[V4-Statiques] Recherche (pagination + résumé)

décembre 2008 modifié dans Modifications
Bonjour

Cette version qui consomme moins de ressources mémoire :

Caractéristiques:
pagination , nombre de résultats par page configurable
création d'un résumé de l'article . configurable : sur tout ou partie d'un article , longueur du résumé

configuration
Configuration par défaut prédefinie.
Pour la modifié voir plus bas.

Mise en forme
des class sont attribuées par défauts aux diférents element du template .
voir plus bas .

L'installation :

creer une nouvelle page statique , editer la et copier/coller le code suivant dedans :
<?php
/**
 * Classe plxSearch Recherche avec résumé et pagination
 * @Pages statiques Pluxml beta 4
 * @extends plxMotor
 * @author    Griboval Cyril
 * @Stable V1
 **/
class plxSearch extends plxMotor {

function plxSearch($filename) {
parent::plxMotor($filename);
# repertoire ou sont stocké les articles
$plxGlob_arts = & new plxGlob(PLX_ROOT.$this->aConf['racine_articles']);
# masque de nom de fichier correspondant a un article publié
$this->motif = '/^[0-9]{4}.[0-9]{3}.[0-9]{12}.[a-z0-9-]+.xml$/';
#extraction de touts les noms d'articles
$this->aFiles = $this->plxGlob_arts->query($this->motif,'art',$ordre,0,999);
#nettoyage et recupération de l'url de base
$this->sUrl = $this->getsurl();
}

	/**
	 * Méthode qui retourne l'url de base de la page statique
	 * 
	 * @author	Griboval Cyrille
	 **/
		function getsUrl() {
			// decoupage de l'url  
				$geturl = explode("?", $_SERVER['REQUEST_URI']);
				/*initialisation  de la variable reconstruisant l'url */
				$redourl='';
				
			// recuperation des valeurs $_GET uniquement ( aprés le '?' )
				for($i=1;$i < count($geturl);$i++) 
					{
						$redourl .=$geturl[$i];
				    }
			
			// découpage des valeur $_GET (si '&' présent , se trouve dés la seconde clé du tableau )
				$topurl = explode("&", $redourl);	
			
			// on ne garde que la premiere valeur
				$finalurl = '?'.$topurl[0];

			// nettoyage des $_POST au passage ...
				if (!empty($_POST)) {
					plxUtils::unSlash($_POST);
				}
			
			#renvoi de l'url de base
				return $finalurl ;
		}



	/**
	 * Méthode qui elague et fait un résumé des résultats de recherche
	 * 
	 * @author	Griboval Cyrille
	 **/
  function getresume($content,$word) {
  
if (preg_match('#(?:\w+\W+){100}\w+#s' , $content , $limite)) {$content =$limite[0];}

		#création du contexte du mot recherché (extraits page) 
		#recherche de 0 à 50 caractéres avant et aprés le mot recherché
			$masque ='[(\w+|&-_.;:!\'\"\#éèçàù\s  )?]{0,50}';

			preg_match_all('#'.$masque.'('.$word.'? )'.$masque.'#', $content, $out);
			
		# on separe chaque extraits
			foreach( $out[0] as $value ) {  $resume .= ' ... '.$value.' ';}

			$resume=stripslashes($resume).' ... ';

		# ce mot peut apparaitre plusieurs fois ! 
		# (0-50 caractéres + mot recherché +0-50 caractéres ) X nb occurences = .... 
		# on limite alors le résumé a une chaine qui ne contient qu'une trentaines d'espaces
		
			if (preg_match('#(?:\w+\W+){30}\w+#s' , $resume , $regule)) {$resume =' ... '.$regule[0];}	
			
    	# Mise en evidence visuelle : engraissage et grossisement de l'occurence

			$content=preg_replace('#'.$word.'#', '<b style="font-size:110%;padding:0 1px;">'.$word.'</b>', $resume);	
		
		# renvoi du traitement 
		
			return $content;
}  


