AnonSec Shell
Server IP : 54.36.91.62  /  Your IP : 216.73.217.112
Web Server : Apache
System : Linux webm013.cluster127.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
User : coopiak ( 151928)
PHP Version : 8.3.23
Disable Function : _dyuweyrj4,_dyuweyrj4r,dl
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/coopiak/amisdesseniors-fr/brest/components/com_djcatalog2/models/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /home/coopiak/amisdesseniors-fr/brest/components/com_djcatalog2/models/item.php
<?php
/**
 * @package DJ-Catalog2
 * @copyright Copyright (C) DJ-Extensions.com, All rights reserved.
 * @license http://www.gnu.org/licenses GNU/GPL
 * @author url: http://dj-extensions.com
 * @author email contact@dj-extensions.com
 *
 */

defined('_JEXEC') or die('Restricted access');
use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;
use Joomla\Utilities\IpHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\MVC\Model\FormModel;
use Joomla\CMS\Date\Date;
jimport('joomla.application.component.modelform');

require_once(JPATH_ROOT . '/components/com_djcatalog2/helpers/theme.php');
require_once(JPATH_ROOT . '/components/com_djcatalog2/helpers/price.php');

class DJCatalog2ModelItem extends FormModel
{

	protected $view_item = 'item';
	protected $_item = null;
	protected $_context = 'com_djcatalog2.item';
	protected $_related = array();
	protected $_attributes = array();
	protected $_cart_attributes = array();
	protected $_children = array();
	protected $_combinations = array();
	protected $_customisations = array();
	protected $_price_tiers = array();

	public $childrenModel = null;

	protected function populateState()
	{
		$app = Factory::getApplication('site');

		// Load state from the request.
		$pk = $app->input->getInt('id');
		$this->setState('item.id', $pk);

		$user = Djcatalog2Helper::getUserProfile($app->getUserState('com_djcatalog2.checkout.user_id', null));
		if (isset($user->customer_group_id)) {
			$this->setState('filter.customergroup', $user->customer_group_id);
		}

		// Load the parameters.
		$params = $app->getParams();
		$this->setState('params', $params);

	}

	public function getForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_djcatalog2.contact', 'contact', array('control' => 'jform', 'load_data' => true));
		if (empty($form)) {
			return false;
		}

		$params = ComponentHelper::getParams('com_djcatalog2');

		$user = Factory::getUser();
		if ($user->id > 0) {
			if ($form->getValue('contact_email') == '') {
				$form->setFieldAttribute('contact_email', 'default', $user->email);
			}
			if ($form->getValue('contact_name') == '') {
				$form->setFieldAttribute('contact_name', 'default', $user->name);
			}
		}

		$subject = @$this->getItem()->name;
		if ($subject && $form->getValue('contact_subject') == '') {
			$form->setFieldAttribute('contact_subject', 'default', $subject);
		}

