<?php
/**
* @version	$Id: selectors_event_handler.php 14241 2011-03-16 20:24:35Z 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!');

safeDefine('STYLE_BASE', 	1);
safeDefine('STYLE_BLOCK', 	2);

	class SelectorsEventHandler extends kDBEventHandler
	{
		/**
		 * Allows to override standart permission mapping
		 *
		 */
		function mapPermissions()
		{
			parent::mapPermissions();
			$permissions = Array(
									'OnResetToBase'		=>	Array('subitem' => 'add|edit'),
									'OnMassResetToBase'	=>	Array('subitem' => 'add|edit'),

									'OnOpenStyleEditor'	=>	Array('subitem' => 'add|edit'),
									'OnSaveStyle'		=>	Array('subitem' => 'add|edit'),
							);
			$this->permMapping = array_merge($this->permMapping, $permissions);
		}

		/**
		 * Occures before an item has been cloned
		 * Id of newly created item is passed as event' 'id' param
		 *
		 * @param kEvent $event
		 */
		function OnBeforeClone(&$event)
		{
			$event->Init($event->Prefix, '-item');
			$object =& $event->getObject();

			$title_field = 'SelectorName';
			$new_name = $object->GetDBField($title_field);
			$original_checked = false;

			$foreign_key = $event->getEventParam('foreign_key'); // in case if whole stylesheet is cloned
			if($foreign_key === false) $foreign_key = $object->GetDBField('StylesheetId'); // in case if selector is copied ifself

			do {
				if ( preg_match('/(.*)-([\d]+)/', $new_name, $regs) ) {
					$new_name = $regs[1].'-'.($regs[2]+1);
				}
				elseif ($original_checked) {
					$new_name = $new_name.'-1';
				}

				// if we are cloning in temp table this will look for names in temp table,
				// since object' TableName contains correct TableName (for temp also!)
				// if we are cloning live - look in live
				$query = '	SELECT '.$title_field.'
							FROM '.$object->TableName.'
							WHERE '.$title_field.' = '.$this->Conn->qstr($new_name).' AND StylesheetId = '.$foreign_key;

				$res = $this->Conn->GetOne($query);

				/*// if not found in live table, check in temp table if applicable
				if ($res === false && $object->Special == 'temp') {
					$query = 'SELECT '.$name_field.' FROM '.$this->GetTempName($master['TableName']).'
										WHERE '.$name_field.' = '.$this->Conn->qstr($new_name);
					$res = $this->Conn->GetOne($query);
				}*/

				$original_checked = true;
			} while ($res !== false);
			$object->SetDBField($title_field, $new_name);
		}

		/**
		 * Show base styles or block styles
		 *
		 * @param kEvent $event
		 */
		function SetCustomQuery(&$event)
		{
			$object =& $event->getObject();
			switch ($event->Special)
			{
				case 'base':
					$object->addFilter('type_filter', '%1$s.Type = 1');
					break;

				case 'block':
					$object->addFilter('type_filter', '%1$s.Type = 2');
					break;
			}
		}

		/**
		 * Enter description here...
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemUpdate(&$event)
		{
			$this->SerializeSelectorData($event);
		}

		/**
		 * Enter description here...
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemCreate(&$event)
		{
			$this->SerializeSelectorData($event);
		}

		/**
		 * Enter description here...
		 *
		 * @param kEvent $event
		 */
		function OnAfterItemUpdate(&$event)
		{
			$this->UnserializeSelectorData($event);
		}

		/**
		 * Enter description here...
		 *
		 * @param kEvent $event
		 */
		function OnAfterItemCreate(&$event)
		{
			$this->UnserializeSelectorData($event);
		}

		/**
		 * Get's special of main item for linking with subitem
		 *
		 * @param kEvent $event
		 * @return string
		 */
		function getMainSpecial(&$event)
		{
			return '';
		}

		/**
		 * Save css-style name & description before opening css editor
		 *
		 * @param kEvent $event
		 */
		function OnOpenStyleEditor(&$event)
		{
			$this->SaveChanges($event);
			$event->redirect = false;
		}

		/**
		 * Saves Changes to Item
		 *
		 * @param kEvent $event
		 */
		function SaveChanges(&$event)
		{
			$object =& $event->getObject( Array('skip_autoload' => true) );

			$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
			if($items_info)
			{
				list($id,$field_values) = each($items_info);
				if ($id == 0) {
					$parent_id = getArrayValue($field_values,'ParentId');
					if($parent_id) $object->Load($parent_id);

					$object->SetFieldsFromHash($field_values);
					$object->Create();

					$this->Application->SetVar($event->getPrefixSpecial().'_id', $object->GetID() );
				}
				else {
					$object->Load($id);
					$object->SetFieldsFromHash($field_values);
					$object->Update();
				}
			}
		}

		/**
		 * Save style changes from style editor
		 *
		 * @param kEvent $event
		 */
		function OnSaveStyle(&$event)
		{
			$this->SaveChanges($event);

			$object =& $event->getObject();
			$this->Application->SetVar($event->getPrefixSpecial().'_id', $object->GetId() );

			$this->finalizePopup($event);
		}

		/**
		 * Extract styles
		 *
		 * @param kEvent $event
		 */
		function OnAfterItemLoad(&$event)
		{
			$object =& $event->getObject();
			$selector_data = $object->GetDBField('SelectorData');
			if($selector_data)
			{
				$selector_data = unserialize($selector_data);
				$object->SetDBField('SelectorData', $selector_data);
			}
			else
			{
				$selector_data = Array();
			}
			$this->AddParentProperties($event, $selector_data);
		}

		/**
		 * Serialize item before saving to db
		 *
		 * @param kEvent $event
		 */
		function SerializeSelectorData(&$event)
		{
			$object =& $event->getObject();
			$selector_data = $object->GetDBField('SelectorData');
			if(!$selector_data) $selector_data = Array();

			$selector_data = $this->RemoveParentProperties($event, $selector_data);

			if( !IsSerialized($selector_data) ) $selector_data = serialize($selector_data);

			$object->SetDBField('SelectorData', $selector_data);
		}

		/**
		 * Unserialize data back when update was made
		 *
		 * @param kEvent $event
		 */
		function UnserializeSelectorData(&$event)
		{
			$object =& $event->getObject();
			$selector_data = $object->GetDBField('SelectorData');
			if(!$selector_data) $selector_data = Array();
			if( IsSerialized($selector_data) ) $selector_data = unserialize($selector_data);

			$selector_data = $this->AddParentProperties($event, $selector_data);

			$object->SetDBField('SelectorData', $selector_data);
		}

		/**
		 * Populate options based on temporary table :)
		 *
		 * @param kEvent $event
		 */
		function OnPrepareBaseStyles(&$event)
		{
			$object =& $event->getObject();

			$parent_info = $object->getLinkedInfo();
			$title_field = $this->Application->getUnitOption($event->Prefix,'TitleField');
			$sql = 'SELECT '.$title_field.', '.$object->IDField.' FROM '.$object->TableName.' WHERE Type = 1 AND StylesheetId = '.$parent_info['ParentId'].' ORDER BY '.$title_field;
			$object->Fields['ParentId']['options'] = $this->Conn->GetCol($sql,$object->IDField);
		}

		/**
		 * Remove properties of parent style that match by value from style
		 *
		 * @param kEvent $event
		 */
		function RemoveParentProperties(&$event, $selector_data)
		{
			$object =& $event->getObject();
			$parent_id = $object->GetDBField('ParentId');
			if($parent_id)
			{
				$sql = 'SELECT SelectorData FROM '.$object->TableName.' WHERE '.$object->IDField.' = '.$parent_id;
				$base_selector_data = $this->Conn->GetOne($sql);

				if( IsSerialized($base_selector_data) ) $base_selector_data = unserialize($base_selector_data);

				foreach($selector_data as $prop_name => $prop_value)
				{
					if( !$prop_value || getArrayValue($base_selector_data,$prop_name) == $prop_value )
					{
						unset($selector_data[$prop_name]);
					}
				}
				$object->SetDBField('SelectorData', $selector_data);
				return $selector_data;
			}
			else
			{
				foreach($selector_data as $prop_name => $prop_value)
				{
					if(!$prop_value) unset($selector_data[$prop_name]);
				}
				$object->SetDBField('SelectorData', $selector_data);
				return $selector_data;
			}
		}

		/**
		 * Add back properties from parent style, that match this style property values
		 *
		 * @param kEvent $event
		 */
		function AddParentProperties(&$event, $selector_data)
		{
			$object =& $event->getObject();
			$parent_id = $object->GetDBField('ParentId');
			if($parent_id)
			{
				$sql = 'SELECT SelectorData FROM '.$object->TableName.' WHERE '.$object->IDField.' = '.$parent_id;
				$base_selector_data = $this->Conn->GetOne($sql);

				if( IsSerialized($base_selector_data) ) $base_selector_data = unserialize($base_selector_data);

				$selector_data = array_merge_recursive2($base_selector_data,$selector_data);

				$object->SetDBField('SelectorData', $selector_data);
				return $selector_data;
			}
			return $selector_data;
		}

		/**
		 * Reset Style definition to base style -> no customizations
		 *
		 * @param kEvent $event
		 */
		function OnResetToBase(&$event)
		{
			$object =& $event->getObject();
			$object->SetFieldsFromHash( $this->getSubmittedFields($event) );
			$object->ResetStyle();

			$event->redirect_params['pass'] = 'all,'.$event->getPrefixSpecial();
		}

		/**
		 * Resets selected styles properties to values of their base classes
		 *
		 * @param kEvent $event
		 */
		function OnMassResetToBase(&$event)
		{
			$object =& $event->getObject( Array('skip_autoload' => true) );

			$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
			if($items_info)
			{
				foreach($items_info as $id => $field_values)
				{
					$object->Load($id);
	 				$object->ResetStyle();
				}
			}
		}
	}