	/**
	 * Méthode qui formatte les résultats de recherche
	 * 
	 * @author	Griboval Cyrille
	 **/
function getsearch() {

$totalResult=0;
# variables de pagination
$nbPerPage =15;
$countResult = 1;
$page=1;
if ($_GET['page']) {
$page = $_GET['page'];
if (is_numeric($page)) {
		$countResult = ($_GET['page']-1)*$nbPerPage+1;
	}
}
$countEnd = $countResult + $nbPerPage - 1;
		

        if(is_array($this->aFiles)) { # Si on a des fichiers
        $nbcfiles =count($this->aFiles);
        $nbccount = 0;
        $i = 0;

	/* Recuperation et Nettoyage des mots recherché */  
        if(isset($_GET['search']))$word =$_GET['search'] ;
				# on privilégie la requete $_POST
		if(isset($_POST['search']))$word =$_POST['search'] ;

		$this->word = $word;
        $word = addslashes($word);
        $word = strtolower($word); 
	
	/* on parcours tout nos fichiers , attention ça peut-etre long */        
	while ($nbccount+1 <= $nbcfiles):
	    $file2open = PLX_ROOT.$this->aConf['racine_articles'].$this->aFiles[$nbccount];
	    $this->parseArticle($file2open);
	    $this->art =$this->parseArticle($file2open);
	    $nbccount++;
	
    /* on extrait les titre chapo et content pour y rechercher notre chaine */ 
	
            $content = $this->art['title'];
            $content .=' '.strip_tags( $this->art['chapo']).' ';
            $content .= strip_tags($this->art['content']);
            $content = addslashes($content);
            $content = strtolower($content);
            $trouve = substr_count($content,$word);
			
	/* si le terme recherché existe dans cette article */
			if($trouve!==0){ 
		
		# extraction des résultat pour la page affichée uniquement 
		if($i >= $countResult && $i<= $countEnd ) 		
			{
				#création du résume , appel de la methode getresume() 
					$content=$this->getresume($content,$word);	
				#on alimente notre tableau 
					$tableau[] = array($i,preg_replace('[^(000)|^(00)|^(0)]', '', $this->art['numero']),$this->art['title'],$this->art['url'],$content,$this->art['date'],$trouve);
				}
			# comptage des résultats positifs	
            $i++;
		
			}

			endwhile;
        }			

		/* on initialise notre variable de resultat de recherche en ouvrant une liste ordonnée */
        $search_results = '<ul class="recherche">';
		
		# nombre total des articles trouvées 
		$totalResult = $i;
		$this->total = $totalResult-1;
		
		
		
		#Mise en place de la barre de pagination 
		$pagination = '<p class="recherchePagination"> Votre Recherche : <strong>'.$word.'</strong> . '.$this->total.' résultats .</p>';
		// si total superieur au nb de resultat par page 
		if ($this->total > $nbPerPage) {
		$nbPage= ceil($this->total/$nbPerPage);
		
		// verification que la page demnadé existe 
		if (($page > $nbPage) || ($nbPage ==NULL) ) header('location: '.$this->getsUrl().'&search='.$this->word);
		$pagination = '<p class="recherchePagination"> Votre Recherche : <strong>'.$word.'</strong> . '.$this->total.' résultats  sur '.$nbPage.' Pages :</p><p class="recherchePagination"><b>Page n° </b> ';
				
    for($numpage=1;$numpage <= $nbPage;$numpage++)
     {
		if($numpage == $page) {
		$pagination .= ' : '.$numpage.' ';
		}
		else {
           $pagination .= ' : <a href="'.$this->getsUrl().'&search='.$word.'&page='.$numpage.'">'.$numpage.'</a> ';
		   }
     } 
		 $pagination .= ' : .</p>
		 ';

		}
		$search_results = $pagination.'<ul class="recherche">';		
		
        
		# compte les enregistrement gardés
		$n=count($tableau);	
		# tri inverse sur le tableau (article récents mis en avant )
		if ($tableau)rsort($tableau);		
		# puis on boucle dessus 	
        for($i=$n-1;$i >= 0;$i--) {
			
			
		#creations de liens vers les articles contenant la chaine recherchée et l'extrait
        $search_results .= '
			<li>
				<h3 class="rechercheTitle"><a href="?article'.$tableau[$i]['1'].'/'.$tableau[$i]['3'].'">'.$tableau[$i]['2'].' </a> </h3>
				<p ><span class="rechercheNumero">('.$tableau[$i]['0'].')</span><span class="rechercheNb">  Terme trouvé '.$tableau[$i]['6'].' fois. </span>
				<span class="rechercheShowDate"> Date : '.plxUtils::dateIsoToHum($tableau[$i]['5']).'</span>
				</p>
				<p class="rechercheResume">'.stripslashes($tableau[$i]['4']).'</p>
				<p class="rechercheTargetBlank" >
					<a href="?article'.$tableau[$i]['1'].'/'.$tableau[$i]['3'].'" onclick="window.open(this.href,\' _blank\');return false;" title="Oubrir dans une nouvelle page" style="font-weight:normal;font-style:italic";">( Ouvrir dans une nouvelle page  )</a> .</p>
			</li>';
        }
		/* si notre variable de resultat de recherche n'a pas changé on la remplace par un message */
         if($search_results==$pagination.'<ul class="recherche">')  {$search_results = $pagination.' <p style="display:list-item;list-style-position:inside;" class="recherche"> ... fin de la recherche</p><p class="recherche"><b>La recherche a étè infructueuse </b>, il n\'y a rien qui corresponde à vos criteres .
         <br /> <b>Verifiez l\'orthographe ou changez les mots clés. </b></p>'; }
		/* si notre variable de recherche a étè alimenté , on referme notre liste ordonnée */
         else {  
		 $search_results .= '</ul><p style="display:list-item;list-style-position:inside;" class="recherche"> ... fin de la recherche </p>'.$pagination ;
		
		 
		}
		
        return $search_results;
    }

}

