<?php
/**
* @version	$Id: products_tag_processor.php 13813 2010-07-07 09:44:57Z alex $
* @package	In-Commerce
* @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license	Commercial License
* This software is protected by copyright law and international treaties.
* Unauthorized reproduction or unlicensed usage of the code of this program,
* or any portion of it may result in severe civil and criminal penalties,
* and will be prosecuted to the maximum extent possible under the law
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/

defined('FULL_PATH') or die('restricted access!');

class ProductsTagProcessor extends kCatDBTagProcessor {

	function Rating($params)
	{
		$object =& $this->getObject($params);
		$rating = round($object->GetDBField('CachedRating') );

		$o = '';
		for ($i = 0; $i < $rating; $i++) {
			$o .= $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'star_on_render_as,block_star_on')) );
		}

		for ($i = 0; $i < 5 - $rating; $i++) {
			$o .= $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'star_off_render_as,block_star_off')) );
		}

		return $o;
	}

	function NewMark($params)
	{
		$object =& $this->getObject($params);
		$o = '';
		if($object->GetDBField('IsNew'))
		{
			$o .= $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'render_as,block')) );
		}
		return $o;
	}

	function HotMark($params)
	{
		$object =& $this->getObject($params);
		$o = '';
		if($object->GetDBField('IsHot'))
		{
			$o .= $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'render_as,block')) );
		}
		return $o;
	}

	function TopSellerMark($params)
	{
		return $this->HotMark($params);
	}

	function PopMark($params)
	{
		$object =& $this->getObject($params);
		$o = '';
		if($object->GetDBField('IsPop'))
		{
			$o .= $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'render_as,block')) );
		}
		return $o;
	}

	function EdPickMark($params)
	{
		$object =& $this->getObject($params);
		$o = '';
		if($object->GetDBField('EditorsPick'))
		{
			$o .= $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'render_as,block')) );
		}
		return $o;
	}

	/**
	 * Parses block only if item is favorite
	 *
	 * @param Array $params
	 * @return string
	 * @deprecated used only in default,onlinestore
	 */
	function FavoriteMark($params)
	{
		if ($this->IsFavorite($params)) {
			return $this->Application->ParseBlock( Array( 'name' => $this->SelectParam($params, 'render_as,block') ) );
		}

		return '';
	}

	function CurrentCategory($params){
		$conn=$this->Application->GetADODBConnection();
		return $conn->GetOne("SELECT Name FROM ".TABLE_PREFIX."Category WHERE CategoryId=".$this->Application->GetVar("m_cat_id"));
	}

	function RateForm($params)
	{
		$params['name'] = $this->SelectParam($params, 'render_as,block');
		$labels = explode(',', $params['labels']);
		$o = '';
		$star_block = $this->SelectParam($params, 'star_render_as,star_block');
		for($i = 5; $i >= 0; $i--)
		{
			$params['rating'] = $i;
			$params['label'] = $this->Application->Phrase($labels[5 - $i]);
			$params['stars'] = '';
			for($j = $i; $j > 0; $j--)
			{
				$params['stars'] .= $this->Application->ParseBlock(Array('name' => $star_block));
			}
			$o .= $this->Application->ParseBlock($params);
		}
		return $o;
	}

	/**
	 * Parses block for changing favorite status
	 *
	 * @param Array $params
	 * @return string
	 * @deprecated used only in default,onlinestore
	 */
	function FavoriteToggle($params)
	{
		$block_params = Array ();
		$block_names = $this->IsFavorite($params) ? 'remove_favorite_render_as,block_remove_favorite' : 'add_favorite_render_as,block_add_favorite';
		$block_params['name'] = $this->SelectParam($params, $block_names);
		$params['template'] = $params[$this->IsFavorite($params) ? 'template_on_remove' : 'template_on_add'];

		$remove_params = Array (
			'remove_favorite_render_as', 'block_remove_favorite', 'add_to_wish_list_render_as', 'block_add_to_wish_list',
			'add_favorite_render_as', 'block_add_favorite', 'remove_from_wish_list_render_as', 'block_remove_from_wish_list',
			'template_on_remove', 'template_on_add'
		);

		foreach ($params as $param_name => $param_value) {
			if (in_array($param_name, $remove_params)) {
				unset($params[$param_name]);
			}
		}

		$block_params['wish_list_toggle_link'] = $this->FavoriteToggleLink($params);
		return $this->Application->ParseBlock($block_params);
	}

	function WishListToggleLink($params)
	{
		$params['block_add_favorite'] = $this->SelectParam($params, 'add_to_wish_list_render_as,block_add_to_wish_list');
		$params['block_remove_favorite'] = $this->SelectParam($params, 'remove_from_wish_list_render_as,block_remove_from_wish_list');
		return $this->FavoriteToggle($params);
	}

	function AddReviewLink($params)
	{
		$o = $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'render_as,block')) );
		return $o;
	}

	function ListProducts($params)
	{
		return $this->PrintList2($params);
	}

	function ListRelatedProducts($params)
	{
//		$related = &$this->Application->recallObject('rel');
		return $this->PrintList2($params);
	}

	function BuildListSpecial($params)
	{
		if ($this->Special != '') return $this->Special;
		if ( isset($params['parent_cat_id']) ) {
			$parent_cat_id = $params['parent_cat_id'];
		}
		else {
			$parent_cat_id = $this->Application->GetVar('c_id');
			if (!$parent_cat_id) {
				$parent_cat_id = $this->Application->GetVar('m_cat_id');
			}
		}

		if ( isset($params['manufacturer']) ) {
			$manufacturer = $params['manufacturer'];
		}
		else {
			$manufacturer = $this->Application->GetVar('manuf_id');
		}

		$recursive = isset($params['recursive']);

		$list_unique_key = $this->getUniqueListKey($params).$recursive;
		if ($list_unique_key == '') {
			return parent::BuildListSpecial($params);
		}

		return crc32($parent_cat_id.$list_unique_key.$manufacturer);
	}

	function ProductList($params)
	{
		if($params['shortlist'])
		{
			$params['per_page'] = $this->Application->ConfigValue('Comm_Perpage_Products_Short');
		}
		$object =& $this->Application->recallObject( $this->getPrefixSpecial() , $this->Prefix.'_List', $params );

		switch($params['ListType'])
		{
			case 'favorites':
				return $this->PrintList($params);
				break;
			case 'search':

			default:
				if(isset($params['block']))
				{
					return $this->PrintList($params);
				}
				else
				{
					$params['block'] = $params['block_main'];
					$params['row_start_block'] = $params['block_row_start'];
					$params['row_end_block'] = $params['block_row_end'];
					return $this->PrintList2($params);
				}
		}
	}

	/**
	 * Adds product to recently viewed list (only in case, when not already there)
	 *
	 * @param Array $params
	 */
	function AddToRecent($params)
	{
		$recent_products = $this->Application->RecallVar('recent_products');
		if (!$recent_products) {
			$recent_products = Array();
		}
		else {
			$recent_products = unserialize($recent_products);
		}

		$product_id = $this->Application->GetVar('p_id');
		if (!in_array($product_id, $recent_products)) {
			array_push($recent_products, $product_id);
			$this->Application->StoreVar('recent_products', serialize($recent_products));
		}
	}

	function SearchMoreLink($params)
	{
		$object =& $this->Application->recallObject( $this->getPrefixSpecial() , $this->Prefix.'_List', $params );
		$o = '';
		if($object->PerPage < $this->SearchResultsCount())
		{
			$o = $this->Application->ParseBlock( Array('name' => $params['block']) );
		}
		return $o;
	}

	function AddToCartLink($params)
	{
		$object =& $this->getObject($params);

		if ($object->GetDBField('HasRequiredOptions')) {
			$t = $params['product_template'];
			if (!$t) {
				$theme =& $this->Application->recallObject('theme.current');
				if ($theme->GetDBField('Name') == 'onlinestore') {
					$t = 'in-commerce/product/details';
				}
				elseif ($theme->GetDBField('Name') == 'default') {
					$t = 'in-commerce/product';
				}
			}
			$link_params = Array('m_cat_id' => $object->GetDBField('CategoryId'), 'pass' => 'm,p');
		}
		else {
			$t = $params['template'];
			$link_params = Array('m_cat_id' => $object->GetDBField('CategoryId'), 'pass' => 'm,p,ord', 'ord_event' => 'OnAddToCart');
		}

		$this->Application->SetVar('p_id', $this->Application->GetVar($this->getPrefixSpecial().'_id'));
		return $this->Application->HREF($t, '', $link_params);
	}

	function SearchResultsCount($params)
	{
		$search_results_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
		$sql = '	SELECT COUNT(ResourceId)
					FROM '.$search_results_table.'
					WHERE ItemType=11';
		return $this->Conn->GetOne($sql);
	}

	function DetailsLink($params)
	{
		$this->Application->SetVar( $this->Prefix.'_id', $this->Application->GetVar($this->getPrefixSpecial().'_id') );
		$ret = $this->Application->HREF('in-commerce/details', '', Array('pass' => 'all,p'));
		return $ret;
	}

	function ProductLink($params)
	{
		return $this->ItemLink($params, 'product');
	}

	function ProductFileLink($params)
	{
		// 'p_id'=>'0',  ??
		$params = array_merge($params,  Array('pass'=>'all,m,p,file.downl'));
		$product_id = getArrayValue($params,'product_id');
		if (!$product_id) {
			$product_id = $this->Application->GetVar($this->Prefix.'_id');
		}
		$params['p_id'] = $product_id;

		$product =& $this->Application->recallObject($this->getPrefixSpecial());
		$params['m_cat_id'] = $product->GetDBField('CategoryId');

		$main_processor =& $this->Application->recallObject('m_TagProcessor');
		return $main_processor->T($params);
	}

	/*
	function MoreLink($params)
	{
		$object =& $this->Application->recallObject( $this->getPrefixSpecial() , $this->Prefix.'_List', $params );
		$favorites_tag_processor =& $this->Application->recallObject('fav_TagProcessor');
		$o = '';
		if($object->PerPage < $favorites_tag_processor->FavoriteProductCount( Array('filter' => 'all') ))
		{
			$o = $this->Application->ParseBlock( Array('name' => $params['block']) );
		}
		return $o;
	}
	*/

	function GetMarkedVal($params)
	{
		$list =& $this->GetList($params);

		return $this->Application->RecallVar($list->getPrefixSpecial().$params['name']);
	}

	function SortingOptions($params)
	{
		$list =& $this->GetList($params);

		$sorting_field_selected = $this->Application->RecallVar($list->getPrefixSpecial().$params['sorting_select_name']);

		if (!$sorting_field_selected){
			$sorting_field_selected = $this->Application->ConfigValue('product_OrderProductsBy');
		}

		$sql = 'SELECT ValueList
				FROM ' . TABLE_PREFIX . 'ConfigurationValues
				WHERE VariableName = "product_OrderProductsBy"';
		$field_list_plain = $this->Conn->GetOne($sql);

		$field_list = explode(',', $field_list_plain);

		$o = '';

		foreach ($field_list as $key=>$field){
			list($fieldname, $fieldlabel) = explode('=', $field);
			$option_params = $this->prepareTagParams($params);
			$option_params['fieldname'] = $fieldname;
			$option_params['fieldlabel'] = $this->Application->Phrase($fieldlabel);
			$option_params['name'] = $params['block_options'];
			if ($fieldname == $sorting_field_selected){
				$option_params['selected'] = 'selected';
			}else{
				$option_params['selected'] = '';
			}
			$o .= $this->Application->ParseBlock($option_params);
		}

		return $o;
	}

	function SortingDirectionOptions($params)
	{
		$list =& $this->GetList($params);

		$sorting_dir_selected = $this->Application->RecallVar($list->getPrefixSpecial().$params['sorting_select_name']);

		if (!$sorting_dir_selected){
			$sorting_dir_selected = $this->Application->ConfigValue('product_OrderProductsByDir');
		}

		$o = '';

		$field_list = array('asc' => 'lu_Ascending', 'desc' => 'lu_Descending');

		foreach ($field_list as $fieldname=>$fieldlabel){

			$option_params = $this->prepareTagParams($params);
			$option_params['fieldname'] = $fieldname;
			$option_params['fieldlabel'] = $this->Application->Phrase($fieldlabel);
			$option_params['name'] = $params['block_options'];
			if ($fieldname == $sorting_dir_selected){
				$option_params['selected'] = 'selected';
			}else{
				$option_params['selected'] = '';
			}
			$o .= $this->Application->ParseBlock($option_params);

		}

		return $o;
	}

	function ErrorMessage($params)
	{
		if( $this->Application->GetVar('keywords_too_short') )
		{
			$ret = $this->Application->ParseBlock(Array('name' => $this->SelectParam($params, 'keywords_too_short_render_as,block_keywords_too_short')));
		}
		elseif( $this->Application->GetVar('adv_search_error') )
		{
			$ret = $this->Application->ParseBlock(Array('name' => $this->SelectParam($params, 'adv_search_error_render_as,block_adv_search_error')));
		}
		else
		{
			$ret = $this->Application->ParseBlock(Array('name' => $this->SelectParam($params, 'no_found_render_as,block_no_found')));
		}
		return $ret;
	}

	function ListReviews($params)
	{
		$review_tag_processor =& $this->Application->recallObject('rev.product_TagProcessor');
		return $review_tag_processor->PrintList($params);
	}

	function ReviewCount($params)
	{
		$review_tag_processor =& $this->Application->recallObject('rev.product_TagProcessor');
		return $review_tag_processor->TotalRecords($params);
	}

	function InitList($params){

		$passed_manuf_id = $this->Application->GetVar('manuf_id');
		if ($passed_manuf_id && !isset($params['manufacturer'])){
			$params['manufacturer'] = $passed_manuf_id;
		}
		parent::InitList($params);

	}

	/**
	 * Builds link to manufacturer page
	 *
	 * @param Array $params
	 * @return string
	 */
	function ManufacturerLink($params)
	{
		if ( array_key_exists('manufacturer_id', $params) ) {
			// use direct manufacturer from tag
			$params['manuf_id'] = $params['manufacturer_id'];
			unset($params['manufacturer_id']);
		}
		else {
			// use product's manufacturer
			$object =& $this->getObject($params);
			$item_manufacturer_id = $object->GetDBField('ManufacturerId');

			if ($item_manufacturer_id){
				$params['manuf_id'] = $item_manufacturer_id;
			}
		}

		$params['pass'] = 'm,manuf';
		$params['m_cat_id'] = 0;
		return $this->Application->ProcessParsedTag('m', 'Link', $params);
	}

	function AlreadyReviewed($params)
	{
		$rev_tag_processor =& $this->Application->recallObject('rev_TagProcessor');
		return $rev_tag_processor->AlreadyReviewed($params);
	}

	function PrepareSearchResults($params)
	{
		$names_mapping = $this->Application->GetVar('NamesToSpecialMapping');

		if($this->Application->GetVar('search_type') == 'advanced' || !getArrayValue($names_mapping, $this->Prefix, 'search_results'))
		{
			$params = Array('list_name'		=>	'search_results',
							'types'			=>	'search',
							'parent_cat_id'	=>	'any',
							'recursive'		=>	'true',
							'per_page'		=>	'short_list'
						);
			$this->InitList($params);
		}
		return '';
	}

	function Available($params)
	{
		$object =& $this->Application->recallObject($this->getPrefixSpecial(), $this->Prefix, $params);

		if (!$object->GetDBField('InventoryStatus')) return true;

		$backordering = $this->Application->ConfigValue('Comm_Enable_Backordering');

		if ($object->GetDBField('InventoryStatus') == 2) {
			$poc_table = $this->Application->getUnitOption('poc', 'TableName');
			$sql = 'SELECT SUM(IF(QtyInStock > '.$object->GetDBField('QtyInStockMin').', 1, 0))
					FROM '.$poc_table.'
					WHERE (ProductId = '.$object->GetID().') AND (Availability = 1)';
			$stock_available = $this->Conn->GetOne($sql) > 0; // at least one option combination present
		}
		else {
		$stock_available = $object->GetDBField('QtyInStock') > $object->GetDBField('QtyInStockMin');
		}

		$prod_backordering = $object->GetDBField('BackOrder');

		if ($stock_available) return true;

		// stock is NOT available:
		if (!$backordering || $prod_backordering == 0) return false; // if backordering is generaly disabled or disabled for product (Never)

		// backordering enabled; (auto or always mode)
		return true;
	}

	function IsSubscription($params)
	{
		$object = &$this->Application->recallObject($this->getPrefixSpecial());
		return ($object->GetDBField('Type') == 2);
	}

	function IsTangible($params)
	{
		$object = &$this->Application->recallObject($this->getPrefixSpecial());
		return ($object->GetDBField('Type') == 1);
	}

	function HasFiles($params)
	{
		$sql = 'SELECT COUNT(FileId) FROM '.$this->Application->getUnitOption('file', 'TableName').'
				WHERE ProductId = '.$this->Application->GetVar('p_id').' AND Status = 1';
		return $this->Conn->GetOne($sql) ? 1 : 0;
	}

	function UniqueFileName($params)
	{
		$file_object =& $this->Application->recallObject('file.downl');
		return ($file_object->GetDBField('Name') &&
				$file_object->GetDBField('Name') != $file_object->GetDBField('FilePath'))
			? 1 : 0;
	}

	function FileDownload($params)
	{
		$file_id = $this->Application->GetVar('file.downl_id');
		$product_id =	$file_id ? $this->Conn->GetOne('SELECT ProductId
														FROM '.$this->Application->getUnitOption('file', 'TableName').'
														WHERE FileId = '.$file_id) :
						$this->Application->GetVar($this->getPrefixSpecial().'_id');

		$download_helper_class = $this->Application->getUnitOption($this->Prefix, 'DownloadHelperClass');

		if (!$download_helper_class) {
			$download_helper_class = 'DownloadHelper';
		}
		$download_helper =& $this->Application->recallObject($download_helper_class);
		if (!$download_helper->CheckAccess($file_id, $product_id)) {
			$this->Application->ApplicationDie('File Access permission check failed!');
		}
		$file_info = $download_helper->SendFile($file_id, $product_id);
		$download_helper->LogDownload($product_id, $file_info);

		define('DBG_SKIP_REPORTING', 1);
		$this->Application->ApplicationDie();
	}

	function PictureLink($params)
	{
		if (getArrayValue($params, 'picture_list')) {
			$params['img_id'] = $this->Application->GetVar('img_id');
			$params['pass'] = 'all,p,img';
			unset($params['picture_list']);
		}
		else {
			$params['pass'] = 'all,p';
		}
		return $this->Application->ProcessParsedTag('m', 'Link', $params);
	}

	function ShouldListOptions($params)
	{
		$object =& $this->getObject($params);

		$req_filter = '';
		if (getArrayValue($params, 'required_only')) {
			$req_filter = ' AND Required = 1';
		}

		$query = 'SELECT COUNT(*) FROM '.TABLE_PREFIX.'ProductOptions WHERE ProductId = '.$object->GetID().$req_filter;
		$res = $this->Conn->GetOne($query);
		return $res > 0;
	}

	function CountOptions($params)
	{
		$object =& $this->getObject($params);

		$query = 'SELECT COUNT(*) FROM '.TABLE_PREFIX.'ProductOptions WHERE ProductId = '.$object->GetID();
		$res = $this->Conn->GetOne($query);

		$max = $this->SelectParam($params, 'greater');
		if (!$max) $max = 0;

		return $res > $max;
	}

	function OptionsUpdateMode($params)
	{
		return $this->Application->GetVar('orditems_id') !== false;
	}

	function OptionsHaveError($params)
	{
		return $this->Application->GetVar('opt_error') > 0;
	}

	function OptionsError($params)
	{
		switch ($this->Application->GetVar('opt_error')) {
			case 1:
				return $this->Application->Phrase($params['required']);
			case 2:
				return $this->Application->Phrase($params['not_available']);
		}
	}

	function ListShippingTypes($params)
	{
		$quote_engine_collector =& $this->Application->recallObject('ShippingQuoteCollector');
		/* @var $quote_engine_collector ShippingQuoteCollector */

		$types = $quote_engine_collector->GetAvailableShippingTypes();

		$object =& $this->getObject($params);
		$selected = $object->GetDBField('ShippingLimitation');
		$selected = explode('|', substr($selected, 1, -1));

		$o = '';
		foreach ($types as $a_type)
		{
			$is_selected = in_array($a_type['_Id'], $selected);
			$continue = $params['mode'] == 'selected' ? !$is_selected : $is_selected;
			if ($continue) continue;
			$block_params = $a_type;
			$block_params['name']	= $params['render_as'];
			$o .= $this->Application->ParseBlock($block_params);
		}
		return $o;
	}

	function PageLink($params)
	{
		$manufacturer_id = $this->Application->GetVar('manuf_id');
		if ($manufacturer_id) {
			$params['pass'] = 'm,'.$this->getPrefixSpecial().',manuf';
		}

		return parent::PageLink($params);
	}

	/**
	 * Calculate savings based on price & market price relationship
	 *
	 * @param Array $params
	 * @return int
	 */
	function Savings($params)
	{
		$object =& $this->getObject($params);
		/* @var $object kDBItem */

		$price = $object->GetDBField('Price');
		$msrp = $object->GetDBField('MSRP');

		$value = 0;
		if (isset($params['type']) && ($params['type'] == 'percent')) {
			if ($msrp > 0) {
				return 100 - round($price * 100 / $msrp);
			}
		}
		else {
			if ($msrp > $price) {
				$value = $msrp - $price;
			}
		}

		if (isset($params['currency'])) {
			$lang =& $this->Application->recallObject('lang.current');
			/* @var $lang LanguagesItem */

			$iso = $this->GetISO($params['currency']);
			$value = $this->ConvertCurrency($value, $iso);
			$value = $lang->formatNumber( sprintf('%.2f', $value) );
			$value = $this->AddCurrencySymbol($value, $iso);
		}

		return $value;
	}

	/**
	 * Hides permission tab, when it's not allowed by configuration settings
	 *
	 * @param Array $params
	 */
	function ModifyUnitConfig($params)
	{
		$edit_tab_presets = $this->Application->getUnitOption($this->Prefix, 'EditTabPresets');
		$edit_tab_preset = $edit_tab_presets['Default'];

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

		$product_type = $object->GetDBField('Type');

		if ($product_type != PRODUCT_TYPE_TANGIBLE) {
			unset($edit_tab_preset['inventory']);
		}

		if ($product_type == PRODUCT_TYPE_SUBSCRIPTION) {
			unset($edit_tab_preset['options']);
		}
		else {
			unset($edit_tab_preset['access_and_pricing']);
		}

		if ($product_type != PRODUCT_TYPE_TANGIBLE && $product_type != PRODUCT_TYPE_PACKAGE) {
			unset($edit_tab_preset['pricing']);
		}
		else {
			unset($edit_tab_preset['pricing2']);
		}

		if ($product_type != PRODUCT_TYPE_DOWNLOADABLE) {
			unset($edit_tab_preset['files_and_pricing']);
		}

		if ($product_type != PRODUCT_TYPE_PACKAGE) {
			unset($edit_tab_preset['package_content']);
		}

		$edit_tab_presets['Default'] = $edit_tab_preset;
		$this->Application->setUnitOption($this->Prefix, 'EditTabPresets', $edit_tab_presets);
	}
}