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

    <sect2 id="zend.paginator.advanced.adapters">
        <title>Adaptateurs de source de données personnalisée</title>

        <para>
            À partir d'un moment, vous pourriez avoir besoin de parcourir un type de données
            qui n'est pas couvert par les adaptateurs fournis par défaut. Dans ce cas, vous devrez
            écrire vos propres adaptateurs.
        </para>

        <para>
            Pour faire ceci, vous devez implémenter
            <classname>Zend_Paginator_Adapter_Interface</classname>. Il existe deux méthodes
            requises :
        </para>

        <itemizedlist>
            <listitem>
                <para><methodname>count()</methodname></para>
            </listitem>

            <listitem>
                <para><methodname>getItems($offset, $itemCountPerPage)</methodname></para>
            </listitem>
        </itemizedlist>

        <para>
            De plus, vous voudrez peut-être implémenter un constructeur qui prend votre source
            de données comme paramètre et le stocke comme propriété protégée ou privée. La manière
            suivant laquelle vous allez spécifiquement faire ceci, vous incombe.
        </para>

        <para>
            Si vous avez déjà utilisé l'interface SPL <ulink
            url="http://www.php.net/~helly/php/ext/spl/interfaceCountable.html">Countable</ulink>,
            vous êtes familier avec <methodname>count()</methodname>. Utilisé avec
            <classname>Zend_Paginator</classname>, il s'agit du nombre total d'éléments dans la
            collection de données. De plus, l'instance <classname>Zend_Paginator</classname> fournit
            une méthode <methodname>countAllItems()</methodname> qui proxie vers la méthode <methodname>count()</methodname>
            de l'adaptateur.
        </para>

        <para>
            La méthode <methodname>getItems()</methodname> est seulement légèrement plus compliquée. Pour
            ceci, les paramètres sont un point de départ et un nombre d'éléments à afficher par
            page. Vous devez retourner la portion appropriée de données. Pour un tableau, il
            s'agirait :
        </para>

        <para>
            <programlisting language="php"><![CDATA[
return array_slice($this->_array, $offset, $itemCountPerPage);
]]></programlisting></para>

        <para>
            Regardez les adaptateurs fournis par défaut (ils implémentent tous
            <classname>Zend_Paginator_Adapter_Interface</classname>) pour avoir une idée de la
            manière d'implémenter votre propre adaptateur.
        </para>
    </sect2>

    <sect2 id="zend.paginator.advanced.scrolling-styles">
        <title>Styles de défilement personnalisés</title>

        <para>
            Créer votre propre style de défilement requiert que vous implémentiez
            <classname>Zend_Paginator_ScrollingStyle_Interface</classname>, qui définit une seule
            méthode, <methodname>getPages()</methodname>. Et plus spécifiquement :
        </para>

        <para>
            <programlisting language="php"><![CDATA[
public function getPages(Zend_Paginator $paginator, $pageRange = null);
]]></programlisting></para>

        <para>
            Cette méthode doit calculer des bornes inférieures et supérieures des numéros de
            page dans la plage des pages dites "local" (c'est-à-dire qui sont proches de la page
            courante).
        </para>

        <para>
            A moins que votre style étende un autre style de défilement (voir
            <classname>Zend_Paginator_ScrollingStyle_Elastic</classname> par exemple), votre style
            personnalisé devra inévitablement se terminer par quelque chose de similaire à ceci
            :
        </para>

        <para>
            <programlisting language="php"><![CDATA[
return $paginator->getPagesInRange($lowerBound, $upperBound);
]]></programlisting></para>

        <para>
            Il n'y a rien de spécial au sujet de cet appel ; c'est simplement une méthode
            pratique pour vérifier la validité de la limite inférieure et supérieure et pour
            renvoyer un tableau de ces bornes au paginateur.
        </para>

        <para>
            Quand vous êtes prêt à utiliser votre style de défilement, vous devez informer
            <classname>Zend_Paginator</classname> dans quel dossier le chercher, en réalisant ceci
            :
        </para>

        <para>
            <programlisting language="php"><![CDATA[
$prefix = 'Mon_Paginator_StyleDefilement';
$path   = 'Mon/Paginator/StyleDefilement/';
Zend_Paginator::addScrollingStylePrefixPath($prefix, $path);
]]></programlisting></para>
    </sect2>

    <sect2 id="zend.paginator.advanced.caching">
        <title>Fonctionnalité de mise en cache</title>

        <para>
            <classname>Zend_Paginator</classname> peut mettre en cache les données qu'il a
            déjà fourni, empêchant ainsi l'adaptateur de les rechercher chaque fois qu'ils sont
            demandés. Pour informer le paginateur de mettre en cache automatiquement les données
            issues de l'adaptateur, fournissez simplement une instance de
            <classname>Zend_Cache_Core</classname> à sa méthode <methodname>setCache()</methodname> :
        </para>

        <para>
            <programlisting language="php"><![CDATA[
$paginator = Zend_Paginator::factory($someData);
$fO = array('lifetime' => 3600, 'automatic_serialization' => true);
$bO = array('cache_dir'=>'/tmp');
$cache = Zend_cache::factory('Core', 'File', $fO, $bO);
Zend_Paginator::setCache($cache);
]]></programlisting></para>

        <para>
            Tant que Zend_Paginator possède une instance de Zend_Cache_Core, les données
            seront mises en cache. Parfois vous ne voudrez pas mettre en cache les données même si
            vous avez déjà fourni un instance de cache. Vous pourrez alors utiliser la méthode
            <methodname>setCacheEnable()</methodname> :
        </para>

        <para>
            <programlisting language="php"><![CDATA[
$paginator = Zend_Paginator::factory($someData);
// $cache est une instance de Zend_Cache_Core
Zend_Paginator::setCache($cache);
// ... plus loin dans le script
$paginator->setCacheEnable(false);
// le cache est maintenant désactivé
]]></programlisting></para>

        <para>
            Quand un cache est paramétré, les données y sont automatiquement stockées et
            extraites. Il peut alors être utile de vider le cache manuellement. Vous pouvez réaliser
            ceci en appelant <methodname>clearPageItemCache($pageNumber)</methodname>. Si vous ne passer aucun
            paramètre, le cache entier sera vidé. Vous pouvez fournir optionnellement un paramètre
            représentant le numéro de page à enlever du cache :
        </para>

        <para>
            <programlisting language="php"><![CDATA[
$paginator = Zend_Paginator::factory($someData);
Zend_Paginator::setCache($cache);
$items = $paginator->getCurrentItems();
// la page 1 est maintenant en cache
$page3Items = $paginator->getItemsByPage(3);
// la page 3 est maintenant en cache

// effacer le cache associé à la page 3
$paginator->clearPageItemCache(3);

// effacer tout le cache
$paginator->clearPageItemCache();
]]></programlisting></para>

        <para>
            Changer le nombre d'éléments par page videra tout le cache comme s'il était devenu
            invalide :
        </para>

        <para>
            <programlisting language="php"><![CDATA[
$paginator = Zend_Paginator::factory($someData);
Zend_Paginator::setCache($cache);
// récupérer des éléments
$items = $paginator->getCurrentItems();

// toutes les données vont être effacées du cache :
$paginator->setItemCountPerPage(2);
]]></programlisting></para>

        <para>
            Il est aussi possible de voir les données en cache et de les appeler directement
            grâce à la méthode <methodname>getPageItemCache()</methodname> :
        </para>

        <para>
            <programlisting language="php"><![CDATA[
$paginator = Zend_Paginator::factory($someData);
$paginator->setItemCountPerPage(3);
Zend_Paginator::setCache($cache);

// récupérer des éléments
$items = $paginator->getCurrentItems();
$otherItems = $paginator->getItemsPerPage(4);

// voir ces éléments sous la forme d'un tableau à 2-dimensions :
var_dump($paginator->getPageItemCache());
]]></programlisting>
        </para>
    </sect2>

    <sect2 id="zend.paginator.advanced.aggregator">
        <title>Zend_Paginator_AdapterAggregate Interface</title>

        <para>
            Depending on your application you might want to paginate objects, whose internal data-structure
            is equal to existing adapters, but you don't want to break up your encapsulation to allow access
            to this data. In other cases an object might be in a "has-an adapter" relationship, rather than
            the "is-an adapter" relationsship that <classname>Zend_Paginator_Adapter_Abstract</classname> promotes.
            For this cases you can use the <classname>Zend_Paginator_AdapterAggregate</classname> interface that
            behaves much like the <classname>IteratorAggregate</classname> interface of the PHP SPL extension.
        </para>

        <para>
            <programlisting language="php"><![CDATA[
interface Zend_Paginator_AdapterAggregate
{
    /**
     * Return a fully configured Paginator Adapter from this method.
     *
     * @return Zend_Paginator_Adapter_Abstract
     */
    public function getPaginatorAdapter();
}
]]></programlisting>
        </para>

        <para>
            The interface is fairly small and only expects you to return an instance of
            <classname>Zend_Paginator_Adapter_Abstract</classname>. An Adapter Aggregate instance is
            then recognized by both <methodname>Zend_Paginator::factory()</methodname> and the
            constructor of <classname>Zend_Paginator</classname> and handled accordingly.
        </para>
    </sect2>
</sect1>