1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect1 id="zend.paginator.advanced">
4 <title>Расширенное использование</title>
6 <sect2 id="zend.paginator.advanced.adapters">
7 <title>Создание собственных адаптеров к источникам данных</title>
10 Вы можете столкнуться с таким типом источника данных, для которого
11 в Zend Framework-е не предусмотрено адаптера. В этом случае
12 нужно создать собственный адаптер.
16 Для этого нужно реализовать интерфейс
17 <classname>Zend_Paginator_Adapter_Interface</classname>. Он включает
26 <para>getItems($offset, $itemCountPerPage)</para>
31 Кроме того, нужно реализовать конструктор, который принимает
32 источник данных в качестве параметра и сохраняет его в
33 защищенном или закрытом свойстве. Как его обрабатывать -
38 Если вы когда-либо использовали SPL-интерфейс
39 <ulink url="http://www.php.net/~helly/php/ext/spl/interfaceCountable.html"><classname>Countable</classname></ulink>,
40 то вам должно быть известно о назначении метода
41 <methodname>count()</methodname>. В
42 <classname>Zend_Paginator</classname> он возвращает общее количество
43 элементов в наборе данных.
44 Кроме того, объект <classname>Zend_Paginator</classname>
45 предоставляет метод <methodname>countAllItems()</methodname>
46 который служит посредником к методу адаптера
47 <methodname>count()</methodname>.
51 Метод <methodname>getItems()</methodname> ненамного сложнее.
52 Он должен принимать смещение и количество элементов на странице
53 и возвращать соответствующий кусок данных. В случае массива он
54 мог бы выглядеть следующим образом:
57 <programlisting language="php"><![CDATA[
58 return array_slice($this->_array, $offset, $itemCountPerPage);
62 Посмотрите исходники адаптеров, входящих в поставку
63 Zend Framework (все они реализуют
64 <classname>Zend_Paginator_Adapter_Interface</classname>), чтобы
65 получить представление о том, как можно реализовать свой адаптер.
69 <sect2 id="zend.paginator.advanced.scrolling-styles">
70 <title>Создание своих стилей прокрутки</title>
73 При создании своего стиля прокрутки реализуйте интерфейс
74 <classname>Zend_Paginator_ScrollingStyle_Interface</classname>,
75 который определяет единственный метод,
76 <methodname>getPages()</methodname>:
79 <programlisting language="php"><![CDATA[
80 public function getPages(Zend_Paginator $paginator, $pageRange = null);
84 Этот метод должен определять номера пограничных
85 страниц в ряде так называемых "локальных" страниц (т.е. страниц,
86 которые находятся рядом с текущей страницей).
90 Если только ваш стиль прокрутки не наследует от уже существующего
92 <classname>Zend_Paginator_ScrollingStyle_Elastic</classname>), то
93 этот метод должен иметь в конце что-то вроде следующего:
96 <programlisting language="php"><![CDATA[
97 return $paginator->getPagesInRange($lowerBound, $upperBound);
101 Этим вызовом не делается ничего особенного. Этот метод просто
102 для удобства - он проверяет на корректность верхний и нижний
103 пределы и возвращает массив номеров страниц для постраничной
108 Для того, чтобы использовать новый стиль прокрутки,
109 следует указать <classname>Zend_Paginator</classname>-у, в какой
110 директории этот стиль находится. Для этого сделайте следующее:
113 <programlisting language="php"><![CDATA[
114 $prefix = 'My_Paginator_ScrollingStyle';
115 $path = 'My/Paginator/ScrollingStyle/';
116 Zend_Paginator::addScrollingStylePrefixPath($prefix, $path);
120 <sect2 id="zend.paginator.advanced.caching">
121 <title>Возможности кэширования</title>
124 Можно указать <classname>Zend_Paginator</classname>-у, чтобы он
125 кэшировал получаемые данные, чтобы они не извлекались через
126 адаптер всякий раз, когда будет в них нужда.
127 Для этого просто передайте его методу
128 <methodname>setCache()</methodname> экземпляр
129 <classname>Zend_Cache_Core</classname>.
133 <programlisting language="php"><![CDATA[
134 $paginator = Zend_Paginator::factory($someData);
135 $fO = array('lifetime' => 3600, 'automatic_serialization' => true);
136 $bO = array('cache_dir'=>'/tmp');
137 $cache = Zend_cache::factory('Core', 'File', $fO, $bO);
138 Zend_Paginator::setCache($cache);
143 После того, как <classname>Zend_Paginator</classname> получит
144 экземпляр <classname>Zend_Cache_Core</classname>, все данные будут
145 кэшироваться. Иногда возникает необходимость отключать кэширование
146 данных даже после того, как вы передали эекземпляр
147 <classname>Zend_Cache_Core</classname>. Для этого вы можете
148 использовать метод <methodname>setCacheEnable()</methodname>.
152 <programlisting language="php"><![CDATA[
153 $paginator = Zend_Paginator::factory($someData);
154 // $cache является экземпляром
155 Zend_Paginator::setCache($cache);
157 $paginator->setCacheEnable(false);
158 // теперь кэширование отключено
163 После того, как был установлен объект для кэширования, данные будут
164 сохраняться и извлекаться через него. Иногда бывает нужно очищать
166 Вы можете делать это через вызов метода
167 <methodname>clearPageItemCache($pageNumber)</methodname>.
168 В качестве аргумента метод принимает номер страницы, кэш
169 которой следует очистить.
170 Если вызов производится без передачи параметра, то весь кэш будет
175 <programlisting language="php"><![CDATA[
176 $paginator = Zend_Paginator::factory($someData);
177 Zend_Paginator::setCache($cache);
178 $items = $paginator->getCurrentItems();
179 // теперь страница 1 в кэше
180 $page3Items = $paginator->getItemsByPage(3);
181 // теперь и страница 3 в кэше
183 // очищение кэша результатов для страницы 3
184 $paginator->clearPageItemCache(3);
186 // очищение всего кэша
187 $paginator->clearPageItemCache();
192 Изменение количества элементов на странице приведет к очищению
193 всего кэша, поскольку после этого он должен потерять актуальность:
197 <programlisting language="php"><![CDATA[
198 $paginator = Zend_Paginator::factory($someData);
199 Zend_Paginator::setCache($cache);
200 // извлечение некоторых элементов
201 $items = $paginator->getCurrentItems();
203 // весь кэш будет очищен:
204 $paginator->setItemCountPerPage(2);
209 Можно также видеть данные в кэше и запрашивать их напрямую.
210 Для этого может использоваться
211 метод <methodname>getPageItemCache()</methodname>:
215 <programlisting language="php"><![CDATA[
216 $paginator = Zend_Paginator::factory($someData);
217 $paginator->setItemCountPerPage(3);
218 Zend_Paginator::setCache($cache);
220 // извлечение некоторых элементов
221 $items = $paginator->getCurrentItems();
222 $otherItems = $paginator->getItemsPerPage(4);
224 // просмотр сохраненных в кэше элементов в виде двухмерного массива:
225 var_dump($paginator->getPageItemCache());
230 <sect2 id="zend.paginator.advanced.aggregator">
231 <title>Интерфейс Zend_Paginator_AdapterAggregate</title>
234 В зависимости от разрабатываемого приложения может возникнуть
235 потребность разбивать на страницы объекты, у которых внутренняя
236 структура данных эквивалентна существующим адаптерам,
237 но при этом вы не хотите нарушать инкапсуляцию для
238 того, что предоставлять доступ к этим данным.
239 В других случаях объект может участвовать в связи
240 "имеет-адаптер" вместо связи "является-адаптером", которую
241 предлагает <classname>Zend_Paginator_Adapter_Abstract</classname>.
242 В этих случаях вы можете использовать интерфейс
243 <classname>Zend_Paginator_AdapterAggregate</classname>,
244 который по поведению значительно похож на интерфейс
245 <classname>IteratorAggregate</classname> из расширения SPL.
249 <programlisting language="php"><![CDATA[
250 interface Zend_Paginator_AdapterAggregate
253 * Возвращайте из этого метода полностью сконфигурированный адаптер.
255 * @return Zend_Paginator_Adapter_Abstract
257 public function getPaginatorAdapter();
263 Как видно из кода, интерфейс довольно небольшой и от вас ожидается
264 только возврат экземпляра
265 <classname>Zend_Paginator_Adapter_Abstract</classname>.
267 <methodname>Zend_Paginator::factory</methodname> и конструктор
268 класса <classname>Zend_Paginator</classname> после этого распознают
269 экземпляр <classname>Zend_Paginator_AdapterAggregate</classname>
270 и обрабатывают его должным образом.