Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Search extends SearchCore{
- protected static function getProductsToIndex($total_languages, $id_product = false, $limit = 50)
- {
- // parent::getProductsToIndex($total_languages, $id_product, $limit);
- // 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.name pname, p.reference, p.ean13, p.upc, pl.description_short, pl.description, cl.name cname, m.name mname, pa.reference as reference_declinaison
- FROM '._DB_PREFIX_.'product p
- LEFT JOIN '._DB_PREFIX_.'product_lang pl ON p.id_product = pl.id_product
- LEFT JOIN '._DB_PREFIX_.'product_attribute pa ON p.id_product = pa.id_product
- LEFT JOIN '._DB_PREFIX_.'category_lang cl ON (cl.id_category = p.id_category_default AND pl.id_lang = cl.id_lang)
- LEFT JOIN '._DB_PREFIX_.'manufacturer m ON m.id_manufacturer = p.id_manufacturer
- WHERE p.indexed = 0
- '.($id_product ? 'AND p.id_product = '.(int)$id_product : '').'
- LIMIT '.(int)$limit);
- }
- public static function indexation($full = false, $id_product = false)
- {
- //parent::indexation($full,$id_product);
- $db = Db::getInstance();
- if ($id_product)
- $full = false;
- if ($full)
- {
- $db->Execute('TRUNCATE '._DB_PREFIX_.'search_index');
- $db->Execute('TRUNCATE '._DB_PREFIX_.'search_word');
- $db->Execute('UPDATE '._DB_PREFIX_.'product SET indexed = 0');
- }
- else
- {
- // Do it even if you already know the product id in order to be sure that it exists
- $products = $db->ExecuteS('
- SELECT id_product
- FROM '._DB_PREFIX_.'product
- WHERE '.($id_product ? 'id_product = '.(int)$id_product : 'indexed = 0'));
- $ids = array();
- if ($products)
- foreach($products AS $product)
- $ids[] = (int)$product['id_product'];
- if (sizeof($ids))
- $db->Execute('DELETE FROM '._DB_PREFIX_.'search_index WHERE id_product IN ('.implode(',', $ids).')');
- }
- // Every fields are weighted according to the configuration in the backend
- $weightArray = array(
- 'pname' => Configuration::get('PS_SEARCH_WEIGHT_PNAME'),
- 'reference' => Configuration::get('PS_SEARCH_WEIGHT_REF'),
- 'ean13' => Configuration::get('PS_SEARCH_WEIGHT_REF'),
- 'upc' => Configuration::get('PS_SEARCH_WEIGHT_REF'),
- 'description_short' => Configuration::get('PS_SEARCH_WEIGHT_SHORTDESC'),
- 'description' => Configuration::get('PS_SEARCH_WEIGHT_DESC'),
- 'cname' => Configuration::get('PS_SEARCH_WEIGHT_CNAME'),
- 'mname' => Configuration::get('PS_SEARCH_WEIGHT_MNAME'),
- 'tags' => Configuration::get('PS_SEARCH_WEIGHT_TAG'),
- 'attributes' => Configuration::get('PS_SEARCH_WEIGHT_ATTRIBUTE'),
- 'features' => Configuration::get('PS_SEARCH_WEIGHT_FEATURE'),
- 'reference_declinaison' => Configuration::get('PS_SEARCH_WEIGHT_REF')
- );
- // Those are kind of global variables required to save the processed data in the database every X occurences, in order to avoid overloading MySQL
- $countWords = 0;
- $countProducts = 0;
- $queryArray3 = array();
- $productsArray = array();
- // Every indexed words are cached into a PHP array
- $wordIdsByWord = array();
- $wordIds = Db::getInstance()->ExecuteS('
- SELECT sw.id_word, sw.word, id_lang
- FROM '._DB_PREFIX_.'search_word sw', false);
- $wordIdsByWord = array();
- while ($wordId = $db->nextRow($wordIds))
- {
- if (!isset($wordIdsByWord[$wordId['id_lang']]))
- $wordIdsByWord[$wordId['id_lang']] = array();
- $wordIdsByWord[$wordId['id_lang']]['_'.$wordId['word']] = (int)$wordId['id_word'];
- }
- // Retrieve the number of languages
- $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)) && is_array($products) && (count($products) > 0))
- {
- // Now each non-indexed product is processed one by one, langage by langage
- foreach ($products as $product)
- {
- $product['tags'] = Search::getTags($db, (int)$product['id_product'], (int)$product['id_lang']);
- $product['attributes'] = Search::getAttributes($db, (int)$product['id_product'], (int)$product['id_lang']);
- $product['features'] = Search::getFeatures($db, (int)$product['id_product'], (int)$product['id_lang']);
- // 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)
- if (strncmp($key, 'id_', 3))
- {
- $words = explode(' ', Search::sanitize($value, (int)$product['id_lang'], true));
- foreach ($words AS $word)
- if (!empty($word))
- {
- $word = Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH);
- // Remove accents
- $word = Tools::replaceAccentedChars($word);
- if (!isset($pArray[$word]))
- $pArray[$word] = 0;
- $pArray[$word] += $weightArray[$key];
- }
- }
- // If we find words that need to be indexed, they're added to the word table in the database
- if (sizeof($pArray))
- {
- $queryArray = array();
- $queryArray2 = array();
- foreach ($pArray AS $word => $weight)
- if ($weight AND !isset($wordIdsByWord['_'.$word]))
- {
- $queryArray[$word] = '('.(int)$product['id_lang'].',\''.pSQL($word).'\')';
- $queryArray2[] = '\''.pSQL($word).'\'';
- $wordIdsByWord[$product['id_lang']]['_'.$word] = 0;
- }
- $existingWords = $db->ExecuteS('
- SELECT DISTINCT word FROM '._DB_PREFIX_.'search_word
- WHERE word IN ('.implode(',', $queryArray2).')
- AND id_lang = '.(int)$product['id_lang']);
- foreach ($existingWords as $data)
- unset($queryArray[Tools::replaceAccentedChars($data['word'])]);
- if (count($queryArray))
- {
- // The words are inserted...
- $db->Execute('
- INSERT IGNORE INTO '._DB_PREFIX_.'search_word (id_lang, word)
- VALUES '.implode(',', $queryArray));
- }
- if (count($queryArray2))
- {
- // ...then their IDs are retrieved and added to the cache
- $addedWords = $db->ExecuteS('
- SELECT sw.id_word, sw.word
- FROM '._DB_PREFIX_.'search_word sw
- WHERE sw.word IN ('.implode(',', $queryArray2).')
- AND sw.id_lang = '.(int)$product['id_lang'].'
- 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)
- $wordIdsByWord[$product['id_lang']]['_'.Tools::replaceAccentedChars($wordId['word'])] = (int)$wordId['id_word'];
- }
- }
- foreach ($pArray AS $word => $weight)
- {
- if (!$weight)
- continue;
- if (!isset($wordIdsByWord[$product['id_lang']]['_'.$word]))
- continue;
- if (!$wordIdsByWord[$product['id_lang']]['_'.$word])
- continue;
- $queryArray3[] = '('.(int)$product['id_product'].','.(int)$wordIdsByWord[$product['id_lang']]['_'.$word].','.(int)$weight.')';
- // Force save every 200 words in order to avoid overloading MySQL
- if (++$countWords % 200 == 0)
- Search::saveIndex($queryArray3);
- }
- if (!in_array($product['id_product'], $productsArray))
- $productsArray[] = (int)$product['id_product'];
- }
- Search::setProductsAsIndexed($productsArray);
- // One last save is done at the end in order to save what's left
- Search::saveIndex($queryArray3);
- }
- return true;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement