Jump to content

Moteur de recherche pour Prestashop + Wordpress


vinskate
 Share

Recommended Posts

Hellooo,

 

J'espère poster dans la bonne partie du forum. Voici mon problème, je suis stagiaire en développement web et je suis sur un projet (presta+WP) et le client aimerait avoir un moteur de recherche qui retourne les résultats aussi bien du blog que du site e-commerce, des solutions?

 

J'ai regardé pour elastic search mais il lui faut un serveur java qui tourne "constamment" sur le serveur, donc ça ne m'arrange pas trop mais si vous avez plus de détails sur le fonctionnement et les possibilités d'elastic search, je suis preneur.

 

Ma seconde "solution", c'était le moteur de recherche google personnalisé? Est-ce une meilleur alternative?

 

En vous remerciant  :)

Share this post


Link to post
Share on other sites

Je pense faire un genre d'include de la fonction de recherche de wordpress lorsque l'utilisateur lance la recherche du prestashop et inversément, ça me semble faisable, si vous avez des avis...

Je mettrais la solution en code et en explication dès que c'est réalisé, à bientôt la communauté.

Share this post


Link to post
Share on other sites

Voilà, donc si ça peut intéresser quelqu'un, j'ai fait quelque chose de simple.

Tout d'abord, lorsque j'installe WordPress sur Prestashop, je lui donne la même base de donnée.

 

En suite, j'ai modifié de la sorte que la header et footer sur le site comme sur le blog soit le header et footer de prestashop.

Etc, etc ... pour l'association des deux, il existe des tutos, suffit de googler!

En suite, pour les deux moteurs de recherches, j'ai simplement ajouter un query qui recherche dans les tables du blog de wordpress (dans le même base de donnée).

 

Où?

 

  • Dans prestashop, vous avez une classe SearchControllers (controllers/front/SearchControllers.php).

 

Modification

else if (($query = Tools::getValue('search_query', Tools::getValue('ref'))) && !is_array($query))
                               {
                                               $this->productSort();
                                               $this->n = abs((int)(Tools::getValue('n', Configuration::get('PS_PRODUCTS_PER_PAGE'))));
                                               $this->p = abs((int)(Tools::getValue('p', 1)));
                                               $query = Tools::replaceAccentedChars(urldecode($query));                                   
                                               $search = Search::find($this->context->language->id, $query, $this->p, $this->n, $this->orderBy, $this->orderWay);
                                               Hook::exec('actionSearch', array('expr' => $query, 'total' => $search['total']));
                                               $nbProducts = $search['total'];
                                               $this->pagination($nbProducts);
                                               $this->context->smarty->assign(array(
                                                               'products' => $search['result'], // DEPRECATED (since to 1.4), not use this: conflict with block_cart module
                                                               'search_products' => $search['result'],
                                                               'nbProducts' => $search['total'],
                                                               'search_query' => $query,
                                                               'homeSize' => Image::getSize(ImageType::getFormatedName('home'))));
                                              
                                               $this->context->smarty->assign(array(
                                                               'resultBlog' => $search['resultFromBlog']));
                               }

Récupère le champ "resultFromBlog" de la classe Search, méthode Find.

 

  • Dans la classe Search.php (/classes/Search.php):

 

