public function process() { parent::process(); $hasProduct = false; $product_list = Tools::getValue('compare_product_list'); $postProducts = isset($product_list) ? rtrim($product_list, '|') : ''; if (!Configuration::get('PS_COMPARATOR_MAX_ITEM')) { return Tools::redirect('404.php'); } if ($postProducts) { $ids = array_unique(explode('|', $postProducts)); if (sizeof($ids) > 0) { if (sizeof($ids) > Configuration::get('PS_COMPARATOR_MAX_ITEM')) { $ids = array_slice($ids, 0, Configuration::get('PS_COMPARATOR_MAX_ITEM')); } $listProducts = array(); $listFeatures = array(); foreach ($ids as $id) { $curProduct = new Product((int) $id, true, (int) self::$cookie->id_lang); if (!Validate::isLoadedObject($curProduct)) { continue; } if (!$curProduct->active) { unset($ids[$k]); continue; } foreach ($curProduct->getFrontFeatures(self::$cookie->id_lang) as $feature) { $listFeatures[$curProduct->id][$feature['id_feature']] = $feature['value']; } $cover = Product::getCover((int) $id); $curProduct->id_image = Tools::htmlentitiesUTF8(Product::defineProductImage(array('id_image' => $cover['id_image'], 'id_product' => $id), self::$cookie->id_lang)); $curProduct->allow_oosp = Product::isAvailableWhenOutOfStock($curProduct->out_of_stock); $listProducts[] = $curProduct; } if (sizeof($listProducts) > 0) { $width = 80 / sizeof($listProducts); $hasProduct = true; $ordered_features = Feature::getFeaturesForComparison($ids, self::$cookie->id_lang); self::$smarty->assign(array('ordered_features' => $ordered_features, 'product_features' => $listFeatures, 'products' => $listProducts, 'link' => new Link(), 'width' => $width, 'homeSize' => Image::getSize('home'))); self::$smarty->assign('HOOK_EXTRA_PRODUCT_COMPARISON', Module::hookExec('extraProductComparison', array('list_ids_product' => $ids))); } } } self::$smarty->assign('hasProduct', $hasProduct); }
/** * \brief Header hook * \retval void */ public function hookHeader() { global $cookie, $cart, $smarty; $html = ''; // Check if product is a multi-dimensions product $multiDimensions_product = false; if (Tools::getIsset('id_product')) { $product = getProducts((int) Tools::getValue('id_product')); if (count($product)) { $multiDimensions_product = true; } } // Header add only if needed if (strtolower(basename($_SERVER['PHP_SELF'])) == 'history.php' || Tools::getIsset('controller') && Tools::getValue('controller') == 'history' || Tools::getIsset('id_product') && $multiDimensions_product) { if ((double) substr(_PS_VERSION_, 0, 3) >= 1.6) { $this->context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/functions' . $GLOBALS['aimd_config_suffix'] . '.js'); $this->context->controller->addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/css/global.css'); } else { if ((double) substr(_PS_VERSION_, 0, 3) == 1.5) { $context = Context::getContext(); $context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/functions' . $GLOBALS['aimd_config_suffix'] . '.js?' . filemtime(_PS_ROOT_DIR_ . '/modules/' . $this->name . '/' . $this->name . '.php')); $context->controller->addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/css/global.css'); } else { Tools::addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/css/global.css', 'all'); Tools::addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/functions' . $GLOBALS['aimd_config_suffix'] . '.js?' . filemtime(_PS_ROOT_DIR_ . '/modules/' . $this->name . '/' . $this->name . '.php')); } } // Header for upload if ((double) substr(_PS_VERSION_, 0, 3) >= 1.6) { // Only if uploader activated if ((int) Configuration::get('AIMD_FILE_UPLOAD_TIME') != -1) { $this->context->controller->addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/css/tabs.css', 'all'); $this->context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/tabs.js'); $this->context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/js/jquery.knob.js'); $this->context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/js/jquery.ui.widget.js'); $this->context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/js/jquery.iframe-transport.js'); $this->context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/js/jquery.fileupload.js'); } } else { if ((double) substr(_PS_VERSION_, 0, 3) == 1.5) { // Only if uploader activated if ((int) Configuration::get('AIMD_FILE_UPLOAD_TIME') != -1) { $context = Context::getContext(); $context->controller->addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/css/style.css', 'all'); $context->controller->addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/css/tabs.css', 'all'); $context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/tabs.js'); $context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/js/jquery.knob.js'); $context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/js/jquery.ui.widget.js'); $context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/js/jquery.iframe-transport.js'); $context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/js/jquery.fileupload.js'); } /* } else { // Only if uploader activated if ( (int) Configuration::get('AIMD_FILE_UPLOAD_TIME') != -1 ) { Tools::addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/css/style.css', 'all'); Tools::addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/css/tabs.css', 'all'); Tools::addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/tabs.js'); Tools::addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/js/jquery.knob.js'); Tools::addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/js/jquery.ui.widget.js'); Tools::addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/js/jquery.iframe-transport.js'); Tools::addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/includes/mini-uploader/assets/js/jquery.fileupload.js'); }*/ } } $html .= '<script type="text/javascript">' . 'var max_files = ' . (int) Configuration::get('AIMD_FILE_NUMBER') . ';' . 'var allowed_extensions = \'' . addslashes(Configuration::get('AIMD_FILE_FORMAT')) . '\';' . 'var progressbar_label = \'' . addslashes($this->l('Upload in progress ...')) . '\';' . 'var label_extensions_error = \'' . addslashes($this->l('Extension error for file')) . '\';' . 'var label_extensions_mustBe = \'' . addslashes($this->l('must be one of')) . '\';' . '</script>'; } if ($multiDimensions_product) { // If magic_quotes is ON, and unactive by config, let's do it if (get_magic_quotes_gpc() && Configuration::get('AIMD_MAGIC_QUOTES_DISABLE')) { $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST); while (list($key, $val) = each($process)) { foreach ($val as $k => $v) { unset($process[$key][$k]); if (is_array($v)) { $process[$key][stripslashes($k)] = $v; $process[] =& $process[$key][stripslashes($k)]; } else { $process[$key][stripslashes($k)] = stripslashes($v); } } } unset($process); } // If small dimension name is to be shows, add the cart CSS file if (Configuration::get('AIMD_CART_NAME') == 1) { if ((double) substr(_PS_VERSION_, 0, 3) >= 1.5) { $context = Context::getContext(); $context->controller->addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/css/cart.css'); } else { Tools::addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/css/cart.css', 'all'); } } // If config is not set, exit if (!Configuration::get('AIMD_FIRST_DIMENSION_ACTIVE') && !Configuration::get('AIMD_SECOND_DIMENSION_ACTIVE') && !Configuration::get('AIMD_THIRD_DIMENSION_ACTIVE')) { return; } // Set the base informations to calculate reductions $html .= '<script type="text/javascript">' . 'var default_dimensions = new Array('; $fdid = Configuration::get('AIMD_FIRST_DIMENSION_ID'); $fdscale = $this->_get_scale(Configuration::get('AIMD_FIRST_DIMENSION_SCALE')); $fddefaultId = Db::getInstance()->ExecuteS('SELECT distinct(attribute.id_attribute) FROM ' . _DB_PREFIX_ . 'attribute as attribute LEFT JOIN ' . _DB_PREFIX_ . 'attribute_lang as lang ON attribute.id_attribute = lang.id_attribute ' . 'WHERE attribute.id_attribute_group = ' . $fdid . ' AND lang.name = ' . $fdscale); $html .= 'new Array(' . $fdid . ', ' . $fdscale . ', ' . $fddefaultId[0]['id_attribute'] . '),'; $sdid = Configuration::get('AIMD_SECOND_DIMENSION_ID'); $sdscale = $this->_get_scale(Configuration::get('AIMD_SECOND_DIMENSION_SCALE')); $sddefaultId = Db::getInstance()->ExecuteS('SELECT distinct(attribute.id_attribute) FROM ' . _DB_PREFIX_ . 'attribute as attribute LEFT JOIN ' . _DB_PREFIX_ . 'attribute_lang as lang ON attribute.id_attribute = lang.id_attribute ' . 'WHERE attribute.id_attribute_group = ' . $sdid . ' AND lang.name = ' . $sdscale); $html .= 'new Array(' . $sdid . ', ' . $sdscale . ', ' . $sddefaultId[0]['id_attribute'] . ')'; $tdid = Configuration::get('AIMD_THIRD_DIMENSION_ID'); $tdscale = $this->_get_scale(Configuration::get('AIMD_THIRD_DIMENSION_SCALE')); $tddefaultId = Db::getInstance()->ExecuteS('SELECT distinct(attribute.id_attribute) FROM ' . _DB_PREFIX_ . 'attribute as attribute LEFT JOIN ' . _DB_PREFIX_ . 'attribute_lang as lang ON attribute.id_attribute = lang.id_attribute ' . 'WHERE attribute.id_attribute_group = ' . $tdid . ' AND lang.name = ' . $tdscale); if (Tools::getValue('id_product')) { if (Db::getInstance()->getValue('SELECT pa.id_product FROM ' . _DB_PREFIX_ . 'product_attribute AS pa LEFT JOIN ' . _DB_PREFIX_ . 'product_attribute_combination AS pac ON pa.id_product_attribute = pac.id_product_attribute WHERE ' . 'pa.id_product = ' . (int) Tools::getValue('id_product') . ' AND pac.id_attribute = ' . $tddefaultId[0]['id_attribute'])) { $html .= ', new Array(' . $tdid . ', ' . $tdscale . ', ' . $tddefaultId[0]['id_attribute'] . ')'; } } else { $html .= ', new Array(' . $tdid . ', ' . $tdscale . ', ' . $tddefaultId[0]['id_attribute'] . ')'; } $html .= ');'; // Set the dimensions reductions if needed $dimensions = $this->l('m²'); if (Tools::getValue('id_product')) { $id_product = (int) Tools::getValue('id_product'); $html .= 'var dimensions_reductions = new Array('; // Get the reductions for the product $first = true; $reductions = Db::getInstance()->ExecuteS('SELECT * FROM ' . _DB_PREFIX_ . 'aimultidimensions_reductions WHERE ar_product = ' . $id_product . ' ORDER BY ar_minimum_size'); foreach ($reductions as $reduction) { $way = '-'; if ($reduction['ar_way']) { $way = '+'; } if ($first) { $html .= 'new Array(' . $reduction['ar_minimum_size'] . ', ' . $way . $reduction['ar_percent'] . ')'; $first = false; } else { $html .= ', new Array(' . $reduction['ar_minimum_size'] . ', ' . $way . $reduction['ar_percent'] . ')'; } } $html .= ');'; // Get the number of dimensions $result = Db::getInstance()->ExecuteS('SELECT attribute.id_product, group_lang.name as group_name, lang.name FROM ' . _DB_PREFIX_ . 'product_attribute_combination as combination LEFT JOIN ' . _DB_PREFIX_ . 'product_attribute as attribute ON combination.id_product_attribute = attribute.id_product_attribute LEFT JOIN ' . _DB_PREFIX_ . 'product_lang as lang ON lang.id_product = attribute.id_product ' . 'LEFT JOIN ' . _DB_PREFIX_ . 'attribute as attribute_group ON attribute_group.id_attribute = combination.id_attribute LEFT JOIN ' . _DB_PREFIX_ . 'attribute_group_lang as group_lang ON ' . 'group_lang.id_attribute_group = attribute_group.id_attribute_group WHERE lang.id_lang = ' . (int) $cookie->id_lang . ' AND lang.id_product = ' . $id_product . ' AND group_lang.id_lang = ' . (int) $cookie->id_lang . ' AND attribute_group.id_attribute IN (SELECT attrib.id_attribute FROM ' . _DB_PREFIX_ . 'attribute as attrib WHERE attrib.id_attribute_group IN (' . $fdid . ', ' . $sdid . ', ' . $tdid . ')) GROUP BY attribute.id_product, group_lang.name'); if (count($result) == 3) { $dimensions = $this->l('m3'); } // Global surface reduction $result = Db::getInstance()->ExecuteS('SELECT aimd_gsr FROM ' . _DB_PREFIX_ . 'product WHERE id_product = ' . $id_product); $html .= 'var global_surface_reduction = ' . $result[0]['aimd_gsr'] . ';'; // Get the default combination $result = Db::getInstance()->ExecuteS('SELECT id_product_attribute FROM ' . _DB_PREFIX_ . 'product_attribute WHERE id_product = ' . $id_product . ' AND default_on = 1'); $id_product_attribute = 0; if (count($result)) { $id_product_attribute = (int) $result[0]['id_product_attribute']; } $html .= 'var default_combination_id = ' . $id_product_attribute . ';'; // Limits $result = Db::getInstance()->ExecuteS('SELECT * FROM ' . _DB_PREFIX_ . 'aimultidimensions_limits WHERE al_product = ' . $id_product . ' AND al_dimension IN (' . (int) $fdid . ', ' . (int) $sdid . ', ' . (int) $tdid . ')'); $html .= 'var limits = new Array('; $cpt = 0; $limits_html = ''; foreach ($result as $row) { $single_limit_id = 0; // Message to display $message = ''; if (floatval($row['al_minimum_size']) == 0) { $message = addslashes($this->l('Less than')) . ' ' . $this->_cleanSize($row['al_maximum_size']); } else { if (floatval($row['al_maximum_size']) == 0) { $message = addslashes($this->l('More than')) . ' ' . $this->_cleanSize($row['al_minimum_size']); } else { $message = addslashes($this->l('From')) . ' ' . $this->_cleanSize($row['al_minimum_size']) . ' ' . addslashes($this->l('To')) . ' ' . $this->_cleanSize($row['al_maximum_size']); } } // Single limit id if ($row['al_minimum_size'] == $row['al_maximum_size'] && $row['al_maximum_size'] != 0) { $single_limit_id = Db::getInstance()->getValue('SELECT pac.id_attribute FROM ' . _DB_PREFIX_ . 'product_attribute_combination AS pac LEFT JOIN ' . _DB_PREFIX_ . 'attribute AS a ON ' . 'a.id_attribute = pac.id_attribute LEFT JOIN ' . _DB_PREFIX_ . 'attribute_lang AS al ON al.id_attribute = a.id_attribute WHERE pac.id_product_attribute = ' . $id_product_attribute . ' AND ' . 'a.id_attribute_group = ' . $row['al_dimension'] . ' AND al.name = "' . floatval($row['al_minimum_size']) . '" GROUP BY al.id_attribute'); if ($limits_html) { $limits_html .= ', '; } $limits_html .= 'new Array(' . $row['al_dimension'] . ', "' . $single_limit_id . '")'; } if ($cpt != 0) { $html .= ', '; } $html .= 'new Array(' . $row['al_dimension'] . ', ' . $row['al_minimum_size'] . ', ' . $row['al_maximum_size'] . ', \'' . $message . '\')'; $cpt++; } // Add limits from product links $result = Db::getInstance()->ExecuteS('SELECT COUNT(fd_attribute_group) AS number, fd_product, fd_attribute_group, fd_value FROM ' . _DB_PREFIX_ . 'aimultidimensions_fixed_dimensions WHERE ' . 'fd_product = ' . $id_product . ' GROUP BY fd_attribute_group ORDER BY number ASC'); foreach ($result as $row) { if ((int) $row['number'] == 1) { $single_limit_id = Db::getInstance()->getValue('SELECT pac.id_attribute FROM ' . _DB_PREFIX_ . 'product_attribute_combination AS pac LEFT JOIN ' . _DB_PREFIX_ . 'attribute AS a ON ' . 'a.id_attribute = pac.id_attribute LEFT JOIN ' . _DB_PREFIX_ . 'attribute_lang AS al ON al.id_attribute = a.id_attribute WHERE pac.id_product_attribute = ' . $id_product_attribute . ' AND ' . 'a.id_attribute_group = ' . $row['fd_attribute_group'] . ' AND al.name = "' . floatval($row['fd_value']) . '" GROUP BY al.id_attribute'); if ($limits_html) { $limits_html .= ', '; } $limits_html .= 'new Array(' . $row['fd_attribute_group'] . ', "' . $single_limit_id . '")'; } } $html .= ');'; $html .= 'var limit_error_message = \'' . addslashes($this->l('Value not in the Limits range')) . '\';'; // Single limit id $html .= 'var single_limit_ids = new Array(' . $limits_html . ');'; // Minimum surface charged $minimum_surface = Db::getInstance()->getValue('SELECT aimd_msc FROM ' . _DB_PREFIX_ . 'product WHERE id_product = ' . $id_product); $html .= 'var minimum_surface = ' . floatval($minimum_surface) . ';'; // fixed dimensions $first_fixed_dimensions = Db::getInstance()->getValue('SELECT GROUP_CONCAT(CAST(fd_value AS CHAR) ORDER BY fd_value) FROM ' . _DB_PREFIX_ . 'aimultidimensions_fixed_dimensions WHERE fd_product = ' . $id_product . ' AND fd_attribute_group = ' . $fdid); $second_fixed_dimensions = Db::getInstance()->getValue('SELECT GROUP_CONCAT(CAST(fd_value AS CHAR) ORDER BY fd_value) FROM ' . _DB_PREFIX_ . 'aimultidimensions_fixed_dimensions WHERE fd_product = ' . $id_product . ' AND fd_attribute_group = ' . $sdid); $third_fixed_dimensions = Db::getInstance()->getValue('SELECT GROUP_CONCAT(CAST(fd_value AS CHAR) ORDER BY fd_value) FROM ' . _DB_PREFIX_ . 'aimultidimensions_fixed_dimensions WHERE fd_product = ' . $id_product . ' AND fd_attribute_group = ' . $tdid); $html .= 'var fixed_dimensions = new Array(' . 'new Array(' . $fdid . ', "' . $first_fixed_dimensions . '"),' . 'new Array(' . $sdid . ', "' . $second_fixed_dimensions . '"),' . 'new Array(' . $tdid . ', "' . $third_fixed_dimensions . '"));' . 'var fixed_dimensions_choose_label = \'' . addslashes($this->l('Choose a dimension')) . '\';'; // Delivery $result = Db::getInstance()->getRow('SELECT ad_delivery FROM ' . _DB_PREFIX_ . 'aimultidimensions_delivery WHERE ad_product = ' . $id_product); if (count($result)) { if ($result['ad_delivery']) { $delivery = $this->_setDate((int) $result['ad_delivery']); $html .= 'var delivery_text =\'' . addslashes($this->l('Delivery')) . ' ' . addslashes($this->l('about')) . ' ' . $delivery . '\';'; } else { $html .= 'var delivery_text =\'\';'; } } else { $html .= 'var delivery_text =\'\';'; } // Quantity display $display = (int) Db::getInstance()->getValue('SELECT aimd_dpq FROM ' . _DB_PREFIX_ . 'product WHERE id_product = ' . $id_product); $html .= 'var aimd_quantity_display = ' . $display . ';'; // Add product formula $format = (int) DB::getInstance()->getValue('SELECT aimd_format FROM ' . _DB_PREFIX_ . 'product WHERE id_product = ' . $id_product); $formula = $GLOBALS['config_format'][$format]['surface_formula']; $html .= 'var aimd_format_formula = \'' . $formula . '\';'; $labels = $GLOBALS['config_format'][$format]['labels']; $html .= 'var aimd_format_labels = {'; if ($labels['x'] != '') { $html .= $fdid . ': \'' . addslashes($labels['x']) . '\','; } if ($labels['y'] != '') { $html .= $sdid . ': \'' . addslashes($labels['y']) . '\','; } if ($labels['z'] != '') { $html .= $tdid . ': \'' . addslashes($labels['z']) . '\','; } $html .= '};'; // Add proportionnal display $html .= 'var aimd_format_proportionnal_display = ' . $GLOBALS['config_format'][$format]['proportionnal display'] . ';'; } // Price display option $html .= 'var price_display_option = ' . (int) Configuration::get('AIMD_PRICE_DISPLAY') . ';'; // Surface & weight display option $html .= 'var surfaceWeight_display_option = ' . (int) Configuration::get('AIMD_SURFACEWEIGHT_DISPLAY') . ';'; // Minimum surface charged labels $html .= 'var minimum_surface_message = \'' . addslashes($this->l('Minimum charged surface is ')) . '\';'; $html .= 'var minimum_surface_scale = \'' . $dimensions . '\';'; $html .= 'var minimum_surface_on_quantity = ' . Configuration::get('AIMD_MIN_SURFACE_ON_QUANTITY') . ';'; // Calculate button label $html .= 'var calculate_button_label =\'' . $this->l('Calculate') . '\';'; // For availability informations $html .= 'var availability_informations_message = \'' . addslashes($this->l('Choose dimensions message')) . '\';'; // For calculating message $html .= 'var calculating_message = \'' . addslashes($this->l('Calculating ...')) . '\';'; // For choose message $html .= 'var choose_message = \'' . addslashes($this->l('Choose dimensions')) . '\';'; // Surface display if (Configuration::get('AIMD_SURFACE_DISPLAY') == '1') { $html .= 'var surface_display = true;' . 'var surface_display_message = \'' . addslashes($this->l('Surface of {value}')) . '\';'; } else { $html .= 'var surface_display = false;'; } // Weight display if (Configuration::get('AIMD_WEIGHT_DISPLAY') == '1') { $html .= 'var weight_display = true;' . 'var calculated_weight_message = \'' . addslashes($this->l('Weight of')) . '\';' . 'var calculated_weight_unit = \'' . addslashes($this->l('Kgs')) . '\';'; } else { $html .= 'var weight_display = false;'; } // Fixed prices $result = Db::getInstance()->ExecuteS('SELECT attributes.* FROM ' . _DB_PREFIX_ . 'aimultidimensions_specials_attributes AS attributes LEFT JOIN ' . _DB_PREFIX_ . 'aimultidimensions_specials AS specials ON ' . 'attributes.asa_group = specials.as_group WHERE specials.as_type = 0 ORDER BY attributes.asa_group'); $html .= 'var fixed_prices = new Array('; $cpt = 0; foreach ($result as $row) { $html .= 'new Array(' . $row['asa_group'] . ', ' . $row['asa_attribute'] . ', ' . $row['asa_value'] . ')'; $cpt++; if ($cpt < count($result)) { $html .= ', '; } } $html .= ');'; // Percent prices $result = Db::getInstance()->ExecuteS('SELECT attributes.* FROM ' . _DB_PREFIX_ . 'aimultidimensions_specials_attributes AS attributes LEFT JOIN ' . _DB_PREFIX_ . 'aimultidimensions_specials AS ' . 'specials ON attributes.asa_group = specials.as_group WHERE specials.as_type = 3 ORDER BY attributes.asa_group'); $html .= 'var percent_prices = new Array('; $cpt = 0; foreach ($result as $row) { $html .= 'new Array(' . $row['asa_group'] . ', ' . $row['asa_attribute'] . ', ' . $row['asa_value'] . ')'; $cpt++; if ($cpt < count($result)) { $html .= ', '; } } $html .= ');'; // Taxes type $taxesType = 0; if (intval($cookie->logged) == 1) { $result_taxesType = Db::getInstance()->ExecuteS('SELECT price_display_method FROM ' . _DB_PREFIX_ . 'group AS g LEFT JOIN ' . _DB_PREFIX_ . 'customer AS c ON g.id_group = c.id_default_group WHERE ' . 'c.id_customer = ' . $cookie->id_customer); } else { $result_taxesType = Db::getInstance()->ExecuteS('SELECT price_display_method FROM ' . _DB_PREFIX_ . 'group WHERE id_group = 1'); } if (count($result_taxesType)) { $taxesType = 1 - $result_taxesType[0]['price_display_method']; } $html .= 'var product_taxes_type = ' . $taxesType . ';'; // Limit placement $html .= 'var limit_placement = ' . Configuration::get('AIMD_LIMIT_PLACEMENT') . ';'; // Single limit display $html .= 'var single_limit_display = ' . Configuration::get('AIMD_FIXED_DIMENSION_DISPLAY') . ';'; // If needed in PS 1.5 and above, add the add to cart button if ((double) substr(_PS_VERSION_, 0, 3) >= 1.5) { $html .= '$(document).ready( function () {'; $productTmp = new Product($id_product); $allowOosp = Product::isAvailableWhenOutOfStock($productTmp->out_of_stock); if ($productTmp->available_for_order && ($allowOosp || $productTmp->quantity >= 0) && !Configuration::get('PS_CATALOG_MODE')) { $html .= '$(\'form#buy_block div.content_prices span.exclusive\').after(\'<p id="add_to_cart" class="buttons_bottom_block" style="display: none"><span></span><input type="submit" name="Submit" value="' . $this->l('Add to cart') . '" class="exclusive" /></p>\');' . '$(\'form#buy_block div.content_prices span.exclusive\').remove();'; } $html .= '$(\'div#ai_calculating_message\').attr(\'style\',\'display: none;\');' . '$(\'span#ai_choose_message\').attr(\'style\',\'\');' . '});'; } // Get active attributs $attributes = getActiveAttributes(); // Default values if needed $defaults = Db::getInstance()->ExecuteS('SELECT ag.id_attribute_group, al.name FROM ' . _DB_PREFIX_ . 'product_attribute AS pa LEFT JOIN ' . _DB_PREFIX_ . 'product_attribute_combination AS pac ON ' . 'pa.id_product_attribute = pac.id_product_attribute LEFT JOIN ' . _DB_PREFIX_ . 'attribute_lang AS al ON al.id_attribute = pac.id_attribute LEFT JOIN ' . _DB_PREFIX_ . 'attribute AS a ON ' . 'a.id_attribute = pac.id_attribute LEFT JOIN ' . _DB_PREFIX_ . 'attribute_group AS ag ON a.id_attribute_group = ag.id_attribute_group WHERE pa.id_product = ' . (int) Tools::getValue('id_product') . ' AND ' . 'pa.aimd_value = 1 AND pa.default_on = 1 AND al.id_lang = ' . (int) $cookie->id_lang . ' AND ag.id_attribute_group IN (' . implode(',', $attributes) . ') ORDER BY ag.id_attribute_group ASC'); $proportional_value = 0; if (count($defaults)) { $add = array(); foreach ($defaults as $default) { $add[] = 'new Array(' . (int) $default['id_attribute_group'] . ', ' . $default['name'] . ')'; if ($default['id_attribute_group'] == Configuration::get('AIMD_PROPORTIONNAL_DIMENSION')) { $proportional_value = (int) $default['name']; } } $html .= 'var aimd_defaults = new Array(' . implode(',', $add) . ');'; } // Add overlay $html .= '$(document).ready(function () {' . '$(\'#attributes\').append(\'<div id="aimd_operations_overlay" class="wait"> </div><div id="aimd_wait"> </div>\');' . '});'; } // Security if (!isset($proportional_value)) { $proportional_value = 0; } // Add Prestashop version if ($html == '' || (strtolower(basename($_SERVER['PHP_SELF'])) == 'history.php' || Tools::getIsset('controller') && Tools::getValue('controller') == 'history')) { $html .= '<script type="text/javascript">'; } $html .= 'var prestashop_version = parseFloat(' . substr(_PS_VERSION_, 0, 3) . ');' . 'var prestashop_version_long = \'' . _PS_VERSION_ . '\';' . 'var multiDimensions_product = ' . (int) $multiDimensions_product . ';'; // Get the proportionality value if (Tools::getValue('id_product') && (int) $multiDimensions_product) { $proportionality = (int) Db::getInstance()->getValue('SELECT aimd_proportional FROM ' . _DB_PREFIX_ . 'product WHERE id_product = ' . (int) Tools::getValue('id_product')); $html .= 'var aimd_proportional = ' . $proportionality . ';' . 'var aimd_proportional_group = ' . (int) Configuration::get('AIMD_PROPORTIONNAL_DIMENSION') . ';' . 'var aimd_proportional_value = ' . $proportional_value . ';' . 'var proportional_message = \'' . addslashes($this->l('The dimensions are proportional, you only need to input the first one.')) . '\';'; } else { $html .= 'var aimd_proportional = 0;'; } // Ending the javascript block $html .= '</script>'; return $html; }
public function getProducts($refresh = false, $id_product = false, $id_country = null) { /* * EU-Legal * 1) correct calculation of prices -> Problem with inaccuracy at high number of items * 2) assign standard delivery times to products */ if (!$this->id) { return array(); } // Product cache must be strictly compared to NULL, or else an empty cart will add dozens of queries if ($this->_products !== null && !$refresh) { // Return product row with specified ID if it exists if (is_int($id_product)) { foreach ($this->_products as $product) { if ($product['id_product'] == $id_product) { return array($product); } } return array(); } return $this->_products; } // Build query $sql = new DbQuery(); // Build SELECT $sql->select('cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, cp.id_shop, pl.`name`, p.`is_virtual`, pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`delivery_now`, pl.`delivery_later`, product_shop.`id_category_default`, p.`id_supplier`, p.`id_manufacturer`, product_shop.`on_sale`, product_shop.`ecotax`, product_shop.`additional_shipping_cost`, product_shop.`available_for_order`, product_shop.`price`, product_shop.`active`, product_shop.`unity`, product_shop.`unit_price_ratio`, stock.`quantity` AS quantity_available, p.`width`, p.`height`, p.`depth`, stock.`out_of_stock`, p.`weight`, p.`date_add`, p.`date_upd`, IFNULL(stock.quantity, 0) as quantity, pl.`link_rewrite`, cl.`link_rewrite` AS category, CONCAT(LPAD(cp.`id_product`, 10, 0), LPAD(IFNULL(cp.`id_product_attribute`, 0), 10, 0), IFNULL(cp.`id_address_delivery`, 0)) AS unique_id, cp.id_address_delivery, product_shop.advanced_stock_management, ps.product_supplier_reference supplier_reference, IFNULL(sp.`reduction_type`, 0) AS reduction_type'); // Build FROM $sql->from('cart_product', 'cp'); // Build JOIN $sql->leftJoin('product', 'p', 'p.`id_product` = cp.`id_product`'); $sql->innerJoin('product_shop', 'product_shop', '(product_shop.`id_shop` = cp.`id_shop` AND product_shop.`id_product` = p.`id_product`)'); $sql->leftJoin('product_lang', 'pl', ' p.`id_product` = pl.`id_product` AND pl.`id_lang` = ' . (int) $this->id_lang . Shop::addSqlRestrictionOnLang('pl', 'cp.id_shop')); $sql->leftJoin('category_lang', 'cl', ' product_shop.`id_category_default` = cl.`id_category` AND cl.`id_lang` = ' . (int) $this->id_lang . Shop::addSqlRestrictionOnLang('cl', 'cp.id_shop')); $sql->leftJoin('product_supplier', 'ps', 'ps.`id_product` = cp.`id_product` AND ps.`id_product_attribute` = cp.`id_product_attribute` AND ps.`id_supplier` = p.`id_supplier`'); $sql->leftJoin('specific_price', 'sp', 'sp.`id_product` = cp.`id_product`'); // AND 'sp.`id_shop` = cp.`id_shop` // @todo test if everything is ok, then refactorise call of this method $sql->join(Product::sqlStock('cp', 'cp')); // Build WHERE clauses $sql->where('cp.`id_cart` = ' . (int) $this->id); if ($id_product) { $sql->where('cp.`id_product` = ' . (int) $id_product); } $sql->where('p.`id_product` IS NOT NULL'); // Build GROUP BY $sql->groupBy('unique_id'); // Build ORDER BY $sql->orderBy('cp.`date_add`, p.`id_product`, cp.`id_product_attribute` ASC'); if (Customization::isFeatureActive()) { $sql->select('cu.`id_customization`, cu.`quantity` AS customization_quantity'); $sql->leftJoin('customization', 'cu', 'p.`id_product` = cu.`id_product` AND cp.`id_product_attribute` = cu.`id_product_attribute` AND cu.`id_cart` = ' . (int) $this->id); } else { $sql->select('NULL AS customization_quantity, NULL AS id_customization'); } if (Combination::isFeatureActive()) { $sql->select(' product_attribute_shop.`price` AS price_attribute, product_attribute_shop.`ecotax` AS ecotax_attr, IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference, (p.`weight`+ pa.`weight`) weight_attribute, IF (IFNULL(pa.`ean13`, \'\') = \'\', p.`ean13`, pa.`ean13`) AS ean13, IF (IFNULL(pa.`upc`, \'\') = \'\', p.`upc`, pa.`upc`) AS upc, pai.`id_image` as pai_id_image, il.`legend` as pai_legend, IFNULL(product_attribute_shop.`minimal_quantity`, product_shop.`minimal_quantity`) as minimal_quantity, IF(product_attribute_shop.wholesale_price > 0, product_attribute_shop.wholesale_price, product_shop.`wholesale_price`) wholesale_price '); $sql->leftJoin('product_attribute', 'pa', 'pa.`id_product_attribute` = cp.`id_product_attribute`'); $sql->leftJoin('product_attribute_shop', 'product_attribute_shop', '(product_attribute_shop.`id_shop` = cp.`id_shop` AND product_attribute_shop.`id_product_attribute` = pa.`id_product_attribute`)'); $sql->leftJoin('product_attribute_image', 'pai', 'pai.`id_product_attribute` = pa.`id_product_attribute`'); $sql->leftJoin('image_lang', 'il', 'il.`id_image` = pai.`id_image` AND il.`id_lang` = ' . (int) $this->id_lang); } else { $sql->select('p.`reference` AS reference, p.`ean13`, p.`upc` AS upc, product_shop.`minimal_quantity` AS minimal_quantity, product_shop.`wholesale_price` wholesale_price'); } $result = Db::getInstance()->executeS($sql); // Reset the cache before the following return, or else an empty cart will add dozens of queries $products_ids = array(); $pa_ids = array(); if ($result) { foreach ($result as $row) { $products_ids[] = $row['id_product']; $pa_ids[] = $row['id_product_attribute']; } } // Thus you can avoid one query per product, because there will be only one query for all the products of the cart Product::cacheProductsFeatures($products_ids); Cart::cacheSomeAttributesLists($pa_ids, $this->id_lang); $this->_products = array(); if (empty($result)) { return array(); } $cart_shop_context = Context::getContext()->cloneContext(); foreach ($result as &$row) { if (isset($row['ecotax_attr']) && $row['ecotax_attr'] > 0) { $row['ecotax'] = (double) $row['ecotax_attr']; } $row['stock_quantity'] = (int) $row['quantity']; // for compatibility with 1.2 themes $row['quantity'] = (int) $row['cart_quantity']; if (isset($row['id_product_attribute']) && (int) $row['id_product_attribute'] && isset($row['weight_attribute'])) { $row['weight'] = (double) $row['weight_attribute']; } if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_invoice') { $address_id = (int) $this->id_address_invoice; } else { $address_id = (int) $row['id_address_delivery']; } if (!Address::addressExists($address_id)) { $address_id = null; } if ($cart_shop_context->shop->id != $row['id_shop']) { $cart_shop_context->shop = new Shop((int) $row['id_shop']); } $address = Address::initialize($address_id, true); $id_tax_rules_group = Product::getIdTaxRulesGroupByIdProduct((int) $row['id_product'], $cart_shop_context); $tax_calculator = TaxManagerFactory::getManager($address, $id_tax_rules_group)->getTaxCalculator(); $row['price'] = Product::getPriceStatic((int) $row['id_product'], false, isset($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null, 6, null, false, true, $row['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : null, (int) $this->id, $address_id, $specific_price_output, false, true, $cart_shop_context); switch (Configuration::get('PS_ROUND_TYPE')) { case Order::ROUND_TOTAL: $row['total'] = $row['price'] * (int) $row['cart_quantity']; $row['total_wt'] = $tax_calculator->addTaxes($row['price']) * (int) $row['cart_quantity']; break; case Order::ROUND_LINE: $row['total'] = Tools::ps_round($row['price'] * (int) $row['cart_quantity'], _PS_PRICE_COMPUTE_PRECISION_); $row['total_wt'] = Tools::ps_round($tax_calculator->addTaxes($row['price']) * (int) $row['cart_quantity'], _PS_PRICE_COMPUTE_PRECISION_); break; case Order::ROUND_ITEM: default: $row['total'] = Tools::ps_round($row['price'], _PS_PRICE_COMPUTE_PRECISION_) * (int) $row['cart_quantity']; $row['total_wt'] = Tools::ps_round($tax_calculator->addTaxes($row['price']), _PS_PRICE_COMPUTE_PRECISION_) * (int) $row['cart_quantity']; break; } $row['price_wt'] = $tax_calculator->addTaxes($row['price']); $row['description_short'] = Tools::nl2br($row['description_short']); if (!isset($row['pai_id_image']) || $row['pai_id_image'] == 0) { $cache_id = 'Cart::getProducts_' . '-pai_id_image-' . (int) $row['id_product'] . '-' . (int) $this->id_lang . '-' . (int) $row['id_shop']; if (!Cache::isStored($cache_id)) { $row2 = Db::getInstance()->getRow(' SELECT image_shop.`id_image` id_image, il.`legend` FROM `' . _DB_PREFIX_ . 'image` i JOIN `' . _DB_PREFIX_ . 'image_shop` image_shop ON (i.id_image = image_shop.id_image AND image_shop.cover=1 AND image_shop.id_shop=' . (int) $row['id_shop'] . ') LEFT JOIN `' . _DB_PREFIX_ . 'image_lang` il ON (image_shop.`id_image` = il.`id_image` AND il.`id_lang` = ' . (int) $this->id_lang . ') WHERE i.`id_product` = ' . (int) $row['id_product'] . ' AND image_shop.`cover` = 1'); Cache::store($cache_id, $row2); } $row2 = Cache::retrieve($cache_id); if (!$row2) { $row2 = array('id_image' => false, 'legend' => false); } else { $row = array_merge($row, $row2); } } else { $row['id_image'] = $row['pai_id_image']; $row['legend'] = $row['pai_legend']; } $row['reduction_applies'] = $specific_price_output && (double) $specific_price_output['reduction']; $row['quantity_discount_applies'] = $specific_price_output && $row['cart_quantity'] >= (int) $specific_price_output['from_quantity']; $row['id_image'] = Product::defineProductImage($row, $this->id_lang); $row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']); $row['features'] = Product::getFeaturesStatic((int) $row['id_product']); if (array_key_exists($row['id_product_attribute'] . '-' . $this->id_lang, self::$_attributesLists)) { $row = array_merge($row, self::$_attributesLists[$row['id_product_attribute'] . '-' . $this->id_lang]); } /* * EU-Legal * assign standard delivery times to products */ $row['delivery_now'] = !empty($row['delivery_now']) ? $row['delivery_now'] : Configuration::get('LEGAL_DELIVERY_NOW', $this->id_lang); $row['delivery_later'] = !empty($row['delivery_later']) ? $row['delivery_later'] : Configuration::get('LEGAL_DELIVERY_LATER', $this->id_lang); $row = Product::getTaxesInformations($row, $cart_shop_context); $this->_products[] = $row; } return $this->_products; }
protected function processChangeProductInCart() { $mode = Tools::getIsset('update') && $this->id_product ? 'update' : 'add'; if (!$this->id_product) { $this->errors[] = Tools::displayError('Product not found', !Tools::getValue('ajax')); } $product = new Product($this->id_product, true, $this->context->language->id); if (!$product->id || !$product->active || !$product->checkAccess($this->context->cart->id_customer)) { $this->errors[] = Tools::displayError('This product is no longer available.', !Tools::getValue('ajax')); return; } $qty_factor = 1; $ext_qty_factor = 1; $ext_prop_quantities = null; $id_cart_product = 0; $qty_behavior = 0; $icp = (int) Tools::getValue('icp'); $properties = $product->productProperties(); if ($icp && $this->context->cart->id) { $cart_products = $this->context->cart->getProducts(); if (count($cart_products)) { foreach ($cart_products as $cart_product) { if ($icp == (int) $cart_product['id_cart_product']) { $id_cart_product = $icp; if ($mode == 'add') { if (Tools::getValue('qty') != 'default') { $qty_factor = (int) Tools::getValue('qty'); } $_POST['qty'] = (double) $cart_product['cart_quantity_fractional'] > 0 ? (double) $cart_product['cart_quantity_fractional'] : ($product->qtyStep() > 0 ? $product->qtyStep() : 1); } elseif ($mode == 'update') { $qty_behavior = PP::qtyBehavior($product, $cart_product['cart_quantity']); } break; } } } } else { if ($properties['pp_ext'] == 1 && in_array($properties['pp_ext_policy'], array(0, 2))) { $ext_prop_quantities = array(); $ext_prop_qty_ratio = array(); if ($properties['pp_ext_policy'] == 2) { $prop = $product->productProp(); if ($this->id_product_attribute) { $id_product_attribute = $this->id_product_attribute; } else { if ($product->hasAttributes()) { $id_product_attribute = Product::getDefaultAttribute($product->id); } else { $id_product_attribute = 0; } } } $positions = count($properties['pp_ext_prop']); for ($position = 1; $position <= $positions; $position++) { $pp_ext_prop = $properties['pp_ext_prop'][$position]; if ($properties['pp_ext_policy'] == 2) { $q = PP::productProp($prop, $id_product_attribute, $position, 'quantity'); if ($q === false) { $q = (double) $pp_ext_prop['default_quantity']; } if ($q <= 0) { $q = 1; } } else { $q = PP::resolveInputQty(Tools::getValue('pp_ext_prop_quantity_' . $position, 'default'), $properties['pp_qty_policy'], $pp_ext_prop['qty_step'], $pp_ext_prop['default_quantity'] > 0 ? $pp_ext_prop['default_quantity'] : 1); } $ext_prop_quantities[$position] = $q; $ext_prop_qty_ratio[$position] = $properties['pp_ext_prop'][$position]['qty_ratio']; if ($q <= 0) { $this->errors[] = Tools::displayError('Quantity not specified.', !Tools::getValue('ajax')); } $min_qty = (double) $pp_ext_prop['minimum_quantity']; if ($min_qty > 0 && $q < $min_qty) { $this->errors[] = Tools::displayError(sprintf('Please specify at least %s for %s', (string) PP::formatQty($min_qty), (string) $pp_ext_prop['property']), !Tools::getValue('ajax')); } $max_qty = (double) $pp_ext_prop['maximum_quantity']; if ($max_qty > 0 && $q > $max_qty) { $this->errors[] = Tools::displayError(sprintf('Please specify no more than %s for %s', (string) PP::formatQty($max_qty), (string) $pp_ext_prop['property']), !Tools::getValue('ajax')); } } if (!$this->errors) { $ext_qty_factor = $properties['pp_ext_method'] == 1 ? 1 : 0; $positions = count($ext_prop_quantities); for ($position = 1; $position <= $positions; $position++) { $value = $ext_prop_quantities[$position]; $qty_ratio = $ext_prop_qty_ratio[$position]; if ($properties['pp_ext_method'] == 1) { $ext_qty_factor *= $qty_ratio > 0 ? $value / $qty_ratio : $value; } elseif ($properties['pp_ext_method'] == 2) { $ext_qty_factor += $qty_ratio > 0 ? $value / $qty_ratio : $value; } } } } } if (!$this->errors) { if ($this->id_product_attribute) { $default_quantity = $product->attributeDefaultQty($this->id_product_attribute); $this->qty = $qty_factor * $this->resolveInputQty($properties, $default_quantity); if ($this->qty == 0) { $this->errors[] = Tools::displayError('Quantity not specified.', !Tools::getValue('ajax')); } else { if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $ext_qty_factor * $this->qty)) { $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax')); } } } else { if ($product->hasAttributes()) { $min_quantity = $product->out_of_stock == 2 ? !Configuration::get('PS_ORDER_OUT_OF_STOCK') : !$product->out_of_stock; $this->id_product_attribute = Product::getDefaultAttribute($product->id, $min_quantity); if (!$this->id_product_attribute) { Tools::redirectAdmin($this->context->link->getProductLink($product)); } else { $default_quantity = $product->attributeDefaultQty($this->id_product_attribute); $this->qty = $qty_factor * $this->resolveInputQty($properties, $default_quantity); if ($this->qty == 0) { $this->errors[] = Tools::displayError('Quantity not specified.', !Tools::getValue('ajax')); } else { if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $ext_qty_factor * $this->qty)) { $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax')); } } } } else { $default_quantity = $product->defaultQty(); $this->qty = $qty_factor * $this->resolveInputQty($properties, $default_quantity); if ($this->qty == 0) { $this->errors[] = Tools::displayError('Quantity not specified.', !Tools::getValue('ajax')); } else { if (!$product->checkQty($ext_qty_factor * $this->qty)) { $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax')); } } } } } if (!$this->errors && ($mode == 'add' || $mode == 'update' && $qty_behavior)) { if ($mode == 'add' && !$this->context->cart->id) { if (Context::getContext()->cookie->id_guest) { $guest = new Guest(Context::getContext()->cookie->id_guest); $this->context->cart->mobile_theme = $guest->mobile_theme; } $this->context->cart->add(); if ($this->context->cart->id) { $this->context->cookie->id_cart = (int) $this->context->cart->id; } } if (!$product->hasAllRequiredCustomizableFields() && !$this->customization_id) { $this->errors[] = Tools::displayError('Please fill in all of the required fields, and then save your customizations.', !Tools::getValue('ajax')); } if (!$this->errors) { $cart_rules = $this->context->cart->getCartRules(); $update_quantity = $this->context->cart->updateQty($id_cart_product ? $mode == 'add' ? $qty_factor : $this->qty : ($ext_prop_quantities !== null ? $ext_qty_factor : $this->qty), $this->id_product, $this->id_product_attribute, $this->customization_id, $mode == 'update' ? 'update' : Tools::getValue('op', 'up'), $this->id_address_delivery, null, true, $id_cart_product, $ext_prop_quantities, $this->qty); if ($update_quantity < 0) { $minimal_quantity = $this->id_product_attribute ? $product->attributeMinQty($this->id_product_attribute) : $product->minQty(); $this->errors[] = Tools::displayError(sprintf('You must add %s minimum quantity', $minimal_quantity), !Tools::getValue('ajax')); } elseif (!$update_quantity) { $this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.', !Tools::getValue('ajax')); } elseif ((int) Tools::getValue('allow_refresh')) { $cart_rules2 = $this->context->cart->getCartRules(); if (count($cart_rules2) != count($cart_rules)) { $this->ajax_refresh = true; } else { $rule_list = array(); foreach ($cart_rules2 as $rule) { $rule_list[] = $rule['id_cart_rule']; } foreach ($cart_rules as $rule) { if (!in_array($rule['id_cart_rule'], $rule_list)) { $this->ajax_refresh = true; break; } } } } } } $removed = CartRule::autoRemoveFromCart(); CartRule::autoAddToCart(); if (count($removed) && (int) Tools::getValue('allow_refresh')) { $this->ajax_refresh = true; } }
/** * @param \Product $product * * @return bool * @author Panagiotis Vagenas <*****@*****.**> * @since 150213 */ protected function backOrdersAllowed(\Product $product) { return \Product::isAvailableWhenOutOfStock($product->out_of_stock) == 1; }
/** * This process add or update a product in the cart */ protected function processChangeProductInCart() { $mode = Tools::getIsset('update') && $this->id_product ? 'update' : 'add'; if ($this->qty == 0) { $this->errors[] = Tools::displayError('Null quantity.', !Tools::getValue('ajax')); } elseif (!$this->id_product) { $this->errors[] = Tools::displayError('Product not found', !Tools::getValue('ajax')); } $product = new Product($this->id_product, true, $this->context->language->id); if (!$product->id || !$product->active || !$product->checkAccess($this->context->cart->id_customer)) { $this->errors[] = Tools::displayError('This product is no longer available.', !Tools::getValue('ajax')); return; } $qty_to_check = $this->qty; $cart_products = $this->context->cart->getProducts(); if (is_array($cart_products)) { foreach ($cart_products as $cart_product) { if ((!isset($this->id_product_attribute) || $cart_product['id_product_attribute'] == $this->id_product_attribute) && (isset($this->id_product) && $cart_product['id_product'] == $this->id_product)) { $qty_to_check = $cart_product['cart_quantity']; if (Tools::getValue('op', 'up') == 'down') { $qty_to_check -= $this->qty; } else { $qty_to_check += $this->qty; } break; } } } // Check product quantity availability if ($this->id_product_attribute) { if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) { $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax')); } } elseif ($product->hasAttributes()) { $minimumQuantity = $product->out_of_stock == 2 ? !Configuration::get('PS_ORDER_OUT_OF_STOCK') : !$product->out_of_stock; $this->id_product_attribute = Product::getDefaultAttribute($product->id, $minimumQuantity); // @todo do something better than a redirect admin !! if (!$this->id_product_attribute) { Tools::redirectAdmin($this->context->link->getProductLink($product)); } elseif (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) { $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax')); } } elseif (!$product->checkQty($qty_to_check)) { $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax')); } // If no errors, process product addition if (!$this->errors && $mode == 'add') { // Add cart if no cart found if (!$this->context->cart->id) { if (Context::getContext()->cookie->id_guest) { $guest = new Guest(Context::getContext()->cookie->id_guest); $this->context->cart->mobile_theme = $guest->mobile_theme; } $this->context->cart->add(); if ($this->context->cart->id) { $this->context->cookie->id_cart = (int) $this->context->cart->id; } } // Check customizable fields if (!$product->hasAllRequiredCustomizableFields() && !$this->customization_id) { $this->errors[] = Tools::displayError('Please fill in all of the required fields, and then save your customizations.', !Tools::getValue('ajax')); } if (!$this->errors) { $cart_rules = $this->context->cart->getCartRules(); $available_cart_rules = CartRule::getCustomerCartRules($this->context->language->id, isset($this->context->customer->id) ? $this->context->customer->id : 0, true, true, true, $this->context->cart, false, true); $update_quantity = $this->context->cart->updateQty($this->qty, $this->id_product, $this->id_product_attribute, $this->customization_id, Tools::getValue('op', 'up'), $this->id_address_delivery); if ($update_quantity < 0) { // If product has attribute, minimal quantity is set with minimal quantity of attribute $minimal_quantity = $this->id_product_attribute ? Attribute::getAttributeMinimalQty($this->id_product_attribute) : $product->minimal_quantity; $this->errors[] = sprintf(Tools::displayError('You must add %d minimum quantity', !Tools::getValue('ajax')), $minimal_quantity); } elseif (!$update_quantity) { $this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.', !Tools::getValue('ajax')); } elseif ((int) Tools::getValue('allow_refresh')) { // If the cart rules has changed, we need to refresh the whole cart $cart_rules2 = $this->context->cart->getCartRules(); if (count($cart_rules2) != count($cart_rules)) { $this->ajax_refresh = true; } elseif (count($cart_rules2)) { $rule_list = array(); foreach ($cart_rules2 as $rule) { $rule_list[] = $rule['id_cart_rule']; } foreach ($cart_rules as $rule) { if (!in_array($rule['id_cart_rule'], $rule_list)) { $this->ajax_refresh = true; break; } } } else { $available_cart_rules2 = CartRule::getCustomerCartRules($this->context->language->id, isset($this->context->customer->id) ? $this->context->customer->id : 0, true, true, true, $this->context->cart, false, true); if (count($available_cart_rules2) != count($available_cart_rules)) { $this->ajax_refresh = true; } elseif (count($available_cart_rules2)) { $rule_list = array(); foreach ($available_cart_rules2 as $rule) { $rule_list[] = $rule['id_cart_rule']; } foreach ($cart_rules2 as $rule) { if (!in_array($rule['id_cart_rule'], $rule_list)) { $this->ajax_refresh = true; break; } } } } } } } $removed = CartRule::autoRemoveFromCart(); CartRule::autoAddToCart(); if (count($removed) && (int) Tools::getValue('allow_refresh')) { $this->ajax_refresh = true; } }
public function process() { global $cart, $currency; parent::process(); if (!($id_product = (int) Tools::getValue('id_product')) or !Validate::isUnsignedId($id_product)) { $this->errors[] = Tools::displayError('Product not found'); } else { if (!Validate::isLoadedObject($this->product) or !$this->product->active and Tools::getValue('adtoken') != Tools::encrypt('PreviewProduct' . $this->product->id) || !file_exists(dirname(__FILE__) . '/../' . Tools::getValue('ad') . '/ajax.php')) { header('HTTP/1.1 404 page not found'); $this->errors[] = Tools::displayError('Product is no longer available.'); } elseif (!$this->product->checkAccess((int) self::$cookie->id_customer)) { $this->errors[] = Tools::displayError('You do not have access to this product.'); } else { self::$smarty->assign('virtual', ProductDownload::getIdFromIdProduct((int) $this->product->id)); if (!$this->product->active) { self::$smarty->assign('adminActionDisplay', true); } /* rewrited url set */ $rewrited_url = self::$link->getProductLink($this->product->id, $this->product->link_rewrite); /* Product pictures management */ require_once 'images.inc.php'; self::$smarty->assign('customizationFormTarget', Tools::safeOutput(urldecode($_SERVER['REQUEST_URI']))); if (Tools::isSubmit('submitCustomizedDatas')) { $this->pictureUpload($this->product, $cart); $this->textRecord($this->product, $cart); $this->formTargetFormat(); } elseif (isset($_GET['deletePicture']) and !$cart->deletePictureToProduct((int) $this->product->id, (int) Tools::getValue('deletePicture'))) { $this->errors[] = Tools::displayError('An error occurred while deleting the selected picture'); } $files = self::$cookie->getFamily('pictures_' . (int) $this->product->id); $textFields = self::$cookie->getFamily('textFields_' . (int) $this->product->id); foreach ($textFields as $key => $textField) { $textFields[$key] = str_replace('<br />', "\n", $textField); } self::$smarty->assign(array('pictures' => $files, 'textFields' => $textFields)); if ((int) Tools::getValue('pp') == 1) { echo 'here1'; } $productPriceWithTax = Product::getPriceStatic($id_product, true, NULL, 6); if (Product::$_taxCalculationMethod == PS_TAX_INC) { $productPriceWithTax = Tools::ps_round($productPriceWithTax, 2); } if ((int) Tools::getValue('pp') == 1) { $time2 = time(); echo 'time2: ' . $time2; } $productPriceWithoutEcoTax = (double) ($productPriceWithTax - $this->product->ecotax); $configs = Configuration::getMultiple(array('PS_ORDER_OUT_OF_STOCK', 'PS_LAST_QTIES')); /* Features / Values */ $features = $this->product->getFrontFeatures((int) self::$cookie->id_lang); $attachments = $this->product->getAttachments((int) self::$cookie->id_lang); /* Category */ $category = false; if (isset($_SERVER['HTTP_REFERER']) and preg_match('!^(.*)\\/([0-9]+)\\-(.*[^\\.])|(.*)id_category=([0-9]+)(.*)$!', $_SERVER['HTTP_REFERER'], $regs) and !strstr($_SERVER['HTTP_REFERER'], '.html')) { if (isset($regs[2]) and is_numeric($regs[2])) { if (Product::idIsOnCategoryId((int) $this->product->id, array('0' => array('id_category' => (int) $regs[2])))) { $category = new Category((int) $regs[2], (int) self::$cookie->id_lang); } } elseif (isset($regs[5]) and is_numeric($regs[5])) { if (Product::idIsOnCategoryId((int) $this->product->id, array('0' => array('id_category' => (int) $regs[5])))) { $category = new Category((int) $regs[5], (int) self::$cookie->id_lang); } } } if (!$category) { $category = new Category($this->product->id_category_default, (int) self::$cookie->id_lang); } if (isset($category) and Validate::isLoadedObject($category)) { self::$smarty->assign(array('path' => Tools::getPath((int) $category->id, $this->product->name, true), 'category' => $category, 'subCategories' => $category->getSubCategories((int) self::$cookie->id_lang, true), 'id_category_current' => (int) $category->id, 'id_category_parent' => (int) $category->id_parent, 'return_category_name' => Tools::safeOutput($category->name))); } else { self::$smarty->assign('path', Tools::getPath((int) $this->product->id_category_default, $this->product->name)); } self::$smarty->assign('return_link', (isset($category->id) and $category->id) ? Tools::safeOutput(self::$link->getCategoryLink($category)) : 'javascript: history.back();'); $lang = Configuration::get('PS_LANG_DEFAULT'); if (Pack::isPack((int) $this->product->id, (int) $lang) and !Pack::isInStock((int) $this->product->id, (int) $lang)) { $this->product->quantity = 0; } $group_reduction = (100 - Group::getReduction((int) self::$cookie->id_customer)) / 100; $id_customer = (isset(self::$cookie->id_customer) and self::$cookie->id_customer) ? (int) self::$cookie->id_customer : 0; $id_group = $id_customer ? (int) Customer::getDefaultGroupId($id_customer) : _PS_DEFAULT_CUSTOMER_GROUP_; $id_country = (int) ($id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get('PS_COUNTRY_DEFAULT')); if ((int) Tools::getValue('pp') == 1) { $time3 = time(); echo 'time3: ' . $time3; } // Tax $tax = (double) Tax::getProductTaxRate((int) $this->product->id, $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); self::$smarty->assign('tax_rate', $tax); $ecotax_rate = (double) Tax::getProductEcotaxRate($cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); $ecotaxTaxAmount = Tools::ps_round($this->product->ecotax, 2); if (Product::$_taxCalculationMethod == PS_TAX_INC && (int) Configuration::get('PS_TAX')) { $ecotaxTaxAmount = Tools::ps_round($ecotaxTaxAmount * (1 + $ecotax_rate / 100), 2); } $manufacturer = new Manufacturer((int) $this->product->id_manufacturer, 1); $sizechart = new Sizechart((int) $this->product->id_sizechart, 1); //see if the product is already in the wishlist if ($id_customer) { $sql = "select id from ps_wishlist where id_customer = " . $id_customer . " and id_product = " . $this->product->id; $res = Db::getInstance()->ExecuteS($sql); if ($res) { self::$smarty->assign("in_wishlist", true); } else { self::$smarty->assign("in_wishlist", false); } } else { self::$smarty->assign("in_wishlist", false); } self::$smarty->assign(array('quantity_discounts' => $this->formatQuantityDiscounts(SpecificPrice::getQuantityDiscounts((int) $this->product->id, (int) Shop::getCurrentShop(), (int) self::$cookie->id_currency, $id_country, $id_group), $this->product->getPrice(Product::$_taxCalculationMethod == PS_TAX_INC, false), (double) $tax), 'product' => $this->product, 'ecotax_tax_inc' => $ecotaxTaxAmount, 'ecotax_tax_exc' => Tools::ps_round($this->product->ecotax, 2), 'ecotaxTax_rate' => $ecotax_rate, 'homeSize' => Image::getSize('home'), 'product_manufacturer' => $manufacturer, 'token' => Tools::getToken(false), 'productPriceWithoutEcoTax' => (double) $productPriceWithoutEcoTax, 'features' => $features, 'attachments' => $attachments, 'allow_oosp' => $this->product->isAvailableWhenOutOfStock((int) $this->product->out_of_stock), 'last_qties' => (int) $configs['PS_LAST_QTIES'], 'group_reduction' => $group_reduction, 'col_img_dir' => _PS_COL_IMG_DIR_, 'sizechart' => $sizechart->sizechart, 'sizechart_data' => $sizechart->sizechart_data)); self::$smarty->assign(array('HOOK_EXTRA_LEFT' => Module::hookExec('extraLeft'), 'HOOK_EXTRA_RIGHT' => Module::hookExec('extraRight'), 'HOOK_PRODUCT_OOS' => Hook::productOutOfStock($this->product), 'HOOK_PRODUCT_FOOTER' => Hook::productFooter($this->product, $category), 'HOOK_PRODUCT_ACTIONS' => Module::hookExec('productActions'), 'HOOK_PRODUCT_TAB' => Module::hookExec('productTab'), 'HOOK_PRODUCT_TAB_CONTENT' => Module::hookExec('productTabContent'))); if ((int) Tools::getValue('pp') == 1) { $time4 = time(); echo 'time4: ' . $time4; } $images = $this->product->getImages((int) self::$cookie->id_lang); $productImages = array(); foreach ($images as $k => $image) { if ($image['cover']) { self::$smarty->assign('mainImage', $images[0]); $cover = $image; $cover['id_image'] = Configuration::get('PS_LEGACY_IMAGES') ? $this->product->id . '-' . $image['id_image'] : $image['id_image']; $cover['id_image_only'] = (int) $image['id_image']; } $productImages[(int) $image['id_image']] = $image; } if (!isset($cover)) { $cover = array('id_image' => Language::getIsoById(self::$cookie->id_lang) . '-default', 'legend' => 'No picture', 'title' => 'No picture'); } $size = Image::getSize('large'); self::$smarty->assign(array('cover' => $cover, 'imgWidth' => (int) $size['width'], 'mediumSize' => Image::getSize('medium'), 'largeSize' => Image::getSize('large'), 'accessories' => $this->product->getAccessories((int) self::$cookie->id_lang))); if (sizeof($productImages)) { self::$smarty->assign('images', $productImages); } if ((int) Tools::getValue('pp') == 1) { $time5 = time(); echo 'time5: ' . $time5; } /* Attributes / Groups & colors */ $colors = array(); //see if the product has shades if ($this->product->id_group && $this->product->id_group > 0) { global $link; $related_productIds = $this->product->getRelatedProducts(); $related_products = array(); foreach ($related_productIds as &$productId) { $relProduct = new Product((int) $productId['id_product'], true, self::$cookie->id_lang); $idImage = $relProduct->getCoverWs(); if ($idImage) { $idImage = $relProduct->id . '-' . $idImage; } else { $idImage = Language::getIsoById(1) . '-default'; } $relProduct->image_link = $link->getImageLink($relProduct->link_rewrite, $idImage, 'small'); $relProduct->link = $relProduct->getLink(); $related_products[] = $relProduct; } self::$smarty->assign('relatedProducts', $related_products); } if ((int) Tools::getValue('pp') == 1) { $time6 = time(); echo 'time6: ' . $time6; } $attributesGroups = $this->product->getAttributesGroups((int) self::$cookie->id_lang); // @todo (RM) should only get groups and not all declination ? if (is_array($attributesGroups) and $attributesGroups) { $groups = array(); $combinationImages = $this->product->getCombinationImages((int) self::$cookie->id_lang); foreach ($attributesGroups as $k => $row) { /* Color management */ if ((isset($row['attribute_color']) and $row['attribute_color'] or file_exists(_PS_COL_IMG_DIR_ . $row['id_attribute'] . '.jpg')) and $row['id_attribute_group'] == $this->product->id_color_default) { $colors[$row['id_attribute']]['value'] = $row['attribute_color']; $colors[$row['id_attribute']]['name'] = $row['attribute_name']; if (!isset($colors[$row['id_attribute']]['attributes_quantity'])) { $colors[$row['id_attribute']]['attributes_quantity'] = 0; } $colors[$row['id_attribute']]['attributes_quantity'] += (int) $row['quantity']; } if (!isset($groups[$row['id_attribute_group']])) { $groups[$row['id_attribute_group']] = array('name' => $row['public_group_name'], 'is_color_group' => $row['is_color_group'], 'default' => -1); } $groups[$row['id_attribute_group']]['attributes'][$row['id_attribute']] = $row['attribute_name']; if ($row['default_on'] && $groups[$row['id_attribute_group']]['default'] == -1) { $groups[$row['id_attribute_group']]['default'] = (int) $row['id_attribute']; } if (!isset($groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']])) { $groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] = 0; } $groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] += (int) $row['quantity']; $combinations[$row['id_product_attribute']]['attributes_values'][$row['id_attribute_group']] = $row['attribute_name']; $combinations[$row['id_product_attribute']]['attributes'][] = (int) $row['id_attribute']; $combinations[$row['id_product_attribute']]['price'] = (double) $row['price']; $combinations[$row['id_product_attribute']]['ecotax'] = (double) $row['ecotax']; $combinations[$row['id_product_attribute']]['weight'] = (double) $row['weight']; $combinations[$row['id_product_attribute']]['quantity'] = (int) $row['quantity']; $combinations[$row['id_product_attribute']]['reference'] = $row['reference']; $combinations[$row['id_product_attribute']]['unit_impact'] = $row['unit_price_impact']; $combinations[$row['id_product_attribute']]['minimal_quantity'] = $row['minimal_quantity']; $combinations[$row['id_product_attribute']]['id_image'] = isset($combinationImages[$row['id_product_attribute']][0]['id_image']) ? $combinationImages[$row['id_product_attribute']][0]['id_image'] : -1; } if ((int) Tools::getValue('pp') == 1) { $time7 = time(); echo 'time7: ' . $time7; } //wash attributes list (if some attributes are unavailables and if allowed to wash it) if (!Product::isAvailableWhenOutOfStock($this->product->out_of_stock) && Configuration::get('PS_DISP_UNAVAILABLE_ATTR') == 0) { foreach ($groups as &$group) { foreach ($group['attributes_quantity'] as $key => &$quantity) { if (!$quantity) { unset($group['attributes'][$key]); } } } foreach ($colors as $key => $color) { if (!$color['attributes_quantity']) { unset($colors[$key]); } } } if ((int) Tools::getValue('pp') == 1) { $time71 = time(); echo 'time71: ' . $time71; } foreach ($groups as &$group) { natcasesort($group['attributes']); } foreach ($combinations as $id_product_attribute => $comb) { $attributeList = ''; foreach ($comb['attributes'] as $id_attribute) { $attributeList .= '\'' . (int) $id_attribute . '\','; } $attributeList = rtrim($attributeList, ','); $combinations[$id_product_attribute]['list'] = $attributeList; } self::$smarty->assign(array('groups' => $groups, 'combinaisons' => $combinations, 'combinations' => $combinations, 'colors' => (sizeof($colors) and $this->product->id_color_default) ? $colors : false, 'combinationImages' => $combinationImages)); } if ((int) Tools::getValue('pp') == 1) { $time72 = time(); echo 'time72: ' . $time72; } //$newProducts = Product::getNewProducts((int)(self::$cookie->id_lang), 0, 10, false, 'date_add', 'desc'); /*$categoryProducts = $this->getRandomCatProducts(); self::$smarty->assign('cat_products', $categoryProducts);*/ //$brandProducts = $this->getRandomBrandProducts(); //self::$smarty->assign('brand_products', $brandProducts); if ((int) Tools::getValue('pp') == 1) { $time73 = time(); echo ' time73: ' . $time73; } self::$smarty->assign(array('no_tax' => Tax::excludeTaxeOption() or !Tax::getProductTaxRate((int) $this->product->id, $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}), 'customizationFields' => $this->product->getCustomizationFields((int) self::$cookie->id_lang))); if ((int) Tools::getValue('pp') == 1) { $time74 = time(); echo 'time74: ' . $time74; } // Pack management self::$smarty->assign('packItems', $this->product->cache_is_pack ? Pack::getItemTable($this->product->id, (int) self::$cookie->id_lang, true) : array()); self::$smarty->assign('packs', Pack::getPacksTable($this->product->id, (int) self::$cookie->id_lang, true, 1)); if ((int) Tools::getValue('pp') == 1) { print_r('pack done'); } } } if ((int) Tools::getValue('pp') == 1) { $time8 = time(); echo 'time8: ' . $time8; } if ($this->is_saree || $this->is_lehenga) { if ($this->is_lehenga) { self::$smarty->assign('is_lehenga', $this->is_lehenga); } self::$smarty->assign('as_shown', (bool) $this->product->as_shown); /*if($blouse_measurements = $this->getCustomerMeasurements(self::$cookie->id_customer, 1)) self::$smarty->assign('measurement_info', $blouse_measurements); if($skirt_measurements = $this->getCustomerMeasurements(self::$cookie->id_customer, 2)) self::$smarty->assign('skirt_measurement_info', $skirt_measurements);*/ if ((int) Tools::getValue('pp') == 1) { $time81 = time(); echo 'time81: ' . $time81; } if ($this->is_saree) { //count of all styles mapped to this product $res = Db::getInstance()->getRow("select count(s.id_style) as style_count from ps_styles s inner join ps_product_style ps on ps.id_style = s.id_style and ps.id_product = {$id_product} and s.style_type = 1"); $style_count = (int) $res['style_count']; if ($style_count === 0) { // show the default style for sarees $style = array('id_style' => 1, 'style_image_small' => '1-small.png', 'style_name' => 'Round'); } else { $res = Db::getInstance()->getRow("select s.id_style, s.style_name, s.style_image_small from ps_styles s inner join ps_product_style ps on ps.id_style = s.id_style and ps.id_product = {$id_product} and s.style_type = 1 and ps.is_default = 1"); if (!empty($res)) { //show the default style for this product $style = array('id_style' => $res['id_style'], 'style_image_small' => $res['style_image_small'], 'style_name' => $res['style_name']); } } if ((int) Tools::getValue('pp') == 1) { $time82 = time(); echo 'time82: ' . $time82; } self::$smarty->assign('blouse_style_count', $style_count); self::$smarty->assign('blouse_style', $style); } } else { if ($this->is_skd || $this->is_skd_rts) { self::$smarty->assign('is_anarkali', $this->is_anarkali); if ($this->is_anarkali) { if ($kurta_measurements = $this->getCustomerMeasurements(self::$cookie->id_customer, 5)) { self::$smarty->assign('kurta_measurement_info', $kurta_measurements); } } else { if ($kurta_measurements = $this->getCustomerMeasurements(self::$cookie->id_customer, 3)) { self::$smarty->assign('kurta_measurement_info', $kurta_measurements); } } if ($salwar_measurements = $this->getCustomerMeasurements(self::$cookie->id_customer, 4)) { self::$smarty->assign('salwar_measurement_info', $salwar_measurements); } //get default styles for this product (RTS) if ($this->is_skd_rts) { $res = Db::getInstance()->ExecuteS("select count(s.id_style) as style_count, s.style_type, ps.id_product from ps_styles s inner join ps_product_style ps on ps.id_style = s.id_style and ps.id_product = {$id_product} group by ps.id_product,s.style_type"); foreach ($res as $s) { $style_count = (int) $s['style_count']; if ((int) $s['style_type'] === 4) { self::$smarty->assign('kurta_style_count', $style_count); } else { if ((int) $s['style_type'] === 5) { self::$smarty->assign('salwar_style_count', $style_count); } } } $res = Db::getInstance()->ExecuteS("select s.id_style, s.style_type, s.style_image_small, s.style_name from ps_styles s inner join ps_product_style ps on ps.id_style = s.id_style and ps.id_product = {$id_product} and ps.is_default = 1"); foreach ($res as $s) { $style = array('id_style' => $s['id_style'], 'style_image_small' => $s['style_image_small'], 'style_name' => $s['style_name']); if ((int) $s['style_type'] === 4) { self::$smarty->assign('kurta_style', $style); } else { if ((int) $s['style_type'] === 5) { self::$smarty->assign('salwar_style', $style); } } } } } } self::$smarty->assign('is_bottoms', $this->is_bottoms); self::$smarty->assign('is_abaya', $this->is_abaya); self::$smarty->assign('is_wristwear', $this->is_wristwear); self::$smarty->assign('is_pakistani_rts', $this->is_pakistani_rts); if ((int) Tools::getValue('pp') == 1) { $time85 = time(); echo 'time85: ' . $time85; } self::$smarty->assign(array('ENT_NOQUOTES' => ENT_NOQUOTES, 'outOfStockAllowed' => (int) Configuration::get('PS_ORDER_OUT_OF_STOCK'), 'errors' => $this->errors, 'categories' => Category::getHomeCategories((int) self::$cookie->id_lang), 'have_image' => Product::getCover((int) Tools::getValue('id_product')), 'tax_enabled' => Configuration::get('PS_TAX'), 'display_qties' => (int) Configuration::get('PS_DISPLAY_QTIES'), 'display_ht' => !Tax::excludeTaxeOption(), 'ecotax' => !sizeof($this->errors) and $this->product->ecotax > 0 ? Tools::convertPrice((double) $this->product->ecotax) : 0, 'currencySign' => $currency->sign, 'currencyRate' => $currency->conversion_rate, 'currencyFormat' => $currency->format, 'currencyBlank' => $currency->blank, 'jqZoomEnabled' => Configuration::get('PS_DISPLAY_JQZOOM'))); if ((int) Tools::getValue('pp') == 1) { $time9 = time(); echo 'time9: ' . $time9; } //add this to product stats //Tools::captureActivity(PSTAT_VIEWS,$id_product); if ((int) Tools::getValue('pp') == 1) { $time1 = time(); echo 'process end: ' . $time1; } }
public function getProducts($refresh = false, $id_product = false, $id_country = null) { if (!$this->id) { return array(); } // Product cache must be strictly compared to NULL, or else an empty cart will add dozens of queries if ($this->_products !== null && !$refresh) { // Return product row with specified ID if it exists if (is_int($id_product)) { foreach ($this->_products as $product) { if ($product['id_product'] == $id_product) { return array($product); } } return array(); } return $this->_products; } // Build query $sql = new DbQuery(); // Build SELECT $sql->select('cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, cp.id_shop, pl.`name`, p.`is_virtual`, pl.`description_short`, pl.`available_now`, pl.`available_later`, product_shop.`id_category_default`, p.`id_supplier`, p.`id_manufacturer`, product_shop.`on_sale`, product_shop.`ecotax`, product_shop.`additional_shipping_cost`, product_shop.`available_for_order`, product_shop.`price`, product_shop.`active`, product_shop.`unity`, product_shop.`unit_price_ratio`, stock.`quantity` AS quantity_available, p.`width`, p.`height`, p.`depth`, stock.`out_of_stock`, p.`weight`, p.`date_add`, p.`date_upd`, IFNULL(stock.quantity, 0) as quantity, pl.`link_rewrite`, cl.`link_rewrite` AS category, CONCAT(LPAD(cp.`id_product`, 10, 0), LPAD(IFNULL(cp.`id_product_attribute`, 0), 10, 0), IFNULL(cp.`id_address_delivery`, 0)) AS unique_id, cp.id_address_delivery, product_shop.`wholesale_price`, product_shop.advanced_stock_management, ps.product_supplier_reference supplier_reference'); // Build FROM $sql->from('cart_product', 'cp'); // Build JOIN $sql->leftJoin('product', 'p', 'p.`id_product` = cp.`id_product`'); $sql->innerJoin('product_shop', 'product_shop', '(product_shop.`id_shop` = cp.`id_shop` AND product_shop.`id_product` = p.`id_product`)'); $sql->leftJoin('product_lang', 'pl', ' p.`id_product` = pl.`id_product` AND pl.`id_lang` = ' . (int) $this->id_lang . Shop::addSqlRestrictionOnLang('pl', 'cp.id_shop')); $sql->leftJoin('category_lang', 'cl', ' product_shop.`id_category_default` = cl.`id_category` AND cl.`id_lang` = ' . (int) $this->id_lang . Shop::addSqlRestrictionOnLang('cl', 'cp.id_shop')); $sql->leftJoin('product_supplier', 'ps', 'ps.`id_product` = cp.`id_product` AND ps.`id_product_attribute` = cp.`id_product_attribute` AND ps.`id_supplier` = p.`id_supplier`'); // @todo test if everything is ok, then refactorise call of this method $sql->join(Product::sqlStock('cp', 'cp')); // Build WHERE clauses $sql->where('cp.`id_cart` = ' . (int) $this->id); if ($id_product) { $sql->where('cp.`id_product` = ' . (int) $id_product); } $sql->where('p.`id_product` IS NOT NULL'); // Build GROUP BY $sql->groupBy('unique_id'); // Build ORDER BY $sql->orderBy('p.`id_product`, cp.`id_product_attribute`, cp.`date_add` ASC'); if (Customization::isFeatureActive()) { $sql->select('cu.`id_customization`, cu.`quantity` AS customization_quantity'); $sql->leftJoin('customization', 'cu', 'p.`id_product` = cu.`id_product` AND cp.`id_product_attribute` = cu.`id_product_attribute` AND cu.`id_cart` = ' . (int) $this->id); } else { $sql->select('NULL AS customization_quantity, NULL AS id_customization'); } if (Combination::isFeatureActive()) { $sql->select(' product_attribute_shop.`price` AS price_attribute, product_attribute_shop.`ecotax` AS ecotax_attr, IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference, (p.`weight`+ pa.`weight`) weight_attribute, IF (IFNULL(pa.`ean13`, \'\') = \'\', p.`ean13`, pa.`ean13`) AS ean13, IF (IFNULL(pa.`upc`, \'\') = \'\', p.`upc`, pa.`upc`) AS upc, pai.`id_image` as pai_id_image, il.`legend` as pai_legend, IFNULL(product_attribute_shop.`minimal_quantity`, product_shop.`minimal_quantity`) as minimal_quantity '); $sql->leftJoin('product_attribute', 'pa', 'pa.`id_product_attribute` = cp.`id_product_attribute`'); $sql->leftJoin('product_attribute_shop', 'product_attribute_shop', '(product_attribute_shop.`id_shop` = cp.`id_shop` AND product_attribute_shop.`id_product_attribute` = pa.`id_product_attribute`)'); $sql->leftJoin('product_attribute_image', 'pai', 'pai.`id_product_attribute` = pa.`id_product_attribute`'); $sql->leftJoin('image_lang', 'il', 'il.`id_image` = pai.`id_image` AND il.`id_lang` = ' . (int) $this->id_lang); } else { $sql->select('p.`reference` AS reference, p.`ean13`, p.`upc` AS upc, product_shop.`minimal_quantity` AS minimal_quantity'); } $result = Db::getInstance()->executeS($sql); // Reset the cache before the following return, or else an empty cart will add dozens of queries $products_ids = array(); $pa_ids = array(); if ($result) { foreach ($result as $row) { $products_ids[] = $row['id_product']; $pa_ids[] = $row['id_product_attribute']; } } // Thus you can avoid one query per product, because there will be only one query for all the products of the cart Product::cacheProductsFeatures($products_ids); Cart::cacheSomeAttributesLists($pa_ids, $this->id_lang); $this->_products = array(); if (empty($result)) { return array(); } $cart_shop_context = Context::getContext()->cloneContext(); foreach ($result as &$row) { // $quantityDiscount = SpecificPrice::getQuantityDiscount((int)$row['id_product'], $row['id_shop'], // (int)$cart->id_currency, (int)$this->vat_address->id_country, // (int)$this->customer->id_default_group, (int)$row['cart_quantity'], false, null, null, $null, true, true, $this->context); // // echo '<pre>'; // print_r($quantityDiscount); // echo '</pre>'; if (isset($row['ecotax_attr']) && $row['ecotax_attr'] > 0) { $row['ecotax'] = (double) $row['ecotax_attr']; } $row['stock_quantity'] = (int) $row['quantity']; // for compatibility with 1.2 themes $row['quantity'] = (int) $row['cart_quantity']; if (isset($row['id_product_attribute']) && (int) $row['id_product_attribute'] && isset($row['weight_attribute'])) { $row['weight'] = (double) $row['weight_attribute']; } if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_invoice') { $address_id = (int) $this->id_address_invoice; } else { $address_id = (int) $row['id_address_delivery']; } if (!Address::addressExists($address_id)) { $address_id = null; } if ($cart_shop_context->shop->id != $row['id_shop']) { $cart_shop_context->shop = new Shop((int) $row['id_shop']); } if ($this->_taxCalculationMethod == PS_TAX_EXC) { $row['price'] = Product::getPriceStatic((int) $row['id_product'], false, isset($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null, 2, null, false, true, (int) $row['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : null, (int) $this->id, (int) $address_id ? (int) $address_id : null, $specific_price_output, true, true, $cart_shop_context); // Here taxes are computed only once the quantity has been applied to the product price $row['price_wt'] = Product::getPriceStatic((int) $row['id_product'], true, isset($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null, 2, null, false, true, (int) $row['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : null, (int) $this->id, (int) $address_id ? (int) $address_id : null, $null, true, true, $cart_shop_context); $tax_rate = Tax::getProductTaxRate((int) $row['id_product'], (int) $address_id); $row['total_wt'] = Tools::ps_round($row['price'] * (double) $row['cart_quantity'] * (1 + (double) $tax_rate / 100), 2); $row['total'] = $row['price'] * (int) $row['cart_quantity']; } else { $row['price'] = Product::getPriceStatic((int) $row['id_product'], false, (int) $row['id_product_attribute'], 2, null, false, true, $row['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : null, (int) $this->id, (int) $address_id ? (int) $address_id : null, $specific_price_output, true, true, $cart_shop_context); $row['price_wt'] = Product::getPriceStatic((int) $row['id_product'], true, (int) $row['id_product_attribute'], 2, null, false, true, $row['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : null, (int) $this->id, (int) $address_id ? (int) $address_id : null, $null, true, true, $cart_shop_context); // In case when you use QuantityDiscount, getPriceStatic() can be return more of 2 decimals $row['price_wt'] = Tools::ps_round($row['price_wt'], 2); $row['total_wt'] = $row['price_wt'] * (int) $row['cart_quantity']; $row['total'] = Tools::ps_round($row['price'] * (int) $row['cart_quantity'], 2); $row['description_short'] = Tools::nl2br($row['description_short']); } if (!isset($row['pai_id_image']) || $row['pai_id_image'] == 0) { $cache_id = 'Cart::getProducts_' . '-pai_id_image-' . (int) $row['id_product'] . '-' . (int) $this->id_lang . '-' . (int) $row['id_shop']; if (!Cache::isStored($cache_id)) { $row2 = Db::getInstance()->getRow(' SELECT image_shop.`id_image` id_image, il.`legend` FROM `' . _DB_PREFIX_ . 'image` i JOIN `' . _DB_PREFIX_ . 'image_shop` image_shop ON (i.id_image = image_shop.id_image AND image_shop.cover=1 AND image_shop.id_shop=' . (int) $row['id_shop'] . ') LEFT JOIN `' . _DB_PREFIX_ . 'image_lang` il ON (image_shop.`id_image` = il.`id_image` AND il.`id_lang` = ' . (int) $this->id_lang . ') WHERE i.`id_product` = ' . (int) $row['id_product'] . ' AND image_shop.`cover` = 1'); Cache::store($cache_id, $row2); } $row2 = Cache::retrieve($cache_id); if (!$row2) { $row2 = array('id_image' => false, 'legend' => false); } else { $row = array_merge($row, $row2); } } else { $row['id_image'] = $row['pai_id_image']; $row['legend'] = $row['pai_legend']; } $row['reduction_applies'] = $specific_price_output && (double) $specific_price_output['reduction']; $row['quantity_discount_applies'] = $specific_price_output && $row['cart_quantity'] >= (int) $specific_price_output['from_quantity']; $row['id_image'] = Product::defineProductImage($row, $this->id_lang); $row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']); $row['features'] = Product::getFeaturesStatic((int) $row['id_product']); if (array_key_exists($row['id_product_attribute'] . '-' . $this->id_lang, self::$_attributesLists)) { $row = array_merge($row, self::$_attributesLists[$row['id_product_attribute'] . '-' . $this->id_lang]); } if (Context::getContext()->language->id != 1) { $row['name'] = Tools::rus2translit($row['name']); } $row = Product::getTaxesInformations($row, $cart_shop_context); $this->_products[] = $row; } return $this->_products; }
private static function isAllowOOSP($product) { return Product::isAvailableWhenOutOfStock($product->out_of_stock); }
$idProduct = intval(Tools::getValue('id_product', NULL)); $idProductAttribute = intval(Tools::getValue('id_product_attribute', Tools::getValue('ipa'))); $customizationId = intval(Tools::getValue('id_customization', 0)); $qty = intval(abs(Tools::getValue('qty', 1))); if ($qty == 0) { $errors[] = Tools::displayError('null quantity'); } elseif (!$idProduct) { $errors[] = Tools::displayError('product not found'); } else { $producToAdd = new Product(intval($idProduct), false, intval($cookie->id_lang)); if ((!$producToAdd->id or !$producToAdd->active) and !$delete) { $errors[] = Tools::displayError('product is no longer available'); } else { /* Check the quantity availability */ if ($idProductAttribute and is_numeric($idProductAttribute)) { if (!$delete and !$producToAdd->isAvailableWhenOutOfStock($producToAdd->out_of_stock) and !Attribute::checkAttributeQty(intval($idProductAttribute), intval($qty))) { $errors[] = Tools::displayError('product is no longer available'); } } elseif ($producToAdd->hasAttributes() and !$delete) { $idProductAttribute = Product::getDefaultAttribute(intval($producToAdd->id), intval($producToAdd->out_of_stock) == 2 ? !intval(Configuration::get('PS_ORDER_OUT_OF_STOCK')) : !intval($producToAdd->out_of_stock)); if (!$idProductAttribute) { Tools::redirectAdmin($link->getProductLink($producToAdd)); } elseif (!$delete and !$producToAdd->isAvailableWhenOutOfStock($producToAdd->out_of_stock) and !Attribute::checkAttributeQty(intval($idProductAttribute), intval($qty))) { $errors[] = Tools::displayError('product is no longer available'); } } elseif (!$delete and !$producToAdd->checkQty(intval($qty))) { $errors[] = Tools::displayError('product is no longer available'); } /* Check vouchers compatibility */ if ($add and (intval($producToAdd->reduction_price) or intval($producToAdd->reduction_percent) or $producToAdd->on_sale)) { $discounts = $cart->getDiscounts();
public function hookActionProductOutOfStock($params) { if (!$this->customer_qty || !Configuration::get('PS_STOCK_MANAGEMENT') || Product::isAvailableWhenOutOfStock($params['product']->out_of_stock)) { return; } $context = Context::getContext(); $id_product = (int) $params['product']->id; $id_product_attribute = 0; $id_customer = (int) $context->customer->id; if ((int) $context->customer->id <= 0) { $this->context->smarty->assign('email', 1); } elseif (MailAlert::customerHasNotification($id_customer, $id_product, $id_product_attribute, (int) $context->shop->id)) { return; } $this->context->smarty->assign(array('id_product' => $id_product, 'id_product_attribute' => $id_product_attribute)); return $this->display(__FILE__, 'product.tpl'); }
public static function getProductProperties($id_lang, $row, Context $context = null) { Hook::exec('actionGetProductPropertiesBefore', ['id_lang' => $id_lang, 'product' => $row, 'context' => $context]); if (!$row['id_product']) { return false; } if ($context == null) { $context = Context::getContext(); } $id_product_attribute = $row['id_product_attribute'] = !empty($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null; // Product::getDefaultAttribute is only called if id_product_attribute is missing from the SQL query at the origin of it: // consider adding it in order to avoid unnecessary queries $row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']); if (Combination::isFeatureActive() && $id_product_attribute === null && (isset($row['cache_default_attribute']) && ($ipa_default = $row['cache_default_attribute']) !== null || ($ipa_default = Product::getDefaultAttribute($row['id_product'], !$row['allow_oosp'])))) { $id_product_attribute = $row['id_product_attribute'] = $ipa_default; } if (!Combination::isFeatureActive() || !isset($row['id_product_attribute'])) { $id_product_attribute = $row['id_product_attribute'] = 0; } // Tax $usetax = !Tax::excludeTaxeOption(); $cache_key = $row['id_product'] . '-' . $id_product_attribute . '-' . $id_lang . '-' . (int) $usetax; if (isset($row['id_product_pack'])) { $cache_key .= '-pack' . $row['id_product_pack']; } if (isset(self::$producPropertiesCache[$cache_key])) { return array_merge($row, self::$producPropertiesCache[$cache_key]); } // Datas $row['category'] = Category::getLinkRewrite((int) $row['id_category_default'], (int) $id_lang); $row['category_name'] = Db::getInstance()->getValue('SELECT name FROM ' . _DB_PREFIX_ . 'category_lang WHERE id_shop = ' . (int) $context->shop->id . ' AND id_lang = ' . (int) $id_lang . ' AND id_category = ' . (int) $row['id_category_default']); $row['link'] = $context->link->getProductLink((int) $row['id_product'], $row['link_rewrite'], $row['category'], $row['ean13']); $row['attribute_price'] = 0; if ($id_product_attribute) { $row['attribute_price'] = (double) Combination::getPrice($id_product_attribute); } if (isset($row['quantity_wanted'])) { // 'quantity_wanted' may very well be zero even if set $quantity = max((int) $row['minimal_quantity'], (int) $row['quantity_wanted']); } else { $quantity = (int) $row['minimal_quantity']; } $row['price_tax_exc'] = Product::getPriceStatic((int) $row['id_product'], false, $id_product_attribute, self::$_taxCalculationMethod == PS_TAX_EXC ? 2 : 6, null, false, true, $quantity); if (self::$_taxCalculationMethod == PS_TAX_EXC) { $row['price_tax_exc'] = Tools::ps_round($row['price_tax_exc'], 2); $row['price'] = Product::getPriceStatic((int) $row['id_product'], true, $id_product_attribute, 6, null, false, true, $quantity); $row['price_without_reduction'] = Product::getPriceStatic((int) $row['id_product'], false, $id_product_attribute, 2, null, false, false, $quantity); } else { $row['price'] = Tools::ps_round(Product::getPriceStatic((int) $row['id_product'], true, $id_product_attribute, 6, null, false, true, $quantity), (int) Configuration::get('PS_PRICE_DISPLAY_PRECISION')); $row['price_without_reduction'] = Product::getPriceStatic((int) $row['id_product'], true, $id_product_attribute, 6, null, false, false, $quantity); } $row['reduction'] = Product::getPriceStatic((int) $row['id_product'], (bool) $usetax, $id_product_attribute, 6, null, true, true, $quantity, true, null, null, null, $specific_prices); $row['specific_prices'] = $specific_prices; $row['quantity'] = Product::getQuantity((int) $row['id_product'], 0, isset($row['cache_is_pack']) ? $row['cache_is_pack'] : null); $row['quantity_all_versions'] = $row['quantity']; if ($row['id_product_attribute']) { $row['quantity'] = Product::getQuantity((int) $row['id_product'], $id_product_attribute, isset($row['cache_is_pack']) ? $row['cache_is_pack'] : null); $row['available_date'] = Product::getAvailableDate((int) $row['id_product'], $id_product_attribute); } $row['id_image'] = Product::defineProductImage($row, $id_lang); $row['features'] = Product::getFrontFeaturesStatic((int) $id_lang, $row['id_product']); $row['attachments'] = array(); if (!isset($row['cache_has_attachments']) || $row['cache_has_attachments']) { $row['attachments'] = Product::getAttachmentsStatic((int) $id_lang, $row['id_product']); } $row['virtual'] = !isset($row['is_virtual']) || $row['is_virtual'] ? 1 : 0; // Pack management $row['pack'] = !isset($row['cache_is_pack']) ? Pack::isPack($row['id_product']) : (int) $row['cache_is_pack']; $row['packItems'] = $row['pack'] ? Pack::getItemTable($row['id_product'], $id_lang) : array(); $row['nopackprice'] = $row['pack'] ? Pack::noPackPrice($row['id_product']) : 0; if ($row['pack'] && !Pack::isInStock($row['id_product'])) { $row['quantity'] = 0; } $row['customization_required'] = false; if (isset($row['customizable']) && $row['customizable'] && Customization::isFeatureActive()) { if (count(Product::getRequiredCustomizableFieldsStatic((int) $row['id_product']))) { $row['customization_required'] = true; } } $attributes = Product::getAttributesParams($row['id_product'], $row['id_product_attribute']); foreach ($attributes as $attribute) { $row['attributes'][$attribute['id_attribute_group']] = $attribute; } $row = Product::getTaxesInformations($row, $context); $row['ecotax_rate'] = (double) Tax::getProductEcotaxRate($context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); Hook::exec('actionGetProductPropertiesAfter', ['id_lang' => $id_lang, 'product' => $row, 'context' => $context]); $combination = new Combination($id_product_attribute); if (0 != $combination->unit_price_impact && 0 != $row['unit_price_ratio']) { $unitPrice = $row['price_tax_exc'] / $row['unit_price_ratio'] + $combination->unit_price_impact; $row['unit_price_ratio'] = $row['price_tax_exc'] / $unitPrice; } $row['unit_price'] = $row['unit_price_ratio'] != 0 ? $row['price'] / $row['unit_price_ratio'] : 0; self::$producPropertiesCache[$cache_key] = $row; return self::$producPropertiesCache[$cache_key]; }
public static function getProductProperties($id_lang, $row) { if (!$row['id_product']) { return false; } $row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']); if ((!isset($row['id_product_attribute']) or !$row['id_product_attribute']) and $ipa_default = Product::getDefaultAttribute($row['id_product'], !$row['allow_oosp'])) { $row['id_product_attribute'] = $ipa_default; } if (!isset($row['id_product_attribute'])) { $row['id_product_attribute'] = 0; } // Tax $usetax = true; $tax = floatval(Tax::getApplicableTax(intval($row['id_tax']), floatval($row['rate']))); if (Tax::excludeTaxeOption() or !$tax) { $usetax = false; } $cacheKey = $row['id_product'] . '-' . $row['id_product_attribute'] . '-' . $id_lang . '-' . intval($usetax); if (array_key_exists($cacheKey, self::$producPropertiesCache)) { return self::$producPropertiesCache[$cacheKey]; } // Datas $link = new Link(); $row['category'] = Category::getLinkRewrite($row['id_category_default'], intval($id_lang)); $row['link'] = $link->getProductLink($row['id_product'], $row['link_rewrite'], $row['category'], $row['ean13']); $row['attribute_price'] = (isset($row['id_product_attribute']) and $row['id_product_attribute']) ? floatval(Product::getProductAttributePrice($row['id_product_attribute'])) : 0; $row['price_tax_exc'] = Product::getPriceStatic($row['id_product'], false, (isset($row['id_product_attribute']) and !empty($row['id_product_attribute'])) ? intval($row['id_product_attribute']) : NULL, 6); if (self::$_taxCalculationMethod == PS_TAX_EXC) { $row['price_tax_exc'] = Tools::ps_round($row['price_tax_exc'], 2); $row['price'] = Product::getPriceStatic($row['id_product'], true, (isset($row['id_product_attribute']) and !empty($row['id_product_attribute'])) ? intval($row['id_product_attribute']) : NULL, 6); } else { $row['price'] = Tools::ps_round(Product::getPriceStatic($row['id_product'], true, (isset($row['id_product_attribute']) and !empty($row['id_product_attribute'])) ? intval($row['id_product_attribute']) : NULL, 6), 2); } $row['reduction'] = self::getReductionValue($row['reduction_price'], $row['reduction_percent'], $row['reduction_from'], $row['reduction_to'], $row['price'], $usetax, floatval($row['rate'])); $row['price_without_reduction'] = Product::getPriceStatic($row['id_product'], true, (isset($row['id_product_attribute']) and !empty($row['id_product_attribute'])) ? intval($row['id_product_attribute']) : NULL, 6, NULL, false, false); $row['quantity'] = Product::getQuantity($row['id_product']); $row['id_image'] = Product::defineProductImage($row); $row['features'] = Product::getFrontFeaturesStatic(intval($id_lang), $row['id_product']); $row['attachments'] = Product::getAttachmentsStatic(intval($id_lang), $row['id_product']); $row['pack'] = Pack::isPack($row['id_product']); $row['packItems'] = $row['pack'] ? Pack::getItemTable($row['id_product'], $id_lang) : array(); $row['nopackprice'] = $row['pack'] ? Pack::noPackPrice($row['id_product']) : 0; self::$producPropertiesCache[$cacheKey] = $row; return self::$producPropertiesCache[$cacheKey]; }
protected function restoreOrderToCart(Cart $cart) { if (!$cart || !ValidateCore::isLoadedObject($cart)) { return null; } Db::getInstance()->execute('BEGIN'); $new_cart = null; try { /** @var CartCore $new_cart */ /** @noinspection PhpUndefinedClassInspection */ $new_cart = new Cart(); /** @noinspection PhpUndefinedFieldInspection */ $new_cart->id_customer = (int) $cart->id_customer; /** @noinspection PhpUndefinedFieldInspection */ $new_cart->id_address_delivery = (int) $cart->id_address_delivery; /** @noinspection PhpUndefinedFieldInspection */ $new_cart->id_address_invoice = (int) $cart->id_address_invoice; /** @noinspection PhpUndefinedFieldInspection */ $new_cart->id_lang = (int) $cart->id_lang; /** @noinspection PhpUndefinedFieldInspection */ $new_cart->id_currency = (int) $cart->id_currency; /** @noinspection PhpUndefinedFieldInspection */ $new_cart->id_carrier = (int) $cart->id_carrier; /** @noinspection PhpUndefinedFieldInspection */ $new_cart->recyclable = (int) $cart->recyclable; /** @noinspection PhpUndefinedFieldInspection */ $new_cart->gift = (int) $cart->gift; $new_cart->add(); /** @noinspection PhpUndefinedMethodInspection */ $products = $cart->getProducts(); if ($products) { foreach ($products as $p) { $idProduct = $p['id_product']; $idProductAttribute = $p['id_product_attribute']; $qty = $p['cart_quantity']; /** @noinspection PhpUndefinedClassInspection */ /** @noinspection PhpUndefinedFieldInspection */ $producToAdd = new Product((int) $idProduct, true, (int) $cart->id_lang); /** @noinspection PhpUndefinedFieldInspection */ if (!$producToAdd->id || !$producToAdd->active) { continue; } /* Check the quantity availability */ if ($idProductAttribute > 0 and is_numeric($idProductAttribute)) { /** @noinspection PhpUndefinedClassInspection */ /** @noinspection PhpUndefinedMethodInspection */ /** @noinspection PhpUndefinedFieldInspection */ if (!$producToAdd->isAvailableWhenOutOfStock($producToAdd->out_of_stock) and !Attribute::checkAttributeQty((int) $idProductAttribute, (int) $qty)) { /* There is not enough product attribute in stock - set customer qty to current stock on hand */ /** @noinspection PhpUndefinedFunctionInspection */ $qty = getAttributeQty($idProductAttribute); } } elseif (!$producToAdd->checkQty((int) $qty)) { /* There is not enough product in stock - set customer qty to current stock on hand */ /** @noinspection PhpUndefinedMethodInspection */ $qty = $producToAdd->getQuantity($idProduct); } $new_cart->updateQty((int) $qty, (int) $idProduct, (int) $idProductAttribute, NULL, 'up'); unset($p); } } $new_cart->update(); Db::getInstance()->execute('COMMIT'); } catch (Exception $e) { Db::getInstance()->execute('ROLLBACK'); throw $e; } /** @noinspection PhpUndefinedFieldInspection */ $this->context->cookie->id_cart = (int) $new_cart->id; return $new_cart; }
/** * Returns module content for left column */ public function hookProductFooter($params) { $cache_id = 'crossselling_mod|productfooter|' . (int) $params['product']->id; if (!$this->isCached('crossselling_mod.tpl', $this->getCacheId($cache_id))) { $orders = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT o.id_order FROM ' . _DB_PREFIX_ . 'orders o LEFT JOIN ' . _DB_PREFIX_ . 'order_detail od ON (od.id_order = o.id_order) WHERE o.valid = 1 AND od.product_id = ' . (int) $params['product']->id); if (count($orders)) { $list = ''; foreach ($orders as $order) { $list .= (int) $order['id_order'] . ','; } $list = rtrim($list, ','); if (Group::isFeatureActive()) { $sql_groups_join = ' LEFT JOIN `' . _DB_PREFIX_ . 'category_product` cp ON (cp.`id_category` = product_shop.id_category_default AND cp.id_product = product_shop.id_product) LEFT JOIN `' . _DB_PREFIX_ . 'category_group` cg ON (cp.`id_category` = cg.`id_category`)'; $groups = FrontController::getCurrentCustomerGroups(); $sql_groups_where = 'AND cg.`id_group` ' . (count($groups) ? 'IN (' . implode(',', $groups) . ')' : '=' . (int) Group::getCurrent()->id); } $order_products = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT DISTINCT od.product_id, pl.name, pl.link_rewrite, p.reference, i.id_image, product_shop.show_price, product_shop.id_category_default, p.available_for_order, p.customizable, cl.link_rewrite category, p.ean13, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity FROM ' . _DB_PREFIX_ . 'order_detail od LEFT JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = od.product_id) ' . Shop::addSqlAssociation('product', 'p') . (Combination::isFeatureActive() ? 'LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON (p.`id_product` = pa.`id_product`) ' . Shop::addSqlAssociation('product_attribute', 'pa', false, 'product_attribute_shop.`default_on` = 1') . ' ' . Product::sqlStock('p', 'product_attribute_shop', false, $this->context->shop) : Product::sqlStock('p', 'product', false, $this->context->shop)) . ' LEFT JOIN ' . _DB_PREFIX_ . 'product_lang pl ON (pl.id_product = od.product_id' . Shop::addSqlRestrictionOnLang('pl') . ') LEFT JOIN ' . _DB_PREFIX_ . 'category_lang cl ON (cl.id_category = product_shop.id_category_default' . Shop::addSqlRestrictionOnLang('cl') . ') LEFT JOIN ' . _DB_PREFIX_ . 'image i ON (i.id_product = od.product_id) ' . (Group::isFeatureActive() ? $sql_groups_join : '') . ' WHERE od.id_order IN (' . $list . ') AND pl.id_lang = ' . (int) $this->context->language->id . ' AND cl.id_lang = ' . (int) $this->context->language->id . ' AND od.product_id != ' . (int) $params['product']->id . ' AND i.cover = 1 AND product_shop.active = 1 ' . (Group::isFeatureActive() ? $sql_groups_where : '') . ' ORDER BY RAND() LIMIT ' . (int) Configuration::get('CROSSSELLING_NBR_M')); $tax_calc = Product::getTaxCalculationMethod(); foreach ($order_products as &$order_product) { $order_product['id_product'] = (int) $order_product['product_id']; $order_product['image'] = $this->context->link->getImageLink($order_product['link_rewrite'], (int) $order_product['product_id'] . '-' . (int) $order_product['id_image'], ImageType::getFormatedName('home')); $order_product['link'] = $this->context->link->getProductLink((int) $order_product['product_id'], $order_product['link_rewrite'], $order_product['category'], $order_product['ean13']); if ($tax_calc == 0 || $tax_calc == 2) { $order_product['price'] = Product::getPriceStatic((int) $order_product['product_id'], true, null); } elseif ($tax_calc == 1) { $order_product['price'] = Product::getPriceStatic((int) $order_product['product_id'], false, null); } $order_product['allow_oosp'] = Product::isAvailableWhenOutOfStock((int) $order_product['out_of_stock']); } $order_products = Product::getProductsProperties((int) $this->context->language->id, $order_products); $this->smarty->assign(array('order' => false, 'orderProducts' => $order_products, 'homeSize' => Image::getSize(ImageType::getFormatedName('home')), 'middlePosition_crossselling' => round(count($order_products) / 2, 0), 'crossDisplayPrice' => Configuration::get('CROSSSELLING_DISPLAY_PRICE_M'))); } } return $this->display(__FILE__, 'crossselling_mod.tpl', $this->getCacheId($cache_id)); }
public function process() { global $cart, $currency; parent::process(); if (!Validate::isLoadedObject($this->product)) { $this->errors[] = Tools::displayError('Product not found'); } else { if (!$this->product->active and Tools::getValue('adtoken') != Tools::encrypt('PreviewProduct' . $this->product->id) || !file_exists(dirname(__FILE__) . '/../' . Tools::getValue('ad') . '/ajax.php')) { header('HTTP/1.1 404 page not found'); $this->errors[] = Tools::displayError('Product is no longer available.'); } elseif (!$this->product->checkAccess((int) self::$cookie->id_customer)) { $this->errors[] = Tools::displayError('You do not have access to this product.'); } else { self::$smarty->assign('virtual', ProductDownload::getIdFromIdProduct((int) $this->product->id)); if (!$this->product->active) { self::$smarty->assign('adminActionDisplay', true); } /* Product pictures management */ require_once 'images.inc.php'; if ($this->product->customizable) { self::$smarty->assign('customizationFormTarget', Tools::safeOutput(urldecode($_SERVER['REQUEST_URI']))); if (Tools::isSubmit('submitCustomizedDatas')) { $this->pictureUpload($this->product, $cart); $this->textRecord($this->product, $cart); $this->formTargetFormat(); } elseif (isset($_GET['deletePicture']) and !$cart->deletePictureToProduct((int) $this->product->id, (int) Tools::getValue('deletePicture'))) { $this->errors[] = Tools::displayError('An error occurred while deleting the selected picture'); } $files = self::$cookie->getFamily('pictures_' . (int) $this->product->id); $textFields = self::$cookie->getFamily('textFields_' . (int) $this->product->id); foreach ($textFields as $key => $textField) { $textFields[$key] = str_replace('<br />', "\n", $textField); } self::$smarty->assign(array('pictures' => $files, 'textFields' => $textFields)); } /* Features / Values */ $features = $this->product->getFrontFeatures((int) self::$cookie->id_lang); $attachments = $this->product->cache_has_attachments ? $this->product->getAttachments((int) self::$cookie->id_lang) : array(); /* Category */ $category = false; if (isset($_SERVER['HTTP_REFERER']) and preg_match('!^(.*)\\/([0-9]+)\\-(.*[^\\.])|(.*)id_category=([0-9]+)(.*)$!', $_SERVER['HTTP_REFERER'], $regs) and !strstr($_SERVER['HTTP_REFERER'], '.html')) { if (isset($regs[2]) and is_numeric($regs[2])) { if (Product::idIsOnCategoryId((int) $this->product->id, array('0' => array('id_category' => (int) $regs[2])))) { $category = new Category((int) $regs[2], (int) self::$cookie->id_lang); } } elseif (isset($regs[5]) and is_numeric($regs[5])) { if (Product::idIsOnCategoryId((int) $this->product->id, array('0' => array('id_category' => (int) $regs[5])))) { $category = new Category((int) $regs[5], (int) self::$cookie->id_lang); } } } if (!$category) { $category = new Category($this->product->id_category_default, (int) self::$cookie->id_lang); } if (isset($category) and Validate::isLoadedObject($category)) { self::$smarty->assign(array('path' => Tools::getPath((int) $category->id, $this->product->name, true), 'category' => $category, 'subCategories' => $category->getSubCategories((int) self::$cookie->id_lang, true), 'id_category_current' => (int) $category->id, 'id_category_parent' => (int) $category->id_parent, 'return_category_name' => Tools::safeOutput($category->name))); } else { self::$smarty->assign('path', Tools::getPath((int) $this->product->id_category_default, $this->product->name)); } self::$smarty->assign('return_link', (isset($category->id) and $category->id) ? Tools::safeOutput(self::$link->getCategoryLink($category)) : 'javascript: history.back();'); if (Pack::isPack((int) $this->product->id) and !Pack::isInStock((int) $this->product->id)) { $this->product->quantity = 0; } $group_reduction = (100 - Group::getReduction((int) self::$cookie->id_customer)) / 100; $id_customer = (isset(self::$cookie->id_customer) and self::$cookie->id_customer) ? (int) self::$cookie->id_customer : 0; $id_group = $id_customer ? (int) Customer::getDefaultGroupId($id_customer) : _PS_DEFAULT_CUSTOMER_GROUP_; $id_country = (int) ($id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get('PS_COUNTRY_DEFAULT')); // Tax $tax = (double) Tax::getProductTaxRate((int) $this->product->id, $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); self::$smarty->assign('tax_rate', $tax); $productPriceWithTax = Product::getPriceStatic($this->product->id, true, NULL, 6); if (Product::$_taxCalculationMethod == PS_TAX_INC) { $productPriceWithTax = Tools::ps_round($productPriceWithTax, 2); } $productPriceWithoutEcoTax = (double) ($productPriceWithTax - $this->product->ecotax); $ecotax_rate = (double) Tax::getProductEcotaxRate($cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); $ecotaxTaxAmount = Tools::ps_round($this->product->ecotax, 2); if (Product::$_taxCalculationMethod == PS_TAX_INC && (int) Configuration::get('PS_TAX')) { $ecotaxTaxAmount = Tools::ps_round($ecotaxTaxAmount * (1 + $ecotax_rate / 100), 2); } self::$smarty->assign(array('quantity_discounts' => $this->formatQuantityDiscounts(SpecificPrice::getQuantityDiscounts((int) $this->product->id, (int) Shop::getCurrentShop(), (int) self::$cookie->id_currency, $id_country, $id_group), $this->product->getPrice(Product::$_taxCalculationMethod == PS_TAX_INC, false), (double) $tax), 'product' => $this->product, 'ecotax_tax_inc' => $ecotaxTaxAmount, 'ecotax_tax_exc' => Tools::ps_round($this->product->ecotax, 2), 'ecotaxTax_rate' => $ecotax_rate, 'homeSize' => Image::getSize('home'), 'product_manufacturer' => new Manufacturer((int) $this->product->id_manufacturer, self::$cookie->id_lang), 'token' => Tools::getToken(false), 'productPriceWithoutEcoTax' => (double) $productPriceWithoutEcoTax, 'features' => $features, 'attachments' => $attachments, 'allow_oosp' => $this->product->isAvailableWhenOutOfStock((int) $this->product->out_of_stock), 'last_qties' => (int) Configuration::get('PS_LAST_QTIES'), 'group_reduction' => $group_reduction, 'col_img_dir' => _PS_COL_IMG_DIR_)); self::$smarty->assign(array('HOOK_EXTRA_LEFT' => Module::hookExec('extraLeft'), 'HOOK_EXTRA_RIGHT' => Module::hookExec('extraRight'), 'HOOK_PRODUCT_OOS' => Hook::productOutOfStock($this->product), 'HOOK_PRODUCT_FOOTER' => Hook::productFooter($this->product, $category), 'HOOK_PRODUCT_ACTIONS' => Module::hookExec('productActions'), 'HOOK_PRODUCT_TAB' => Module::hookExec('productTab'), 'HOOK_PRODUCT_TAB_CONTENT' => Module::hookExec('productTabContent'))); $images = $this->product->getImages((int) self::$cookie->id_lang); $productImages = array(); foreach ($images as $k => $image) { if ($image['cover']) { self::$smarty->assign('mainImage', $images[0]); $cover = $image; $cover['id_image'] = Configuration::get('PS_LEGACY_IMAGES') ? $this->product->id . '-' . $image['id_image'] : $image['id_image']; $cover['id_image_only'] = (int) $image['id_image']; } $productImages[(int) $image['id_image']] = $image; } if (!isset($cover)) { $cover = array('id_image' => Language::getIsoById(self::$cookie->id_lang) . '-default', 'legend' => 'No picture', 'title' => 'No picture'); } $size = Image::getSize('large'); self::$smarty->assign(array('cover' => $cover, 'imgWidth' => (int) $size['width'], 'mediumSize' => Image::getSize('medium'), 'largeSize' => Image::getSize('large'), 'accessories' => $this->product->getAccessories((int) self::$cookie->id_lang))); if (count($productImages)) { self::$smarty->assign('images', $productImages); } /* Attributes / Groups & colors */ $colors = array(); $attributesGroups = $this->product->getAttributesGroups((int) self::$cookie->id_lang); // @todo (RM) should only get groups and not all declination ? if (is_array($attributesGroups) and $attributesGroups) { $groups = array(); $combinationImages = $this->product->getCombinationImages((int) self::$cookie->id_lang); foreach ($attributesGroups as $k => $row) { /* Color management */ if ((isset($row['attribute_color']) and $row['attribute_color'] or file_exists(_PS_COL_IMG_DIR_ . $row['id_attribute'] . '.jpg')) and $row['id_attribute_group'] == $this->product->id_color_default) { $colors[$row['id_attribute']]['value'] = $row['attribute_color']; $colors[$row['id_attribute']]['name'] = $row['attribute_name']; if (!isset($colors[$row['id_attribute']]['attributes_quantity'])) { $colors[$row['id_attribute']]['attributes_quantity'] = 0; } $colors[$row['id_attribute']]['attributes_quantity'] += (int) $row['quantity']; } if (!isset($groups[$row['id_attribute_group']])) { $groups[$row['id_attribute_group']] = array('name' => $row['public_group_name'], 'is_color_group' => $row['is_color_group'], 'default' => -1); } $groups[$row['id_attribute_group']]['attributes'][$row['id_attribute']] = $row['attribute_name']; if ($row['default_on'] && $groups[$row['id_attribute_group']]['default'] == -1) { $groups[$row['id_attribute_group']]['default'] = (int) $row['id_attribute']; } if (!isset($groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']])) { $groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] = 0; } $groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] += (int) $row['quantity']; $combinations[$row['id_product_attribute']]['attributes_values'][$row['id_attribute_group']] = $row['attribute_name']; $combinations[$row['id_product_attribute']]['attributes'][] = (int) $row['id_attribute']; $combinations[$row['id_product_attribute']]['price'] = (double) $row['price']; $combinations[$row['id_product_attribute']]['ecotax'] = (double) $row['ecotax']; $combinations[$row['id_product_attribute']]['weight'] = (double) $row['weight']; $combinations[$row['id_product_attribute']]['quantity'] = (int) $row['quantity']; $combinations[$row['id_product_attribute']]['reference'] = $row['reference']; $combinations[$row['id_product_attribute']]['unit_impact'] = $row['unit_price_impact']; $combinations[$row['id_product_attribute']]['minimal_quantity'] = $row['minimal_quantity']; $combinations[$row['id_product_attribute']]['id_image'] = isset($combinationImages[$row['id_product_attribute']][0]['id_image']) ? $combinationImages[$row['id_product_attribute']][0]['id_image'] : -1; } //wash attributes list (if some attributes are unavailables and if allowed to wash it) if (!Product::isAvailableWhenOutOfStock($this->product->out_of_stock) && Configuration::get('PS_DISP_UNAVAILABLE_ATTR') == 0) { foreach ($groups as &$group) { foreach ($group['attributes_quantity'] as $key => &$quantity) { if (!$quantity) { unset($group['attributes'][$key]); } } } foreach ($colors as $key => $color) { if (!$color['attributes_quantity']) { unset($colors[$key]); } } } foreach ($groups as &$group) { natcasesort($group['attributes']); } foreach ($combinations as $id_product_attribute => $comb) { $attributeList = ''; foreach ($comb['attributes'] as $id_attribute) { $attributeList .= '\'' . (int) $id_attribute . '\','; } $attributeList = rtrim($attributeList, ','); $combinations[$id_product_attribute]['list'] = $attributeList; } self::$smarty->assign(array('groups' => $groups, 'combinaisons' => $combinations, 'combinations' => $combinations, 'colors' => (sizeof($colors) and $this->product->id_color_default) ? $colors : false, 'combinationImages' => $combinationImages)); } self::$smarty->assign(array('no_tax' => Tax::excludeTaxeOption() or !Tax::getProductTaxRate((int) $this->product->id, $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}), 'customizationFields' => $this->product->customizable ? $this->product->getCustomizationFields((int) self::$cookie->id_lang) : false)); // Pack management self::$smarty->assign('packItems', $this->product->cache_is_pack ? Pack::getItemTable($this->product->id, (int) self::$cookie->id_lang, true) : array()); self::$smarty->assign('packs', Pack::getPacksTable($this->product->id, (int) self::$cookie->id_lang, true, 1)); } } self::$smarty->assign(array('ENT_NOQUOTES' => ENT_NOQUOTES, 'outOfStockAllowed' => (int) Configuration::get('PS_ORDER_OUT_OF_STOCK'), 'errors' => $this->errors, 'categories' => Category::getHomeCategories((int) self::$cookie->id_lang), 'have_image' => isset($cover) ? (int) $cover['id_image'] : false, 'tax_enabled' => Configuration::get('PS_TAX'), 'display_qties' => (int) Configuration::get('PS_DISPLAY_QTIES'), 'display_ht' => !Tax::excludeTaxeOption(), 'ecotax' => !sizeof($this->errors) and $this->product->ecotax > 0 ? Tools::convertPrice((double) $this->product->ecotax) : 0, 'currencySign' => $currency->sign, 'currencyRate' => $currency->conversion_rate, 'currencyFormat' => $currency->format, 'currencyBlank' => $currency->blank, 'jqZoomEnabled' => Configuration::get('PS_DISPLAY_JQZOOM'))); }
public function getFilterBlock($selected_filters = array()) { global $cookie; static $cache = null; $id_lang = Context::getContext()->language->id; $currency = Context::getContext()->currency; $id_shop = (int) Context::getContext()->shop->id; $alias = 'product_shop'; if (is_array($cache)) { return $cache; } $home_category = Configuration::get('PS_HOME_CATEGORY'); $id_parent = (int) Tools::getValue('id_category', Tools::getValue('id_category_layered', $home_category)); if ($id_parent == $home_category) { return; } $parent = new Category((int) $id_parent, $id_lang); /* Get the filters for the current category */ $filters = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT * FROM ' . _DB_PREFIX_ . 'layered_category WHERE id_category = ' . (int) $id_parent . ' AND id_shop = ' . $id_shop . ' GROUP BY `type`, id_value ORDER BY position ASC'); // Remove all empty selected filters foreach ($selected_filters as $key => $value) { switch ($key) { case 'price': case 'weight': if ($value[0] === '' && $value[1] === '') { unset($selected_filters[$key]); } break; default: if ($value == '') { unset($selected_filters[$key]); } break; } } $filter_blocks = array(); foreach ($filters as $filter) { $sql_query = array('select' => '', 'from' => '', 'join' => '', 'where' => '', 'group' => '', 'second_query' => ''); switch ($filter['type']) { // conditions + quantities + weight + price case 'price': case 'weight': case 'condition': case 'quantity': $sql_query['select'] = 'SELECT p.`id_product`, product_shop.`condition`, p.`id_manufacturer`, sa.`quantity`, p.`weight` '; $sql_query['from'] = ' FROM ' . _DB_PREFIX_ . 'product p '; $sql_query['join'] = ' INNER JOIN ' . _DB_PREFIX_ . 'category_product cp ON (cp.id_product = p.id_product) INNER JOIN ' . _DB_PREFIX_ . 'category c ON (c.id_category = cp.id_category AND ' . (Configuration::get('PS_LAYERED_FULL_TREE') ? 'c.nleft >= ' . (int) $parent->nleft . ' AND c.nright <= ' . (int) $parent->nright : 'c.id_category = ' . (int) $id_parent) . ' AND c.active = 1) '; $sql_query['join'] .= 'LEFT JOIN `' . _DB_PREFIX_ . 'stock_available` sa ON (sa.id_product = p.id_product AND sa.id_shop = ' . (int) $this->context->shop->id . ') '; $sql_query['where'] = 'WHERE product_shop.`active` = 1 AND product_shop.`visibility` IN ("both", "catalog") '; $sql_query['group'] = ' GROUP BY p.id_product '; break; case 'manufacturer': $sql_query['select'] = 'SELECT m.name, COUNT(DISTINCT p.id_product) nbr, m.id_manufacturer '; $sql_query['from'] = ' FROM `' . _DB_PREFIX_ . 'category_product` cp INNER JOIN `' . _DB_PREFIX_ . 'category` c ON (c.id_category = cp.id_category) INNER JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = cp.id_product) INNER JOIN ' . _DB_PREFIX_ . 'manufacturer m ON (m.id_manufacturer = p.id_manufacturer) '; $sql_query['where'] = 'WHERE ' . (Configuration::get('PS_LAYERED_FULL_TREE') ? 'c.nleft >= ' . (int) $parent->nleft . ' AND c.nright <= ' . (int) $parent->nright : 'c.id_category = ' . (int) $id_parent) . ' AND c.active = 1 AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog")'; $sql_query['group'] = ' GROUP BY p.id_manufacturer ORDER BY m.name'; if (!Configuration::get('PS_LAYERED_HIDE_0_VALUES')) { $sql_query['second_query'] = ' SELECT m.name, 0 nbr, m.id_manufacturer FROM `' . _DB_PREFIX_ . 'category_product` cp' . Shop::addSqlAssociation('product', 'cp') . ' INNER JOIN `' . _DB_PREFIX_ . 'category` c ON (c.id_category = cp.id_category) INNER JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = cp.id_product) INNER JOIN ' . _DB_PREFIX_ . 'manufacturer m ON (m.id_manufacturer = p.id_manufacturer) WHERE ' . (Configuration::get('PS_LAYERED_FULL_TREE') ? 'c.nleft >= ' . (int) $parent->nleft . ' AND c.nright <= ' . (int) $parent->nright : 'c.id_category = ' . (int) $id_parent) . ' AND c.active = 1 AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog") GROUP BY p.id_manufacturer ORDER BY m.name'; } break; case 'id_attribute_group': // attribute group $sql_query['select'] = ' SELECT COUNT(DISTINCT p.id_product) nbr, lpa.id_attribute_group, a.color, al.name attribute_name, agl.public_name attribute_group_name , lpa.id_attribute, ag.is_color_group, liagl.url_name name_url_name, liagl.meta_title name_meta_title, lial.url_name value_url_name, lial.meta_title value_meta_title'; $sql_query['from'] = ' FROM ' . _DB_PREFIX_ . 'layered_product_attribute lpa INNER JOIN ' . _DB_PREFIX_ . 'attribute a ON a.id_attribute = lpa.id_attribute INNER JOIN ' . _DB_PREFIX_ . 'attribute_lang al ON al.id_attribute = a.id_attribute AND al.id_lang = ' . (int) $id_lang . ' INNER JOIN ' . _DB_PREFIX_ . 'product as p ON p.id_product = lpa.id_product INNER JOIN ' . _DB_PREFIX_ . 'attribute_group ag ON ag.id_attribute_group = lpa.id_attribute_group INNER JOIN ' . _DB_PREFIX_ . 'attribute_group_lang agl ON agl.id_attribute_group = lpa.id_attribute_group AND agl.id_lang = ' . (int) $id_lang . ' LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_attribute_group_lang_value liagl ON (liagl.id_attribute_group = lpa.id_attribute_group AND liagl.id_lang = ' . (int) $id_lang . ') LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_attribute_lang_value lial ON (lial.id_attribute = lpa.id_attribute AND lial.id_lang = ' . (int) $id_lang . ') '; $sql_query['where'] = 'WHERE a.id_attribute_group = ' . (int) $filter['id_value']; $sql_query['where'] .= ' AND lpa.`id_shop` = ' . (int) Context::getContext()->shop->id; $sql_query['where'] .= ' AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog") AND p.id_product IN ( SELECT id_product FROM ' . _DB_PREFIX_ . 'category_product cp INNER JOIN ' . _DB_PREFIX_ . 'category c ON (c.id_category = cp.id_category AND ' . (Configuration::get('PS_LAYERED_FULL_TREE') ? 'c.nleft >= ' . (int) $parent->nleft . ' AND c.nright <= ' . (int) $parent->nright : 'c.id_category = ' . (int) $id_parent) . ' AND c.active = 1) ) '; $sql_query['group'] = ' GROUP BY lpa.id_attribute ORDER BY ag.`position` ASC, a.`position` ASC'; if (!Configuration::get('PS_LAYERED_HIDE_0_VALUES')) { $sql_query['second_query'] = ' SELECT 0 nbr, lpa.id_attribute_group, a.color, al.name attribute_name, agl.public_name attribute_group_name , lpa.id_attribute, ag.is_color_group, liagl.url_name name_url_name, liagl.meta_title name_meta_title, lial.url_name value_url_name, lial.meta_title value_meta_title FROM ' . _DB_PREFIX_ . 'layered_product_attribute lpa' . Shop::addSqlAssociation('product', 'lpa') . ' INNER JOIN ' . _DB_PREFIX_ . 'attribute a ON a.id_attribute = lpa.id_attribute INNER JOIN ' . _DB_PREFIX_ . 'attribute_lang al ON al.id_attribute = a.id_attribute AND al.id_lang = ' . (int) $id_lang . ' INNER JOIN ' . _DB_PREFIX_ . 'product as p ON p.id_product = lpa.id_product INNER JOIN ' . _DB_PREFIX_ . 'attribute_group ag ON ag.id_attribute_group = lpa.id_attribute_group INNER JOIN ' . _DB_PREFIX_ . 'attribute_group_lang agl ON agl.id_attribute_group = lpa.id_attribute_group AND agl.id_lang = ' . (int) $id_lang . ' LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_attribute_group_lang_value liagl ON (liagl.id_attribute_group = lpa.id_attribute_group AND liagl.id_lang = ' . (int) $id_lang . ') LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_attribute_lang_value lial ON (lial.id_attribute = lpa.id_attribute AND lial.id_lang = ' . (int) $id_lang . ') WHERE ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog") AND a.id_attribute_group = ' . (int) $filter['id_value'] . ' AND lpa.`id_shop` = ' . (int) Context::getContext()->shop->id . ' GROUP BY lpa.id_attribute ORDER BY id_attribute_group, id_attribute'; } break; case 'id_feature': $sql_query['select'] = 'SELECT fl.name feature_name, fp.id_feature, fv.id_feature_value, fvl.value, COUNT(DISTINCT p.id_product) nbr, lifl.url_name name_url_name, lifl.meta_title name_meta_title, lifvl.url_name value_url_name, lifvl.meta_title value_meta_title '; $sql_query['from'] = ' FROM ' . _DB_PREFIX_ . 'feature_product fp INNER JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = fp.id_product) LEFT JOIN ' . _DB_PREFIX_ . 'feature_lang fl ON (fl.id_feature = fp.id_feature AND fl.id_lang = ' . $id_lang . ') INNER JOIN ' . _DB_PREFIX_ . 'feature_value fv ON (fv.id_feature_value = fp.id_feature_value AND (fv.custom IS NULL OR fv.custom = 0)) LEFT JOIN ' . _DB_PREFIX_ . 'feature_value_lang fvl ON (fvl.id_feature_value = fp.id_feature_value AND fvl.id_lang = ' . $id_lang . ') LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_feature_lang_value lifl ON (lifl.id_feature = fp.id_feature AND lifl.id_lang = ' . $id_lang . ') LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_feature_value_lang_value lifvl ON (lifvl.id_feature_value = fp.id_feature_value AND lifvl.id_lang = ' . $id_lang . ') '; $sql_query['where'] = 'WHERE ' . $alias . '.`active` = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog") AND fp.id_feature = ' . (int) $filter['id_value'] . ' AND p.id_product IN ( SELECT id_product FROM ' . _DB_PREFIX_ . 'category_product cp INNER JOIN ' . _DB_PREFIX_ . 'category c ON (c.id_category = cp.id_category AND ' . (Configuration::get('PS_LAYERED_FULL_TREE') ? 'c.nleft >= ' . (int) $parent->nleft . ' AND c.nright <= ' . (int) $parent->nright : 'c.id_category = ' . (int) $id_parent) . ' AND c.active = 1)) '; $sql_query['group'] = 'GROUP BY fv.id_feature_value'; if (!Configuration::get('PS_LAYERED_HIDE_0_VALUES')) { $sql_query['second_query'] = ' SELECT fl.name feature_name, fp.id_feature, fv.id_feature_value, fvl.value, 0 nbr, lifl.url_name name_url_name, lifl.meta_title name_meta_title, lifvl.url_name value_url_name, lifvl.meta_title value_meta_title FROM ' . _DB_PREFIX_ . 'feature_product fp' . Shop::addSqlAssociation('product', 'fp') . ' INNER JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = fp.id_product) LEFT JOIN ' . _DB_PREFIX_ . 'feature_lang fl ON (fl.id_feature = fp.id_feature AND fl.id_lang = ' . (int) $id_lang . ') INNER JOIN ' . _DB_PREFIX_ . 'feature_value fv ON (fv.id_feature_value = fp.id_feature_value AND (fv.custom IS NULL OR fv.custom = 0)) LEFT JOIN ' . _DB_PREFIX_ . 'feature_value_lang fvl ON (fvl.id_feature_value = fp.id_feature_value AND fvl.id_lang = ' . (int) $id_lang . ') LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_feature_lang_value lifl ON (lifl.id_feature = fp.id_feature AND lifl.id_lang = ' . (int) $id_lang . ') LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_feature_value_lang_value lifvl ON (lifvl.id_feature_value = fp.id_feature_value AND lifvl.id_lang = ' . (int) $id_lang . ') WHERE ' . $alias . '.`active` = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog") AND fp.id_feature = ' . (int) $filter['id_value'] . ' GROUP BY fv.id_feature_value'; } break; case 'category': if (Group::isFeatureActive()) { $this->user_groups = $this->context->customer->isLogged() ? $this->context->customer->getGroups() : array(Configuration::get('PS_UNIDENTIFIED_GROUP')); } $depth = Configuration::get('PS_LAYERED_FILTER_CATEGORY_DEPTH'); if ($depth === false) { $depth = 1; } $sql_query['select'] = ' SELECT c.id_category, c.id_parent, cl.name, (SELECT count(DISTINCT p.id_product) # '; $sql_query['from'] = ' FROM ' . _DB_PREFIX_ . 'category_product cp LEFT JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = cp.id_product) '; $sql_query['where'] = ' WHERE cp.id_category = c.id_category AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog")'; $sql_query['group'] = ') count_products FROM ' . _DB_PREFIX_ . 'category c LEFT JOIN ' . _DB_PREFIX_ . 'category_lang cl ON (cl.id_category = c.id_category AND cl.`id_shop` = ' . (int) Context::getContext()->shop->id . ' and cl.id_lang = ' . (int) $id_lang . ') '; if (Group::isFeatureActive()) { $sql_query['group'] .= 'RIGHT JOIN ' . _DB_PREFIX_ . 'category_group cg ON (cg.id_category = c.id_category AND cg.`id_group` IN (' . implode(', ', $this->user_groups) . ')) '; } $sql_query['group'] .= 'WHERE c.nleft > ' . (int) $parent->nleft . ' AND c.nright < ' . (int) $parent->nright . ' ' . ($depth ? 'AND c.level_depth <= ' . ($parent->level_depth + (int) $depth) : '') . ' AND c.active = 1 GROUP BY c.id_category ORDER BY c.nleft, c.position'; } foreach ($filters as $filter_tmp) { $method_name = 'get' . ucfirst($filter_tmp['type']) . 'FilterSubQuery'; if (method_exists('BlockLayered', $method_name) && (!in_array($filter['type'], array('price', 'weight')) && $filter['type'] != $filter_tmp['type'] || $filter['type'] == $filter_tmp['type'])) { if ($filter['type'] == $filter_tmp['type'] && $filter['id_value'] == $filter_tmp['id_value']) { $sub_query_filter = self::$method_name(array(), true); } else { if (!is_null($filter_tmp['id_value'])) { $selected_filters_cleaned = $this->cleanFilterByIdValue(@$selected_filters[$filter_tmp['type']], $filter_tmp['id_value']); } else { $selected_filters_cleaned = @$selected_filters[$filter_tmp['type']]; } $sub_query_filter = self::$method_name($selected_filters_cleaned, $filter['type'] == $filter_tmp['type']); } foreach ($sub_query_filter as $key => $value) { $sql_query[$key] .= $value; } } } $products = false; if (!empty($sql_query['from'])) { $sql_query['from'] .= Shop::addSqlAssociation('product', 'p'); $products = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql_query['select'] . "\n" . $sql_query['from'] . "\n" . $sql_query['join'] . "\n" . $sql_query['where'] . "\n" . $sql_query['group']); } foreach ($filters as $filter_tmp) { $method_name = 'filterProductsBy' . ucfirst($filter_tmp['type']); if (method_exists('BlockLayered', $method_name) && (!in_array($filter['type'], array('price', 'weight')) && $filter['type'] != $filter_tmp['type'] || $filter['type'] == $filter_tmp['type'])) { if ($filter['type'] == $filter_tmp['type']) { $products = self::$method_name(array(), $products); } else { $products = self::$method_name(@$selected_filters[$filter_tmp['type']], $products); } } } if (!empty($sql_query['second_query'])) { $res = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql_query['second_query']); if ($res) { $products = array_merge($products, $res); } } switch ($filter['type']) { case 'price': if ($this->showPriceFilter()) { $price_array = array('type_lite' => 'price', 'type' => 'price', 'id_key' => 0, 'name' => $this->l('Price'), 'slider' => true, 'max' => '0', 'min' => null, 'values' => array('1' => 0), 'unit' => $currency->sign, 'format' => $currency->format, 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']); if (isset($products) && $products) { foreach ($products as $product) { if (is_null($price_array['min'])) { $price_array['min'] = $product['price_min']; $price_array['values'][0] = $product['price_min']; } else { if ($price_array['min'] > $product['price_min']) { $price_array['min'] = $product['price_min']; $price_array['values'][0] = $product['price_min']; } } if ($price_array['max'] < $product['price_max']) { $price_array['max'] = $product['price_max']; $price_array['values'][1] = $product['price_max']; } } } if ($price_array['max'] != $price_array['min'] && $price_array['min'] != null) { if ($filter['filter_type'] == 2) { $price_array['list_of_values'] = array(); $nbr_of_value = $filter['filter_show_limit']; if ($nbr_of_value < 2) { $nbr_of_value = 4; } $delta = ($price_array['max'] - $price_array['min']) / $nbr_of_value; $current_step = $price_array['min']; for ($i = 0; $i < $nbr_of_value; $i++) { $price_array['list_of_values'][] = array((int) ($price_array['min'] + $i * $delta), (int) ($price_array['min'] + ($i + 1) * $delta)); } } if (isset($selected_filters['price']) && isset($selected_filters['price'][0]) && isset($selected_filters['price'][1])) { $price_array['values'][0] = $selected_filters['price'][0]; $price_array['values'][1] = $selected_filters['price'][1]; } $filter_blocks[] = $price_array; } } break; case 'weight': $weight_array = array('type_lite' => 'weight', 'type' => 'weight', 'id_key' => 0, 'name' => $this->l('Weight'), 'slider' => true, 'max' => '0', 'min' => null, 'values' => array('1' => 0), 'unit' => Configuration::get('PS_WEIGHT_UNIT'), 'format' => 5, 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']); if (isset($products) && $products) { foreach ($products as $product) { if (is_null($weight_array['min'])) { $weight_array['min'] = $product['weight']; $weight_array['values'][0] = $product['weight']; } else { if ($weight_array['min'] > $product['weight']) { $weight_array['min'] = $product['weight']; $weight_array['values'][0] = $product['weight']; } } if ($weight_array['max'] < $product['weight']) { $weight_array['max'] = $product['weight']; $weight_array['values'][1] = $product['weight']; } } } if ($weight_array['max'] != $weight_array['min'] && $weight_array['min'] != null) { if (isset($selected_filters['weight']) && isset($selected_filters['weight'][0]) && isset($selected_filters['weight'][1])) { $weight_array['values'][0] = $selected_filters['weight'][0]; $weight_array['values'][1] = $selected_filters['weight'][1]; } $filter_blocks[] = $weight_array; } break; case 'condition': $condition_array = array('new' => array('name' => $this->l('New'), 'nbr' => 0), 'used' => array('name' => $this->l('Used'), 'nbr' => 0), 'refurbished' => array('name' => $this->l('Refurbished'), 'nbr' => 0)); if (isset($products) && $products) { foreach ($products as $product) { if (isset($selected_filters['condition']) && in_array($product['condition'], $selected_filters['condition'])) { $condition_array[$product['condition']]['checked'] = true; } } } foreach ($condition_array as $key => $condition) { if (isset($selected_filters['condition']) && in_array($key, $selected_filters['condition'])) { $condition_array[$key]['checked'] = true; } } if (isset($products) && $products) { foreach ($products as $product) { if (isset($condition_array[$product['condition']])) { $condition_array[$product['condition']]['nbr']++; } } } $filter_blocks[] = array('type_lite' => 'condition', 'type' => 'condition', 'id_key' => 0, 'name' => $this->l('Condition'), 'values' => $condition_array, 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']); break; case 'quantity': $quantity_array = array(0 => array('name' => $this->l('Not available'), 'nbr' => 0), 1 => array('name' => $this->l('In stock'), 'nbr' => 0)); foreach ($quantity_array as $key => $quantity) { if (isset($selected_filters['quantity']) && in_array($key, $selected_filters['quantity'])) { $quantity_array[$key]['checked'] = true; } } if (isset($products) && $products) { foreach ($products as $product) { //If oosp move all not available quantity to available quantity if ((int) $product['quantity'] > 0 || Product::isAvailableWhenOutOfStock(StockAvailable::outOfStock($product['id_product']))) { $quantity_array[1]['nbr']++; } else { $quantity_array[0]['nbr']++; } } } $filter_blocks[] = array('type_lite' => 'quantity', 'type' => 'quantity', 'id_key' => 0, 'name' => $this->l('Availability'), 'values' => $quantity_array, 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']); break; case 'manufacturer': if (isset($products) && $products) { $manufaturers_array = array(); foreach ($products as $manufacturer) { if (!isset($manufaturers_array[$manufacturer['id_manufacturer']])) { $manufaturers_array[$manufacturer['id_manufacturer']] = array('name' => $manufacturer['name'], 'nbr' => $manufacturer['nbr']); } if (isset($selected_filters['manufacturer']) && in_array((int) $manufacturer['id_manufacturer'], $selected_filters['manufacturer'])) { $manufaturers_array[$manufacturer['id_manufacturer']]['checked'] = true; } } $filter_blocks[] = array('type_lite' => 'manufacturer', 'type' => 'manufacturer', 'id_key' => 0, 'name' => $this->l('Manufacturer'), 'values' => $manufaturers_array, 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']); } break; case 'id_attribute_group': $attributes_array = array(); if (isset($products) && $products) { foreach ($products as $attributes) { if (!isset($attributes_array[$attributes['id_attribute_group']])) { $attributes_array[$attributes['id_attribute_group']] = array('type_lite' => 'id_attribute_group', 'type' => 'id_attribute_group', 'id_key' => (int) $attributes['id_attribute_group'], 'name' => $attributes['attribute_group_name'], 'is_color_group' => (bool) $attributes['is_color_group'], 'values' => array(), 'url_name' => $attributes['name_url_name'], 'meta_title' => $attributes['name_meta_title'], 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']); } if (!isset($attributes_array[$attributes['id_attribute_group']]['values'][$attributes['id_attribute']])) { $attributes_array[$attributes['id_attribute_group']]['values'][$attributes['id_attribute']] = array('color' => $attributes['color'], 'name' => $attributes['attribute_name'], 'nbr' => (int) $attributes['nbr'], 'url_name' => $attributes['value_url_name'], 'meta_title' => $attributes['value_meta_title']); } if (isset($selected_filters['id_attribute_group'][$attributes['id_attribute']])) { $attributes_array[$attributes['id_attribute_group']]['values'][$attributes['id_attribute']]['checked'] = true; } } $filter_blocks = array_merge($filter_blocks, $attributes_array); } break; case 'id_feature': $feature_array = array(); if (isset($products) && $products) { foreach ($products as $feature) { if (!isset($feature_array[$feature['id_feature']])) { $feature_array[$feature['id_feature']] = array('type_lite' => 'id_feature', 'type' => 'id_feature', 'id_key' => (int) $feature['id_feature'], 'values' => array(), 'name' => $feature['feature_name'], 'url_name' => $feature['name_url_name'], 'meta_title' => $feature['name_meta_title'], 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']); } if (!isset($feature_array[$feature['id_feature']]['values'][$feature['id_feature_value']])) { $feature_array[$feature['id_feature']]['values'][$feature['id_feature_value']] = array('nbr' => (int) $feature['nbr'], 'name' => $feature['value'], 'url_name' => $feature['value_url_name'], 'meta_title' => $feature['value_meta_title']); } if (isset($selected_filters['id_feature'][$feature['id_feature_value']])) { $feature_array[$feature['id_feature']]['values'][$feature['id_feature_value']]['checked'] = true; } } //Natural sort foreach ($feature_array as $key => $value) { $temp = array(); foreach ($feature_array[$key]['values'] as $keyint => $valueint) { $temp[$keyint] = $valueint['name']; } natcasesort($temp); $temp2 = array(); foreach ($temp as $keytemp => $valuetemp) { $temp2[$keytemp] = $feature_array[$key]['values'][$keytemp]; } $feature_array[$key]['values'] = $temp2; } $filter_blocks = array_merge($filter_blocks, $feature_array); } break; case 'category': $tmp_array = array(); if (isset($products) && $products) { $categories_with_products_count = 0; foreach ($products as $category) { $tmp_array[$category['id_category']] = array('name' => $category['name'], 'nbr' => (int) $category['count_products']); if ((int) $category['count_products']) { $categories_with_products_count++; } if (isset($selected_filters['category']) && in_array($category['id_category'], $selected_filters['category'])) { $tmp_array[$category['id_category']]['checked'] = true; } } if ($categories_with_products_count || !Configuration::get('PS_LAYERED_HIDE_0_VALUES')) { $filter_blocks[] = array('type_lite' => 'category', 'type' => 'category', 'id_key' => 0, 'name' => $this->l('Categories'), 'values' => $tmp_array, 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']); } } break; } } // All non indexable attribute and feature $non_indexable = array(); // Get all non indexable attribute groups foreach (Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT public_name FROM `' . _DB_PREFIX_ . 'attribute_group_lang` agl LEFT JOIN `' . _DB_PREFIX_ . 'layered_indexable_attribute_group` liag ON liag.id_attribute_group = agl.id_attribute_group WHERE indexable IS NULL OR indexable = 0 AND id_lang = ' . (int) $id_lang) as $attribute) { $non_indexable[] = Tools::link_rewrite($attribute['public_name']); } // Get all non indexable features foreach (Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT name FROM `' . _DB_PREFIX_ . 'feature_lang` fl LEFT JOIN `' . _DB_PREFIX_ . 'layered_indexable_feature` lif ON lif.id_feature = fl.id_feature WHERE indexable IS NULL OR indexable = 0 AND id_lang = ' . (int) $id_lang) as $attribute) { $non_indexable[] = Tools::link_rewrite($attribute['name']); } //generate SEO link $param_selected = ''; $param_product_url = ''; $option_checked_array = array(); $param_group_selected_array = array(); $title_values = array(); $meta_values = array(); //get filters checked by group foreach ($filter_blocks as $type_filter) { $filter_name = !empty($type_filter['url_name']) ? $type_filter['url_name'] : $type_filter['name']; $filter_meta = !empty($type_filter['meta_title']) ? $type_filter['meta_title'] : $type_filter['name']; $attr_key = $type_filter['type'] . '_' . $type_filter['id_key']; $param_group_selected = ''; if (in_array(strtolower($type_filter['type']), array('price', 'weight')) && (double) $type_filter['values'][0] > (double) $type_filter['min'] && (double) $type_filter['values'][1] > (double) $type_filter['max']) { $param_group_selected .= $this->getAnchor() . str_replace($this->getAnchor(), '_', $type_filter['values'][0]) . $this->getAnchor() . str_replace($this->getAnchor(), '_', $type_filter['values'][1]); $param_group_selected_array[Tools::link_rewrite($filter_name)][] = Tools::link_rewrite($filter_name); if (!isset($title_values[$filter_meta])) { $title_values[$filter_meta] = array(); } $title_values[$filter_meta][] = $filter_meta; if (!isset($meta_values[$attr_key])) { $meta_values[$attr_key] = array('title' => $filter_meta, 'values' => array()); } $meta_values[$attr_key]['values'][] = $filter_meta; } else { foreach ($type_filter['values'] as $key => $value) { if (is_array($value) && array_key_exists('checked', $value)) { $value_name = !empty($value['url_name']) ? $value['url_name'] : $value['name']; $value_meta = !empty($value['meta_title']) ? $value['meta_title'] : $value['name']; $param_group_selected .= $this->getAnchor() . str_replace($this->getAnchor(), '_', Tools::link_rewrite($value_name)); $param_group_selected_array[Tools::link_rewrite($filter_name)][] = Tools::link_rewrite($value_name); if (!isset($title_values[$filter_meta])) { $title_values[$filter_meta] = array(); } $title_values[$filter_meta][] = $value_name; if (!isset($meta_values[$attr_key])) { $meta_values[$attr_key] = array('title' => $filter_meta, 'values' => array()); } $meta_values[$attr_key]['values'][] = $value_meta; } else { $param_group_selected_array[Tools::link_rewrite($filter_name)][] = array(); } } } if (!empty($param_group_selected)) { $param_selected .= '/' . str_replace($this->getAnchor(), '_', Tools::link_rewrite($filter_name)) . $param_group_selected; $option_checked_array[Tools::link_rewrite($filter_name)] = $param_group_selected; } // select only attribute and group attribute to display an unique product combination link if (!empty($param_group_selected) && $type_filter['type'] == 'id_attribute_group') { $param_product_url .= '/' . str_replace($this->getAnchor(), '_', Tools::link_rewrite($filter_name)) . $param_group_selected; } } if ($this->page > 1) { $param_selected .= '/page-' . $this->page; } $blacklist = array('weight', 'price'); if (!Configuration::get('PS_LAYERED_FILTER_INDEX_CDT')) { $blacklist[] = 'condition'; } if (!Configuration::get('PS_LAYERED_FILTER_INDEX_QTY')) { $blacklist[] = 'quantity'; } if (!Configuration::get('PS_LAYERED_FILTER_INDEX_MNF')) { $blacklist[] = 'manufacturer'; } if (!Configuration::get('PS_LAYERED_FILTER_INDEX_CAT')) { $blacklist[] = 'category'; } $global_nofollow = false; foreach ($filter_blocks as &$type_filter) { $filter_name = !empty($type_filter['url_name']) ? $type_filter['url_name'] : $type_filter['name']; if (count($type_filter) > 0 && !isset($type_filter['slider'])) { foreach ($type_filter['values'] as $key => $values) { $nofollow = false; if (!empty($values['checked']) && in_array($type_filter['type'], $blacklist)) { $global_nofollow = true; } $option_checked_clone_array = $option_checked_array; // If not filters checked, add parameter $value_name = !empty($values['url_name']) ? $values['url_name'] : $values['name']; if (!in_array(Tools::link_rewrite($value_name), $param_group_selected_array[Tools::link_rewrite($filter_name)])) { // Update parameter filter checked before if (array_key_exists(Tools::link_rewrite($filter_name), $option_checked_array)) { $option_checked_clone_array[Tools::link_rewrite($filter_name)] = $option_checked_clone_array[Tools::link_rewrite($filter_name)] . $this->getAnchor() . str_replace($this->getAnchor(), '_', Tools::link_rewrite($value_name)); if (in_array($type_filter['type'], $blacklist)) { $nofollow = true; } } else { $option_checked_clone_array[Tools::link_rewrite($filter_name)] = $this->getAnchor() . str_replace($this->getAnchor(), '_', Tools::link_rewrite($value_name)); } } else { // Remove selected parameters $option_checked_clone_array[Tools::link_rewrite($filter_name)] = str_replace($this->getAnchor() . str_replace($this->getAnchor(), '_', Tools::link_rewrite($value_name)), '', $option_checked_clone_array[Tools::link_rewrite($filter_name)]); if (empty($option_checked_clone_array[Tools::link_rewrite($filter_name)])) { unset($option_checked_clone_array[Tools::link_rewrite($filter_name)]); } } $parameters = ''; ksort($option_checked_clone_array); // Order parameters foreach ($option_checked_clone_array as $key_group => $value_group) { $parameters .= '/' . str_replace($this->getAnchor(), '_', $key_group) . $value_group; } // Add nofollow if any blacklisted filters ins in parameters foreach ($filter_blocks as $filter) { $name = Tools::link_rewrite(!empty($filter['url_name']) ? $filter['url_name'] : $filter['name']); if (in_array($filter['type'], $blacklist) && strpos($parameters, $name . '-') !== false) { $nofollow = true; } } // Check if there is an non indexable attribute or feature in the url foreach ($non_indexable as $value) { if (strpos($parameters, '/' . $value) !== false) { $nofollow = true; } } $type_filter['values'][$key]['link'] = Context::getContext()->link->getCategoryLink($parent, null, null) . '#' . ltrim($parameters, '/'); $type_filter['values'][$key]['rel'] = $nofollow ? 'nofollow' : ''; } } } $n_filters = 0; if (isset($selected_filters['price'])) { if ($price_array['min'] == $selected_filters['price'][0] && $price_array['max'] == $selected_filters['price'][1]) { unset($selected_filters['price']); } } if (isset($selected_filters['weight'])) { if ($weight_array['min'] == $selected_filters['weight'][0] && $weight_array['max'] == $selected_filters['weight'][1]) { unset($selected_filters['weight']); } } foreach ($selected_filters as $filters) { $n_filters += count($filters); } $cache = array('layered_show_qties' => (int) Configuration::get('PS_LAYERED_SHOW_QTIES'), 'id_category_layered' => (int) $id_parent, 'selected_filters' => $selected_filters, 'n_filters' => (int) $n_filters, 'nbr_filterBlocks' => count($filter_blocks), 'filters' => $filter_blocks, 'title_values' => $title_values, 'meta_values' => $meta_values, 'current_friendly_url' => $param_selected, 'param_product_url' => $param_product_url, 'no_follow' => !empty($param_selected) || $global_nofollow); return $cache; }
public function preProcess() { parent::preProcess(); $orderTotal = self::$cart->getOrderTotal(true, Cart::ONLY_PRODUCTS); $this->cartDiscounts = self::$cart->getDiscounts(); foreach ($this->cartDiscounts as $k => $this->cartDiscount) { if ($error = self::$cart->checkDiscountValidity(new Discount((int) $this->cartDiscount['id_discount']), $this->cartDiscounts, $orderTotal, self::$cart->getProducts())) { self::$cart->deleteDiscount((int) $this->cartDiscount['id_discount']); } } $add = Tools::getIsset('add') ? 1 : 0; $delete = Tools::getIsset('delete') ? 1 : 0; if (Configuration::get('PS_TOKEN_ENABLE') == 1 && strcasecmp(Tools::getToken(false), strval(Tools::getValue('token'))) && self::$cookie->isLogged() === true) { $this->errors[] = Tools::displayError('Invalid token'); } // Update the cart ONLY if $this->cookies are available, in order to avoid ghost carts created by bots if (($add or Tools::getIsset('update') or $delete) and isset(self::$cookie->date_add)) { //get the values $idProduct = (int) Tools::getValue('id_product', NULL); $idProductAttribute = (int) Tools::getValue('id_product_attribute', Tools::getValue('ipa')); $customizationId = (int) Tools::getValue('id_customization', 0); $qty = (int) abs(Tools::getValue('qty', 1)); if ($qty == 0) { $this->errors[] = Tools::displayError('Null quantity'); } elseif (!$idProduct) { $this->errors[] = Tools::displayError('Product not found'); } else { $producToAdd = new Product((int) $idProduct, true, (int) self::$cookie->id_lang); if ((!$producToAdd->id or !$producToAdd->active) and !$delete) { if (Tools::getValue('ajax') == 'true') { die('{"hasError" : true, "errors" : ["' . Tools::displayError('Pproduct is no longer available.', false) . '"]}'); } else { $this->errors[] = Tools::displayError('Pproduct is no longer available.', false); } } else { /* Check the quantity availability */ if ($idProductAttribute and is_numeric($idProductAttribute)) { if (!$delete and !$producToAdd->isAvailableWhenOutOfStock($producToAdd->out_of_stock) and !Attribute::checkAttributeQty((int) $idProductAttribute, (int) $qty)) { if (Tools::getValue('ajax') == 'true') { die('{"hasError" : true, "errors" : ["' . Tools::displayError('There is not enough product in stock.', false) . '"]}'); } else { $this->errors[] = Tools::displayError('There is not enough product in stock.'); } } } elseif ($producToAdd->hasAttributes() and !$delete) { $idProductAttribute = Product::getDefaultAttribute((int) $producToAdd->id, (int) $producToAdd->out_of_stock == 2 ? !(int) Configuration::get('PS_ORDER_OUT_OF_STOCK') : !(int) $producToAdd->out_of_stock); if (!$idProductAttribute) { Tools::redirectAdmin($link->getProductLink($producToAdd)); } elseif (!$delete and !$producToAdd->isAvailableWhenOutOfStock($producToAdd->out_of_stock) and !Attribute::checkAttributeQty((int) $idProductAttribute, (int) $qty)) { if (Tools::getValue('ajax') == 'true') { die('{"hasError" : true, "errors" : ["' . Tools::displayError('There is not enough product in stock.', false) . '"]}'); } else { $this->errors[] = Tools::displayError('There is not enough product in stock.'); } } } elseif (!$delete and !$producToAdd->checkQty((int) $qty)) { if (Tools::getValue('ajax') == 'true') { die('{"hasError" : true, "errors" : ["' . Tools::displayError('There is not enough product in stock.') . '"]}'); } else { $this->errors[] = Tools::displayError('There is not enough product in stock.'); } } /* Check vouchers compatibility */ if ($add and ($producToAdd->specificPrice and (double) $producToAdd->specificPrice['reduction'] or $producToAdd->on_sale)) { $discounts = self::$cart->getDiscounts(); foreach ($discounts as $discount) { if (!$discount['cumulable_reduction']) { $this->errors[] = Tools::displayError('Cannot add this product because current voucher does not allow additional discounts.'); } } } if (!sizeof($this->errors)) { if ($add and $qty >= 0) { /* Product addition to the cart */ if (!isset(self::$cart->id) or !self::$cart->id) { self::$cart->add(); if (self::$cart->id) { self::$cookie->id_cart = (int) self::$cart->id; } } if ($add and !$producToAdd->hasAllRequiredCustomizableFields() and !$customizationId) { $this->errors[] = Tools::displayError('Please fill in all required fields, then save the customization.'); } if (!sizeof($this->errors)) { $updateQuantity = self::$cart->updateQty((int) $qty, (int) $idProduct, (int) $idProductAttribute, $customizationId, Tools::getValue('op', 'up')); if ($updateQuantity < 0) { /* if product has attribute, minimal quantity is set with minimal quantity of attribute*/ if ((int) $idProductAttribute) { $minimal_quantity = Attribute::getAttributeMinimalQty((int) $idProductAttribute); } else { $minimal_quantity = $producToAdd->minimal_quantity; } if (Tools::getValue('ajax') == 'true') { die('{"hasError" : true, "errors" : ["' . Tools::displayError('You must add', false) . ' ' . $minimal_quantity . ' ' . Tools::displayError('Minimum quantity', false) . '"]}'); } else { $this->errors[] = Tools::displayError('You must add') . ' ' . $minimal_quantity . ' ' . Tools::displayError('Minimum quantity') . ((isset($_SERVER['HTTP_REFERER']) and basename($_SERVER['HTTP_REFERER']) == 'order.php' or !Tools::isSubmit('ajax') and substr(basename($_SERVER['REQUEST_URI']), 0, strlen('cart.php')) == 'cart.php') ? '<script language="javascript">setTimeout("history.back()",5000);</script><br />- ' . Tools::displayError('You will be redirected to your cart in a few seconds.') : ''); } } elseif (!$updateQuantity) { if (Tools::getValue('ajax') == 'true') { die('{"hasError" : true, "errors" : ["' . Tools::displayError('You already have the maximum quantity available for this product.', false) . '"]}'); } else { $this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.') . ((isset($_SERVER['HTTP_REFERER']) and basename($_SERVER['HTTP_REFERER']) == 'order.php' or !Tools::isSubmit('ajax') and substr(basename($_SERVER['REQUEST_URI']), 0, strlen('cart.php')) == 'cart.php') ? '<script language="javascript">setTimeout("history.back()",5000);</script><br />- ' . Tools::displayError('You will be redirected to your cart in a few seconds.') : ''); } } } } elseif ($delete) { if (self::$cart->deleteProduct((int) $idProduct, (int) $idProductAttribute, (int) $customizationId)) { if (!Cart::getNbProducts((int) self::$cart->id)) { self::$cart->id_carrier = 0; self::$cart->gift = 0; self::$cart->gift_message = ''; self::$cart->update(); } } } } $discounts = self::$cart->getDiscounts(); foreach ($discounts as $discount) { $discountObj = new Discount((int) $discount['id_discount'], (int) self::$cookie->id_lang); if ($error = self::$cart->checkDiscountValidity($discountObj, $discounts, self::$cart->getOrderTotal(true, Cart::ONLY_PRODUCTS), self::$cart->getProducts())) { self::$cart->deleteDiscount((int) $discount['id_discount']); self::$cart->update(); $errors[] = $error; } } if (!sizeof($this->errors)) { $queryString = Tools::safeOutput(Tools::getValue('query', NULL)); if ($queryString and !Configuration::get('PS_CART_REDIRECT')) { Tools::redirect('search.php?search=' . $queryString); } if (isset($_SERVER['HTTP_REFERER'])) { // Redirect to previous page preg_match('!http(s?)://(.*)/(.*)!', $_SERVER['HTTP_REFERER'], $regs); if (isset($regs[3]) and !Configuration::get('PS_CART_REDIRECT') and Tools::getValue('ajax') != 'true') { Tools::redirect($regs[3]); } } } } if (Tools::getValue('ajax') != 'true' and !sizeof($this->errors)) { Tools::redirect('order.php?' . (isset($idProduct) ? 'ipa=' . (int) $idProduct : '')); } } } }
/** * Update product quantity * * @param integer $quantity Quantity to add (or substract) * @param integer $id_product Product ID * @param integer $id_product_attribute Attribute ID if needed * @param string $operator Indicate if quantity must be increased or decreased */ public function updateQty($quantity, $id_product, $id_product_attribute = NULL, $id_customization = false, $operator = 'up') { $product = new Product((int) $id_product, false, (int) Configuration::get('PS_LANG_DEFAULT')); /* If we have a product combination, the minimal quantity is set with the one of this combination */ if (!empty($id_product_attribute)) { $minimalQuantity = (int) Attribute::getAttributeMinimalQty((int) $id_product_attribute); } else { $minimalQuantity = (int) $product->minimal_quantity; } if (!Validate::isLoadedObject($product)) { die(Tools::displayError()); } if (isset(self::$_nbProducts[$this->id])) { unset(self::$_nbProducts[$this->id]); } if (isset(self::$_totalWeight[$this->id])) { unset(self::$_totalWeight[$this->id]); } if ((int) $quantity <= 0) { return $this->deleteProduct((int) $id_product, (int) $id_product_attribute, (int) $id_customization); } else { if (!$product->available_for_order or Configuration::get('PS_CATALOG_MODE')) { return false; } else { /* Check if the product is already in the cart */ $result = $this->containsProduct((int) $id_product, (int) $id_product_attribute, (int) $id_customization); /* Update quantity if product already exist */ if ($result) { if ($operator == 'up') { $result2 = Db::getInstance()->getRow(' SELECT ' . (!empty($id_product_attribute) ? 'pa' : 'p') . '.`quantity`, p.`out_of_stock` FROM `' . _DB_PREFIX_ . 'product` p ' . (!empty($id_product_attribute) ? 'LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON p.`id_product` = pa.`id_product`' : '') . ' WHERE p.`id_product` = ' . (int) $id_product . (!empty($id_product_attribute) ? ' AND `id_product_attribute` = ' . (int) $id_product_attribute : '')); $productQty = (int) $result2['quantity']; $newQty = (int) $result['quantity'] + (int) $quantity; $qty = '+ ' . (int) $quantity; if (!Product::isAvailableWhenOutOfStock((int) $result2['out_of_stock'])) { if ($newQty > $productQty) { return false; } } } elseif ($operator == 'down') { $qty = '- ' . (int) $quantity; $newQty = (int) $result['quantity'] - (int) $quantity; if ($newQty < $minimalQuantity and $minimalQuantity > 1) { return -1; } } else { return false; } /* Delete product from cart */ if ($newQty <= 0) { return $this->deleteProduct((int) $id_product, (int) $id_product_attribute, (int) $id_customization); } else { if ($newQty < $minimalQuantity) { return -1; } else { Db::getInstance()->Execute(' UPDATE `' . _DB_PREFIX_ . 'cart_product` SET `quantity` = `quantity` ' . $qty . ', `date_add` = NOW() WHERE `id_product` = ' . (int) $id_product . (!empty($id_product_attribute) ? ' AND `id_product_attribute` = ' . (int) $id_product_attribute : '') . ' AND `id_cart` = ' . (int) $this->id . ' LIMIT 1'); } } } else { $result2 = Db::getInstance()->getRow(' SELECT ' . (!empty($id_product_attribute) ? 'pa' : 'p') . '.`quantity`, p.`out_of_stock` FROM `' . _DB_PREFIX_ . 'product` p ' . (!empty($id_product_attribute) ? 'LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON p.`id_product` = pa.`id_product`' : '') . ' WHERE p.`id_product` = ' . (int) $id_product . (!empty($id_product_attribute) ? ' AND `id_product_attribute` = ' . (int) $id_product_attribute : '')); if (!Product::isAvailableWhenOutOfStock((int) $result2['out_of_stock'])) { if ((int) $quantity > $result2['quantity']) { return false; } } if ((int) $quantity < $minimalQuantity) { return -1; } if (!Db::getInstance()->AutoExecute(_DB_PREFIX_ . 'cart_product', array('id_product' => (int) $id_product, 'id_product_attribute' => (int) $id_product_attribute, 'id_cart' => (int) $this->id, 'quantity' => (int) $quantity, 'date_add' => date('Y-m-d H:i:s')), 'INSERT')) { return false; } } } } // refresh cache of self::_products $this->_products = $this->getProducts(true); $this->update(true); if ($product->customizable) { return $this->_updateCustomizationQuantity((int) $quantity, (int) $id_customization, (int) $id_product, (int) $id_product_attribute, $operator); } else { return true; } }
/** * @param array $products_id an array of product ids * @return array */ protected function getOrderProducts(array $products_id) { $q_orders = 'SELECT o.id_order FROM ' . _DB_PREFIX_ . 'orders o LEFT JOIN ' . _DB_PREFIX_ . 'order_detail od ON (od.id_order = o.id_order) WHERE o.valid = 1 AND od.product_id IN (' . implode(',', $products_id) . ')'; $orders = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($q_orders); $final_products_list = array(); if (count($orders) > 0) { $list = ''; foreach ($orders as $order) { $list .= (int) $order['id_order'] . ','; } $list = rtrim($list, ','); $list_product_ids = join(',', $products_id); if (Group::isFeatureActive()) { $sql_groups_join = ' LEFT JOIN `' . _DB_PREFIX_ . 'category_product` cp ON (cp.`id_category` = product_shop.id_category_default AND cp.id_product = product_shop.id_product) LEFT JOIN `' . _DB_PREFIX_ . 'category_group` cg ON (cp.`id_category` = cg.`id_category`)'; $groups = FrontController::getCurrentCustomerGroups(); $sql_groups_where = 'AND cg.`id_group` ' . (count($groups) ? 'IN (' . implode(',', $groups) . ')' : '=' . (int) Group::getCurrent()->id); } $order_products = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT DISTINCT od.product_id, pl.name, pl.description_short, pl.link_rewrite, p.reference, i.id_image, product_shop.show_price, cl.link_rewrite category, p.ean13, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity FROM ' . _DB_PREFIX_ . 'order_detail od LEFT JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = od.product_id) ' . Shop::addSqlAssociation('product', 'p') . (Combination::isFeatureActive() ? 'LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON (p.`id_product` = pa.`id_product`) ' . Shop::addSqlAssociation('product_attribute', 'pa', false, 'product_attribute_shop.`default_on` = 1') . ' ' . Product::sqlStock('p', 'product_attribute_shop', false, $this->context->shop) : Product::sqlStock('p', 'product', false, $this->context->shop)) . ' LEFT JOIN ' . _DB_PREFIX_ . 'product_lang pl ON (pl.id_product = od.product_id' . Shop::addSqlRestrictionOnLang('pl') . ') LEFT JOIN ' . _DB_PREFIX_ . 'category_lang cl ON (cl.id_category = product_shop.id_category_default' . Shop::addSqlRestrictionOnLang('cl') . ') LEFT JOIN ' . _DB_PREFIX_ . 'image i ON (i.id_product = od.product_id) ' . (Group::isFeatureActive() ? $sql_groups_join : '') . ' WHERE od.id_order IN (' . $list . ') AND pl.id_lang = ' . (int) $this->context->language->id . ' AND cl.id_lang = ' . (int) $this->context->language->id . ' AND od.product_id NOT IN (' . $list_product_ids . ') AND i.cover = 1 AND product_shop.active = 1 ' . (Group::isFeatureActive() ? $sql_groups_where : '') . ' ORDER BY RAND() LIMIT ' . (int) Configuration::get('CROSSSELLING_NBR')); $tax_calc = Product::getTaxCalculationMethod(); foreach ($order_products as &$order_product) { $order_product['id_product'] = (int) $order_product['product_id']; $order_product['image'] = $this->context->link->getImageLink($order_product['link_rewrite'], (int) $order_product['product_id'] . '-' . (int) $order_product['id_image'], ImageType::getFormatedName('home')); $order_product['link'] = $this->context->link->getProductLink((int) $order_product['product_id'], $order_product['link_rewrite'], $order_product['category'], $order_product['ean13']); if (Configuration::get('CROSSSELLING_DISPLAY_PRICE') && ($tax_calc == 0 || $tax_calc == 2)) { $order_product['displayed_price'] = Product::getPriceStatic((int) $order_product['product_id'], true, null); } elseif (Configuration::get('CROSSSELLING_DISPLAY_PRICE') && $tax_calc == 1) { $order_product['displayed_price'] = Product::getPriceStatic((int) $order_product['product_id'], false, null); } $order_product['allow_oosp'] = Product::isAvailableWhenOutOfStock((int) $order_product['out_of_stock']); if (!isset($final_products_list[$order_product['product_id'] . '-' . $order_product['id_image']])) { $final_products_list[$order_product['product_id'] . '-' . $order_product['id_image']] = $order_product; } } } return $final_products_list; }
/** * Assign template vars related to page content * @see FrontController::initContent() */ public function initContent() { parent::initContent(); //Clean compare product table CompareProduct::cleanCompareProducts('week'); $hasProduct = false; if (!Configuration::get('PS_COMPARATOR_MAX_ITEM')) { return Tools::redirect('index.php?controller=404'); } if (($product_list = Tools::getValue('compare_product_list')) && ($postProducts = isset($product_list) ? rtrim($product_list, '|') : '')) { $ids = array_unique(explode('|', $postProducts)); } else { if (isset($this->context->cookie->id_compare)) { $ids = CompareProduct::getCompareProducts($this->context->cookie->id_compare); } else { $ids = null; } } if ($ids) { if (count($ids) > 0) { if (count($ids) > Configuration::get('PS_COMPARATOR_MAX_ITEM')) { $ids = array_slice($ids, 0, Configuration::get('PS_COMPARATOR_MAX_ITEM')); } $listProducts = array(); $listFeatures = array(); foreach ($ids as $k => &$id) { $curProduct = new Product((int) $id, true, $this->context->language->id); if (!Validate::isLoadedObject($curProduct) || !$curProduct->active || !$curProduct->isAssociatedToShop()) { if (isset($this->context->cookie->id_compare)) { CompareProduct::removeCompareProduct($this->context->cookie->id_compare, $id); } unset($ids[$k]); continue; } foreach ($curProduct->getFrontFeatures($this->context->language->id) as $feature) { $listFeatures[$curProduct->id][$feature['id_feature']] = $feature['value']; } $cover = Product::getCover((int) $id); $curProduct->id_image = Tools::htmlentitiesUTF8(Product::defineProductImage(array('id_image' => $cover['id_image'], 'id_product' => $id), $this->context->language->id)); $curProduct->allow_oosp = Product::isAvailableWhenOutOfStock($curProduct->out_of_stock); $listProducts[] = $curProduct; } if (count($listProducts) > 0) { $width = 80 / count($listProducts); $hasProduct = true; $ordered_features = Feature::getFeaturesForComparison($ids, $this->context->language->id); $this->context->smarty->assign(array('ordered_features' => $ordered_features, 'product_features' => $listFeatures, 'products' => $listProducts, 'width' => $width, 'homeSize' => Image::getSize(ImageType::getFormatedName('home')))); $this->context->smarty->assign('HOOK_EXTRA_PRODUCT_COMPARISON', Hook::exec('displayProductComparison', array('list_ids_product' => $ids))); } else { if (isset($this->context->cookie->id_compare)) { $object = new CompareProduct((int) $this->context->cookie->id_compare); if (Validate::isLoadedObject($object)) { $object->delete(); } } } } } $this->context->smarty->assign('hasProduct', $hasProduct); $this->setTemplate(_PS_THEME_DIR_ . 'products-comparison.tpl'); }
public static function getProductProperties($id_lang, $row, Context $context = null) { if (!$row['id_product']) { return false; } if ($context == null) { $context = Context::getContext(); } // Product::getDefaultAttribute is only called if id_product_attribute is missing from the SQL query at the origin of it: // consider adding it in order to avoid unnecessary queries $row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']); if (Combination::isFeatureActive() && (!isset($row['id_product_attribute']) || !$row['id_product_attribute']) && (isset($row['cache_default_attribute']) && ($ipa_default = $row['cache_default_attribute']) !== null || ($ipa_default = Product::getDefaultAttribute($row['id_product'], !$row['allow_oosp'])))) { $row['id_product_attribute'] = $ipa_default; } if (!Combination::isFeatureActive() || !isset($row['id_product_attribute'])) { $row['id_product_attribute'] = 0; } // Tax $usetax = Tax::excludeTaxeOption(); $cache_key = $row['id_product'] . '-' . $row['id_product_attribute'] . '-' . $id_lang . '-' . (int) $usetax; if (isset($row['id_product_pack'])) { $cache_key .= '-pack' . $row['id_product_pack']; } if (isset(self::$producPropertiesCache[$cache_key])) { return self::$producPropertiesCache[$cache_key]; } // Datas $row['category'] = Category::getLinkRewrite((int) $row['id_category_default'], (int) $id_lang); $row['link'] = $context->link->getProductLink((int) $row['id_product'], $row['link_rewrite'], $row['category'], $row['ean13']); $row['attribute_price'] = 0; if (isset($row['id_product_attribute']) && $row['id_product_attribute']) { $row['attribute_price'] = (double) Product::getProductAttributePrice($row['id_product_attribute']); } $row['price_tax_exc'] = Product::getPriceStatic((int) $row['id_product'], false, isset($row['id_product_attribute']) && !empty($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null, self::$_taxCalculationMethod == PS_TAX_EXC ? 2 : 6); if (self::$_taxCalculationMethod == PS_TAX_EXC) { $row['price_tax_exc'] = Tools::ps_round($row['price_tax_exc'], 2); $row['price'] = Product::getPriceStatic((int) $row['id_product'], true, isset($row['id_product_attribute']) && !empty($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null, 6); $row['price_without_reduction'] = Product::getPriceStatic((int) $row['id_product'], false, isset($row['id_product_attribute']) && !empty($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null, 2, null, false, false); } else { $row['price'] = Tools::ps_round(Product::getPriceStatic((int) $row['id_product'], true, isset($row['id_product_attribute']) && !empty($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null, 2), 2); $row['price_without_reduction'] = Product::getPriceStatic((int) $row['id_product'], true, isset($row['id_product_attribute']) && !empty($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null, 6, null, false, false); } $row['reduction'] = Product::getPriceStatic((int) $row['id_product'], (bool) $usetax, (int) $row['id_product_attribute'], 6, null, true, true, 1, true, null, null, null, $specific_prices); $row['specific_prices'] = $specific_prices; if ($row['id_product_attribute']) { $row['quantity_all_versions'] = $row['quantity']; $row['quantity'] = Product::getQuantity((int) $row['id_product'], $row['id_product_attribute'], isset($row['cache_is_pack']) ? $row['cache_is_pack'] : null); } else { $row['quantity'] = Product::getQuantity((int) $row['id_product']); } $row['id_image'] = Product::defineProductImage($row, $id_lang); $row['features'] = Product::getFrontFeaturesStatic((int) $id_lang, $row['id_product']); $row['attachments'] = array(); if (!isset($row['cache_has_attachments']) || $row['cache_has_attachments']) { $row['attachments'] = Product::getAttachmentsStatic((int) $id_lang, $row['id_product']); } $row['virtual'] = !isset($row['is_virtual']) || $row['is_virtual'] ? 1 : 0; // Pack management $row['pack'] = !isset($row['cache_is_pack']) ? Pack::isPack($row['id_product']) : (int) $row['cache_is_pack']; $row['packItems'] = $row['pack'] ? Pack::getItemTable($row['id_product'], $id_lang) : array(); $row['nopackprice'] = $row['pack'] ? Pack::noPackPrice($row['id_product']) : 0; if ($row['pack'] && !Pack::isInStock($row['id_product'])) { $row['quantity'] = 0; } self::$producPropertiesCache[$cache_key] = $row; return self::$producPropertiesCache[$cache_key]; }
protected function insertOrderItems(ShopgateOrder $order) { $this->log('start insertOrderItems()', ShopgateLogger::LOGTYPE_DEBUG); $products = array(); //Check product quantitys $settings = Configuration::getMultiple(array('SHOPGATE_MIN_QUANTITY_CHECK', 'SHOPGATE_OUT_OF_STOCK_CHECK')); // complete weight of the order foreach ($order->getItems() as $i) { list($id_product, $id_product_attribute) = $this->getProductIdentifiers($i); if ($id_product == 0) { continue; } $wantedQty = (int) $i->getQuantity(); $product = new Product($id_product, true, (int) Configuration::get('PS_LANG_DEFAULT')); $minQty = 1; if ((int) $id_product_attribute) { $stockQty = (int) Product::getQuantity((int) $id_product, (int) $id_product_attribute); if (version_compare(_PS_VERSION_, '1.4.0.7', '>=')) { // this attribute doesn't exist before 1.4.0.7 $minQty = Attribute::getAttributeMinimalQty((int) $id_product_attribute); } } else { $stockQty = (int) Product::getQuantity((int) $id_product, NULL); if (version_compare(_PS_VERSION_, '1.4.0.2', '>=')) { // this attribute doesn't exist before 1.4.0.2 $minQty = (int) $product->minimal_quantity; } } $oos_available = Product::isAvailableWhenOutOfStock($product->out_of_stock); $qtyDifference = 0; if (!$oos_available && $wantedQty > $stockQty) { $qtyDifference = $wantedQty - $stockQty; } $p = array(); $p['id_product'] = (int) $id_product; $p['id_product_attribute'] = (int) $id_product_attribute; $p['name'] = $product->name; $p['quantity'] = $wantedQty; $p['quantity_in_stock'] = $stockQty; $p['quantity_difference'] = $qtyDifference; if (empty($p['name'])) { $p['name'] = $i->getName(); } if ($oos_available) { $stockQty = $wantedQty; } if ((bool) $settings['SHOPGATE_MIN_QUANTITY_CHECK'] && $wantedQty < $minQty) { throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_DATABASE_ERROR, 'Minimum quantity required', true); } if ((bool) $settings['SHOPGATE_OUT_OF_STOCK_CHECK'] && $wantedQty > $stockQty) { throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_DATABASE_ERROR, 'Out of stock', true); } array_push($products, $p); } $this->log('end insertOrderItems()', ShopgateLogger::LOGTYPE_DEBUG); return $products; }
/** * Return cart products * * @result array Products */ public function getProducts($refresh = false, $id_product = false) { if (!$this->id) { return array(); } if ($this->_products and !$refresh) { return $this->_products; } $sql = ' SELECT cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, pl.`name`, pl.`description_short`, pl.`available_now`, pl.`available_later`, p.`id_product`, p.`id_category_default`, p.`id_supplier`, p.`id_manufacturer`, p.`id_tax`, p.`on_sale`, p.`ecotax`, p.`quantity`, p.`price`, p.`reduction_price`, p.`reduction_percent`, p.`reduction_from`, p.`reduction_to`, p.`weight`, p.`out_of_stock`, p.`active`, p.`date_add`, p.`date_upd`, t.`id_tax`, tl.`name` AS tax, t.`rate`, pa.`price` AS price_attribute, pa.`quantity` AS quantity_attribute, pa.`ecotax` AS ecotax_attr, i.`id_image`, il.`legend`, pl.`link_rewrite`, cl.`link_rewrite` AS category, CONCAT(cp.`id_product`, cp.`id_product_attribute`) AS unique_id, IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference, IF (IFNULL(pa.`supplier_reference`, \'\') = \'\', p.`supplier_reference`, pa.`supplier_reference`) AS supplier_reference, IF (IFNULL(pa.`weight`, 0) = \'\', p.`weight`, pa.`weight`) AS weight_attribute, IF (IFNULL(pa.`ean13`, \'\') = \'\', p.`ean13`, pa.`ean13`) AS ean13 FROM `' . _DB_PREFIX_ . 'cart_product` cp LEFT JOIN `' . _DB_PREFIX_ . 'product` p ON p.`id_product` = cp.`id_product` LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = ' . intval($this->id_lang) . ') LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON (pa.`id_product_attribute` = cp.`id_product_attribute`) LEFT JOIN `' . _DB_PREFIX_ . 'tax` t ON (t.`id_tax` = p.`id_tax`) LEFT JOIN `' . _DB_PREFIX_ . 'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = ' . intval($this->id_lang) . ') LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_image` pai ON (pai.`id_product_attribute` = cp.`id_product_attribute`) LEFT JOIN `' . _DB_PREFIX_ . 'image` i ON (i.`id_product` = cp.`id_product` AND (IF(pai.`id_image`, pai.`id_image` = i.`id_image`, i.`cover` = 1))) LEFT JOIN `' . _DB_PREFIX_ . 'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = ' . intval($this->id_lang) . ') LEFT JOIN `' . _DB_PREFIX_ . 'category_lang` cl ON (p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = ' . intval($this->id_lang) . ') WHERE `id_cart` = ' . intval($this->id) . ' ' . ($id_product ? ' AND cp.`id_product` = ' . intval($id_product) : '') . ' AND p.`id_product` IS NOT NULL GROUP BY unique_id ORDER BY cp.date_add ASC'; $result = Db::getInstance()->ExecuteS($sql); /* Modify SQL results */ $products = array(); if (empty($result)) { return array(); } foreach ($result as $k => $row) { if (isset($row['ecotax_attr']) and $row['ecotax_attr'] > 0) { $row['ecotax'] = floatval($row['ecotax_attr']); } $row['stock_quantity'] = intval($row['quantity']); $row['weight'] = $row['weight_attribute']; $row['quantity'] = intval($row['cart_quantity']); $row['price'] = Product::getPriceStatic(intval($row['id_product']), false, isset($row['id_product_attribute']) ? intval($row['id_product_attribute']) : NULL, 6, NULL, false, true, intval($row['quantity'])); $row['price_wt'] = Product::getPriceStatic(intval($row['id_product']), true, isset($row['id_product_attribute']) ? intval($row['id_product_attribute']) : NULL, 6, NULL, false, true, intval($row['quantity'])); $row['total'] = $row['price'] * intval($row['quantity']); $row['total_wt'] = $row['price_wt'] * intval($row['quantity']); $row['id_image'] = Product::defineProductImage($row); $row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']); $row['features'] = Product::getFeaturesStatic(intval($row['id_product'])); /* Add attributes to the SQL result if needed */ if (isset($row['id_product_attribute']) and intval($row['id_product_attribute'])) { $result2 = Db::getInstance()->ExecuteS(' SELECT agl.`public_name` AS public_group_name, al.`name` AS attribute_name FROM `' . _DB_PREFIX_ . 'product_attribute_combination` pac LEFT JOIN `' . _DB_PREFIX_ . 'attribute` a ON a.`id_attribute` = pac.`id_attribute` LEFT JOIN `' . _DB_PREFIX_ . 'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group` LEFT JOIN `' . _DB_PREFIX_ . 'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = ' . intval($this->id_lang) . ') LEFT JOIN `' . _DB_PREFIX_ . 'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = ' . intval($this->id_lang) . ') WHERE pac.`id_product_attribute` = ' . intval($row['id_product_attribute'])); $attributesList = ''; $attributesListSmall = ''; if ($result2) { foreach ($result2 as $k2 => $row2) { $attributesList .= $row2['public_group_name'] . ' : ' . $row2['attribute_name'] . ', '; $attributesListSmall .= $row2['attribute_name'] . ', '; } } $attributesList = rtrim($attributesList, ', '); $attributesListSmall = rtrim($attributesListSmall, ', '); $row['attributes'] = $attributesList; $row['attributes_small'] = $attributesListSmall; $row['stock_quantity'] = $row['quantity_attribute']; } $products[] = $row; } $this->_products = $products; return $this->_products; }
public function ajaxProcessUpdateQty() { if ($this->tabAccess['edit'] === '1') { $errors = array(); if (!$this->context->cart->id) { return; } if ($this->context->cart->OrderExists()) { $errors[] = Tools::displayError('An order has already been placed with this cart.'); } elseif (!($id_product = (int) Tools::getValue('id_product')) || !($product = new Product((int) $id_product, true, $this->context->language->id))) { $errors[] = Tools::displayError('Invalid product'); } elseif (!($qty = Tools::getValue('qty')) || $qty == 0) { $errors[] = Tools::displayError('Invalid quantity'); } // Don't try to use a product if not instanciated before due to errors if (isset($product) && $product->id) { if (($id_product_attribute = Tools::getValue('id_product_attribute')) != 0) { if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty((int) $id_product_attribute, (int) $qty)) { $errors[] = Tools::displayError('There is not enough product in stock.'); } } else { if (!$product->checkQty((int) $qty)) { $errors[] = Tools::displayError('There is not enough product in stock.'); } } if (!($id_customization = (int) Tools::getValue('id_customization', 0)) && !$product->hasAllRequiredCustomizableFields()) { $errors[] = Tools::displayError('Please fill in all the required fields.'); } $this->context->cart->save(); } else { $errors[] = Tools::displayError('This product cannot be added to the cart.'); } if (!count($errors)) { if ((int) $qty < 0) { $qty = str_replace('-', '', $qty); $operator = 'down'; } else { $operator = 'up'; } if (!($qty_upd = $this->context->cart->updateQty($qty, $id_product, (int) $id_product_attribute, (int) $id_customization, $operator))) { $errors[] = Tools::displayError('You already have the maximum quantity available for this product.'); } elseif ($qty_upd < 0) { $minimal_qty = $id_product_attribute ? Attribute::getAttributeMinimalQty((int) $id_product_attribute) : $product->minimal_quantity; $errors[] = sprintf(Tools::displayError('You must add a minimum quantity of %d', false), $minimal_qty); } } echo Tools::jsonEncode(array_merge($this->ajaxReturnVars(), array('errors' => $errors))); } }
} if (!isset($groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']])) { $groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] = 0; } $groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] += intval($row['quantity']); $combinations[$row['id_product_attribute']]['attributes_values'][$row['id_attribute_group']] = $row['attribute_name']; $combinations[$row['id_product_attribute']]['attributes'][] = intval($row['id_attribute']); $combinations[$row['id_product_attribute']]['price'] = floatval($row['price']); $combinations[$row['id_product_attribute']]['ecotax'] = floatval($row['ecotax']); $combinations[$row['id_product_attribute']]['weight'] = floatval($row['weight']); $combinations[$row['id_product_attribute']]['quantity'] = intval($row['quantity']); $combinations[$row['id_product_attribute']]['reference'] = $row['reference']; $combinations[$row['id_product_attribute']]['id_image'] = isset($combinationImages[$row['id_product_attribute']][0]['id_image']) ? $combinationImages[$row['id_product_attribute']][0]['id_image'] : -1; } //wash attributes list (if some attributes are unavailables and if allowed to wash it) if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && Configuration::get('PS_DISP_UNAVAILABLE_ATTR') == 0) { foreach ($groups as &$group) { foreach ($group['attributes_quantity'] as $key => &$quantity) { if (!$quantity) { unset($group['attributes'][$key]); } } } } foreach ($groups as &$group) { natcasesort($group['attributes']); } foreach ($combinations as $id_product_attribute => $comb) { $attributeList = ''; foreach ($comb['attributes'] as $id_attribute) { $attributeList .= '\'' . intval($id_attribute) . '\',';
/** * Update product quantity * * @param integer $quantity Quantity to add (or substract) * @param integer $id_product Product ID * @param integer $id_product_attribute Attribute ID if needed * @param string $operator Indicate if quantity must be increased or decreased */ public function updateQty($quantity, $id_product, $id_product_attribute = null, $id_customization = false, $operator = 'up', $id_address_delivery = 0, Shop $shop = null, $auto_add_cart_rule = true) { if (!$shop) { $shop = Context::getContext()->shop; } if (Context::getContext()->customer->id) { if ($id_address_delivery == 0 && (int) $this->id_address_delivery) { // The $id_address_delivery is null, use the cart delivery address $id_address_delivery = $this->id_address_delivery; } elseif ($id_address_delivery == 0) { // The $id_address_delivery is null, get the default customer address $id_address_delivery = (int) Address::getFirstCustomerAddressId((int) Context::getContext()->customer->id); } elseif (!Customer::customerHasAddress(Context::getContext()->customer->id, $id_address_delivery)) { // The $id_address_delivery must be linked with customer $id_address_delivery = 0; } } $quantity = (int) $quantity; $id_product = (int) $id_product; $id_product_attribute = (int) $id_product_attribute; $product = new Product($id_product, false, Configuration::get('PS_LANG_DEFAULT'), $shop->id); if ($id_product_attribute) { $combination = new Combination((int) $id_product_attribute); if ($combination->id_product != $id_product) { return false; } } /* If we have a product combination, the minimal quantity is set with the one of this combination */ if (!empty($id_product_attribute)) { $minimal_quantity = (int) Attribute::getAttributeMinimalQty($id_product_attribute); } else { $minimal_quantity = (int) $product->minimal_quantity; } if (!Validate::isLoadedObject($product)) { die(Tools::displayError()); } if (isset(self::$_nbProducts[$this->id])) { unset(self::$_nbProducts[$this->id]); } if (isset(self::$_totalWeight[$this->id])) { unset(self::$_totalWeight[$this->id]); } if ((int) $quantity <= 0) { return $this->deleteProduct($id_product, $id_product_attribute, (int) $id_customization); } elseif (!$product->available_for_order || Configuration::get('PS_CATALOG_MODE')) { return false; } else { /* Check if the product is already in the cart */ $result = $this->containsProduct($id_product, $id_product_attribute, (int) $id_customization, (int) $id_address_delivery); /* Update quantity if product already exist */ if ($result) { if ($operator == 'up') { $sql = 'SELECT stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity FROM ' . _DB_PREFIX_ . 'product p ' . Product::sqlStock('p', $id_product_attribute, true, $shop) . ' WHERE p.id_product = ' . $id_product; $result2 = Db::getInstance()->getRow($sql); $product_qty = (int) $result2['quantity']; // Quantity for product pack if (Pack::isPack($id_product)) { $product_qty = Pack::getQuantity($id_product, $id_product_attribute); } $new_qty = (int) $result['quantity'] + (int) $quantity; $qty = '+ ' . (int) $quantity; if (!Product::isAvailableWhenOutOfStock((int) $result2['out_of_stock'])) { if ($new_qty > $product_qty) { return false; } } } else { if ($operator == 'down') { $qty = '- ' . (int) $quantity; $new_qty = (int) $result['quantity'] - (int) $quantity; if ($new_qty < $minimal_quantity && $minimal_quantity > 1) { return -1; } } else { return false; } } /* Delete product from cart */ if ($new_qty <= 0) { return $this->deleteProduct((int) $id_product, (int) $id_product_attribute, (int) $id_customization); } else { if ($new_qty < $minimal_quantity) { return -1; } else { Db::getInstance()->execute(' UPDATE `' . _DB_PREFIX_ . 'cart_product` SET `quantity` = `quantity` ' . $qty . ', `date_add` = NOW() WHERE `id_product` = ' . (int) $id_product . (!empty($id_product_attribute) ? ' AND `id_product_attribute` = ' . (int) $id_product_attribute : '') . ' AND `id_cart` = ' . (int) $this->id . (Configuration::get('PS_ALLOW_MULTISHIPPING') && $this->isMultiAddressDelivery() ? ' AND `id_address_delivery` = ' . (int) $id_address_delivery : '') . ' LIMIT 1'); } } } elseif ($operator == 'up') { $sql = 'SELECT stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity FROM ' . _DB_PREFIX_ . 'product p ' . Product::sqlStock('p', $id_product_attribute, true, $shop) . ' WHERE p.id_product = ' . $id_product; $result2 = Db::getInstance()->getRow($sql); // Quantity for product pack if (Pack::isPack($id_product)) { $result2['quantity'] = Pack::getQuantity($id_product, $id_product_attribute); } if (!Product::isAvailableWhenOutOfStock((int) $result2['out_of_stock'])) { if ((int) $quantity > $result2['quantity']) { return false; } } if ((int) $quantity < $minimal_quantity) { return -1; } $result_add = Db::getInstance()->insert('cart_product', array('id_product' => (int) $id_product, 'id_product_attribute' => (int) $id_product_attribute, 'id_cart' => (int) $this->id, 'id_address_delivery' => (int) $id_address_delivery, 'id_shop' => $shop->id, 'quantity' => (int) $quantity, 'date_add' => date('Y-m-d H:i:s'))); if (!$result_add) { return false; } } } // refresh cache of self::_products $this->_products = $this->getProducts(true); $this->update(true); $context = Context::getContext()->cloneContext(); $context->cart = $this; Cache::clean('getContextualValue_*'); if ($auto_add_cart_rule) { CartRule::autoAddToCart($context); } if ($product->customizable) { return $this->_updateCustomizationQuantity((int) $quantity, (int) $id_customization, (int) $id_product, (int) $id_product_attribute, (int) $id_address_delivery, $operator); } else { return true; } }
public static function getProductProperties($id_lang, $row) { if (!$row['id_product']) { return false; } // Product::getDefaultAttribute is only called if id_product_attribute is missing from the SQL query at the origin of it: consider adding it in order to avoid unnecessary queries $row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']); if ((!isset($row['id_product_attribute']) or !$row['id_product_attribute']) and (isset($row['cache_default_attribute']) and ($ipa_default = $row['cache_default_attribute']) !== NULL or $ipa_default = Product::getDefaultAttribute($row['id_product'], !$row['allow_oosp']))) { $row['id_product_attribute'] = $ipa_default; } if (!isset($row['id_product_attribute'])) { $row['id_product_attribute'] = 0; } // Tax $usetax = Tax::excludeTaxeOption(); $cacheKey = $row['id_product'] . '-' . $row['id_product_attribute'] . '-' . $id_lang . '-' . (int) $usetax; if (array_key_exists($cacheKey, self::$producPropertiesCache)) { return self::$producPropertiesCache[$cacheKey]; } // Datas $link = new Link(); $row['category'] = Category::getLinkRewrite((int) $row['id_category_default'], (int) $id_lang); $row['link'] = $link->getProductLink((int) $row['id_product'], $row['link_rewrite'], $row['category'], $row['ean13']); $row['attribute_price'] = (isset($row['id_product_attribute']) and $row['id_product_attribute']) ? (double) Product::getProductAttributePrice($row['id_product_attribute']) : 0; $row['price_tax_exc'] = Product::getPriceStatic((int) $row['id_product'], false, (isset($row['id_product_attribute']) and !empty($row['id_product_attribute'])) ? (int) $row['id_product_attribute'] : NULL, self::$_taxCalculationMethod == PS_TAX_EXC ? 2 : 6); if (self::$_taxCalculationMethod == PS_TAX_EXC) { $row['price_tax_exc'] = Tools::ps_round($row['price_tax_exc'], 2); $row['price'] = Product::getPriceStatic((int) $row['id_product'], true, (isset($row['id_product_attribute']) and !empty($row['id_product_attribute'])) ? (int) $row['id_product_attribute'] : NULL, 6); $row['price_without_reduction'] = Product::getPriceStatic((int) $row['id_product'], false, (isset($row['id_product_attribute']) and !empty($row['id_product_attribute'])) ? (int) $row['id_product_attribute'] : NULL, 2, NULL, false, false); } else { $row['price'] = Tools::ps_round(Product::getPriceStatic((int) $row['id_product'], true, (isset($row['id_product_attribute']) and !empty($row['id_product_attribute'])) ? (int) $row['id_product_attribute'] : NULL, 2), 2); $row['price_without_reduction'] = Product::getPriceStatic((int) $row['id_product'], true, (isset($row['id_product_attribute']) and !empty($row['id_product_attribute'])) ? (int) $row['id_product_attribute'] : NULL, 6, NULL, false, false); } $row['reduction'] = Product::getPriceStatic((int) $row['id_product'], (bool) $usetax, (int) $row['id_product_attribute'], 6, NULL, true, true, 1, true, NULL, NULL, NULL, $specific_prices); $row['specific_prices'] = $specific_prices; if ($row['id_product_attribute']) { $row['quantity_all_versions'] = $row['quantity']; $row['quantity'] = Product::getQuantity((int) $row['id_product'], $row['id_product_attribute'], isset($row['cache_is_pack']) ? $row['cache_is_pack'] : NULL); } $row['id_image'] = Product::defineProductImage($row, $id_lang); $row['features'] = Product::getFrontFeaturesStatic((int) $id_lang, $row['id_product']); $row['attachments'] = (!isset($row['cache_has_attachments']) or $row['cache_has_attachments']) ? Product::getAttachmentsStatic((int) $id_lang, $row['id_product']) : array(); // Pack management $row['pack'] = !isset($row['cache_is_pack']) ? Pack::isPack($row['id_product']) : (int) $row['cache_is_pack']; $row['packItems'] = $row['pack'] ? Pack::getItemTable($row['id_product'], $id_lang) : array(); $row['nopackprice'] = $row['pack'] ? Pack::noPackPrice($row['id_product']) : 0; if ($row['pack'] and !Pack::isInStock($row['id_product'])) { $row['quantity'] = 0; } self::$producPropertiesCache[$cacheKey] = $row; return self::$producPropertiesCache[$cacheKey]; }
/** * Assign template vars related to attribute groups and colors */ protected function assignAttributesGroups() { $colors = array(); $groups = array(); // @todo (RM) should only get groups and not all declination ? $attributes_groups = $this->product->getAttributesGroups($this->context->language->id); if (is_array($attributes_groups) && $attributes_groups) { $combination_images = $this->product->getCombinationImages($this->context->language->id); $combination_prices_set = array(); foreach ($attributes_groups as $k => $row) { // Color management if (isset($row['attribute_color']) && $row['attribute_color'] || file_exists(_PS_COL_IMG_DIR_ . $row['id_attribute'] . '.jpg')) { $colors[$row['id_attribute']]['value'] = $row['attribute_color']; $colors[$row['id_attribute']]['name'] = $row['attribute_name']; if (!isset($colors[$row['id_attribute']]['attributes_quantity'])) { $colors[$row['id_attribute']]['attributes_quantity'] = 0; } $colors[$row['id_attribute']]['attributes_quantity'] += (int) $row['quantity']; } if (!isset($groups[$row['id_attribute_group']])) { $groups[$row['id_attribute_group']] = array('name' => $row['public_group_name'], 'group_type' => $row['group_type'], 'default' => -1); } $groups[$row['id_attribute_group']]['attributes'][$row['id_attribute']] = $row['attribute_name']; if ($row['default_on'] && $groups[$row['id_attribute_group']]['default'] == -1) { $groups[$row['id_attribute_group']]['default'] = (int) $row['id_attribute']; } if (!isset($groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']])) { $groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] = 0; } $groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] += (int) $row['quantity']; if ($row['available_date'] != '0000-00-00 00:00:00' && $row['available_date'] != '0000-00-00') { $available_date = Tools::displayDate($row['available_date'], $this->context->language->id); } else { $available_date = $row['available_date']; } $combinations[$row['id_product_attribute']]['attributes_values'][$row['id_attribute_group']] = $row['attribute_name']; $combinations[$row['id_product_attribute']]['attributes'][] = (int) $row['id_attribute']; $combinations[$row['id_product_attribute']]['price'] = (double) $row['price']; // Call getPriceStatic in order to set $combination_specific_price if (!isset($combination_prices_set[(int) $row['id_product_attribute']])) { Product::getPriceStatic((int) $this->product->id, false, $row['id_product_attribute'], 6, null, false, true, 1, false, null, null, null, $combination_specific_price); $combination_prices_set[(int) $row['id_product_attribute']] = true; $combinations[$row['id_product_attribute']]['specific_price'] = $combination_specific_price; } $combinations[$row['id_product_attribute']]['ecotax'] = (double) $row['ecotax']; $combinations[$row['id_product_attribute']]['weight'] = (double) $row['weight']; $combinations[$row['id_product_attribute']]['quantity'] = (int) $row['quantity']; $combinations[$row['id_product_attribute']]['reference'] = $row['reference']; $combinations[$row['id_product_attribute']]['unit_impact'] = $row['unit_price_impact']; $combinations[$row['id_product_attribute']]['minimal_quantity'] = $row['minimal_quantity']; $combinations[$row['id_product_attribute']]['available_date'] = $available_date; if (isset($combination_images[$row['id_product_attribute']][0]['id_image'])) { $combinations[$row['id_product_attribute']]['id_image'] = $combination_images[$row['id_product_attribute']][0]['id_image']; } else { $combinations[$row['id_product_attribute']]['id_image'] = -1; } } // wash attributes list (if some attributes are unavailables and if allowed to wash it) if (!Product::isAvailableWhenOutOfStock($this->product->out_of_stock) && Configuration::get('PS_DISP_UNAVAILABLE_ATTR') == 0) { foreach ($groups as &$group) { foreach ($group['attributes_quantity'] as $key => &$quantity) { if (!$quantity) { unset($group['attributes'][$key]); } } } foreach ($colors as $key => $color) { if (!$color['attributes_quantity']) { unset($colors[$key]); } } } foreach ($combinations as $id_product_attribute => $comb) { $attribute_list = ''; foreach ($comb['attributes'] as $id_attribute) { $attribute_list .= '\'' . (int) $id_attribute . '\','; } $attribute_list = rtrim($attribute_list, ','); $combinations[$id_product_attribute]['list'] = $attribute_list; } $this->context->smarty->assign(array('groups' => $groups, 'combinations' => $combinations, 'colors' => count($colors) ? $colors : false, 'combinationImages' => $combination_images)); } }
public static function getProductProperties($id_lang, $row) { if (!$row['id_product']) { return false; } // Product::getDefaultAttribute is only called if id_product_attribute is missing from the SQL query at the origin of it: consider adding it in order to avoid unnecessary queries $row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']); if ((!isset($row['id_product_attribute']) or !$row['id_product_attribute']) and (isset($row['cache_default_attribute']) and ($ipa_default = $row['cache_default_attribute']) !== NULL or $ipa_default = Product::getDefaultAttribute($row['id_product'], !$row['allow_oosp']))) { $row['id_product_attribute'] = $ipa_default; } if (!isset($row['id_product_attribute'])) { $row['id_product_attribute'] = 0; } // Tax $usetax = Tax::excludeTaxeOption(); $cacheKey = $row['id_product'] . '-' . $row['id_product_attribute'] . '-' . $id_lang . '-' . (int) $usetax; if (array_key_exists($cacheKey, self::$producPropertiesCache)) { return self::$producPropertiesCache[$cacheKey]; } // Datas $row['category'] = Category::getLinkRewrite((int) $row['id_category_default'], (int) $id_lang); if (!preg_match("/^1.3.*/", _PS_VERSION_)) { // Not available in Prestashop 1.3.x $row['reduction'] = Product::getPriceStatic((int) $row['id_product'], (bool) $usetax, (int) $row['id_product_attribute'], 6, NULL, true, true, 1, true, NULL, NULL, NULL, $specific_prices); $row['specific_prices'] = $specific_prices; } if ($row['id_product_attribute']) { $row['quantity_all_versions'] = $row['quantity']; $row['quantity'] = Product::getQuantity((int) $row['id_product'], $row['id_product_attribute'], isset($row['cache_is_pack']) ? $row['cache_is_pack'] : NULL); } $row['id_image'] = Product::defineProductImage($row, $id_lang); $row['features'] = Product::getFrontFeaturesStatic((int) $id_lang, $row['id_product']); // Pack management $row['pack'] = !isset($row['cache_is_pack']) ? Pack::isPack($row['id_product']) : (int) $row['cache_is_pack']; $row['packItems'] = $row['pack'] ? Pack::getItemTable($row['id_product'], $id_lang) : array(); $row['nopackprice'] = $row['pack'] ? Pack::noPackPrice($row['id_product']) : 0; if ($row['pack'] and !Pack::isInStock($row['id_product'])) { $row['quantity'] = 0; } $sql_combination = ' SELECT pa.id_product_attribute, pa.price, pa.quantity, pa.id_product FROM `' . _DB_PREFIX_ . 'product` p LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON (p.`id_product` = pa.`id_product`) WHERE p.`id_product` =' . $row['id_product']; $result_combination = ProductExtended::getDbInstance()->ExecuteS($sql_combination); $row['combinations'] = array(); if ($result_combination) { foreach ($result_combination as $combination) { $combination['attributes'] = array(); /* New combinations system Prestashop 1.5.x */ if (!preg_match("/^1.(3|4).*/", _PS_VERSION_)) { $combination['quantity'] = StockAvailable::getQuantityAvailableByProduct($row['id_product'], $combination['id_product_attribute']); } if (isset($combination['id_product_attribute'])) { $sql_attribute = ' SELECT pa.id_product_attribute, agl.id_attribute_group, al.name as name_value, agl.name as name_option FROM `' . _DB_PREFIX_ . 'product_attribute` pa LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_combination` pac ON (pac.`id_product_attribute` = pa.`id_product_attribute`) LEFT JOIN `' . _DB_PREFIX_ . 'attribute` a ON (a.`id_attribute` = pac.`id_attribute`) LEFT JOIN `' . _DB_PREFIX_ . 'attribute_lang` al ON (al.`id_attribute` = a.`id_attribute` AND al.`id_lang` = ' . $id_lang . ') LEFT JOIN `' . _DB_PREFIX_ . 'attribute_group` ag ON (ag.`id_attribute_group` = a.`id_attribute_group`) LEFT JOIN `' . _DB_PREFIX_ . 'attribute_group_lang` agl ON (agl.`id_attribute_group` = ag.`id_attribute_group` AND agl.`id_lang` = ' . $id_lang . ') WHERE pa.`id_product_attribute` =' . $combination['id_product_attribute']; $result_attribute = ProductExtended::getDbInstance()->ExecuteS($sql_attribute); if ($result_attribute) { foreach ($result_attribute as $attribute) { array_push($combination['attributes'], $attribute); } } array_push($row['combinations'], $combination); } } } $sql_image = ' SELECT DISTINCT i.*, pl.link_rewrite FROM `' . _DB_PREFIX_ . 'product` p LEFT JOIN `' . _DB_PREFIX_ . 'image` i ON (p.`id_product` = i.`id_product`) LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (p.`id_product` = pl.`id_product`) WHERE p.`id_product` =' . $row['id_product']; $result_image = ProductExtended::getDbInstance()->ExecuteS($sql_image); $row['images'] = array(); $lang = new Language($id_lang); $row['url_locale'] = $lang->iso_code; if ($result_image) { $link = preg_match("/^1.(3|4).*/", _PS_VERSION_) ? new Link() : Context::getContext()->link; foreach ($result_image as $image) { if (!preg_match("/^1.3.*/", _PS_VERSION_)) { // Image URL gives relative version using 1.3.x- $image['image_url'] = $link->getImageLink($image['link_rewrite'], $image['id_product'] . '-' . $image['id_image']); } array_push($row['images'], $image); } } self::$producPropertiesCache[$cacheKey] = $row; return self::$producPropertiesCache[$cacheKey]; }