<?php
/**
* @version	$Id: phrases_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!');

	class PhrasesEventHandler extends kDBEventHandler
	{
		/**
		 * Apply some special processing to
		 * object beeing recalled before using
		 * it in other events that call prepareObject
		 *
		 * @param Object $object
		 * @param kEvent $event
		 * @access protected
		 */
		function prepareObject(&$object, &$event)
		{
			// don't call parent
			if ($event->Special == 'import' || $event->Special == 'export') {
				$this->RemoveRequiredFields($object);
				$object->setRequired('LangFile');
				$object->setRequired('PhraseType');
				$object->setRequired('Module');

				// allow multiple phrase types to be selected during import/export
				$field_options = $object->GetFieldOptions('PhraseType');
				$field_options['type'] = 'string';
				$object->SetFieldOptions('PhraseType', $field_options);
			}
		}

		/**
		 * Allow to create phrases from front end in debug mode with DBG_PHRASES constant set
		 *
		 * @param kEvent $event
		 */
		function CheckPermission(&$event)
		{
			if (!$this->Application->isAdmin && $this->Application->isDebugMode() && constOn('DBG_PHRASES')) {
				$allow_events = Array ('OnCreate', 'OnUpdate');

				if (in_array($event->Name, $allow_events)) {
					return true;
				}
			}

			return parent::CheckPermission($event);
		}

		function mapPermissions()
		{
			parent::mapPermissions();

			$permissions = Array (
				'OnItemBuild' => Array('self' => true, 'subitem' => true),
				'OnPreparePhrase' => Array('self' => true, 'subitem' => true),
			);

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

		/**
		 * Prepares phrase for translation
		 *
		 * @param kEvent $event
		 */
		function OnPreparePhrase(&$event)
		{
			$label = $this->Application->GetVar($event->getPrefixSpecial() . '_label');

			if (!$label) {
				return ;
			}

			// we got label, try to get it's ID then if any
			$phrase_id = $this->_getPhraseId($label);

			if ($phrase_id) {
				$event->SetRedirectParam($event->getPrefixSpecial(true) . '_id', $phrase_id);
				$event->SetRedirectParam('pass', 'm,' . $event->getPrefixSpecial());
			}
			else {
				$event->CallSubEvent('OnNew');
			}

			if ($this->Application->GetVar('simple_mode')) {
				$event->SetRedirectParam('simple_mode', 1);
			}
		}

		function _getPhraseId($phrase)
		{
			$sql = 'SELECT ' . $this->Application->getUnitOption($this->Prefix, 'IDField') . '
					FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . '
					WHERE PhraseKey = ' . $this->Conn->qstr( mb_strtoupper($phrase) );

			return $this->Conn->GetOne($sql);
		}

		/**
		 * Forces new label in case if issued from get link
		 *
		 * @param kEvent $event
		 */
		function OnNew(&$event)
		{
			parent::OnNew($event);

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

			$label = $this->Application->GetVar($event->getPrefixSpecial() . '_label');

			if ($label) {
				// phrase is created in language, used to display phrases
				$object->SetDBField('Phrase', $label);
				$object->SetDBField('PhraseType', 1); // admin
				$object->SetDBField('PrimaryTranslation', $this->_getPrimaryTranslation($label));
			}

			// set module from cookie
			$last_module = $this->Application->GetVar('last_module');

			if ($last_module) {
				$object->SetDBField('Module', $last_module);
			}

			if (($event->Special == 'export') || ($event->Special == 'import')) {
				$object->SetDBField('PhraseType', '|0|1|2|');
				$object->SetDBField('Module', '|' . implode('|', array_keys($this->Application->ModuleInfo)) . '|' );
			}
		}

		/**
		 * Returns given phrase translation on primary language
		 *
		 * @param string $phrase
		 * @return string
		 */
		function _getPrimaryTranslation($phrase)
		{
			$sql = 'SELECT l' . $this->Application->GetDefaultLanguageId() . '_Translation
					FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . '
					WHERE PhraseKey = ' . $this->Conn->qstr( mb_strtoupper($phrase) );

			return $this->Conn->GetOne($sql);
		}

		/**
		 * Forces create to use live table
		 *
		 * @param kEvent $event
		 */
		function OnCreate(&$event)
		{
			if ( $this->Application->GetVar($event->Prefix . '_label') ) {
				$object =& $event->getObject( Array('skip_autoload' => true) );

				if ($this->Application->GetVar('m_lang') != $this->Application->GetVar('lang_id')) {
					$object->SwitchToLive();
				}
			}

			parent::OnCreate($event);
		}

		/**
		 * Set last change info, when phrase is created
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemCreate(&$event)
		{
			parent::OnBeforeItemCreate($event);

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

			$primary_language_id = $this->Application->GetDefaultLanguageId();

			if (!$object->GetDBField('l' . $primary_language_id . '_Translation')) {
				// no translation on primary language -> try to copy from other language
				$src_languages = Array ('lang_id', 'm_lang'); // editable language, theme language

				foreach ($src_languages as $src_language) {
					$src_language = $this->Application->GetVar($src_language);
					$src_value = $src_language ? $object->GetDBField('l' . $src_language . '_Translation') : false;

					if ($src_value) {
						$object->SetDBField('l' . $primary_language_id . '_Translation', $src_value);
						break;
					}
				}
			}

			$this->_phraseChanged($event);
		}

		/**
		 * Update last change info, when phrase is updated
		 *
		 * @param kEvent $event
		 */
		function OnBeforeItemUpdate(&$event)
		{
			parent::OnBeforeItemUpdate($event);

			$this->_phraseChanged($event);
		}

		/**
		 * Set's phrase key and last change info, used for phrase updating and loading
		 *
		 * @param kEvent $event
		 */
		function _phraseChanged(&$event)
		{
			$object =& $event->getObject();
			/* @var $object kDBItem */

			$object->SetDBField('PhraseKey', mb_strtoupper($object->GetDBField('Phrase')));

			if ($object->GetOriginalField('Translation') != $object->GetDBField('Translation')) {
				$object->SetDBField('LastChanged_date', adodb_mktime() );
				$object->SetDBField('LastChanged_time', adodb_mktime() );
				$object->SetDBField('LastChangeIP', $_SERVER['REMOTE_ADDR']);
			}

			$this->Application->Session->SetCookie('last_module', $object->GetDBField('Module'));
		}

		/**
		 * Changes default module to custom (when available)
		 *
		 * @param kEvent $event
		 */
		function OnAfterConfigRead(&$event)
		{
			parent::OnAfterConfigRead($event);

			if ($this->Application->findModule('Name', 'Custom')) {
				$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
				$fields['Module']['default'] = 'Custom';
				$this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
			}

			// make sure, that PrimaryTranslation column always refrers to primary language column
			$language_id = $this->Application->GetVar('lang_id');

			if (!$language_id) {
				$language_id = $this->Application->GetVar('m_lang');
			}

			$primary_language_id = $this->Application->GetDefaultLanguageId();
			$calculated_fields = $this->Application->getUnitOption($event->Prefix, 'CalculatedFields');

			foreach ($calculated_fields[''] as $field_name => $field_expression) {
				$field_expression = str_replace('%5$s', $language_id, $field_expression);
				$field_expression = str_replace('%4$s', $primary_language_id, $field_expression);

				$calculated_fields[''][$field_name] = $field_expression;
			}

			$this->Application->setUnitOption($event->Prefix, 'CalculatedFields', $calculated_fields);

			if ($this->Application->GetVar('regional')) {
				$this->Application->setUnitOption($event->Prefix, 'PopulateMlFields', true);
			}
		}

		/**
		 * Saves changes & changes language
		 *
		 * @param kEvent $event
		 */
		function OnPreSaveAndChangeLanguage(&$event)
		{
			$label = $this->Application->GetVar($event->getPrefixSpecial() . '_label');

			if ($label && !$this->UseTempTables($event)) {
				$phrase_id = $this->_getPhraseId($label);

				if ($phrase_id) {
					$event->CallSubEvent('OnUpdate');
					$event->SetRedirectParam('opener', 's');
				}
				else {
					$event->CallSubEvent('OnCreate');
					$event->SetRedirectParam('opener', 's');
				}

				if ($event->status != erSUCCESS) {
					return ;
				}

				$event->SetRedirectParam($event->getPrefixSpecial() . '_event', 'OnPreparePhrase');
				$event->SetRedirectParam('pass_events', true);
			}

			if ($this->Application->GetVar('simple_mode')) {
				$event->SetRedirectParam('simple_mode', 1);
			}

			parent::OnPreSaveAndChangeLanguage($event);
		}

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

			// use language from grid, instead of primary language used by default
			$event->SetRedirectParam('m_lang', $this->Application->GetVar('m_lang'));
		}
	}