<?php
/**
 * @version	$Id: system_event_subscription_tp.php 16513 2017-01-20 14:10:53Z alex $
 * @package	In-Portal
 * @copyright	Copyright (C) 1997 - 2012 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 SystemEventSubscriptionTagProcessor extends kDBTagProcessor {

	/**
	 * Holds reference to subscription analyzer
	 *
	 * @var kSubscriptionAnalyzer
	 */
	protected $_analyzer = null;

	/**
	 * Allows to show category path of selected module
	 *
	 * @param Array $params
	 * @return string
	 */
	function CategoryPath($params)
	{
		/** @var kDBItem $object */
		$object = $this->getObject($params);

		$category_id = $object->GetDBField('CategoryId');

		if ( !is_numeric($category_id) ) {
			return '';
		}

		$params['cat_id'] = $category_id;

		/** @var kNavigationBar $navigation_bar */
		$navigation_bar = $this->Application->recallObject('kNavigationBar');

		return $navigation_bar->build($params);
	}

	/**
	 * Prints item name
	 *
	 * @param Array $params
	 * @return string
	 * @access protected
	 */
	protected function ItemName($params)
	{
		/** @var kDBList $object */
		$object = $this->getObject($params);

		if ( !isset($this->_analyzer) ) {
			$this->_analyzer = new kSubscriptionAnalyzer($object);
			$this->_analyzer->run();
		}

		return $this->_analyzer->getTitle($this->SelectParam($params, 'name,field'));
	}
}


class kSubscriptionAnalyzer extends kBase {

	/**
	 * Reference to a list object
	 *
	 * @var kDBList
	 * @access protected
	 */
	protected $_subscriptions = null;

	/**
	 * Remember what to what ids subscription exists for each of subscribed prefixes
	 *
	 * @var Array
	 * @access protected
	 */
	protected $_prefixToIdsMap = Array ();

	/**
	 * Reverse index that remembers what prefix is used in what row (fields: ItemId, ParentItemId)
	 *
	 * @var Array
	 * @access protected
	 */
	protected $_prefixToRowMap = Array ();

	/**
	 * Holds title of each item in list in format [prefix][id] = title
	 *
	 * @var Array
	 * @access protected
	 */
	protected $_itemTitles = Array ();

	/**
	 * Set's references to kApplication and DBConnection interface class instances
	 *
	 * @param kDBList $subscriptions
	 * @access public
	 * @see kApplication
	 * @see IDBConnection
	 */
	public function __construct($subscriptions)
	{
		parent::__construct();

		$this->_subscriptions = $subscriptions;
	}

	/**
	 * Analyzes list
	 *
	 * @return void
	 * @access public
	 */
	public function run()
	{
		foreach ($this->_subscriptions as $subscription) {
			$prefix = $this->_getPrefix();
			$parent_prefix = $this->Application->getUnitOption($prefix, 'ParentPrefix');

			$this->_addIdToPrefix($prefix, 'ItemId');
			$this->_addIdToPrefix($parent_prefix, 'ParentItemId');
		}

		$this->_queryItemTitles();
		$this->_subscriptions->GoFirst();
	}

	/**
	 * Returns item title, associated with item's ID in given field
	 *
	 * @param string $field
	 * @return string
	 */
	public function getTitle($field)
	{
		$row_index = $this->_subscriptions->key();

		if ( !isset($this->_prefixToRowMap[$row_index][$field]) ) {
			return '';
		}

		$prefix = $this->_prefixToRowMap[$row_index][$field];
		$value = $this->_subscriptions->GetDBField($field);

		return $this->_itemTitles[$prefix][$value];
	}

	/**
	 * Queries titles for each of subscribed items
	 *
	 * @return void
	 * @access protected
	 */
	protected function _queryItemTitles()
	{
		foreach ($this->_prefixToIdsMap as $prefix => $ids) {
			$id_field = $this->Application->getUnitOption($prefix, 'IDField');

			$sql = 'SELECT ' . $this->_getTitleField($prefix) . ', ' . $id_field . '
					FROM ' . $this->Application->getUnitOption($prefix, 'TableName') . '
					WHERE ' . $id_field . ' IN (' . implode(',', $ids) . ')';
			$this->_itemTitles[$prefix] = $this->Conn->GetCol($sql, $id_field);
		}
	}

	/**
	 * Adds ID from a gvein field (when it isn't NULL) to prefix ids
	 *
	 * @param string $prefix
	 * @param string $field
	 * @return void
	 * @access protected
	 */
	protected function _addIdToPrefix($prefix, $field)
	{
		$id = $this->_subscriptions->GetDBField($field);

		if ( !$id || !$prefix ) {
			return;
		}

		// add id to prefix ids list
		if ( !isset($this->_prefixToIdsMap[$prefix]) ) {
			$this->_prefixToIdsMap[$prefix] = Array ();
		}

		if ( !in_array($id, $this->_prefixToIdsMap[$prefix]) ) {
			$this->_prefixToIdsMap[$prefix][] = $id;
		}

		// remeber prefix associated with this field
		$row_index = $this->_subscriptions->key();

		if ( !isset($this->_prefixToRowMap[$row_index]) ) {
			$this->_prefixToRowMap[$row_index] = Array ();
		}

		$this->_prefixToRowMap[$row_index][$field] = $prefix;
	}

	/**
	 * Returns prefix of main item in current row
	 *
	 * @return string
	 * @access protected
	 * @throws Exception
	 */
	protected function _getPrefix()
	{
		$event = new kEvent($this->_subscriptions->GetDBField('BindToSystemEvent'));

		if ( !$event->Prefix ) {
			throw new Exception('Subscription "<strong>#' . $this->_subscriptions->GetID() . '</strong>" is connected to invalid or missing e-mail template "<strong>#' . $this->_subscriptions->GetDBField('EmailTemplateId') . '</strong>"');
		}

		return $event->Prefix;
	}

	/**
	 * Returns title field of given prefix
	 *
	 * @param string $prefix
	 * @return array
	 */
	protected function _getTitleField($prefix)
	{
		$lang_prefix = '';
		$title_field = $this->Application->getUnitOption($prefix, 'TitleField');

		if ( preg_match('/^(l[\d]+_)(.*)/', $title_field, $regs) ) {
			// object was initialized and we have lang prefix in unit config
			$lang_prefix = $regs[1];
			$title_field = $regs[2];
		}
		else {
			// object wasn't initialized -> check other way OR not ml title field
			$fields = $this->Application->getUnitOption($prefix, 'Fields');

			if ( isset($fields[$title_field]['formatter']) && $fields[$title_field]['formatter'] == 'kMultiLanguage' ) {
				$lang_prefix = 'l' . $this->Application->GetVar('m_lang') . '_';
			}
		}

		return $lang_prefix . $title_field;
	}
}