Jump to content

Recherche rapide et page CMS


Recommended Posts

  • 2 months later...

Bonjour,

 

Non, rien. Du coup nous avons eut plusieurs idée, mais des dev assez lourds... Donc nous avons orienté le client sur la création de pages produits avec un indicateur qui précise que ce dernier est une page de contenu et n'affiche pas certaines informations, de ce fait les pages sont indexés par la recherche...

Mais bon je trouve que c'est une très très grosse lacune !

 

Bon courage,

Link to comment
Share on other sites

  • 1 month later...
  • 3 months later...
  • 1 month later...

Je cherche aussi une solution, mais apres avoir regardé le code, ca semble plutot lourd à faire.. et délicat à réaliser en module.. Il me semble ? ou alors il faudrait dupliquer completement les fonctions du coeur de prestashop et les modifier ?

Deja modifier le moteur d'indexation pour qu'il fasse le meme boulot avec les pages du CMS qu'avec les produits.. et refaire le code de la recherche pour retourner les deux types de contenu.. ?

Link to comment
Share on other sites

  • 4 months later...
  • 4 months later...

En vrai ce n'est pas bien compliqué, un simple override de la classe search.php et du controller cms, petite modification du fichier template, et le tour est joué. Je viens de le faire, ça m'a pris 20 min, alors courage, il faut mettre les mains dans le cambouis !

Pour ceux qui sont intéressés et qui ne sont pas développeurs, demandez moi par mp je vous fournirai les fichiers. C'est mieux que de payer un module qui fait beaucoup plus que ce qu'on a besoin ;)

Link to comment
Share on other sites

  • 2 weeks later...

Bonjour,

 

