<?php
/**
* @version	$Id: private_message_eh.php 14251 2011-03-16 21:21:42Z alex $
* @package	In-Bulletin
* @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license      GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/

	defined('FULL_PATH') or die('restricted access!');

	class PrivateMessageEventHandler extends kDBEventHandler {

		function mapPermissions()
		{
			parent::mapPermissions();
			$permissions = Array(
				'OnItemBuild' => Array('self' => true),
				'OnCreate' => Array('self' => true),
				'OnDelete' => Array('self' => true),
			);

			$this->permMapping = array_merge($this->permMapping, $permissions);
		}

		/**
		 * Applies folder & message owner filter to message list
		 *
		 * @param kEvent $event
		 */
		function SetCustomQuery(&$event)
		{
			$folder_id = $this->Application->GetVar('folder_id');
			if ($folder_id === false) {
				$folder_id = PM_FOLDER_INBOX;
				$this->Application->SetVar('folder_id', $folder_id);
			}

			$object =& $event->getObject();
			/* @var $object kDBList */

			$user_id = $this->Application->RecallVar('user_id');
			if ($folder_id == PM_FOLDER_INBOX) {
				$object->addFilter('owner_filter', '%1$s.ToId = '.$user_id);
			}
			else {
				$object->addFilter('owner_filter', '%1$s.FromId = '.$user_id);
			}
			$object->addFilter('folder_filter', '%1$s.FolderId = '.$folder_id);
		}

		/**
		 * Puts message to Sent folder
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemCreate(&$event)
		{
			$object =& $event->getObject();
			/* @var $object kDBItem */

			if ($object->GetDBField('FolderId') != PM_FOLDER_SENT) {
				// when creating "Inbox" message (from "Sent" message) don't reset folder & status
				return ;
			}

			$user_id = $this->Application->RecallVar('user_id');
			$object->SetDBField('FromId', $user_id);
			$object->SetDBField('FolderId', PM_FOLDER_SENT);
			$object->SetDBField('Status', PM_STATUS_READ);
		}

		/**
		 * Creates 1st post when topic is created
		 *
		 * @param kEvent $event
		 */
		function OnAfterItemCreate(&$event)
		{
			parent::OnAfterItemCreate($event);

			$object =& $event->getObject();
			/* @var $object kDBItem */

			$this->Application->EmailEventUser('PM.ADD', $object->GetDBField('ToId'));

			if ($object->GetDBField('FolderId') != PM_FOLDER_SENT) {
				// 1. create message in sender's "Sent" folder (this method only for this step)
				// 2. create message body (shared)
				// 3. create message copy in recipient's "Inbox" folder
				return ;
			}

			$message_body =& $this->Application->recallObject($event->Prefix.'-body', null, Array ('skip_autoload' => true));
			/* @var $message_body kDBItem */

			// 1. create message body (for sender & recipient)
			$copy_fields = Array ('Subject', 'Body', 'ShowSignatures', 'DisableSmileys', 'DisableBBCodes');
			$message_body->SetDBFieldsFromHash($object->GetFieldValues(), $copy_fields);

			$body_created = $message_body->Create();
			if ($body_created) {
				// 2. link body with message
				$object->SetDBField('PMBodyId', $message_body->GetID());
				$object->Update();

				// 3. create message in recipient's Inbox folder
				$object->SetDBField('FolderId', PM_FOLDER_INBOX);
				$object->SetDBField('Status', PM_STATUS_UNREAD);
				$object->Create();
			}
		}

		/**
		 * Sets post options to virtual fields
		 *
		 * @param kEvent $event
		 */
		function OnAfterItemLoad(&$event)
		{
			$object =& $event->getObject();
			/* @var $object kDBItem */

			$post_helper =& $this->Application->recallObject('PostHelper');
			/* @var $post_helper PostHelper */

			$options_map = $post_helper->getOptionsMap();
			$post_options = $object->GetDBField('Options');
			foreach ($options_map as $option_name => $field_name) {
				$option_value = $post_helper->GetPostOption($option_name, $post_options);
				$object->SetDBField($field_name, (int)$option_value);
			}
		}

		/**
		 * Goes to next_template after post creation
		 *
		 * @param kEvent $event
		 */
		function OnCreate(&$event)
		{
			parent::OnCreate($event);

			if ($event->status == erSUCCESS && !$this->Application->isAdmin) {
				$event->SetRedirectParam('opener', 's');
				$event->redirect = $this->Application->GetVar('next_template');
			}
		}

		/**
		 * Prevents user from deleting other user private messages
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemDelete(&$event)
		{
			$object =& $event->getObject();
	    	/* @var $object kDBItem */

			$user_id = $this->Application->RecallVar('user_id');
			$owner_field = ($object->GetDBField('FolderId') == PM_FOLDER_INBOX) ? 'ToId' : 'FromId';
			if ($object->GetDBField($owner_field) != $user_id) {
	    		$event->status = erFAIL;
	    	}
		}

		/**
		 * Updates reference counter in message body record
		 *
		 * @param kEvent $event
		 */
		function OnAfterItemDelete(&$event)
		{
	    	$object =& $event->getObject();
	    	/* @var $object kDBItem */

	    	$body_idfield = $this->Application->getUnitOption($event->Prefix.'-body', 'IDField');
	    	$body_table = $this->Application->getUnitOption($event->Prefix.'-body', 'TableName');
	    	$sql = 'UPDATE '.$body_table.'
	    			SET ReferenceCount = ReferenceCount - 1
	    			WHERE '.$body_idfield.' = '.$object->GetDBField('PMBodyId');
	    	$this->Conn->Query($sql);
		}

		/**
		 * Sets default values to posting options based on persistent session
		 *
		 * @param kEvent $event
		 */
		function OnAfterConfigRead(&$event)
		{
			$virtual_fields = $this->Application->getUnitOption($event->Prefix, 'VirtualFields');
			$virtual_fields['DisableBBCodes']['default'] = (int)!$this->Application->RecallPersistentVar('bbcode');
			$virtual_fields['DisableSmileys']['default'] = (int)!$this->Application->RecallPersistentVar('smileys');
			$virtual_fields['ShowSignatures']['default'] = (int)$this->Application->RecallPersistentVar('show_sig');
			$this->Application->setUnitOption($event->Prefix, 'VirtualFields', $virtual_fields);
		}

		/**
		 * Checks, that current user is recipient or sender of viewed message
		 *
		 * @param kEvent $event
		 * @return bool
		 */
		function checkItemStatus(&$event)
		{
			$object =& $event->getObject();
			if (!$object->isLoaded()) {
				return true;
			}

			$user_id = $this->Application->RecallVar('user_id');
			return ($object->GetDBField('FromId') == $user_id) || ($object->GetDBField('ToId') == $user_id);
		}

		/**
		 * Prepares new reply & new message form
		 *
		 * @param kEvent $event
		 */
		function OnNew(&$event)
		{
			parent::OnNew($event);

			$reply_to = $this->Application->GetVar('reply_to');
			$user_id = $this->Application->GetVar('user_id');

			$object =& $event->getObject();
			/* @var $object kDBItem */

			if ($reply_to > 0) {
				// reply to message
				$source_msg =& $this->Application->recallObject($event->Prefix.'.-item', null, Array ('skip_autoload' => true));
				/* @var $source_msg kDBItem */

				$source_msg->Load($reply_to);

				$object->SetDBField('ToId', $source_msg->GetDBField('FromId'));
				$object->SetDBField('Subject', 'Re: '.$source_msg->GetDBField('Subject'));
			}
			elseif ($user_id > 0) {
				// send message to any user by id
				$object->SetDBField('ToId', $user_id);
			}
		}
	}