<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.paginator.usage">
    <title>Utilisation</title>

    <sect2 id="zend.paginator.usage.paginating">
        <title>Paginer des collections de données</title>

        <para>
            Afin de pouvoir paginer des éléments, <classname>Zend_Paginator</classname> doit
            posséder une manière générique d'accéder aux sources de données. De ce fait, tous les
            accès aux données se font via des adaptateurs de sources. Plusieurs adaptateurs existent
            par défaut :
        </para>

        <table id="zend.paginator.usage.paginating.adapters">
            <title>Adaptateurs pour <classname>Zend_Paginator</classname></title>

            <tgroup cols="2">
                <thead>
                    <row>
                        <entry>Adaptateur</entry>
                        <entry>Description</entry>
                    </row>
                </thead>

                <tbody>
                    <row>
                        <entry><code>Array</code></entry>
                        <entry>Utilise un tableau <acronym>PHP</acronym></entry>
                    </row>

                    <row>
                        <entry><code>DbSelect</code></entry>
                        <entry>Utilise une instance de <link
                        linkend="zend.db.select"><classname>Zend_Db_Select</classname></link>
                        qui retourne un tableau</entry>
                    </row>

                    <row>
                        <entry><code>DbTableSelect</code></entry>
                        <entry>Utilise une instance <link
                        linkend="zend.db.table.fetch-all"><classname>Zend_Db_Table_Select</classname></link>,
                        qui retournera une instance de
                        <classname>Zend_Db_Table_Rowset_Abstract</classname>. Ceci fournit aussi
                        des informations supplémentaires sur le jeu de résultats, tel que les
                        noms de colonne.</entry>
                    </row>

                    <row>
                        <entry><code>Iterator</code></entry>
                        <entry>Utilise une instance implémentant <ulink
                        url="http://www.php.net/~helly/php/ext/spl/interfaceIterator.html"><code>Iterator</code></ulink></entry>
                    </row>

                    <row>
                        <entry><constant>NULL</constant></entry>
                        <entry>N'utilise pas <classname>Zend_Paginator</classname> pour la
                        pagination. En revanche, les options et capacités de contrôle de la
                        pagination restent disponibles.</entry>
                    </row>
                </tbody>
            </tgroup>
        </table>

        <note>
            <para>
                Plutôt que de sélectionner chaque ligne correspondant à une requête fournie,
                les adaptateurs <code>DbSelect</code> et <code>DbTableSelect</code> récupèrent
                seulement la quantité de données nécessaire pour l'affichage de la page
                courante.
            </para>

            <para>
                A cause de ceci, une seconde requête est générée dynamiquement pour déterminer
                le nombre total de lignes correspondantes. Cependant, il est possible de directement
                fournir un nombre ou un requête de dénombrement vous-même. Regardez la méthode
                <methodname>setRowCount()</methodname> de l'adaptateur <code>DbSelect</code> pour de plus amples
                informations.
            </para>
        </note>

        <para>
            Pour créer une instance de <classname>Zend_Paginator</classname>, vous devez
            spécifier un adaptateur à son constructeur:
        </para>

        <para>
            <programlisting language="php"><![CDATA[
$paginator = new Zend_Paginator(new Zend_Paginator_Adapter_Array($array));
]]></programlisting></para>

        <para>
            Pour une meilleure intégration, vous pouvez utiliser la fabrique
            <methodname>factory()</methodname>:
        </para>

        <para>
            <programlisting language="php"><![CDATA[
$paginator = Zend_Paginator::factory($array);
]]></programlisting></para>

            <note>
            <para>
                Pour l'adaptateur <constant>NULL</constant>, il faut spécifier un chiffre à son
                constructeur en lieu et place de la collection de données.
            </para>
        </note>

        <para>
            Bien que l'instance soit techniquement utilisable dans l'état, dans votre
            contrôleur d'action vous devrez informer le paginateur du numéro de page demandé par
            l'utilisateur. Ceci lui permet d'avancer à travers les données paginées.
        </para>

        <para>
            <programlisting language="php"><![CDATA[
$paginator->setCurrentPageNumber($page);
]]></programlisting></para>

        <para>
            La manière la plus simple de suivre et scruter cette valeur est via l'URL. Nous
            recommandons l'utilisation d'un routeur compatible avec
            <classname>Zend_Controller_Router_Interface</classname>, mais ceci n'est pas
            nécessaire.
        </para>

        <para>
            Voici une route que vous pourriez définir dans un fichier de configuration
            <acronym>INI</acronym>:
        </para>

        <para>
            <programlisting language="php"><![CDATA[
routes.example.route = articles/:articleName/:page
routes.example.defaults.controller = articles
routes.example.defaults.action = view
routes.example.defaults.page = 1
routes.example.reqs.articleName = \w+
routes.example.reqs.page = \d+
]]></programlisting></para>

        <para>
            Avec une telle route (et en utilisant les composants <acronym>MVC</acronym> de Zend Framework), vous
            pourriez spécifier le numéro de la page de cette manière :
        </para>

        <para>
            <programlisting language="php"><![CDATA[
$paginator->setCurrentPageNumber($this->_getParam('page'));
]]></programlisting></para>

        <para>
            Il y a d'autres options disponibles, voyez <link
            linkend="zend.paginator.configuration">la configuration</link> pour plus de
            détails.
        </para>

        <para>
            Enfin, il faut passer l'instance du paginateur à votre vue. Si vous utilisez
            <classname>Zend_View</classname> avec l'aide d'action <code>ViewRenderer</code>, ceci
            fonctionnera :
        </para>

        <para>
            <programlisting language="php"><![CDATA[
$this->view->paginator = $paginator;
]]></programlisting>
        </para>
    </sect2>

    <sect2 id="zend.paginator.usage.dbselect">
        <title>The DbSelect and DbTableSelect adapter</title>
        <para>
            The usage of most adapters is pretty straight-forward. However, the
            database adapters require a more detailed explanation regarding
            the retrieval and count of the data from the database.
        </para>

        <para>
            To use the DbSelect and DbTableSelect adapters you don't have to retrieve the data upfront from
            the database. Both adapters do the retrieval for you, aswell as the counting of the total pages.
            If additional work has to be done on the database results the adapter <methodname>getItems()</methodname> method
            has to be extended in your application.
        </para>

        <para>
            Additionally these adapters do <emphasis>not</emphasis> fetch all records from the database
            Instead, the adapters manipulates the original query to produce the corresponding
            COUNT query. Paginator then executes that COUNT query to get the number of rows.
            This does require an extra round-trip to the database, but this is many times
            faster than fetching an entire result set and using count(). Especially with
            large collections of data.
        </para>

        <para>
            The database adapters will try and build the most efficient query that will execute
            on pretty much all modern databases. However, depending on your database or even your
            own schema setup, there might be more efficient ways to get a rowcount. For this scenario
            the database adapters allow you to set a custom COUNT query. For example,
            if you keep track of the count of blog posts in a separate table, you could achieve a
            faster count query with the following setup:
        </para>

            <programlisting language="php"><![CDATA[
$adapter = new Zend_Paginator_Adapter_DbSelect($db->select()->from('posts'));
$adapter->setRowCount(
    $db->select()->from('item_counts', array(Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN => 'post_count'))
)

$paginator = new Zend_Paginator($adapter);
]]></programlisting>

        <para>
            This approach will probably not give you a huge performance gain on
            small collections and/or simple select queries. However, with complex
            queries and large collections, a similar approach could give you a
            significant performance boost.
        </para>
    </sect2>

    <sect2 id="zend.paginator.rendering">
        <title>Rendre des pages avec les scripts de vue</title>

        <para>
            Le script de vue va être utilisé pour rendre les éléments de la page (bien sûr si
            <classname>Zend_Paginator</classname> est utilisé à cet effet), et pour afficher les
            éléments relatifs au contrôle de la pagination.
        </para>

        <para>
            Comme <classname>Zend_Paginator</classname> implémente l'interface SPL <ulink
            url="http://www.php.net/~helly/php/ext/spl/interfaceIteratorAggregate.html"><code>IteratorAggregate</code></ulink>,
            boucler sur les éléments et les afficher est très simple.
        </para>

        <para>
            <programlisting language="php"><![CDATA[
<html>
<body>
<h1>Example</h1>
<?php if (count($this->paginator)): ?>
<ul>
<?php foreach ($this->paginator as $item): ?>
  <li><?php echo $item; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>

<?php echo $this->paginationControl($this->paginator,
                                    'Sliding',
                                    'my_pagination_control.phtml'); ?>
</body>
</html>
]]></programlisting></para>

        <para>
            Notez l'appel à l'aide de vue en fin de script. <code>PaginationControl</code>
            accepte jusqu'à quatre paramètres : l'instance du paginateur, un type de défilement
            (optionnel), un partial de vue (optionnel) et un tableau de paramètres
            additionnels.
        </para>

        <para>
            Les second et troisième paramètres sont très importants. Alors que le partial est
            utiliser pour déterminer comment <emphasis>présenter</emphasis> les données, le type de
            défilement définira la manière dont ils se <emphasis>comportent</emphasis>. Disons que
            le partial ressemble à un contrôle de recherche, comme ce qui suit :
        </para>

        <para>
            <inlinegraphic align="center"
            fileref="figures/zend.paginator.usage.rendering.control.png" format="PNG"
            valign="middle" />
        </para>

        <para>
            Que se passe-t-il lorsque l'utilisateur clique sur le lien "next" quelques fois?
            Plusieurs choses peuvent arriver. Le numéro de la page courante pourrait rester au
            milieu (comme c'est le cas sur Yahoo!), ou il pourrait aussi bien avancer à la fin de la
            fourchette des pages et apparaître encore à gauche lorsque l'utilisateur clique alors
            sur "next". Le nombre de pages pourrait alors s'étendre ou se comprimer alors que
            l'utilisateur avance ("scroll") à travers (comme chez Google).
        </para>

        <para>Il existe 4 types de défilement intégrés dans Zend Framework :</para>

        <table id="zend.paginator.usage.rendering.scrolling-styles">
            <title>Types de défilement pour <classname>Zend_Paginator</classname></title>

            <tgroup cols="2">
                <thead>
                    <row>
                        <entry>Type de défilement</entry>
                        <entry>Description</entry>
                    </row>
                </thead>

                <tbody>
                    <row>
                        <entry>All</entry>
                        <entry>Retourne toutes les pages. Très pratique lorsqu'il y a peu de
                        pages totales.</entry>
                    </row>

                    <row>
                        <entry>Elastic</entry>
                        <entry>Un défilement de type Google qui s'étend et se contracte au fur
                        et à mesure que l'utilisateur avance dans les pages de
                        résultats.</entry>
                    </row>

                    <row>
                        <entry>Jumping</entry>
                        <entry>Alors que l'utilisateur défile, le nombre de pages avance à la
                        fin d'une échelle donnée, puis recommence au début de l'échelle
                        suivante.</entry>
                    </row>

                    <row>
                        <entry>Sliding</entry>
                        <entry>Un défilement de type Yahoo! qui positionne la page en cours au
                        centre d'une échelle de pages, le plus justement et près possible. Ce
                        type de défilement est le type par défaut.</entry>
                    </row>
                </tbody>
            </tgroup>
        </table>

        <para>
            Le quatrième et dernier paramètre est réservé pour un tableau associatif optionnel
            de variables supplémentaires que vous voulez rendre disponible dans vos partiels de vues
            (disponible via <varname>$this</varname>). Par exemple, ces valeurs permettent d'inclure des
            paramètres d'URL supplémentaires pour les liens de pagination.
        </para>

        <para>
            En spécifiant le partial de vue par défaut, le défilement et l'instance de vue,
            vous pouvez alors vous affranchir totalement des appels à <code>PaginationControl</code>
            :
        </para>

        <para>
            <programlisting language="php"><![CDATA[
Zend_Paginator::setDefaultScrollingStyle('Sliding');
Zend_View_Helper_PaginationControl::setDefaultViewPartial(
    'my_pagination_control.phtml'
);
$paginator->setView($view);
]]></programlisting></para>

        <para>
            Utilisez dès lors un simple <code>echo</code> dans le script de vue pour le rendu
            du paginateur complet:
        </para>

        <para>
            <programlisting language="php"><![CDATA[
<?php echo $this->paginator; ?>
]]></programlisting></para>

            <note>
            <para>
                Bien sûr, il est possible d'utiliser Zend_paginator avec d'autres moteurs de
                templates. Par exemple, avec Smarty vous pourriez faire ceci :
            </para>

            <para>
                <programlisting language="php"><![CDATA[
$smarty->assign('pages', $paginator->getPages());
]]></programlisting></para>

            <para>
                Vous pouvez ainsi accéder aux valeurs du paginateur grâce à un template comme
                ceci :
            </para>

            <para>
                <programlisting language="php"><![CDATA[
{$pages->pageCount}
]]></programlisting></para>
            </note>

            <sect3 id="zend.paginator.usage.rendering.example-controls">
                <title>Exemples de contrôles de pagination</title>

            <para>
                Voici quelques exemples qui vous aideront à démarrer avec le
                paginateur:
            </para>

            <para>
                Pagination de recherche :<programlisting language="php"><![CDATA[
<!--
Voir http://developer.yahoo.com/ypatterns/pattern.php?pattern=searchpagination
-->

<?php if ($this->pageCount): ?>
<div class="paginationControl">
<!-- Previous page link -->
<?php if (isset($this->previous)): ?>
  <a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
    &lt; Previous
  </a> |
<?php else: ?>
  <span class="disabled">&lt; Previous</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)); ?>">
        <?php echo $page; ?>
    </a> |
  <?php else: ?>
    <?php echo $page; ?> |
  <?php endif; ?>
<?php endforeach; ?>

<!-- Next page link -->
<?php if (isset($this->next)): ?>
  <a href="<?php echo $this->url(array('page' => $this->next)); ?>">
    Next &gt;
  </a>
<?php else: ?>
  <span class="disabled">Next &gt;</span>
<?php endif; ?>
</div>
<?php endif; ?>
]]></programlisting></para>

            <para>
                Pagination d'objets :<programlisting language="php"><![CDATA[
