J3.x

Création d'un plugin de recherche

From Joomla! Documentation

This page is a translated version of the page J3.x:Creating a search plugin and the translation is 100% complete.

Other languages:
English • ‎español • ‎français • ‎Nederlands
Joomla! 
3.x
série

Description

Ce document aborde la façon de créer un plugin de recherche. Vous pouvez utiliser un plugin de recherche afin de faire des recherches par le biais de la base de données de votre site Joomla. Pour créer un plugin, vous aurez besoin d'au moins deux fichiers ; un fichier XML et un fichier PHP. Pour l'internationalisation, il est conseillé de créer également un fichier INI.

Fichier XML

Le fichier XML porte le même nom que le fichier PHP, et est un des deux fichiers requis. Commencez toujours par la balise XML, et définissez-la au format UTF-8.

<?xml version="1.0" encoding="utf-8"?>

Pour indiquer que ce plugin est un plugin de recherche, ajoutez cette ligne :

<extension version="3.1" type="plugin" group="search">

'Type' permet d'indiquer que c'est un plugin, et 'group' indique que le plugin fait partie du groupe des plugins de recherche.

Après cela, ajoutez des informations à propos de vous et du plugin :

<name>Name of your search plugin</name>
<creationDate>Creation date</creationDate>
<author>Your name</author>
<authorEmail>Your e-mail address</authorEmail>
<authorUrl>Your website</authorUrl>
<copyright>Copyright information</copyright>
<license>License, for example GNU/GPL</license>
<version>Version of the plugin</version>
<description>Description of the plugin; shown during installation and when editing 
the plugin in the Plugin Manager</description>

Maintenant, ajoutez votre fichier PHP au plugin de recherche. Le nom de ce fichier doit être le même que celui du fichier XML. Indiquez ce nom après la partie plugin=""

Vous pouvez également ajouter d'autres fichiers à votre plugin, par exemple, une image. Il suffit d'ajouter une ligne entre <files> et </files>, puis de placer le fichier entre des balises <filename>.

<files>
   <filename plugin="nameofplugin">nameofplugin.php</filename>
</files>

Pour l'internationalisation, nous allons utiliser des fichiers de langue. Ce n'est pas obligatoire, mais les personnes d'autres pays apprécieront de pouvoir traduire facilement votre plugin dans leur propre langue. Les codes de langue sont listés ici (utiliser la colonne ISO 639-1) et les codes pays ici

<languages>
   <language tag="en-GB">language/en-GB/en-GB.plg_search_nameofplugin.ini</language>
</languages>

Vous pouvez également ajouter optionnellement des paramètres au plugin. Ils ressembleront à cela :

	<config>
		<fields name="params">

			<fieldset name="basic">
				<field name="search_limit" type="text"
					default="50"
					description="JFIELD_PLG_SEARCH_SEARCHLIMIT_DESC"
					label="JFIELD_PLG_SEARCH_SEARCHLIMIT_LABEL"
					size="5"
				/>

				<field name="search_content" type="radio"
					default="0"
					description="JFIELD_PLG_SEARCH_ALL_DESC"
					label="JFIELD_PLG_SEARCH_ALL_LABEL"
				>
					<option value="0">JOFF</option>
					<option value="1">JON</option>
				</field>

			</fieldset>
		</fields>
	</config>

N'oubliez pas de terminer votre fichier XML avec la balise suivante :

</extension>

Fichier PHP

Le fichier PHP de votre plugin est le fichier le plus important du plugin. Voici un exemple de fichier PHP pour un plugin de recherche. Les commentaires sont inclus.

<?php
//First start with information about the Plugin and yourself. For example:
/**
 * @package     Joomla.Plugin
 * @subpackage  Search.nameofplugin
 *
 * @copyright   Copyright
 * @license     License, for example GNU/GPL
 */

//To prevent accessing the document directly, enter this code:
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );

// Require the component's router file (Replace 'nameofcomponent' with the component your providing the search for
require_once JPATH_SITE .  '/components/nameofcomponent/helpers/route.php';