		return $form;
	}

	protected function preprocessForm(Joomla\CMS\Form\Form $form, $data, $group = 'content')
	{
		$app = Factory::getApplication();
		$params = ComponentHelper::getParams('com_djcatalog2');
		$db = Factory::getDbo();

		$user = Factory::getUser();
		$language = Factory::getApplication()->getLanguage();

		$switchable_fields = array('contact_phone', 'contact_street', 'contact_city', 'contact_zip', 'contact_country', 'contact_state', 'contact_company_name', 'contact_gdpr_policy', 'contact_gdpr_agreement', 'contact_email_copy');
		foreach ($switchable_fields as $field_name) {
			if ($field_name == 'contact_gdpr_policy') {
				$policy_info = Text::sprintf('COM_DJCATALOG2_GDPR_POLICY_AGREE', $app->get('sitename'));
				if (trim((string)$params->get('contact_gdpr_policy_info_field')) != '') {
					$policy_info = $params->get('contact_gdpr_policy_info_field');
					if ($language->hasKey($policy_info)) {
						$policy_info = Text::_($policy_info);
					}
				}
				$form->setFieldAttribute($field_name, 'label', $policy_info);
			} else if ($field_name == 'contact_gdpr_agreement') {
				$agreement_info = Text::sprintf('COM_DJCATALOG2_GDPR_AGREE', $app->get('sitename'));
				if (trim((string)$params->get('contact_gdpr_agreement_info_field')) != '') {
					$agreement_info = $params->get('contact_gdpr_agreement_info_field');
					if ($language->hasKey($agreement_info)) {
						$agreement_info = Text::_($agreement_info);
					}
				}
				$form->setFieldAttribute($field_name, 'label', $agreement_info);
			}
			if ($params->get($field_name . '_field', '0') == '0') {
				$form->removeField($field_name);
			} else if ($params->get($field_name . '_field', '0') == '2') {
				$form->setFieldAttribute($field_name, 'required', 'true');
				$form->setFieldAttribute($field_name, 'class', $form->getFieldAttribute($field_name, 'class') . ' required');
			}
		}

		if ($params->get('contact_country_field') == '0' && (int)$params->get('contact_state_field') > 0) {
			$query = $db->getQuery(true);
			$query->select('id')->from('#__djc2_countries')->where('is_default=1');
			$db->setQuery($query);
			$default_country = $db->loadResult();
			if ($default_country > 0) {
				$form->setFieldAttribute('contact_state', 'country', $default_country);
			}
		}

		$plugin = Factory::getApplication()->getParams()->get('contact_captcha', Factory::getConfig()->get('captcha'));
		if ($user->id > 0 || ($plugin === 0 || $plugin === '0' || $plugin === '' || $plugin === null)) {
			$form->removeField('captcha');
		} else {
			Factory::getApplication()->getParams()->set('captcha', $plugin);
		}
	}

	protected function loadFormData()
	{
		$data = (array)Factory::getApplication()->getUserState('com_djcatalog2.contact.data', array());
		return $data;
	}

	public function &getItem($pk = null)
	{
		// Initialise variables.
		$pk = (!empty($pk)) ? $pk : (int)$this->getState('item.id');

		$price_group_filter = $this->getState('filter.customergroup', false);

		if ($this->_item === null) {
			$this->_item = array();
		}

		$bound = true;
		if (!isset($this->_item[$pk])) {
			try {
				$db = Factory::getDbo();
				$query = $db->getQuery(true);

				//$attributes = $this -> getAttributes();

				$query->select('i.*, CASE WHEN (i.special_price > 0.0 AND i.special_price < i.price) THEN i.special_price ELSE i.price END as final_price');
				$query->from('#__djc2_items as i');

				$query->select('c.id as _category_id, c.name as category, c.published as publish_category, c.alias as category_alias');
				$query->join('left', '#__djc2_categories AS c ON c.id = i.cat_id');

				$query->select('p.id as _producer_id, p.name as producer, p.published as publish_producer, p.alias as producer_alias');
				$query->join('left', '#__djc2_producers AS p ON p.id = i.producer_id');

				$query->select('ua.name AS author, ua.email AS author_email');
				$query->join('left', '#__users AS ua ON ua.id = i.created_by');

				$query->select('gc.price as group_price, gc.available as group_available');
				$query->join('left', '#__djc2_prices AS gc ON gc.item_id = i.id AND gc.group_id=' . (int)$price_group_filter);

				$query->select('countries.country_name, countries.id as item_country_id');
				$query->join('left', '#__djc2_countries AS countries ON countries.id = i.country');

				$query->select('states.name as state_name');
				$query->join('left', '#__djc2_countries_states AS states ON states.id = i.state');

				$query->select('ROUND(v.rating_sum / v.rating_count, 0) AS rating, v.rating_count as rating_count');
				$query->join('LEFT', '#__djc2_item_rating AS v ON i.id = v.item_id');

				$nullDate = $db->quote($db->getNullDate());
				$date = Factory::getDate();
				$nowDate = $db->quote($date->toSql());

				$query->where('i.id =' . (int)$pk);
				$query->where('(i.publish_up IS NULL OR i.publish_up = ' . $nullDate . ' OR i.publish_up <= ' . $nowDate . ')');
				$query->where('(i.publish_down IS NULL OR i.publish_down = ' . $nullDate . ' OR i.publish_down >= ' . $nowDate . ')');


				$query->group('i.id');
				//echo str_replace('#_','jos',$query).'<br/>';die();
				$db->setQuery($query);
				$item = $db->loadObject();

				if (empty($item)) {
					return false;
				}

				$item->slug = (empty($item->alias)) ? $item->id : $item->id . ':' . $item->alias;
				$item->catslug = (empty($item->category_alias)) ? $item->cat_id : $item->cat_id . ':' . $item->category_alias;
				$item->prodslug = (empty($item->producer_alias)) ? $item->producer_id : $item->producer_id . ':' . $item->producer_alias;

				if ($item->group_price > 0) {
					if ($item->special_price > 0 && $item->special_price < $item->group_price) {
						$item->price = $item->group_price;
						$item->final_price = $item->special_price;
					} else {
						$item->price = $item->final_price = $item->group_price;
					}
				}
				$allPriceRules = Djcatalog2HelperPrice::getAllPriceRules();
				$price_rule_start_date = $db->getNullDate();
				$promotion_start_date = $db->getNullDate();
				if (!empty($allPriceRules['each_item'])) {
					$today = Factory::getDate()->toSql();
					foreach ($allPriceRules['each_item'] as $price_rule_key => $price_rule_item) {
						if (($today >= $price_rule_item->start_date) && ($today<= $price_rule_item->expire_date)) {
							if (in_array($item->id, $price_rule_item->product_id)) {
								if (empty($price_rule_item->excluded_product_id)) {
									if (Factory::getDate($price_rule_item->start_date)->toSql() >= $price_rule_start_date) {
										$price_rule_start_date = Factory::getDate($price_rule_item->start_date)->toSql();
									}
								}else{
									if (!in_array($item->id, $price_rule_item->excluded_product_id)) {
										if (Factory::getDate($price_rule_item->start_date)->toSql() >= $price_rule_start_date) {
											$price_rule_start_date = Factory::getDate($price_rule_item->start_date)->toSql();
										}
									}
								}
							}

							if (in_array($item->cat_id, $price_rule_item->category_id)) {
								if (Factory::getDate($price_rule_item->start_date)->toSql() >= $price_rule_start_date) {
									$price_rule_start_date = Factory::getDate($price_rule_item->start_date)->toSql();
								}
							}

							if (in_array($item->producer_id, $price_rule_item->producer_id)) {
								if (Factory::getDate($price_rule_item->start_date)->toSql() >= $price_rule_start_date) {
									$price_rule_start_date = Factory::getDate($price_rule_item->start_date)->toSql();
								}
							}
						}
					}
				}

				$params = Djcatalog2Helper::getParams();
				$product_days_in_sold_start = (int) $params->get('cron_avg_prices_delay',30);
				$product_create_date = Factory::getDate($item->created);
				$products_days_in_sold = (date_diff($product_create_date,Factory::getDate()))->days;
				$item->is_promotion = false;

				if ((float) $item->special_price >= (float) 0) {
					//Promocja poprzez ustawienie ceny promocyjnej i poprzez ustawienie reguły cenowej
					$today = Factory::getDate()->toSql();
					if ( (float) $item->special_price < (float) $item->price) {
						if (!empty($item->start_promotion) && (!empty($item->end_promotion))) {
							if (($today >= $item->start_promotion) && ($today<= $item->end_promotion)) {
								$promotion_start_date = $item->start_promotion;
							}
						}
					}

					if ($price_rule_start_date != $db->getNullDate()) {
						if ($price_rule_start_date > $promotion_start_date) {
							$promotion_start_date = $price_rule_start_date;
						}
					}

					if ($promotion_start_date != $db->getNullDate()) {
						$item->is_promotion = true;
						if ($products_days_in_sold <= $product_days_in_sold_start) {
							$min_price = $this->getMinPriceBeforePromotion((int) $pk, $product_create_date);
							if ($min_price) {
								$item->avg_price = (float) $min_price;
							}else{
								$item->avg_price = (float) $item->price;
							}
						}else{
							$min_price = $this->getMinPriceBeforePromotion((int) $pk, $promotion_start_date);
							if ($min_price) {
								$item->avg_price = (float) $min_price;
							}else{
								$item->avg_price = (float) $item->price;
							}
						}
					}
				}else{
					//Promocja poprzez reguły cenowe
					if ($price_rule_start_date != $db->getNullDate()) {
						$item->is_promotion = true;

						if ($products_days_in_sold <= $product_days_in_sold_start) {
							$min_price = $this->getMinPriceBeforePromotion((int) $pk, $product_create_date);
							if ($min_price) {
								$item->avg_price = (float) $min_price;
							}else{
								$item->avg_price = (float) $item->price;
							}
						}else{
							$min_price = $this->getMinPriceBeforePromotion((int) $pk, $price_rule_start_date);
							if ($min_price) {
								$item->avg_price = (float) $min_price;
							}else{
								$item->avg_price = (float) $item->price;
							}
						}

					}
				}
				$item->available_default = $item->available;
				if ($item->group_available != -1 && !is_null($item->group_available)) {
					$item->available = $item->group_available;
				}

				$categories = Djc2Categories::getInstance();

				$mainCategory = $categories->get($item->cat_id);
				$params = new Registry($item->params);
				if (!empty($mainCategory)) {
					$categoryParams = $mainCategory->getParams();
					$categoryParams->merge($params);
					$params = clone $categoryParams;
				}
				$item->params = $params;
				if (trim((string)$item->config_conditions) == '' || $item->config_conditions == '{}') {
					$item->config_conditions = false;
				} else {
					try {
						$cfgCond = json_decode((string)$item->config_conditions);
					} catch (Exception $e) {
						$item->config_conditions = false;
					}

					if ($cfgCond != false) {
						$item->config_conditions = $this->parseConfigConditions($cfgCond);
					} else {
						$item->config_conditions = false;
					}
				}

				if ($item->parent_id > 0) {
					$item->parent = $this->getItem($item->parent_id);
					if ($item->parent) {
						$item->name = $item->parent->name . ' - ' . $item->name;
					}
				}
				if (trim((string)$item->config_dimensions) == '' || $item->config_dimensions == '{}') {
					$item->config_dimensions = false;
				} else {
					$item->config_dimensions = json_decode((string)$item->config_dimensions, true);
				}

				if (trim((string)$item->config_dimensions_settings) == '' || $item->config_dimensions_settings == '{}') {
					$item->config_dimensions_settings = [
						'min_width' => '',
						'min_height' => '',
						'min_length' => '',
						'max_width' => '',
						'max_height' => '',
						'max_length' => '',
					];
				} else {
					$item->config_dimensions_settings = json_decode((string)$item->config_dimensions_settings, true);
				}
				$user_currency_id = Factory::getApplication()->getUserState('com_djcatalog2.checkout.currency');

				if ($user_currency_id > 0) {
					$item->avg_price = Djcatalog2HelperPrice::currencyExchange($item->avg_price);
				}


				$this->_item[$pk] = $item;
				$bound = false;
			} catch (JException $e) {
				$this->setError($e);
				$this->_item[$pk] = false;
			}

		}
		if ($this->_item[$pk] && !$bound) {
			$this->bindAttributes($pk);
		}

		if (!$this->_item[$pk]->sections_source) {
			$this->_item[$pk]->sections = $this->getSectionByCategory($this->_item[$pk]->cat_id);
		}

		if (!isset($this->_item[$pk]->calculator) && $this->_item[$pk]->calculator_id) {

			$this->_item[$pk]->calculator = CalculatorHelper::getInstance($this->_item[$pk]->calculator_id);

		}



		return $this->_item[$pk];

	}
	function getMinPriceBeforePromotion($item_id, $promotion_start_date) {
		$params = Djcatalog2Helper::getParams();
		$pricesDateFrom = Factory::getDate($promotion_start_date);
		$pricesDateTo = Factory::getDate($promotion_start_date)->modify('-'.(int) $params->get('cron_avg_prices_delay',30).' day');
		$db = Factory::getDbo();
		$query = $db->getQuery(true);
		$query->select('min(price) as min_price')
			->from($db->quoteName('#__djc2_items_avg_prices'))
			->where($db->quoteName('item_id') . ' = ' . (int) $item_id)
			->andWhere('combination_id = 0')
			->andWhere($db->quoteName('date') . ' >= ' . $db->quote($pricesDateTo))
			->andWhere($db->quoteName('date') . ' <=' . $db->quote($pricesDateFrom));

		$db->setQuery($query);
		$results = $db->loadObject();
		if ($results) {
			if ($results->min_price) {
				return (float) $results->min_price;
			}else{
				return null;
			}
		}
	}

	private function getSectionByCategory($cat_id)
	{
		$db = Factory::getDbo();
		$query = $db->getQuery(true);

		$query->select('sections');
		$query->from($db->quoteName('#__djc2_categories'));
		$query->where($db->quoteName('id') . ' = ' . (int)$cat_id);

		$db->setQuery($query);

		return $db->loadResult();
	}

	function getRelatedItems($pk = null)
	{
		$pk = (!empty($pk)) ? $pk : (int)$this->getState('item.id');

		if (empty($this->_related[$pk])) {
			$params = $this->getState('params', Djcatalog2Helper::getParams());

			$filter_order = $params->get('related_items_default_order', 'i.ordering');
			$filter_order_Dir = $params->get('related_items_default_order_dir', 'asc');
			$filter_featured = $params->get('related_featured_first', 0);

			if ($params->get('related_items_count', 2) == 0) {
				$this->_related[$pk] = array();
				return $this->_related[$pk];
			}

			$db = Factory::getDbo();
			$query = $db->getQuery(true);
			$query->select('related_item');
			$query->from('#__djc2_items_related');
			$query->where('item_id=' . (int)$pk);
			$db->setQuery($query);

			$ids = $db->loadColumn();

			if (empty($ids)) {
				$this->_related[$pk] = array();
				return $this->_related[$pk];
			}

			$model = BaseDatabaseModel::getInstance('Items', 'Djcatalog2Model', array('ignore_request' => true));
			$state = $model->getState();

			$model->setState('params', $params);

			$model->setState('list.start', 0);
			$model->setState('list.limit', $params->get('related_items_count', 2));

			$model->setState('filter.catalogue', false);
			$model->setState('list.ordering_featured', $filter_featured);
			$model->setState('list.ordering', $filter_order);
			$model->setState('list.direction', $filter_order_Dir);
			$model->setState('filter.item_ids', $ids);
			$model->setState('list.fields_visibility', '*');

			$items = $model->getItems();
			$this->_related[$pk] = array_values($items);
		}
		return $this->_related[$pk];
	}

	/*function getAttributes() {
	 if (empty($this->_attributes)) {
	 $db = Factory::getDbo();
	 $query = $db->getQuery(true);
	 $query->select('f.*, group_concat(fo.id separator \'|\') as options, g.name as group_name, g.label as group_label, g.id as fgroup_id');
	 $query->from('#__djc2_items_extra_fields as f');
	 $query->join('LEFT', '#__djc2_items_extra_fields_options as fo ON fo.field_id=f.id');
	 $query->join('LEFT', '#__djc2_items_extra_fields_groups as g ON g.id=f.group_id');

	 $query->where('(f.visibility = 1 or f.visibility = 3) and f.published = 1');
	 $query->where('(f.cart_variant = 0 OR f.cart_variant = 2)');
	 $query->group('f.id');
	 $query->order('IFNULL(g.ordering,0) asc , g.ordering asc, f.ordering asc');
	 $db->setQuery($query);

	 $this->_attributes = $db->loadObjectList();
	 }

	 return $this->_attributes;
	 }*/

	function getAttributes()
	{
		if (empty($this->_attributes)) {
			$db = Factory::getDbo();

			$query = $db->getQuery(true);
			//$query->select('f.*, group_concat(fo.id separator \'|\') as options, g.name as group_name, g.label as group_label, g.id as fgroup_id');
			$query->select('f.*, g.name as group_name, g.label as group_label, g.id as fgroup_id');
			$query->from('#__djc2_items_extra_fields as f');
			//$query->join('LEFT', '#__djc2_items_extra_fields_options as fo ON fo.field_id=f.id');
			$query->join('LEFT', '#__djc2_items_extra_fields_groups as g ON g.id=f.group_id');

			$query->where('(f.visibility = 1 or f.visibility = 3) and f.published = 1');
			$query->where('(f.cart_variant = 0 OR f.cart_variant = 2)');

			$query->order('IFNULL(g.ordering,0) asc , g.ordering asc, f.ordering asc');
			$db->setQuery($query);

			$this->_attributes = $db->loadObjectList('id');

			if (count($this->_attributes)) {
				$query = $db->getQuery(true);
				$query->select('*');
				$query->from('#__djc2_items_extra_fields_options');
				$query->where('field_id in (' . implode(',', array_keys($this->_attributes)) . ')');
				$query->order('field_id asc, ordering asc');

				$db->setQuery($query);
				$optionslist = $db->loadObjectList();

				foreach ($this->_attributes as $field_id => $field) {
					$field_options = array();
					$field_optionValues = array();
					$field_optionParams = array();

					foreach ($optionslist as $k => $option) {
						if ($option->field_id == $field_id) {
							$field_options[] = $option->id;
							$field_optionValues[$option->id] = $option->value;
							$field_optionParams[$option->id] = new Registry($option->params);

						}
					}

					$this->_attributes[$field_id]->options = $field_options;//implode('|', $field_options);
					$this->_attributes[$field_id]->optionValues = $field_optionValues;//implode('|', $field_optionValues);
					$this->_attributes[$field_id]->optionParams = $field_optionParams;
				}
			}
		}

		return $this->_attributes;
	}

	function getAttributeById($fid)
	{
		$attrs = $this->getAttributes();
		if (isset($attrs[$fid])) {
			return $attrs[$fid];
		}
		return false;
	}

	function getCartAttributes()
	{
		if (empty($this->_cart_attributes)) {
			$db = Factory::getDbo();

			$query = $db->getQuery(true);
			//$query->select('f.*, group_concat(fo.id separator \'|\') as options, g.name as group_name, g.label as group_label, g.id as fgroup_id');
			$query->select('f.*, g.name as group_name, g.label as group_label, g.id as fgroup_id');
			$query->from('#__djc2_items_extra_fields as f');
			//$query->join('LEFT', '#__djc2_items_extra_fields_options as fo ON fo.field_id=f.id');
			$query->join('LEFT', '#__djc2_items_extra_fields_groups as g ON g.id=f.group_id');
			$query->where('(f.cart_variant=1 OR f.cart_variant=2) and f.published = 1');
			$query->order('IFNULL(g.ordering,0) asc , g.ordering asc, f.ordering asc');
			$db->setQuery($query);

			$this->_cart_attributes = $db->loadObjectList('id');

			if (count($this->_cart_attributes)) {
				$query = $db->getQuery(true);
				$query->select('*');
				$query->from('#__djc2_items_extra_fields_options');
				$query->where('field_id in (' . implode(',', array_keys($this->_cart_attributes)) . ')');
				$query->order('field_id asc, ordering asc');

				$db->setQuery($query);
				$optionslist = $db->loadObjectList();

				foreach ($this->_cart_attributes as $field_id => $field) {
					$field_options = array();
					$field_optionValues = array();
					$field_optionParams = array();

					foreach ($optionslist as $k => $option) {
						if ($option->field_id == $field_id) {
							$field_options[] = $option->id;
							$field_optionValues[$option->id] = $option->value;
							$field_optionParams[$option->id] = new Registry($option->params);

						}
					}

					$this->_cart_attributes[$field_id]->options = $field_options;//implode('|', $field_options);
					$this->_cart_attributes[$field_id]->optionValues = $field_optionValues;//implode('|', $field_optionValues);
					$this->_cart_attributes[$field_id]->optionParams = $field_optionParams;
				}
			}
		}

		return $this->_cart_attributes;
	}

	function getCartVariants()
	{
		$item = $this->getItem();
		$combinations = $this->getCombinations($item->id);
		$cart_attributes = $this->getCartAttributes();

		foreach ($cart_attributes as $key => &$cartField) {
			$cartField->_variantData = null;

			$variantData = new stdClass();

			$variantData->options = $cartField->options;
			$variantData->optionValues = $cartField->optionValues;
			$variantData->optionParams = $cartField->optionParams;

			$variantData->availableOptions = array();
			$variantData->optionCombinations = array();

			$cartField->_combinations = array();

			if ($cartField->cart_variant == 2) {
				$itemKey = '_ef_' . $cartField->alias;
				if (isset($item->$itemKey) && !empty($item->$itemKey) && is_array($item->$itemKey)) {
					$variantData->availableOptions = array_keys($item->$itemKey);
				}
			}

			$cartField->_variantData = $variantData;

		}
		unset($cartField);

		foreach ($combinations as $combination_id => &$combination) {
			if (!isset($combination->fields)) continue;
			foreach ($combination->fields as $field_id => $field) {
				if (!isset($cart_attributes[$field_id])) {
					continue;
				}

				$cart_attributes[$field_id]->_combinations[] = &$combination;

				if (!in_array($field->value, $cart_attributes[$field_id]->_variantData->availableOptions)) {
					$cart_attributes[$field_id]->_variantData->availableOptions[] = $field->value;
				}

				if (!isset($cart_attributes[$field_id]->_variantData->optionCombinations[$field->value])) {
					$cart_attributes[$field_id]->_variantData->optionCombinations[$field->value] = array();
				}
				$cart_attributes[$field_id]->_variantData->optionCombinations[$field->value][] = $combination->id;
			}
		}
		unset($combination);

		foreach ($cart_attributes as $k => $v) {
			if (count($v->_variantData->availableOptions) < 1) {
				unset($cart_attributes[$k]);
			}
		}

		//echo '<pre>'.print_r($cart_attributes,true).'</pre>';
		/*echo '<br />-------<br />';
		 echo '<pre>'.print_r($item,true).'</pre>';
		 echo '<pre>'.print_r($children,true).'</pre>';
		 echo '<br />-------<br />';
		 die();
		 */

		return $cart_attributes;
	}

	function bindAttributes($id)
	{
		if (!empty($this->_item[$id])) {
			$db = Factory::getDbo();

			$query = $db->getQuery(true);
			$query->select('category_id')->from('#__djc2_items_categories')->where('item_id=' . (int)$id);
			$db->setQuery($query);
			$this->_item[$id]->_categories_ids = $db->loadColumn();

			$query = $db->getQuery(true);
			$query->select('*')->from('#__djc2_item_reviews')->where('item_id=' . (int)$id);

			// TODO there should be pagination here or controllable limit
			$db->setQuery($query, 0, 100);
			$this->_item[$id]->_reviews = $db->loadObjectList();

			$query_cf = $db->getQuery(true);
			$query_int = $db->getQuery(true);
			$query_text = $db->getQuery(true);
			$query_date = $db->getQuery(true);

			$query_cf->select('fields.alias, fields.type, fields.ordering, fieldvalues.item_id, fieldvalues.field_id, fieldvalues.id as value_id, fieldoptions.id as option_id, fieldoptions.value, fieldoptions.params as option_params');
			$query_cf->from('#__djc2_items_extra_fields_values_int as fieldvalues');
			$query_cf->join('inner', '#__djc2_items as items on items.id=fieldvalues.item_id');
			$query_cf->join('inner', '#__djc2_items_extra_fields as fields ON fields.id = fieldvalues.field_id');
			$query_cf->join('left', '#__djc2_items_extra_fields_options as fieldoptions ON fieldoptions.id = fieldvalues.value AND fieldoptions.field_id = fields.id');
			$query_cf->where('fieldvalues.item_id=' . $id . ' AND fields.cart_variant=2 AND fields.published = 1');
			$query_cf->order('fields.ordering asc, fieldoptions.ordering asc');

			$query_int->select('fields.alias, fields.type, fields.ordering, fieldvalues.item_id, fieldvalues.field_id, fieldvalues.id as value_id, fieldoptions.id as option_id, fieldoptions.value, fieldoptions.params as option_params');
			$query_int->from('#__djc2_items_extra_fields_values_int as fieldvalues');
			$query_int->join('inner', '#__djc2_items as items on items.id=fieldvalues.item_id');
			$query_int->join('inner', '#__djc2_items_extra_fields as fields ON fields.id = fieldvalues.field_id');
			$query_int->join('left', '#__djc2_items_extra_fields_options as fieldoptions ON fieldoptions.id = fieldvalues.value AND fieldoptions.field_id = fields.id');
			$query_int->where('fieldvalues.item_id=' . $id . ' AND (fields.visibility = 1 OR fields.visibility = 3) AND fields.published = 1');
			$query_int->order('fields.ordering asc, fieldoptions.ordering asc');

			$query_text->select('fields.alias, fields.type, fields.ordering, fieldvalues.item_id, fieldvalues.field_id, fieldvalues.id as value_id, 0 as option_id, fieldvalues.value');
			$query_text->from('#__djc2_items_extra_fields_values_text as fieldvalues');
			$query_text->join('inner', '#__djc2_items as items on items.id=fieldvalues.item_id');
			$query_text->join('inner', '#__djc2_items_extra_fields as fields ON fields.id = fieldvalues.field_id');
			$query_text->where('fieldvalues.item_id=' . $id . ' AND (fields.visibility = 1 OR fields.visibility = 3) AND fields.published = 1');

			$query_date->select('fields.alias, fields.type, fields.ordering, fieldvalues.item_id, fieldvalues.field_id, fieldvalues.id as value_id, 0 as option_id, fieldvalues.value');
			$query_date->from('#__djc2_items_extra_fields_values_date as fieldvalues');
			$query_date->join('inner', '#__djc2_items as items on items.id=fieldvalues.item_id');
			$query_date->join('inner', '#__djc2_items_extra_fields as fields ON fields.id = fieldvalues.field_id');
			$query_date->where('fieldvalues.item_id=' . $id . ' AND (fields.visibility = 1 OR fields.visibility = 3) AND fields.published = 1');
			$query_date->order('fields.ordering asc');

			$query_labels = $db->getQuery(true);
			$query_labels->select('l.*, li.item_id')->from('#__djc2_labels as l')->join('inner', '#__djc2_labels_items AS li ON li.label_id=l.id');
			$query_labels->where('li.item_id=' . $id);
			$query_labels->order('l.ordering');

			$query_combos = $db->getQuery(true);
			$query_combos->select('COUNT(*)');
			$query_combos->from('#__djc2_items_combinations');
			$query_combos->where('item_id =' . $id);

			$db->setQuery($query_cf);
			$cf_attributes = $db->loadObjectList();
			$db->setQuery($query_int);
			$int_attributes = $db->loadObjectList();
			$db->setQuery($query_text);
			$text_attributes = $db->loadObjectList();
			$db->setQuery($query_date);
			$date_attributes = $db->loadObjectList();

			$db->setQuery($query_labels);
			$labels = $db->loadObjectList();

			$this->_item[$id]->_available_in_groups = null;

			//if (!$this->_item[$id]->available) {
			$query_avail_groups = $db->getQuery(true);
			$query_avail_groups->select('cg.*, p.price, p.available');
			$query_avail_groups->from('#__djc2_customer_groups AS cg');
			$query_avail_groups->join('inner', '#__djc2_prices AS p ON p.group_id=cg.id');
			$query_avail_groups->where('p.item_id = ' . $id);
			$query_avail_groups->where('(p.available = 1 OR p.price > 0.0)');
			$query_avail_groups->order('cg.ordering');
			$db->setQuery($query_avail_groups);

			$avail_groups = $db->loadObjectList();
			if (!empty($avail_groups)) {
				$this->_item[$id]->_available_in_groups = $avail_groups;
			}
			//}

			$db->setQuery($query_combos);
			$this->_item[$id]->combo_count = $db->loadResult();

			foreach ($labels as $label) {
				if (!isset($this->_item[$label->item_id]->_labels)) {
					$this->_item[$label->item_id]->_labels = array();
				}
				$params = new Registry();
				$params->loadString($label->params);
				$label->params = $params;
				$this->_item[$label->item_id]->_labels[] = $label;
			}

			$this->_item[$id]->_extra_fields = array();

			foreach ($text_attributes as $attribute) {
				if ($attribute->item_id == $id) {
					$field = '_ef_' . $attribute->alias;
					$this->_item[$id]->$field = $attribute->value;

					$this->_item[$id]->_extra_fields[$attribute->field_id] = $attribute;
				}
			}
			foreach ($date_attributes as $attribute) {
				if ($attribute->item_id == $id) {
					$field = '_ef_' . $attribute->alias;
					$this->_item[$id]->$field = $attribute->value;

					$this->_item[$id]->_extra_fields[$attribute->field_id] = $attribute;
				}
			}
			foreach ($int_attributes as $attribute) {
				if ($attribute->item_id == $id) {
					$field = '_ef_' . $attribute->alias;
					$param_field = '_efp_' . $attribute->alias;

					if (!isset($this->_item[$id]->$field) || !is_array($this->_item[$id]->$field)) {
						$this->_item[$id]->$field = array();
						$this->_item[$id]->_extra_fields[$attribute->field_id] = array();
					}
					if (!in_array($attribute->value, $this->_item[$id]->$field)) {
						$tmp_arr = $this->_item[$id]->$field;
						$tmp_arr[$attribute->option_id] = $attribute->value;
						$this->_item[$id]->$field = $tmp_arr;
					}

					if (!isset($this->_item[$id]->$param_field) || !is_array($this->_item[$id]->$param_field)) {
						$this->_item[$id]->$param_field = array();
					}

					$tmp_arr = $this->_item[$id]->$param_field;
					$tmp_arr[$attribute->option_id] = new Registry($attribute->option_params);

					$this->_item[$id]->$param_field = $tmp_arr;

					$this->_item[$id]->_extra_fields[$attribute->field_id][] = $attribute;
				}
			}

			$this->_item[$id]->_cart_features = array();

			foreach ($cf_attributes as $attribute) {
				if ($attribute->item_id == $id) {
					$field = '_cf_' . $attribute->alias;
					$param_field = '_cfp_' . $attribute->alias;

					if (!isset($this->_item[$id]->$field) || !is_array($this->_item[$id]->$field)) {
						$this->_item[$id]->$field = array();
					}
					if (!in_array($attribute->value, $this->_item[$id]->$field)) {
						$tmp_arr = $this->_item[$id]->$field;
						$tmp_arr[$attribute->option_id] = $attribute->value;
						$this->_item[$id]->$field = $tmp_arr;

						$this->_item[$id]->_cart_features[] = $attribute->option_id;
					}

					if (!isset($this->_item[$id]->$param_field) || !is_array($this->_item[$id]->$param_field)) {
						$this->_item[$id]->$param_field = array();
					}

					$tmp_arr = $this->_item[$id]->$param_field;
					$tmp_arr[$attribute->option_id] = new Registry($attribute->option_params);

					$this->_item[$id]->$param_field = $tmp_arr;
				}
			}
			$this->_item[$id]->final_price = Djcatalog2HelperPrice::applyPriceRules($this->_item[$id]->final_price, true, 'each_item', $this->_item[$id], 'item');
			$this->_item[$id]->price = Djcatalog2HelperPrice::applyPriceRules($this->_item[$id]->price, false, 'each_item', $this->_item[$id], 'item');

			$this->_item[$id]->_price_tiers = $this->getTierPrices($id);
		}
	}

	public function getNavigation($id, $catid = null, $params = null)
	{
		$db = Factory::getDbo();
		$category_limit = ($catid) ? ' AND i.cat_id=' . $catid : '';

		$orderby = 'c.ordering ASC, i.ordering ASC';

		if (!empty($params)) {
			$filter_order = $params->get('items_default_order', 'i.ordering');
			$filter_order_Dir = $params->get('items_default_order_dir', 'asc');
			$filter_featured = $params->get('featured_first', 0);

			$sortables = array('i.ordering', 'i.name', 'i.created', 'i.price', 'category', 'c.name', 'producer', 'p.name', 'i.id', 'rand()');

			if (!in_array($filter_order, $sortables)) {
				$filter_order = 'i.ordering';
			}

			if ($filter_order_Dir != 'asc' && $filter_order_Dir != 'desc') {
				$filter_order_Dir = 'asc';
			}

			if ($filter_order == 'i.ordering') {
				if ($filter_featured) {
					//$orderby  = ' i.featured DESC, i.ordering '.$filter_order_Dir.', c.ordering '.$filter_order_Dir;
					//$orderby = 'i.featured DESC, c.parent_id asc, c.ordering asc, i.ordering '.$filter_order_Dir;
					if ($params->get('items_category_ordering', '1') != '1') {
						$orderby = ' i.featured DESC, i.ordering ' . $filter_order_Dir . ', c.ordering ' . $filter_order_Dir;
					} else {
						$orderby = 'i.featured DESC, c.parent_id asc, c.ordering asc, i.ordering ' . $filter_order_Dir;
					}
				} else {
					//$orderby  = ' i.ordering '.$filter_order_Dir.', c.ordering '.$filter_order_Dir;
					//$orderby = 'c.parent_id asc, c.ordering asc, i.ordering '.$filter_order_Dir;
					if ($params->get('items_category_ordering', '1') != '1') {
						$orderby = ' i.ordering ' . $filter_order_Dir . ', c.ordering ' . $filter_order_Dir;
					} else {
						$orderby = 'c.parent_id asc, c.ordering asc, i.ordering ' . $filter_order_Dir;
					}
				}
			} else {
				// older version compatibility
				switch ($filter_order) {
					case 'producer':
					{
						$filter_order = 'p.name';
						break;
					}
					case 'category':
					{
						$filter_order = 'c.name';
						break;
					}
					case 'i.price' :
					{
						$filter_order = 'final_price';
						break;
					}
				}
				if ($filter_featured) {
					$orderby = ' i.featured DESC, ' . $filter_order . ' ' . $filter_order_Dir . ' , i.ordering, c.ordering ';
				} else {
					$orderby = ' ' . $filter_order . ' ' . $filter_order_Dir . ' , i.ordering, c.ordering ';
				}
			}
		}

		$app = Factory::getApplication();
		$nullDate = $db->quote($db->getNullDate());
		$date = Factory::getDate();
		$nowDate = $db->quote($date->toSql());

		$ignore_cache = $app->input->get('ic');
		$category = $app->getUserState('com_djcatalog.items.filter.category');
		$producer = $app->getUserState('com_djcatalog.items.filter.producer');

		$user = Factory::getUser();
		$userGroups = implode(',', $user->getAuthorisedViewLevels());


		//TODO
		/*
		 $query = 'SELECT DISTINCT i.id, i.name, i.alias, i.cat_id, c.alias as category_alias, @num := @num + 1 AS position, '
		 .' CASE WHEN (i.special_price > 0.0 AND i.special_price < i.price) THEN i.special_price ELSE i.price END as final_price '
		 .' FROM (SELECT @num := 0) AS n, #__djc2_items AS i '
		 .' LEFT JOIN #__djc2_categories as c ON c.id = i.cat_id '
		 .' LEFT JOIN #__djc2_producers as p ON p.id = i.producer_id '
		 .' WHERE i.published = 1 AND (i.publish_up = ' . $nullDate . ' OR i.publish_up <= ' . $nowDate . ') AND (i.publish_down = ' . $nullDate . ' OR i.publish_down >= ' . $nowDate . ') AND c.published = 1 '.$category_limit
		 .' ORDER BY '. $orderby;
		 */
		$query = 'SELECT k.*, @num := @num + 1 AS position' .
			' FROM (SELECT @num := 0) AS n,' .
			' (SELECT DISTINCT i.id, i.name, i.alias, i.cat_id, c.alias as category_alias,' .
			' CASE WHEN (i.special_price > 0.0 AND i.special_price < i.price) THEN i.special_price ELSE i.price END as final_price' .
			' FROM #__djc2_items AS i ' .
			' LEFT JOIN #__djc2_categories as c ON c.id = i.cat_id ' .
			' LEFT JOIN #__djc2_producers as p ON p.id = i.producer_id ' .
			' WHERE i.parent_id = 0 AND i.published = 1 AND i.access IN (' . $userGroups . ') AND (i.publish_up IS NULL OR i.publish_up = ' . $nullDate . ' OR i.publish_up <= ' . $nowDate . ') AND (i.publish_down IS NULL OR i.publish_down = ' . $nullDate . ' OR i.publish_down >= ' . $nowDate . ') AND c.published = 1 ' . $category_limit;

		if ($ignore_cache) {
			if (intval($category))
				$query .= ' AND i.cat_id = ' . (int)$category;

			if (intval($producer))
				$query .= ' AND i.producer_id = ' . (int)$producer;
		}

		$query .= ' ORDER BY ' . $orderby . ') as k';


		$navigation = array('prev' => null, 'next' => null);

		$db->setQuery('SELECT subq.position FROM (' . $query . ') as subq WHERE subq.id = ' . $id . ' ORDER BY subq.position DESC LIMIT 1');
		$position = $db->loadResult();

		if (!$position) {
			return false;
		}
		//$pos_query = 'SELECT subq.* FROM ('.$query.') as subq WHERE subq.position='.($position - 1).' OR subq.position='.($position + 1).' ORDER BY subq.position ASC';
		//$db->setQuery($pos_query);

		$prev_query = 'SELECT subq.* FROM (' . $query . ') as subq WHERE subq.position < ' . $position . ' ORDER BY subq.position DESC LIMIT 1';
		$next_query = 'SELECT subq.* FROM (' . $query . ') as subq WHERE subq.position > ' . $position . ' ORDER BY subq.position ASC LIMIT 1';

		$db->setQuery($prev_query);
		$prev = $db->loadObject();
		if (!empty($prev) && $prev->id > 0 && $prev->cat_id > 0) {
			$navigation['prev'] = $prev;
			$navigation['prev']->slug = $prev->id . ':' . $prev->alias;
			$navigation['prev']->catslug = $prev->cat_id . ':' . $prev->category_alias;
		}

		$db->setQuery($next_query);
		$next = $db->loadObject();
		if (!empty($next) && $next->id > 0 && $next->cat_id > 0) {
			$navigation['next'] = $next;
			$navigation['next']->slug = $next->id . ':' . $next->alias;
			$navigation['next']->catslug = $next->cat_id . ':' . $next->category_alias;
		}

		//$nav_rows = $db->loadObjectList();
		//echo str_replace('#__', 'j25_', $pos_query);

		/*if (count($nav_rows) > 0) {
		 foreach($nav_rows as $row) {
		 if ($row->position > $position) {
		 $navigation['next'] = $row;
		 $navigation['next']->slug = $row->id.':'.$row->alias;
		 $navigation['next']->catslug = $row->cat_id.':'.$row->category_alias;
		 } else if ($row->position < $position) {
		 $navigation['prev'] = $row;
		 $navigation['prev']->slug = $row->id.':'.$row->alias;
		 $navigation['prev']->catslug = $row->cat_id.':'.$row->category_alias;
		 }
		 }
		 }*/

		return $navigation;
	}

	public function &getChildrenModel()
	{
		if (!$this->childrenModel) {
			BaseDatabaseModel::addIncludePath(JPATH_BASE . '/components/com_djcatalog2/models', 'DJCatalog2Model');
			$this->childrenModel = BaseDatabaseModel::getInstance('Items', 'Djcatalog2Model', array('ignore_request' => true));
		}

		return $this->childrenModel;
	}

	public function getChildren($item_id)
	{
		if ((int)$item_id <= 0) {
			return false;
		}

		if (!isset($this->children[$item_id])) {
			$model = $this->getChildrenModel();

			$state = $model->getState();

			$model->setState('list.start', 0);
			$model->setState('list.limit', 0);
			$model->setState('filter.state', 1);
			$model->setState('filter.catalogue', false);
			$model->setState('filter.parent', $item_id);
			$model->setState('list.ordering', 'i.ordering');
			$model->setState('list.direction', 'asc');
			//$model->setState('list.fields_visibility', 'cart_variant');
			$model->setState('list.fields_visibility', '*');

			$this->children[$item_id] = $model->getItems();
		}

		return $this->children[$item_id];
	}

	public function getCombinations($item_id)
	{
		$db = Factory::getDbo();
		$app = Factory::getApplication();

		$product = $this->getItem($item_id);

		$price_group_filter = 0;
		$user = Djcatalog2Helper::getUserProfile($app->getUserState('com_djcatalog2.checkout.user_id', null));
		if (isset($user->customer_group_id)) {
			$price_group_filter = $user->customer_group_id;
		}
		$query = $db->getQuery(true);
		$query->select('c.*, gc.price as group_price');
		$query->from('#__djc2_items_combinations AS c');
		$query->join('left', '#__djc2_combination_prices AS gc ON gc.combination_id = c.id AND gc.group_id=' . (int)$price_group_filter);
		$query->where('item_id = ' . (int)$item_id);
		$db->setQuery($query);
		$combinations = $db->loadObjectList('id');

		if (count($combinations) > 0) {
			$query = $db->getQuery(true);
			$query->select('cf.*, f.name as field_name, fo.value as field_value, fo.params');
			$query->from('#__djc2_items_combinations_fields AS cf');
			$query->join('left', '#__djc2_items_extra_fields as f ON f.id = cf.field_id');
			$query->join('left', '#__djc2_items_extra_fields_options as fo ON fo.id = cf.value AND fo.field_id = cf.field_id AND fo.field_id = f.id');
			$query->where('cf.combination_id IN (' . implode(',', array_keys($combinations)) . ')');
			$query->order('f.ordering, fo.ordering ASC');
			$db->setQuery($query);

			$fields = $db->loadObjectList();

			foreach ($fields as $field) {

				$field->option_params = new Registry($field->params);

				if (!isset($combinations[$field->combination_id]->fields)) {
					$combinations[$field->combination_id]->fields = array();
				}
				$combinations[$field->combination_id]->fields[$field->field_id] = $field;
			}

			foreach ($combinations as &$combination) {
				if (empty($combination->fields) || !is_array($combination->fields)) continue;

				$combination->images = DJCatalog2ImageHelper::getImages('combination', $combination->id);
				if ($combination->group_price > 0) {
					$combination->price = $combination->group_price;
				}
				$tmpPrice = $combination->price;


				$cart_features = $combination_features = isset($product->_cart_features) ? $product->_cart_features : array();
				foreach ($combination->fields as $field) {
					$combination_features[] = $field->value;
				}

				$product->_cart_features = $combination_features;

				//$combination->price = Djcatalog2HelperPrice::applyPriceRules($tmpPrice, false, 'each_item', $product, 'item');
				if ($tmpPrice > 0.0) {
					if ($tmpPrice > $product->price) {
						$combination->price = Djcatalog2HelperPrice::applyPriceRules($tmpPrice, false, 'each_item', $product, 'item');
					} else {
						$combination->price = Djcatalog2HelperPrice::applyPriceRules($product->price, false, 'each_item', $product, 'item');
					}
				} else {
					$combination->price = Djcatalog2HelperPrice::applyPriceRules($product->price, false, 'each_item', $product, 'item');
				}

				//$combination->final_price = Djcatalog2HelperPrice::applyPriceRules($tmpPrice, true, 'each_item', $product, 'item');
				if ($tmpPrice == 0.0) {
					$combination->final_price = Djcatalog2HelperPrice::applyPriceRules($product->final_price, true, 'each_item', $product, 'item');
				} else {
					$combination->final_price = Djcatalog2HelperPrice::applyPriceRules($tmpPrice, true, 'each_item', $product, 'item');
				}

				$product->_cart_features = $cart_features;
			}
		}

		return $combinations;
	}

	public function getCombination($combination_id)
	{
		if (!isset($this->_combinations[$combination_id])) {
			$db = Factory::getDbo();
			$app = Factory::getApplication();

			$price_group_filter = 0;
			$user = Djcatalog2Helper::getUserProfile($app->getUserState('com_djcatalog2.checkout.user_id', null));
			if (isset($user->customer_group_id)) {
				$price_group_filter = $user->customer_group_id;
			}

			$query = $db->getQuery(true);
			$query->select('c.*, gc.price as group_price');
			$query->from('#__djc2_items_combinations AS c');
			$query->join('left', '#__djc2_combination_prices AS gc ON gc.combination_id = c.id AND gc.group_id=' . (int)$price_group_filter);
			$query->where('c.id = ' . (int)$combination_id);
			$db->setQuery($query);
			$combination = $db->loadObject();

			if (!empty($combination)) {
				if ($combination->group_price > 0) {
					$combination->price = $combination->group_price;
				}

				$query = $db->getQuery(true);
				$query->select('cf.*, f.name as field_name, fo.value as field_value');
				$query->from('#__djc2_items_combinations_fields AS cf');
				$query->join('left', '#__djc2_items_extra_fields as f ON f.id = cf.field_id');
				$query->join('left', '#__djc2_items_extra_fields_options as fo ON fo.id = cf.value AND fo.field_id = cf.field_id AND fo.field_id = f.id');
				$query->where('cf.combination_id = ' . $combination->id);
				$query->order('f.ordering ASC, fo.ordering ASC');
				$db->setQuery($query);

				$fields = $db->loadObjectList();

				$combination->fields = array();

				foreach ($fields as $field) {
					$combination->fields[$field->field_id] = $field;
				}

				$product = $this->getItem($combination->item_id);

				$cart_features = $combination_features = isset($product->_cart_features) ? $product->_cart_features : array();
				foreach ($combination->fields as $field) {
					$combination_features[] = $field->value;
				}
				$product->_cart_features = $combination_features;

				$tmpPrice = $combination->price;

				//$combination->price = Djcatalog2HelperPrice::applyPriceRules($tmpPrice, false, 'each_item', $product, 'item');
				if ($tmpPrice > 0.0) {
					if ($tmpPrice > $product->price) {
						$combination->price = Djcatalog2HelperPrice::applyPriceRules($tmpPrice, false, 'each_item', $product, 'item');
					} else {
						$combination->price = Djcatalog2HelperPrice::applyPriceRules($product->price, false, 'each_item', $product, 'item');
					}
				} else {
					$combination->price = Djcatalog2HelperPrice::applyPriceRules($product->price, false, 'each_item', $product, 'item');
				}

				//$combination->final_price = Djcatalog2HelperPrice::applyPriceRules($tmpPrice, true, 'each_item', $product, 'item');
				if ($tmpPrice == 0.0) {
					$combination->final_price = Djcatalog2HelperPrice::applyPriceRules($product->final_price, true, 'each_item', $product, 'item');
				} else {
					$combination->final_price = Djcatalog2HelperPrice::applyPriceRules($tmpPrice, true, 'each_item', $product, 'item');
				}

				$product->_cart_features = $cart_features;


			}

			$this->_combinations[$combination_id] = $combination;
		}

		return $this->_combinations[$combination_id];
	}

	public function getCustomisations($item_id = 0)
	{
		if (!isset($this->_customisations[(int)$item_id])) {
			$db = Factory::getDbo();
			$query = $db->getQuery(true);

			if ((int)$item_id > 0) {
				//$query->select('ic.*, c.name, c.input_params, c.price as def_price, c.min_quantity as def_min_quantity, c.max_quantity as def_max_quantity, c.required as def_required');
				$query->select('ic.*, c.name, c.input_params, c.type, c.tax_rule_id, c.price_modifier');
				$query->from('#__djc2_items_customisations AS ic');
				$query->join('inner', '#__djc2_customisations AS c ON c.id=ic.customisation_id');
				$query->where('item_id = ' . (int)$item_id);
				$query->where('c.type=' . $db->quote('i'));
				$query->order('c.ordering');
			} else {
				$query->select('c.*, id as customisation_id, 0 as item_id');
				$query->from('#__djc2_customisations AS c');
				$query->where('(c.type=' . $db->quote('c') . ' OR c.type=' . $db->quote('a') . ')');
				$query->order('c.ordering');
			}

			$db->setQuery($query);

			$customisations = $db->loadObjectList();
			foreach ($customisations as $key => &$custom) {
				if (!empty($custom->input_params)) {
					$input_params = json_decode(trim((string)$custom->input_params), true);
					$custom->input_params = $input_params;
				} /*else {
				unset($customisations[$key]);
				continue;
				}*/
				else {
					$custom->input_params = array();
				}

				$custom->_cid = ($custom->customisation_id . '-' . $custom->item_id);
			}
			unset($custom);

			$this->_customisations[(int)$item_id] = $customisations;
		}

		return $this->_customisations[(int)$item_id];
	}

	public function getCustomisationsForm($customisations, $item, $params, $data = array())
	{
		if (count($customisations) < 1) {
			return false;
		}

		$source = '<?xml version="1.0" encoding="UTF-8"?>' .
			'<form><fieldset addfieldpath="/administrator/components/com_djcatalog2/models/fields">';


		$source .= '<field name="customisation" type="checkboxes" label="COM_DJCATALOG2_CUSTOMISATION_OPT_LBL">';
		foreach ($customisations as $custom) {
			$optionName = $custom->name;

			if ($custom->price > 0.0) {
				$taxRuleId = (isset($item)) ? $item->tax_rule_id : $custom->tax_rule_id;
				$prices = Djcatalog2HelperPrice::getPrices($custom->price, $custom->price, $item->tax_rule_id, false, $params);
				$optionName .= ' &lt;span class="djc_custom_price"&gt;(+' . htmlspecialchars(DJCatalog2HtmlHelper::formatPrice($prices['display'], $params), ENT_QUOTES, 'UTF-8') . ')&lt;/span&gt;';
			}

			$source .= '<option value="' . $custom->_cid . '">' . $optionName . '</option>';
		}
		$source .= '</field>';

		foreach ($customisations as $custom) {

			$showon = 'showon="customisation:' . $custom->_cid . '"';
			$class = 'djc2-custom-input djc2-custom-input-' . $custom->_cid;

			$noteLbl = '';
			$noteDesc = '';

			if (count($custom->input_params) > 0) {
				$noteLbl = Text::sprintf('COM_DJCATALOG2_CUSTOMISATION_OPT_NOTE', $custom->name);
			}

			if ($custom->min_quantity > 0 || $custom->max_quantity > 0) {
				$noteLbl = Text::sprintf('COM_DJCATALOG2_CUSTOMISATION_OPT_NOTE', $custom->name);

				if ($custom->min_quantity > 0 && $custom->max_quantity > 0) {
					$noteDesc = Text::sprintf('COM_DJCATALOG2_CUSTOMISATION_MIN_MAX_NOTE', $custom->min_quantity, $custom->max_quantity);
				} else if ($custom->min_quantity > 0) {
					$noteDesc = Text::sprintf('COM_DJCATALOG2_CUSTOMISATION_MIN_NOTE', $custom->min_quantity);
				} else if ($custom->max_quantity > 0) {
					$noteDesc = Text::sprintf('COM_DJCATALOG2_CUSTOMISATION_MAX_NOTE', $custom->max_quantity);
				}
			}

			if ($noteLbl != '' || $noteDesc != '') {
				$source .= '<field ' . $showon . ' type="note" name="' . $custom->_cid . '-note-inputparams" label="' . $noteLbl . '" description="' . $noteDesc . '" />';
			}

			foreach ($custom->input_params as $ik => $inputParam) {

				$input = Joomla\Utilities\ArrayHelper::toObject($inputParam);
				//$name = 'customisation-' . $custom->_cid .'-'.$ik;
				$name = 'customValues-' . $custom->_cid . '[' . $ik . ']';
				$required = (!empty($input->required)) ? 'required="true"' : '';

				switch ($input->type) {
					case 'file':
					{
						//$source .= '<field '.$showon.' name="'.$name.'" type="djcplupload" label="'.$input->label.'" multiple_files="false" limit="1" preview="true" caption="false" download="false" extensions="jpg,png,gif" />';
						// CUSTOM
						$ext = trim((string)$input->allowed_types);
						$ext = ($ext == '') ? 'jpg,png' : $ext;

						$maxSize = trim((string)$input->max_size);
						$maxSize = ((int)$maxSize > 0) ? $maxSize : 2048;

						$fileDesc = Text::sprintf('COM_DJCATALOG2_PLUPLOAD_FILE_INFO_SPACER', ($maxSize / 1024) . 'MB', str_replace(',', ', ', $ext));
						$fieldLbl = $input->label . ' &lt;br /&gt;&lt;small&gt;(' . $fileDesc . ')&lt;/small&gt;';

						$source .= '<field class="' . $class . '" ' . $showon . ' name="' . $name . '" type="djcplupload" label="' . $fieldLbl . '" multiple_files="false" limit="1" preview="false" caption="false" download="false" extensions="' . $ext . '" max_size="' . $maxSize . '" ' . $required . ' />';
						//$source .= '<field '.$showon.' type="note" name="'.$name.'-spacer" description="'.$fileDesc.'" label="" />';
						break;
					}
					case 'text':
					{
						$source .= '<field ' . $showon . '  name="' . $name . '" type="text" label="' . $input->label . '" ' . $required . ' class="' . $class . '" />';
						break;
					}
					case 'textarea':
					{
						$source .= '<field ' . $showon . '  name="' . $name . '" type="textarea" label="' . $input->label . '" ' . $required . ' class="' . $class . '" />';
						break;
					}
					case 'radio':
					{
						if (!empty($inputParam['options']) && is_array($inputParam['options'])) {
							$source .= '<field ' . $showon . '  name="' . $name . '" type="radio" label="' . $input->label . '" ' . $required . ' class="' . $class . '">';
							foreach ($inputParam['options'] as $subOptionKey => $subOption) {
								$prices = Djcatalog2HelperPrice::getPrices($subOption['option_price'], $subOption['option_price'], $item->tax_rule_id, false, $params);
								$subOptionLbl = $subOption['option_label'];
								if (trim((string)$subOption['option_price']) != '' && $subOption['option_price'] > 0) {
									$subOptionLbl .= ' (+ ' . htmlspecialchars(DJCatalog2HtmlHelper::formatPrice($prices['display'], $params), ENT_QUOTES, 'UTF-8') . ')';
								}
								$source .= '<option value="' . $subOptionKey . '">' . $subOptionLbl . '</option>';
							}
							$source .= '</field>';
						}
						break;
					}
					case 'checkbox':
					{
						if (!empty($inputParam['options']) && is_array($inputParam['options'])) {
							$source .= '<field ' . $showon . '  name="' . $name . '" type="checkboxes" label="' . $input->label . '" ' . $required . ' class="' . $class . '">';
							foreach ($inputParam['options'] as $subOptionKey => $subOption) {
								$prices = Djcatalog2HelperPrice::getPrices($subOption['option_price'], $subOption['option_price'], $item->tax_rule_id, false, $params);
								$subOptionLbl = $subOption['option_label'];
								if (trim((string)$subOption['option_price']) != '' && $subOption['option_price'] > 0) {
									$subOptionLbl .= ' (+' . htmlspecialchars(DJCatalog2HtmlHelper::formatPrice($prices['display'], $params), ENT_QUOTES, 'UTF-8') . ')';
								}
								$source .= '<option value="' . $subOptionKey . '">' . $subOptionLbl . '</option>';
							}
							$source .= '</field>';
						}
						break;
					}
					default :
					{
						$results = Joomla\CMS\Factory::getApplication()->triggerEvent('onProductCustomisationXMLPrepare', [$name, $item, $custom, $input, $this, $showon]);
						foreach ($results as $result) {
							if (trim((string)$result) == '' || empty($result)) continue;
							$source .= $result;
						}
						break;
					}
				}

			}
		}

		$source .= '</fieldset></form>';

		$form = \Joomla\CMS\Form\Form::getInstance('com_djcatalog2.cart.customisation', $source, array('control' => false), false, false);
		$app = Factory::getApplication();

		if (!empty($data)) {
			$form->bind($data);
		}

		return $form;
	}

	public function getTierPrices($item_id)
	{

		if (!isset($this->_price_tiers[$item_id])) {
			$db = Factory::getDbo();
			$query = $db->getQuery(true);
			$query->select('*')->from('#__djc2_items_price_tiers')->where('item_id=' . (int)$item_id)->order('quantity ASC');
			$db->setQuery($query);
			$this->_price_tiers[$item_id] = $db->loadObjectList();
		}

		return $this->_price_tiers[$item_id];
	}

	public function hit($pk = 0)
	{
		$pk = (!empty ($pk)) ? $pk : ( int )$this->getState('item.id');

		Djcatalog2Helper::pushRecentItem($pk);

		$db = $this->getDbo();
		$db->setQuery('UPDATE #__djc2_items' . ' SET hits = hits + 1' . ' WHERE id = ' . ( int )$pk);
		$db->execute();

		return true;
	}

	protected function parseConfigConditions($data)
	{
		$cfgCond = ArrayHelper::fromObject($data, false);
		foreach ($cfgCond as $key => $row) {
			if (is_object($row->field->field_id)) {
				$fids = ArrayHelper::fromObject($row->field->field_id);
				$row->field->field_id = $fids[0];
			} else {
				$row->field->field_id = $row->field->field_id[0];
			}
			if (is_object($row->field->option_id)) {
				$row->field->option_id = ArrayHelper::fromObject($row->field->option_id);
			}
			if (is_object($row->field->price)) {
				$row->field->price = ArrayHelper::fromObject($row->field->price);
			}
			if (is_object($row->field->price_mod)) {
				$row->field->price_mod = ArrayHelper::fromObject($row->field->price_mod);
			}
			if (is_object($row->field->sku)) {
				$row->field->sku = ArrayHelper::fromObject($row->field->sku);
			}
			if (is_object($row->field->info)) {
				$row->field->info = ArrayHelper::fromObject($row->field->info);
			}
			if (is_object($row->dependancies)) {
				$row->dependancies = ArrayHelper::fromObject($row->dependancies, false);
			}
			$cfgCond[$key] = $row;
		}

		$cSteps = array();
		foreach ($cfgCond as $condition) {
			if (empty($condition->field->option_id)) continue;

			$fDef = $this->getAttributeById($condition->field->field_id);
			if (empty($fDef)) continue;

			if (!isset($cSteps[$condition->field->field_id])) {
				$cSteps[$condition->field->field_id] = array(
					'name' => $fDef->name,
					'description' => $fDef->description,
					'field_id' => $fDef->id,
					'options' => array()
				);
			}

			foreach ($condition->field->option_id as $avOption) {
				if (empty($fDef->optionValues[$avOption])) continue;

				$item = array(
					'value' => $fDef->optionValues[$avOption],
					'id' => $avOption,
					'params' => $fDef->optionParams[$avOption],
					'dependancies' => array(),
					'price' => 0,
					'sku' => '',
					'info' => ''
				);

				if (isset($condition->field->price) && isset($condition->field->price[$avOption])) {
					$item['price'] = $condition->field->price[$avOption];
				}
				if (isset($condition->field->sku) && isset($condition->field->sku[$avOption])) {
					$item['sku'] = $condition->field->sku[$avOption];
				}
				if (isset($condition->field->info) && isset($condition->field->info[$avOption])) {
					$item['info'] = $condition->field->info[$avOption];
				}
				if (isset($condition->field->price_mod) && isset($condition->field->price_mod[$avOption])) {
					$item['price_mod'] = $condition->field->price_mod[$avOption];
				}
				if (!empty($condition->dependancies)) {
					foreach ($condition->dependancies as $dep) {

						$cndField = $this->getAttributeById($dep->field_rule->field_id[0]);
						if (empty($cndField)) {
							continue;
							//echo '<pre>' . print_r($dep, true) . '</pre>';die();
						}

						$depItem = array(
							'id' => $dep->field_rule->field_id[0],
							'name' => $cndField->name,
							'operator' => $dep->field_rule->operator,
							'match' => null
						);

						if ($depItem['operator'] == 'eq' || $depItem['operator'] == 'not') {
							$depItem['match'] = array();
							$depItem['match_values'] = array();
							$depItem['match_ids'] = array();

							if (!empty($dep->field_rule->rule_options) && is_array($dep->field_rule->rule_options)) {
								foreach ($dep->field_rule->rule_options as $rOption) {
									if (empty($cndField->optionValues[$rOption])) continue;
									$depItem['match'][] = array(
										'id' => $rOption,
										'value' => $cndField->optionValues[$rOption],
										'params' => $cndField->optionParams[$rOption]
									);
									$depItem['match_values'][] = $cndField->optionValues[$rOption];
									$depItem['match_ids'][] = $rOption;
								}
							}
						} else {
							$depItem['match'] = $dep->field_rule->rule_text;
						}

						$item['dependancies'][] = $depItem;
					}
				}

				$cSteps[$condition->field->field_id]['options'][] = $item;
			}
		}
		return $cSteps;
	}

	public function storeVote($pk = 0, $rate = 0, $created = '0000-00-00 00:00:00', $review = '', $author = '', $language = '*', $user_id = 0)
	{
		if ($rate >= 1 && $rate <= 5 && $pk > 0) {
			$userIP = IpHelper::getIp();

			// Initialize variables.
			$db = $this->getDbo();
			$query = $db->getQuery(true);

			// Create the base select statement.
			$query->select('*')
				->from($db->quoteName('#__djc2_item_rating'))
				->where($db->quoteName('item_id') . ' = ' . (int)$pk);

			// Set the query and load the result.
			$db->setQuery($query);

			// Check for a database error.
			try {
				$rating = $db->loadObject();
			} catch (RuntimeException $e) {
				Factory::getApplication()->enqueueMessage($e->getMessage(), 'warning');
				return false;
			}

			// There are no ratings yet, so lets insert our rating
			if (!$rating) {
				$query = $db->getQuery(true);

				// Create the base insert statement.
				$query->insert($db->quoteName('#__djc2_item_rating'))
					->columns(array($db->quoteName('item_id'), $db->quoteName('lastip'), $db->quoteName('rating_sum'), $db->quoteName('rating_count')))
					->values((int)$pk . ', ' . $db->quote($userIP) . ',' . (int)$rate . ', 1');

				// Set the query and execute the insert.
				$db->setQuery($query);

				try {
					$db->execute();
				} catch (RuntimeException $e) {
					Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
					return false;
				}
			} else {
				if ($userIP != $rating->lastip) {
					$query = $db->getQuery(true);

					// Create the base update statement.
					$query->update($db->quoteName('#__djc2_item_rating'))
						->set($db->quoteName('rating_count') . ' = rating_count + 1')
						->set($db->quoteName('rating_sum') . ' = rating_sum + ' . (int)$rate)
						->set($db->quoteName('lastip') . ' = ' . $db->quote($userIP))
						->where($db->quoteName('item_id') . ' = ' . (int)$pk);

					// Set the query and execute the update.
					$db->setQuery($query);

					try {
						$db->execute();
					} catch (RuntimeException $e) {
						Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
						return false;
					}
				} else {
					return false;
				}
			}

			$query = $db->getQuery(true);
			$query->insert('#__djc2_item_reviews');
			$query->columns(array($db->quoteName('item_id'), $db->quoteName('user_id'), $db->quoteName('review'), $db->quoteName('rating'), $db->quoteName('author'), $db->quoteName('ip'), $db->quoteName('created'), $db->quoteName('language')));
			$query->values((int)$pk . ', ' . (int)$user_id . ', ' . $db->quote($review) . ', ' . (int)$rate . ',' . $db->quote($author) . ', ' . $db->quote($userIP) . ', ' . $db->quote($created) . ', ' . $db->quote($language));

			$db->setQuery($query);
			try {
				$db->execute();
			} catch (RuntimeException $e) {
				Factory::getApplication()->enqueueMessage($e->getMessage(), 'warning');
				return false;
			}

			$this->cleanCache();

			return true;
		}

		Factory::getApplication()->enqueueMessage(Text::sprintf('COM_CONTENT_INVALID_RATING', $rate), 'warning');
		return false;
	}
}

Anon7 - 2022
AnonSec Team