<!--
Voir http://developer.yahoo.com/ypatterns/pattern.php?pattern=itempagination
-->

<?php if ($this->pageCount): ?>
<div class="paginationControl">
<?php echo $this->firstItemNumber; ?> - <?php echo $this->lastItemNumber; ?>
of <?php echo $this->totalItemCount; ?>

<!-- First page link -->
<?php if (isset($this->previous)): ?>
  <a href="<?php echo $this->url(array('page' => $this->first)); ?>">
    First
  </a> |
<?php else: ?>
  <span class="disabled">First</span> |
<?php endif; ?>

<!-- Previous page link -->
<?php if (isset($this->previous)): ?>
  <a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
    &lt; Previous
  </a> |
<?php else: ?>
  <span class="disabled">&lt; Previous</span> |
<?php endif; ?>

<!-- Next page link -->
<?php if (isset($this->next)): ?>
  <a href="<?php echo $this->url(array('page' => $this->next)); ?>">
    Next &gt;
  </a> |
<?php else: ?>
  <span class="disabled">Next &gt;</span> |
<?php endif; ?>

<!-- Last page link -->
<?php if (isset($this->next)): ?>
  <a href="<?php echo $this->url(array('page' => $this->last)); ?>">Last</a>
<?php else: ?>
  <span class="disabled">Last</span>
