Zend_Paginator-Advanced.xml 9.6 KB

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