<?php
/**
* @version	$Id: content_eh.php 16513 2017-01-20 14:10:53Z alex $
* @package	In-Portal
* @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 ContentEventHandler extends kDBEventHandler {

		/**
		 * Checks user permission to execute given $event
		 *
		 * @param kEvent $event
		 * @return bool
		 * @access public
		 */
		public function CheckPermission(kEvent $event)
		{
			/** @var kPermissionsHelper $perm_helper */
			$perm_helper = $this->Application->recallObject('PermissionsHelper');

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

			// user can change top category
			$top_category = $this->Application->getBaseCategory();
			$perm_status = $perm_helper->CheckUserPermission($user_id, 'CATEGORY.MODIFY', 0, $top_category);

			return $perm_helper->finalizePermissionCheck($event, $perm_status);
		}

		/**
		 * Saves changes to a content block (+ creates draft if missing)
		 *
		 * @param kEvent $event
		 */
		function OnSaveContentBlock($event)
		{
			if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) {
				$event->status = kEvent::erFAIL;

				return;
			}

			$updated = $this->saveContentBlock($event, false);

			if ( $this->Application->GetVar('ajax') == 'yes' ) {
				$event->status = kEvent::erSTOP;
				echo ($updated === false) ? 'FAILED' : 'OK';
			}
			elseif ( !$updated ) {
				$event->status = kEvent::erFAIL;
			}

			$event->SetRedirectParam('opener', 'u');
		}

		/**
		 * Prepare temp tables and populate it
		 * with items selected in the grid
		 *
		 * @param kEvent $event
		 * @return void
		 * @access protected
		 */
		protected function OnEdit(kEvent $event)
		{
			parent::OnEdit($event);

			/** @var fckFCKHelper $fck_helper */
			$fck_helper = $this->Application->recallObject('FCKHelper');

			$transit_params = $fck_helper->getTransitParams();

			foreach ($transit_params as $param_name => $param_value) {
				$event->SetRedirectParam($param_name, $param_value);
			}
		}

		/**
		 * Saves changes & changes language
		 *
		 * @param kEvent $event
		 * @return void
		 * @access protected
		 */
		protected function OnPreSaveAndChangeLanguage(kEvent $event)
		{
			if ( $this->UseTempTables($event) ) {
				parent::OnPreSaveAndChangeLanguage($event);

				return;
			}

			// CUSTOM: begin
			$event->CallSubEvent('OnSaveContentBlock');
			$event->SetRedirectParam('opener', 's');
			// CUSTOM: end

			if ( $event->status == kEvent::erSUCCESS ) {
				$this->Application->SetVar('m_lang', $this->Application->GetVar('language'));

				$data = $this->Application->GetVar('st_id');

				if ( $data ) {
					$event->SetRedirectParam('st_id', $data);
				}
			}
		}
		/**
		 * Performs auto-save of current content block (will create draft too)
		 *
		 * @param kEvent $event
		 */
		function OnAutoSave($event)
		{
			$event->status = kEvent::erSTOP;

			if ( $this->Application->GetVar('ajax') != 'yes' ) {
				return ;
			}

			echo $this->saveContentBlock($event, true);
		}

		/**
		 * Saves content block
		 *
		 * @param kEvent $event
		 * @param bool $is_draft
		 * @return string
		 */
		function saveContentBlock($event, $is_draft)
		{
			$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));

			if ( !$items_info ) {
				return '';
			}

			list ($object, $revision) = $this->getContentBlockAndRevision($event);
			/** @var kDBItem $revision */
			/** @var kDBItem $object */

			list (, $field_values) = each($items_info);
			$object->SetFieldsFromHash($field_values);
			$event->setEventParam('form_data', $field_values);
			$updated = $object->Update();

			if ( $updated ) {
				$revision->SetDBField('AutoSavedOn_date', adodb_mktime());
				$revision->SetDBField('AutoSavedOn_time', adodb_mktime());
				$revision->Update();
			}

			if ( $is_draft ) {
				if ( $updated ) {
					/** @var PageHelper $page_helper */
					$page_helper = $this->Application->recallObject('PageHelper');

					return $revision->GetField('AutoSavedOn') . ' (' . $page_helper->getAgoTime($revision->GetDBField('AutoSavedOn')) . ')';
				}
			}
			else {
				return $updated;
			}

			return '';
		}

		/**
		 * Returns last autosave time
		 *
		 * @param kEvent $event
		 */
		function OnGetAutoSaveTime($event)
		{
			$event->status = kEvent::erSTOP;

			if ( $this->Application->GetVar('ajax') != 'yes' ) {
				return;
			}

			list (, $revision) = $this->getContentBlockAndRevision($event);
			/** @var kDBItem $revision */

			/** @var PageHelper $page_helper */
			$page_helper = $this->Application->recallObject('PageHelper');

			$time = $revision->GetField('AutoSavedOn');

			if ( $time ) {
				echo $time . ' (' . $page_helper->getAgoTime($revision->GetDBField('AutoSavedOn')) . ')';
			}
		}

		/**
		 * Loads content block from given revision
		 *
		 * @param kDBItem $object
		 * @param kDBItem $revision
		 */
		function loadFromRevision(&$object, &$revision)
		{
			$load_keys = Array(
				'PageId' => $object->GetDBField('PageId'),
				'ContentNum' => $object->GetDBField('ContentNum'),
				'RevisionId' => $revision->GetID(),
			);

			$object->Load($load_keys);
		}

		/**
		 * Returns content block.
		 *
		 * @param kEvent $event
		 *
		 * @return kDBItem[]
		 */
		function getContentBlockAndRevision($event)
		{
			/** @var kDBItem $object */
			$object = $event->getObject(Array('skip_autoload' => true));

			$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
			if ( !$items_info ) {
				return array();
			}

			list ($id,) = each($items_info);
			$object->Load($id);

			/** @var kDBItem $revision */
			$revision = $this->Application->recallObject('page-revision', null, Array('skip_autoload' => true));

			$revision->Load($object->GetDBField('RevisionId'));

			if ( $this->Application->ConfigValue('EnablePageContentRevisionControl') && !$revision->GetDBField('IsDraft') ) {
				// editing live revision of a page's content block -> get draft for current user and page
				$load_keys = Array(
					'PageId' => $revision->GetDBField('PageId'),
					'IsDraft' => 1,
					'CreatedById' => $this->Application->RecallVar('user_id'),
				);

				$revision->Load($load_keys);

				if ( $revision->isLoaded() ) {
					// draft found -> use draft's content block version
					$this->loadFromRevision($object, $revision);
				}
				else {
					// draft not found -> create new
					$revision->SetDBFieldsFromHash($load_keys);
					$revision->SetDBField('FromRevisionId', $object->GetDBField('RevisionId'));

					if ( $revision->Create() ) {
						$this->loadFromRevision($object, $revision);
					}
				}
			}

			return Array(&$object, &$revision);
		}
	}