<?php endif; ?>

</div>
<?php endif; ?>
]]></programlisting>
            </para>

            <para>
                Pagination Dropdown :<programlisting language="php"><![CDATA[
<?php if ($this->pageCount): ?>
<select id="paginationControl" size="1">
<?php foreach ($this->pagesInRange as $page): ?>
  <?php $selected = ($page == $this->current) ? ' selected="selected"' : ''; ?>
  <option value="<?php echo $this->url(array('page' => $page)); ?>"
          <?php echo $selected ?>>
    <?php echo $page; ?>
  </option>
<?php endforeach; ?>
</select>
<?php endif; ?>

<script type="text/javascript"
    src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js">
</script>
<script type="text/javascript">
$('paginationControl').observe('change', function() {
    window.location = this.options[this.selectedIndex].value;
})
</script>
]]></programlisting>
            </para>
        </sect3>

        <sect3 id="zend.paginator.usage.rendering.properties">
            <title>Liste des propriétés</title>

            <para>
                Les options suivantes sont disponibles pour contrôler la pagination dans les
                partials de vue :
            </para>

            <table id="zend.paginator.usage.rendering.properties.table">
                <title>Propriétés disponibles aux partials de vue</title>

                <tgroup cols="3">
                    <thead>
                        <row>
                            <entry>Propriété</entry>
                            <entry>Type</entry>
                            <entry>Description</entry>
                        </row>
                    </thead>

                    <tbody>
                        <row>
                            <entry>first</entry>
                            <entry>entier</entry>
                            <entry>Numéro de la première page</entry>
                        </row>

                        <row>
                            <entry>firstItemNumber</entry>
                            <entry>entier</entry>
                            <entry>Numéro absolu du premier objet(item) dans cette page</entry>
                        </row>

                        <row>
                            <entry>firstPageInRange</entry>
                            <entry>entier</entry>
                            <entry>Première page dans l'échelle retournée par le type de
                            défilement</entry>
                        </row>

                        <row>
                            <entry>current</entry>
                            <entry>entier</entry>
                            <entry>Numéro de la page en cours</entry>
                        </row>

                        <row>
                            <entry>currentItemCount</entry>
                            <entry>entier</entry>
                            <entry>Nombre d'objets sur cette page</entry>
                        </row>

                        <row>
                            <entry>itemCountPerPage</entry>
                            <entry>integer</entry>
                            <entry>Nombre d'objets maximum à afficher par page</entry>
                        </row>

                        <row>
                            <entry>last</entry>
                            <entry>entier</entry>
                            <entry>Numéro de la dernière page</entry>
                        </row>

                        <row>
                            <entry>lastItemNumber</entry>
                            <entry>entier</entry>
                            <entry>Numéro absolu du dernier objet sur cette page</entry>
                        </row>

                        <row>
                            <entry>lastPageInRange</entry>
                            <entry>entier</entry>
                            <entry>Dernière page dans l'échelle retournée par le type de
                            défilement</entry>
                        </row>

                        <row>
                            <entry>next</entry>
                            <entry>entier</entry>
                            <entry>Numéro de la page suivante</entry>
                        </row>

                        <row>
                            <entry>pageCount</entry>
                            <entry>entier</entry>
                            <entry>Nombre de pages</entry>
                        </row>

                        <row>
                            <entry>pagesInRange</entry>
                            <entry>tableau (array)</entry>
                            <entry>Tableau des pages retournées par le type de
                            défilement</entry>
                        </row>

                        <row>
                            <entry>previous</entry>
                            <entry>entier</entry>
                            <entry>Numéro de la page précédente</entry>
                        </row>

                        <row>
                            <entry>totalItemCount</entry>
                            <entry>entier</entry>
                            <entry>Nombre total d'objets</entry>
                        </row>
                    </tbody>
                </tgroup>
            </table>
        </sect3>
    </sect2>
</sect1>