Modification:

 

 
public static function find($id_lang, $expr, $page_number = 1, $page_size = 1, $order_by = 'position',
$order_way = 'desc', $ajax = false, $use_cookie = true, Context $context = null)
{
if (!$context)
$context = Context::getContext();
$db = Db::getInstance(_PS_USE_SQL_SLAVE_);

// Only use cookie if id_customer is not present
if ($use_cookie)
$id_customer = $context->customer->id;
else
$id_customer = 0;




$bool = false;
$wordsBlog = explode(' ', Search::sanitize($expr, $id_lang, false, $context->language->iso_code));
$sqlBlog = "SELECT * FROM wp_posts WHERE ";
$sqlCountBlog = "SELECT COUNT(*) FROM wp_posts WHERE ";
foreach ($wordsBlog as $key=>$word)
{
if($bool)
{
$sqlBlog .= " OR post_content LIKE \"%" .$word. "%\" OR post_title LIKE \"%" .$word. "%\"";
$sqlCountBlog .= " OR post_content LIKE \"%" .$word. "%\" OR post_title LIKE \"%" .$word. "%\"";
}
else
{
$sqlBlog .= "post_content LIKE \"%" .$word. "%\" OR post_title LIKE \"%" .$word. "%\" ";
$sqlCountBlog .= "post_content LIKE \"%" .$word. "%\" OR post_title LIKE \"%" .$word. "%\" ";
$bool = true;
}
}
$sqlBlog .= "";




// TODO : smart page management
if ($page_number < 1) $page_number = 1;
if ($page_size < 1) $page_size = 1;

if (!Validate::isOrderBy($order_by) || !Validate::isOrderWay($order_way))
return false;

$intersect_array = array();
$score_array = array();
$words = explode(' ', Search::sanitize($expr, $id_lang, false, $context->language->iso_code));

foreach ($words as $key => $word)
if (!empty($word) && strlen($word) >= (int)Configuration::get('PS_SEARCH_MINWORDLEN'))
{
$word = str_replace('%', '\\%', $word);
$word = str_replace('_', '\\_', $word);
$intersect_array[] = 'SELECT si.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 = '.(int)$id_lang.'
AND sw.id_shop = '.$context->shop->id.'
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] != '-')
$score_array[] = 'sw.word LIKE \''.pSQL(Tools::substr($word, 0, PS_SEARCH_MAX_WORD_LENGTH)).'%\'';
}
else
unset($words[$key]);

if (!count($words) && !$bool)
return ($ajax ? array() : array('total' => 0, 'result' => array()));

$score = '';
if (count($score_array))
$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 = '.(int)$id_lang.'
AND sw.id_shop = '.$context->shop->id.'
AND si.id_product = p.id_product
AND ('.implode(' OR ', $score_array).')
) position';

$sql = 'SELECT 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`
'.Shop::addSqlAssociation('product', 'p', false).'
WHERE c.`active` = 1
AND product_shop.`active` = 1
AND product_shop.`visibility` IN ("both", "search")
AND product_shop.indexed = 1
AND cg.`id_group` '.(!$id_customer ?  '= '.(int)Configuration::get('PS_UNIDENTIFIED_GROUP') : 'IN (
SELECT id_group FROM '._DB_PREFIX_.'customer_group
WHERE id_customer = '.(int)$id_customer.'
)');
$results = $db->executeS($sql);

$eligible_products = array();
foreach ($results as $row)
$eligible_products[] = $row['id_product'];
foreach ($intersect_array as $query)
{
$eligible_products2 = array();
foreach ($db->executeS($query) as $row)
$eligible_products2[] = $row['id_product'];

$eligible_products = array_intersect($eligible_products, $eligible_products2);
if (!count($eligible_products) && !$bool)
return ($ajax ? array() : array('total' => 0, 'result' => array()));
}

$eligible_products = array_unique($eligible_products);

$product_pool = '';
foreach ($eligible_products as $id_product)
if ($id_product)
$product_pool .= (int)$id_product.',';
if (empty($product_pool) && !$bool)
return ($ajax ? array() : array('total' => 0, 'result' => array()));
$product_pool = ((strpos($product_pool, ',') === false) ? (' = '.(int)$product_pool.' ') : (' IN ('.rtrim($product_pool, ',').') '));

if ($ajax)
{
$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.Shop::addSqlRestrictionOnLang('pl').'
)
'.Shop::addSqlAssociation('product', 'p').'
INNER JOIN `'._DB_PREFIX_.'category_lang` cl ON (
product_shop.`id_category_default` = cl.`id_category`
AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').'
)
WHERE p.`id_product` '.$product_pool.'
ORDER BY position DESC LIMIT 10';
return $db->executeS($sql);
}

