Egy régi gond megoldása: Paginate 1.1 alatt

A hétvégén tetszhalott állapotban (felénk í­gy hí­vják, ha a férfiember egy kis megfázástól küzködve élni se bí­r) találkoztam egy régi kedves problémával: de jó lenne normális lapozó (mondjuk pont, mint az 1.2-ben) cake 1.1 alá is. Úgy esett, hogy egy model miatt az 1.2 (svn és a letölthető zipes is) összekakilta magát és ha már ott volt magával rántotta az apache-ot is. Mondanom se kell, hogy 1.1-gyel tökéletesen működött minden.

állapotomra való tekintettel nem áltam neki túl hosszan vacakolni (a halál küszöbén lustább már az ember), inkább egye fene csináljuk meg ugyanezt 1.1 alá. Időközben még hozzácsapódott egy-két hasznos dolog, ami a lapozós cucctól függetlenül is jól használható.

Az itt bemutatott kódok jelenlegi formájukban is működőképesek, ám érdemes meggondolni újraszervezésüket egy komponens formájában. Egyébként mindenki saját felelősségére úgy játszik vele, ahogy akar😉.

Kezdjük neki. Az egyik tetszetős dolog 1.2 alatt az, hogy az URL-ben szereplő …/key:value/… párokkal szépen lehet értéket átadni (ala GET). Ezek az értékek a controller alatt a

$this->passedArgs[KEY]

módon érhetők el. Kicsit végig gondolva a dolgot nem olyan bonyolult ez. Először is kell egy függvény a controllerbe (app_controller), ami ezt elvégzi: _parsePassedArgs();

function _parsePassedArgs() {
   $this->passedArgs = array();
   $url = $this->params['url']['url'];

   preg_match_all('%(w+):(w+)%', $url, $matches, PREG_SET_ORDER);
   foreach ($matches as $match) {
      $this->passedArgs[$match[1]] = $match[2];
   }
}

UPDATE: az egészben vicces, hogy mí­g 1.2 alatt a lapozó működéséhez szükség van a teljes controller/action párosra az url-ben, addig itt ez minden probléma nélkül működik. Világosabban: 1.2 esetén a /posts/page:2 hibát ad vissza, mivel szerinte page2 action nincs a posts_controller-ben, addig itt a /posts/page:2 simán működik.

Ezzel megvagyunk, szépen működik. Kicsit előre ugorva: szükségünk lesz néhány függvényre, amely nyilvántartja, hogy hol voltunk utoljára lapozás közben és ha kell visszaadja azt. Gondoljuk meg, ha egy lista közepén megnyitunk egy rekordot szerkesztésre, majd save után nem a korábbi pozí­cióban találjuk magunkat, hanem visszadob a lista elejére. Ezt szeretnénk elkerülni.

var $_urlSaverActions = array('index', 'lista');
function _saveReturnUrl() {
   if (isset($this->params['action']) &&
      in_array($this->params['action'], $this->_urlSaverActions)) {

      $this->Session->write('User.URL', $this->params['url']['url']);
   }
}

function _readReturnUrl() {
   if ($this->Session->check('User.URL')) {
      return $this->Session->read('User.URL');
   } else {
      return '/'.$this->params['controller'];
   }
}

A _saveReturnUrl() menti az aktuális url-t, ha az éppen használatos action eleme a $_urlSaverActions tömbben megadottak egyikének. Erre azért van szükség, hogy pl edit esetén ne mentsük feleslegesen az urlt. Valszeg nem a legjobb megoldás, viszont eddig még működik.
Ehhez még szükség van a generált controllerek kis átí­rására: add, edit, delete sikeressége esetén a redirect ne az index action legyen.

...
$this->redirect($this->_readReturnUrl());
...

Azt még hozzátenném, hogy mind a _parsePassedArgs(), mind a _saveReturnUrl() metódust érdemes beállí­tani az app_controller beforeFilter()-ébe.

function beforeFilter() {
   $this->_parsePassedArgs();
   $this->_saveReturnUrl();
}

A teljes kód letölthető, nem részletezem tovább.

Nem kí­vántam minden funkciót átvenni az 1.2-ből.
A következő funkciók működnek:

  1. controllerben: $paginate tagváltozóval a lapozó alapbeállí­tása
    var $paginate = array('limit' => 20, 'page' => 1, 'order' => array('id' => 'desc'));
  2. helperben:
    • $paginator->counter(): aktuális oldalszám, vagy egy megfelelően formázott stringgel egy részletes fejléc
      echo $paginator->counter(
       ''Page %page% of %pages%, showing %current% records out of %count% total,
         starting on record %start%, ending on %end%''
      );
    • $paginator->prev(), $paginator->next(): ha lehetséges, visszaadja az előző ill. a következő oldalhoz tartozó linket.
    • $paginator->first(), $paginator->last(): ha lehetséges, visszaadja az első ill. az utolsó oldalhoz tartozó linket.
    • $paginator->numbers(10): a paraméterben megadott oldalhoz jelení­t meg linkeket az aktuális oldal előtt és után.
    • $paginator->sort(SZOVEG, MEZO): SZOVEG – linkszöveggel, mező szerinti rendezéssel linket ad vissza (leginkább oszlop fejlécnek)

Felhí­vnám a figyelmet, hogy lusta voltam megnézni, hogyan működnek a fenti függvények 1.2 alatt, illetve azt is, hogy mi a pontos paraméter listájuk.

Amit nem tud a helper: ajax kéréseket kezelni. Erre egy más módszert ajánlok (de ez egy újabb bejegyzés témája). Az alapkoncepció az, hogy minden visszaadott link alapértelmezetten paginator osztályú (), ezek szépen elkaphatók külső javascripttel.

Kategória: cakephp, php
Címke:
Közvetlen link a könyvjelzőhöz.

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s