Création d'une liste paginée avec un critère de recherche avec Zend Framework

Dans notre cadre professionnel, nous rencontrons souvent des collègues compétents et passionnés.
C'est le cas ici avec Jonathan, qui de plus, nous gratifie d'une petite documentation et nous permet de partager celle-ci.
Le but étant de mettre en application l'article de Julien Pauli sur le sujet.
Je tiens également à remercier Yannick Komotir (Thes32), pour avoir pris le temps d'uniformiser la mise en page de cet article afin que tout le monde en profite, sans oublier Benj. pour la relecture et son aide précieuse dans la réalisation finale.
À vous trois je dis merci.
MaitrePylos.

Article lu   fois.

L'auteur

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Afficher des données dans une liste, tel un tableau est très simple à l'aide de Zend Framework (ZF). Ces listes sont parfois longues sur la page (voire très longues !) et donc prennent forcément une grande place sur la page Web, même si des critères sont spécifiés. Je vais vous montrer comment créer une liste divisée en plusieurs pages (paginée) via un critère. Cela dit, il n'est pas obligatoire d'avoir un ou des critères de recherche sur la liste pour réaliser cet exemple.

Avant tout, il est nécessaire de créer un formulaire. Cela se fait très simplement en utilisant le composant Zend_Form, créant une classe qui hérite du composant ainsi que votre formulaire customisé. Au minimum, vous aurez une zone de saisie de texte pour le critère de recherche et un bouton (submit) pour envoyer la requête. Dans cet exemple j'utilise un formulaire exploitant la méthode GET, afin de renvoyer les données en paramètre de l'URL.

Image non disponible

II. Création de la page

Créer une simple page index qui contiendra le formulaire de recherche. Il faut donc un controller indexController et une vue index/index.phtml. Ajoutez aussi un model model/exemple.php.

III. Le model

Le model aura comme fonction de retourner la liste des données extraites de la base de données selon le critère de recherche voulu :

 
Sélectionnez
              <?php
class Model_Exemple {
    private $_db = null;

    public function __construct () {
        $params = array(
                'host' => 'hostname' ,
                'username' => 'user' ,
                'password' => 'password' ,
                'dbname' => 'dbName'
        );

        try {
            $this->_db = Zend_Db::factory('PDO_MYSQL', $params);
            $this->_db->getConnection();
        } catch (Zend_Db_Adapter_Exception $e) {
            echo $e->getMessage();
        }
    }
    public function exempleCritere($name) {
        $sql = "SELECT * FROM a_table WHERE critere like ? ";
        return $this->_db->fetchAll($sql,$name.'%');
    }
}
?>