if (strpos($order_by, '.') > 0)
{
$order_by = explode('.', $order_by);
$order_by = pSQL($order_by[0]).'.`'.pSQL($order_by[1]).'`';
}
$alias = '';
if ($order_by == 'price')
$alias = 'product_shop.';
else if ($order_by == 'date_upd')
$alias = 'p.';
$sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity, 
pl.`description_short`, pl.`available_now`, pl.`available_later`, pl.`link_rewrite`, pl.`name`,
MAX(image_shop.`id_image`) id_image, il.`legend`, m.`name` manufacturer_name '.$score.', MAX(product_attribute_shop.`id_product_attribute`) id_product_attribute,
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
'.Shop::addSqlAssociation('product', 'p').'
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').'
)
LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (p.`id_product` = pa.`id_product`)
'.Shop::addSqlAssociation('product_attribute', 'pa', false, 'product_attribute_shop.`default_on` = 1').'
'.Product::sqlStock('p', 'product_attribute_shop', false, $context->shop).'
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`)'.
Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').'
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
WHERE p.`id_product` '.$product_pool.'
GROUP BY product_shop.id_product
'.($order_by ? 'ORDER BY  '.$alias.$order_by : '').($order_way ? ' '.$order_way : '').'
LIMIT '.(int)(($page_number - 1) * $page_size).','.(int)$page_size;
$result = $db->executeS($sql);

$sql = 'SELECT COUNT(*)
FROM '._DB_PREFIX_.'product p
'.Shop::addSqlAssociation('product', 'p').'
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (
p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').'
)
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
WHERE p.`id_product` '.$product_pool;
$total = $db->getValue($sql);

if (!$result)
$result_properties = false;
else
$result_properties = Product::getProductsProperties((int)$id_lang, $result);



$resultBlog = $db->ExecuteS($sqlBlog);
if(!$resultBlog)
$result_properties_blog = false;
else
foreach ($resultBlog as $row)
{
$result_properties_blog[] = $row;
}

$total += $db->getValue($sqlBlog);


return array('total' => $total,'result' => $result_properties, 'resultFromBlog' => $result_properties_blog);
}
 
  • Dans Product-list.tpl (/themes/default/product-list.tpl):
 
Modification:
 
{*
* 2007-2013 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
*  @author PrestaShop SA <[email protected]>
*  @copyright  2007-2013 PrestaShop SA
*  @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
*  International Registered Trademark & Property of PrestaShop SA
*}
{foreach from=$resultBlog item=art name=article}
                {$art.post_title}
{/foreach}

{if isset($products)}
                <!-- Products list -->
                <ul id="product_list" class="clear">
                {foreach from=$products item=product name=products}
                               <li class="ajax_block_product {if $smarty.foreach.products.first}first_item{elseif $smarty.foreach.products.last}last_item{/if} {if $smarty.foreach.products.index % 2}alternate_item{else}item{/if} clearfix">
                                               <div class="left_block">
                                                               {if isset($comparator_max_item) && $comparator_max_item}
                                                                              <p class="compare">
                                                                                              <input type="checkbox" class="comparator" id="comparator_item_{$product.id_product}" value="comparator_item_{$product.id_product}" {if isset($compareProducts) && in_array($product.id_product, $compareProducts)}checked="checked"{/if} autocomplete="off"/>
                                                                                              <label for="comparator_item_{$product.id_product}">{l s='Select to compare'}</label>
                                                                              </p>
                                                               {/if}
                                               </div>
                                               <div class="center_block">
                                                               <a href="{$product.link|escape:'htmlall':'UTF-8'}" class="product_img_link" title="{$product.name|escape:'htmlall':'UTF-8'}">
                                                                              <img src="{$link->getImageLink($product.link_rewrite, $product.id_image, 'home_default')|escape:'html'}" alt="{if !empty($product.legend)}{$product.legend|escape:'htmlall':'UTF-8'}{else}{$product.name|escape:'htmlall':'UTF-8'}{/if}" title="{if !empty($product.legend)}{$product.legend|escape:'htmlall':'UTF-8'}{else}{$product.name|escape:'htmlall':'UTF-8'}{/if}" {if isset($homeSize)} width="{$homeSize.width}" height="{$homeSize.height}"{/if} />
                                                                              {if isset($product.new) && $product.new == 1}<span class="new">{l s='New'}</span>{/if}
                                                               </a>
                                                               <h3>{if isset($product.pack_quantity) && $product.pack_quantity}{$product.pack_quantity|intval|cat:' x '}{/if}<a href="{$product.link|escape:'htmlall':'UTF-8'}" title="{$product.name|escape:'htmlall':'UTF-8'}">{$product.name|truncate:35:'...'|escape:'htmlall':'UTF-8'}</a></h3>
                                                               <p class="product_desc"><a href="{$product.link|escape:'htmlall':'UTF-8'}" title="{$product.description_short|strip_tags:'UTF-8'|truncate:360:'...'}" >{$product.description_short|strip_tags:'UTF-8'|truncate:360:'...'}</a></p>
                                               </div>
                                               <div class="right_block">
                                                               {if isset($product.on_sale) && $product.on_sale && isset($product.show_price) && $product.show_price && !$PS_CATALOG_MODE}<span class="on_sale">{l s='On sale!'}</span>
                                                               {elseif isset($product.reduction) && $product.reduction && isset($product.show_price) && $product.show_price && !$PS_CATALOG_MODE}<span class="discount">{l s='Reduced price!'}</span>{/if}
                                                               {if (!$PS_CATALOG_MODE AND ((isset($product.show_price) && $product.show_price) || (isset($product.available_for_order) && $product.available_for_order)))}
                                                               <div class="content_price">
                                                                              {if isset($product.show_price) && $product.show_price && !isset($restricted_country_mode)}<span class="price" style="display: inline;">{if !$priceDisplay}{convertPrice price=$product.price}{else}{convertPrice price=$product.price_tax_exc}{/if}</span><br />{/if}
                                                                              {if isset($product.available_for_order) && $product.available_for_order && !isset($restricted_country_mode)}<span class="availability">{if ($product.allow_oosp || $product.quantity > 0)}{l s='Available'}{elseif (isset($product.quantity_all_versions) && $product.quantity_all_versions > 0)}{l s='Product available with different options'}{else}<span class="warning_inline">{l s='Out of stock'}</span>{/if}</span>{/if}
                                                               </div>
                                                               {if isset($product.online_only) && $product.online_only}<span class="online_only">{l s='Online only'}</span>{/if}
                                                               {/if}
                                                               {if ($product.id_product_attribute == 0 || (isset($add_prod_display) && ($add_prod_display == 1))) && $product.available_for_order && !isset($restricted_country_mode) && $product.minimal_quantity <= 1 && $product.customizable != 2 && !$PS_CATALOG_MODE}
                                                                              {if ($product.allow_oosp || $product.quantity > 0)}
                                                                                              {if isset($static_token)}
                                                                                                              <a class="button ajax_add_to_cart_button exclusive" rel="ajax_id_product_{$product.id_product|intval}" href="{$link->getPageLink('cart',false, NULL, "add=1&id_product={$product.id_product|intval}&token={$static_token}", false)|escape:'html'}" title="{l s='Add to cart'}"><span></span>{l s='Add to cart'}</a>
                                                                                              {else}
                                                                                                              <a class="button ajax_add_to_cart_button exclusive" rel="ajax_id_product_{$product.id_product|intval}" href="{$link->getPageLink('cart',false, NULL, "add=1&id_product={$product.id_product|intval}", false)|escape:'html'}" title="{l s='Add to cart'}"><span></span>{l s='Add to cart'}</a>
                                                                                              {/if}                                                                                     
                                                                              {else}
                                                                                              <span class="exclusive"><span></span>{l s='Add to cart'}</span><br />
                                                                              {/if}
                                                               {/if}
                                                               <a class="button lnk_view" href="{$product.link|escape:'htmlall':'UTF-8'}" title="{l s='View'}">{l s='View'}</a>
                                               </div>
                               </li>
                {/foreach}
                </ul>
                <!-- /Products list -->
{/if}

Et voilà,

 

ça aidera peut être certain même si ce n'est pas terminé. Il faut pour bien faire, améliorer l'affichage des résultats et organiser ça selon ses besoins.

Au plaisir  :)

Edited by vinskate (see edit history)

Share this post


Link to post
Share on other sites

Si je peux me permettre humblement, n'hésites pas à utiliser les balises code pour ton "code" afin que le lecteur s'y retrouve mieux et puisse mieux voir ton travail !

 

Et sinon, merci pour le partage

  • Like 1

Share this post


Link to post
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
 Share

×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More