Astuce [eZ5] Rechercher des contenus par mot clé

L'extension eZTags pour eZ Publish fournit un système de mots clés pour regrouper des contenus par thématique. Avec elle arrive un nouveau type de champ, pour taguer vos contenus.

Dans eZ Publish 4.x (ou en mode legacy), le template de ce champ affiche un lien vers une page qui liste les contenus avec ce mot clé. La version pour eZ Publish 5 est disponible ici. Malheureusement, elle ne fournit aucune méthode pour trouver des contenus à partir d'un mot clé.

Voici trois méthodes pour récupérer ces contenus.

<?php

// [...]

use \Netgen\TagsBundle\API\Repository\Values\Tags\Tag;

/**
 * Retrouve les contenus avec le mot clé en argument.
 *
 * @param string $keyword Mot clé recherché
 * @param int $offset Offset pour les résultats de la recherche
 * @param int $limit Nombre maximal de résultats de recherche
 *
 * @return \eZ\Publish\API\Repository\Values\Content\Content[]
 *
 * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException Si l'utilisateur courant n'a pas le droit de voir les tags
 * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException Si aucun tag avec cet ID n'existe
 */
public function getRelatedContentByKeyword($keyword, $offset = 0, $limit = 50) {

    $rootTagID = 2;

    // Recherche du tag correspond au mot clé
    $tag = $this->getTagByKeyword($rootTagID, $keyword);

    $relatedContentList = array();

    if (!empty($tag)) {

        // Recherche des contenus avec le mot clé souhaité
        $tagService         = $this->container->get('ezpublish.api.service.tags');
        $relatedContentList = $tagService->getRelatedContent($tag, $offset, $limit);
    }

    return $relatedContentList;
}

/**
 * Retrouve un Tag à partir de son mot clé.
 * Le premier trouvé parmi les descendants de celui dont l'ID est en argument est retourné.
 *
 * @param string $rootTagID ID du tag parmi les descendants duquel rechercher
 * @param string $keyword Mot clé recherché
 *
 * @return \Netgen\TagsBundle\API\Repository\Values\Tags\Tag
 *
 * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException Si l'utilisateur courant n'a pas le droit de voir le tag courant
 * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException Si aucun tag avec cet ID n'existe
 */
public function getTagByKeyword($rootTagID, $keyword) {

    $tag = null;

    // Récupération du tag racine
    $tagService = $this->container->get('ezpublish.api.service.tags');
    $rootTag    = $tagService->loadTag($rootTagID);

    if (!empty($rootTag)) {

        // Récupération des tags descendants
        $descendantTagList = $this->getTagDescendantList($rootTag);

        if (!empty($descendantTagList)) {

            // Parcours des tags descendants
            for ($i = 0, $length = count($descendantTagList); $i < $length && $tag == null; $i++) {

                if ($descendantTagList[$i]->keyword == $keyword) { 
                    $tag = $descendantTagList[$i];
                }
            }
        }
    }

    return $tag;
}

/**
 * Retourne tous les tags descendant de celui en argument.
 *
 * @param \Netgen\TagsBundle\API\Repository\Values\Tags\Tag $rootTag Tag racine
 *
 * @return \Netgen\TagsBundle\API\Repository\Values\Tags\Tag[]
 *
 * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException Si l'utilisateur courant n'a pas le droit de voir le tag courant
 */
public function getTagDescendantList( Tag $rootTag ) {

    // Récupération des tag descendants
    $descendantTagList = array();

    $tagService       = $this->container->get( 'ezpublish.api.service.tags' );
    $childrenTagList  = $tagService->loadTagChildren( $rootTag );

    // Parcours des tags enfants
    foreach ( $childrenTagList as $childTag ) {

        $descendantTagList[] = $childTag;

        // Récupération des descendants
        $descendantTagList = array_merge( $descendantTagList, $this->getTagDescendantList( $childTag ) );
    }

    return $descendantTagList;
}

Remarques :

  • Ces méthodes peuvent être utilisées dans un contrôleur, où l'attribut $container (ContainerInterface) est disponible.
  • Tous vos tags doivent avoir une racine commune (= une seule arborescence). Cette racine servira de base pour les recherches.
  • Dans la première méthode, la variables $rootTagID (identifiant du tag racine) est en dur et devrait être récupérée depuis un fichier de configuration.
  • Dans cet exemple, la recherche ne fonctionne pas pour les synonymes. La deuxième méthode peut être améliorée pour les gérer.