KXStudio Website https://kx.studio/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

230 lines
8.1KB

  1. <?php
  2. /**
  3. * Class: Paginator
  4. * Paginates over an array.
  5. */
  6. class Paginator {
  7. # Array: $array
  8. # The original, unmodified data.
  9. public $array;
  10. # Integer: $per_page
  11. # Number of items per page.
  12. public $per_page;
  13. # String: $name
  14. # Name of the $_GET value for the current page.
  15. public $name;
  16. # Boolean: $model
  17. # Should the <$array> items be treated as Models?
  18. # In this case, <$array> should be in the form of array(<ids>, "ModelName")
  19. public $model;
  20. # Integer: $total
  21. # Total number of items to paginate.
  22. public $total;
  23. # Integer: $page
  24. # The current page.
  25. public $page;
  26. # Integer: $pages
  27. # Total number of pages.
  28. public $pages;
  29. # Array: $result
  30. # The result of the pagination.
  31. # @paginated@, @paginate@, and @list@ are references to this.
  32. public $result = array();
  33. # Array: $names
  34. # An array of the currently-used pagination URL parameters.
  35. static $names = array();
  36. /**
  37. * Function: __construct
  38. * Prepares an array for pagination.
  39. *
  40. * Parameters:
  41. * $array - The array to paginate.
  42. * $per_page - Number of items per page.
  43. * $name - The name of the $_GET parameter to use for determining the current page.
  44. * $model - If this is true, each item in $array that gets shown on the page will be
  45. * initialized as a model of whatever is passed as the second argument to $array.
  46. * The first argument of $array is expected to be an array of IDs.
  47. * $page - Page number to start at.
  48. *
  49. * Returns:
  50. * A paginated array of length $per_page or smaller.
  51. */
  52. public function __construct($array, $per_page = 5, $name = "page", $model = null, $page = null) {
  53. self::$names[] = $name;
  54. $this->array = (array) $array;
  55. $this->per_page = $per_page;
  56. $this->name = $name;
  57. $this->model = fallback($model, (count($this->array) == 2 and is_array($this->array[0]) and is_string($this->array[1]) and class_exists($this->array[1])));
  58. if ($model)
  59. list($this->array, $model_name) = $this->array;
  60. $this->total = count($this->array);
  61. $this->page = oneof($page, @$_GET[$name], 1);
  62. $this->pages = ceil($this->total / $this->per_page);
  63. $offset = ($this->page - 1) * $this->per_page;
  64. $this->result = array();
  65. if ($model) {
  66. for ($i = $offset; $i < ($offset + $this->per_page); $i++)
  67. if (isset($this->array[$i]))
  68. $this->result[] = new $model_name(null, array("read_from" => $this->array[$i]));
  69. } else
  70. $this->result = array_slice($this->array, $offset, $this->per_page);
  71. $shown_dates = array();
  72. if ($model)
  73. foreach ($this->result as &$result)
  74. if (isset($result->created_at)) {
  75. $pinned = (isset($result->pinned) and $result->pinned);
  76. $shown = in_array(when("m-d-Y", $result->created_at), $shown_dates);
  77. $result->first_of_day = (!$pinned and !$shown and !AJAX);
  78. if (!$pinned and !$shown)
  79. $shown_dates[] = when("m-d-Y", $result->created_at);
  80. }
  81. $this->paginated = $this->paginate = $this->list =& $this->result;
  82. }
  83. /**
  84. * Function: next
  85. * Returns the next pagination sequence.
  86. */
  87. public function next() {
  88. return new self($this->array, $this->per_page, $this->name, $this->model, $this->page + 1);
  89. }
  90. /**
  91. * Function: prev
  92. * Returns the next pagination sequence.
  93. */
  94. public function prev() {
  95. return new self($this->array, $this->per_page, $this->name, $this->model, $this->page - 1);
  96. }
  97. /**
  98. * Function: next_page
  99. * Checks whether or not it makes sense to show the Next Page link.
  100. */
  101. public function next_page() {
  102. return ($this->page < $this->pages and $this->pages != 1 and $this->pages != 0);
  103. }
  104. /**
  105. * Function: prev_page
  106. * Checks whether or not it makes sense to show the Previous Page link.
  107. */
  108. public function prev_page() {
  109. return ($this->page != 1 and $this->page <= $this->pages);
  110. }
  111. /**
  112. * Function: next_link
  113. * Outputs a link to the next page.
  114. *
  115. * Parameters:
  116. * $text - The text for the link.
  117. * $class - The CSS class for the link.
  118. * $page - Page number to link to.
  119. */
  120. public function next_link($text = null, $class = "next_page", $page = null) {
  121. if (!$this->next_page())
  122. return;
  123. fallback($text, __("Next &rarr;"));
  124. echo '<a class="'.$class.'" id="next_page_'.$this->name.'" href="'.$this->next_page_url($page).'">'.
  125. $text.
  126. '</a>';
  127. }
  128. /**
  129. * Function: prev_link
  130. * Outputs a link to the previous page.
  131. *
  132. * Parameters:
  133. * $text - The text for the link.
  134. * $class - The CSS class for the link.
  135. * $page - Page number to link to.
  136. */
  137. public function prev_link($text = null, $class = "prev_page", $page = null) {
  138. if (!$this->prev_page())
  139. return;
  140. fallback($text, __("&larr; Previous"));
  141. echo '<a class="'.$class.'" id="prev_page_'.$this->name.'" href="'.$this->prev_page_url($page).'">'.
  142. $text.
  143. '</a>';
  144. }
  145. /**
  146. * Function: next_page_url
  147. * Returns the URL to the next page.
  148. *
  149. * Parameters:
  150. * $page - Page number to link to.
  151. */
  152. public function next_page_url($page = null) {
  153. $config = Config::current();
  154. $request = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
  155. # Only used for adding to the end of the URL and clean URLs is off.
  156. $mark = (substr_count($request, "?")) ? "&amp;" : "?" ;
  157. fallback($page, $this->page + 1);
  158. # No page is set, add it to the end.
  159. if (!isset($_GET[$this->name]))
  160. return ($config->clean_urls and !ADMIN) ?
  161. rtrim($request, "/")."/".$this->name."/".$page :
  162. $request.$mark.$this->name."=".$page ;
  163. return ($config->clean_urls and !ADMIN) ?
  164. preg_replace("/(\/{$this->name}\/([0-9]+)|$)/", "/".$this->name."/".$page, $request, 1) :
  165. preg_replace("/((\?|&){$this->name}=([0-9]+)|$)/", "\\2".$this->name."=".$page, $request, 1) ;
  166. }
  167. /**
  168. * Function: prev_page_url
  169. * Returns the URL to the previous page.
  170. *
  171. * Parameters:
  172. * $page - Page number to link to.
  173. */
  174. public function prev_page_url($page = null) {
  175. $config = Config::current();
  176. $request = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
  177. # Only used for adding to the end of the URL and clean URLs is off.
  178. $mark = (substr_count($request, "?")) ? "&amp;" : "?" ;
  179. fallback($page, $this->page - 1);
  180. # No page is set, add it to the end.
  181. if (!isset($_GET[$this->name]))
  182. return ($config->clean_urls and !ADMIN) ?
  183. rtrim($request, "/")."/".$this->name."/".$page :
  184. $request.$mark.$this->name."=".$page ;
  185. return ($config->clean_urls and !ADMIN) ?
  186. preg_replace("/(\/{$this->name}\/([0-9]+)|$)/", "/".$this->name."/".$page, $request, 1) :
  187. preg_replace("/((\?|&){$this->name}=([0-9]+)|$)/", "\\2".$this->name."=".$page, $request, 1) ;
  188. }
  189. }