Created
January 3, 2015 03:32
-
-
Save mcfog/2df96e37fc7fe3edbc6e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Paginator implements \IteratorAggregate | |
{ | |
const TPL_WRAPPER = 'wrapper'; | |
const TPL_NUM = 'num'; | |
const TPL_NUM_CURRENT = 'currentNum'; | |
const TPL_TAG = 'tag'; | |
const TPL_NEXT = 'next'; | |
const TPL_PREV = 'prev'; | |
const TPL_TEXT = 'text'; | |
const CFG_FIELD_NAME = 'fieldName'; | |
/** | |
* 当前页前后显示几页 | |
*/ | |
const CFG_NUM_MIDDLE = 'middleNum'; | |
/** | |
* 末页前显示几页 | |
*/ | |
const CFG_NUM_TAIL = 'tailNum'; | |
/** | |
* 首页后显示几页 | |
*/ | |
const CFG_NUM_HEAD = 'headNum'; | |
protected $app; | |
protected $data; | |
/** | |
* @var IListProvider | |
*/ | |
protected $list; | |
protected $config = [ | |
self::CFG_NUM_HEAD => 1, | |
self::CFG_NUM_TAIL => 1, | |
self::CFG_NUM_MIDDLE => 2, | |
self::CFG_FIELD_NAME => 'page', | |
]; | |
protected $template = [ | |
self::TPL_WRAPPER => <<<'HTML' | |
<div class="page_right fontsize9 fontcolor3">%s</div> | |
HTML | |
, | |
self::TPL_NUM => <<<'HTML' | |
<a class="p_num" href="%2$s">%1$d</a> | |
HTML | |
, | |
self::TPL_NUM_CURRENT => <<<'HTML' | |
<a class="p_num selected">%1$d</a> | |
HTML | |
, | |
self::TPL_TAG => <<<'HTML' | |
<a class="p_num first_or_last" href="%2$s">%1$s</a> | |
HTML | |
, | |
self::TPL_TEXT => <<<'HTML' | |
<span class="page_dian">%s</span> | |
HTML | |
, | |
self::TPL_NEXT => <<<'HTML' | |
<a class="p_num next" href="%1$s">下一页</a> | |
HTML | |
, | |
self::TPL_PREV => <<<'HTML' | |
<a class="p_num previous" href="%1$s">上一页</a> | |
HTML | |
, | |
]; | |
/** | |
* @var string | |
*/ | |
protected $urlBase; | |
/** | |
* @param Site $app | |
* @param IListProvider $list | |
* @param string $urlBase | |
*/ | |
public function __construct(Site $app, IListProvider $list, $urlBase = null) | |
{ | |
if (is_null($urlBase)) { | |
$urlBase = $app->request->getPath(); | |
} | |
$this->app = $app; | |
$this->list = $list; | |
$this->urlBase = $urlBase; | |
} | |
/** | |
* (PHP 5 >= 5.0.0)<br/> | |
* Retrieve an external iterator | |
* @link http://php.net/manual/en/iteratoraggregate.getiterator.php | |
* @return Traversable An instance of an object implementing <b>Iterator</b> or | |
* <b>Traversable</b> | |
*/ | |
public function getIterator() | |
{ | |
return new \ArrayIterator($this->getData()); | |
} | |
public function renderPaginator() | |
{ | |
$maxPage = $this->getMaxPage(); | |
$curPage = $this->getCurrentPage(); | |
if($maxPage <= 1) { | |
return ''; | |
} | |
$contents = []; | |
// $contents[] = $this->renderTpl(self::TPL_TAG, '首页', $this->getUrlForPage(1)); | |
if ($curPage !== 1) { | |
$contents[] = $this->renderTpl(self::TPL_PREV, $this->getUrlForPage($curPage - 1)); | |
} | |
for ($i = 1; $i <= $maxPage; $i++) { | |
$middleCount = $this->config[self::CFG_NUM_MIDDLE]; | |
switch (true) { | |
case $i === $curPage: | |
$contents[] = $this->renderTpl(self::TPL_NUM_CURRENT, $i); | |
break; | |
case $i >= $curPage - $middleCount && $i <= $curPage + $middleCount: | |
case $i <= $this->config[self::CFG_NUM_HEAD]: | |
case $i > $maxPage - $this->config[self::CFG_NUM_TAIL]: | |
$contents[] = $this->renderTpl(self::TPL_NUM, $i, $this->getUrlForPage($i)); | |
break; | |
default: | |
if ($i < $curPage) { | |
$contents[] = $this->renderTpl(self::TPL_TEXT, '...'); | |
$i = $curPage - $middleCount - 1; | |
} else { | |
$contents[] = $this->renderTpl(self::TPL_TEXT, '...'); | |
$i = $maxPage - $this->config[self::CFG_NUM_TAIL]; | |
} | |
} | |
} | |
if ($curPage !== $maxPage) { | |
$contents[] = $this->renderTpl(self::TPL_NEXT, $this->getUrlForPage($curPage + 1)); | |
} | |
// $contents[] = $this->renderTpl(self::TPL_TAG, '末页', $this->getUrlForPage($maxPage)); | |
return $this->renderTpl(self::TPL_WRAPPER, implode('', $contents)); | |
} | |
public function getUrlForPage($page) | |
{ | |
$part = parse_url($this->urlBase); | |
$query = []; | |
if (isset($part['query'])) { | |
parse_str($part['query'], $query); | |
} | |
$query[$this->config[self::CFG_FIELD_NAME]] = $page; | |
if (!isset($part['path'])) { | |
$part['path'] = '/'; | |
} | |
return sprintf('%s?%s', $part['path'], http_build_query($query)); | |
} | |
protected function renderTpl($tpl) | |
{ | |
$args = func_get_args(); | |
$args[0] = $this->template[$tpl]; | |
return call_user_func_array('sprintf', $args); | |
} | |
/** | |
* @return int | |
*/ | |
protected function getCurrentPage() | |
{ | |
$page = intval($this->app->request->get($this->config[self::CFG_FIELD_NAME])); | |
return min(max($page, 1), $this->getMaxPage()); | |
} | |
protected function getPager() | |
{ | |
return $this->list->getPager(); | |
} | |
public function getItemCount() | |
{ | |
$pager = $this->getPager(); | |
return intval($pager['count']); | |
} | |
public function getMaxPage() | |
{ | |
$pager = $this->getPager(); | |
return intval($pager['maxPage']); | |
} | |
/** | |
* @return array | |
*/ | |
protected function getData() | |
{ | |
if (!isset($this->data)) { | |
$this->data = $this->list->fetch($this->getCurrentPage()); | |
} | |
return $this->data; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment