<?php
/**
* @version	$Id: plain_url_processor.php 16513 2017-01-20 14:10:53Z 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 kPlainUrlProcessor extends kUrlProcessor {

	/**
	 * Process QueryString only, create events, ids, based on config
	 * set template name and sid in desired application variables.
	 *
	 * @param string $env_var environment string value
	 * @param string $pass_name
	 * @return Array
	 */
	public function parse($env_var, $pass_name = 'passed')
	{
		// env=SID-TEMPLATE:m-1-1-1-1:l0-0-0:n-0-0-0:bb-0-0-1-1-1-0
		if ( !$env_var ) {
			return Array ('t' => $this->manager->getTemplateName());
		}

		parse_str(ENV_VAR_NAME . '=' . $env_var, $vars);
		$env_var = $vars[ENV_VAR_NAME];
		unset($vars[ENV_VAR_NAME]);

		// replace escaped ":" symbol not to explode by it
		$env_var = str_replace('\:', '_&+$$+&_', $env_var); // replace escaped "=" with spec-chars :)
		$parts = explode(':', $env_var);

		if ( !$this->Application->RewriteURLs() || ($this->Application->RewriteURLs() && $this->Application->GetVar('rewrite') != 'on') ) {
			$vars = array_merge($vars, $this->extractSIDAndTemplate($parts));
		}

		if ( $parts ) {
			$passed = Array ();

			foreach ($parts as $mixed_part) {
				list ($passed[], $processed_vars) = $this->_parseEnvPart($mixed_part);
				$vars = array_merge($vars, $processed_vars);
			}

			$vars[$pass_name] = implode(',', array_unique($passed));
		}

		return $vars;
	}

	/**
	 * Retrieves SessionID and current template from given ENV parts
	 *
	 * @param Array $parts
	 * @return array
	 * @access protected
	 */
	protected function extractSIDAndTemplate(&$parts)
	{
		$template = '';
		$vars = Array ();

		if ( preg_match('/^([\d]+|)-(.*)$/', $parts[0], $regs) ) {
			// first "env" component matches "sid-template" format
			// (will be false, when mod-rewrite url to home page is built)
			$sid = $regs[1];
			$template = $regs[2];
			array_shift($parts);

			if ( $sid ) {
				// Save Session ID
				$this->Application->SetVar('sid', $sid);
				$vars['sid'] = $sid;
			}
		}

		// Save Template Name
		$vars['t'] = $this->manager->getTemplateName($template);

		return $vars;
	}

	/**
	 * Converts environment part into variable array (based on query map for given prefix)
	 *
	 * @param string $mixed_part
	 * @return Array
	 * @access protected
	 */
	protected function _parseEnvPart($mixed_part)
	{
		// In-portal old style env conversion - adds '-' between prefix and first var
		$mixed_part = str_replace('_&+$$+&_', ':', $mixed_part);
		$mixed_part = preg_replace("/^([a-zA-Z]+)([0-9]+)-(.*)/", "$1-$2-$3", $mixed_part);

		// replace escaped "-" symbol not to explode by it
		$escaped_part = str_replace('\-', '_&+$$+&_', $mixed_part);
		$escaped_part = explode('-', $escaped_part);

		$mixed_part = Array();
		foreach ($escaped_part as $escaped_val) {
			$mixed_part[] = str_replace('_&+$$+&_', '-', $escaped_val);
		}

		$vars = Array ();
		$prefix_special = array_shift($mixed_part); // l.pick, l

		/** @var kHTTPQuery $http_query */
		$http_query = $this->Application->recallObject('HTTPQuery');

		$query_map = $http_query->discoverUnit($prefix_special); // from $_GET['env']

		// if config is not defined for prefix in QueryString, then don't process it
		if ($query_map) {
			foreach ($query_map as $index => $var_name) {
				// l_id, l_page, l_bla-bla-bla
				$val = $mixed_part[$index - 1];
				if ($val == '') $val = false;
				$vars[$prefix_special.'_'.$var_name] = $val;
			}
		}

		return Array ($prefix_special, $vars);
	}

	/**
	 * Builds url
	 *
	 * @param string $t
	 * @param Array $params
	 * @param string $pass
	 * @param bool $pass_events
	 * @param bool $env_var
	 * @return string
	 * @access public
	 */
	public function build($t, $params, $pass='all', $pass_events = false, $env_var = true)
	{
		if ( $this->Application->GetVar('admin') || (array_key_exists('admin', $params) && $params['admin']) ) {
			$params['admin'] = 1;

			if ( !array_key_exists('editing_mode', $params) ) {
				$params['editing_mode'] = EDITING_MODE;
			}
		}

		$ssl = isset($params['__SSL__']) ? $params['__SSL__'] : 0;
		$sid = isset($params['sid']) && !$this->Application->RewriteURLs($ssl) ? $params['sid'] : '';

		if ( isset($params['__SSL__']) ) {
			unset($params['__SSL__']);
		}

		$env_string = '';
		$category_id = isset($params['m_cat_id']) ? $params['m_cat_id'] : $this->Application->GetVar('m_cat_id');

		$item_id = false;
		$pass_info = $this->getPassInfo($pass);

		if ( $pass_info ) {
			if ( $pass_info[0] == 'm' ) {
				array_shift($pass_info);
			}

			foreach ($pass_info as $pass_element) {
				list($prefix) = explode('.', $pass_element);
				$require_rewrite = $this->Application->findModule('Var', $prefix);

				if ( $require_rewrite ) {
					$item_id = isset($params[$pass_element . '_id']) ? $params[$pass_element . '_id'] : $this->Application->GetVar($pass_element . '_id');
				}

				$env_string .= ':' . $this->BuildModuleEnv($pass_element, $params, $pass_events);
			}
		}

		if ( strtolower($t) == '__default__' ) {
			if ( is_numeric($item_id) ) {
				$this->manager->initRewrite();
				$t = $this->manager->rewrite->GetItemTemplate($category_id, $pass_element); // $pass_element should be the last processed element
				// $t = $this->Application->getCategoryCache($category_id, 'item_templates');
			}
			elseif ( $category_id ) {
				$t = strtolower(preg_replace('/^Content\//i', '', $this->Application->getCategoryCache($category_id, 'filenames')));
			}
			else {
				$t = 'index';
			}
		}

		$env_string = $sid . '-' . $t . ':' . $this->BuildModuleEnv('m', $params, $pass_events) . $env_string;
		unset($params['pass'], $params['opener'], $params['m_event']);
		$params = array(ENV_VAR_NAME => $env_string) + $params;

		$params_str = http_build_query($params);
		$ret = str_replace('%23', '#', $params_str);

		if ( !$env_var ) {
			$ret = substr($ret, strlen(ENV_VAR_NAME) + 1);
		}

		return $ret;
	}

	/**
	 * Builds env part that corresponds prefix passed
	 *
	 * @param string $prefix_special item's prefix & [special]
	 * @param Array $params url params
	 * @param bool $pass_events
	 * @return string
	 * @access public
	 */
	public function BuildModuleEnv($prefix_special, &$params, $pass_events = false)
	{
		list($prefix) = explode('.', $prefix_special);

		/** @var Array $query_vars */
		$query_vars = $this->Application->getUnitOption($prefix, 'QueryString', Array ());

		//if pass events is off and event is not implicitly passed
		if ( !$pass_events && !isset($params[$prefix_special . '_event']) ) {
			$params[$prefix_special . '_event'] = ''; // remove event from url if requested
			//otherwise it will use value from get_var
		}

		if ( !$query_vars ) {
			return '';
		}

		$tmp_string = Array (0 => $prefix_special);
		foreach ($query_vars as $index => $var_name) {
			//if value passed in params use it, otherwise use current from application
			$var_name = $prefix_special . '_' . $var_name;
			$tmp_string[$index] = isset($params[$var_name]) ? $params[$var_name] : $this->Application->GetVar($var_name);

			if ( isset($params[$var_name]) ) {
				unset($params[$var_name]);
			}
		}

		$escaped = array ();
		foreach ($tmp_string as $tmp_val) {
			$escaped[] = str_replace(Array ('-', ':'), Array ('\-', '\:'), $tmp_val);
		}

		$ret = implode('-', $escaped);
		if ( $this->Application->getUnitOption($prefix, 'PortalStyleEnv') == true ) {
			$ret = preg_replace('/^([a-zA-Z]+)-([0-9]+)-(.*)/', '\\1\\2-\\3', $ret);
		}

		return $ret;
	}
}