[GENERIC] Zend_Translate:
[zend.git] / documentation / manual / en / module_specs / Zend_Paginator-Advanced.xml
blob0832db96b7cb4547b225111fa183318b9a9a1f7c
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect1 id="zend.paginator.advanced">
4     <title>Advanced usage</title>
6     <sect2 id="zend.paginator.advanced.adapters">
7         <title>Custom data source adapters</title>
9         <para>
10             At some point you may run across a data type that is not covered by
11             the packaged adapters. In this case, you will need to write your
12             own.
13         </para>
15         <para>
16             To do so, you must implement
17             <classname>Zend_Paginator_Adapter_Interface</classname>. There are two
18             methods required to do this:
19         </para>
21         <itemizedlist>
22             <listitem>
23                 <para>count()</para>
24             </listitem>
26             <listitem>
27                 <para>getItems($offset, $itemCountPerPage)</para>
28             </listitem>
29         </itemizedlist>
31         <para>
32             Additionally, you'll want to implement a constructor that takes
33             your data source as a parameter and stores it as a protected or
34             private property. How you wish to go about doing this
35             specifically is up to you.
36         </para>
38         <para>
39             If you've ever used the SPL interface <ulink
40                 url="http://www.php.net/~helly/php/ext/spl/interfaceCountable.html"><code>Countable</code></ulink>,
41             you're familiar with <methodname>count()</methodname>. As used with
42             <classname>Zend_Paginator</classname>, this is the total number of items
43             in the data collection.
44             Additionally, the <classname>Zend_Paginator</classname> instance provides a method
45             <methodname>countAllItems()</methodname> that proxies to the adapter
46             <methodname>count()</methodname> method.
47         </para>
49         <para>
50             The <methodname>getItems()</methodname> method is only slightly more
51             complicated. For this, your adapter is supplied with an offset and
52             the number of items to display per page. You must return the
53             appropriate slice of data. For an array, that would be:
54         </para>
56         <programlisting language="php"><![CDATA[
57 return array_slice($this->_array, $offset, $itemCountPerPage);
58 ]]></programlisting>
60         <para>
61             Take a look at the packaged adapters (all of which implement the
62             <classname>Zend_Paginator_Adapter_Interface</classname>) for ideas of how you
63             might go about implementing your own.
64         </para>
65     </sect2>
67     <sect2 id="zend.paginator.advanced.scrolling-styles">
68         <title>Custom scrolling styles</title>
70         <para>
71             Creating your own scrolling style requires that you implement
72             <classname>Zend_Paginator_ScrollingStyle_Interface</classname>, which defines
73             a single method, <methodname>getPages()</methodname>. Specifically,
74         </para>
76         <programlisting language="php"><![CDATA[
77 public function getPages(Zend_Paginator $paginator, $pageRange = null);
78 ]]></programlisting>
80         <para>
81             This method should calculate a lower and upper bound for page
82             numbers within the range of so-called "local" pages (that is, pages
83             that are nearby the current page).
84         </para>
86         <para>
87             Unless it extends another scrolling style (see
88             <classname>Zend_Paginator_ScrollingStyle_Elastic</classname> for an example),
89             your custom scrolling style will inevitably end with something
90             similar to the following line of code:
91         </para>
93         <programlisting language="php"><![CDATA[
94 return $paginator->getPagesInRange($lowerBound, $upperBound);
95 ]]></programlisting>
97         <para>
98             There's nothing special about this call; it's merely a convenience
99             method to check the validity of the lower and upper bound and
100             return an array of the range to the paginator.
101         </para>
103         <para>
104             When you're ready to use your new scrolling style, you'll need to
105             tell <classname>Zend_Paginator</classname> what directory to look in. To do
106             that, do the following:
107         </para>
109         <programlisting language="php"><![CDATA[
110 $prefix = 'My_Paginator_ScrollingStyle';
111 $path   = 'My/Paginator/ScrollingStyle/';
112 Zend_Paginator::addScrollingStylePrefixPath($prefix, $path);
113 ]]></programlisting>
114     </sect2>
116     <sect2 id="zend.paginator.advanced.caching">
117         <title>Caching features</title>
119         <para>
120             <classname>Zend_Paginator</classname> can be told to cache the data it has already
121             passed on, preventing the adapter from fetching them each time they are used.
122             To tell paginator to automatically cache the adapter's data, just pass to
123             its <methodname>setCache()</methodname> method a <classname>Zend_Cache_Core</classname>
124             instance.
125         </para>
127         <programlisting language="php"><![CDATA[
128 $paginator = Zend_Paginator::factory($someData);
129 $fO = array('lifetime' => 3600, 'automatic_serialization' => true);
130 $bO = array('cache_dir'=>'/tmp');
131 $cache = Zend_cache::factory('Core', 'File', $fO, $bO);
132 Zend_Paginator::setCache($cache);
133 ]]></programlisting>
135         <para>
136             As far as <classname>Zend_Paginator</classname> has got a
137             <classname>Zend_Cache_Core</classname> instance, data will be cached. Sometimes you
138             would like not to cache data even if you already passed a cache instance. You should
139             then use <methodname>setCacheEnable()</methodname> for that.
140         </para>
142         <programlisting language="php"><![CDATA[
143 $paginator = Zend_Paginator::factory($someData);
144 // $cache is a Zend_Cache_Core instance
145 Zend_Paginator::setCache($cache);
146 // ... later on the script
147 $paginator->setCacheEnable(false);
148 // cache is now disabled
149 ]]></programlisting>
151         <para>
152             When a cache is set, data are automatically stored in it and pulled out from
153             it. It then can be useful to empty the cache manually. You can get this done by
154             calling <methodname>clearPageItemCache($pageNumber)</methodname>.
155             If you don't pass any parameter, the whole cache will be empty. You can optionally
156             pass a parameter representing the page number to empty in the cache:
157         </para>
159         <programlisting language="php"><![CDATA[
160 $paginator = Zend_Paginator::factory($someData);
161 Zend_Paginator::setCache($cache);
162 $items = $paginator->getCurrentItems();
163 // page 1 is now in cache
164 $page3Items = $paginator->getItemsByPage(3);
165 // page 3 is now in cache
167 // clear the cache of the results for page 3
168 $paginator->clearPageItemCache(3);
170 // clear all the cache data
171 $paginator->clearPageItemCache();
172 ]]></programlisting>
174         <para>
175             Changing the item count per page will empty the whole cache
176             as it would have become invalid:
177         </para>
179         <programlisting language="php"><![CDATA[
180 $paginator = Zend_Paginator::factory($someData);
181 Zend_Paginator::setCache($cache);
182 // fetch some items
183 $items = $paginator->getCurrentItems();
185 // all the cache data will be flushed:
186 $paginator->setItemCountPerPage(2);
187 ]]></programlisting>
189         <para>
190             It is also possible to see the data in cache and ask for them directly.
191             <methodname>getPageItemCache()</methodname> can be used for that:
192         </para>
194         <programlisting language="php"><![CDATA[
195 $paginator = Zend_Paginator::factory($someData);
196 $paginator->setItemCountPerPage(3);
197 Zend_Paginator::setCache($cache);
199 // fetch some items
200 $items = $paginator->getCurrentItems();
201 $otherItems = $paginator->getItemsPerPage(4);
203 // see the cached items as a two-dimension array:
204 var_dump($paginator->getPageItemCache());
205 ]]></programlisting>
206     </sect2>
208     <sect2 id="zend.paginator.advanced.aggregator">
209         <title>Zend_Paginator_AdapterAggregate Interface</title>
211         <para>
212             Depending on your application you might want to paginate objects, whose internal
213             data-structure is equal to existing adapters, but you don't want to break up your
214             encapsulation to allow access to this data. In other cases an object might be in a
215             "has-an adapter" relationship, rather than the "is-an adapter" relationsship that
216             <classname>Zend_Paginator_Adapter_Abstract</classname> promotes. For this cases you can
217             use the <classname>Zend_Paginator_AdapterAggregate</classname> interface that behaves
218             much like the <classname>IteratorAggregate</classname> interface of the
219             <acronym>PHP</acronym> SPL extension.
220         </para>
222         <programlisting language="php"><![CDATA[
223 interface Zend_Paginator_AdapterAggregate
225     /**
226      * Return a fully configured Paginator Adapter from this method.
227      *
228      * @return Zend_Paginator_Adapter_Abstract
229      */
230     public function getPaginatorAdapter();
232 ]]></programlisting>
234         <para>
235             The interface is fairly small and only expects you to return an instance of
236             <classname>Zend_Paginator_Adapter_Abstract</classname>. An Adapter Aggregate instance is
237             then recognized by both <code>Zend_Paginator::factory</code> and the constructor of
238             <classname>Zend_Paginator</classname> and handled accordingly.
239         </para>
240     </sect2>
241 </sect1>
242 <!--
243 vim:se ts=4 sw=4 et: