// Stock Available : Improve BackOffice interface + Update all SQL requests relative to StockAvailable + code refactoring on Product Class
git-svn-id: http://dev.prestashop.com/svn/v1/branches/1.5.x@10843 b9a71923-0436-4b27-9f14-aed3839534dd
This commit is contained in:
+81
-38
@@ -123,7 +123,7 @@ class SearchCore
|
||||
|
||||
if (!$indexation)
|
||||
{
|
||||
$alias = new Alias(NULL, $string);
|
||||
$alias = new Alias(null, $string);
|
||||
if (Validate::isLoadedObject($alias))
|
||||
$string = $alias->search;
|
||||
}
|
||||
@@ -145,7 +145,8 @@ class SearchCore
|
||||
return $string;
|
||||
}
|
||||
|
||||
public static function find($id_lang, $expr, $pageNumber = 1, $pageSize = 1, $orderBy = 'position', $orderWay = 'desc', $ajax = false, $useCookie = true, Context $context = null)
|
||||
public static function find($id_lang, $expr, $pageNumber = 1, $pageSize = 1, $orderBy = 'position',
|
||||
$orderWay = 'desc', $ajax = false, $useCookie = true, Context $context = null)
|
||||
{
|
||||
if (!$context)
|
||||
$context = Context::getContext();
|
||||
@@ -161,15 +162,15 @@ class SearchCore
|
||||
if ($pageNumber < 1) $pageNumber = 1;
|
||||
if ($pageSize < 1) $pageSize = 1;
|
||||
|
||||
if (!Validate::isOrderBy($orderBy) OR !Validate::isOrderWay($orderWay))
|
||||
if (!Validate::isOrderBy($orderBy) || !Validate::isOrderWay($orderWay))
|
||||
return false;
|
||||
|
||||
$intersectArray = array();
|
||||
$scoreArray = array();
|
||||
$words = explode(' ', Search::sanitize($expr, $id_lang));
|
||||
|
||||
foreach ($words AS $key => $word)
|
||||
if (!empty($word) AND strlen($word) >= (int)Configuration::get('PS_SEARCH_MINWORDLEN'))
|
||||
foreach ($words as $key => $word)
|
||||
if (!empty($word) && strlen($word) >= (int)Configuration::get('PS_SEARCH_MINWORDLEN'))
|
||||
{
|
||||
$word = str_replace('%', '\\%', $word);
|
||||
$word = str_replace('_', '\\_', $word);
|
||||
@@ -190,11 +191,11 @@ class SearchCore
|
||||
else
|
||||
unset($words[$key]);
|
||||
|
||||
if (!sizeof($words))
|
||||
if (!count($words))
|
||||
return ($ajax ? array() : array('total' => 0, 'result' => array()));
|
||||
|
||||
$score = '';
|
||||
if (sizeof($scoreArray))
|
||||
if (count($scoreArray))
|
||||
$score = ',(
|
||||
SELECT SUM(weight)
|
||||
FROM '._DB_PREFIX_.'search_word sw
|
||||
@@ -237,7 +238,7 @@ class SearchCore
|
||||
array_unique($eligibleProducts);
|
||||
|
||||
$productPool = '';
|
||||
foreach ($eligibleProducts AS $id_product)
|
||||
foreach ($eligibleProducts as $id_product)
|
||||
if ($id_product)
|
||||
$productPool .= (int)$id_product.',';
|
||||
if (empty($productPool))
|
||||
@@ -249,17 +250,34 @@ class SearchCore
|
||||
$sql = 'SELECT DISTINCT p.id_product, pl.name pname, cl.name cname,
|
||||
cl.link_rewrite crewrite, pl.link_rewrite prewrite '.$score.'
|
||||
FROM '._DB_PREFIX_.'product p
|
||||
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('pl').')
|
||||
INNER JOIN `'._DB_PREFIX_.'category_lang` cl ON (p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('cl').')
|
||||
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
|
||||
p.`id_product` = pl.`id_product`
|
||||
AND pl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('pl').'
|
||||
)
|
||||
INNER JOIN `'._DB_PREFIX_.'category_lang` cl ON (
|
||||
p.`id_category_default` = cl.`id_category`
|
||||
AND cl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('cl').'
|
||||
)
|
||||
WHERE p.`id_product` '.$productPool.'
|
||||
ORDER BY position DESC LIMIT 10';
|
||||
return $db->executeS($sql);
|
||||
}
|
||||
|
||||
$sql = 'SELECT p.*, stock.out_of_stock, pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`name`,
|
||||
tax.`rate`, i.`id_image`, il.`legend`, m.`name` manufacturer_name '.$score.', 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 new
|
||||
$sql = 'SELECT p.*, stock.out_of_stock, stock.quantity as quantity,
|
||||
pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`name`,
|
||||
tax.`rate`, i.`id_image`, il.`legend`, m.`name` manufacturer_name '.$score.',
|
||||
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 new
|
||||
FROM '._DB_PREFIX_.'product p
|
||||
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('pl').')
|
||||
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
|
||||
p.`id_product` = pl.`id_product`
|
||||
AND pl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('pl').'
|
||||
)
|
||||
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)
|
||||
@@ -275,7 +293,10 @@ class SearchCore
|
||||
|
||||
$sql = 'SELECT COUNT(*)
|
||||
FROM '._DB_PREFIX_.'product p
|
||||
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('pl').')
|
||||
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
|
||||
p.`id_product` = pl.`id_product`
|
||||
AND pl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('pl').'
|
||||
)
|
||||
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
|
||||
AND tr.`id_country` = '.(int)Context::getContext()->country->id.'
|
||||
AND tr.`id_state` = 0)
|
||||
@@ -301,7 +322,7 @@ class SearchCore
|
||||
SELECT t.name FROM '._DB_PREFIX_.'product_tag pt
|
||||
LEFT JOIN '._DB_PREFIX_.'tag t ON (pt.id_tag = t.id_tag AND t.id_lang = '.(int)$id_lang.')
|
||||
WHERE pt.id_product = '.(int)$id_product);
|
||||
foreach ($tagsArray AS $tag)
|
||||
foreach ($tagsArray as $tag)
|
||||
$tags .= $tag['name'].' ';
|
||||
return $tags;
|
||||
}
|
||||
@@ -317,7 +338,7 @@ class SearchCore
|
||||
INNER JOIN '._DB_PREFIX_.'product_attribute_combination pac ON pa.id_product_attribute = pac.id_product_attribute
|
||||
INNER JOIN '._DB_PREFIX_.'attribute_lang al ON (pac.id_attribute = al.id_attribute AND al.id_lang = '.(int)$id_lang.')
|
||||
WHERE pa.id_product = '.(int)$id_product);
|
||||
foreach ($attributesArray AS $attribute)
|
||||
foreach ($attributesArray as $attribute)
|
||||
$attributes .= $attribute['name'].' ';
|
||||
return $attributes;
|
||||
}
|
||||
@@ -332,7 +353,7 @@ class SearchCore
|
||||
SELECT fvl.value FROM '._DB_PREFIX_.'feature_product fp
|
||||
LEFT JOIN '._DB_PREFIX_.'feature_value_lang fvl ON (fp.id_feature_value = fvl.id_feature_value AND fvl.id_lang = '.(int)$id_lang.')
|
||||
WHERE fp.id_product = '.(int)$id_product);
|
||||
foreach ($featuresArray AS $feature)
|
||||
foreach ($featuresArray as $feature)
|
||||
$features .= $feature['value'].' ';
|
||||
return $features;
|
||||
}
|
||||
@@ -342,7 +363,8 @@ class SearchCore
|
||||
// Adjust the limit to get only "whole" products, in every languages (and at least one)
|
||||
$limit = max(1, round($limit / $total_languages) * $total_languages);
|
||||
return Db::getInstance()->executeS('
|
||||
SELECT p.id_product, pl.id_lang, pl.id_shop, pl.name pname, p.reference, p.ean13, p.upc, pl.description_short, pl.description, cl.name cname, m.name mname
|
||||
SELECT p.id_product, pl.id_lang, pl.id_shop, pl.name pname, p.reference, p.ean13, p.upc,
|
||||
pl.description_short, pl.description, cl.name cname, m.name mname
|
||||
FROM '._DB_PREFIX_.'product p
|
||||
LEFT JOIN '._DB_PREFIX_.'product_lang pl ON p.id_product = pl.id_product
|
||||
LEFT JOIN '._DB_PREFIX_.'category_lang cl ON (cl.id_category = p.id_category_default AND pl.id_lang = cl.id_lang)
|
||||
@@ -375,7 +397,7 @@ class SearchCore
|
||||
|
||||
$ids = array();
|
||||
if ($products)
|
||||
foreach($products AS $product)
|
||||
foreach ($products as $product)
|
||||
$ids[] = (int)$product['id_product'];
|
||||
if (count($ids))
|
||||
$db->Execute('DELETE FROM '._DB_PREFIX_.'search_index WHERE id_product IN ('.implode(',', $ids).')');
|
||||
@@ -419,7 +441,8 @@ class SearchCore
|
||||
$total_languages = count(Language::getLanguages(false));
|
||||
|
||||
// Products are processed 50 by 50 in order to avoid overloading MySQL
|
||||
while ($products = Search::getProductsToIndex($total_languages, $id_product, 50) && count($products) > 0)
|
||||
$count = count($products);
|
||||
while ($products = Search::getProductsToIndex($total_languages, $id_product, 50) && $count > 0)
|
||||
{
|
||||
// Now each non-indexed product is processed one by one, langage by langage
|
||||
foreach ($products as $product)
|
||||
@@ -430,11 +453,11 @@ class SearchCore
|
||||
|
||||
// Data must be cleaned of html, bad characters, spaces and anything, then if the resulting words are long enough, they're added to the array
|
||||
$pArray = array();
|
||||
foreach ($product AS $key => $value)
|
||||
foreach ($product as $key => $value)
|
||||
if (strncmp($key, 'id_', 3))
|
||||
{
|
||||
$words = explode(' ', Search::sanitize($value, (int)$product['id_lang'], true));
|
||||
foreach ($words AS $word)
|
||||
foreach ($words as $word)
|
||||
if (!empty($word))
|
||||
{
|
||||
$word = Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH);
|
||||
@@ -452,8 +475,8 @@ class SearchCore
|
||||
{
|
||||
$queryArray = array();
|
||||
$queryArray2 = array();
|
||||
foreach ($pArray AS $word => $weight)
|
||||
if ($weight AND !isset($wordIdsByWord['_'.$word]))
|
||||
foreach ($pArray as $word => $weight)
|
||||
if ($weight && !isset($wordIdsByWord['_'.$word]))
|
||||
{
|
||||
$queryArray[$word] = '('.(int)$product['id_lang'].', '.(int)$product['id_shop'].', \''.pSQL($word).'\')';
|
||||
$queryArray2[] = '\''.pSQL($word).'\'';
|
||||
@@ -466,7 +489,7 @@ class SearchCore
|
||||
AND id_lang = '.(int)$product['id_lang'].'
|
||||
AND id_shop = '.(int)$product['id_shop']);
|
||||
|
||||
foreach($existingWords as $data)
|
||||
foreach ($existingWords as $data)
|
||||
unset($queryArray[Tools::replaceAccentedChars($data['word'])]);
|
||||
|
||||
if (count($queryArray))
|
||||
@@ -474,7 +497,7 @@ class SearchCore
|
||||
// The words are inserted...
|
||||
$db->Execute('
|
||||
INSERT IGNORE INTO '._DB_PREFIX_.'search_word (id_lang, id_shop, word)
|
||||
VALUES '.implode(',',$queryArray));
|
||||
VALUES '.implode(',', $queryArray));
|
||||
}
|
||||
if (count($queryArray2))
|
||||
{
|
||||
@@ -487,12 +510,12 @@ class SearchCore
|
||||
AND sw.id_shop = '.(int)$product['id_shop'].'
|
||||
LIMIT '.count($queryArray2));
|
||||
// replace accents from the retrieved words so that words without accents or with differents accents can still be linked
|
||||
foreach ($addedWords AS $wordId)
|
||||
foreach ($addedWords as $wordId)
|
||||
$wordIdsByWord[$product['id_shop']][$product['id_lang']]['_'.Tools::replaceAccentedChars($wordId['word'])] = (int)$wordId['id_word'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($pArray AS $word => $weight)
|
||||
foreach ($pArray as $word => $weight)
|
||||
{
|
||||
if (!$weight)
|
||||
continue;
|
||||
@@ -500,7 +523,8 @@ class SearchCore
|
||||
continue;
|
||||
if (!$wordIdsByWord[$product['id_shop']][$product['id_lang']]['_'.$word])
|
||||
continue;
|
||||
$queryArray3[] = '('.(int)$product['id_product'].','.(int)$wordIdsByWord[$product['id_shop']][$product['id_lang']]['_'.$word].','.(int)$weight.')';
|
||||
$queryArray3[] = '('.(int)$product['id_product'].','.
|
||||
(int)$wordIdsByWord[$product['id_shop']][$product['id_lang']]['_'.$word].','.(int)$weight.')';
|
||||
// Force save every 200 words in order to avoid overloading MySQL
|
||||
if (++$countWords % 200 == 0)
|
||||
Search::saveIndex($queryArray3);
|
||||
@@ -520,19 +544,28 @@ class SearchCore
|
||||
protected static function setProductsAsIndexed(&$products)
|
||||
{
|
||||
if (count($products))
|
||||
Db::getInstance()->execute('UPDATE '._DB_PREFIX_.'product SET indexed = 1 WHERE id_product IN ('.implode(',', $products).') LIMIT '.(int)count($products));
|
||||
Db::getInstance()->execute(
|
||||
'UPDATE '._DB_PREFIX_.'product SET indexed = 1
|
||||
WHERE id_product IN ('.implode(',', $products).')
|
||||
LIMIT '.(int)count($products)
|
||||
);
|
||||
$productsArray = array();
|
||||
}
|
||||
|
||||
// $queryArray3 is automatically emptied in order to be reused immediatly
|
||||
/** $queryArray3 is automatically emptied in order to be reused immediatly */
|
||||
protected static function saveIndex(&$queryArray3)
|
||||
{
|
||||
if (count($queryArray3))
|
||||
Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'search_index (id_product, id_word, weight) VALUES '.implode(',', $queryArray3).' ON DUPLICATE KEY UPDATE weight = weight + VALUES(weight)');
|
||||
Db::getInstance()->execute(
|
||||
'INSERT INTO '._DB_PREFIX_.'search_index (id_product, id_word, weight)
|
||||
VALUES '.implode(',', $queryArray3).'
|
||||
ON DUPLICATE KEY UPDATE weight = weight + VALUES(weight)'
|
||||
);
|
||||
$queryArray3 = array();
|
||||
}
|
||||
|
||||
public static function searchTag($id_lang, $tag, $count = false, $pageNumber = 0, $pageSize = 10, $orderBy = false, $orderWay = false, $useCookie = true, Context $context = null)
|
||||
public static function searchTag($id_lang, $tag, $count = false, $pageNumber = 0, $pageSize = 10, $orderBy = false, $orderWay = false,
|
||||
$useCookie = true, Context $context = null)
|
||||
{
|
||||
if (!$context)
|
||||
$context = Context::getContext();
|
||||
@@ -543,8 +576,8 @@ class SearchCore
|
||||
else
|
||||
$id_customer = 0;
|
||||
|
||||
if (!is_numeric($pageNumber) OR !is_numeric($pageSize) OR !Validate::isBool($count) OR !Validate::isValidSearch($tag)
|
||||
OR $orderBy AND !$orderWay OR ($orderBy AND !Validate::isOrderBy($orderBy)) OR ($orderWay AND !Validate::isOrderBy($orderWay)))
|
||||
if (!is_numeric($pageNumber) || !is_numeric($pageSize) || !Validate::isBool($count) || !Validate::isValidSearch($tag)
|
||||
|| $orderBy && !$orderWay || ($orderBy && !Validate::isOrderBy($orderBy)) || ($orderWay && !Validate::isOrderBy($orderWay)))
|
||||
return false;
|
||||
|
||||
if ($pageNumber < 1) $pageNumber = 1;
|
||||
@@ -567,10 +600,20 @@ class SearchCore
|
||||
return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
|
||||
}
|
||||
|
||||
$sql = 'SELECT DISTINCT p.*, stock.out_of_stock, pl.`description_short`, pl.`link_rewrite`, pl.`name`, tax.`rate`, i.`id_image`, il.`legend`, m.`name` manufacturer_name, 1 position,
|
||||
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 new
|
||||
$sql = 'SELECT DISTINCT p.*, stock.out_of_stock, stock.quantity as quantity, pl.`description_short`, pl.`link_rewrite`, pl.`name`,
|
||||
tax.`rate`, i.`id_image`, il.`legend`, m.`name` manufacturer_name, 1 position,
|
||||
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 new
|
||||
FROM `'._DB_PREFIX_.'product` p
|
||||
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('pl').')
|
||||
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
|
||||
p.`id_product` = pl.`id_product`
|
||||
AND pl.`id_lang` = '.(int)$id_lang.$context->shop->addSqlRestrictionOnLang('pl').'
|
||||
)
|
||||
'.$context->shop->addSqlAssociation('product', 'p', false).'
|
||||
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.')
|
||||
|
||||
Reference in New Issue
Block a user