Advertisement
Guest User

Override Search

a guest
Sep 7th, 2012
253
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 8.42 KB | None | 0 0
  1. class Search extends SearchCore{
  2.  
  3.  
  4.   protected static function getProductsToIndex($total_languages, $id_product = false, $limit = 50)
  5.   {
  6.    
  7.   // parent::getProductsToIndex($total_languages, $id_product, $limit);
  8.     // Adjust the limit to get only "whole" products, in every languages (and at least one)
  9.     $limit = max(1, round($limit / $total_languages) * $total_languages);
  10.     return Db::getInstance()->ExecuteS('
  11.        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
  12.        FROM '._DB_PREFIX_.'product p
  13.        LEFT JOIN '._DB_PREFIX_.'product_lang pl ON p.id_product = pl.id_product
  14.        LEFT JOIN '._DB_PREFIX_.'product_attribute pa ON p.id_product = pa.id_product
  15.        LEFT JOIN '._DB_PREFIX_.'category_lang cl ON (cl.id_category = p.id_category_default AND pl.id_lang = cl.id_lang)
  16.        LEFT JOIN '._DB_PREFIX_.'manufacturer m ON m.id_manufacturer = p.id_manufacturer
  17.        WHERE p.indexed = 0
  18.        '.($id_product ? 'AND p.id_product = '.(int)$id_product : '').'
  19.        LIMIT '.(int)$limit);
  20.   }
  21.  
  22.  
  23.   public static function indexation($full = false, $id_product = false)
  24.   {
  25.     //parent::indexation($full,$id_product);
  26.    
  27.     $db = Db::getInstance();
  28.     if ($id_product)
  29.       $full = false;
  30.  
  31.     if ($full)
  32.     {
  33.       $db->Execute('TRUNCATE '._DB_PREFIX_.'search_index');
  34.       $db->Execute('TRUNCATE '._DB_PREFIX_.'search_word');
  35.       $db->Execute('UPDATE '._DB_PREFIX_.'product SET indexed = 0');
  36.     }
  37.     else
  38.     {
  39.       // Do it even if you already know the product id in order to be sure that it exists
  40.       $products = $db->ExecuteS('
  41.          SELECT id_product
  42.          FROM '._DB_PREFIX_.'product
  43.          WHERE '.($id_product ? 'id_product = '.(int)$id_product : 'indexed = 0'));
  44.  
  45.       $ids = array();
  46.       if ($products)
  47.         foreach($products AS $product)
  48.         $ids[] = (int)$product['id_product'];
  49.       if (sizeof($ids))
  50.         $db->Execute('DELETE FROM '._DB_PREFIX_.'search_index WHERE id_product IN ('.implode(',', $ids).')');
  51.     }
  52.  
  53.     // Every fields are weighted according to the configuration in the backend
  54.     $weightArray = array(
  55.         'pname' => Configuration::get('PS_SEARCH_WEIGHT_PNAME'),
  56.         'reference' => Configuration::get('PS_SEARCH_WEIGHT_REF'),
  57.         'ean13' => Configuration::get('PS_SEARCH_WEIGHT_REF'),
  58.         'upc' => Configuration::get('PS_SEARCH_WEIGHT_REF'),
  59.         'description_short' => Configuration::get('PS_SEARCH_WEIGHT_SHORTDESC'),
  60.         'description' => Configuration::get('PS_SEARCH_WEIGHT_DESC'),
  61.         'cname' => Configuration::get('PS_SEARCH_WEIGHT_CNAME'),
  62.         'mname' => Configuration::get('PS_SEARCH_WEIGHT_MNAME'),
  63.         'tags' => Configuration::get('PS_SEARCH_WEIGHT_TAG'),
  64.         'attributes' => Configuration::get('PS_SEARCH_WEIGHT_ATTRIBUTE'),
  65.         'features' => Configuration::get('PS_SEARCH_WEIGHT_FEATURE'),
  66.         'reference_declinaison' => Configuration::get('PS_SEARCH_WEIGHT_REF')
  67.     );
  68.  
  69.     // Those are kind of global variables required to save the processed data in the database every X occurences, in order to avoid overloading MySQL
  70.     $countWords = 0;
  71.     $countProducts = 0;
  72.     $queryArray3 = array();
  73.     $productsArray = array();
  74.  
  75.     // Every indexed words are cached into a PHP array
  76.     $wordIdsByWord = array();
  77.     $wordIds = Db::getInstance()->ExecuteS('
  78.        SELECT sw.id_word, sw.word, id_lang
  79.        FROM '._DB_PREFIX_.'search_word sw', false);
  80.     $wordIdsByWord = array();
  81.     while ($wordId = $db->nextRow($wordIds))
  82.     {
  83.       if (!isset($wordIdsByWord[$wordId['id_lang']]))
  84.         $wordIdsByWord[$wordId['id_lang']] = array();
  85.       $wordIdsByWord[$wordId['id_lang']]['_'.$wordId['word']] = (int)$wordId['id_word'];
  86.     }
  87.  
  88.     // Retrieve the number of languages
  89.     $total_languages = count(Language::getLanguages(false));
  90.  
  91.     // Products are processed 50 by 50 in order to avoid overloading MySQL
  92.     while (($products = Search::getProductsToIndex($total_languages, $id_product, 50)) && is_array($products) && (count($products) > 0))
  93.     {
  94.       // Now each non-indexed product is processed one by one, langage by langage
  95.       foreach ($products as $product)
  96.       {
  97.         $product['tags'] = Search::getTags($db, (int)$product['id_product'], (int)$product['id_lang']);
  98.         $product['attributes'] = Search::getAttributes($db, (int)$product['id_product'], (int)$product['id_lang']);
  99.         $product['features'] = Search::getFeatures($db, (int)$product['id_product'], (int)$product['id_lang']);
  100.  
  101.         // 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
  102.         $pArray = array();
  103.         foreach ($product AS $key => $value)
  104.           if (strncmp($key, 'id_', 3))
  105.           {
  106.             $words = explode(' ', Search::sanitize($value, (int)$product['id_lang'], true));
  107.             foreach ($words AS $word)
  108.               if (!empty($word))
  109.               {
  110.                 $word = Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH);
  111.                 // Remove accents
  112.                 $word = Tools::replaceAccentedChars($word);
  113.  
  114.                 if (!isset($pArray[$word]))
  115.                   $pArray[$word] = 0;
  116.                 $pArray[$word] += $weightArray[$key];
  117.               }
  118.           }
  119.  
  120.           // If we find words that need to be indexed, they're added to the word table in the database
  121.           if (sizeof($pArray))
  122.           {
  123.             $queryArray = array();
  124.             $queryArray2 = array();
  125.             foreach ($pArray AS $word => $weight)
  126.               if ($weight AND !isset($wordIdsByWord['_'.$word]))
  127.               {
  128.                 $queryArray[$word] = '('.(int)$product['id_lang'].',\''.pSQL($word).'\')';
  129.                 $queryArray2[] = '\''.pSQL($word).'\'';
  130.                 $wordIdsByWord[$product['id_lang']]['_'.$word] = 0;
  131.               }
  132.  
  133.               $existingWords = $db->ExecuteS('
  134.                  SELECT DISTINCT word FROM '._DB_PREFIX_.'search_word
  135.                  WHERE word IN ('.implode(',', $queryArray2).')
  136.                  AND id_lang = '.(int)$product['id_lang']);
  137.  
  138.               foreach ($existingWords as $data)
  139.                 unset($queryArray[Tools::replaceAccentedChars($data['word'])]);
  140.  
  141.               if (count($queryArray))
  142.               {
  143.                 // The words are inserted...
  144.                 $db->Execute('
  145.                    INSERT IGNORE INTO '._DB_PREFIX_.'search_word (id_lang, word)
  146.                    VALUES '.implode(',', $queryArray));
  147.               }
  148.               if (count($queryArray2))
  149.               {
  150.                 // ...then their IDs are retrieved and added to the cache
  151.                 $addedWords = $db->ExecuteS('
  152.                    SELECT sw.id_word, sw.word
  153.                    FROM '._DB_PREFIX_.'search_word sw
  154.                    WHERE sw.word IN ('.implode(',', $queryArray2).')
  155.                    AND sw.id_lang = '.(int)$product['id_lang'].'
  156.                    LIMIT '.count($queryArray2));
  157.                 // replace accents from the retrieved words so that words without accents or with differents accents can still be linked
  158.                 foreach ($addedWords AS $wordId)
  159.                   $wordIdsByWord[$product['id_lang']]['_'.Tools::replaceAccentedChars($wordId['word'])] = (int)$wordId['id_word'];
  160.               }
  161.           }
  162.  
  163.           foreach ($pArray AS $word => $weight)
  164.           {
  165.             if (!$weight)
  166.               continue;
  167.             if (!isset($wordIdsByWord[$product['id_lang']]['_'.$word]))
  168.               continue;
  169.             if (!$wordIdsByWord[$product['id_lang']]['_'.$word])
  170.               continue;
  171.             $queryArray3[] = '('.(int)$product['id_product'].','.(int)$wordIdsByWord[$product['id_lang']]['_'.$word].','.(int)$weight.')';
  172.  
  173.             // Force save every 200 words in order to avoid overloading MySQL
  174.             if (++$countWords % 200 == 0)
  175.               Search::saveIndex($queryArray3);
  176.           }
  177.  
  178.           if (!in_array($product['id_product'], $productsArray))
  179.             $productsArray[] = (int)$product['id_product'];
  180.       }
  181.       Search::setProductsAsIndexed($productsArray);
  182.       // One last save is done at the end in order to save what's left
  183.       Search::saveIndex($queryArray3);
  184.     }
  185.     return true;
  186.   }
  187.  
  188. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement