<?php
/**
* @version	$Id: permissions_tag_processor.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 PermissionsTagProcessor extends kDBTagProcessor {

		function HasPermission($params)
		{
			$section_name = $params['section_name'];

			$sections_helper =& $this->Application->recallObject('SectionsHelper');
			$section_data =& $sections_helper->getSectionData($section_name);

			return array_search($params['perm_name'], $section_data['permissions']) !== false;
		}

		function HasAdvancedPermissions($params)
		{
			$section_name = $params['section_name'];

			$sections_helper =& $this->Application->recallObject('SectionsHelper');
			$section_data =& $sections_helper->getSectionData($section_name);

			$ret = false;
			foreach ($section_data['permissions'] as $perm_name) {
				if (preg_match('/^advanced:(.*)/', $perm_name)) {
					$ret = true;
					break;
				}
			}
			return $ret;
		}

		function PermissionValue($params)
		{
			$section_name = $params['section_name'];
			$perm_name = $params['perm_name'];

			$sections_helper =& $this->Application->recallObject('SectionsHelper');
			$section_data =& $sections_helper->getSectionData($section_name);

			if ($section_data && isset($section_data['perm_prefix'])) {
				// using permission from other prefix
				$section_name = $this->Application->getUnitOption($section_data['perm_prefix'].'.main', 'PermSection');
			}

			$permissions_helper =& $this->Application->recallObject('PermissionsHelper');
			if (!$permissions_helper->isOldPermission($section_name, $perm_name)) {
				$perm_name = $section_name.'.'.$perm_name;
			}

			return $permissions_helper->getPermissionValue($perm_name);
		}

		function LoadPermissions($params)
		{
			$permissions_helper =& $this->Application->recallObject('PermissionsHelper');
			$prefix_parts = explode('-', $this->Prefix, 2);
			/* @var $permissions_helper kPermissionsHelper */

			$permissions_helper->LoadPermissions($this->Application->GetVar('g_id'), 0, 1, 'g');
		}

		function LevelIndicator($params)
		{
			return $params['level'] * $params['multiply'];
		}

		function PrintPermissions($params)
		{
			$category =& $this->Application->recallObject('c');
			/* @var $category kDBItem */

			$group_id = $this->Application->GetVar('group_id');
			$prefix = $this->Application->GetVar('item_prefix');
			$module = $this->Application->findModule('Var', $prefix, 'Name');

			$perm_live_table = $this->Application->getUnitOption('c-perm', 'TableName');
			$perm_temp_table = $this->Application->GetTempName($perm_live_table, 'prefix:'.$this->Prefix);

			if ($category->GetID() == 0) {
				$categories = Array(0);
			}
			else {
				$categories = explode('|', substr($category->GetDBField('ParentPath'), 1, -1));
			}

			if (count($categories) == 1 || $category->GetID() == 0) {
				// category located in root category ("Home") => then add it to path virtually
				array_unshift($categories, 0);
			}
			$this_cat = array_pop($categories);

			// get permission name + category position in parent path that has value set for that permission
			$case = 'MAX(CASE p.CatId';
			foreach ($categories as $pos => $cat_id) {
				$case .= ' WHEN '.$cat_id.' THEN '.$pos;
			}
			$case .= ' END) AS InheritedPosition';

			$sql = 'SELECT '.$case.', p.Permission AS Perm
					FROM '.$perm_live_table.' p
					LEFT JOIN '.TABLE_PREFIX.'PermissionConfig pc ON pc.PermissionName = p.Permission
					WHERE
						p.CatId IN ('.implode(',', $categories).') AND
						pc.ModuleId = ' . $this->Conn->qstr($module) . ' AND
						(
							(p.GroupId = ' . (int)$group_id . ' AND p.Type = 0)
						)
					GROUP BY Perm';
			$perm_positions = $this->Conn->GetCol($sql, 'Perm');

			$pos_sql = '';
			foreach ($perm_positions as $perm_name => $category_pos) {
				$pos_sql .= '(#TABLE_PREFIX#.Permission = "'.$perm_name.'" AND #TABLE_PREFIX#.CatId = '.$categories[$category_pos].') OR ';
			}
			$pos_sql = $pos_sql ? substr($pos_sql, 0, -4) : '0';

			// get all permissions list with iheritence status, inherited category id and permission value
			$sql = 'SELECT 	pc.PermissionName,
							pc.Description,
							IF (tmp_p.PermissionValue IS NULL AND p.PermissionValue IS NULL,
								0,
								IF (tmp_p.PermissionValue IS NOT NULL, tmp_p.PermissionValue, p.PermissionValue)
							) AS Value,
							IF (tmp_p.CatId IS NOT NULL, tmp_p.CatId, IF(p.CatId IS NOT NULL, p.CatId, 0) ) AS InheritedFrom,
							IF(tmp_p.CatId = '.$category->GetID().', 0, 1) AS Inherited,
							IF(p.PermissionValue IS NOT NULL, p.PermissionValue, 0) AS InheritedValue
					FROM '.TABLE_PREFIX.'PermissionConfig pc
					LEFT JOIN '.$perm_live_table.' p
					ON (p.Permission = pc.PermissionName) AND ('.str_replace('#TABLE_PREFIX#', 'p', $pos_sql).') AND (p.GroupId = '.(int)$group_id.')
					LEFT JOIN '.$perm_temp_table.' tmp_p
					ON (tmp_p.Permission = pc.PermissionName) AND (tmp_p.CatId = '.$this_cat.') AND (tmp_p.GroupId = '.$group_id.')
					WHERE ModuleId = "'.$module.'"';
			$permissions = $this->Conn->Query($sql);

			$ret = '';
			$block_params = array_merge_recursive2( $this->prepareTagParams($params), Array('name' => $params['render_as']));
			foreach ($permissions as $perm_record) {
				$block_params = array_merge_recursive2($block_params, $perm_record);
				$ret .= $this->Application->ParseBlock($block_params);
			}
			return $ret;
		}

		/**
		 * Print module tab for each module
		 *
		 * @param Array $params
		 * @return string
		 */
		function PrintTabs($params)
		{
			$ret = '';
			$block_params = $params;
			foreach ($this->Application->ModuleInfo as $module_name => $module_data) {
				if (!$this->Application->prefixRegistred($module_data['Var']) || !$this->Application->getUnitOption($module_data['Var'], 'CatalogItem')) continue;
				$params['item_prefix'] = $module_data['Var'];
				$ret .= $this->Application->IncludeTemplate($params);
			}

			return $ret;
		}

		/**
		 * Returns category name by ID
		 *
		 * @param Array $params
		 */
		function CategoryPath($params)
		{
			$category_id = $params['cat_id'];
			$cache_key = 'category_paths[%CIDSerial:' . $category_id . '%][%PhrasesSerial%][Adm:' . (int)$this->Application->isAdmin . ']';
			$category_path = $this->Application->getCache($cache_key);

			if ($category_path === false) {
				// not chached
				if ($category_id > 0) {
					$id_field = $this->Application->getUnitOption('c', 'IDField');
					$table_name = $this->Application->getUnitOption('c', 'TableName');
					$ml_formatter =& $this->Application->recallObject('kMultiLanguage');

					$sql = 'SELECT '.$ml_formatter->LangFieldName('CachedNavbar').'
							FROM '.$table_name.'
							WHERE '.$id_field.' = '.$category_id;
					$cached_navbar = preg_replace('/^Content(&\|&){0,1}/i', '', $this->Conn->GetOne($sql));
					$category_path = trim($this->CategoryPath( Array('cat_id' => 0) ).' > '.str_replace('&|&', ' > ', $cached_navbar), ' > ');
				}
				else {
					$category_path = $this->Application->Phrase(($this->Application->isAdmin ? 'la_' : 'lu_') . 'rootcategory_name');
				}

				$this->Application->setCache($cache_key, $category_path);
			}

			return $category_path;
		}

		function PermInputName($params)
		{
			 return $this->Prefix.'['.$this->Application->GetVar('group_id').']['.$this->Application->Parser->GetParam('PermissionName').']['.$params['sub_key'].']';
		}

	}