• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List

E:/E/GEAMP/www/openbiz/openbiz/others/Zend/Paginator.php

00001 <?php
00025 require_once 'Zend/Loader/PluginLoader.php';
00026 
00030 require_once 'Zend/Json.php';
00031 
00038 class Zend_Paginator implements Countable, IteratorAggregate
00039 {
00045     const INTERNAL_ADAPTER = 'Zend_Paginator_Adapter_Internal';
00046 
00051     const CACHE_TAG_PREFIX = 'Zend_Paginator_';
00052 
00058     protected static $_adapterLoader = null;
00059 
00065     protected static $_config = null;
00066 
00072     protected static $_defaultScrollingStyle = 'Sliding';
00073 
00079     protected static $_defaultItemCountPerPage = 10;
00080 
00086     protected static $_scrollingStyleLoader = null;
00087 
00093     protected static $_cache;
00094 
00100     protected $_cacheEnabled = true;
00101 
00107     protected $_adapter = null;
00108 
00114     protected $_currentItemCount = null;
00115 
00121     protected $_currentItems = null;
00122 
00128     protected $_currentPageNumber = 1;
00129 
00135     protected $_filter = null;
00136 
00142     protected $_itemCountPerPage = null;
00143 
00149     protected $_pageCount = null;
00150 
00157     protected $_pageRange = 10;
00158 
00164     protected $_pages = null;
00165 
00171     protected $_view = null;
00172 
00179     public static function addAdapterPrefixPath($prefix, $path)
00180     {
00181         self::getAdapterLoader()->addPrefixPath($prefix, $path);
00182     }
00183 
00197     public static function addAdapterPrefixPaths(array $prefixPaths)
00198     {
00199         if (isset($prefixPaths['prefix']) && isset($prefixPaths['path'])) {
00200             self::addAdapterPrefixPath($prefixPaths['prefix'], $prefixPaths['path']);
00201         } else {
00202             foreach ($prefixPaths as $prefix => $path) {
00203                 if (is_array($path) && isset($path['prefix']) && isset($path['path'])) {
00204                     $prefix = $path['prefix'];
00205                     $path   = $path['path'];
00206                 }
00207 
00208                 self::addAdapterPrefixPath($prefix, $path);
00209             }
00210         }
00211     }
00212 
00219     public static function addScrollingStylePrefixPath($prefix, $path)
00220     {
00221         self::getScrollingStyleLoader()->addPrefixPath($prefix, $path);
00222     }
00223 
00237     public static function addScrollingStylePrefixPaths(array $prefixPaths)
00238     {
00239         if (isset($prefixPaths['prefix']) && isset($prefixPaths['path'])) {
00240             self::addScrollingStylePrefixPath($prefixPaths['prefix'], $prefixPaths['path']);
00241         } else {
00242             foreach ($prefixPaths as $prefix => $path) {
00243                 if (is_array($path) && isset($path['prefix']) && isset($path['path'])) {
00244                     $prefix = $path['prefix'];
00245                     $path   = $path['path'];
00246                 }
00247 
00248                 self::addScrollingStylePrefixPath($prefix, $path);
00249             }
00250         }
00251     }
00252 
00261     public static function factory($data, $adapter = self::INTERNAL_ADAPTER,
00262                                    array $prefixPaths = null)
00263     {
00264         if ($data instanceof Zend_Paginator_AdapterAggregate) {
00265             return new self($data->getPaginatorAdapter());
00266         } else {
00267             if ($adapter == self::INTERNAL_ADAPTER) {
00268                 if (is_array($data)) {
00269                     $adapter = 'Array';
00270                 } else if ($data instanceof Zend_Db_Table_Select) {
00271                     $adapter = 'DbTableSelect';
00272                 } else if ($data instanceof Zend_Db_Select) {
00273                     $adapter = 'DbSelect';
00274                 } else if ($data instanceof Iterator) {
00275                     $adapter = 'Iterator';
00276                 } else if (is_integer($data)) {
00277                     $adapter = 'Null';
00278                 } else {
00279                     $type = (is_object($data)) ? get_class($data) : gettype($data);
00280 
00284                     require_once 'Zend/Paginator/Exception.php';
00285 
00286                     throw new Zend_Paginator_Exception('No adapter for type ' . $type);
00287                 }
00288             }
00289 
00290             $pluginLoader = self::getAdapterLoader();
00291 
00292             if (null !== $prefixPaths) {
00293                 foreach ($prefixPaths as $prefix => $path) {
00294                     $pluginLoader->addPrefixPath($prefix, $path);
00295                 }
00296             }
00297 
00298             $adapterClassName = $pluginLoader->load($adapter);
00299 
00300             return new self(new $adapterClassName($data));
00301         }
00302     }
00303 
00309     public static function getAdapterLoader()
00310     {
00311         if (self::$_adapterLoader === null) {
00312             self::$_adapterLoader = new Zend_Loader_PluginLoader(
00313                 array('Zend_Paginator_Adapter' => 'Zend/Paginator/Adapter')
00314             );
00315         }
00316 
00317         return self::$_adapterLoader;
00318     }
00319 
00325     public static function setConfig(Zend_Config $config)
00326     {
00327         self::$_config = $config;
00328 
00329         $adapterPaths = $config->get('adapterpaths');
00330 
00331         if ($adapterPaths != null) {
00332             self::addAdapterPrefixPaths($adapterPaths->adapterpath->toArray());
00333         }
00334 
00335         $prefixPaths = $config->get('prefixpaths');
00336 
00337         if ($prefixPaths != null) {
00338             self::addScrollingStylePrefixPaths($prefixPaths->prefixpath->toArray());
00339         }
00340 
00341         $scrollingStyle = $config->get('scrollingstyle');
00342 
00343         if ($scrollingStyle != null) {
00344             self::setDefaultScrollingStyle($scrollingStyle);
00345         }
00346     }
00347 
00353     public static function getDefaultScrollingStyle()
00354     {
00355         return self::$_defaultScrollingStyle;
00356     }
00357 
00363     public static function getDefaultItemCountPerPage()
00364     {
00365         return self::$_defaultItemCountPerPage;
00366     }
00367 
00373     public static function setDefaultItemCountPerPage($count)
00374     {
00375         self::$_defaultItemCountPerPage = (int) $count;
00376     }
00377 
00383     public static function setCache(Zend_Cache_Core $cache)
00384     {
00385         self::$_cache = $cache;
00386     }
00387 
00393     public static function setDefaultScrollingStyle($scrollingStyle = 'Sliding')
00394     {
00395         self::$_defaultScrollingStyle = $scrollingStyle;
00396     }
00397 
00404     public static function getScrollingStyleLoader()
00405     {
00406         if (self::$_scrollingStyleLoader === null) {
00407             self::$_scrollingStyleLoader = new Zend_Loader_PluginLoader(
00408                 array('Zend_Paginator_ScrollingStyle' => 'Zend/Paginator/ScrollingStyle')
00409             );
00410         }
00411 
00412         return self::$_scrollingStyleLoader;
00413     }
00414 
00420     public function __construct($adapter)
00421     {
00422         if ($adapter instanceof Zend_Paginator_Adapter_Interface) {
00423             $this->_adapter = $adapter;
00424         } else if ($adapter instanceof Zend_Paginator_AdapterAggregate) {
00425             $this->_adapter = $adapter->getPaginatorAdapter();
00426         } else {
00430             require_once 'Zend/Paginator/Exception.php';
00431 
00432             throw new Zend_Paginator_Exception(
00433                 'Zend_Paginator only accepts instances of the type ' .
00434                 'Zend_Paginator_Adapter_Interface or Zend_Paginator_AdapterAggregate.'
00435             );
00436         }
00437 
00438         $config = self::$_config;
00439 
00440         if ($config != null) {
00441             $setupMethods = array('ItemCountPerPage', 'PageRange');
00442 
00443             foreach ($setupMethods as $setupMethod) {
00444                 $value = $config->get(strtolower($setupMethod));
00445 
00446                 if ($value != null) {
00447                     $setupMethod = 'set' . $setupMethod;
00448                     $this->$setupMethod($value);
00449                 }
00450             }
00451         }
00452     }
00453 
00459     public function __toString()
00460     {
00461         try {
00462             $return = $this->render();
00463             return $return;
00464         } catch (Exception $e) {
00465             trigger_error($e->getMessage(), E_USER_WARNING);
00466         }
00467 
00468         return '';
00469     }
00470 
00477     public function setCacheEnabled($enable)
00478     {
00479         $this->_cacheEnabled = (bool)$enable;
00480         return $this;
00481     }
00482 
00488     public function count()
00489     {
00490         if (!$this->_pageCount) {
00491             $this->_pageCount = $this->_calculatePageCount();
00492         }
00493 
00494         return $this->_pageCount;
00495     }
00496 
00502     public function getTotalItemCount()
00503     {
00504         return count($this->getAdapter());
00505     }
00506 
00513     public function clearPageItemCache($pageNumber = null)
00514     {
00515         if (!$this->_cacheEnabled()) {
00516             return $this;
00517         }
00518 
00519         if (null === $pageNumber) {
00520             $cleanTags = self::CACHE_TAG_PREFIX;
00521             foreach (self::$_cache->getIdsMatchingTags(array($this->_getCacheInternalId())) as $id) {
00522                 if (preg_match('|'.self::CACHE_TAG_PREFIX."(\d+)_.*|", $id, $page)) {
00523                     self::$_cache->remove($this->_getCacheId($page[1]));
00524                 }
00525             }
00526         } else {
00527             $cleanId = $this->_getCacheId($pageNumber);
00528             self::$_cache->remove($cleanId);
00529         }
00530         return $this;
00531     }
00532 
00540     public function getAbsoluteItemNumber($relativeItemNumber, $pageNumber = null)
00541     {
00542         $relativeItemNumber = $this->normalizeItemNumber($relativeItemNumber);
00543 
00544         if ($pageNumber == null) {
00545             $pageNumber = $this->getCurrentPageNumber();
00546         }
00547 
00548         $pageNumber = $this->normalizePageNumber($pageNumber);
00549 
00550         return (($pageNumber - 1) * $this->getItemCountPerPage()) + $relativeItemNumber;
00551     }
00552 
00558     public function getAdapter()
00559     {
00560         return $this->_adapter;
00561     }
00562 
00568     public function getCurrentItemCount()
00569     {
00570         if ($this->_currentItemCount === null) {
00571             $this->_currentItemCount = $this->getItemCount($this->getCurrentItems());
00572         }
00573 
00574         return $this->_currentItemCount;
00575     }
00576 
00582     public function getCurrentItems()
00583     {
00584         if ($this->_currentItems === null) {
00585             $this->_currentItems = $this->getItemsByPage($this->getCurrentPageNumber());
00586         }
00587 
00588         return $this->_currentItems;
00589     }
00590 
00596     public function getCurrentPageNumber()
00597     {
00598         return $this->normalizePageNumber($this->_currentPageNumber);
00599     }
00600 
00607     public function setCurrentPageNumber($pageNumber)
00608     {
00609         $this->_currentPageNumber = (integer) $pageNumber;
00610         $this->_currentItems      = null;
00611         $this->_currentItemCount  = null;
00612 
00613         return $this;
00614     }
00615 
00621     public function getFilter()
00622     {
00623         return $this->_filter;
00624     }
00625 
00632     public function setFilter(Zend_Filter_Interface $filter)
00633     {
00634         $this->_filter = $filter;
00635 
00636         return $this;
00637     }
00638 
00647     public function getItem($itemNumber, $pageNumber = null)
00648     {
00649         $itemNumber = $this->normalizeItemNumber($itemNumber);
00650 
00651         if ($pageNumber == null) {
00652             $pageNumber = $this->getCurrentPageNumber();
00653         }
00654 
00655         $page = $this->getItemsByPage($pageNumber);
00656         $itemCount = $this->getItemCount($page);
00657 
00658         if ($itemCount == 0) {
00662             require_once 'Zend/Paginator/Exception.php';
00663 
00664             throw new Zend_Paginator_Exception('Page ' . $pageNumber . ' does not exist');
00665         }
00666 
00667         if ($itemNumber > $itemCount) {
00671             require_once 'Zend/Paginator/Exception.php';
00672 
00673             throw new Zend_Paginator_Exception('Page ' . $pageNumber . ' does not'
00674                                              . ' contain item number ' . $itemNumber);
00675         }
00676 
00677         return $page[$itemNumber - 1];
00678     }
00679 
00685     public function getItemCountPerPage()
00686     {
00687         if (empty($this->_itemCountPerPage)) {
00688             $this->_itemCountPerPage = self::getDefaultItemCountPerPage();
00689         }
00690 
00691         return $this->_itemCountPerPage;
00692     }
00693 
00700     public function setItemCountPerPage($itemCountPerPage)
00701     {
00702         $this->_itemCountPerPage = (integer) $itemCountPerPage;
00703         if ($this->_itemCountPerPage < 1) {
00704             $this->_itemCountPerPage = $this->getItemCountPerPage();
00705         }
00706         $this->_pageCount        = $this->_calculatePageCount();
00707         $this->_currentItems     = null;
00708         $this->_currentItemCount = null;
00709 
00710         return $this;
00711     }
00712 
00719     public function getItemCount($items)
00720     {
00721         $itemCount = 0;
00722 
00723         if (is_array($items) || $items instanceof Countable) {
00724             $itemCount = count($items);
00725         } else { // $items is something like LimitIterator
00726             $itemCount = iterator_count($items);
00727         }
00728 
00729         return $itemCount;
00730     }
00731 
00737     public function getItemsByPage($pageNumber)
00738     {
00739         $pageNumber = $this->normalizePageNumber($pageNumber);
00740 
00741         if ($this->_cacheEnabled()) {
00742             $data = self::$_cache->load($this->_getCacheId($pageNumber));
00743             if ($data !== false) {
00744                 return $data;
00745             }
00746         }
00747 
00748         $offset = ($pageNumber - 1) * $this->getItemCountPerPage();
00749 
00750         $items = $this->_adapter->getItems($offset, $this->getItemCountPerPage());
00751 
00752         $filter = $this->getFilter();
00753 
00754         if ($filter !== null) {
00755             $items = $filter->filter($items);
00756         }
00757 
00758         if (!$items instanceof Traversable) {
00759             $items = new ArrayIterator($items);
00760         }
00761 
00762         if ($this->_cacheEnabled()) {
00763             self::$_cache->save($items, $this->_getCacheId($pageNumber), array($this->_getCacheInternalId()));
00764         }
00765 
00766         return $items;
00767     }
00768 
00774     public function getIterator()
00775     {
00776         return $this->getCurrentItems();
00777     }
00778 
00784     public function getPageRange()
00785     {
00786         return $this->_pageRange;
00787     }
00788 
00795     public function setPageRange($pageRange)
00796     {
00797         $this->_pageRange = (integer) $pageRange;
00798 
00799         return $this;
00800     }
00801 
00808     public function getPages($scrollingStyle = null)
00809     {
00810         if ($this->_pages === null) {
00811             $this->_pages = $this->_createPages($scrollingStyle);
00812         }
00813 
00814         return $this->_pages;
00815     }
00816 
00824     public function getPagesInRange($lowerBound, $upperBound)
00825     {
00826         $lowerBound = $this->normalizePageNumber($lowerBound);
00827         $upperBound = $this->normalizePageNumber($upperBound);
00828 
00829         $pages = array();
00830 
00831         for ($pageNumber = $lowerBound; $pageNumber <= $upperBound; $pageNumber++) {
00832             $pages[$pageNumber] = $pageNumber;
00833         }
00834 
00835         return $pages;
00836     }
00837 
00843     public function getPageItemCache()
00844     {
00845         $data = array();
00846         if ($this->_cacheEnabled()) {
00847             foreach (self::$_cache->getIdsMatchingTags(array($this->_getCacheInternalId())) as $id) {
00848                     if (preg_match('|'.self::CACHE_TAG_PREFIX."(\d+)_.*|", $id, $page)) {
00849                         $data[$page[1]] = self::$_cache->load($this->_getCacheId($page[1]));
00850                     }
00851             }
00852         }
00853         return $data;
00854     }
00855 
00862     public function getView()
00863     {
00864         if ($this->_view === null) {
00868             require_once 'Zend/Controller/Action/HelperBroker.php';
00869 
00870             $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
00871             if ($viewRenderer->view === null) {
00872                 $viewRenderer->initView();
00873             }
00874             $this->_view = $viewRenderer->view;
00875         }
00876 
00877         return $this->_view;
00878     }
00879 
00886     public function setView(Zend_View_Interface $view = null)
00887     {
00888         $this->_view = $view;
00889 
00890         return $this;
00891     }
00892 
00899     public function normalizeItemNumber($itemNumber)
00900     {
00901         if ($itemNumber < 1) {
00902             $itemNumber = 1;
00903         }
00904 
00905         if ($itemNumber > $this->getItemCountPerPage()) {
00906             $itemNumber = $this->getItemCountPerPage();
00907         }
00908 
00909         return $itemNumber;
00910     }
00911 
00918     public function normalizePageNumber($pageNumber)
00919     {
00920         if ($pageNumber < 1) {
00921             $pageNumber = 1;
00922         }
00923 
00924         $pageCount = $this->count();
00925 
00926         if ($pageCount > 0 && $pageNumber > $pageCount) {
00927             $pageNumber = $pageCount;
00928         }
00929 
00930         return $pageNumber;
00931     }
00932 
00939     public function render(Zend_View_Interface $view = null)
00940     {
00941         if (null !== $view) {
00942             $this->setView($view);
00943         }
00944 
00945         $view = $this->getView();
00946 
00947         return $view->paginationControl($this);
00948     }
00949 
00955     public function toJson()
00956     {
00957         $currentItems = $this->getCurrentItems();
00958 
00959         if ($currentItems instanceof Zend_Db_Table_Rowset_Abstract) {
00960             return Zend_Json::encode($currentItems->toArray());
00961         } else {
00962             return Zend_Json::encode($currentItems);
00963         }
00964     }
00965 
00972     protected function _cacheEnabled()
00973     {
00974         return ((self::$_cache !== null) && $this->_cacheEnabled);
00975     }
00976 
00987     protected function _getCacheId($page = null)
00988     {
00989         if ($page === null) {
00990             $page = $this->getCurrentPageNumber();
00991         }
00992         return self::CACHE_TAG_PREFIX . $page . '_' . $this->_getCacheInternalId();
00993     }
00994 
01003     protected function _getCacheInternalId()
01004     {
01005         return md5(serialize($this->getAdapter()) . $this->getItemCountPerPage());
01006     }
01007 
01013     protected function _calculatePageCount()
01014     {
01015         return (integer) ceil($this->getAdapter()->count() / $this->getItemCountPerPage());
01016     }
01017 
01024     protected function _createPages($scrollingStyle = null)
01025     {
01026         $pageCount         = $this->count();
01027         $currentPageNumber = $this->getCurrentPageNumber();
01028 
01029         $pages = new stdClass();
01030         $pages->pageCount        = $pageCount;
01031         $pages->itemCountPerPage = $this->getItemCountPerPage();
01032         $pages->first            = 1;
01033         $pages->current          = $currentPageNumber;
01034         $pages->last             = $pageCount;
01035 
01036         // Previous and next
01037         if ($currentPageNumber - 1 > 0) {
01038             $pages->previous = $currentPageNumber - 1;
01039         }
01040 
01041         if ($currentPageNumber + 1 <= $pageCount) {
01042             $pages->next = $currentPageNumber + 1;
01043         }
01044 
01045         // Pages in range
01046         $scrollingStyle = $this->_loadScrollingStyle($scrollingStyle);
01047         $pages->pagesInRange     = $scrollingStyle->getPages($this);
01048         $pages->firstPageInRange = min($pages->pagesInRange);
01049         $pages->lastPageInRange  = max($pages->pagesInRange);
01050 
01051         // Item numbers
01052         if ($this->getCurrentItems() !== null) {
01053             $pages->currentItemCount = $this->getCurrentItemCount();
01054             $pages->itemCountPerPage = $this->getItemCountPerPage();
01055             $pages->totalItemCount   = $this->getTotalItemCount();
01056             $pages->firstItemNumber  = (($currentPageNumber - 1) * $this->getItemCountPerPage()) + 1;
01057             $pages->lastItemNumber   = $pages->firstItemNumber + $pages->currentItemCount - 1;
01058         }
01059 
01060         return $pages;
01061     }
01062 
01069     protected function _loadScrollingStyle($scrollingStyle = null)
01070     {
01071         if ($scrollingStyle === null) {
01072             $scrollingStyle = self::$_defaultScrollingStyle;
01073         }
01074 
01075         switch (strtolower(gettype($scrollingStyle))) {
01076             case 'object':
01077                 if (!$scrollingStyle instanceof Zend_Paginator_ScrollingStyle_Interface) {
01081                     require_once 'Zend/View/Exception.php';
01082 
01083                     throw new Zend_View_Exception('Scrolling style must implement ' .
01084                         'Zend_Paginator_ScrollingStyle_Interface');
01085                 }
01086 
01087                 return $scrollingStyle;
01088 
01089             case 'string':
01090                 $className = self::getScrollingStyleLoader()->load($scrollingStyle);
01091 
01092                 return new $className();
01093 
01094             case 'null':
01095                 // Fall through to default case
01096 
01097             default:
01101                 require_once 'Zend/View/Exception.php';
01102 
01103                 throw new Zend_View_Exception('Scrolling style must be a class ' .
01104                     'name or object implementing Zend_Paginator_ScrollingStyle_Interface');
01105         }
01106     }
01107 }

Generated on Thu Apr 19 2012 17:01:18 for openbiz by  doxygen 1.7.2