/**
 * All functions need to get wrapped in a class
 *
 * The class name should start with 'PlgSearch' followed by the name of the plugin. Joomla calls the class based on the name of the plugin, so it is very important that they match
 */
class PlgSearchNameofplugin extends JPlugin
{
	/**
	 * Constructor
	 *
	 * @access      protected
	 * @param       object  $subject The object to observe
	 * @param       array   $config  An array that holds the plugin configuration
	 * @since       1.6
	 */
	public function __construct(& $subject, $config)
	{
		parent::__construct($subject, $config);
		$this->loadLanguage();
	}

	// Define a function to return an array of search areas. Replace 'nameofplugin' with the name of your plugin.
	// Note the value of the array key is normally a language string
	function onContentSearchAreas()
	{
		static $areas = array(
			'nameofplugin' => 'Nameofplugin'
		);
		return $areas;
	}

	// The real function has to be created. The database connection should be made. 
	// The function will be closed with an } at the end of the file.
	/**
	 * The sql must return the following fields that are used in a common display
	 * routine: href, title, section, created, text, browsernav
	 *
	 * @param string Target search string
	 * @param string mathcing option, exact|any|all
	 * @param string ordering option, newest|oldest|popular|alpha|category
	 * @param mixed An array if the search it to be restricted to areas, null if search all
	 */
	function onContentSearch( $text, $phrase='', $ordering='', $areas=null )
	{
		$user	= JFactory::getUser(); 
		$groups	= implode(',', $user->getAuthorisedViewLevels());

		// If the array is not correct, return it:
		if (is_array( $areas )) {
			if (!array_intersect( $areas, array_keys( $this->onContentSearchAreas() ) )) {
				return array();
			}
		}

		// Now retrieve the plugin parameters like this:
		$nameofparameter = $this->params->get('nameofparameter', defaultsetting );

		// Use the PHP function trim to delete spaces in front of or at the back of the searching terms
		$text = trim( $text );

		// Return Array when nothing was filled in.
		if ($text == '') {
			return array();
		}

		// After this, you have to add the database part. This will be the most difficult part, because this changes per situation.
		// In the coding examples later on you will find some of the examples used by Joomla! 3.1 core Search Plugins.
		//It will look something like this.
		$wheres = array();
		switch ($phrase) {

			// Search exact
			case 'exact':
				$text		= $this->db->Quote( '%'.$this->db->escape( $text, true ).'%', false );
				$wheres2 	= array();
				$wheres2[] 	= 'LOWER(a.name) LIKE '.$text;
				$where 		= '(' . implode( ') OR (', $wheres2 ) . ')';
				break;

			// Search all or any
			case 'all':
			case 'any':

			// Set default
			default:
				$words 	= explode( ' ', $text );
				$wheres = array();
				foreach ($words as $word)
				{
					$word		= $this->db->Quote( '%'.$this->db->escape( $word, true ).'%', false );
					$wheres2 	= array();
					$wheres2[] 	= 'LOWER(a.name) LIKE '.$word;
					$wheres[] 	= implode( ' OR ', $wheres2 );
				}
				$where = '(' . implode( ($phrase == 'all' ? ') AND (' : ') OR ('), $wheres ) . ')';
				break;
		}

		// Ordering of the results
		switch ( $ordering ) {

			//Alphabetic, ascending
			case 'alpha':
				$order = 'a.name ASC';
				break;

			// Oldest first
			case 'oldest':

			// Popular first
			case 'popular':

			// Newest first
			case 'newest':

			// Default setting: alphabetic, ascending
			default:
				$order = 'a.name ASC';
		}

		// Replace nameofplugin
		$section = JText::_( 'Nameofplugin' );

		// The database query; differs per situation! It will look something like this (example from newsfeed search plugin):
		$query	= $this->db->getQuery(true);
		$query->select('a.name AS title, "" AS created, a.link AS text, ' . $case_when."," . $case_when1);
				$query->select($query->concatenate(array($this->db->Quote($section), 'c.title'), " / ").' AS section');
				$query->select('"1" AS browsernav');
				$query->from('#__nameofcomponent AS a');
				$query->innerJoin('#__categories as c ON c.id = a.catid');
				$query->where('('. $where .')' . 'AND a.published IN ('.implode(',', $state).') AND c.published = 1 AND c.access IN ('. $groups .')');
				$query->order($order);

		// Set query
		$this->db->setQuery( $query, 0, $limit );
		$rows = $this->db->loadObjectList();

		// The 'output' of the displayed link. Again a demonstration from the newsfeed search plugin
		foreach($rows as $key => $row) {
			$rows[$key]->href = 'index.php?option=com_newsfeeds&view=newsfeed&catid='.$row->catslug.'&id='.$row->slug;
		}

	//Return the search results in an array
	return $rows;
	}
}

