1 <?xml version="1.0" encoding="UTF-8"?>
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>
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
16 To do so, you must implement
17 <classname>Zend_Paginator_Adapter_Interface</classname>. There are two
18 methods required to do this:
27 <para>getItems($offset, $itemCountPerPage)</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.
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.
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:
56 <programlisting language="php"><![CDATA[
57 return array_slice($this->_array, $offset, $itemCountPerPage);
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.
67 <sect2 id="zend.paginator.advanced.scrolling-styles">
68 <title>Custom scrolling styles</title>
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,
76 <programlisting language="php"><![CDATA[
77 public function getPages(Zend_Paginator $paginator, $pageRange = null);
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).
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:
93 <programlisting language="php"><![CDATA[
94 return $paginator->getPagesInRange($lowerBound, $upperBound);
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.
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:
109 <programlisting language="php"><![CDATA[
110 $prefix = 'My_Paginator_ScrollingStyle';
111 $path = 'My/Paginator/ScrollingStyle/';
112 Zend_Paginator::addScrollingStylePrefixPath($prefix, $path);
116 <sect2 id="zend.paginator.advanced.caching">
117 <title>Caching features</title>
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>
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);
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.
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
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:
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();
175 Changing the item count per page will empty the whole cache
176 as it would have become invalid:
179 <programlisting language="php"><![CDATA[
180 $paginator = Zend_Paginator::factory($someData);
181 Zend_Paginator::setCache($cache);
183 $items = $paginator->getCurrentItems();
185 // all the cache data will be flushed:
186 $paginator->setItemCountPerPage(2);
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:
194 <programlisting language="php"><![CDATA[
195 $paginator = Zend_Paginator::factory($someData);
196 $paginator->setItemCountPerPage(3);
197 Zend_Paginator::setCache($cache);
200 $items = $paginator->getCurrentItems();
201 $otherItems = $paginator->getItemsPerPage(4);
203 // see the cached items as a two-dimension array:
204 var_dump($paginator->getPageItemCache());
208 <sect2 id="zend.paginator.advanced.aggregator">
209 <title>Zend_Paginator_AdapterAggregate Interface</title>
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.
222 <programlisting language="php"><![CDATA[
223 interface Zend_Paginator_AdapterAggregate
226 * Return a fully configured Paginator Adapter from this method.
228 * @return Zend_Paginator_Adapter_Abstract
230 public function getPaginatorAdapter();
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.