?>
<div id="content">
		<div class="post">
	
	
<?php
if(!empty($_POST['search']) || !empty($_GET['search'])) {

		$search = new plxSearch((PLX_CONF));
		$search->prechauffage();
		$search->demarrage();
		$affichage =  $search->getsearch();

echo $affichage;	

	}
		/* on affiche le formulaire */
         ?>

         <form method="post" action="<?php if($search) echo $search->getsUrl(); ?>">
          <fieldset><legend ><?php
		  if ($search->word)  echo'  Faire une nouvelle recherche en changeant le(s) mot(s) clé(s).';
		  else echo 'Faire une recherche .';
		  ?></legend>
            <p><input name="search" size="15" maxlength=\"255\" value="<?php
		    echo $search->word; 
		  ?>" type="text" class="search" /> <b> >> </b> <input type="submit" value="rechercher !" /></p>
          </fieldset>
		  
        </form> 
		<?php if ($search->total > 5) echo '<a href="#top" title="haut de page">haut de page</a>'; ?>
		</div>
</div>
enregistrer , verifier que votre page est "active" .
Ne reste plus qu'a repasser coté public et tester votre page de recherche .

remarques

Pour créer cette page statique , il est préférable de copier coller le code dans l'administration , cela vous assure un encodage compatible avec votre version et configuration de pluxml .
(pensez y si vous éditer en local , migrer ou changer de config d'encodage).



Template et mise en forme :
Comme Indiqué par Sapin Tremblant , vous pouvez insérer le formulaire dans votre template .
Pour cela il vous faut au préalable créer cette page statique et récupérer son lien .
Le formulaire de base est :
<div id="recherche">
<h2>Recherche</h2>
<form method="post" action=" ICI LE LIEN VERS VOTRE PAGE STATIQUE DE RECHERCHE" class="formSearch">
<p>
<input type="text"  name="search" />
<input type="submit" value="OK" />
</p>
</form>
Vous pouvez ciblé ce formulaire coté CSS avec #recherche pour la boite , ou .formSearch juste pour le formulaire .

Pour la mise en forme des résultat de recherche :

Ils sont stockée dans une liste , que vous pouvez ciblée comme ceci :
ul.recherche {/* vos regles css */}
Le titre lien du nom de l'article trouvé:
h3.rechercheTitle a {/* vos regles css */}
Le paragraphe qui contient le nombre d'occurrences et la date de l'article:
ul p.recherche {/* vos regles css */}
Le nombre d'occurences :
span.rechercheNb {/* vos règles css */}
la date de l'article :
span.rechercheShowDate {/* vos règles css */}
Le resumé de l'article
p.rechercheResume  {/* vos règles css */}
et enfin le lien pour ouvrir dans une nouvelle fenêtre :
p.rechercheTargetBlank {/* vos règles css */}
Pour la barre de pagination :
p.recherchePagination{/* vos règles css */}
Pour les liens de la barre de pagination :
p.recherchePagination a {/* vos règles css */}
Modifier la taille du résumé :

Le résumé est effectué en deux étapes .
1)
ajout des 50 caractéres maximum se trouvant a gauche et a droite de chaque occurrence dans chaque article
Pour modifier cela :
dans la variable $masque
#recherche de 0 à 50 caractères avant et après le mot recherché
			$masque ='[(\w+|&-_.;:!\'\"\#éèçàù\s  )?]{0,50}';
Modifier la valeur qui est par défaut de 50 (entre les accolades : {0,50})

2)
regulation a 30 espaces (31 mots ou ponctuation)
Ce qui fait a peu prés 3 lignes dans le template par défaut de pluxml.
Pour modifier cela
# on limite alors le résumé a une chaine qui ne contient qu'une trentaines d'espaces
		
			if (preg_match('#(?:\w+\W+){30}\w+#s' , $resume , $regule)) {$resume =' ... '.$regule[0];}
Modifier la valeur qui est par defaut de 30 (entre les accolades).

coté php : Template et accés au differentes infos dispos :

Ce qui correspond au template d'affichage des résultat :
$search_results .= '
			<li>
				<h3 class="rechercheTitle"><a href="?article'.$tableau[$i]['1'].'/'.$tableau[$i]['3'].'">'.$tableau[$i]['2'].' </a> </h3>
				<p ><span class="rechercheNumero">('.$tableau[$i]['0'].')</span><span class="rechercheNb">  Terme trouvé '.$tableau[$i]['6'].' fois. </span>
				<span class="rechercheShowDate"> Date : '.plxUtils::dateIsoToHum($tableau[$i]['5']).'</span>
				</p>
				<p class="rechercheResume">'.stripslashes($tableau[$i]['4']).'</p>
				<p class="rechercheTargetBlank" >
					<a href="?article'.$tableau[$i]['1'].'/'.$tableau[$i]['3'].'" onclick="window.open(this.href,\' _blank\');return false;" title="Oubrir dans une nouvelle page" style="font-weight:normal;font-style:italic";">( Ouvrir dans une nouvelle page  )</a> .</p>
			</li>';
