Jump to content

Recommended Posts

Dear list!

 

My search function seems to be broken in 1.4.7

 

When changing display_errors to 'on' in config.inc.php, I'm getting the following error from FO, when searching:

 

Warning: preg_replace(): Compilation failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 1829 in /usr/local/www/apache22/domains/domain.tld/classes/Search.php on line 103

 

When trying to rebuild index in BO, I'm getting the same error:

 

Warning: preg_replace(): Compilation failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 1829 in /usr/local/www/apache22/domains/domain.tld/classes/Search.php on line 103

 

Both the tables search_index and search_word are empty. Even after running rebulding...

 

Any ideas? Please let me know!

Link to comment
Share on other sites

I remarked the following line (line 103):

$string = preg_replace('/['.PREG_CLASS_SEARCH_EXCLUDE.']+/u', ' ', $string);

 

Everything seems to be working just fine right now.

Could this be a subject for a bug report?

 

Ps: We only have 1 language installed, if that could be the case.

Link to comment
Share on other sites

  • 3 weeks later...

me to

 

oke, found the solution.

 

open the file /classes/search.php

 

this file uses source from drupal, you can read on this --link--- site that Drupal had thesame problem.

/* Copied from Drupal search module, except for \x{0}-\x{2f} that has been replaced by \x{0}-\x{2c}\x{2e}-\x{2f} in order to keep the char '-' */

define('PREG_CLASS_SEARCH_EXCLUDE',

 

For prestashop we can solve it by replacing line 56.

original line : '\x{a806}\x{a80b}\x{a823}-\x{a82b}\x{d800}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}'.

replace with this one : '\x{a806}\x{a80b}\x{a823}-\x{a82b}\x{e000}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}'.

 

My index works again.

  • Like 6
Link to comment
Share on other sites

  • 5 months later...
  • 1 month later...
  • 1 month later...
  • 2 weeks later...

 

For prestashop we can solve it by replacing line 56.

original line : '\x{a806}\x{a80b}\x{a823}-\x{a82b}\x{d800}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}'.

replace with this one : '\x{a806}\x{a80b}\x{a823}-\x{a82b}\x{e000}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}'.

 

 

Hi, I've the same problem with the search in Prestashop 1.4.9. But if I open the file classes/search.php, line 56 isn't this... My line 56 is:

 

'\x{E000}-\x{F8FF}\x{FB29}\x{FD3E}-\x{FD3F}\x{FDFC}-\x{FDFD}'.

 

And there isn't this line: '\x{a806}\x{a80b}\x{a823}-\x{a82b}\x{d800}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}'. in the whole document. How can I do? Is different in Version 1.4.9? Many thanks.

Link to comment
Share on other sites

  • 3 weeks later...

Hi, I've the same problem with the search in Prestashop 1.4.9. But if I open the file classes/search.php, line 56 isn't this... My line 56 is:

 

'\x{E000}-\x{F8FF}\x{FB29}\x{FD3E}-\x{FD3F}\x{FDFC}-\x{FDFD}'.

 

And there isn't this line: '\x{a806}\x{a80b}\x{a823}-\x{a82b}\x{d800}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}'. in the whole document. How can I do? Is different in Version 1.4.9? Many thanks.

 

Maybe is late, but the solution for PrestaShop 1.4.9 is replace the line 56:

'\x{E000}-\x{F8FF}\x{FB29}\x{FD3E}-\x{FD3F}\x{FDFC}-\x{FDFD}'.

 

for:

'\x{e000}-\x{f8ff}\x{fb29}\x{fd3e}-\x{fd3f}\x{fdfc}-\x{fdfd}'.

 

In my case, now is working perfectly.

 

Best regards.

Edited by Zeyckler (see edit history)
Link to comment
Share on other sites

hello,

 

I'm working with Prestashop 1.4.6.2 and I have the same problem: the error string is no longer there but the search box still doesn't work. Hope somebody can help me because now my shop is'nt working properly and clients leave without ordering :-(

 

Thank you in advance.

Best regards

Monika

Link to comment
Share on other sites

Hi all,

on PS 1.4.5.1, after I have replaced the string \x{d800} with \x{e000} I did an index update (Admin panel -> Preferences -> Search). After this, the search works fine.

 

I hope this can help someone.

 

Regards.

  • Like 2
Link to comment
Share on other sites

Hi people,

 

Thank your for your report. This has been reported in 1.4 and 1.5 versions.

 

