<?php
/**
* @version	$Id: themes_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 ThemesEventHandler extends kDBEventHandler {

		/**
		 * Allows to override standard permission mapping
		 *
		 * @return void
		 * @access protected
		 * @see kEventHandler::$permMapping
		 */
		protected function mapPermissions()
		{
			parent::mapPermissions();

			$permissions = Array(
				'OnChangeTheme' => Array('self' => true),
			);

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

		/**
		 * Checks user permission to execute given $event
		 *
		 * @param kEvent $event
		 * @return bool
		 * @access public
		 */
		public function CheckPermission(kEvent $event)
		{
			if ( $event->Name == 'OnItemBuild' ) {
				// check permission without using $event->getSection(),
				// so first cache rebuild won't lead to "ldefault_Name" field being used
				return true;
			}

			return parent::CheckPermission($event);
		}

		/**
		 * Ensure, that current object is always taken from live table.
		 *
		 * @param kDBBase|kDBItem|kDBList $object Object.
		 * @param kEvent                  $event  Event.
		 *
		 * @return void
		 */
		protected function dbBuild(&$object, kEvent $event)
		{
			if ( $event->Special == 'current' ) {
				$event->setEventParam('live_table', true);
			}

			parent::dbBuild($object, $event);
		}

		/**
		 * Ensures that current theme detection will fallback to primary without extra DB query.
		 *
		 * @param kEvent $event Event.
		 *
		 * @return integer
		 */
		public function getPassedID(kEvent $event)
		{
			if ( $event->Special == 'current' ) {
				$theme_id = $this->Application->GetVar('m_theme');

				if ( !$theme_id ) {
					$theme_id = 'default';
				}
				else {
					$event->setEventParam(kEvent::FLAG_ID_FROM_REQUEST, true);
				}

				$this->Application->SetVar('m_theme', $theme_id);
				$this->Application->SetVar($event->getPrefixSpecial() . '_id', $theme_id);

				return $theme_id;
			}

			return parent::getPassedID($event);
		}

		/**
		 * Allows to set selected theme as primary
		 *
		 * @param kEvent $event
		 */
		function OnSetPrimary($event)
		{
			if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
				$event->status = kEvent::erFAIL;
				return;
			}

			$ids = $this->StoreSelectedIDs($event);
			if ($ids) {
				$id = array_shift($ids);
				$this->setPrimary($id);

				$this->Application->HandleEvent(new kEvent('adm:OnRebuildThemes'));
			}

			$this->clearSelectedIDs($event);
		}

		function setPrimary($id)
		{
			$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
			$table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');

			$sql = 'UPDATE '.$table_name.'
					SET PrimaryTheme = 0';
			$this->Conn->Query($sql);


			$sql = 'UPDATE '.$table_name.'
					SET PrimaryTheme = 1, Enabled = 1
					WHERE '.$id_field.' = '.$id;
			$this->Conn->Query($sql);
		}

		/**
		 * Validate entered stylesheet path.
		 *
		 * @param kEvent $event Event.
		 *
		 * @return void
		 */
		protected function OnBeforeItemUpdate(kEvent $event)
		{
			parent::OnBeforeItemUpdate($event);

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

			if ( $object->GetDBField('StylesheetFile') && !$object->getStylesheetFile() ) {
				$object->SetError('StylesheetFile', 'not_found');
			}
		}

		/**
		 * Set's primary theme (when checkbox used on editing form)
		 *
		 * @param kEvent $event
		 * @return void
		 * @access protected
		 */
		protected function OnAfterCopyToLive(kEvent $event)
		{
			parent::OnAfterCopyToLive($event);

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

			$object->Load($event->getEventParam('id'));

			if ( $object->GetDBField('PrimaryTheme') ) {
				$this->setPrimary($event->getEventParam('id'));
			}
		}

		/**
		 * Also rebuilds theme files, when enabled theme is saved
		 *
		 * @param kEvent $event
		 * @return void
		 * @access protected
		 */
		protected function OnSave(kEvent $event)
		{
			parent::OnSave($event);

			if ( ($event->status != kEvent::erSUCCESS) || !$event->getEventParam('ids') ) {
				return ;
			}

			$ids = $event->getEventParam('ids');

			$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
			$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');

			$sql = 'SELECT COUNT(*)
					FROM ' . $table_name . '
					WHERE ' . $id_field . ' IN (' . $ids . ') AND (Enabled = 1)';
			$enabled_themes = $this->Conn->GetOne($sql);

			if ( $enabled_themes ) {
				$this->Application->HandleEvent(new kEvent('adm:OnRebuildThemes'));
			}
		}

		/**
		 * Allows to change the theme
		 *
		 * @param kEvent $event
		 */
		function OnChangeTheme($event)
		{
			if ($this->Application->isAdminUser) {
				// for structure theme dropdown
				$this->Application->StoreVar('theme_id', $this->Application->GetVar('theme'));
				$this->Application->StoreVar('RefreshStructureTree', 1);
				return ;
			}

			$this->Application->SetVar('t', 'index');
			$this->Application->SetVar('m_cat_id', 0);

			$this->Application->SetVar('m_theme', $this->Application->GetVar('theme'));
		}

		/**
		 * Apply system filter to themes list
		 *
		 * @param kEvent $event
		 * @return void
		 * @access protected
		 * @see kDBEventHandler::OnListBuild()
		 */
		protected function SetCustomQuery(kEvent $event)
		{
			parent::SetCustomQuery($event);

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

			if ( in_array($event->Special, Array ('enabled', 'selected', 'available')) || !$this->Application->isAdminUser ) {
				// "enabled" special or Front-End
				$object->addFilter('enabled_filter', '%1$s.Enabled = ' . STATUS_ACTIVE);
			}

			// site domain theme picker
			if ( $event->Special == 'selected' || $event->Special == 'available' ) {
				/** @var EditPickerHelper $edit_picker_helper */
				$edit_picker_helper = $this->Application->recallObject('EditPickerHelper');

				$edit_picker_helper->applyFilter($event, 'Themes');
			}

			// apply domain-based theme filtering
			$themes = $this->Application->siteDomainField('Themes');

			if ( strlen($themes) ) {
				$themes = explode('|', substr($themes, 1, -1));
				$object->addFilter('domain_filter', '%1$s.ThemeId IN (' . implode(',', $themes) . ')');
			}
		}
	}
