<?php
/**
* @version	$Id: post_eh.php 12740 2009-10-20 19:39:07Z 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 PostEventHandler extends kDBEventHandler {

		/**
		 * Checks topic-post modify and delete permissions
		 *
		 * @param kEvent $event
		 */
		function CheckPermission(&$event)
		{
			$events = Array('OnUpdate', 'OnDelete');
			if (in_array($event->Name, $events)) {
				return true;
			}

			return parent::CheckPermission($event);
		}

		/**
		 * Sets default values
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemCreate(&$event)
		{
			$object =& $event->getObject();
			/* @var $object kDBItem */

			$user_id = $this->Application->RecallVar('user_id');

			$now = adodb_mktime();

			$object->SetDBField('CreatedById', $user_id);
			$object->SetDBField('CreatedOn_date', $now);
			$object->SetDBField('CreatedOn_time', $now);

			$object->SetDBField('ModifiedById', $user_id);
			$object->SetDBField('Modified_date', $now);
			$object->SetDBField('Modified_time', $now);

			$object->SetDBField('IPAddress', $_SERVER['REMOTE_ADDR']);

			$sql = 'SELECT Login
					FROM '.TABLE_PREFIX.'PortalUser
					WHERE PortalUserId = '.$user_id;
			$object->SetDBField('PosterAlias', $this->Conn->GetOne($sql));

			// set post options
			$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 = $object->GetDBField($field_name);
				$post_helper->SetPostOption($option_name, $option_value, $post_options);
			}
			$object->SetDBField('Options', $post_options);

			$table_info = $object->getLinkedInfo($event->Special, true);
			$object->SetDBField($table_info['ForeignKey'], $table_info['ParentId']);
		}

		/**
		 * Checks if user has permission on post
		 *
		 * @param kEvent $event
		 * @param string $permissions
		 */
		function checkPostPermission(&$event, $permissions)
		{
			$object =& $event->getObject();
			/* @var $object kDBItem */

			$sql = 'SELECT ci.CategoryId, p.CreatedById
					FROM '.$object->TableName.' p
					LEFT JOIN '.TABLE_PREFIX.'Topic t ON t.TopicId = p.TopicId
					LEFT JOIN '.TABLE_PREFIX.'CategoryItems ci ON ci.ItemResourceId = t.ResourceId AND ci.PrimaryCat = 1
					WHERE p.'.$object->IDField.' = '.$object->GetID();
			$post_info = $this->Conn->GetRow($sql);

			$perm_helper =& $this->Application->recallObject('PermissionsHelper');
			/* @var $perm_helper kPermissionsHelper */

			$is_owner = $post_info['CreatedById'] == $this->Application->RecallVar('user_id');
			$params['permissions'] = 'TOPIC.REPLY.MODIFY|TOPIC.REPLY.OWNER.MODIFY';
			$params['cat_id'] = $post_info['CategoryId'];
			return $perm_helper->TagPermissionCheck($params, $is_owner);
		}

		/**
		 * Sets post options before post update
		 * Ensures, that only user with permission will update topic
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemUpdate(&$event)
		{
			$object =& $event->getObject();
			/* @var $object kDBItem */

			$perm_status = $this->checkPostPermission($event, 'TOPIC.REPLY.MODIFY|TOPIC.REPLY.OWNER.MODIFY');
			if (!$perm_status) {
				$event->status = erFAIL;
				return ;
			}

			$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 = $object->GetDBField($field_name);
				$post_helper->SetPostOption($option_name, $option_value, $post_options);
			}
			$object->SetDBField('Options', $post_options);
		}

		/**
		 * Notifies admin about post change
		 *
		 * @param kEvent $event
		 */
		function OnAfterItemUpdate(&$event)
		{
			parent::OnAfterItemUpdate($event);

			$this->Application->EmailEventAdmin('POST.MODIFY');
		}

		/**
		 * Checks, that user can delete post
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemDelete(&$event)
		{
			$object =& $event->getObject();
			/* @var $object kDBItem */

			$perm_status = $this->checkPostPermission($event, 'TOPIC.REPLY.OWNER.DELETE|TOPIC.REPLY.DELETE');
			if (!$perm_status) {
				$event->status = erFAIL;
			}
		}

		/**
		 * 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);
			}
		}

		/**
		 * Updates cached post counter in topic
		 *
		 * @param kEvent $event
		 */
		function OnAfterItemCreate(&$event)
		{
			$object =& $event->getObject();
			/* @var $object kDBItem */

			$parent_prefix = $this->Application->getUnitOption($event->Prefix, 'ParentPrefix');

			$main_object =& $this->Application->recallObject($parent_prefix);
			/* @var $main_object kCatDBItem */

			// update user posts counter
			$user_posts = $this->Application->RecallPersistentVar('bb_posts');
			$this->Application->StorePersistentVar('bb_posts', $user_posts + 1);

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

			$category_id = $this->Application->GetVar('m_cat_id');
			$post_helper->PropagateCategoryField($category_id, 'Modified', $object->GetDBField('CreatedOn'));

			if (!$this->Application->isAdmin && $main_object->GetDBField('Posts')) {
				// don't send any email events when in admin OR new topic just added (0 posts)

				$user_notified = false; // don't send POST.ADD event twice to same user (in case if owner adds new post)
				if ($main_object->GetDBField('NotifyOwnerOnChanges')) {
					$user_notified = $main_object->GetDBField('OwnerId');
					$this->Application->EmailEventUser('POST.ADD', $user_notified);
				}

				$post_owner_id = $object->GetDBField('CreatedById');
				if (($post_owner_id > 0) && ($user_notified != $post_owner_id)) {
					$this->Application->EmailEventUser('POST.ADD', $post_owner_id);
				}

				$this->Application->EmailEventAdmin('POST.ADD');
			}

			$post_helper->updateTodayPostsCount($main_object, $object->GetDBField('CreatedOn'), +1);
			$this->updateTopicInfo($event, $main_object);

			$topic_id = $object->GetDBField('TopicId');
			$posts_count = $post_helper->updatePostCount($topic_id, +1);
			$main_object->SetDBField('Posts', $posts_count);

			// autolock topic after N number of posts (if option enabled)
			$auto_lock = $this->Application->ConfigValue('AutoTopicLockPosts');
			if ((int)$auto_lock > 0) {
				if ($posts_count >= $auto_lock) {
					// user has unlocked topic after $auto_lock and posts again -> ensure that topic will be locked again
					$this->Application->HandleEvent($parent_prefix.':OnTopicLockToggle');
				}
			}
		}

		/**
		 * Update last post info in topic
		 *
		 * @param kEvent $event
		 * @param kCatDBItem $main_object
		 */
		function updateTopicInfo(&$event, &$main_object)
		{
			$object =& $event->getObject();
			/* @var $object kDBItem */

			$main_object->SetDBField('Modified_date', $object->GetDBField('Modified'));
			$main_object->SetDBField('Modified_time', $object->GetDBField('Modified'));

			$main_object->SetDBField('LastPostId', $object->GetID());

			$main_object->SetDBField('LastPostDate_date', $object->GetDBField('CreatedOn'));
			$main_object->SetDBField('LastPostDate_time', $object->GetDBField('CreatedOn'));

			$main_object->Update();
		}

		/**
		 * 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');
			}
		}

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

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

		/**
		 * Moves reference to last post in topic, when it is deleted
		 *
		 * @param kEvent $event
		 */
		function OnAfterItemDelete(&$event)
		{
			$object =& $event->getObject();
			/* @var $object kDBItem */

			$topic_id = $object->GetDBField('TopicId');
			if (!$topic_id) {
				// deleting non-existing post
				return ;
			}

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

			// update posts count in topic
			$post_helper->updatePostCount($topic_id, -1);

			// update post owner posts counter
			$sql = 'UPDATE '.TABLE_PREFIX.'PersistantSessionData
					SET VariableValue = IF (VariableValue > 0, VariableValue - 1, 0)
					WHERE (PortalUserId = '.$object->GetDBField('CreatedById').') AND (VariableName = "bb_posts")';
			$this->Conn->Query($sql);


			$main_object =& $this->Application->recallObject('bb.-item', null, Array('skip_autoload' => true));
			/* @var $main_object kCatDBItem */

			$main_object->Load($topic_id);

			$post_helper->updateTodayPostsCount($main_object, $object->GetDBField('CreatedOn'), -1);

			if ($main_object->GetDBField('LastPostId') == $object->GetID()) {
				$sql = 'SELECT PostingId, CreatedOn
						FROM '.$object->TableName.'
						WHERE TopicId = '.$topic_id.'
						ORDER BY PostingId DESC';
				$last_post = $this->Conn->GetRow($sql);

				$fields_hash = Array (
					'LastPostId' => $last_post['PostingId'],
					'LastPostDate' => $last_post['CreatedOn'],
				);
				$this->Conn->doUpdate($fields_hash, $main_object->TableName, $main_object->IDField.' = '.$topic_id);
			}
		}

		/**
		 * 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);
		}

		/**
		 * Deletes items & preserves clean env
		 *
		 * @param kEvent $event
		 */
		function OnDelete(&$event)
		{
			parent::OnDelete($event);

			if ($event->status == erSUCCESS && !$this->Application->isAdmin) {
				$parent_prefix = $this->Application->getUnitOption($event->Prefix, 'ParentPrefix');
				$event->SetRedirectParam('pass', 'm,'.$parent_prefix);
			}
		}

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

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

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

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

				$source_post->Load($reply_to);

				$object->SetDBField('Subject', 'Re: '.$source_post->GetDBField('Subject'));
				$object->SetDBField('PostingText', '[quote id='.$reply_to.']'.$source_post->GetDBField('PostingText').'[/quote]');
			}
		}
	}