:
'\x{E000}-\x{F8FF}\x{FB29}\x{FD3E}-\x{FD3F}\x{FDFC}-\x{FDFD}'.

for:

'\x{e000}-\x{f8ff}\x{fb29}\x{fd3e}-\x{fd3f}\x{fdfc}-\x{fdfd}'.

In my case, now is working perfectly. Best regards.

 

https://github.com/PrestaShop/PrestaShop-1.4/commit/23f841cb3bb57106a9dd82b2c31d7092c92d546d

https://github.com/PrestaShop/PrestaShop/commit/4f6cbdc0ccb417e34ed2034aaafd6e2e211c51f6

 

Regards

  • Like 1
Link to comment
Share on other sites

  • 4 months later...

Same situation my Search Doesn't work after transferring host from kvchost to Godaddy.

 

I still have the old demo site Live http://pdemo.ootiz.co.in/ (search works perfectly)

and new on godaddy is http://pletukobabyshoes.com/ (here search doesnt works, it shows Error 404 page)

 

PS 1.5.4.1

Any suggestion or help is highly appreciated.

Thanks.

 

I also tried https://github.com/PrestaShop/PrestaShop/commit/4f6cbdc0ccb417e34ed2034aaafd6e2e211c51f6

 

but I see that Line no 55 is already '\x{e000}-\x{f8ff}\x{fb29}\x{fd3e}-\x{fd3f}\x{fdfc}-\x{fdfd}'.

Edited by ootiz (see edit history)
Link to comment
Share on other sites

  • 1 month later...

 

search does not work when you type the "-" symbol
version prestashop 1.4.11
Here is an example:
I enter search article: A890-PT100-N
 
finds nothing
 
A890 tidy up and wonder finds multiple articles at once
as soon as I write a "-" then immediately finds nothing
 
please help!

 

 

Hi, make sure to back-up your Database and files and then replace your search.php with this version (1.4.10). Let me know if it works! 

Search.zip

  • Like 1
Link to comment
Share on other sites

  • 2 months later...

Hi! I use Prestashop 1.4.10  and ajax-search works well on localserver.

But when I move it to hosting-server (hostmonster.com), ajax-search dont't work! If I type a word and tap enter - search is working.

My site  is etnomagazin.ru

Can you help me?

Link to comment
Share on other sites

I can not understand why everything works fine on the local server and does not work after migration. I did not change anything!

Thank you for your answers. I, unfortunately, not a programmer, but only a novice user. So this behavior puzzles me)

Link to comment
Share on other sites

It's unbelievable))!

I made a full copy of my shop (etnomagazin.ru) and put it to subdomain old.etnomagazin.ru . Ajax-search at subdomain is fully works!

What am I doing wrong? I do not know what can be done to search for the primary domain joined...

Link to comment
Share on other sites

  • 1 month later...
  • 4 weeks later...
  • 2 months later...
  • 4 months later...

After error at .../public_html/classes/Search.php I did this and worked again. Thanks.

Prestashop 1.4.7.0

 

 

Solved! This is the wrong character: \x{d800}, substituted with \x{e000} and works!

 

Tras un error de la noche a la mañana en .../public_html/classes/Search.php hice lo que se ha descrito aqui y VOILA! funcionando a la perfección:

Usando Prestashop 1.4.7.0

 

Sustituir  la Cadena \x{d800}, por \x{e000} y funcionando!

 

Link to comment
Share on other sites

  • 1 month later...

Hi,

after a transfert of my shop to OVH , 

i have the same problème with the prestashop 1.3.2.3
I trye to remplace de ‘\x{a806}\x{a80b}\x{a823}-\x{a82b}\x{d800}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}’ in the line 43 with "e800"
no error any more, but search result empty...
please help me..
tanks

 

 

my original search.php

<?php

/**
  * Search class, Search.php
  * Search management
  * @category classes
  *
  * @author PrestaShop <[email protected]>
  * @copyright PrestaShop
  * @license http://www.opensource.org/licenses/osl-3.0.php Open-source licence 3.0
  * @version 1.3
  *
  */

define('PS_SEARCH_MAX_WORD_LENGTH', 15);
  
