PageRenderTime 104ms CodeModel.GetById 60ms app.highlight 18ms RepoModel.GetById 22ms app.codeStats 1ms

/sally/core/lib/sly/Util/Pager.php

https://bitbucket.org/SallyCMS/trunk
PHP | 321 lines | 206 code | 51 blank | 64 comment | 43 complexity | 3192635344e48afaa13ee452249bfe08 MD5 | raw file
  1<?php
  2/*
  3 * Copyright (c) 2012, webvariants GbR, http://www.webvariants.de
  4 *
  5 * This file is released under the terms of the MIT license. You can find the
  6 * complete text in the attached LICENSE file or online at:
  7 *
  8 * http://www.opensource.org/licenses/mit-license.php
  9 */
 10
 11/**
 12 * @ingroup util
 13 */
 14class sly_Util_Pager {
 15	const FIRST_ACTIVE   = -1;  ///< int
 16	const FIRST_INACTIVE = -2;  ///< int
 17	const PREV_ACTIVE    = -3;  ///< int
 18	const PREV_INACTIVE  = -4;  ///< int
 19	const NEXT_ACTIVE    = -5;  ///< int
 20	const NEXT_INACTIVE  = -6;  ///< int
 21	const LAST_ACTIVE    = -7;  ///< int
 22	const LAST_INACTIVE  = -8;  ///< int
 23	const ELLIPSIS_LEFT  = -9;  ///< int
 24	const ELLIPSIS_RIGHT = -10; ///< int
 25
 26	protected $currentPage;     ///< int
 27	protected $totalElements;   ///< int
 28	protected $perPage;         ///< int
 29	protected $maxLinks;        ///< int
 30	protected $linksLeftRight;  ///< int
 31	protected $linksOnEnd;      ///< int
 32
 33	private $pages; ///< int
 34
 35	/**
 36	 * @param int $currentPage
 37	 * @param int $totalElements
 38	 * @param int $perPage
 39	 * @param int $maxLinks
 40	 * @param int $linksLeftRight
 41	 * @param int $linksOnEnds
 42	 */
 43	public function __construct($currentPage, $totalElements, $perPage = 10, $maxLinks = 10, $linksLeftRight = 2, $linksOnEnds = 2) {
 44		$this->currentPage    = abs((int) $currentPage);
 45		$this->totalElements  = abs((int) $totalElements);
 46		$this->perPage        = abs((int) $perPage);
 47		$this->maxLinks       = abs((int) $maxLinks);
 48		$this->linksLeftRight = abs((int) $linksLeftRight);
 49		$this->linksOnEnd     = abs((int) $linksOnEnds);
 50
 51		$this->pages = ceil($this->totalElements / $this->perPage);
 52
 53		if ($this->currentPage > $this->pages-1) $this->currentPage = $this->pages - 1;
 54		if ($this->currentPage < 0) $this->currentPage = 0;
 55		if ($this->maxLinks < 5) $this->maxLinks = 5;
 56	}
 57
 58	/**
 59	 * @return array
 60	 */
 61	public function getPaginationData() {
 62		$result = array();
 63
 64		if ($this->currentPage > 0) {
 65			$result[] = self::FIRST_ACTIVE;
 66			$result[] = self::PREV_ACTIVE;
 67		}
 68		else {
 69			$result[] = self::FIRST_INACTIVE;
 70			$result[] = self::PREV_INACTIVE;
 71		}
 72
 73		if ($this->pages <= $this->maxLinks) {
 74			for ($i = 0; $i < $this->pages; ++$i) $result[] = $i;
 75			if ($this->pages == 0) $result[] = 0;
 76		}
 77		else {
 78			// Links am Anfang
 79
 80			$result[] = 0;
 81			for ($i = 0; $i < $this->linksOnEnd; ++$i) $result[] = $i+1;
 82
 83			// Links um die aktuelle Seite herum
 84
 85			$begin = $this->currentPage - $this->linksLeftRight;
 86			$end   = $this->currentPage + $this->linksLeftRight;
 87
 88			if ($begin-1 > $this->linksOnEnd) $result[] = self::ELLIPSIS_LEFT;
 89
 90			for ($i = $begin; $i <= $end; ++$i) {
 91				if ($i > 0 && $i < $this->pages) $result[] = $i;
 92			}
 93
 94			if ($end < ($this->pages - $this->linksOnEnd - 2)) $result[] = self::ELLIPSIS_RIGHT;
 95
 96			// Links am Ende
 97
 98			for ($i = $this->linksOnEnd; $i > 0; --$i) $result[] = $this->pages - $i - 1;
 99			$result[] = $this->pages - 1;
100
101			// Doppelte entfernen
102
103			$result = array_unique($result);
104		}
105
106		if ($this->currentPage < $this->pages - 1) {
107			$result[] = self::NEXT_ACTIVE;
108			$result[] = self::LAST_ACTIVE;
109		}
110		else {
111			$result[] = self::NEXT_INACTIVE;
112			$result[] = self::LAST_INACTIVE;
113		}
114
115		return $result;
116	}
117
118	/**
119	 * @param  array  $getParams
120	 * @param  string $pageParamName
121	 * @param  string $filename
122	 * @param  array  $specialSymbols
123	 * @return array
124	 */
125	public function getRawLinks($getParams = array(), $pageParamName = 'p', $filename = 'index.php', $specialSymbols = array()) {
126		// Standardwerte f?r die Spezialsymbole
127
128		if (!isset($specialSymbols['first_active']))   $specialSymbols['first_active']   = '|&laquo;';
129		if (!isset($specialSymbols['first_inactive'])) $specialSymbols['first_inactive'] = '|&laquo;';
130		if (!isset($specialSymbols['prev_active']))    $specialSymbols['prev_active']    = '&laquo;';
131		if (!isset($specialSymbols['prev_inactive']))  $specialSymbols['prev_inactive']  = '&laquo;';
132		if (!isset($specialSymbols['next_active']))    $specialSymbols['next_active']    = '&raquo;';
133		if (!isset($specialSymbols['next_inactive']))  $specialSymbols['next_inactive']  = '&raquo;';
134		if (!isset($specialSymbols['last_active']))    $specialSymbols['last_active']    = '&raquo;|';
135		if (!isset($specialSymbols['last_inactive']))  $specialSymbols['last_inactive']  = '&raquo;|';
136		if (!isset($specialSymbols['ellipsis']))       $specialSymbols['ellipsis']       = '&hellip;';
137
138		// Auf geht's!
139
140		$data = $this->getPaginationData();
141		if (isset($getParams[$pageParamName])) unset($getParams[$pageParamName]);
142		$links = array();
143
144		foreach ($data as $pageCode) {
145			$url     = '';
146			$text    = '';
147			$attribs = array();
148
149			switch ($pageCode) {
150				case self::FIRST_ACTIVE:
151					$url     = $this->getURL($filename, $getParams, $pageParamName, 0);
152					$text    = $specialSymbols['first_active'];
153					$attribs = array('class' => 'first');
154					break;
155
156				case self::FIRST_INACTIVE:
157					$url     = '';
158					$text    = $specialSymbols['first_inactive'];
159					$attribs = array('class' => 'first');
160					break;
161
162				case self::PREV_ACTIVE:
163					$url     = $this->getURL($filename, $getParams, $pageParamName, $this->currentPage-1);
164					$text    = $specialSymbols['prev_active'];
165					$attribs = array('class' => 'prev');
166					break;
167
168				case self::PREV_INACTIVE:
169					$url     = '';
170					$text    = $specialSymbols['prev_inactive'];
171					$attribs = array('class' => 'prev');
172					break;
173
174				case self::NEXT_ACTIVE:
175					$url     = $this->getURL($filename, $getParams, $pageParamName, $this->currentPage+1);
176					$text    = $specialSymbols['next_active'];
177					$attribs = array('class' => 'next');
178					break;
179
180				case self::NEXT_INACTIVE:
181					$url     = '';
182					$text    = $specialSymbols['next_inactive'];
183					$attribs = array('class' => 'next');
184					break;
185
186				case self::LAST_ACTIVE:
187					$url     = $this->getURL($filename, $getParams, $pageParamName, $this->pages - 1);
188					$text    = $specialSymbols['last_active'];
189					$attribs = array('class' => 'last');
190					break;
191
192				case self::LAST_INACTIVE:
193					$url     = '';
194					$text    = $specialSymbols['last_inactive'];
195					$attribs = array('class' => 'last');
196					break;
197
198				case self::ELLIPSIS_LEFT:
199				case self::ELLIPSIS_RIGHT:
200					$url     = '';
201					$text    = $specialSymbols['ellipsis'];
202					$attribs = array('class' => 'ellipsis');
203					break;
204
205				case $this->currentPage:
206					$url     = '';
207					$text    = $pageCode + 1;
208					$attribs = array('class' => 'active page'.($this->currentPage + 1));
209					break;
210
211				default:
212					$url       = $this->getURL($filename, $getParams, $pageParamName, $pageCode);
213					$text      = $pageCode + 1;
214					$direction = $pageCode < $this->currentPage ? 'before' : 'after';
215					$attribs   = array('class' => 'normal page'.($pageCode+1).' '.$direction);
216					break;
217			}
218
219			if (mb_strlen($text) > 0) {
220				$links[] = array(
221					'url'        => $url,
222					'text'       => $text,
223					'attributes' => $attribs
224				);
225			}
226		}
227
228		return $links;
229	}
230
231	/**
232	 * @param  array  $getParams
233	 * @param  string $pageParamName
234	 * @param  string $filename
235	 * @param  array  $specialSymbols
236	 * @return string
237	 */
238	public function getHTMLString($getParams = array(), $pageParamName = 'p', $filename = 'index.php', $specialSymbols = array()) {
239		$links = $this->getRawLinks($getParams, $pageParamName, $filename, $specialSymbols);
240
241		foreach ($links as $idx => $data) {
242			if (!empty($data['url'])) {
243				$data['attributes']['href'] = $data['url'];
244			}
245
246			foreach ($data['attributes'] as $name => $value) {
247				$data['attributes'][$name] = $name.'="'.$value.'"';
248			}
249
250			$attributes  = implode(' ', $data['attributes']);
251			$attributes  = empty($attributes) ? '' : " $attributes";
252			$tagName     = empty($data['url']) ? 'span' : 'a';
253			$links[$idx] = '<'.$tagName.$attributes.'>'.$data['text'].'</'.$tagName.'>';
254		}
255
256		return "\n".implode("\n", $links)."\n";
257	}
258
259	/**
260	 * @param  string $tag
261	 * @param  array  $getParams
262	 * @param  string $pageParamName
263	 * @param  string $filename
264	 * @param  array  $specialSymbols
265	 * @return string
266	 */
267	public function getHTMLList($tag = 'ul', $getParams = array(), $pageParamName = 'p', $filename = 'index.php', $specialSymbols = array()) {
268		$links  = $this->getRawLinks($getParams, $pageParamName, $filename, $specialSymbols);
269		$result = "\n<$tag class=\"pager\">";
270
271		foreach ($links as $idx => $data) {
272			foreach ($data['attributes'] as $name => $value) {
273				if ($name == 'class' && $value == 'first') unset($data['attributes'][$name]);
274				else $data['attributes'][$name] = $name.'="'.$value.'"';
275			}
276
277			$attributes = implode(' ', $data['attributes']);
278			$attributes = empty($attributes) ? '' : " $attributes";
279			$link       = empty($data['url']) ? '<span>'.$data['text'].'</span>' : '<a href="'.$data['url'].'">'.$data['text'].'</a>';
280			$result    .= "\n<li$attributes>$link</li>";
281		}
282
283		$result .= "\n</$tag>\n";
284		return $result;
285	}
286
287	/**
288	 * @return array
289	 */
290	public function getCurrentElements() {
291		$elements = array();
292		$base     = $this->currentPage * $this->perPage;
293		for ($i = 0; $i < $this->perPage; ++$i) {
294			$elements[] = $base + $i;
295		}
296		return $elements;
297	}
298
299	/**
300	 * @param  string $filename
301	 * @param  array  $getParams
302	 * @param  string $pageParamName
303	 * @param  int    $page
304	 * @return string
305	 */
306	protected function getURL($filename, $getParams = array(), $pageParamName = 'p', $page = 0) {
307		$link = $filename;
308		if ($page > 0) $getParams[$pageParamName] = $page;
309		$getString = http_build_query($getParams, '', '&amp;');
310		if (!empty($getString)) $link .= '?'.$getString;
311		return $link;
312	}
313
314	/**
315	 * @param  int $code
316	 * @return boolean
317	 */
318	public static function isEllipsis($code) {
319		return $code == self::ELLIPSIS_LEFT || $code == self::ELLIPSIS_RIGHT;
320	}
321}