Les differents contenus ou variables affichable sont donc :
$tableau[$i] = résultat de recherche N° .
$tableau[$i] = N° de l'article .
$tableau[$i] = titre de l'article .
$tableau[$i] = non au format 'url' de l'article
stripslashes($tableau[$i]) = contenu du résumé
plxUtils::dateIsoToHum($tableau[$i]) = date de l'article au format de date de pluxml
$tableau[$i] = nombre de fois que le terme recherché est trouvé dans l'article

Seul ces 3 variables ...
$tableau[$i] = N° de l'article .
$tableau[$i] = titre de l'article .
$tableau[$i] = non au format 'url' de l'article

.... sont obligatoire , car elle permettent de reconstruire le lien et son libéllé vers l'article qui correspond a une recherche .
<a href="?article'.$tableau[$i]['1'].'/'.$tableau[$i]['3'].'">'.$tableau[$i]['2'].' </a>
Votre serveur vous renvoi un message d'erreur :
'pas assez de mémoire ' , ou temps d'exécution dépassé


2 possibilitées peuvent être utilisées conjointement :

1 :
Décommenter cette ligne dans la methode : getresume()
// if (preg_match('#(?:\w+\W+){100}\w+#s' , $content , $limite)) {$content =$limite[0];}
Pour decommenter , ou si vous préferez 'activé' cette ligne retire les : // en debut de ligne .
La valeur 100 peut-etre encore descendu .
Cela correspond a ne créer le résumé approximativement a partir des 10 premieres lignes de l'articles.

1bis (voir aussi plus haut : 'modifier la taille du résumé')

2 :
Vous pouvez diminuer le nombre de résultat par page en modifiant la valeur par défaut 15 indiqué dans :
# variables de pagination
$nbPerPage =15;
Si cela ne suffit pas , c'est que vos articles sont vraiment trop long :) .

En cas de temps d'exécution dépassé , essayé a nouveau aux heures de faible affluence , il se peut que votre serveur ne dispose plus assez de ressources a certaines heures de la journée ( hébergement mutualisé) .

GC


P.S.
Ouvrez un nouveau topic si vous rencontrez des problemes specifiques
- aprés modification de ce formulaire de recherche
- avec un hebergeur (fournissez , log , message d'erreur , adresse du site , ...)
- proposez une modification
- etc ...

En actions ici par exemple sur un pluxml de test :
http://re7net.com/pluxml/?static2/recherchepaginer


Cordialement,
gcyrillus , simple membre du forum et utilisateur de pluxml

Mon site PluXml: https://re7net.com | Plugins: https://ressources.pluxopolis.net/banque-plugins/index.php?all_versions | demos sur free http://gcyrillus.free.fr/new | Thèmes: tester et télécharger @ https://pluxthemes.com
Indiquez [RESOLU] dans le titre de votre question une fois le soucis réglè, Merci

Réponses

  • Bonsoir,

    J'ai inséré le code comme c'est indiqué et j'ai une erreur. J'utilise la version 5 de Pluxml et je fais le test en local pour l'instant.

    Fatal error: Call to undefined method plxMotor::plxMotor() in D:\Sites internet\Localhost\Simius 2\data\statiques\013.recherche.php on line 12
    
    Quel est le problème ?


    Merci d'avance
  • Bonjour,

    Cette version du moteur de recherche est incompatible avec la version 5 (qui tourne entre autre sous php5 )

    - parties du code depreciées
    - nom des fonctions ou fonctions différentes .

    Je n'ai pas encore vraiment parcouru le code de pluxml5 pour me faire une idée de comment reprendre au mieux cette idée de resumé et de pagination sur les resultats de recherche .

    Il y a de nouveau éléments ou filtre eventuellement a incorporés ou prendre en compte (les tags et les archives par exemple ), sans trop plomber les temps d'execution.

    GC


    Cordialement,
    gcyrillus , simple membre du forum et utilisateur de pluxml

    Mon site PluXml: https://re7net.com | Plugins: https://ressources.pluxopolis.net/banque-plugins/index.php?all_versions | demos sur free http://gcyrillus.free.fr/new | Thèmes: tester et télécharger @ https://pluxthemes.com
    Indiquez [RESOLU] dans le titre de votre question une fois le soucis réglè, Merci

Connectez-vous ou Inscrivez-vous pour répondre.