PageRenderTime 71ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/common/libraries/plugin/pear/Pager/Common.php

https://bitbucket.org/renaatdemuynck/chamilo
PHP | 1756 lines | 725 code | 226 blank | 805 comment | 115 complexity | e215fe3893c416ab626aee5bf4911ad3 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * Contains the Pager_Common class
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * LICENSE: Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. The name of the author may not be used to endorse or promote products
  16. * derived from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
  19. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  20. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21. * IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. * @category HTML
  30. * @package Pager
  31. * @author Lorenzo Alberton <l.alberton@quipo.it>
  32. * @author Richard Heyes <richard@phpguru.org>
  33. * @copyright 2003-2007 Lorenzo Alberton, Richard Heyes
  34. * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
  35. * @version CVS: $Id: Common.php 137 2009-11-09 13:24:37Z vanpouckesven $
  36. * @link http://pear.php.net/package/Pager
  37. */
  38. /**
  39. * Two constants used to guess the path- and file-name of the page
  40. * when the user doesn't set any other value
  41. */
  42. if (substr($_SERVER['PHP_SELF'], - 1) == '/')
  43. {
  44. $http = (isset($_SERVER['HTTPS']) && ('on' == strtolower($_SERVER['HTTPS']))) ? 'https://' : 'http://';
  45. define('PAGER_CURRENT_FILENAME', '');
  46. define('PAGER_CURRENT_PATHNAME', $http . $_SERVER['HTTP_HOST'] . str_replace('\\', '/', $_SERVER['PHP_SELF']));
  47. }
  48. else
  49. {
  50. define('PAGER_CURRENT_FILENAME', preg_replace('/(.*)\?.*/', '\\1', basename($_SERVER['PHP_SELF'])));
  51. define('PAGER_CURRENT_PATHNAME', str_replace('\\', '/', dirname($_SERVER['PHP_SELF'])));
  52. }
  53. /**
  54. * Error codes
  55. */
  56. define('PAGER_OK', 0);
  57. define('ERROR_PAGER', - 1);
  58. define('ERROR_PAGER_INVALID', - 2);
  59. define('ERROR_PAGER_INVALID_PLACEHOLDER', - 3);
  60. define('ERROR_PAGER_INVALID_USAGE', - 4);
  61. define('ERROR_PAGER_NOT_IMPLEMENTED', - 5);
  62. /**
  63. * Pager_Common - Common base class for [Sliding|Jumping] Window Pager
  64. * Extend this class to write a custom paging class
  65. *
  66. * @category HTML
  67. * @package Pager
  68. * @author Lorenzo Alberton <l.alberton@quipo.it>
  69. * @author Richard Heyes <richard@phpguru.org>
  70. * @copyright 2003-2007 Lorenzo Alberton, Richard Heyes
  71. * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
  72. * @link http://pear.php.net/package/Pager
  73. */
  74. class Pager_Common
  75. {
  76. // {{{ class vars
  77. /**
  78. * @var integer number of items
  79. * @access private
  80. */
  81. var $_totalItems;
  82. /**
  83. * @var integer number of items per page
  84. * @access private
  85. */
  86. var $_perPage = 10;
  87. /**
  88. * @var integer number of page links for each window
  89. * @access private
  90. */
  91. var $_delta = 10;
  92. /**
  93. * @var integer current page number
  94. * @access private
  95. */
  96. var $_currentPage = 1;
  97. /**
  98. * @var integer total pages number
  99. * @access private
  100. */
  101. var $_totalPages = 1;
  102. /**
  103. * @var string CSS class for links
  104. * @access private
  105. */
  106. var $_linkClass = '';
  107. /**
  108. * @var string wrapper for CSS class name
  109. * @access private
  110. */
  111. var $_classString = '';
  112. /**
  113. * @var string path name
  114. * @access private
  115. */
  116. var $_path = PAGER_CURRENT_PATHNAME;
  117. /**
  118. * @var string file name
  119. * @access private
  120. */
  121. var $_fileName = PAGER_CURRENT_FILENAME;
  122. /**
  123. * @var boolean If false, don't override the fileName option. Use at your own risk.
  124. * @access private
  125. */
  126. var $_fixFileName = true;
  127. /**
  128. * @var boolean you have to use FALSE with mod_rewrite
  129. * @access private
  130. */
  131. var $_append = true;
  132. /**
  133. * @var string specifies which HTTP method to use
  134. * @access private
  135. */
  136. var $_httpMethod = 'GET';
  137. /**
  138. * @var string specifies which HTML form to use
  139. * @access private
  140. */
  141. var $_formID = '';
  142. /**
  143. * @var boolean whether or not to import submitted data
  144. * @access private
  145. */
  146. var $_importQuery = true;
  147. /**
  148. * @var string name of the querystring var for pageID
  149. * @access private
  150. */
  151. var $_urlVar = 'pageID';
  152. /**
  153. * @var array data to pass through the link
  154. * @access private
  155. */
  156. var $_linkData = array();
  157. /**
  158. * @var array additional URL vars
  159. * @access private
  160. */
  161. var $_extraVars = array();
  162. /**
  163. * @var array URL vars to ignore
  164. * @access private
  165. */
  166. var $_excludeVars = array();
  167. /**
  168. * @var boolean TRUE => expanded mode (for Pager_Sliding)
  169. * @access private
  170. */
  171. var $_expanded = true;
  172. /**
  173. * @var boolean TRUE => show accesskey attribute on <a> tags
  174. * @access private
  175. */
  176. var $_accesskey = false;
  177. /**
  178. * @var string extra attributes for the <a> tag
  179. * @access private
  180. */
  181. var $_attributes = '';
  182. /**
  183. * @var string onclick
  184. * @access private
  185. */
  186. var $_onclick = '';
  187. /**
  188. * @var string alt text for "first page" (use "%d" placeholder for page number)
  189. * @access private
  190. */
  191. var $_altFirst = 'first page';
  192. /**
  193. * @var string alt text for "previous page"
  194. * @access private
  195. */
  196. var $_altPrev = 'previous page';
  197. /**
  198. * @var string alt text for "next page"
  199. * @access private
  200. */
  201. var $_altNext = 'next page';
  202. /**
  203. * @var string alt text for "last page" (use "%d" placeholder for page number)
  204. * @access private
  205. */
  206. var $_altLast = 'last page';
  207. /**
  208. * @var string alt text for "page" (use optional "%d" placeholder for page number)
  209. * @access private
  210. */
  211. var $_altPage = 'page';
  212. /**
  213. * @var string image/text to use as "prev" link
  214. * @access private
  215. */
  216. var $_prevImg = '&lt;&lt; Back';
  217. /**
  218. * image/text to use as "prev" link when no prev link is needed (e.g. on the first page)
  219. * NULL deactivates it
  220. *
  221. * @var string
  222. * @access private
  223. */
  224. var $_prevImgEmpty = null;
  225. /**
  226. * @var string image/text to use as "next" link
  227. * @access private
  228. */
  229. var $_nextImg = 'Next &gt;&gt;';
  230. /**
  231. * image/text to use as "next" link when
  232. * no next link is needed (e.g. on the last page)
  233. * NULL deactivates it
  234. *
  235. * @var string
  236. * @access private
  237. */
  238. var $_nextImgEmpty = null;
  239. /**
  240. * @var string link separator
  241. * @access private
  242. */
  243. var $_separator = '';
  244. /**
  245. * @var integer number of spaces before separator
  246. * @access private
  247. */
  248. var $_spacesBeforeSeparator = 0;
  249. /**
  250. * @var integer number of spaces after separator
  251. * @access private
  252. */
  253. var $_spacesAfterSeparator = 1;
  254. /**
  255. * @var string CSS class name for current page link
  256. * @access private
  257. */
  258. var $_curPageLinkClassName = '';
  259. /**
  260. * @var string Text before current page link
  261. * @access private
  262. */
  263. var $_curPageSpanPre = '';
  264. /**
  265. * @var string Text after current page link
  266. * @access private
  267. */
  268. var $_curPageSpanPost = '';
  269. /**
  270. * @var string Text before first page link
  271. * @access private
  272. */
  273. var $_firstPagePre = '[';
  274. /**
  275. * @var string Text to be used for first page link
  276. * @access private
  277. */
  278. var $_firstPageText = '';
  279. /**
  280. * @var string Text after first page link
  281. * @access private
  282. */
  283. var $_firstPagePost = ']';
  284. /**
  285. * @var string Text before last page link
  286. * @access private
  287. */
  288. var $_lastPagePre = '[';
  289. /**
  290. * @var string Text to be used for last page link
  291. * @access private
  292. */
  293. var $_lastPageText = '';
  294. /**
  295. * @var string Text after last page link
  296. * @access private
  297. */
  298. var $_lastPagePost = ']';
  299. /**
  300. * @var string Will contain the HTML code for the spaces
  301. * @access private
  302. */
  303. var $_spacesBefore = '';
  304. /**
  305. * @var string Will contain the HTML code for the spaces
  306. * @access private
  307. */
  308. var $_spacesAfter = '';
  309. /**
  310. * @var string String used as title in <link rel="first"> tag
  311. * @access private
  312. */
  313. var $_firstLinkTitle = 'first page';
  314. /**
  315. * @var string String used as title in <link rel="next"> tag
  316. * @access private
  317. */
  318. var $_nextLinkTitle = 'next page';
  319. /**
  320. * @var string String used as title in <link rel="previous"> tag
  321. * @access private
  322. */
  323. var $_prevLinkTitle = 'previous page';
  324. /**
  325. * @var string String used as title in <link rel="last"> tag
  326. * @access private
  327. */
  328. var $_lastLinkTitle = 'last page';
  329. /**
  330. * @var string Text to be used for the 'show all' option in the select box
  331. * @access private
  332. */
  333. var $_showAllText = '';
  334. /**
  335. * @var array data to be paged
  336. * @access private
  337. */
  338. var $_itemData = null;
  339. /**
  340. * @var boolean If TRUE and there's only one page, links aren't shown
  341. * @access private
  342. */
  343. var $_clearIfVoid = true;
  344. /**
  345. * @var boolean Use session for storing the number of items per page
  346. * @access private
  347. */
  348. var $_useSessions = false;
  349. /**
  350. * @var boolean Close the session when finished reading/writing data
  351. * @access private
  352. */
  353. var $_closeSession = false;
  354. /**
  355. * @var string name of the session var for number of items per page
  356. * @access private
  357. */
  358. var $_sessionVar = 'setPerPage';
  359. /**
  360. * Pear error mode (when raiseError is called)
  361. * (see PEAR doc)
  362. *
  363. * @var integer $_pearErrorMode
  364. * @access private
  365. */
  366. var $_pearErrorMode = null;
  367. // }}}
  368. // {{{ public vars
  369. /**
  370. * @var string Complete set of links
  371. * @access public
  372. */
  373. var $links = '';
  374. /**
  375. * @var string Complete set of link tags
  376. * @access public
  377. */
  378. var $linkTags = '';
  379. /**
  380. * @var array Complete set of raw link tags
  381. * @access public
  382. */
  383. var $linkTagsRaw = array();
  384. /**
  385. * @var array Array with a key => value pair representing
  386. * page# => bool value (true if key==currentPageNumber).
  387. * can be used for extreme customization.
  388. * @access public
  389. */
  390. var $range = array();
  391. /**
  392. * @var array list of available options (safety check)
  393. * @access private
  394. */
  395. var $_allowed_options = array('totalItems', 'perPage', 'delta', 'linkClass', 'path', 'fileName', 'fixFileName',
  396. 'append', 'httpMethod', 'formID', 'importQuery', 'urlVar', 'altFirst', 'altPrev', 'altNext', 'altLast',
  397. 'altPage', 'prevImg', 'prevImgEmpty', 'nextImg', 'nextImgEmpty', 'expanded', 'accesskey', 'attributes',
  398. 'onclick', 'separator', 'spacesBeforeSeparator', 'spacesAfterSeparator', 'curPageLinkClassName',
  399. 'curPageSpanPre', 'curPageSpanPost', 'firstPagePre', 'firstPageText', 'firstPagePost', 'lastPagePre',
  400. 'lastPageText', 'lastPagePost', 'firstLinkTitle', 'nextLinkTitle', 'prevLinkTitle', 'lastLinkTitle',
  401. 'showAllText', 'itemData', 'clearIfVoid', 'useSessions', 'closeSession', 'sessionVar', 'pearErrorMode',
  402. 'extraVars', 'excludeVars', 'currentPage');
  403. // }}}
  404. // {{{ build()
  405. /**
  406. * Generate or refresh the links and paged data after a call to setOptions()
  407. *
  408. * @return void
  409. * @access public
  410. */
  411. function build()
  412. {
  413. //reset
  414. $this->_pageData = array();
  415. $this->links = '';
  416. $this->linkTags = '';
  417. $this->linkTagsRaw = array();
  418. $this->_generatePageData();
  419. $this->_setFirstLastText();
  420. if ($this->_totalPages > (2 * $this->_delta + 1))
  421. {
  422. $this->links .= $this->_printFirstPage();
  423. }
  424. $this->links .= $this->_getBackLink();
  425. $this->links .= $this->_getPageLinks();
  426. $this->links .= $this->_getNextLink();
  427. $this->linkTags .= $this->_getFirstLinkTag();
  428. $this->linkTags .= $this->_getPrevLinkTag();
  429. $this->linkTags .= $this->_getNextLinkTag();
  430. $this->linkTags .= $this->_getLastLinkTag();
  431. $this->linkTagsRaw['first'] = $this->_getFirstLinkTag(true);
  432. $this->linkTagsRaw['prev'] = $this->_getPrevLinkTag(true);
  433. $this->linkTagsRaw['next'] = $this->_getNextLinkTag(true);
  434. $this->linkTagsRaw['last'] = $this->_getLastLinkTag(true);
  435. if ($this->_totalPages > (2 * $this->_delta + 1))
  436. {
  437. $this->links .= $this->_printLastPage();
  438. }
  439. }
  440. // }}}
  441. // {{{ getPageData()
  442. /**
  443. * Returns an array of current pages data
  444. *
  445. * @param integer $pageID Desired page ID (optional)
  446. *
  447. * @return array Page data
  448. * @access public
  449. */
  450. function getPageData($pageID = null)
  451. {
  452. $pageID = empty($pageID) ? $this->_currentPage : $pageID;
  453. if (! isset($this->_pageData))
  454. {
  455. $this->_generatePageData();
  456. }
  457. if (! empty($this->_pageData[$pageID]))
  458. {
  459. return $this->_pageData[$pageID];
  460. }
  461. return array();
  462. }
  463. // }}}
  464. // {{{ getPageIdByOffset()
  465. /**
  466. * Returns pageID for given offset
  467. *
  468. * @param integer $index Offset to get pageID for
  469. *
  470. * @return integer PageID for given offset
  471. * @access public
  472. */
  473. function getPageIdByOffset($index)
  474. {
  475. $msg = 'function "getPageIdByOffset()" not implemented.';
  476. return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED);
  477. }
  478. // }}}
  479. // {{{ getOffsetByPageId()
  480. /**
  481. * Returns offsets for given pageID. Eg, if you
  482. * pass it pageID one and your perPage limit is 10
  483. * it will return (1, 10). PageID of 2 would
  484. * give you (11, 20).
  485. *
  486. * @param integer $pageID PageID to get offsets for
  487. *
  488. * @return array First and last offsets
  489. * @access public
  490. */
  491. function getOffsetByPageId($pageID = null)
  492. {
  493. $pageID = isset($pageID) ? $pageID : $this->_currentPage;
  494. if (! isset($this->_pageData))
  495. {
  496. $this->_generatePageData();
  497. }
  498. if (isset($this->_pageData[$pageID]) || is_null($this->_itemData))
  499. {
  500. return array(max(($this->_perPage * ($pageID - 1)) + 1, 1),
  501. min($this->_totalItems, $this->_perPage * $pageID));
  502. }
  503. return array(0, 0);
  504. }
  505. // }}}
  506. // {{{ getPageRangeByPageId()
  507. /**
  508. * Given a PageId, it returns the limits of the range of pages displayed.
  509. *
  510. * @param integer $pageID PageID to get offsets for
  511. *
  512. * @return array First and last offsets
  513. * @access public
  514. */
  515. function getPageRangeByPageId($pageID = null)
  516. {
  517. $msg = 'function "getPageRangeByPageId()" not implemented.';
  518. return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED);
  519. }
  520. // }}}
  521. // {{{ getLinks()
  522. /**
  523. * Returns back/next/first/last and page links,
  524. * both as ordered and associative array.
  525. *
  526. * NB: in original PEAR::Pager this method accepted two parameters,
  527. * $back_html and $next_html. Now the only parameter accepted is
  528. * an integer ($pageID), since the html text for prev/next links can
  529. * be set in the factory. If a second parameter is provided, then
  530. * the method act as it previously did. This hack was done to mantain
  531. * backward compatibility only.
  532. *
  533. * @param integer $pageID Optional pageID. If specified, links for that
  534. * page are provided instead of current one.
  535. * [ADDED IN NEW PAGER VERSION]
  536. * @param string $next_html HTML to put inside the next link
  537. * [deprecated: use the factory instead]
  538. *
  539. * @return array back/next/first/last and page links
  540. * @access public
  541. */
  542. function getLinks($pageID = null, $next_html = '')
  543. {
  544. $msg = 'function "getLinks()" not implemented.';
  545. return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED);
  546. }
  547. // }}}
  548. // {{{ getCurrentPageID()
  549. /**
  550. * Returns ID of current page
  551. *
  552. * @return integer ID of current page
  553. * @access public
  554. */
  555. function getCurrentPageID()
  556. {
  557. return $this->_currentPage;
  558. }
  559. // }}}
  560. // {{{ getNextPageID()
  561. /**
  562. * Returns next page ID. If current page is last page
  563. * this function returns FALSE
  564. *
  565. * @return mixed Next page ID or false
  566. * @access public
  567. */
  568. function getNextPageID()
  569. {
  570. return ($this->getCurrentPageID() == $this->numPages() ? false : $this->getCurrentPageID() + 1);
  571. }
  572. // }}}
  573. // {{{ getPreviousPageID()
  574. /**
  575. * Returns previous page ID. If current page is first page
  576. * this function returns FALSE
  577. *
  578. * @return mixed Previous page ID or false
  579. * @access public
  580. */
  581. function getPreviousPageID()
  582. {
  583. return $this->isFirstPage() ? false : $this->getCurrentPageID() - 1;
  584. }
  585. // }}}
  586. // {{{ numItems()
  587. /**
  588. * Returns number of items
  589. *
  590. * @return integer Number of items
  591. * @access public
  592. */
  593. function numItems()
  594. {
  595. return $this->_totalItems;
  596. }
  597. // }}}
  598. // {{{ numPages()
  599. /**
  600. * Returns number of pages
  601. *
  602. * @return integer Number of pages
  603. * @access public
  604. */
  605. function numPages()
  606. {
  607. return (int) $this->_totalPages;
  608. }
  609. // }}}
  610. // {{{ isFirstPage()
  611. /**
  612. * Returns whether current page is first page
  613. *
  614. * @return bool First page or not
  615. * @access public
  616. */
  617. function isFirstPage()
  618. {
  619. return ($this->_currentPage < 2);
  620. }
  621. // }}}
  622. // {{{ isLastPage()
  623. /**
  624. * Returns whether current page is last page
  625. *
  626. * @return bool Last page or not
  627. * @access public
  628. */
  629. function isLastPage()
  630. {
  631. return ($this->_currentPage == $this->_totalPages);
  632. }
  633. // }}}
  634. // {{{ isLastPageComplete()
  635. /**
  636. * Returns whether last page is complete
  637. *
  638. * @return bool Last age complete or not
  639. * @access public
  640. */
  641. function isLastPageComplete()
  642. {
  643. return ! ($this->_totalItems % $this->_perPage);
  644. }
  645. // }}}
  646. // {{{ _generatePageData()
  647. /**
  648. * Calculates all page data
  649. *
  650. * @return void
  651. * @access private
  652. */
  653. function _generatePageData()
  654. {
  655. // Been supplied an array of data?
  656. if (! is_null($this->_itemData))
  657. {
  658. $this->_totalItems = count($this->_itemData);
  659. }
  660. $this->_totalPages = ceil((float) $this->_totalItems / (float) $this->_perPage);
  661. $i = 1;
  662. if (! empty($this->_itemData))
  663. {
  664. foreach ($this->_itemData as $key => $value)
  665. {
  666. $this->_pageData[$i][$key] = $value;
  667. if (count($this->_pageData[$i]) >= $this->_perPage)
  668. {
  669. $i ++;
  670. }
  671. }
  672. }
  673. else
  674. {
  675. $this->_pageData = array();
  676. }
  677. //prevent URL modification
  678. $this->_currentPage = min($this->_currentPage, $this->_totalPages);
  679. }
  680. // }}}
  681. // {{{ _renderLink()
  682. /**
  683. * Renders a link using the appropriate method
  684. *
  685. * @param string $altText Alternative text for this link (title property)
  686. * @param string $linkText Text contained by this link
  687. *
  688. * @return string The link in string form
  689. * @access private
  690. */
  691. function _renderLink($altText, $linkText)
  692. {
  693. if ($this->_httpMethod == 'GET')
  694. {
  695. if ($this->_append)
  696. {
  697. $href = '?' . $this->_http_build_query_wrapper($this->_linkData);
  698. }
  699. else
  700. {
  701. $href = str_replace('%d', $this->_linkData[$this->_urlVar], $this->_fileName);
  702. }
  703. $onclick = '';
  704. if (array_key_exists($this->_urlVar, $this->_linkData))
  705. {
  706. $onclick = str_replace('%d', $this->_linkData[$this->_urlVar], $this->_onclick);
  707. }
  708. return sprintf('<a href="%s"%s%s%s%s title="%s">%s</a>', htmlentities($this->_url . $href, ENT_COMPAT, 'UTF-8'), empty($this->_classString) ? '' : ' ' . $this->_classString, empty($this->_attributes) ? '' : ' ' . $this->_attributes, empty($this->_accesskey) ? '' : ' accesskey="' . $this->_linkData[$this->_urlVar] . '"', empty($onclick) ? '' : ' onclick="' . $onclick . '"', $altText, $linkText);
  709. }
  710. elseif ($this->_httpMethod == 'POST')
  711. {
  712. $href = $this->_url;
  713. if (! empty($_GET))
  714. {
  715. $href .= '?' . $this->_http_build_query_wrapper($_GET);
  716. }
  717. return sprintf("<a href='javascript:void(0)' onclick='%s'%s%s%s title='%s'>%s</a>", $this->_generateFormOnClick($href, $this->_linkData), empty($this->_classString) ? '' : ' ' . $this->_classString, empty($this->_attributes) ? '' : ' ' . $this->_attributes, empty($this->_accesskey) ? '' : ' accesskey=\'' . $this->_linkData[$this->_urlVar] . '\'', $altText, $linkText);
  718. }
  719. return '';
  720. }
  721. // }}}
  722. // {{{ _generateFormOnClick()
  723. /**
  724. * Mimics http_build_query() behavior in the way the data
  725. * in $data will appear when it makes it back to the server.
  726. * For example:
  727. * $arr = array('array' => array(array('hello', 'world'),
  728. * 'things' => array('stuff', 'junk'));
  729. * http_build_query($arr)
  730. * and _generateFormOnClick('foo.php', $arr)
  731. * will yield
  732. * $_REQUEST['array'][0][0] === 'hello'
  733. * $_REQUEST['array'][0][1] === 'world'
  734. * $_REQUEST['array']['things'][0] === 'stuff'
  735. * $_REQUEST['array']['things'][1] === 'junk'
  736. *
  737. * However, instead of generating a query string, it generates
  738. * Javascript to create and submit a form.
  739. *
  740. * @param string $formAction where the form should be submitted
  741. * @param array $data the associative array of names and values
  742. *
  743. * @return string A string of javascript that generates a form and submits it
  744. * @access private
  745. */
  746. function _generateFormOnClick($formAction, $data)
  747. {
  748. // Check we have an array to work with
  749. if (! is_array($data))
  750. {
  751. trigger_error('_generateForm() Parameter 1 expected to be Array or Object. Incorrect value given.', E_USER_WARNING);
  752. return false;
  753. }
  754. if (! empty($this->_formID))
  755. {
  756. $str = 'var form = document.getElementById("' . $this->_formID . '"); var input = ""; ';
  757. }
  758. else
  759. {
  760. $str = 'var form = document.createElement("form"); var input = ""; ';
  761. }
  762. // We /shouldn't/ need to escape the URL ...
  763. $str .= sprintf('form.action = "%s"; ', htmlentities($formAction, ENT_COMPAT, 'UTF-8'));
  764. $str .= sprintf('form.method = "%s"; ', $this->_httpMethod);
  765. foreach ($data as $key => $val)
  766. {
  767. $str .= $this->_generateFormOnClickHelper($val, $key);
  768. }
  769. if (empty($this->_formID))
  770. {
  771. $str .= 'document.getElementsByTagName("body")[0].appendChild(form);';
  772. }
  773. $str .= 'form.submit(); return false;';
  774. return $str;
  775. }
  776. // }}}
  777. // {{{ _generateFormOnClickHelper
  778. /**
  779. * This is used by _generateFormOnClick().
  780. * Recursively processes the arrays, objects, and literal values.
  781. *
  782. * @param mixed $data Data that should be rendered
  783. * @param string $prev The name so far
  784. *
  785. * @return string A string of Javascript that creates form inputs
  786. * representing the data
  787. * @access private
  788. */
  789. function _generateFormOnClickHelper($data, $prev = '')
  790. {
  791. $str = '';
  792. if (is_array($data) || is_object($data))
  793. {
  794. // foreach key/visible member
  795. foreach ((array) $data as $key => $val)
  796. {
  797. // append [$key] to prev
  798. $tempKey = sprintf('%s[%s]', $prev, $key);
  799. $str .= $this->_generateFormOnClickHelper($val, $tempKey);
  800. }
  801. }
  802. else
  803. { // must be a literal value
  804. // escape newlines and carriage returns
  805. $search = array("\n", "\r");
  806. $replace = array('\n', '\n');
  807. $escapedData = str_replace($search, $replace, $data);
  808. // am I forgetting any dangerous whitespace?
  809. // would a regex be faster?
  810. // if it's already encoded, don't encode it again
  811. if (! $this->_isEncoded($escapedData))
  812. {
  813. $escapedData = urlencode($escapedData);
  814. }
  815. $escapedData = htmlentities($escapedData, ENT_QUOTES, 'UTF-8');
  816. $str .= 'input = document.createElement("input"); ';
  817. $str .= 'input.type = "hidden"; ';
  818. $str .= sprintf('input.name = "%s"; ', $prev);
  819. $str .= sprintf('input.value = "%s"; ', $escapedData);
  820. $str .= 'form.appendChild(input); ';
  821. }
  822. return $str;
  823. }
  824. // }}}
  825. // {{{ _isRegexp()
  826. /**
  827. * Returns true if the string is a regexp pattern
  828. *
  829. * @param string $string the pattern to check
  830. *
  831. * @return boolean
  832. * @access private
  833. */
  834. function _isRegexp($string)
  835. {
  836. return preg_match('/^\/.*\/([Uims]+)?$/', $string);
  837. }
  838. // }}}
  839. // {{{ _getLinksData()
  840. /**
  841. * Returns the correct link for the back/pages/next links
  842. *
  843. * @return array Data
  844. * @access private
  845. */
  846. function _getLinksData()
  847. {
  848. $qs = array();
  849. if ($this->_importQuery)
  850. {
  851. if ($this->_httpMethod == 'POST')
  852. {
  853. $qs = $_POST;
  854. }
  855. elseif ($this->_httpMethod == 'GET')
  856. {
  857. $qs = $_GET;
  858. }
  859. }
  860. foreach ($this->_excludeVars as $exclude)
  861. {
  862. $use_preg = $this->_isRegexp($exclude);
  863. foreach (array_keys($qs) as $qs_item)
  864. {
  865. if ($use_preg)
  866. {
  867. if (preg_match($exclude, $qs_item, $matches))
  868. {
  869. foreach ($matches as $m)
  870. {
  871. unset($qs[$m]);
  872. }
  873. }
  874. }
  875. elseif ($qs_item == $exclude)
  876. {
  877. unset($qs[$qs_item]);
  878. break;
  879. }
  880. }
  881. }
  882. if (count($this->_extraVars))
  883. {
  884. $this->_recursive_urldecode($this->_extraVars);
  885. $qs = array_merge($qs, $this->_extraVars);
  886. }
  887. if (count($qs) && function_exists('get_magic_quotes_gpc') && - 1 == version_compare(PHP_VERSION, '5.2.99') && get_magic_quotes_gpc())
  888. {
  889. $this->_recursive_stripslashes($qs);
  890. }
  891. return $qs;
  892. }
  893. // }}}
  894. // {{{ _recursive_stripslashes()
  895. /**
  896. * Helper method
  897. *
  898. * @param string|array &$var variable to clean
  899. *
  900. * @return void
  901. * @access private
  902. */
  903. function _recursive_stripslashes(&$var)
  904. {
  905. if (is_array($var))
  906. {
  907. foreach (array_keys($var) as $k)
  908. {
  909. $this->_recursive_stripslashes($var[$k]);
  910. }
  911. }
  912. else
  913. {
  914. $var = stripslashes($var);
  915. }
  916. }
  917. // }}}
  918. // {{{ _recursive_urldecode()
  919. /**
  920. * Helper method
  921. *
  922. * @param string|array &$var variable to decode
  923. *
  924. * @return void
  925. * @access private
  926. */
  927. function _recursive_urldecode(&$var)
  928. {
  929. if (is_array($var))
  930. {
  931. foreach (array_keys($var) as $k)
  932. {
  933. $this->_recursive_urldecode($var[$k]);
  934. }
  935. }
  936. else
  937. {
  938. $trans_tbl = array_flip(get_html_translation_table(HTML_ENTITIES));
  939. $var = strtr($var, $trans_tbl);
  940. }
  941. }
  942. // }}}
  943. // {{{ _getBackLink()
  944. /**
  945. * Returns back link
  946. *
  947. * @param string $url URL to use in the link [deprecated: use the factory instead]
  948. * @param string $link HTML to use as the link [deprecated: use the factory instead]
  949. *
  950. * @return string The link
  951. * @access private
  952. */
  953. function _getBackLink($url = '', $link = '')
  954. {
  955. //legacy settings... the preferred way to set an option
  956. //now is passing it to the factory
  957. if (! empty($url))
  958. {
  959. $this->_path = $url;
  960. }
  961. if (! empty($link))
  962. {
  963. $this->_prevImg = $link;
  964. }
  965. $back = '';
  966. if ($this->_currentPage > 1)
  967. {
  968. $this->_linkData[$this->_urlVar] = $this->getPreviousPageID();
  969. $back = $this->_renderLink($this->_altPrev, $this->_prevImg) . $this->_spacesBefore . $this->_spacesAfter;
  970. }
  971. else
  972. if ($this->_prevImgEmpty !== null && $this->_totalPages > 1)
  973. {
  974. $back = $this->_prevImgEmpty . $this->_spacesBefore . $this->_spacesAfter;
  975. }
  976. return $back;
  977. }
  978. // }}}
  979. // {{{ _getPageLinks()
  980. /**
  981. * Returns pages link
  982. *
  983. * @param string $url URL to use in the link [deprecated: use the factory instead]
  984. *
  985. * @return string Links
  986. * @access private
  987. */
  988. function _getPageLinks($url = '')
  989. {
  990. $msg = 'function "_getPageLinks()" not implemented.';
  991. return $this->raiseError($msg, ERROR_PAGER_NOT_IMPLEMENTED);
  992. }
  993. // }}}
  994. // {{{ _getNextLink()
  995. /**
  996. * Returns next link
  997. *
  998. * @param string $url URL to use in the link [deprecated: use the factory instead]
  999. * @param string $link HTML to use as the link [deprecated: use the factory instead]
  1000. *
  1001. * @return string The link
  1002. * @access private
  1003. */
  1004. function _getNextLink($url = '', $link = '')
  1005. {
  1006. //legacy settings... the preferred way to set an option
  1007. //now is passing it to the factory
  1008. if (! empty($url))
  1009. {
  1010. $this->_path = $url;
  1011. }
  1012. if (! empty($link))
  1013. {
  1014. $this->_nextImg = $link;
  1015. }
  1016. $next = '';
  1017. if ($this->_currentPage < $this->_totalPages)
  1018. {
  1019. $this->_linkData[$this->_urlVar] = $this->getNextPageID();
  1020. $next = $this->_spacesAfter . $this->_renderLink($this->_altNext, $this->_nextImg) . $this->_spacesBefore . $this->_spacesAfter;
  1021. }
  1022. else
  1023. if ($this->_nextImgEmpty !== null && $this->_totalPages > 1)
  1024. {
  1025. $next = $this->_spacesAfter . $this->_nextImgEmpty . $this->_spacesBefore . $this->_spacesAfter;
  1026. }
  1027. return $next;
  1028. }
  1029. // }}}
  1030. // {{{ _getFirstLinkTag()
  1031. /**
  1032. * Returns first link tag
  1033. *
  1034. * @param bool $raw should tag returned as array
  1035. *
  1036. * @return mixed string with html link tag or separated as array
  1037. * @access private
  1038. */
  1039. function _getFirstLinkTag($raw = false)
  1040. {
  1041. if ($this->isFirstPage() || ($this->_httpMethod != 'GET'))
  1042. {
  1043. return $raw ? array() : '';
  1044. }
  1045. if ($raw)
  1046. {
  1047. return array('url' => $this->_getLinkTagUrl(1), 'title' => $this->_firstLinkTitle);
  1048. }
  1049. return sprintf('<link rel="first" href="%s" title="%s" />' . "\n", $this->_getLinkTagUrl(1), $this->_firstLinkTitle);
  1050. }
  1051. // }}}
  1052. // {{{ _getPrevLinkTag()
  1053. /**
  1054. * Returns previous link tag
  1055. *
  1056. * @param bool $raw should tag returned as array
  1057. *
  1058. * @return mixed string with html link tag or separated as array
  1059. * @access private
  1060. */
  1061. function _getPrevLinkTag($raw = false)
  1062. {
  1063. if ($this->isFirstPage() || ($this->_httpMethod != 'GET'))
  1064. {
  1065. return $raw ? array() : '';
  1066. }
  1067. if ($raw)
  1068. {
  1069. return array('url' => $this->_getLinkTagUrl($this->getPreviousPageID()), 'title' => $this->_prevLinkTitle);
  1070. }
  1071. return sprintf('<link rel="previous" href="%s" title="%s" />' . "\n", $this->_getLinkTagUrl($this->getPreviousPageID()), $this->_prevLinkTitle);
  1072. }
  1073. // }}}
  1074. // {{{ _getNextLinkTag()
  1075. /**
  1076. * Returns next link tag
  1077. *
  1078. * @param bool $raw should tag returned as array
  1079. *
  1080. * @return mixed string with html link tag or separated as array
  1081. * @access private
  1082. */
  1083. function _getNextLinkTag($raw = false)
  1084. {
  1085. if ($this->isLastPage() || ($this->_httpMethod != 'GET'))
  1086. {
  1087. return $raw ? array() : '';
  1088. }
  1089. if ($raw)
  1090. {
  1091. return array('url' => $this->_getLinkTagUrl($this->getNextPageID()), 'title' => $this->_nextLinkTitle);
  1092. }
  1093. return sprintf('<link rel="next" href="%s" title="%s" />' . "\n", $this->_getLinkTagUrl($this->getNextPageID()), $this->_nextLinkTitle);
  1094. }
  1095. // }}}
  1096. // {{{ _getLastLinkTag()
  1097. /**
  1098. * Returns last link tag
  1099. *
  1100. * @param bool $raw should tag returned as array
  1101. *
  1102. * @return mixed string with html link tag or separated as array
  1103. * @access private
  1104. */
  1105. function _getLastLinkTag($raw = false)
  1106. {
  1107. if ($this->isLastPage() || ($this->_httpMethod != 'GET'))
  1108. {
  1109. return $raw ? array() : '';
  1110. }
  1111. if ($raw)
  1112. {
  1113. return array('url' => $this->_getLinkTagUrl($this->_totalPages), 'title' => $this->_lastLinkTitle);
  1114. }
  1115. return sprintf('<link rel="last" href="%s" title="%s" />' . "\n", $this->_getLinkTagUrl($this->_totalPages), $this->_lastLinkTitle);
  1116. }
  1117. // }}}
  1118. // {{{ _getLinkTagUrl()
  1119. /**
  1120. * Helper method
  1121. *
  1122. * @param integer $pageID page ID
  1123. *
  1124. * @return string the link tag url
  1125. * @access private
  1126. */
  1127. function _getLinkTagUrl($pageID)
  1128. {
  1129. $this->_linkData[$this->_urlVar] = $pageID;
  1130. if ($this->_append)
  1131. {
  1132. $href = '?' . $this->_http_build_query_wrapper($this->_linkData);
  1133. }
  1134. else
  1135. {
  1136. $href = str_replace('%d', $this->_linkData[$this->_urlVar], $this->_fileName);
  1137. }
  1138. return htmlentities($this->_url . $href, ENT_COMPAT, 'UTF-8');
  1139. }
  1140. // }}}
  1141. // {{{ getPerPageSelectBox()
  1142. /**
  1143. * Returns a string with a XHTML SELECT menu,
  1144. * useful for letting the user choose how many items per page should be
  1145. * displayed. If parameter useSessions is TRUE, this value is stored in
  1146. * a session var. The string isn't echoed right now so you can use it
  1147. * with template engines.
  1148. *
  1149. * @param integer $start starting value for the select menu
  1150. * @param integer $end ending value for the select menu
  1151. * @param integer $step step between values in the select menu
  1152. * @param boolean $showAllData If true, perPage is set equal to totalItems.
  1153. * @param array $extraParams (or string $optionText for BC reasons)
  1154. * - 'optionText': text to show in each option.
  1155. * Use '%d' where you want to see the number of pages selected.
  1156. * - 'attributes': (html attributes) Tag attributes or
  1157. * HTML attributes (id="foo" pairs), will be inserted in the
  1158. * <select> tag
  1159. *
  1160. * @return string xhtml select box
  1161. * @access public
  1162. */
  1163. function getPerPageSelectBox($start = 5, $end = 30, $step = 5, $showAllData = false, $extraParams = array())
  1164. {
  1165. include_once 'Pager/HtmlWidgets.php';
  1166. $widget = new Pager_HtmlWidgets($this);
  1167. return $widget->getPerPageSelectBox($start, $end, $step, $showAllData, $extraParams);
  1168. }
  1169. // }}}
  1170. // {{{ getPageSelectBox()
  1171. /**
  1172. * Returns a string with a XHTML SELECT menu with the page numbers,
  1173. * useful as an alternative to the links
  1174. *
  1175. * @param array $params - 'optionText': text to show in each option.
  1176. * Use '%d' where you want to see the number
  1177. * of pages selected.
  1178. * - 'autoSubmit': if TRUE, add some js code
  1179. * to submit the form on the onChange event
  1180. * @param string $extraAttributes (html attributes) Tag attributes or
  1181. * HTML attributes (id="foo" pairs), will be
  1182. * inserted in the <select> tag
  1183. *
  1184. * @return string xhtml select box
  1185. * @access public
  1186. */
  1187. function getPageSelectBox($params = array(), $extraAttributes = '')
  1188. {
  1189. include_once 'Pager/HtmlWidgets.php';
  1190. $widget = new Pager_HtmlWidgets($this);
  1191. return $widget->getPageSelectBox($params, $extraAttributes);
  1192. }
  1193. // }}}
  1194. // {{{ _printFirstPage()
  1195. /**
  1196. * Print [1]
  1197. *
  1198. * @return string String with link to 1st page,
  1199. * or empty string if this is the 1st page.
  1200. * @access private
  1201. */
  1202. function _printFirstPage()
  1203. {
  1204. if ($this->isFirstPage())
  1205. {
  1206. return '';
  1207. }
  1208. $this->_linkData[$this->_urlVar] = 1;
  1209. return $this->_renderLink(str_replace('%d', 1, $this->_altFirst), $this->_firstPagePre . $this->_firstPageText . $this->_firstPagePost) . $this->_spacesBefore . $this->_spacesAfter;
  1210. }
  1211. // }}}
  1212. // {{{ _printLastPage()
  1213. /**
  1214. * Print [numPages()]
  1215. *
  1216. * @return string String with link to last page,
  1217. * or empty string if this is the 1st page.
  1218. * @access private
  1219. */
  1220. function _printLastPage()
  1221. {
  1222. if ($this->isLastPage())
  1223. {
  1224. return '';
  1225. }
  1226. $this->_linkData[$this->_urlVar] = $this->_totalPages;
  1227. return $this->_renderLink(str_replace('%d', $this->_totalPages, $this->_altLast), $this->_lastPagePre . $this->_lastPageText . $this->_lastPagePost);
  1228. }
  1229. // }}}
  1230. // {{{ _setFirstLastText()
  1231. /**
  1232. * sets the private _firstPageText, _lastPageText variables
  1233. * based on whether they were set in the options
  1234. *
  1235. * @return void
  1236. * @access private
  1237. */
  1238. function _setFirstLastText()
  1239. {
  1240. if ($this->_firstPageText == '')
  1241. {
  1242. $this->_firstPageText = '1';
  1243. }
  1244. if ($this->_lastPageText == '')
  1245. {
  1246. $this->_lastPageText = $this->_totalPages;
  1247. }
  1248. }
  1249. // }}}
  1250. // {{{ _http_build_query_wrapper()
  1251. /**
  1252. * This is a slightly modified version of the http_build_query() function;
  1253. * it heavily borrows code from PHP_Compat's http_build_query().
  1254. * The main change is the usage of htmlentities instead of urlencode,
  1255. * since it's too aggressive
  1256. *
  1257. * @param array $data array of querystring values
  1258. *
  1259. * @return string
  1260. * @access private
  1261. */
  1262. function _http_build_query_wrapper($data)
  1263. {
  1264. $data = (array) $data;
  1265. if (empty($data))
  1266. {
  1267. return '';
  1268. }
  1269. $separator = ini_get('arg_separator.output');
  1270. if ($separator == '&amp;')
  1271. {
  1272. $separator = '&'; //the string is escaped by htmlentities anyway...
  1273. }
  1274. $tmp = array();
  1275. foreach ($data as $key => $val)
  1276. {
  1277. if (is_scalar($val))
  1278. {
  1279. //array_push($tmp, $key.'='.$val);
  1280. $val = urlencode($val);
  1281. array_push($tmp, $key . '=' . str_replace('%2F', '/', $val));
  1282. continue;
  1283. }
  1284. // If the value is an array, recursively parse it
  1285. if (is_array($val))
  1286. {
  1287. array_push($tmp, $this->__http_build_query($val, urlencode($key)));
  1288. continue;
  1289. }
  1290. }
  1291. return implode($separator, $tmp);
  1292. }
  1293. // }}}
  1294. // {{{ __http_build_query()
  1295. /**
  1296. * Helper function
  1297. *
  1298. * @param array $array array of querystring values
  1299. * @param string $name key
  1300. *
  1301. * @return string
  1302. * @access private
  1303. */
  1304. function __http_build_query($array, $name)
  1305. {
  1306. $tmp = array();
  1307. $separator = ini_get('arg_separator.output');
  1308. if ($separator == '&amp;')
  1309. {
  1310. $separator = '&'; //the string is escaped by htmlentities anyway...
  1311. }
  1312. foreach ($array as $key => $value)
  1313. {
  1314. if (is_array($value))
  1315. {
  1316. //array_push($tmp, $this->__http_build_query($value, sprintf('%s[%s]', $name, $key)));
  1317. array_push($tmp, $this->__http_build_query($value, $name . '%5B' . $key . '%5D'));
  1318. }
  1319. elseif (is_scalar($value))
  1320. {
  1321. //array_push($tmp, sprintf('%s[%s]=%s', $name, htmlentities($key), htmlentities($value)));
  1322. array_push($tmp, $name . '%5B' . urlencode($key) . '%5D=' . urlencode($value));
  1323. }
  1324. elseif (is_object($value))
  1325. {
  1326. //array_push($tmp, $this->__http_build_query(get_object_vars($value), sprintf('%s[%s]', $name, $key)));
  1327. array_push($tmp, $this->__http_build_query(get_object_vars($value), $name . '%5B' . $key . '%5D'));
  1328. }
  1329. }
  1330. return implode($separator, $tmp);
  1331. }
  1332. // }}}
  1333. // {{{ _isEncoded()
  1334. /**
  1335. * Helper function
  1336. * Check if a string is an encoded multibyte string
  1337. *
  1338. * @param string $string string to check
  1339. *
  1340. * @return boolean
  1341. * @access private
  1342. */
  1343. function _isEncoded($string)
  1344. {
  1345. $hexchar = '&#[\dA-Fx]{2,};';
  1346. return preg_match("/^(\s|($hexchar))*$/Uims", $string) ? true : false;
  1347. }
  1348. // }}}
  1349. // {{{ raiseError()
  1350. /**
  1351. * conditionally includes PEAR base class and raise an error
  1352. *
  1353. * @param string $msg Error message
  1354. * @param integer $code Error code
  1355. *
  1356. * @return PEAR_Error
  1357. * @access private
  1358. */
  1359. function raiseError($msg, $code)
  1360. {
  1361. include_once 'PEAR.php';
  1362. if (empty($this->_pearErrorMode))
  1363. {
  1364. $this->_pearErrorMode = PEAR_ERROR_RETURN;
  1365. }
  1366. return PEAR :: raiseError($msg, $code, $this->_pearErrorMode);
  1367. }
  1368. // }}}
  1369. // {{{ setOptions()
  1370. /**
  1371. * Set and sanitize options
  1372. *
  1373. * @param mixed $options An associative array of option names and their values
  1374. *
  1375. * @return integer error code (PAGER_OK on success)
  1376. * @access public
  1377. */
  1378. function setOptions($options)
  1379. {
  1380. foreach ($options as $key => $value)
  1381. {
  1382. if (in_array($key, $this->_allowed_options) && (! is_null($value)))
  1383. {
  1384. $this->{'_' . $key} = $value;
  1385. }
  1386. }
  1387. //autodetect http method
  1388. if (! isset($options['httpMethod']) && ! isset($_GET[$this->_urlVar]) && isset($_POST[$this->_urlVar]))
  1389. {
  1390. $this->_httpMethod = 'POST';
  1391. }
  1392. else
  1393. {
  1394. $this->_httpMethod = strtoupper($this->_httpMethod);
  1395. }
  1396. if (substr($this->_path, - 1, 1) == '/')
  1397. {
  1398. $this->_fileName = ltrim($this->_fileName, '/'); //strip leading slash
  1399. }
  1400. if ($this->_append)
  1401. {
  1402. if ($this->_fixFileName)
  1403. {
  1404. $this->_fileName = PAGER_CURRENT_FILENAME; //avoid possible user error;
  1405. }
  1406. $this->_url = $this->_path . (empty($this->_path) ? '' : '/') . $this->_fileName;
  1407. }
  1408. else
  1409. {
  1410. $this->_url = $this->_path;
  1411. if (0 != strncasecmp($this->_fileName, 'javascript', 10))
  1412. {
  1413. $this->_url .= (empty($this->_path) ? '' : '/');
  1414. }
  1415. if (false === strpos($this->_fileName, '%d'))
  1416. {
  1417. trigger_error($this->errorMessage(ERROR_PAGER_INVALID_USAGE), E_USER_WARNING);
  1418. }
  1419. }
  1420. if (substr($this->_url, 0, 2) == '//')
  1421. {
  1422. $this->_url = substr($this->_url, 1);
  1423. }
  1424. if (false === strpos($this->_altPage, '%d'))
  1425. {
  1426. //by default, append page number at the end
  1427. $this->_altPage .= ' %d';
  1428. }
  1429. $this->_classString = '';
  1430. if (strlen($this->_linkClass))
  1431. {
  1432. $this->_classString = 'class="' . $this->_linkClass . '"';
  1433. }
  1434. if (strlen($this->_curPageLinkClassName))
  1435. {
  1436. $this->_curPageSpanPre .= '<span class="' . $this->_curPageLinkClassName . '">';
  1437. $this->_curPageSpanPost = '</span>' . $this->_curPageSpanPost;
  1438. }
  1439. $this->_perPage = max($this->_perPage, 1); //avoid possible user errors
  1440. if ($this->_useSessions && ! isset($_SESSION))
  1441. {
  1442. session_start();
  1443. }
  1444. if (! empty($_REQUEST[$this->_sessionVar]))
  1445. {
  1446. $this->_perPage = max(1, (int) $_REQUEST[$this->_sessionVar]);
  1447. if ($this->_useSessions)
  1448. {
  1449. $_SESSION[$this->_sessionVar] = $this->_perPage;
  1450. }
  1451. }
  1452. if (! empty($_SESSION[$this->_sessionVar]) && $this->_useSessions)
  1453. {
  1454. $this->_perPage = $_SESSION[$this->_sessionVar];
  1455. }
  1456. if ($this->_closeSession)
  1457. {
  1458. session_write_close();
  1459. }
  1460. $this->_spacesBefore = str_repeat('&nbsp;', $this->_spacesBeforeSeparator);
  1461. $this->_spacesAfter = str_repeat('&nbsp;', $this->_spacesAfterSeparator);
  1462. if (isset($_REQUEST[$this->_urlVar]) && empty($options['currentPage']))
  1463. {
  1464. $this->_currentPage = (int) $_REQUEST[$this->_urlVar];
  1465. }
  1466. $this->_currentPage = max($this->_currentPage, 1);
  1467. $this->_linkData = $this->_getLinksData();
  1468. return PAGER_OK;
  1469. }
  1470. // }}}
  1471. // {{{ getOption()
  1472. /**
  1473. * Return the current value of a given option
  1474. *
  1475. * @param string $name option name
  1476. *
  1477. * @return mixed option value
  1478. * @access public
  1479. */
  1480. function getOption($name)
  1481. {
  1482. if (! in_array($name, $this->_allowed_options))
  1483. {
  1484. $msg = 'invalid option: ' . $name;
  1485. return $this->raiseError($msg, ERROR_PAGER_INVALID);
  1486. }
  1487. return $this->{'_' . $name};
  1488. }
  1489. // }}}
  1490. // {{{ getOptions()
  1491. /**
  1492. * Return an array with all the current pager options
  1493. *
  1494. * @return array list of all the pager options
  1495. * @access public
  1496. */
  1497. function getOptions()
  1498. {
  1499. $options = array();
  1500. foreach ($this->_allowed_options as $option)
  1501. {
  1502. $options[$option] = $this->{'_' . $option};
  1503. }
  1504. return $options;
  1505. }
  1506. // }}}
  1507. // {{{ errorMessage()
  1508. /**
  1509. * Return a textual error message fo…

Large files files are truncated, but you can click here to view the full file