vinskate Posted February 21, 2014 Share Posted February 21, 2014 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 Link to comment Share on other sites More sharing options...
vinskate Posted February 21, 2014 Author Share Posted February 21, 2014 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é. Link to comment Share on other sites More sharing options...
vinskate Posted February 24, 2014 Author Share Posted February 24, 2014 (edited) 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 February 24, 2014 by vinskate (see edit history) Link to comment Share on other sites More sharing options...
SleT Posted February 24, 2014 Share Posted February 24, 2014 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 1 Link to comment Share on other sites More sharing options...
vinskate Posted February 24, 2014 Author Share Posted February 24, 2014 Oufff, ce forum n'est pas mort Je commençais à me demander quoi, j'te remercie du conseil, je ne suis pas un habitué des forums, je fais ça de suite! Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now