La fonction exempleCritere prend en paramètre le texte entré dans le champ de saisie du formulaire (ici ce sera le paramètre passé dans l'URL). Ensuite, créez une requête SQL pour récupérer le résultat obtenu dans un tableau (Array).

IV. Le controller index

Dans le controller, ajouter le code suivant dans 'indexAction' :

 
Sélectionnez
public function indexAction()
    {
        //vérifie si le paramètre existe et non vide
        if($this->_request->getParam('nom')!=''){

            $med = strtoupper($this->_request->getParam('nom'));

            //on crée un validateur pour vérifier qu'il y a au moins deux caractères
            $validate = new Zend_Validate_StringLength(2);
            //messages fournis en cas d'erreurs
            $validate->setMessage('Search string is not specific enough as this would copy the whole table blocking the network and your PC');
            if($validate->isValid($med)) {
                //Récupère la page courante du paginator qui se trouve dans le parameter 'page'
                $currentPage = $this->_getParam('page', 1);
                //Crée une instance du model créé
                $db = new Model_Exemple();
                //Appel à la fonction pour récupérer le paginator
                $page = $db->getPaginator($med, $currentPage, 20,10);
                //Le paginator recupéré à la ligne précédente
                $this->view->paginator = $page['page'];      
                //Le nombre de records récupérés à la recherche
                $this->view->count = $page['count'];


            }else {
                
                $this->_redirect('index');
            }
        }

IV-A. Expliquons quelques points de ce code

La fonction getPaginator() est une fonction à rajouter dans le model créé plus haut. Celle-ci permet de créer le paginator, de le récupérer dans le controller et de l'afficher par la suite dans la vue.

 
Sélectionnez
                    /*
                    * @param name, premier critère de recherche
                    * @param item, second critère de recherche
                    * @param currentPage, la page courante dans le paginator
                    * @param rangePage, nombre de pages total dans le paginator
                    * @param counterPerPage, nombre de records dans une page du paginator
                    */
                    public function getPaginator($critere, $currentPage, $rangePage,
                    $counterPerPage)
                    {
                    //Liste des données selon les critères rentrés
                    $rows = $this-> exempleCritere ($critere);
                    //Création du paginator
                    $page = Zend_Paginator::factory($rows);
                    $page->setPageRange($rangePage);
                    $page->setCurrentPageNumber($currentPage);
                    $page->setItemCountPerPage($counterPerPage);
                    //Compteur de records pour la requête (si >0 alors affichage du paginator
                    sinon
                    //un message pour indiquer que rien n'a été trouvé.
                    $count = count($rows);
                    //Return le paginator + le nombre de lignes de la requête
                    return array('page'=>$page,'count'=>$count);
                    }

V. Le paginator

Et maintenant que fait-on ? Parlons un peu du paginator. Il faut créer une vue par défaut pour le paginator, une vue partielle. Il va falloir assigner cette vue partielle au paginator, cela se fera dans le fichier bootstrap.php. Dans ce dernier, créons une fonction d'initialisation par exemple _initPaginationDefault()

 
Sélectionnez
protected function _initPaginationDefault() {
    Zend_Paginator::setDefaultScrollingStyle('Sliding');
    Zend_View_Helper_PaginationControl::setDefaultViewPartial("\partials\pagination.phtml");
}

Cela permet d'initialiser les paramètres par défaut du paginator, par exemple le mode de scrolling en 'Sliding' (pour d'autres paramètres, se référer à la documentation). On voit aussi notre vue par default pour le paginator qui se trouvera dans views/script/partials/pagination.phtml.

Dans ce fichier il faut indiquer la pagination que l'on souhaite utiliser, voici un exemple : Image non disponible

Et le fichier pagination.phtml donne ça :

 
Sélectionnez
<?php
if ($this->pageCount): ?>
<div id="paginationControl">
    <!-- Previous page link -->
        <?php if (isset($this->previous)): ?>
    <a href="<?php echo $this->url(array('page' => $this->previous)).'?'.
                       $_SERVER['QUERY_STRING']; ?>">&lt; <?php echo $this->translate("precedent");
                ?></a> |
        <?php else: ?>
    <span class="disabled">&lt; <?php echo $this->translate("precedent"); ?></span> |
        <?php endif; ?>
    <!-- Numbered page links -->
        <?php foreach ($this->pagesInRange as $page): ?>
            <?php if ($page != $this->current): ?>
    <a href="<?php echo $this->url(array('page' => $page)).'?'.
                           $_SERVER['QUERY_STRING']; ?>"><?php echo $page; ?></a> |
               <?php else: ?>
    <span class="current"><?php echo $page; ?></span> |
            <?php endif; ?>
        <?php endforeach; ?>
    <!-- Next page link -->
        <?php if (isset($this->next)): ?>
    <a href="<?php echo $this->url(array('page' => $this->next)).'?'.
                       $_SERVER['QUERY_STRING']; ?>"><?php echo $this->translate("suivant"); ?>
        &gt;</a>
        <?php else: ?>
    <span class="disabled"><?php echo $this->translate("suivant"); ?> &gt;</span>
        <?php endif; ?>
</div>
<?php endif; ?>

L'astuce est qu'il faut redéfinir l'URL de chaque lien (boutons « précédent », « suivant » ainsi que les numéros de page) et il ne faut pas oublier le paramètre qui est utilisé pour la recherche ! Pour cela il suffit d'ajouter à l'URL : .' ?' .$_SERVER['QUERY_STRING'] et nous aurons notre paramètre ajouté à la fin de chaque lien.

Pour terminer, voici le contenu de la vue index.phtml :

 
Sélectionnez
<?php
//Affichage du formulaire
echo $this->form;
?>
<?php if($this->count !=0): ?>
<table class="tablesorter">
    <caption><B>Titre <?php echo $this->item; ?> </B></caption>
    <thead>
        <tr>
            <th>titre 1</th>
            <th>titre 2</th>
            <th>titre 3</th>
            <th>titre 4</th>
        </tr>
    </thead>
    <tbody>
            <?php $i = 1; ?>
        //boucle sur chaque élément contenu dans paginator (un paginator est un iterator ;) )
            <?php foreach ($this->paginator as $value):?>
                <?php $class = ($i%2)?'vert':'white'; ?>
        <tr>
            <td class="<?php echo $class ?>"><?php echo $value['donnée'] ?></td>
        </tr>
                <?php $i++ ?>
            <?php endforeach; ?>
    </tbody>
</table>
//afficher le paginator en lui-même, donc ce qui a été créé dans la vue partielle
    <?php echo $this->paginator ?>
    <?php echo ("Number of rows returned: ".$this->count); ?>
<?php endif ?>
<?php if ($this->count==0) {
    print("Nothing found\n");
} ?>

Et voilà maintenant vous avez un paginator basique.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2010 developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.