Web-M à quel moment as-tu eu besoin de toucher à la classe CMSController ? Toute la partie technique ne peut-elle pas être gérée dans l'override de la classe Search.php ? Je me lance dans cette modif qui me semblait déjà indispensable depuis bien longtemps. Il est clair qu'un visiteur va faire une recherche plutôt que chercher la page (aussi bien mise en valeur soit-elle dans l'interface) où trouver l'information qu'il recherche.

 

Merci à toi.

Link to comment
Share on other sites

  • 3 weeks later...

Bonjour,

 

oNine, j'ai fait un override du CMScontroller pour traiter directement la requête dans le controller et pour bien séparer le formulaire de recherche à destination des pages CMS du formulaire de recherche pour les produits.

 

@Switchboard, exemple pour une recherche dans les pages CMS (on peut affiner encore plus à quelle page faire la recherche en spécifiant l'ID de la catégorie CMS ou même de la page).

Pour une recherche sur tout le site, c'est le même principe, tout se joue dans la requête SQL, il faut simplement ajouter toutes les tables qui contiennent des données où l'on souhaite pouvoir rechercher du contenu.

 

/override/controllers/CMSController.php

class CmsController extends CmsControllerCore
{
 public function process()
 {
parent::process();
$search_query_faq = Tools::getValue('search_query_faq');
if($search_query_faq)
{
   $this->n = abs((int)(Tools::getValue('n', Configuration::get('PS_PRODUCTS_PER_PAGE'))));
   $this->p = abs((int)(Tools::getValue('p', 1)));
   $result = Search::searchCMS((int)(self::$cookie->id_lang), $search_query_faq, false,	 $this->p, $this->n, 'position', 'desc');
   $nb_result = ($result) ? count($result) : 0;

   self::$smarty->assign(array(
	  'nb_result' => $nb_result,
	  'result' => $result,
   ));
}
 }
}

 

/override/classes/Search.php

class Search extends SearchCore
{
public static function searchCMS($id_lang, $query, $count = false, $pageNumber = 0, $pageSize = 10, $orderBy = false, $orderWay = false)
{
	 global $cookie;

	if (!is_numeric($pageNumber) OR !is_numeric($pageSize) OR !Validate::isBool($count) OR !Validate::isValidSearch($query)
	OR $orderBy AND !$orderWay OR ($orderBy AND !Validate::isOrderBy($orderBy))	OR ($orderWay AND !Validate::isOrderBy($orderWay)))
		return false;

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

	$words = explode(" ", $query);
	$where = '
	WHERE cms.`active` = 1
	AND l.id_lang = '.(int)($id_lang).'
	';
	reset($words);
	while(list($key, $data) = each($words))
	{
		$where .= " AND l.`content` LIKE '%" . pSQL($data) . "%' ";  
	}

	$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
	SELECT DISTINCT cms.*, l.*
	FROM `'._DB_PREFIX_.'cms` cms
	JOIN `'._DB_PREFIX_.'cms_lang` l ON (cms.id_cms = l.id_cms)
	'.$where.'
	ORDER BY position DESC'.($orderBy ? ', '.$orderBy : '').($orderWay ? ' '.$orderWay : '').'
	LIMIT '.(int)(($pageNumber - 1) * $pageSize).','.(int)$pageSize);
	if (!$result) return false;

	return $result;
}
}

 

Et enfin un exemple de comment je l'utilise pour une page FAQ :

 

/themes/MON_THEME/cms.tpl

{if isset($cms) && $cms->id != $cgv_id}
{include file="$tpl_dir./breadcrumb.tpl"}
{/if}
{if isset($cms) && !isset($category)}
{if !$cms->active}
	<br />
	<div id="admin-action-cms">
		<p>{l s='This CMS page is not visible to your customers.'}
		<input type="hidden" id="admin-action-cms-id" value="{$cms->id}" />
		<input type="submit" value="{l s='Publish'}" class="exclusive" onclick="submitPublishCMS('{$base_dir}{$smarty.get.ad}', 0)"/>			
		<input type="submit" value="{l s='Back'}" class="exclusive" onclick="submitPublishCMS('{$base_dir}{$smarty.get.ad}', 1)"/>			
		</p>
		<div class="clear" ></div>
		<p id="admin-action-result"></p>
		</p>
	</div>
{/if}
<div class="rte{if $content_only} content_only{/if}">
	{$cms->content}
</div>
{elseif isset($category)}
<div>
	<h1>{$category->name|escape:'htmlall':'UTF-8'}</h1>
  	 {if $category->id == 3}
	<form id="searchboxfaq" action="#" method="post">
		<p>
			<label for="search_query_faq">{l s='Rechercher dans la FAQ'}</label>
		</p>
		<div style="clear:both;"></div>
		<p>
			<input type="hidden" value="position" name="orderby">
			<input type="hidden" value="desc" name="orderway">
			<input id="search_query_faq" class="search_query ac_input" type="text" value="" name="search_query_faq" autocomplete="off">
			<input class="button" type="submit" value="Rechercher" name="submit_search_faq">
		</p>
	</form>
	{/if}

	{if isset($nb_result)}

		{if $nb_result > 0}
			<p>{$nb_result} {l s='résultat(s) trouvé(s).'}</p>
			<ul class="bullet">
				{foreach from=$result item=cmspages}
					<li>
						<a href="{$link->getCMSLink($cmspages.id_cms, $cmspages.link_rewrite)|escape:'htmlall':'UTF-8'}">{$cmspages.meta_title|escape:'htmlall':'UTF-8'}</a>
					</li>
				{/foreach}
			</ul>
		{else}
			<p>{l s='Nous n\'avons trouvé aucun résultat pour votre recherche.'}</p>
		{/if}

	{else}

		{if isset($sub_category) & !empty($sub_category)}	
			<h4>{l s='List of sub categories in '}{$category->name}{l s=':'}</h4>
			<ul class="bullet">
				{foreach from=$sub_category item=subcategory}
					<li>
						<a href="{$link->getCMSCategoryLink($subcategory.id_cms_category, $subcategory.link_rewrite)|escape:'htmlall':'UTF-8'}">{$subcategory.name|escape:'htmlall':'UTF-8'}</a>
					</li>
				{/foreach}
			</ul>
		{/if}
		{if isset($cms_pages) & !empty($cms_pages)}
		<h4>{l s='List of pages in '}{$category->name}{l s=':'}</h4>
			<ul class="bullet">
				{foreach from=$cms_pages item=cmspages}
					<li>
						<a href="{$link->getCMSLink($cmspages.id_cms, $cmspages.link_rewrite)|escape:'htmlall':'UTF-8'}">{$cmspages.meta_title|escape:'htmlall':'UTF-8'}</a>
					</li>
				{/foreach}
			</ul>
		{/if}

	{/if}


</div>
{else}
{l s='This page does not exist.'}
{/if}

Link to comment
Share on other sites

  • 3 months later...

J'ai essayer la marche à suivre de Web-M:

 

1. crée un override de CMScontroller

2. crée un override de Search.php

3. modifier cms.tpl

 

Cependant n'était pas super à l'aise avec smarty, que dois-je modifier concrètement pour rechercher sur tous les pages CMS, et sur lequel de ces fichiers?

 

Pour une recherche sur tout le site, c'est le même principe, tout se joue dans la requête SQL, il faut simplement ajouter toutes les tables qui contiennent des données où l'on souhaite pouvoir rechercher du contenu.
Link to comment
Share on other sites

  • 7 months later...
  • 1 year later...

Bonjour,

 

Ce sujet est il traité dans un autre post pour la version 1.6 ?

avez-vous une solution pour indexer les catégories au bloc recherche rapide ?

ou sinon, est il possible de remplacer la recherche sur un produit par une recherche dans les catégories ?

 

Merci

Link to comment
Share on other sites

  • 2 months later...

Bonjour,

 

Ce sujet est il traité dans un autre post pour la version 1.6 ?

avez-vous une solution pour indexer les catégories au bloc recherche rapide ?

ou sinon, est il possible de remplacer la recherche sur un produit par une recherche dans les catégories ?

 

Merci

Bonjour, avez-vous trouvé la solution pour indexer les catégories au bloc recherche rapide ?

 

Cordialement,

Link to comment
Share on other sites

  • 4 years later...

Bonjour,

Cet article de 2015 est encore d'actualité, je viens d’implémenter cette modif sur un site en 1.6.1.24 pour proposer une base de connaissance. Merci pour  Web-M.

Dans un soucis de partage, si vous souhaitez que la recherche s'effectue aussi dans le contenu des catégories CMS, voici ce qu'il faut modifier au code proposé par Web-M :

1/dans l'override du Searchcontroller, il faut exécuter deux fois la fonction searchCMS, avec un paramètre de plus ("cms" ou "cms_catgory), et retourner deux tableaux de résultats comme ceci :

public function process()
	{
		parent::process();
		$search_query_faq = Tools::getValue('search_query_faq');

		if($search_query_faq){
			$this->n = abs((int)(Tools::getValue('n', Configuration::get('PS_PRODUCTS_PER_PAGE'))));
			$this->p = abs((int)(Tools::getValue('p', 1)));
			
			$result_cms = Search::searchCMS((int)(self::$cookie->id_lang), $search_query_faq, "cms",false,	 $this->p, $this->n, 'position', 'desc');	
			$nb_result_cms = ($result_cms) ? count($result_cms) : 0;
			
			$result_cms_category = Search::searchCMS((int)(self::$cookie->id_lang), $search_query_faq, "cms_category",false,	 $this->p, $this->n, 'position', 'desc');
			$nb_result_cms_category = ($result_cms_category) ? count($result_cms_category) : 0;
			
			//$nb_result=$nb_result_cms+$nb_result_cms_category;
			//$result=array_merge($result_cms,$result_cms_category);
				
			self::$smarty->assign(array(
				//'nb_result' => $nb_result,
				//'result' => $result,
				'nb_result_cms' => $nb_result_cms,
				'result_cms' => $result_cms,
				'nb_result_cms_category' => $nb_result_cms_category,
				'result_cms_category' => $result_cms_category,
			));
		}
	 
	}

 

Pour le Search.PHP, il faut modifier le code pour traiter ce paramètre supplémentaire et selon sa valeur, chercher dans les tables cms ou cms_category. On aurait pu faire deux routines par copier coller, j'ai préféré paramétrer le code avec la variable $table dans la requete sql, qui vaut soit cms, soit cms_category.

A noter que j'ai également modifié ce code pour rechercher non seulement dans le champ "content" (ou "description" pour les catégories, mais également dans les champs "name" et "summary", des champs que j'ai ajouté aux 2 classes. Re-simplifiez le code si vous n'avez pas ces champs :

<?php

class Search extends SearchCore
{
	public static function searchCMS($id_lang, $query, $table, $count = false, $pageNumber = 0, $pageSize = 10, $orderBy = false, $orderWay = false)
	{
		 global $cookie;

		if (!is_numeric($pageNumber) OR !is_numeric($pageSize) OR !Validate::isBool($count) OR !Validate::isValidSearch($query)
		OR $orderBy AND !$orderWay OR ($orderBy AND !Validate::isOrderBy($orderBy))	OR ($orderWay AND !Validate::isOrderBy($orderWay)))
			return false;

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

		$words = explode(" ", $query);
		$where = '
		WHERE cms.`active` = 1
		AND l.id_lang = '.(int)($id_lang).'
		 AND ((1=1 ';
		reset($words);
		if($table=="cms_category"){
			while(list($key, $data) = each($words))
			{
				$where .= " AND l.`description` LIKE '%" . pSQL($data) . "%' ";  
			}
		}
		else
		{
			while(list($key, $data) = each($words))
			{
				$where .= " AND l.`content` LIKE '%" . pSQL($data) . "%' ";  
			}
		}
		reset($words);
		$where .= ") OR (1=1";
		while(list($key, $data) = each($words))
		{
			$where .= " AND l.`summary` LIKE '%" . pSQL($data) . "%' ";  
		}
		reset($words);
		$where .= ") OR (1=1";
		while(list($key, $data) = each($words))
		{
			$where .= " AND l.`meta_keywords` LIKE '%" . pSQL($data) . "%' ";  
		}
		reset($words);
		$where .= ") OR (1=1";
		while(list($key, $data) = each($words))
		{
			$where .= " AND l.`name` LIKE '%" . pSQL($data) . "%' ";  
		}
		$where .= "))";
		
		$search_query='
		SELECT DISTINCT cms.*, l.*
		FROM `'._DB_PREFIX_.$table.'` cms
		JOIN `'._DB_PREFIX_.$table.'_lang` l ON (cms.id_'.$table.' = l.id_'.$table.')'.$where.'
		ORDER BY position DESC'.($orderBy ? ', '.$orderBy : '').($orderWay ? ' '.$orderWay : '').'
		LIMIT '.(int)(($pageNumber - 1) * $pageSize).','.(int)$pageSize;
		
		$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($search_query);
		
		
		if (!$result) return false;

		return $result;
	}
	
	
}

?>

 

Et enfin, au niveau du theme (tpl), il faut mettre deux blocs d'affichages, un pour les produits trouvés un autre pour les catégories :

<form id="searchboxfaq" action="#" method="post">
			<p>
				<label for="search_query_faq">{l s='Rechercher dans la FAQ'}</label>
			</p>
			<div style="clear:both;"></div>
			<p>
				<input type="hidden" value="position" name="orderby">
				<input type="hidden" value="desc" name="orderway">
				<input id="search_query_faq" class="search_query ac_input" type="text" value="" name="search_query_faq" autocomplete="off">
				<input class="button" type="submit" value="Rechercher" name="submit_search_faq">
			</p>
		</form>

		{if isset($nb_result_cms_category)}

			{if $nb_result_cms_category > 0}
				<p>{$nb_result_cms_category} {l s='category(ies) found.'}</p>
				<ul class="bullet">
					{foreach from=$result_cms_category item=cmscategory}
						<li>
							<a href="{$link->getCMSCategoryLink($cmscategory.id_cms_category, $cmscategory.link_rewrite)|escape:'htmlall':'UTF-8'}">{$cmscategory.name|escape:'htmlall':'UTF-8'}</a>
						</li>
					{/foreach}
				</ul>
			{else}
				<p>{l s='We found no category matching your query'}</p>
			{/if}
		{/if}
		{if isset($nb_result_cms)}

			{if $nb_result_cms > 0}
				<p>{$nb_result_cms} {l s='article(s) found.'}</p>
				<ul class="bullet">
					{foreach from=$result_cms item=cmspage}
						<li>
							<a href="{$link->getCMSLink($cmspage.id_cms, $cmspage.link_rewrite)|escape:'htmlall':'UTF-8'}">{$cmspage.name|escape:'htmlall':'UTF-8'}</a>
						</li>
					{/foreach}
				</ul>
			{else}
				<p>{l s='We found no article matching your query'}</p>
			{/if}
		{/if}

Ce qui donne qcq chose comme cela (il faudra adapter le CSS), car c'est moche en l'état, mais ça fonctionne :

image.png.ae29c3bcfa402aa55a06d2df98e84188.png

 

Bon codage...

Crdlt

Franck

Edited by SITOLOG - F Bugnet (see edit history)
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...