<?php
/**
* @version	$Id: promo_block_eh.php 15373 2012-05-30 10:32:20Z alex $
* @package	In-Portal
* @copyright	Copyright (C) 1997 - 2011 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 PromoBlockEventHandler extends kDBEventHandler {

	/**
	 * Define alternative event processing method names
	 *
	 * @return void
	 * @see kEventHandler::$eventMethods
	 * @access protected
	 */
	protected function mapEvents()
	{
		parent::mapEvents();

		$events_map = Array (
			'OnMassMoveUp' => 'OnChangePriority',
			'OnMassMoveDown' => 'OnChangePriority',
		);

		$this->eventMethods = array_merge($this->eventMethods, $events_map);
	}

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

		$permissions = Array (
			'OnItemBuild' => Array ('self' => true),
			'OnSetSticky' => Array ('self' => 'view'),
			'OnRegisterView' => Array ('self' => true),
			'OnFollowLink' => Array ('self' => true),
			'OnResetCounters' => Array ('self' => 'add|edit'),
		);

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

	/**
	 * Sets default value for promo block group
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnPreCreate(kEvent $event)
	{
		parent::OnPreCreate($event);

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

		$promo_block_group = $this->Application->recallObject('promo-block-group');
		/* @var $promo_block_group kDBItem */

		$object->SetDBField('PromoBlockGroupId', $promo_block_group->GetID());
	}

	/**
	 * Processes OnMassMoveUp, OnMassMoveDown events
	 *
	 * @param kEvent $event
	 */
	function OnChangePriority($event)
	{
		$this->Application->SetVar('priority_prefix', $event->getPrefixSpecial());
		$event->CallSubEvent('priority:' . $event->Name);
	}

	/**
	 * Apply any custom changes to list's sql query
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 * @see kDBEventHandler::OnListBuild()
	 */
	protected function SetCustomQuery(kEvent $event)
	{
		parent::SetCustomQuery($event);

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

		if ( $this->Application->isAdmin ) {
			$promo_block_group = $this->Application->recallObject('promo-block-group');
			/* @var $promo_block_group kDBItem */

			$object->addFilter('promo_group_filter', '%1$s.PromoBlockGroupId = ' . $promo_block_group->GetID());
			return;
		}

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

		if ( !$group_id ) {
			$page = $this->Application->recallObject('st');
			/* @var $page CategoriesItem */

			$group_id = $page->GetDBField('PromoBlockGroupId');
		}

		$object->addFilter('status_filter', '%1$s.Status = ' . STATUS_ACTIVE);
		$object->addFilter('scheduled_from_filter', '%1$s.ScheduleFromDate IS NULL OR %1$s.ScheduleFromDate <= ' . TIMENOW);
		$object->addFilter('scheduled_to_filter', '%1$s.ScheduleToDate IS NULL OR %1$s.ScheduleToDate >= ' . TIMENOW);
		$object->addFilter('promo_group_filter', $group_id ? '%1$s.PromoBlockGroupId = ' . $group_id : 'FALSE');
	}

	/**
	 * Set's block as sticky
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnSetSticky(kEvent $event)
	{
		$object = $event->getObject( Array('skip_autoload' => true) );
		/* @var $object kDBItem */

		$ids = $this->StoreSelectedIDs($event);

		if ( $ids ) {
			$id = array_shift($ids);

			$sql = 'UPDATE ' . $object->TableName . '
					SET Sticky = 0';
			$this->Conn->Query($sql);

			$sql = 'UPDATE ' . $object->TableName . '
					SET Sticky = 1, Status = ' . STATUS_ACTIVE . '
					WHERE BlockId = ' . $id;
			$this->Conn->Query($sql);
		}

		$this->clearSelectedIDs($event);
	}


	/**
	 * Set Required fields
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnBeforeItemCreate(kEvent $event)
	{
		parent::OnBeforeItemCreate($event);

		$this->_itemChanged($event);
	}

	/**
	 * Set Required fields
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnBeforeItemUpdate(kEvent $event)
	{
		parent::OnBeforeItemUpdate($event);

		$this->_itemChanged($event);
	}

	/**
	 * Schedule dates
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function _itemChanged(kEvent $event)
	{
		$object = $event->getObject();
		/* @var $object kDBItem */

		$date_from = $object->GetDBField('ScheduleFromDate_date');
		$date_to = $object->GetDBField('ScheduleToDate_date');

		if ( $date_from && $date_to && $date_from >= $date_to ) {
			$object->SetError('ScheduleFromDate_date', 'wrong_date_interval');
		}

		$object->setRequired('CategoryId', $object->GetDBField('LinkType') == PromoBlockType::INTERNAL);
		$object->setRequired('ExternalLink', $object->GetDBField('LinkType') == PromoBlockType::EXTERNAL);
	}

	/**
	 * Registers view of the promo block
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnRegisterView(kEvent $event)
	{
		$this->_incrementField($event, 'NumberOfViews');
	}

	/**
	 * Registers click on the promo block
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnFollowLink(kEvent $event)
	{
		$object = $event->getObject();
		/* @var $object kDBItem */

		$this->_incrementField($event, 'NumberOfClicks', false);

		if ( $object->GetDBField('LinkType') == 1 ) { // Internal
			$sql = 'SELECT NamedParentPath
					FROM ' . TABLE_PREFIX . 'Categories
					WHERE CategoryId = ' . $object->GetDBField('CategoryId');
			$event->redirect = $this->Conn->GetOne($sql);

			$event->SetRedirectParam('pass', 'm');
		}
		else {
			$ext_url = $object->GetDBField('ExternalLink');
			$event->redirect = 'external:' . (preg_match('/^(http|ftp):\\/\\/.*/', $ext_url) ? $ext_url : $this->Application->BaseURL() . $ext_url);
		}
	}

	/**
	 * Increment given promo block counters
	 *
	 * @param kEvent $event
	 * @param string $field
	 * @param bool $is_ajax
	 * @return void
	 * @access protected
	 */
	protected function _incrementField(kEvent $event, $field, $is_ajax = true)
	{
		if ( $is_ajax ) {
			$event->status = kEvent::erSTOP;

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

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

		if ( !$object->isLoaded() ) {
			echo 'FAILED';
			return ;
		}

		// don't use kDBItem::Update to support concurrent view updates from different visitors
		$sql = 'UPDATE ' . $object->TableName . '
				SET ' . $field . ' = ' . $field . ' + 1
				WHERE ' . $object->IDField . ' = ' . $object->GetID();
		$this->Conn->Query($sql);

		echo 'OK';
	}

	/**
	 * Resets promo block counters
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnResetCounters(kEvent $event)
	{
		$object = $event->getObject( Array ('skip_autoload' => true) );
		/* @var $object kDBItem */

		$ids = $this->StoreSelectedIDs($event);

		foreach ($ids as $id) {
			$object->Load($id);
			$object->SetDBField('NumberOfViews', 0);
			$object->SetDBField('NumberOfClicks', 0);
			$object->Update();
		}

		$this->clearSelectedIDs($event);
	}

	/**
	 * Occurs, when config was parsed, allows to change config data dynamically
	 *
	 * @param kEvent $event
	 * @return void
	 * @access protected
	 */
	protected function OnAfterConfigRead(kEvent $event)
	{
		parent::OnAfterConfigRead($event);

		$category_helper = $this->Application->recallObject('CategoryHelper');
		/* @var $category_helper CategoryHelper */

		$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');

		$fields['CategoryId']['options'] = $category_helper->getStructureTreeAsOptions();

		// images multilang fields
		$a_image = Array(
			'type' => 'string', 'max_len' => 255,
			'formatter' => 'kUploadFormatter', 'upload_dir' => IMAGES_PATH . 'promo_blocks/',
			'multiple' => 1, 'thumb_format' => 'resize:100x100',
			'file_types' => '*.jpg;*.gif;*.png', 'files_description' => '!la_hint_ImageFiles!',
			'not_null' => 1, 'default' => '',
		);

		// get active languages
		$sql = 'SELECT LanguageId
				FROM ' . TABLE_PREFIX . 'Languages';
		$languages = $this->Conn->GetCol($sql);

		foreach ($languages as $lang_id) {
			$fields['l' . $lang_id . '_Image'] = $a_image;
		}

		$fields['l' . $this->Application->GetDefaultLanguageId() . '_Image']['required'] = 1;

		$this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
	}
}
