* @license PHP License * @package WB * @subpackage db */ /** * Simple pager * * @version 0.2.1 * @package WB * @subpackage db */ class WBDatasource_Pager extends WBStdClass { /** * datasource * @var WBDatasource */ protected $_source; /** * id * @var string */ protected $_id; /** * limit * @var string */ protected $_limit; /** * position of options * @var int */ protected $_optPos = 1; /** * current pager * @var array */ protected $_pager = array(); /** * args * @var array */ protected $_args = array(); /** * session * @var patSession_Storage */ protected $_sess; /** * constructor * * @param array $parameter */ public function __construct( $parameter = array() ) { if (!isset($parameter['id'])) { WBClass::load('WBException_Argument'); throw new WBException_Argument('Pager id is required.', 1, __CLASS__); } if (!isset($parameter['source'])) { WBClass::load('WBException_Argument'); throw new WBException_Argument('Source is required.', 2, __CLASS__); } if (!isset($parameter['limit'])) { WBClass::load('WBException_Argument'); throw new WBException_Argument('Limit is required.', 3, __CLASS__); } if (!isset($parameter['options'])) { WBClass::load('WBException_Argument'); throw new WBException_Argument('Need to know the position of get options.', 4, __CLASS__); } $this->_source = $parameter['source']; $this->_limit = $parameter['limit']; $this->_optPos = $parameter['options']; $this->_id = $parameter['id'] . '-' . $this->_limit; $this->_sess = WBClass::create('patSession'); if ($this->_sess->has( 'WBDatasource.Pager.' . $this->_id)) { $this->_pager = $this->_sess->get( 'WBDatasource.Pager.' . $this->_id ); } if (empty($this->_pager)) { $this->_pager = array(); $this->_pager['limit'] = $this->_limit; $this->_pager['total'] = '__undefined'; $this->_pager['pages'] = '__undefined'; $this->_pager['next'] = 0; $this->_pager['prev'] = 0; $this->_pager['offset'] = 0; $this->_pager['current'] = 0; $this->_pager['page'] = 1; $this->_pager['page_prev'] = 0; $this->_pager['page_next'] = 0; } } /** * destruct * * save current pager position in session */ public function __destruct() { $this->_sess->set('WBDatasource.Pager.' . $this->_id, $this->_pager); } /** * init pager * * @param mixed $args... * @return bool true on success */ public function setArgs() { $this->_args = func_get_args(); return true; } /** * Wrapper for get function to receive a list * * @return array list */ public function get() { $this->_args[$this->_optPos]['limit'] = $this->_pager['limit']; $this->_args[$this->_optPos]['offset'] = $this->_pager['offset']; $list = call_user_func_array(array($this->_source, 'get'), $this->_args); foreach ($list as $i => &$l) { $l['pager_row_var'] = $this->_pager['offset'] + 1 + $i; } return $list; } /** * go to page number # * * Calculate offest for next get(). * * @param string|int $goto page number * @return array $pager info */ public function browse( $goto = '__first' ) { $total = $this->_source->count($this->_args[0] , $this->_args[1] , $this->_args[2] , $this->_args[3] , $this->_args[$this->_optPos] ); $pages = ceil($total / $this->_limit); $this->_pager['pages'] = $pages; $this->_pager['total'] = $total; $this->_pager['next'] = 0; $this->_pager['prev'] = 0; switch (strtolower($goto)) { case '__first': $goto = 0; break; case '__prev': $goto = $this->_pager['current']; --$goto; break; case '__current': $goto = $this->_pager['current']; break; case '__next': $goto = $this->_pager['current']; ++$goto; break; case '__last': $goto = $pages - 1; break; default: // goto starts at zero but human readable pages start at one --$goto; break; } // stay within boundaries if ($goto < 0) { $goto = 0; } if ($goto > ($pages - 1)) { $goto = $pages - 1; } // is it allow to browse next and previous? if ($goto > 0) { $this->_pager['prev'] = 1; } if ($goto < ($pages -1)) { $this->_pager['next'] = 1; } // assample pager information $this->_pager['current'] = $goto; $this->_pager['page'] = $goto + 1; $this->_pager['offset'] = $goto * $this->_limit; $this->_pager['page_prev'] = $this->_pager['page'] - $this->_pager['prev']; $this->_pager['page_next'] = $this->_pager['page'] + $this->_pager['next']; return $this->_pager; } } ?>