diff --git a/controllers/front/ProductController.php b/controllers/front/ProductController.php
index 8cf1f087b..7e0316931 100644
--- a/controllers/front/ProductController.php
+++ b/controllers/front/ProductController.php
@@ -56,6 +56,10 @@ class ProductControllerCore extends FrontController
parent::canonicalRedirection($this->context->link->getProductLink($this->product));
}
+ /**
+ * Initialize product controller
+ * @see FrontController::init()
+ */
public function init()
{
parent::init();
@@ -70,184 +74,244 @@ class ProductControllerCore extends FrontController
}
else
$this->canonicalRedirection();
+
+ if (Pack::isPack((int)$this->product->id) && !Pack::isInStock((int)$this->product->id))
+ $this->product->quantity = 0;
+
+ $this->product->description = $this->transformDescriptionWithImg($this->product->description);
}
-
- public function process()
+
+ /**
+ * Start forms process
+ * @see FrontController::preProcess()
+ */
+ public function preProcess()
{
- parent::process();
-
if (!Validate::isLoadedObject($this->product))
$this->errors[] = Tools::displayError('Product not found');
else
{
+ /*
+ * If the product is associated to the shop
+ * and is active or not active but preview mode (need token + file_exists)
+ * allow showing the product
+ * In all the others cases => 404 "Product is no longer available"
+ */
if (!$this->product->isAssociatedToShop()
- OR (!$this->product->active AND (Tools::getValue('adtoken') != Tools::encrypt('PreviewProduct'.$this->product->id))
- || !file_exists(dirname(__FILE__).'/../'.Tools::getValue('ad').'/ajax.php')))
+ || ((!$this->product->active && ((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(isset($this->context->customer) ? $this->context->customer->id : 0))
+ else if (!$this->product->checkAccess(isset($this->context->customer) ? $this->context->customer->id : 0))
$this->errors[] = Tools::displayError('You do not have access to this product.');
- else
+ }
+ }
+
+ /**
+ * Assign template vars related to page content
+ * @see FrontController::process()
+ */
+ public function process()
+ {
+ parent::process();
+
+ if (!count($this->errors))
+ {
+ // Assign to the tempate the id of the virtuale product. "0" if the product is not downloadable.
+ $this->context->smarty->assign('virtual', ProductDownload::getIdFromIdProduct((int)($this->product->id)));
+
+ // If the product is not active, it's the admin preview mode
+ if (!$this->product->active)
+ $this->context->smarty->assign('adminActionDisplay', true);
+
+ // Product pictures management
+ require_once('images.inc.php');
+ $this->context->smarty->assign('customizationFormTarget', Tools::safeOutput(urldecode($_SERVER['REQUEST_URI'])));
+
+ if (Tools::isSubmit('submitCustomizedDatas'))
{
- $this->context->smarty->assign('virtual', ProductDownload::getIdFromIdProduct((int)($this->product->id)));
-
- if (!$this->product->active)
- $this->context->smarty->assign('adminActionDisplay', true);
-
- /* Product pictures management */
- require_once('images.inc.php');
- $this->context->smarty->assign('customizationFormTarget', Tools::safeOutput(urldecode($_SERVER['REQUEST_URI'])));
-
- if (Tools::isSubmit('submitCustomizedDatas'))
+ // If cart has not been saved, we need to do it so that customization fields can have an id_cart
+ // We check that the cookie exists first to avoid ghost carts
+ if (!$this->context->cart->id && isset($_COOKIE[$this->context->cookie->getName()]))
{
- // If cart has not been saved, we need to do it so that customization fields can have an id_cart
- // We check that the cookie exists first to avoid ghost carts
- if (!$this->context->cart->id && isset($_COOKIE[$this->context->cookie->getName()]))
- {
- $this->context->cart->add();
- $this->context->cookie->id_cart = (int)$this->context->cart->id;
- }
- $this->pictureUpload($this->product, $this->context->cart);
- $this->textRecord($this->product, $this->context->cart);
- $this->formTargetFormat();
+ $this->context->cart->add();
+ $this->context->cookie->id_cart = (int)$this->context->cart->id;
}
- elseif (isset($_GET['deletePicture']) AND !$this->context->cart->deletePictureToProduct($this->product->id, Tools::getValue('deletePicture')))
- $this->errors[] = Tools::displayError('An error occurred while deleting the selected picture');
+ $this->pictureUpload($this->product, $this->context->cart);
+ $this->textRecord($this->product, $this->context->cart);
+ $this->formTargetFormat();
+ }
+ else if (Tools::getIsset('deletePicture') && !$this->context->cart->deletePictureToProduct($this->product->id, Tools::getValue('deletePicture')))
+ $this->errors[] = Tools::displayError('An error occurred while deleting the selected picture');
- $files = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_FILE, true);
- $pictures = array();
- foreach($files as $file)
- $pictures['pictures_'.$this->product->id.'_'.$file['index']] = $file['value'];
+ $files = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_FILE, true);
+ $pictures = array();
+ foreach ($files as $file)
+ $pictures['pictures_'.$this->product->id.'_'.$file['index']] = $file['value'];
- $texts = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_TEXTFIELD, true);
- $textFields = array();
- foreach ($texts as $textField)
- $textFields['textFields_'.$this->product->id.'_'.$textField['index']] = str_replace('
', "\n", $textField['value']);
- $this->context->smarty->assign(array(
- 'pictures' => $pictures,
- 'textFields' => $textFields));
+ $texts = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_TEXTFIELD, true);
+ $textFields = array();
+ foreach ($texts as $textField)
+ $textFields['textFields_'.$this->product->id.'_'.$textField['index']] = str_replace('
', "\n", $textField['value']);
+ $this->context->smarty->assign(array(
+ 'pictures' => $pictures,
+ 'textFields' => $textFields));
- $configs = Configuration::getMultiple(array('PS_ORDER_OUT_OF_STOCK', 'PS_LAST_QTIES'));
+ // Assign template vars related to the category + execute hooks related to the category
+ $this->assignCategory();
+ // Assign template vars related to the price and tax
+ $this->assignPriceAndTax();
+
- /* Features / Values */
- $features = $this->product->getFrontFeatures($this->context->language->id);
- $attachments = ($this->product->cache_has_attachments) ? $this->product->getAttachments($this->context->language->id) : array();
+ // Assign template vars related to the images
+ $this->assignImages();
+ // Assign attribute groups to the template
+ $this->assignAttributesGroups();
- /* 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'))
+ // Pack management
+ $this->context->smarty->assign('packItems', $this->product->cache_is_pack ? Pack::getItemTable($this->product->id, $this->context->language->id, true) : array());
+ $this->context->smarty->assign('packs', Pack::getPacksTable($this->product->id, $this->context->language->id, true, 1));
+
+ $this->context->smarty->assign(array(
+ 'customizationFields' => ($this->product->customizable) ? $this->product->getCustomizationFields($this->context->language->id) : false,
+ 'accessories' => $this->product->getAccessories($this->context->language->id),
+ 'return_link' => (isset($category->id) && $category->id) ? Tools::safeOutput($this->context->link->getCategoryLink($category)) : 'javascript: history.back();',
+ 'product' => $this->product,
+ 'product_manufacturer' => new Manufacturer((int)$this->product->id_manufacturer, $this->context->language->id),
+ 'token' => Tools::getToken(false),
+ 'features' => $this->product->getFrontFeatures($this->context->language->id),
+ 'attachments' => (($this->product->cache_has_attachments) ? $this->product->getAttachments($this->context->language->id) : array()),
+ 'allow_oosp' => $this->product->isAvailableWhenOutOfStock((int)$this->product->out_of_stock),
+ 'last_qties' => (int)Configuration::get('PS_LAST_QTIES'),
+ 'HOOK_EXTRA_LEFT' => Module::hookExec('extraLeft'),
+ 'HOOK_EXTRA_RIGHT' => Module::hookExec('extraRight'),
+ 'HOOK_PRODUCT_OOS' => Hook::productOutOfStock($this->product),
+ 'HOOK_PRODUCT_ACTIONS' => Module::hookExec('productActions'),
+ 'HOOK_PRODUCT_TAB' => Module::hookExec('productTab'),
+ 'HOOK_PRODUCT_TAB_CONTENT' => Module::hookExec('productTabContent'),
+ 'display_qties' => (int)(Configuration::get('PS_DISPLAY_QTIES')),
+ 'display_ht' => !Tax::excludeTaxeOption(),
+ 'currencySign' => $this->context->currency->sign,
+ 'currencyRate' => $this->context->currency->conversion_rate,
+ 'currencyFormat' => $this->context->currency->format,
+ 'currencyBlank' => $this->context->currency->blank,
+ 'jqZoomEnabled' => Configuration::get('PS_DISPLAY_JQZOOM'),
+ 'ENT_NOQUOTES' => ENT_NOQUOTES,
+ 'outOfStockAllowed' => (int)(Configuration::get('PS_ORDER_OUT_OF_STOCK'))
+ ));
+ }
+
+ $this->context->smarty->assign('errors', $this->errors);
+
+ $this->setTemplate(_PS_THEME_DIR_.'product.tpl');
+ }
+
+ /**
+ * Assign price and tax to the template
+ */
+ private function assignPriceAndTax()
+ {
+ $id_customer = (isset($this->context->customer) ? (int)($this->context->customer->id) : 0);
+ $group_reduction = (100 - Group::getReduction($id_customer)) / 100;
+ $id_group = (isset($this->context->customer) ? $this->context->customer->id_default_group : _PS_DEFAULT_CUSTOMER_GROUP_);
+ $id_country = (int)($id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get('PS_COUNTRY_DEFAULT'));
+
+ // Tax
+ $tax = (float)$this->product->getTaxesRate(new Address((int)$this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
+ $this->context->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 = (float)($productPriceWithTax - $this->product->ecotax);
+
+ $ecotax_rate = (float)Tax::getProductEcotaxRate($this->context->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);
+
+ $quantityDiscounts = SpecificPrice::getQuantityDiscounts((int)$this->product->id, $this->context->shop->getID(true), (int)$this->context->cookie->id_currency, $id_country, $id_group);
+
+ $productPrice = $this->product->getPrice(Product::$_taxCalculationMethod == PS_TAX_INC, false);
+
+ $this->context->smarty->assign(array(
+ 'quantity_discounts' => $this->formatQuantityDiscounts($quantityDiscounts, $productPrice, (float)$tax),
+ 'ecotax_tax_inc' => $ecotaxTaxAmount,
+ 'ecotax_tax_exc' => Tools::ps_round($this->product->ecotax, 2),
+ 'ecotaxTax_rate' => $ecotax_rate,
+ 'productPriceWithoutEcoTax' => (float)$productPriceWithoutEcoTax,
+ 'group_reduction' => $group_reduction,
+ 'no_tax' => Tax::excludeTaxeOption() || !$this->product->getTaxesRate(new Address($this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')})),
+ 'ecotax' => (!count($this->errors) && $this->product->ecotax > 0 ? Tools::convertPrice((float)($this->product->ecotax)) : 0),
+ 'tax_enabled' => Configuration::get('PS_TAX')
+ ));
+ }
+
+ /**
+ * Assign template vars related to images
+ */
+ private function assignImages()
+ {
+ $images = $this->product->getImages((int)$this->context->cookie->id_lang);
+ $productImages = array();
+ foreach ($images as $k => $image)
+ {
+ if ($image['cover'])
+ {
+ $this->context->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' => $this->context->language->iso_code.'-default', 'legend' => 'No picture', 'title' => 'No picture');
+ $size = Image::getSize('large');
+ $this->context->smarty->assign(array(
+ 'have_image' => Product::getCover((int)(Tools::getValue('id_product'))),
+ 'cover' => $cover,
+ 'imgWidth' => (int)($size['width']),
+ 'mediumSize' => Image::getSize('medium'),
+ 'largeSize' => Image::getSize('large'),
+ 'homeSize' => Image::getSize('home'),
+ 'col_img_dir' => _PS_COL_IMG_DIR_));
+ if (count($productImages))
+ $this->context->smarty->assign('images', $productImages);
+ }
+
+ /**
+ * Assign template vars related to attribute groups and colors
+ */
+ private function assignAttributesGroups()
+ {
+ $colors = array();
+ $attributesGroups = $this->product->getAttributesGroups($this->context->language->id); // @todo (RM) should only get groups and not all declination ?
+ if (is_array($attributesGroups) && $attributesGroups)
+ {
+ $groups = array();
+ $combinationImages = $this->product->getCombinationImages($this->context->language->id);
+ foreach ($attributesGroups as $k => $row)
+ {
+ // Color management
+ if ((isset($row['attribute_color']) && $row['attribute_color']) || (file_exists(_PS_COL_IMG_DIR_.$row['id_attribute'].'.jpg')))
{
- 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($regs[2], (int)$this->context->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($regs[5], (int)$this->context->cookie->id_lang);
- }
+ $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 (!$category)
- $category = new Category($this->product->id_category_default, (int)$this->context->cookie->id_lang);
-
- if (isset($category) AND Validate::isLoadedObject($category))
- {
- $this->context->smarty->assign(array(
- 'path' => Tools::getPath($category->id, $this->product->name, true),
- 'category' => $category,
- 'subCategories' => $category->getSubCategories($this->context->language->id, true),
- 'id_category_current' => (int)($category->id),
- 'id_category_parent' => (int)($category->id_parent),
- 'return_category_name' => Tools::safeOutput($category->name),
- ));
- }
- else
- $this->context->smarty->assign('path', Tools::getPath((int)$this->product->id_category_default, $this->product->name));
-
- $this->context->smarty->assign('return_link', (isset($category->id) AND $category->id) ? Tools::safeOutput($this->context->link->getCategoryLink($category)) : 'javascript: history.back();');
-
- if (Pack::isPack((int)$this->product->id) AND !Pack::isInStock((int)$this->product->id))
- $this->product->quantity = 0;
-
- $id_customer = (isset($this->context->customer) ? (int)($this->context->customer->id) : 0);
- $group_reduction = (100 - Group::getReduction($id_customer)) / 100;
- $id_group = (isset($this->context->customer) ? $this->context->customer->id_default_group : _PS_DEFAULT_CUSTOMER_GROUP_);
- $id_country = (int)($id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get('PS_COUNTRY_DEFAULT'));
-
- // Tax
- $tax = (float)$this->product->getTaxesRate(new Address((int)$this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
- $this->context->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 = (float)($productPriceWithTax - $this->product->ecotax);
-
- $ecotax_rate = (float) Tax::getProductEcotaxRate($this->context->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);
-
- $this->context->smarty->assign(array(
- 'quantity_discounts' => $this->formatQuantityDiscounts(SpecificPrice::getQuantityDiscounts((int)$this->product->id, $this->context->shop->getID(true), (int)$this->context->cookie->id_currency, $id_country, $id_group), $this->product->getPrice(Product::$_taxCalculationMethod == PS_TAX_INC, false), (float)$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, $this->context->language->id),
- 'token' => Tools::getToken(false),
- 'productPriceWithoutEcoTax' => (float)$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_,
- ));
- $this->context->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)$this->context->cookie->id_lang);
- $productImages = array();
- foreach ($images AS $k => $image)
- {
- if ($image['cover'])
- {
- $this->context->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' => $this->context->language->iso_code.'-default', 'legend' => 'No picture', 'title' => 'No picture');
- $size = Image::getSize('large');
- $this->context->smarty->assign(array(
- 'cover' => $cover,
- 'imgWidth' => (int)($size['width']),
- 'mediumSize' => Image::getSize('medium'),
- 'largeSize' => Image::getSize('large'),
- 'accessories' => $this->product->getAccessories($this->context->language->id)));
- if (sizeof($productImages))
- $this->context->smarty->assign('images', $productImages);
-
- /* Attributes / Groups & colors */
- $colors = array();
- $attributesGroups = $this->product->getAttributesGroups($this->context->language->id); // @todo (RM) should only get groups and not all declination ?
- if (is_array($attributesGroups) AND $attributesGroups)
+ 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 = array();
$combinationImages = $this->product->getCombinationImages($this->context->language->id);
foreach ($attributesGroups AS $k => $row)
@@ -277,7 +341,10 @@ class ProductControllerCore extends FrontController
$groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] = 0;
$groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] += (int)($row['quantity']);
- $availableDate = ($row['available_date'] != '0000-00-00') ? Tools::displayDate($row['available_date'], $this->context->language->id) : $row['available_date'];
+ if($row['available_date'] != '0000-00-00' && $row['available_date'] != '0000-00-00 00:00:00')
+ $availableDate = Tools::displayDate($row['available_date'], $this->context->language->id);
+ else
+ $availableDate = $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']);
@@ -320,37 +387,106 @@ class ProductControllerCore extends FrontController
'combinationImages' => $combinationImages));
}
- $this->context->smarty->assign(array(
- 'no_tax' => Tax::excludeTaxeOption() OR !$this->product->getTaxesRate(new Address($this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')})),
- 'customizationFields' => ($this->product->customizable) ? $this->product->getCustomizationFields($this->context->language->id) : false,
- ));
+ $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']);
- // Pack management
- $this->context->smarty->assign('packItems', $this->product->cache_is_pack ? Pack::getItemTable($this->product->id, $this->context->language->id, true) : array());
- $this->context->smarty->assign('packs', Pack::getPacksTable($this->product->id, $this->context->language->id, true, 1));
+ if($row['available_date'] != '0000-00-00 00:00:00' && $row['available_date'] != '0000-00-00')
+ $availableDate = Tools::displayDate($row['available_date'], $this->context->language->id);
+ else
+ $availableDate = $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'] = (float)($row['price']);
+ $combinations[$row['id_product_attribute']]['ecotax'] = (float)($row['ecotax']);
+ $combinations[$row['id_product_attribute']]['weight'] = (float)($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'] = $availableDate;
+ if (isset($combinationImages[$row['id_product_attribute']][0]['id_image']))
+ $combinations[$row['id_product_attribute']]['id_image'] = $combinationImages[$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]);
- $this->product->description = $this->transformDescriptionWithImg($this->product->description);
+ foreach ($colors as $key => $color)
+ if (!$color['attributes_quantity'])
+ unset($colors[$key]);
+ }
+
+ 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;
+ }
+ $this->context->smarty->assign(array(
+ 'groups' => $groups,
+ 'combinaisons' => $combinations, /* Kept for compatibility purpose only */
+ 'combinations' => $combinations,
+ 'colors' => (count($colors)) ? $colors : false,
+ 'combinationImages' => $combinationImages));
+ }
+ }
+
+ /**
+ * Assign template vars related to category
+ */
+ private function assignCategory()
+ {
+ $category = false;
+ if (isset($_SERVER['HTTP_REFERER'])
+ && !strstr($_SERVER['HTTP_REFERER'], Tools::getHttpHost()) // Assure us the previous page was one of the shop
+ && preg_match('!^(.*)\/([0-9]+)\-(.*[^\.])|(.*)id_category=([0-9]+)(.*)$!', $_SERVER['HTTP_REFERER'], $regs))
+ {
+ // If the previous page was a category and is a parent category of the product use this category as parent category
+ if (isset($regs[2]) && is_numeric($regs[2]))
+ {
+ if (Product::idIsOnCategoryId((int)$this->product->id, array('0' => array('id_category' => (int)$regs[2]))))
+ $category = new Category($regs[2], (int)$this->context->cookie->id_lang);
+ }
+ else if (isset($regs[5]) && is_numeric($regs[5]))
+ {
+ if (Product::idIsOnCategoryId((int)($this->product->id), array('0' => array('id_category' => (int)$regs[5]))))
+ $category = new Category($regs[5], (int)$this->context->cookie->id_lang);
}
}
+ else
+ // Set default product category
+ $category = new Category($this->product->id_category_default, (int)$this->context->cookie->id_lang);
- $this->context->smarty->assign(array(
- 'ENT_NOQUOTES' => ENT_NOQUOTES,
- 'outOfStockAllowed' => (int)(Configuration::get('PS_ORDER_OUT_OF_STOCK')),
- 'errors' => $this->errors,
- 'categories' => Category::getHomeCategories($this->context->language->id),
- '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((float)($this->product->ecotax)) : 0),
- 'currencySign' => $this->context->currency->sign,
- 'currencyRate' => $this->context->currency->conversion_rate,
- 'currencyFormat' => $this->context->currency->format,
- 'currencyBlank' => $this->context->currency->blank,
- 'jqZoomEnabled' => Configuration::get('PS_DISPLAY_JQZOOM')
- ));
-
- $this->setTemplate(_PS_THEME_DIR_.'product.tpl');
+ // Assign category to the template
+ if ($category !== false && Validate::isLoadedObject($category))
+ {
+ $this->context->smarty->assign(array(
+ 'path' => Tools::getPath($category->id, $this->product->name, true),
+ 'category' => $category,
+ 'subCategories' => $category->getSubCategories($this->context->language->id, true),
+ 'id_category_current' => (int)($category->id),
+ 'id_category_parent' => (int)($category->id_parent),
+ 'return_category_name' => Tools::safeOutput($category->name)
+ ));
+ }
+ else
+ $this->context->smarty->assign('path', Tools::getPath((int)$this->product->id_category_default, $this->product->name));
+
+ $this->context->smarty->assign('categories', Category::getHomeCategories($this->context->language->id));
+ $this->context->smarty->assign(array('HOOK_PRODUCT_FOOTER' => Hook::productFooter($this->product, $category)));
}
public function transformDescriptionWithImg($desc)
@@ -371,26 +507,26 @@ class ProductControllerCore extends FrontController
if (!$fieldIds = $this->product->getCustomizationFieldIds())
return false;
$authorizedFileFields = array();
- foreach ($fieldIds AS $fieldId)
+ foreach ($fieldIds as $fieldId)
if ($fieldId['type'] == Product::CUSTOMIZE_FILE)
$authorizedFileFields[(int)($fieldId['id_customization_field'])] = 'file'.(int)($fieldId['id_customization_field']);
$indexes = array_flip($authorizedFileFields);
- foreach ($_FILES AS $fieldName => $file)
- if (in_array($fieldName, $authorizedFileFields) AND isset($file['tmp_name']) AND !empty($file['tmp_name']))
+ foreach ($_FILES as $fieldName => $file)
+ if (in_array($fieldName, $authorizedFileFields) && isset($file['tmp_name']) && !empty($file['tmp_name']))
{
$fileName = md5(uniqid(rand(), true));
if ($error = checkImage($file, (int)(Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE'))))
$this->errors[] = $error;
- if ($error OR (!$tmpName = tempnam(_PS_TMP_IMG_DIR_, 'PS') OR !move_uploaded_file($file['tmp_name'], $tmpName)))
+ if ($error || (!$tmpName = tempnam(_PS_TMP_IMG_DIR_, 'PS') || !move_uploaded_file($file['tmp_name'], $tmpName)))
return false;
/* Original file */
- elseif (!imageResize($tmpName, _PS_UPLOAD_DIR_.$fileName))
+ else if (!imageResize($tmpName, _PS_UPLOAD_DIR_.$fileName))
$this->errors[] = Tools::displayError('An error occurred during the image upload.');
/* A smaller one */
- elseif (!imageResize($tmpName, _PS_UPLOAD_DIR_.$fileName.'_small', (int)(Configuration::get('PS_PRODUCT_PICTURE_WIDTH')), (int)(Configuration::get('PS_PRODUCT_PICTURE_HEIGHT'))))
+ else if (!imageResize($tmpName, _PS_UPLOAD_DIR_.$fileName.'_small', (int)(Configuration::get('PS_PRODUCT_PICTURE_WIDTH')), (int)(Configuration::get('PS_PRODUCT_PICTURE_HEIGHT'))))
$this->errors[] = Tools::displayError('An error occurred during the image upload.');
- elseif (!chmod(_PS_UPLOAD_DIR_.$fileName, 0777) OR !chmod(_PS_UPLOAD_DIR_.$fileName.'_small', 0777))
+ else if (!chmod(_PS_UPLOAD_DIR_.$fileName, 0777) || !chmod(_PS_UPLOAD_DIR_.$fileName.'_small', 0777))
$this->errors[] = Tools::displayError('An error occurred during the image upload.');
else
{
@@ -407,26 +543,26 @@ class ProductControllerCore extends FrontController
if (!$fieldIds = $this->product->getCustomizationFieldIds())
return false;
$authorizedTextFields = array();
- foreach ($fieldIds AS $fieldId)
+ foreach ($fieldIds as $fieldId)
if ($fieldId['type'] == Product::CUSTOMIZE_TEXTFIELD)
$authorizedTextFields[(int)($fieldId['id_customization_field'])] = 'textField'.(int)($fieldId['id_customization_field']);
$indexes = array_flip($authorizedTextFields);
- foreach ($_POST AS $fieldName => $value)
- if (in_array($fieldName, $authorizedTextFields) AND !empty($value))
+ foreach ($_POST as $fieldName => $value)
+ if (in_array($fieldName, $authorizedTextFields) && !empty($value))
{
if (!Validate::isMessage($value))
$this->errors[] = Tools::displayError('Invalid message');
else
$cart->addTextFieldToProduct($this->product->id, $indexes[$fieldName], Product::CUSTOMIZE_TEXTFIELD, $value);
}
- elseif (in_array($fieldName, $authorizedTextFields) AND empty($value))
+ else if (in_array($fieldName, $authorizedTextFields) && empty($value))
$cart->deleteCustomizationToProduct((int)($this->product->id), $indexes[$fieldName]);
}
public function formTargetFormat()
{
$customizationFormTarget = Tools::safeOutput(urldecode($_SERVER['REQUEST_URI']));
- foreach ($_GET AS $field => $value)
+ foreach ($_GET as $field => $value)
if (strncmp($field, 'group_', 6) == 0)
$customizationFormTarget = preg_replace('/&group_([[:digit:]]+)=([[:digit:]]+)/', '', $customizationFormTarget);
if (isset($_POST['quantityBackup']))
@@ -436,31 +572,31 @@ class ProductControllerCore extends FrontController
public function formatQuantityDiscounts($specificPrices, $price, $taxRate)
{
- foreach ($specificPrices AS $key => &$row)
+ foreach ($specificPrices as $key => &$row)
{
$row['quantity'] = &$row['from_quantity'];
if ($row['price'] != 0) // The price may be directly set
{
- $cur_price = (Product::$_taxCalculationMethod == PS_TAX_EXC ? $row['price'] : $row['price'] * (1 + $taxRate / 100));
+ $cur_price = (Product::$_taxCalculationMethod == PS_TAX_EXC ? $row['price'] : $row['price'] * (1 + $taxRate / 100));
- if ($row['reduction_type'] == 'amount')
- $cur_price = Product::$_taxCalculationMethod == PS_TAX_INC ? $cur_price - $row['reduction'] : $cur_price - ($row['reduction'] / (1 + $taxRate / 100));
- else
- $cur_price = $cur_price * ( 1 - ($row['reduction']));
+ if ($row['reduction_type'] == 'amount')
+ $cur_price = Product::$_taxCalculationMethod == PS_TAX_INC ? $cur_price - $row['reduction'] : $cur_price - ($row['reduction'] / (1 + $taxRate / 100));
+ else
+ $cur_price = $cur_price * ( 1 - ($row['reduction']));
- $row['real_value'] = $price - $cur_price;
+ $row['real_value'] = $price - $cur_price;
}
else
{
- if ($row['reduction_type'] == 'amount')
- {
- $reduction_amount = $row['reduction'];
- if (!$row['id_currency'])
- $reduction_amount = Tools::convertPrice($reduction_amount, $this->context->currency->id);
- $row['real_value'] = Product::$_taxCalculationMethod == PS_TAX_INC ? $row['reduction'] : $row['reduction'] / (1 + $taxRate / 100);
- }
- else
- $row['real_value'] = $row['reduction'] * 100;
+ if ($row['reduction_type'] == 'amount')
+ {
+ $reduction_amount = $row['reduction'];
+ if (!$row['id_currency'])
+ $reduction_amount = Tools::convertPrice($reduction_amount, $this->context->currency->id);
+ $row['real_value'] = Product::$_taxCalculationMethod == PS_TAX_INC ? $row['reduction'] : $row['reduction'] / (1 + $taxRate / 100);
+ }
+ else
+ $row['real_value'] = $row['reduction'] * 100;
}
$row['nextQuantity'] = (isset($specificPrices[$key + 1]) ? (int)($specificPrices[$key + 1]['from_quantity']) : -1);
}