Quatre variables sont passées. Elles sont évidentes du fait de leurs noms et utilisées dans le code ci-dessus. Ce qui moins évident est ce que la fonction doit retourner : un array d'objets que l'outil de recherche utilise pour afficher les résultats. Les résultats pourraient alternativement avoir été assemblés comme suit :

$rows[] = (object) array(
			'href'        => 'index.php?option=com_newsfeeds&view=newsfeed&catid='.$row->catslug.'&id='.$row->slug,
			'title'       => $row['name'],
			'section'     => $nameofcomponent,
			'created'     => $row['date'],
			'text'        => $row['name'],
			'browsernav'  => '1'
		);

Fichier(s) INI

Il est bon pour l'internationalisation d'utiliser des fichiers INI. Vous pouvez tout ajouter au fichier langue qui affichera le texte à l'utilisateur, dans cet ordre :

  • balise de description XML
  • attributs d'intitulé et de description des paramètres
  • JText::_( 'chaine' ) utilisé par le plugin

Commencez votre fichier INI avec quelque chose comme ceci :

# $Id: en-GB.plg_search_nameofplugin.ini
# Joomla! Project
# Copyright (C) 2005 - 2007 Open Source Matters. All rights reserved.
# License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE.php
# Note : All ini files need to be saved as UTF-8 - No BOM

Bien sûr, vous pouvez également ajouter d'autres informations, comme l'auteur.

Par exemple, ce paramètre :

<field name="search_limit" type="text"
  default="50"
  description="JFIELD_PLG_SEARCH_SEARCHLIMIT_DESC"
  label="JFIELD_PLG_SEARCH_SEARCHLIMIT_LABEL"
  size="5"
/>

Ce qui va provoquer la sortie suivante dans le fichier INI :

JFIELD_PLG_SEARCH_SEARCHLIMIT_DESC=Search Limit
JFIELD_PLG_SEARCH_SEARCHLIMIT_LABEL=Number of Search items to return

Le fichier semble répétitif, mais cela sera très utile aux traducteurs.

Lorsque vous souhaitez que votre plugin de recherche soit disponible dans d'autres langues, ajoutez-les au préalable à la balise languages du fichier XML. Puis créez le même fichier INI et modifiez la partie située après le =. Par exemple la version néerlandaise devrait être :

JFIELD_PLG_SEARCH_SEARCHLIMIT_DESC=Zoek limiet
JFIELD_PLG_SEARCH_SEARCHLIMIT_LABEL=Aantal weer te geven zoekresultaten

Astuces

  • Dans le fichier PHP, on oublie souvent de mettre un point virgule (;) à la fin d'une ligne. Ce qui engendre des erreurs. Faites une vérification avant de tester votre plugin.
  • Assurez-vos que les paramètres dans le fichier XML sont fermés correctement. Lorsque vous ajoutez une option, par exemple, il vous faut la fermer avec </param>.
  • Il est simple de faire des tests sur un environnement local lorsque vous modifiez votre plugin.
  • Lorsque vous créez votre fichier zip, n'oubliez pas de faire les répertoires pour les fichiers de langue. Un dossier zippé typique devrait contenir ceci :
    • nameofplugin.xml
    • nameofplugin.php
    • language\en-GB\en-GB.plg_search_nameofplugin.ini