380 lines
17 KiB
PHP
380 lines
17 KiB
PHP
<?php
|
|
|
|
class Product extends ProductCore
|
|
{
|
|
public $home_edito;
|
|
public $failling_price;
|
|
public static $products_flashsale;
|
|
|
|
public static $definition = array(
|
|
'table' => 'product',
|
|
'primary' => 'id_product',
|
|
'multilang' => true,
|
|
'multilang_shop' => true,
|
|
'fields' => array(
|
|
/* Classic fields */
|
|
'id_shop_default' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
|
'id_manufacturer' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
|
'id_supplier' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
|
'reference' => array('type' => self::TYPE_STRING, 'validate' => 'isReference', 'size' => 32),
|
|
'supplier_reference' => array('type' => self::TYPE_STRING, 'validate' => 'isReference', 'size' => 32),
|
|
'location' => array('type' => self::TYPE_STRING, 'validate' => 'isReference', 'size' => 64),
|
|
'width' => array('type' => self::TYPE_FLOAT, 'validate' => 'isUnsignedFloat'),
|
|
'height' => array('type' => self::TYPE_FLOAT, 'validate' => 'isUnsignedFloat'),
|
|
'depth' => array('type' => self::TYPE_FLOAT, 'validate' => 'isUnsignedFloat'),
|
|
'weight' => array('type' => self::TYPE_FLOAT, 'validate' => 'isUnsignedFloat'),
|
|
'quantity_discount' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
|
|
'ean13' => array('type' => self::TYPE_STRING, 'validate' => 'isEan13', 'size' => 13),
|
|
'upc' => array('type' => self::TYPE_STRING, 'validate' => 'isUpc', 'size' => 12),
|
|
'cache_is_pack' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
|
|
'cache_has_attachments' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
|
|
'is_virtual' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
|
|
|
|
/* Shop fields */
|
|
'id_category_default' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedId'),
|
|
'id_tax_rules_group' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedId'),
|
|
'on_sale' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
|
|
'online_only' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
|
|
'home_edito' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
|
|
'failling_price' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
|
|
'ecotax' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isPrice'),
|
|
'minimal_quantity' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'),
|
|
'price' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isPrice', 'required' => true),
|
|
'wholesale_price' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isPrice'),
|
|
'unity' => array('type' => self::TYPE_STRING, 'shop' => true, 'validate' => 'isString'),
|
|
'unit_price_ratio' => array('type' => self::TYPE_FLOAT, 'shop' => true),
|
|
'additional_shipping_cost' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isPrice'),
|
|
'customizable' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'),
|
|
'text_fields' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'),
|
|
'uploadable_files' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'),
|
|
'active' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
|
|
'redirect_type' => array('type' => self::TYPE_STRING, 'shop' => true, 'validate' => 'isString'),
|
|
'id_product_redirected' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedId'),
|
|
'available_for_order' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
|
|
'available_date' => array('type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDateFormat'),
|
|
'condition' => array('type' => self::TYPE_STRING, 'shop' => true, 'validate' => 'isGenericName', 'values' => array('new', 'used', 'refurbished'), 'default' => 'new'),
|
|
'show_price' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
|
|
'indexed' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
|
|
'visibility' => array('type' => self::TYPE_STRING, 'shop' => true, 'validate' => 'isProductVisibility', 'values' => array('both', 'catalog', 'search', 'none'), 'default' => 'both'),
|
|
'cache_default_attribute' => array('type' => self::TYPE_INT, 'shop' => true),
|
|
'advanced_stock_management' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
|
|
'date_add' => array('type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDate'),
|
|
'date_upd' => array('type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDate'),
|
|
'pack_stock_type' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'),
|
|
|
|
/* Lang fields */
|
|
'meta_description' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
|
|
'meta_keywords' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
|
|
'meta_title' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 128),
|
|
'link_rewrite' => array(
|
|
'type' => self::TYPE_STRING,
|
|
'lang' => true,
|
|
'validate' => 'isLinkRewrite',
|
|
'required' => true,
|
|
'size' => 128,
|
|
'ws_modifier' => array(
|
|
'http_method' => WebserviceRequest::HTTP_POST,
|
|
'modifier' => 'modifierWsLinkRewrite'
|
|
)
|
|
),
|
|
'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCatalogName', 'required' => true, 'size' => 128),
|
|
'description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
|
|
'description_short' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
|
|
'available_now' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
|
|
'available_later' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'IsGenericName', 'size' => 255),
|
|
),
|
|
'associations' => array(
|
|
'manufacturer' => array('type' => self::HAS_ONE),
|
|
'supplier' => array('type' => self::HAS_ONE),
|
|
'default_category' => array('type' => self::HAS_ONE, 'field' => 'id_category_default', 'object' => 'Category'),
|
|
'tax_rules_group' => array('type' => self::HAS_ONE),
|
|
'categories' => array('type' => self::HAS_MANY, 'field' => 'id_category', 'object' => 'Category', 'association' => 'category_product'),
|
|
'stock_availables' => array('type' => self::HAS_MANY, 'field' => 'id_stock_available', 'object' => 'StockAvailable', 'association' => 'stock_availables'),
|
|
),
|
|
);
|
|
|
|
public function loadReductionInfo(Context $context = null) {
|
|
|
|
if(empty(self::$products_flashsale)) {
|
|
self::$products_flashsale = self::getProductsInFlashsales();
|
|
}
|
|
$this->isflash = in_array($this->id, self::$products_flashsale);
|
|
|
|
if ($context == null)
|
|
$context = Context::getContext();
|
|
|
|
$id_lang = $context->language->id;
|
|
|
|
// Tax
|
|
$usetax = Tax::excludeTaxeOption();
|
|
|
|
if (isset($this->id_product_attribute)) {
|
|
$id_product_attribute = $this->id_product_attribute;
|
|
} else {
|
|
$id_product_attribute = null;
|
|
}
|
|
|
|
$this->category = Category::getLinkRewrite((int)$this->id_category_default, (int)$id_lang);
|
|
$this->link = Context::getContext()->link->getProductLink($this);
|
|
$this->id_product = $this->id;
|
|
|
|
$id_image = Product::getCover($this->id);
|
|
$this->id_image = $id_image['id_image'];
|
|
|
|
if (self::$_taxCalculationMethod == PS_TAX_EXC)
|
|
{
|
|
$this->price_tax_exc = Tools::ps_round($this->price_tax_exc, 2);
|
|
$this->price = Product::getPriceStatic(
|
|
(int)$this->id,
|
|
true,
|
|
$id_product_attribute,
|
|
6
|
|
);
|
|
$this->price_without_reduction = Product::getPriceStatic(
|
|
(int)$this->id,
|
|
false,
|
|
$id_product_attribute,
|
|
2,
|
|
null,
|
|
false,
|
|
false
|
|
);
|
|
}
|
|
else
|
|
{
|
|
$this->price = Tools::ps_round(
|
|
Product::getPriceStatic(
|
|
(int)$this->id,
|
|
true,
|
|
$id_product_attribute,
|
|
6
|
|
),
|
|
(int)Configuration::get('PS_PRICE_DISPLAY_PRECISION')
|
|
);
|
|
$this->price_without_reduction = Product::getPriceStatic(
|
|
(int)$this->id,
|
|
true,
|
|
$id_product_attribute,
|
|
6,
|
|
null,
|
|
false,
|
|
false
|
|
);
|
|
}
|
|
|
|
$this->reduction = Product::getPriceStatic(
|
|
(int)$this->id,
|
|
(bool)$usetax,
|
|
$id_product_attribute,
|
|
6,
|
|
null,
|
|
true,
|
|
true,
|
|
1,
|
|
true,
|
|
null,
|
|
null,
|
|
null,
|
|
$specific_prices
|
|
);
|
|
$this->specific_prices = $specific_prices;
|
|
$this->quantity = Product::getQuantity(
|
|
(int)$this->id,
|
|
0,
|
|
isset($this->cache_is_pack) ? $this->cache_is_pack : null
|
|
);
|
|
|
|
$this->quantity_all_versions = $this->quantity;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public static function getProductsInFlashsales()
|
|
{
|
|
$products = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
|
|
SELECT fsp.`id_product`
|
|
FROM '._DB_PREFIX_.'flash_sale_products fsp
|
|
INNER JOIN '._DB_PREFIX_.'flash_sale fs ON (fs.id_flash_sale = fsp.id_flash_sale AND fs.active = 1)'
|
|
);
|
|
|
|
if (!empty($products)) {
|
|
$products = array_map(function($row) { return $row['id_product']; }, $products);
|
|
}
|
|
|
|
return $products;
|
|
}
|
|
|
|
public static function getProductsProperties($id_lang, $query_result)
|
|
{
|
|
self::$products_flashsale = self::getProductsInFlashsales();
|
|
|
|
$results_array = array();
|
|
|
|
if (is_array($query_result)) {
|
|
foreach ($query_result as $row) {
|
|
if ($row2 = Product::getProductProperties($id_lang, $row)) {
|
|
$results_array[] = $row2;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $results_array;
|
|
}
|
|
|
|
public static function getProductProperties($id_lang, $row, Context $context = null)
|
|
{
|
|
if (!$row['id_product']) {
|
|
return false;
|
|
}
|
|
|
|
$row['isflash'] = in_array($row['id_product'], self::$products_flashsale);
|
|
|
|
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['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'] = (float)Product::getProductAttributePrice($id_product_attribute);
|
|
}
|
|
|
|
$row['price_tax_exc'] = Product::getPriceStatic(
|
|
(int)$row['id_product'],
|
|
false,
|
|
$id_product_attribute,
|
|
(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,
|
|
$id_product_attribute,
|
|
6
|
|
);
|
|
$row['price_without_reduction'] = Product::getPriceStatic(
|
|
(int)$row['id_product'],
|
|
false,
|
|
$id_product_attribute,
|
|
2,
|
|
null,
|
|
false,
|
|
false
|
|
);
|
|
} else {
|
|
$row['price'] = Tools::ps_round(
|
|
Product::getPriceStatic(
|
|
(int)$row['id_product'],
|
|
true,
|
|
$id_product_attribute,
|
|
6
|
|
),
|
|
(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
|
|
);
|
|
}
|
|
|
|
$row['reduction'] = Product::getPriceStatic(
|
|
(int)$row['id_product'],
|
|
(bool)$usetax,
|
|
$id_product_attribute,
|
|
6,
|
|
null,
|
|
true,
|
|
true,
|
|
1,
|
|
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['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;
|
|
}
|
|
}
|
|
|
|
$row = Product::getTaxesInformations($row, $context);
|
|
self::$producPropertiesCache[$cache_key] = $row;
|
|
return self::$producPropertiesCache[$cache_key];
|
|
}
|
|
}
|