PageRenderTime 26ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/phpmyfaq/inc/Pagination.php

http://github.com/thorsten/phpMyFAQ
PHP | 378 lines | 161 code | 50 blank | 167 comment | 25 complexity | 403d43d432a3f9722d63c18bb1ea8531 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, LGPL-3.0
  1. <?php
  2. /**
  3. * Pagination handler class
  4. *
  5. * PHP Version 5.3
  6. *
  7. * This Source Code Form is subject to the terms of the Mozilla Public License,
  8. * v. 2.0. If a copy of the MPL was not distributed with this file, You can
  9. * obtain one at http://mozilla.org/MPL/2.0/.
  10. *
  11. * @category phpMyFAQ
  12. * @package PMF_Pagination
  13. * @author Anatoliy Belsky <ab@php.net>
  14. * @author Thorsten Rinne <thorsten@phpmyfaq.de>
  15. * @copyright 2009-2012 phpMyFAQ Team
  16. * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
  17. * @link http://www.phpmyfaq.de
  18. * @since 2009-09-27
  19. */
  20. if (!defined('IS_VALID_PHPMYFAQ')) {
  21. exit();
  22. }
  23. /**
  24. * PMF_Pagination
  25. *
  26. * @category phpMyFAQ
  27. * @package PMF_Pagination
  28. * @author Anatoliy Belsky <ab@php.net>
  29. * @author Thorsten Rinne <thorsten@phpmyfaq.de>
  30. * @copyright 2009-2012 phpMyFAQ Team
  31. * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
  32. * @link http://www.phpmyfaq.de
  33. * @since 2009-09-27
  34. */
  35. class PMF_Pagination
  36. {
  37. /**
  38. * Template vars
  39. */
  40. const TPL_VAR_LINK_URL = '{LINK_URL}';
  41. const TPL_VAR_LINK_TEXT = '{LINK_TEXT}';
  42. const TPL_VAR_LAYOUT_CONTENT = '{LAYOUT_CONTENT}';
  43. /**
  44. * Base url used for links
  45. *
  46. * @var string
  47. */
  48. protected $baseUrl = '';
  49. /**
  50. * Total items count
  51. *
  52. * @var integer
  53. */
  54. protected $total = 0;
  55. /**
  56. * Items per page count
  57. *
  58. * @var integer
  59. */
  60. protected $perPage = 0;
  61. /**
  62. * Number of adjacent links
  63. *
  64. * @var integer
  65. */
  66. protected $adjacents = 4;
  67. /**
  68. * Default link template.
  69. * Possible variables are {LINK}, {TITLE}, {TEXT}
  70. *
  71. * @var string
  72. */
  73. protected $linkTpl = '<li><a href="{LINK_URL}">{LINK_TEXT}</a></li>';
  74. /**
  75. * Current page link template
  76. *
  77. * @var string
  78. */
  79. protected $currentPageLinkTpl = '<li class="active"><a href="{LINK_URL}">{LINK_TEXT}</a></li>';
  80. /**
  81. * Next page link template
  82. *
  83. * @var string
  84. */
  85. protected $nextPageLinkTpl = '<li><a href="{LINK_URL}">&gt;</a></li>';
  86. /**
  87. * Previous page link template
  88. *
  89. * @var string
  90. */
  91. protected $prevPageLinkTpl = '<li><a href="{LINK_URL}">&lt;</a></li>';
  92. /**
  93. * First page link template
  94. *
  95. * @var string
  96. */
  97. protected $firstPageLinkTpl = '<li><a href="{LINK_URL}">â&#x2020;?</a></li>';
  98. /**
  99. * Last page link template
  100. *
  101. * @var string
  102. */
  103. protected $lastPageLinkTpl = '<li><a href="{LINK_URL}">â&#x2020;&#x2019;</a></li>';
  104. /**
  105. * Layout template
  106. *
  107. * @var string
  108. */
  109. protected $layoutTpl = '<div class="pagination pagination-centered"><ul>{LAYOUT_CONTENT}</ul></div>';
  110. /**
  111. * Current page index
  112. *
  113. * @var integer
  114. */
  115. protected $currentPage = 0;
  116. /**
  117. * Param name to associate the page numbers to
  118. *
  119. * @var string
  120. */
  121. protected $pageParamName = 'page';
  122. /**
  123. * SEO name
  124. *
  125. * @var string
  126. */
  127. protected $seoName = '';
  128. /**
  129. * @var PMF_Configuration
  130. */
  131. private $_config;
  132. /**
  133. * Constructor
  134. *
  135. * We read in the current page from the baseUrl, so if it contains
  136. * no pageParamName, first page is asumed
  137. *
  138. * @param PMF_Configuration $config
  139. * @param array $options initialization options,
  140. * possible options:
  141. * - baseUrl (default "")
  142. * - total
  143. * - perPage
  144. * - linkTpl
  145. * - currentPageLinkTpl
  146. * - nextPageLinkTpl
  147. * - prevPageLinkTpl
  148. * - firstPageLinkTpl
  149. * - lastPageLinkTpl
  150. * - layoutTpl
  151. * - pageParamName (default "page")
  152. *
  153. * @return PMF_Pagination
  154. */
  155. public function __construct(PMF_Configuration $config, Array $options = null)
  156. {
  157. $this->_config = $config;
  158. if (isset($options['baseUrl'])) {
  159. $this->baseUrl = $options['baseUrl'];
  160. }
  161. if (isset($options['total'])) {
  162. $this->total = $options['total'];
  163. }
  164. if (isset($options['perPage'])) {
  165. $this->perPage = $options['perPage'];
  166. }
  167. if (isset($options['linkTpl'])) {
  168. $this->linkTpl = $options['linkTpl'];
  169. }
  170. if (isset($options['currentPageLinkTpl'])) {
  171. $this->currentPageLinkTpl = $options['currentPageLinkTpl'];
  172. }
  173. if (isset($options['nextPageLinkTpl'])) {
  174. $this->nextPageLinkTpl = $options['nextPageLinkTpl'];
  175. }
  176. if (isset($options['prevPageLinkTpl'])) {
  177. $this->prevPageLinkTpl = $options['prevPageLinkTpl'];
  178. }
  179. if (isset($options['firstPageLinkTpl'])) {
  180. $this->firstPageLinkTpl = $options['firstPageLinkTpl'];
  181. }
  182. if (isset($options['lastPageLinkTpl'])) {
  183. $this->lastPageLinkTpl = $options['lastPageLinkTpl'];
  184. }
  185. if (isset($options['layoutTpl'])) {
  186. $this->layoutTpl = $options['layoutTpl'];
  187. }
  188. if (isset($options['pageParamName'])) {
  189. $this->pageParamName = $options['pageParamName'];
  190. }
  191. if (isset($options['seoName'])) {
  192. $this->seoName = $options['seoName'];
  193. }
  194. // Let this call to be last cuz it needs some options to be set before
  195. $this->currentPage = $this->getCurrentPageFromUrl($this->baseUrl);
  196. }
  197. /**
  198. * Returns the current page URL
  199. *
  200. * @param string $url URL
  201. *
  202. * @return integer
  203. */
  204. protected function getCurrentPageFromUrl($url)
  205. {
  206. $page = 1;
  207. if (!empty($url)) {
  208. $match = array();
  209. if (PMF_String::preg_match('$&(amp;|)' . $this->pageParamName . '=(\d+)$', $url, $match)) {
  210. $page = isset($match[2]) ? $match[2] : $page;
  211. }
  212. }
  213. return $page;
  214. }
  215. /**
  216. * Render full pagination string
  217. *
  218. * @return string
  219. */
  220. public function render()
  221. {
  222. $content = array();
  223. $pages = ceil($this->total / $this->perPage);
  224. $adjacents = floor($this->adjacents / 2) >= 1 ? floor($this->adjacents / 2) : 1;
  225. for ($page = 1; $page <= $pages; $page++) {
  226. if ($page > $this->adjacents && $page < $this->currentPage - $adjacents) {
  227. $content[] = '&hellip;';
  228. $page = $this->currentPage - $adjacents - 1;
  229. continue;
  230. }
  231. if ($page > $this->currentPage + $adjacents && $page <= $pages - $this->adjacents) {
  232. $content[] = '&hellip;';
  233. $page = $pages - $this->adjacents;
  234. continue;
  235. }
  236. $link = $this->renderUrl($this->baseUrl, $page);
  237. if ($page == $this->currentPage) {
  238. $template = $this->currentPageLinkTpl;
  239. } else {
  240. $template = $this->linkTpl;
  241. }
  242. $content[] = $this->renderLink($template, $link, $page);
  243. }
  244. if (1 < $this->currentPage) {
  245. array_unshift(
  246. $content,
  247. $this->renderLink(
  248. $this->prevPageLinkTpl,
  249. $this->renderUrl($this->baseUrl, $this->currentPage - 1),
  250. $this->currentPage - 1
  251. )
  252. );
  253. array_unshift(
  254. $content,
  255. $this->renderLink(
  256. $this->firstPageLinkTpl,
  257. $this->renderUrl($this->baseUrl, 1),
  258. 1
  259. )
  260. );
  261. }
  262. if ($page - 1 > $this->currentPage) {
  263. array_push(
  264. $content,
  265. $this->renderLink(
  266. $this->nextPageLinkTpl,
  267. $this->renderUrl($this->baseUrl, $this->currentPage + 1),
  268. $this->currentPage + 1
  269. )
  270. );
  271. array_push(
  272. $content,
  273. $this->renderLink(
  274. $this->lastPageLinkTpl,
  275. $this->renderUrl($this->baseUrl, $page - 1),
  276. $page - 1
  277. )
  278. );
  279. }
  280. return $this->renderLayout(implode('&nbsp;&nbsp;', $content));
  281. }
  282. /**
  283. * Render url for a given page
  284. *
  285. * @param string $url url
  286. * @param integer $page page number
  287. *
  288. * @return string
  289. */
  290. protected function renderUrl($url, $page)
  291. {
  292. $cleanedUrl = PMF_String::preg_replace(
  293. array('$&(amp;|)' . $this->pageParamName . '=(\d+)$'),
  294. '',
  295. $url
  296. );
  297. $url = sprintf('%s&amp;%s=%d', $cleanedUrl, $this->pageParamName, $page);
  298. $link = new PMF_Link($url, $this->_config);
  299. $link->itemTitle = $this->seoName;
  300. return $link->toString();
  301. }
  302. /**
  303. * Render a link
  304. *
  305. * @param string $tpl link template
  306. * @param string $url url value for template container
  307. * @param string $linkText text value for template container
  308. *
  309. * @return string
  310. */
  311. protected function renderLink($tpl, $url, $linkText)
  312. {
  313. $search = array(self::TPL_VAR_LINK_URL, self::TPL_VAR_LINK_TEXT);
  314. $replace = array($url, $linkText);
  315. return str_replace($search, $replace, $tpl);
  316. }
  317. /**
  318. * Render the whole pagination layout
  319. *
  320. * @param string $content layout contents
  321. *
  322. * @return string
  323. */
  324. protected function renderLayout($content)
  325. {
  326. return str_replace(self::TPL_VAR_LAYOUT_CONTENT, $content, $this->layoutTpl);
  327. }
  328. }