/* Copied from Drupal search module, except for \x{0}-\x{2f} that has been replaced by \x{0}-\x{2c}\x{2e}-\x{2f} in order to keep the char '-' */
define('PREG_CLASS_SEARCH_EXCLUDE',
'\x{0}-\x{2f}\x{3a}-\x{40}\x{5b}-\x{60}\x{7b}-\x{bf}\x{d7}\x{f7}\x{2b0}-'.
'\x{385}\x{387}\x{3f6}\x{482}-\x{489}\x{559}-\x{55f}\x{589}-\x{5c7}\x{5f3}-'.
'\x{61f}\x{640}\x{64b}-\x{65e}\x{66a}-\x{66d}\x{670}\x{6d4}\x{6d6}-\x{6ed}'.
'\x{6fd}\x{6fe}\x{700}-\x{70f}\x{711}\x{730}-\x{74a}\x{7a6}-\x{7b0}\x{901}-'.
'\x{903}\x{93c}\x{93e}-\x{94d}\x{951}-\x{954}\x{962}-\x{965}\x{970}\x{981}-'.
'\x{983}\x{9bc}\x{9be}-\x{9cd}\x{9d7}\x{9e2}\x{9e3}\x{9f2}-\x{a03}\x{a3c}-'.
'\x{a4d}\x{a70}\x{a71}\x{a81}-\x{a83}\x{abc}\x{abe}-\x{acd}\x{ae2}\x{ae3}'.
'\x{af1}-\x{b03}\x{b3c}\x{b3e}-\x{b57}\x{b70}\x{b82}\x{bbe}-\x{bd7}\x{bf0}-'.
'\x{c03}\x{c3e}-\x{c56}\x{c82}\x{c83}\x{cbc}\x{cbe}-\x{cd6}\x{d02}\x{d03}'.
'\x{d3e}-\x{d57}\x{d82}\x{d83}\x{dca}-\x{df4}\x{e31}\x{e34}-\x{e3f}\x{e46}-'.
'\x{e4f}\x{e5a}\x{e5b}\x{eb1}\x{eb4}-\x{ebc}\x{ec6}-\x{ecd}\x{f01}-\x{f1f}'.
'\x{f2a}-\x{f3f}\x{f71}-\x{f87}\x{f90}-\x{fd1}\x{102c}-\x{1039}\x{104a}-'.
'\x{104f}\x{1056}-\x{1059}\x{10fb}\x{10fc}\x{135f}-\x{137c}\x{1390}-\x{1399}'.
'\x{166d}\x{166e}\x{1680}\x{169b}\x{169c}\x{16eb}-\x{16f0}\x{1712}-\x{1714}'.
'\x{1732}-\x{1736}\x{1752}\x{1753}\x{1772}\x{1773}\x{17b4}-\x{17db}\x{17dd}'.
'\x{17f0}-\x{180e}\x{1843}\x{18a9}\x{1920}-\x{1945}\x{19b0}-\x{19c0}\x{19c8}'.
'\x{19c9}\x{19de}-\x{19ff}\x{1a17}-\x{1a1f}\x{1d2c}-\x{1d61}\x{1d78}\x{1d9b}-'.
'\x{1dc3}\x{1fbd}\x{1fbf}-\x{1fc1}\x{1fcd}-\x{1fcf}\x{1fdd}-\x{1fdf}\x{1fed}-'.
'\x{1fef}\x{1ffd}-\x{2070}\x{2074}-\x{207e}\x{2080}-\x{2101}\x{2103}-\x{2106}'.
'\x{2108}\x{2109}\x{2114}\x{2116}-\x{2118}\x{211e}-\x{2123}\x{2125}\x{2127}'.
'\x{2129}\x{212e}\x{2132}\x{213a}\x{213b}\x{2140}-\x{2144}\x{214a}-\x{2b13}'.
'\x{2ce5}-\x{2cff}\x{2d6f}\x{2e00}-\x{3005}\x{3007}-\x{303b}\x{303d}-\x{303f}'.
'\x{3099}-\x{309e}\x{30a0}\x{30fb}\x{30fd}\x{30fe}\x{3190}-\x{319f}\x{31c0}-'.
'\x{31cf}\x{3200}-\x{33ff}\x{4dc0}-\x{4dff}\x{a015}\x{a490}-\x{a716}\x{a802}'.
'\x{a806}\x{a80b}\x{a823}-\x{a82b}\x{d800}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}'.
'\x{fd3f}\x{fdfc}-\x{fe6b}\x{feff}-\x{ff0f}\x{ff1a}-\x{ff20}\x{ff3b}-\x{ff40}'.
'\x{ff5b}-\x{ff65}\x{ff70}\x{ff9e}\x{ff9f}\x{ffe0}-\x{fffd}');

/**
 * Matches all 'N' Unicode character classes (numbers)
 */
