Sistem de paginare folosind Zend Framework
0Paginare datelor este un mijloc eficient de a reduce datele raportate unui utilizator la o sectiune de interes local in ideea de a economisi timp de executie, spatiu de afisare si se a crea niste raportari prietenoase. Exemplul cel mai simplu in reprezinta afisarea unor produse dintr-un magazin online pe … pagini, lucru care are avantajul ca pe de partea clientului nu incarca excesiv pagina utilizatorului (un magazin poate avea cateva sute de produse, poate chiar mii) iar pe partea serverului nu solicita nici baza de date dar nici procesarile facute dupa ce un set de date a fost returnat aplicatiei, toate acestea facandu-se asupra unui set restrans de date.
Introdus in versiunea 1.6 a Zend Framework, modulul Zend_Paginator, asteptat inca din versiunea 0.9, se vrea a fi o componenta flexibila pentru paginarea colectiilor de date si prezentarea lor catre utilizatori. Principalele avantaje ale acestui modul sunt posibilitatea de a pagina orice set de date, nu doar cele provenite din baza de date, aduce si prelucreaza doar setul de date care urmeaza a fi afisat nu asupra tuturor datelor, plus ca fiind felxibil nu limiteaza programatorii doar la folosirea lui si intr-un anume mod, dar ofera totodata posibilitatea de folosirea a lui din alte componente ale framework-ului precum Zend_View sau Zend_Db.
Folosirea paginatorului este relativ simpla, si se foloseste de ideea ca pentru a putea pagina un set de date, in orice format ar fi el, este nevoie de un adaptro specific pentru a putea interactiona cu acele date. Astfel, pentru a putea pagina un vector, se poate folosi un array simplu din PHP, pentru a pagina un set de date returnate in urma unei interogari a bazei de date se foloseste o instanta a Zend_Db_Select, iar pentru a pagina un iterator se va folosi o instansa a acestei clase din SPL. Pentru a incepe folosirea paginatorului se poate instantia acesta folosind adaptorul dorit, sau se poate folosi metoda statica factory():
$array = array(‘Luni’, ‘Marti’, ‘Miercuri’, ‘Joi’, ‘Vineri’, ‘Sambata’, ‘Duminica’); $paginator = new Zend_Paginator(new Zend_Paginator_Adapter_Array($array)); $paginator = Zend_Paginator::factory($array);
In acest moment paginatorul are nevoie de o referinta pentru a putea determnia si prelucra sectiunea care va fi afisata utilizatorului, si anume pagina, informatie care de regula se stocheaza intr-un parametru al URL-ului(implicit va fi considerata pagina 1). Totodata se poate specifica si numarul de elemente care vor aparea intr-o pagina, acest numar este implicit 10.
$paginator->setCurrentPageNumber($this->_request->getParam(‘page’)); $paginator->setItemCountPerPage(20);
In final paginatorul se atribuie unei variabile din partea vizuala a aplicatiei …
$this->view->paginator = $paginator;
iar apoi va fi afisata
paginator as $element): ?>
Daca dorim paginarea unor date provenite din baza de date, cu siguranta ca va fi mai eficient ca interogarea facuta catre baza de date sa returneze doar acele date din pagina care ne intereseaza. Pentru acest lucru vom instantia paginatorul folosind un obiect de tipul Zend_Db_Select, care va contine o instructiune select personalizata pentru nevoile noastre.
class My_Model { public static function getCategoryList($category_id, $page = 1) { $databaseAdaptor = Zend_Registry::get('db'); try { $select = new Zend_Db_Select($databaseAdaptor); /*$select = $databaseAdaptor->select();*/ $select->from('products', array('id', 'name', 'price')) ->where('category_id = ?', $category_id) ->order('name asc') ; $paginator = Zend_Paginator::factory($select); $paginator->setCurrentPageNumber($page); $paginator->setItemCountPerPage(10); return $paginator; } catch (Zend_Exception $ex) { Zend_Debug:dump($ex); return null; } } }
Am creat asadar un model care va returna din baza de date toate produsele dintr-o anumita categorie, sortate dupa nume, folosind un obiect Zend_Db_Select instantiat folosind un adaptor pentru baza de date, care a fost preluat din registru. Rezultatul unei astefel de abordari poate fi procesat intr-un controller dupa cum urmeaza:
class IndexController extends Zend_Controller_Action { public function indexAction() { Zend_Loader::loadClass('My_Model'); $this->view->paginator = My_Model::getNewsletterList($this->_request->getParam('category_id'), $this->_request->getParam('page')); } }
Un alt aspect important al paginarii este capacitatea acestei componente de a genera un nagivator printre “paginile†astfel determinate ale paginarii, deci in ultima instanta posibilitatea de a avea acces secvential la tot setul de informatii. Zend_Paginator furnizeata unul chiar interesant, datorita facilitatilor ce le ofera.
echo $this->paginationControl($this->paginator, 'Sliding', 'pagination_control.phtml');
Desi ultimii doi parametri sunt optionali, iar controlul ar putea functiona perfect fara aceste doua informatii, acestia pot influenta foarte mult modul in care acest index al navigarii este construit. Ele se refera la, si influenteaza modul in care navigatorul generat va arata si comporta. Vom considera, pentru exemplificare, ca navigatorul generat de Google la o cautare ar fi generat chiar de catre Zend_Paginator.
Cel de-al doilea parametru controleaza ce se intampla daca actionam linkul “Precedenta†sau “Urmatoarele†si poate avea urmatoarele valori
- All caz in care va afisa toate paginile existente, lucru util pentru momentele cand numarul paginilor rezultate este relativ scazut
- Elastic caz in care paginile se largesc si se contracta in functie de pozitia in paginare si numarul de pagini – gen Google
- Jumping caz in care pe masura ce utilizatorul trece de la o pagina la alta, pagina curenta se muta catre finalul unui interval de pagini, la finalul caruia va continua cu un interval nou
- Sliding caz in care pagina curenta va fi afisata in centrul intervalului de pagini afisat, sau cel mai aproape posibil (gen Yahoo!); acesta este valoarea implicita
Cu toate acestea insa programatorul nu este restrictionat la acest set de posibilitati, oferindui-se posibilitatea de a-si crea singur porpiul paginator. Pentru acest lucru sunt disponibile o serie de metode predefinite:
- first() — numarul primei pagini
- firstItemNumber() — numarul primei inregistrari din pagina in setul general de date
- firstPageInRange() — numarul primei pagini din setul curent
- current() — numarul paginii curente
- currentItemCount() — numarul de elemente afisate pe pagina curenta
- last() — numarul ultimei pagini
- lastItemNumber() — numarul ultimei inregistrari din pagina in setul general de date
- lastPageInRange() — numarul ultimei pagini din setul curent
- next() — numarul paginii urmatoare
- pageCount() — numarul total de pagini
- pagesInRange() — paginile aflate in setul de pagini
- previous() — numarul paginii precedente
- totalItemCount() — numarul total de elemente
Prin setul curent de pagini, ne-am referit la paginile vizibile la o afisare.
Autor: George Enciu