diff --git a/classes/Cart.php b/classes/Cart.php index d55d19346..06204c41f 100644 --- a/classes/Cart.php +++ b/classes/Cart.php @@ -370,24 +370,24 @@ class CartCore extends ObjectModel // Build SELECT $sql->select('cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, cp.id_shop, pl.`name`, - pl.`description_short`, pl.`available_now`, pl.`available_later`, p.`id_product`, p.`id_category_default`, p.`id_supplier`, p.`id_manufacturer`') - ->select('p.`on_sale`, p.`ecotax`, p.`additional_shipping_cost`, p.`available_for_order`, p.`price`, p.`weight`, p.`width`, p.`height`, p.`depth`, p.`out_of_stock`') - ->select('p.`active`, p.`date_add`, p.`date_upd`, t.`id_tax`, tl.`name` AS tax, t.`rate`, stock.quantity, pl.`link_rewrite`, cl.`link_rewrite` AS category') - ->select('CONCAT(cp.`id_product`, cp.`id_product_attribute`) AS unique_id'); + pl.`description_short`, pl.`available_now`, pl.`available_later`, p.`id_product`, p.`id_category_default`, p.`id_supplier`, p.`id_manufacturer`, + p.`on_sale`, p.`ecotax`, p.`additional_shipping_cost`, p.`available_for_order`, p.`price`, p.`weight`, p.`width`, p.`height`, p.`depth`, p.`out_of_stock`, + p.`active`, p.`date_add`, p.`date_upd`, t.`id_tax`, tl.`name` AS tax, t.`rate`, stock.quantity, pl.`link_rewrite`, cl.`link_rewrite` AS category, + CONCAT(cp.`id_product`, cp.`id_product_attribute`) AS unique_id'); // Build FROM $sql->from('cart_product cp'); // Build JOIN - $sql->leftJoin('product p ON p.`id_product` = cp.`id_product`') - ->leftJoin('product_lang pl ON p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$this->id_lang.Context::getContext()->shop->sqlLang('pl')) - ->leftJoin('tax_rule tr ON p.`id_tax_rules_group` = tr.`id_tax_rules_group` + $sql->leftJoin('product p ON p.`id_product` = cp.`id_product`'); + $sql->leftJoin('product_lang pl ON p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$this->id_lang.Context::getContext()->shop->sqlLang('pl')); + $sql->leftJoin('tax_rule tr ON p.`id_tax_rules_group` = tr.`id_tax_rules_group` AND tr.`id_country` = '.(int)$id_country.' AND tr.`id_state` = 0 - AND tr.`zipcode_from` = 0') - ->leftJoin('tax t ON t.`id_tax` = tr.`id_tax`') - ->leftJoin('tax_lang tl ON t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$this->id_lang) - ->leftJoin('category_lang cl ON p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.(int)$this->id_lang.Context::getContext()->shop->sqlLang('cl')); + AND tr.`zipcode_from` = 0'); + $sql->leftJoin('tax t ON t.`id_tax` = tr.`id_tax`'); + $sql->leftJoin('tax_lang tl ON t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$this->id_lang); + $sql->leftJoin('category_lang cl ON p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.(int)$this->id_lang.Context::getContext()->shop->sqlLang('cl')); // @todo test if everything is ok, then refactorise call of this method Product::sqlStock('cp', 'cp', false, null, $sql); @@ -412,15 +412,15 @@ class CartCore extends ObjectModel if (Combination::isFeatureActive()) { - $sql->select('pa.`price` AS price_attribute, pa.`ecotax` AS ecotax_attr') - ->select('IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference') - ->select('IF (IFNULL(pa.`supplier_reference`, \'\') = \'\', p.`supplier_reference`, pa.`supplier_reference`) AS supplier_reference') - ->select('(p.`weight`+ pa.`weight`) weight_attribute') - ->select('IF (IFNULL(pa.`ean13`, \'\') = \'\', p.`ean13`, pa.`ean13`) AS ean13, IF (IFNULL(pa.`upc`, \'\') = \'\', p.`upc`, pa.`upc`) AS upc') - ->select('pai.`id_image` as pai_id_image, IFNULL(pa.`minimal_quantity`, p.`minimal_quantity`) as minimal_quantity, pa.`ecotax` AS ecotax_attr'); + $sql->select('pa.`price` AS price_attribute, pa.`ecotax` AS ecotax_attr, + IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference, + IF (IFNULL(pa.`supplier_reference`, \'\') = \'\', p.`supplier_reference`, pa.`supplier_reference`) AS supplier_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, IFNULL(pa.`minimal_quantity`, p.`minimal_quantity`) as minimal_quantity, pa.`ecotax` AS ecotax_attr'); - $sql->leftJoin('product_attribute pa ON pa.`id_product_attribute` = cp.`id_product_attribute`') - ->leftJoin('product_attribute_image pai ON pai.`id_product_attribute` = pa.`id_product_attribute`'); + $sql->leftJoin('product_attribute pa ON pa.`id_product_attribute` = cp.`id_product_attribute`'); + $sql->leftJoin('product_attribute_image pai ON pai.`id_product_attribute` = pa.`id_product_attribute`'); } else $sql->select('p.`reference` AS reference, p.`supplier_reference` AS supplier_reference, p.`ean13`, p.`upc` AS upc, p.`minimal_quantity` AS minimal_quantity'); diff --git a/classes/Product.php b/classes/Product.php index 87d8822f1..cc1933369 100644 --- a/classes/Product.php +++ b/classes/Product.php @@ -495,7 +495,7 @@ class ProductCore extends ObjectModel */ public static function cleanPositions($id_category) { - $return = true; + $return = true; $result = Db::getInstance()->ExecuteS(' SELECT `id_product` @@ -1395,43 +1395,39 @@ class ProductCore extends ObjectModel return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); } - $sql = array(); - $sql['select'] = ' - SELECT p.*, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, p.`ean13`, p.`upc`, - i.`id_image`, il.`legend`, t.`rate`, m.`name` AS manufacturer_name, DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new, - (p.`price` * ((100 + (t.`rate`))/100)) AS orderprice - '; - $sql['from'] = 'FROM `'._DB_PREFIX_.'product` p'; - $sql['join'] = $context->shop->sqlAsso('product', 'p').' - LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.$context->shop->sqlLang('pl').') - LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1) - LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.') - LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group` - AND tr.`id_country` = '.(int)$context->country->id.' - AND tr.`id_state` = 0) - LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`) - LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`) - '; - $sql['where'] = ' - WHERE p.`active` = 1 - AND DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 - AND p.`id_product` IN ( + $sql = new DbQuery(); + $sql->select('p.*, pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, p.`ean13`, p.`upc`, + i.`id_image`, il.`legend`, t.`rate`, m.`name` AS manufacturer_name, DATEDIFF(p.`date_add`, DATE_SUB(NOW(), + INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new, + (p.`price` * ((100 + (t.`rate`))/100)) AS orderprice'); + + $sql->from('product p'); + $sql->join($context->shop->sqlAsso('product', 'p')); + $sql->leftJoin('product_lang pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.$context->shop->sqlLang('pl').')'); + $sql->leftJoin('image i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)'); + $sql->leftJoin('image_lang il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')'); + $sql->leftJoin('tax_rule tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group` AND tr.`id_country` = '.(int)$context->country->id.' AND tr.`id_state` = 0)'); + $sql->leftJoin('tax t ON (t.`id_tax` = tr.`id_tax`)'); + $sql->leftJoin('manufacturer m ON (m.`id_manufacturer` = p.`id_manufacturer`)'); + + $sql->where('p.`active` = 1'); + $sql->where('DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0'); + $sql->where('p.`id_product` IN ( SELECT cp.`id_product` FROM `'._DB_PREFIX_.'category_group` cg LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_category` = cg.`id_category`) - WHERE cg.`id_group` '.$sqlGroups.' - ) - '; - $sql['orderby'] = 'ORDER BY '.(isset($orderByPrefix) ? pSQL($orderByPrefix).'.' : '').'`'.pSQL($orderBy).'` '.pSQL($orderWay); - $sql['limit'] = 'LIMIT '.(int)($pageNumber * $nbProducts).', '.(int)($nbProducts); + WHERE cg.`id_group` '.$sqlGroups.')'); + + $sql->orderBy((isset($orderByPrefix) ? pSQL($orderByPrefix).'.' : '').'`'.pSQL($orderBy).'` '.pSQL($orderWay)); + $sql->limit($nbProducts, $pageNumber * $nbProducts); if (Combination::isFeatureActive()) { - $sql['select'] .= ', pa.id_product_attribute'; - $sql['join'] .= 'LEFT OUTER JOIN `'._DB_PREFIX_.'product_attribute` pa ON (p.`id_product` = pa.`id_product` AND `default_on` = 1)'; + $sql->select('pa.id_product_attribute'); + $sql->leftOuterJoin('product_attribute pa ON (p.`id_product` = pa.`id_product` AND `default_on` = 1)'); } - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS(Tools::buildQuery($sql)); + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($sql); if ($orderBy == 'price') Tools::orderbyPrice($result, $orderWay); @@ -1817,23 +1813,23 @@ class ProductCore extends ObjectModel $cacheId2 = $id_product.'-'.$id_product_attribute; if (!isset(self::$_pricesLevel2[$cacheId2])) { - $sql = array(); - $sql['select'] = 'SELECT p.`price`, p.`ecotax`'; - $sql['from'] = 'FROM `'._DB_PREFIX_.'product` p'; - $sql['where'] = 'WHERE p.`id_product` = '.(int)($id_product); + $sql = new DbQuery(); + $sql->select('p.`price`, p.`ecotax`'); + $sql->from('product p'); + $sql->where('p.`id_product` = '.(int)$id_product); if (Combination::isFeatureActive()) { if ($id_product_attribute) { - $sql['select'] .= ', pa.`price` AS attribute_price'; - $sql['join'] = 'LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (pa.`id_product_attribute` = '.(int)($id_product_attribute).')'; + $sql->select('pa.`price` AS attribute_price'); + $sql->leftJoin('product_attribute pa ON (pa.`id_product_attribute` = '.(int)($id_product_attribute).')'); } else - $sql['select'] .= ', IFNULL((SELECT pa.price FROM `'._DB_PREFIX_.'product_attribute` pa WHERE id_product = '.(int)($id_product).' AND default_on = 1), 0) AS attribute_price'; + $sql->select('IFNULL((SELECT pa.price FROM `'._DB_PREFIX_.'product_attribute` pa WHERE id_product = '.(int)($id_product).' AND default_on = 1), 0) AS attribute_price'); } - self::$_pricesLevel2[$cacheId2] = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(Tools::buildQuery($sql)); + self::$_pricesLevel2[$cacheId2] = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql); } $result = self::$_pricesLevel2[$cacheId2]; @@ -2536,31 +2532,28 @@ class ProductCore extends ObjectModel if (!$context) $context = Context::getContext(); - $sql = array(); - $sql['select'] = 'SELECT p.`id_product`, pl.`name`, p.`active`, p.`reference`, m.`name` AS manufacturer_name, stock.`quantity`'; - $sql['from'] = 'FROM `'._DB_PREFIX_.'category_product` cp'; - $sql['join'] = ' - LEFT JOIN `'._DB_PREFIX_.'product` p ON p.`id_product` = cp.`id_product` - '.$context->shop->sqlAsso('product', 'p').' - LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.$context->shop->sqlLang('pl').') - LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer` - '; - $sql['where'] = ' - WHERE pl.`name` LIKE \'%'.pSQL($query).'%\' - OR p.`reference` LIKE \'%'.pSQL($query).'%\' - OR p.`supplier_reference` LIKE \'%'.pSQL($query).'%\''; - $sql['groupby'] = 'GROUP BY `id_product`'; - $sql['orderby'] = 'ORDER BY pl.`name` ASC'; + $sql = new DbQuery(); + $sql->select('p.`id_product`, pl.`name`, p.`active`, p.`reference`, m.`name` AS manufacturer_name, stock.`quantity`'); + $sql->from('category_product cp'); + $sql->leftJoin('product p ON p.`id_product` = cp.`id_product`'); + $sql->join($context->shop->sqlAsso('product', 'p')); + $sql->leftJoin('product_lang pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.$context->shop->sqlLang('pl').')'); + $sql->leftJoin('manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`'); + + $where = 'pl.`name` LIKE \'%'.pSQL($query).'%\' OR p.`reference` LIKE \'%'.pSQL($query).'%\' OR p.`supplier_reference` LIKE \'%'.pSQL($query).'%\''; + $sql->where(); + $sql->groupBy('`id_product`'); + $sql->orderBy('pl.`name` ASC'); if (Combination::isFeatureActive()) { - $sql['join'] .= ' - LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON pa.`id_product` = p.`id_product`'; - $sql['where'] .= 'OR pa.`reference` LIKE \'%'.pSQL($query).'%\''; + $sql->leftJoin('product_attribute pa ON pa.`id_product` = p.`id_product`'); + $where .= ' OR pa.`reference` LIKE \'%'.pSQL($query).'%\''; } - $sql['join'] .= Product::sqlStock('p', 'pa', false, $context->shop); + $sql->where($where); + Product::sqlStock('p', 'pa', false, $context->shop, $sql); - $result = Db::getInstance()->ExecuteS(Tools::buildQuery($sql)); + $result = Db::getInstance()->ExecuteS($sql); if (!$result) return false; diff --git a/classes/Tools.php b/classes/Tools.php index 20f1184f2..f5fd06537 100644 --- a/classes/Tools.php +++ b/classes/Tools.php @@ -2090,39 +2090,6 @@ FileETag INode MTime Size return (PHP_INT_MAX == '9223372036854775807'); } - /** - * @param array SQL query in array - * @return string SQL query - */ - public static function buildQuery(array $sql) - { - if (!isset($sql['select'])) - $sql['select'] = 'SELECT *'; - - $req = $sql['select']."\n"; - $req .= $sql['from']."\n"; - - if (isset($sql['join'])) - $req .= $sql['join']."\n"; - - if (isset($sql['where'])) - $req .= $sql['where']."\n"; - - if (isset($sql['groupby'])) - $req .= $sql['groupby']."\n"; - - if (isset($sql['having'])) - $req .= $sql['having']."\n"; - - if (isset($sql['orderby'])) - $req .= $sql['orderby']."\n"; - - if (isset($sql['limit'])) - $req .= $sql['limit']."\n"; - - return $req; - } - /** * Get max file upload size considering server settings and optional max value * diff --git a/classes/db/DbQuery.php b/classes/db/DbQuery.php index e65678137..bd2ed476c 100644 --- a/classes/db/DbQuery.php +++ b/classes/db/DbQuery.php @@ -105,6 +105,26 @@ class DbQueryCore return $this->join('INNER JOIN '._DB_PREFIX_.$join); } + /** + * Add LEFT OUTER JOIN clause + * + * @param string $join Table followed by ON claused + */ + public function leftOuterJoin($join) + { + return $this->join('LEFT OUTER JOIN '._DB_PREFIX_.$join); + } + + /** + * Add NATURAL JOIN clause + * + * @param string $join + */ + public function naturalJoin($join) + { + return $this->join('NATURAL JOIN '._DB_PREFIX_.$join); + } + /** * Add a restriction in WHERE clause (each restriction will be separated by AND statement) * diff --git a/classes/tax/Tax.php b/classes/tax/Tax.php index 483f46443..e2e40b1ff 100644 --- a/classes/tax/Tax.php +++ b/classes/tax/Tax.php @@ -150,22 +150,22 @@ class TaxCore extends ObjectModel */ public static function getTaxes($id_lang = false, $active_only = true) { - $query = array(); - $query['select'] = 'SELECT t.id_tax, t.rate'; - $query['from'] = 'FROM `'._DB_PREFIX_.'tax` t'; - $query['where'] = 'WHERE t.`deleted` != 1'; + $sql = new DbQuery(); + $sql->select('t.id_tax, t.rate'); + $sql->from('tax t'); + $sql->where('t.`deleted` != 1'); if ($id_lang) { - $query['select'] .= ', tl.name, tl.id_lang '; - $query['join'] = 'LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)($id_lang).')'; - $query['order'] = 'ORDER BY `name` ASC'; + $sql->select('tl.name, tl.id_lang'); + $sql->leftJoin('tax_lang tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$id_lang.')'); + $sql->orderBy('`name` ASC'); } if ($active_only) - $query['where'] .= ' AND t.`active` = 1'; + $sql->where('t.`active` = 1'); - return Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS(Tools::buildQuery($query)); + return Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($sql); } public static function excludeTaxeOption()