define('PREG_CLASS_NUMBERS',
'\x{30}-\x{39}\x{b2}\x{b3}\x{b9}\x{bc}-\x{be}\x{660}-\x{669}\x{6f0}-\x{6f9}'.
'\x{966}-\x{96f}\x{9e6}-\x{9ef}\x{9f4}-\x{9f9}\x{a66}-\x{a6f}\x{ae6}-\x{aef}'.
'\x{b66}-\x{b6f}\x{be7}-\x{bf2}\x{c66}-\x{c6f}\x{ce6}-\x{cef}\x{d66}-\x{d6f}'.
'\x{e50}-\x{e59}\x{ed0}-\x{ed9}\x{f20}-\x{f33}\x{1040}-\x{1049}\x{1369}-'.
'\x{137c}\x{16ee}-\x{16f0}\x{17e0}-\x{17e9}\x{17f0}-\x{17f9}\x{1810}-\x{1819}'.
'\x{1946}-\x{194f}\x{2070}\x{2074}-\x{2079}\x{2080}-\x{2089}\x{2153}-\x{2183}'.
'\x{2460}-\x{249b}\x{24ea}-\x{24ff}\x{2776}-\x{2793}\x{3007}\x{3021}-\x{3029}'.
'\x{3038}-\x{303a}\x{3192}-\x{3195}\x{3220}-\x{3229}\x{3251}-\x{325f}\x{3280}-'.
'\x{3289}\x{32b1}-\x{32bf}\x{ff10}-\x{ff19}');

/**
 * Matches all 'P' Unicode character classes (punctuation)
 */
define('PREG_CLASS_PUNCTUATION',
'\x{21}-\x{23}\x{25}-\x{2a}\x{2c}-\x{2f}\x{3a}\x{3b}\x{3f}\x{40}\x{5b}-\x{5d}'.
'\x{5f}\x{7b}\x{7d}\x{a1}\x{ab}\x{b7}\x{bb}\x{bf}\x{37e}\x{387}\x{55a}-\x{55f}'.
'\x{589}\x{58a}\x{5be}\x{5c0}\x{5c3}\x{5f3}\x{5f4}\x{60c}\x{60d}\x{61b}\x{61f}'.
'\x{66a}-\x{66d}\x{6d4}\x{700}-\x{70d}\x{964}\x{965}\x{970}\x{df4}\x{e4f}'.
'\x{e5a}\x{e5b}\x{f04}-\x{f12}\x{f3a}-\x{f3d}\x{f85}\x{104a}-\x{104f}\x{10fb}'.
'\x{1361}-\x{1368}\x{166d}\x{166e}\x{169b}\x{169c}\x{16eb}-\x{16ed}\x{1735}'.
'\x{1736}\x{17d4}-\x{17d6}\x{17d8}-\x{17da}\x{1800}-\x{180a}\x{1944}\x{1945}'.
'\x{2010}-\x{2027}\x{2030}-\x{2043}\x{2045}-\x{2051}\x{2053}\x{2054}\x{2057}'.
'\x{207d}\x{207e}\x{208d}\x{208e}\x{2329}\x{232a}\x{23b4}-\x{23b6}\x{2768}-'.
'\x{2775}\x{27e6}-\x{27eb}\x{2983}-\x{2998}\x{29d8}-\x{29db}\x{29fc}\x{29fd}'.
'\x{3001}-\x{3003}\x{3008}-\x{3011}\x{3014}-\x{301f}\x{3030}\x{303d}\x{30a0}'.
'\x{30fb}\x{fd3e}\x{fd3f}\x{fe30}-\x{fe52}\x{fe54}-\x{fe61}\x{fe63}\x{fe68}'.
'\x{fe6a}\x{fe6b}\x{ff01}-\x{ff03}\x{ff05}-\x{ff0a}\x{ff0c}-\x{ff0f}\x{ff1a}'.
'\x{ff1b}\x{ff1f}\x{ff20}\x{ff3b}-\x{ff3d}\x{ff3f}\x{ff5b}\x{ff5d}\x{ff5f}-'.
'\x{ff65}'); 

/**
 * Matches all CJK characters that are candidates for auto-splitting
 * (Chinese, Japanese, Korean).
 * Contains kana and BMP ideographs.
 */
define('PREG_CLASS_CJK', '\x{3041}-\x{30ff}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}'.
'\x{4e00}-\x{9fbb}\x{f900}-\x{fad9}');


class Search
{
	public static function sanitize($string, $id_lang, $indexation = false)
	{
		$string = Tools::strtolower(strip_tags($string));
		$string = html_entity_decode($string, ENT_NOQUOTES, 'utf-8');

		$string = preg_replace('/(['.PREG_CLASS_NUMBERS.']+)['.PREG_CLASS_PUNCTUATION.']+(?=['.PREG_CLASS_NUMBERS.'])/u', '\1', $string);
		$string = preg_replace('/['.PREG_CLASS_SEARCH_EXCLUDE.']+/u', ' ', $string);
		
		if ($indexation)
			$string = preg_replace('/[._-]+/', '', $string);
		else
		{
			$string = preg_replace('/[._]+/', '', $string);
			$string = ltrim(preg_replace('/([^ ])-/', '$1', ' '.$string));
			$string = preg_replace('/[._]+/', '', $string);
			$string = preg_replace('/[^\s]-+/', '', $string);
		}
		
		$blacklist = Configuration::get('PS_SEARCH_BLACKLIST', $id_lang);
		if (!empty($blacklist))
		{
			$string = preg_replace('/(?<=\s)('.$blacklist.')(?=\s)/Su', '', $string);
			$string = preg_replace('/^('.$blacklist.')(?=\s)/Su', '', $string);
			$string = preg_replace('/(?<=\s)('.$blacklist.')$/Su', '', $string);
			$string = preg_replace('/^('.$blacklist.')$/Su', '', $string);
		}
		
		if (!$indexation)
		{
			$alias = new Alias(NULL, $string);
			if (Validate::isLoadedObject($alias))
				$string = $alias->search;
		}
		
		if ($indexation)
		{
			$minWordLen = intval(Configuration::get('PS_SEARCH_MINWORDLEN'));
			if ($minWordLen > 1)
			{
				$minWordLen -= 1;
				$string = preg_replace('/(?<=\s)[^\s]{1,'.$minWordLen.'}(?=\s)/Su', ' ', $string);
				$string = preg_replace('/^[^\s]{1,'.$minWordLen.'}(?=\s)/Su', '', $string);
				$string = preg_replace('/(?<=\s)[^\s]{1,'.$minWordLen.'}$/Su', '', $string);
				$string = preg_replace('/^[^\s]{1,'.$minWordLen.'}$/Su', '', $string);
			}
		}
		
		$string = trim(preg_replace('/\s+/', ' ', $string));
		return $string;
	}

	public static function find($id_lang, $expr, $pageNumber = 1, $pageSize = 1, $orderBy = 'position', $orderWay = 'desc', $ajax = false)
	{
		global $cookie;
		$db = Db::getInstance();

		// TODO : smart page management
		if ($pageNumber < 1) $pageNumber = 1;
		if ($pageSize < 1) $pageSize = 1;
		
		if (!Validate::isOrderBy($orderBy) OR !Validate::isOrderWay($orderWay))
			die(Tools::displayError());
		
		$whereArray = array();
		$scoreArray = array();
		$words = explode(' ', Search::sanitize($expr, $id_lang));

		foreach ($words as $key => $word)
			if (!empty($word) AND strlen($word) != 1)
			{
				$word = str_replace('%', '\\%', $word);
				$word = str_replace('_', '\\_', $word);
				$whereArray[] = ' p.id_product '.($word[0] == '-' ? 'NOT' : '').' IN (
					SELECT id_product
					FROM '._DB_PREFIX_.'search_word sw
					LEFT JOIN '._DB_PREFIX_.'search_index si ON sw.id_word = si.id_word
					WHERE sw.id_lang = '.intval($id_lang).'
					AND sw.word LIKE '.($word[0] == '-' ? ' \''.pSQL(Tools::substr($word, 1, PS_SEARCH_MAX_WORD_LENGTH)).'%\'' : '\''.pSQL(Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH)).'%\'').'
				) ';
				if ($word[0] != '-')
					$scoreArray[] = 'sw.word LIKE \''.pSQL(Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH)).'%\'';
			}
			else
				unset($words[$key]);

		if (!sizeof($words))
			return ($ajax ? array() : array('total' => 0, 'result' => array()));
			
		$score = '';
		if (sizeof($scoreArray))
			$score = ',(
				SELECT SUM(weight)
				FROM '._DB_PREFIX_.'search_word sw
				LEFT JOIN '._DB_PREFIX_.'search_index si ON sw.id_word = si.id_word
				WHERE sw.id_lang = '.intval($id_lang).'
				AND si.id_product = p.id_product
				AND ('.implode(' OR ', $scoreArray).')
			) as position';
			
		$eligibleProducts = $db->ExecuteS('
		SELECT DISTINCT cp.`id_product`
		FROM `'._DB_PREFIX_.'category_group` cg
		INNER JOIN `'._DB_PREFIX_.'category_product` cp ON cp.`id_category` = cg.`id_category`
		INNER JOIN `'._DB_PREFIX_.'category` c ON cp.`id_category` = c.`id_category`
		INNER JOIN `'._DB_PREFIX_.'product` p ON cp.`id_product` = p.`id_product`
		WHERE c.`active` = 1 AND p.`active` = 1 
		AND cg.`id_group` '.(!$cookie->id_customer ?  '= 1' : 'IN (
			SELECT id_group FROM '._DB_PREFIX_.'customer_group
			WHERE id_customer = '.intval($cookie->id_customer).'
		)').'
		AND '.implode(' AND ', $whereArray));
		
		$productPool = '';
		foreach ($eligibleProducts as $product)
			if (!empty($product['id_product']))
				$productPool .= $product['id_product'].',';
		if (empty($productPool))
			return ($ajax ? array() : array('total' => 0, 'result' => array()));
		$productPool = ((strpos($productPool, ',') === false) ? (' = '.(int)$productPool.' ') : (' IN ('.rtrim($productPool, ',').') '));
		
		if ($ajax)
		{
			if (!$result = $db->ExecuteS('
				SELECT DISTINCT p.id_product, pl.name as pname, cl.name AS cname,
					cl.link_rewrite as crewrite, pl.link_rewrite as 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` = '.intval($id_lang).')
				INNER JOIN `'._DB_PREFIX_.'category_lang` cl ON (p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.intval($id_lang).')
				WHERE p.`id_product` '.$productPool.'
				ORDER BY position DESC LIMIT 10
			'))
				return false;
			foreach ($result AS &$row)
				$row['cname'] = Category::hideCategoryPosition($row['cname']);
			return $result;
		}

		$queryResults = '
		SELECT SQL_CALC_FOUND_ROWS p.*, pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`name`,
			t.`rate`, i.`id_image`, il.`legend`, m.`name` AS manufacturer_name '.$score.'
		FROM '._DB_PREFIX_.'product p
		INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.intval($id_lang).')
		LEFT JOIN `'._DB_PREFIX_.'tax` t ON p.`id_tax` = t.`id_tax`
		LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
		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` = '.intval($id_lang).')
		WHERE p.`id_product` '.$productPool.'
		'.($orderBy ? 'ORDER BY  '.$orderBy : '').($orderWay ? ' '.$orderWay : '').'
		LIMIT '.intval(($pageNumber - 1) * $pageSize).','.intval($pageSize);
		
		$result = $db->ExecuteS($queryResults);
		$total = $db->getValue('SELECT FOUND_ROWS()');

		Module::hookExec('search', array('expr' => $expr, 'total' => $total));

		return array('total' => $total,'result' => Product::getProductsProperties($id_lang, $result));
	}
	
	public static function getTags($db, $id_product, $id_lang)
	{
		$tags = '';
		$tagsArray = $db->ExecuteS('
		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 = '.intval($id_lang).')
		WHERE pt.id_product = '.intval($id_product));
		foreach ($tagsArray as $tag)
			$tags .= $tag['name'].' ';
		return $tags;
	}

	public static function getAttributes($db, $id_product, $id_lang)
	{
		$attributes = '';
		$attributesArray = $db->ExecuteS('
		SELECT al.name FROM '._DB_PREFIX_.'product_attribute pa
		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 = '.intval($id_lang).')
		WHERE pa.id_product = '.intval($id_product));
		foreach ($attributesArray as $attribute)
			$attributes .= $attribute['name'].' ';
		return $attributes;
	}

	public static function getFeatures($db, $id_product, $id_lang)
	{
		$features = '';
		$featuresArray = $db->ExecuteS('
		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 = '.intval($id_lang).')
		WHERE fp.id_product = '.intval($id_product));
		foreach ($featuresArray as $feature)
			$features .= $feature['value'].' ';
		return $features;
	}
	
	public static function indexation($full = false)
	{
		$db = Db::getInstance();
		
		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
		{
			$products = $db->ExecuteS('SELECT id_product FROM '._DB_PREFIX_.'product WHERE indexed = 0');
			
			$ids = array();
			if ($products)
				foreach($products AS $product)
					$ids[] = intval($product['id_product']);
			if (sizeof($ids))
				$db->Execute('DELETE FROM '._DB_PREFIX_.'search_index WHERE id_product IN ('.implode(',', $ids).')');
		}
	
		$weightArray = array(
			'pname' => Configuration::get('PS_SEARCH_WEIGHT_PNAME'),
			'reference' => Configuration::get('PS_SEARCH_WEIGHT_REF'),
			'ean13' => 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')
		);
		
		$products = $db->ExecuteS('
		SELECT p.id_product, pl.id_lang, pl.name as pname, p.reference, p.ean13, pl.description_short, pl.description, cl.name as cname, m.name as 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)
		LEFT JOIN '._DB_PREFIX_.'manufacturer m ON m.id_manufacturer = p.id_manufacturer
		WHERE p.indexed = 0', false);
		
		while ($product = $db->nextRow($products))
		{
			$product['tags'] = self::getTags($db, $product['id_product'], $product['id_lang']);
			$product['attributes'] = self::getAttributes($db, $product['id_product'], $product['id_lang']);
			$product['features'] = self::getFeatures($db, $product['id_product'], $product['id_lang']);

			$pArray = array();
			foreach ($product as $key => $value)
				if (strncmp($key, 'id_', 3))
				{
					if ($key == 'cname')
						$value = Category::hideCategoryPosition($value);
					$words = explode(' ', self::sanitize($value, $product['id_lang'], true));
					foreach ($words as $word)
						if (!empty($word))
						{
							$word = Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH);
							if (!isset($pArray[$word]))
								$pArray[$word] = $weightArray[$key];
							else
								$pArray[$word] += $weightArray[$key];
						}
				}
			
			$count = 0;
			$queryArray = array();
			$queryArray2 = array();
			foreach ($pArray as $word => $weight)
			{
				$queryArray[] = '('.intval($product['id_lang']).',\''.pSQL($word).'\')';
				$queryArray2[] = '('.intval($product['id_product']).',(SELECT id_word FROM '._DB_PREFIX_.'search_word WHERE word = \''.pSQL($word).'\' AND id_lang = '.intval($product['id_lang']).' LIMIT 1),'.intval($weight).')';
				// Force save every 10 words in order to avoid overloading MySQL
				if (++$count % 10 == 0)
					self::saveIndex($queryArray, $queryArray2);
			}
			self::saveIndex($queryArray, $queryArray2);
			$db->Execute('UPDATE '._DB_PREFIX_.'product SET indexed = 1 WHERE id_product = '.intval($product['id_product']));
		}
		$db->Execute('DELETE FROM '._DB_PREFIX_.'search_word WHERE id_word NOT IN (SELECT id_word FROM '._DB_PREFIX_.'search_index)');
		return true;
	}
	
	private static function saveIndex(array &$queryArray, array &$queryArray2)
	{
		if (sizeof($queryArray) AND sizeof($queryArray2))
		{
			if (!($rows = $db = Db::getInstance()->Execute('INSERT IGNORE INTO '._DB_PREFIX_.'search_word (id_lang, word) VALUES '.implode(',',$queryArray))) OR $rows != sizeof($queryArray))
				Tools:(array(mysql_error(), $queryArray));
			if (!($rows = $db = Db::getInstance()->Execute('INSERT INTO '._DB_PREFIX_.'search_index (id_product, id_word, weight) VALUES '.implode(',',$queryArray2).' ON DUPLICATE KEY UPDATE weight = weight + VALUES(weight)')) OR $rows != sizeof($queryArray2))
				Tools:(array(mysql_error(), $queryArray2));
		}
		$queryArray = array();
		$queryArray2 = array();
	}
	
	public static function searchTag($id_lang, $tag, $count = false, $pageNumber = 0, $pageSize = 10, $orderBy = false, $orderWay = false)
	{
	 	global $link;

		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)))
			die(Tools::displayError());

		if ($pageNumber < 1) $pageNumber = 1;
		if ($pageSize < 1) $pageSize = 10;

		if ($count)
		{
			$result = Db::getInstance()->getRow('
			SELECT COUNT(pt.`id_product`) AS nb
			FROM `'._DB_PREFIX_.'product` p
			LEFT JOIN `'._DB_PREFIX_.'product_tag` pt ON (p.`id_product` = pt.`id_product`)
			LEFT JOIN `'._DB_PREFIX_.'tag` t ON (pt.`id_tag` = t.`id_tag` AND t.`id_lang` = '.intval($id_lang).')
			WHERE p.`active` = 1
			AND t.`name` LIKE \'%'.pSQL($tag).'%\'');
			return isset($result['nb']) ? $result['nb'] : 0;
		}
		$result = Db::getInstance()->ExecuteS('
		SELECT p.*, pl.`description_short`, pl.`link_rewrite`, pl.`name`, tax.`rate`, i.`id_image`, il.`legend`, m.`name` AS manufacturer_name, 1 as position
		FROM `'._DB_PREFIX_.'product` p
		LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.intval($id_lang).')
		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` = '.intval($id_lang).')
		LEFT JOIN `'._DB_PREFIX_.'tax` tax ON (p.`id_tax` = tax.`id_tax`)
		LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
		LEFT JOIN `'._DB_PREFIX_.'product_tag` pt ON (p.`id_product` = pt.`id_product`)
		LEFT JOIN `'._DB_PREFIX_.'tag` t ON (pt.`id_tag` = t.`id_tag` AND t.`id_lang` = '.intval($id_lang).')
		WHERE p.`active` = 1
		AND t.`name` LIKE \'%'.pSQL($tag).'%\'
		GROUP BY pt.`id_product`
		ORDER BY position DESC'.($orderBy ? ', '.$orderBy : '').($orderWay ? ' '.$orderWay : '').'
		LIMIT '.intval(($pageNumber - 1) * $pageSize).','.intval($pageSize));
		if (!$result) return false;

		return Product::getProductsProperties($id_lang, $result);
	}
}
	
?>

Link to comment
Share on other sites

I have the same error in PS 1.3.2.3 with the message :

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND pa.quantity >= 1' at line 6

SELECT al.name
			FROM ps_product_attribute pa
			JOIN ps_product_attribute_combination pac ON pac.id_product_attribute = pa.id_product_attribute
			JOIN ps_attribute_lang al ON (al.id_attribute = pac.id_attribute AND al.id_lang = 2)
			JOIN ps_attribute a ON (a.id_attribute_group = 4 AND a.id_attribute = pac.id_attribute)
			WHERE pa.id_product =  AND pa.quantity >= 1 

There is no value for id_product :blink:

Link to comment
Share on other sites

I have the same error in PS 1.3.2.3 with the message :

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND pa.quantity >= 1' at line 6

SELECT al.name
			FROM ps_product_attribute pa
			JOIN ps_product_attribute_combination pac ON pac.id_product_attribute = pa.id_product_attribute
			JOIN ps_attribute_lang al ON (al.id_attribute = pac.id_attribute AND al.id_lang = 2)
			JOIN ps_attribute a ON (a.id_attribute_group = 4 AND a.id_attribute = pac.id_attribute)
			WHERE pa.id_product =  AND pa.quantity >= 1 

There is no value for id_product :blink:

It's ok, after the change of the Search.php, you must build all the index.   

Link to comment
Share on other sites

  • 3 months later...

Hi all,

on PS 1.4.5.1, after I have replaced the string \x{d800} with \x{e000} I did an index update (Admin panel -> Preferences -> Search). After this, the search works fine.

 

I hope this can help someone.

 

Regards.

Thank you.

 

\x means an hexa value and the code is the code on the hexadecimal charset table.

d800 to ascii is that char = Ø

e000 to ascii is that char = à

 

Making that change on the /classes/Search.php as suggested is fine. Don't forget rebuild the index again.

You don't need to change whole line, just search for that string, because your file may be from another version and wouldn't match.

I tried to replace whole line n 56 and didn't work, then changed only \x{d800} to \x{e000} and worked :)

 

If you got problems with it, set display_errors value to On (/config/config.php file) and you will get the exact character position on the file that is causing the problem.

 

Thank you TheSnake.

Edited by wippa (see edit history)
Link to comment
Share on other sites

  • 1 year later...

Clap for you. Thank You!

oke, found the solution.

open the file /classes/search.php

this file uses source from drupal, you can read on this --link--- site that Drupal had thesame problem.
/* Copied from Drupal search module, except for \x{0}-\x{2f} that has been replaced by \x{0}-\x{2c}\x{2e}-\x{2f} in order to keep the char '-' */
define('PREG_CLASS_SEARCH_EXCLUDE',

For prestashop we can solve it by replacing line 56.
original line : '\x{a806}\x{a80b}\x{a823}-\x{a82b}\x{d800}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}'.
replace with this one : '\x{a806}\x{a80b}\x{a823}-\x{a82b}\x{e000}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}'.

My index works again.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...