pagination.php
304 lines
| 1 | <?php |
| 2 | /** |
| 3 | * @package VikWP - Libraries |
| 4 | * @subpackage adapter.pagination |
| 5 | * @author E4J s.r.l. |
| 6 | * @copyright Copyright (C) 2023 E4J s.r.l. All Rights Reserved. |
| 7 | * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL |
| 8 | * @link https://vikwp.com |
| 9 | */ |
| 10 | |
| 11 | // No direct access |
| 12 | defined('ABSPATH') or die('No script kiddies please!'); |
| 13 | |
| 14 | /** |
| 15 | * This class provides a common interface for content |
| 16 | * pagination for the Wordpress CMS plugins. |
| 17 | * |
| 18 | * @since 10.0 |
| 19 | */ |
| 20 | class JPagination |
| 21 | { |
| 22 | /** |
| 23 | * The layout file to use for rendering the pagination. |
| 24 | * |
| 25 | * @var JLayoutFile |
| 26 | */ |
| 27 | private static $_layout = null; |
| 28 | |
| 29 | /** |
| 30 | * The total number of items. |
| 31 | * |
| 32 | * @var integer |
| 33 | */ |
| 34 | protected $total; |
| 35 | |
| 36 | /** |
| 37 | * The offset of the item to start at. |
| 38 | * |
| 39 | * @var integer |
| 40 | */ |
| 41 | protected $limitstart; |
| 42 | |
| 43 | /** |
| 44 | * The number of items to display per page. |
| 45 | * |
| 46 | * @var integer |
| 47 | */ |
| 48 | protected $limit; |
| 49 | |
| 50 | /** |
| 51 | * Prefix used for request variables. |
| 52 | * |
| 53 | * @var string |
| 54 | * @since 10.1.44 |
| 55 | */ |
| 56 | protected $prefix; |
| 57 | |
| 58 | /** |
| 59 | * A list of additional URL params. |
| 60 | * |
| 61 | * @var array |
| 62 | */ |
| 63 | protected $params = []; |
| 64 | |
| 65 | /** |
| 66 | * Class constructor. |
| 67 | * |
| 68 | * @param integer $total The total number of items. |
| 69 | * @param integer $limitstart The offset of the item to start at. |
| 70 | * @param integer $limit The number of items to display per page. |
| 71 | * @param string $prefix The prefix used for request variables. |
| 72 | */ |
| 73 | public function __construct($total, $limitstart, $limit, $prefix = '') |
| 74 | { |
| 75 | $this->total = $total; |
| 76 | $this->limitstart = $limitstart; |
| 77 | $this->limit = $limit; |
| 78 | $this->prefix = $prefix; |
| 79 | } |
| 80 | |
| 81 | /** |
| 82 | * Sets the global layout file renderer. |
| 83 | * |
| 84 | * @param JLayoutFile $layout The layout file object. |
| 85 | * |
| 86 | * @return void |
| 87 | */ |
| 88 | public static function setLayout(JLayoutFile $layout) |
| 89 | { |
| 90 | static::$_layout = $layout; |
| 91 | } |
| 92 | |
| 93 | /** |
| 94 | * Gets the global layout file renderer. |
| 95 | * |
| 96 | * @return JLayoutFile The layout file object. |
| 97 | */ |
| 98 | public static function getLayout() |
| 99 | { |
| 100 | if (!static::$_layout) |
| 101 | { |
| 102 | // use default layout if not specified |
| 103 | static::$_layout = new JLayoutFile('html.system.pagination'); |
| 104 | } |
| 105 | |
| 106 | return static::$_layout; |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Method to set an additional URL parameter to be added |
| 111 | * to all pagination class generated links. |
| 112 | * |
| 113 | * @param string $key The name of the URL parameter for which to set a value. |
| 114 | * @param mixed $value The value to set for the URL parameter. |
| 115 | * |
| 116 | * @return mixed The old value for the parameter. |
| 117 | */ |
| 118 | public function setAdditionalUrlParam($key, $value) |
| 119 | { |
| 120 | // get the old value to return and set the new one for the URL parameter |
| 121 | $result = isset($this->params[$key]) ? $this->params[$key] : null; |
| 122 | |
| 123 | // if the passed parameter value is null unset the parameter, otherwise set it to the given value |
| 124 | if ($value === null) |
| 125 | { |
| 126 | unset($this->params[$key]); |
| 127 | } |
| 128 | else |
| 129 | { |
| 130 | $this->params[$key] = $value; |
| 131 | } |
| 132 | |
| 133 | return $result; |
| 134 | } |
| 135 | |
| 136 | /** |
| 137 | * Method to get an additional URL parameter (if it exists) to be added to |
| 138 | * all pagination class generated links. |
| 139 | * |
| 140 | * @param string $key The name of the URL parameter for which to get the value. |
| 141 | * |
| 142 | * @return mixed The value if it exists, otherwise null. |
| 143 | */ |
| 144 | public function getAdditionalUrlParam($key) |
| 145 | { |
| 146 | return isset($this->params[$key]) ? $this->params[$key] : null; |
| 147 | } |
| 148 | |
| 149 | /** |
| 150 | * Create and return the pagination page list string. |
| 151 | * For example: Previous, Next, 1 2 3 ... x. |
| 152 | * |
| 153 | * @return string Pagination page list string. |
| 154 | */ |
| 155 | public function getPagesLinks() |
| 156 | { |
| 157 | return $this->getListFooter(); |
| 158 | } |
| 159 | |
| 160 | /** |
| 161 | * Return the pagination footer. |
| 162 | * |
| 163 | * @return string Pagination footer. |
| 164 | * |
| 165 | * @uses buildPaginationData() |
| 166 | */ |
| 167 | public function getListFooter() |
| 168 | { |
| 169 | $layout = static::getLayout(); |
| 170 | |
| 171 | // make sure a layout has been set |
| 172 | if (is_null($layout)) |
| 173 | { |
| 174 | return ''; |
| 175 | } |
| 176 | |
| 177 | $data = $this->buildPaginationData(); |
| 178 | |
| 179 | // use the pagination only if we have 2 or more pages |
| 180 | if ($data['pages'] <= 1) |
| 181 | { |
| 182 | return ''; |
| 183 | } |
| 184 | |
| 185 | $app = JFactory::getApplication(); |
| 186 | |
| 187 | // set pagination URLs |
| 188 | $data['links'] = []; |
| 189 | |
| 190 | if ($app->isAdmin()) |
| 191 | { |
| 192 | // include script to handle pagination events |
| 193 | JFactory::getDocument()->addScriptDeclaration( |
| 194 | <<<JAVASCRIPT |
| 195 | jQuery(function() { |
| 196 | Joomla.getPagination('{$data['prefix']}') |
| 197 | .setTotal({$data['total']}) |
| 198 | .setLimit({$data['lim']}) |
| 199 | .setStart({$data['lim0']}) |
| 200 | .setListener(document.adminForm); |
| 201 | }); |
| 202 | JAVASCRIPT |
| 203 | ); |
| 204 | |
| 205 | $data['links']['first'] = 'href="javascript: void(0);" onclick="Joomla.getPagination(\'' . $data['prefix'] . '\').first();"'; |
| 206 | $data['links']['prev'] = 'href="javascript: void(0);" onclick="Joomla.getPagination(\'' . $data['prefix'] . '\').prev();"'; |
| 207 | $data['links']['next'] = 'href="javascript: void(0);" onclick="Joomla.getPagination(\'' . $data['prefix'] . '\').next();"'; |
| 208 | $data['links']['last'] = 'href="javascript: void(0);" onclick="Joomla.getPagination(\'' . $data['prefix'] . '\').last();"'; |
| 209 | } |
| 210 | else |
| 211 | { |
| 212 | // get current URI |
| 213 | $current = JUri::getInstance(); |
| 214 | |
| 215 | // replace or inject each additional param |
| 216 | foreach ($this->params as $k => $v) |
| 217 | { |
| 218 | $current->setVar($k, $v); |
| 219 | } |
| 220 | |
| 221 | $seek = array( |
| 222 | 'first' => 0, |
| 223 | 'prev' => $data['lim0'] - $data['lim'], |
| 224 | 'next' => $data['lim0'] + $data['lim'], |
| 225 | 'last' => ($data['pages'] - 1) * $data['lim'], |
| 226 | ); |
| 227 | |
| 228 | foreach ($seek as $k => $v) |
| 229 | { |
| 230 | // replace limitstart |
| 231 | $current->setVar($this->prefix . 'limitstart', $v); |
| 232 | // route the URI |
| 233 | $data['links'][$k] = 'href="' . JRoute::rewrite($current) . '"'; |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | return $layout->render($data); |
| 238 | } |
| 239 | |
| 240 | /** |
| 241 | * Helper method to build the pagination data array. |
| 242 | * |
| 243 | * @param array &$data The array data to fill. |
| 244 | * |
| 245 | * @return array The resulting data array. |
| 246 | */ |
| 247 | protected function buildPaginationData(?array &$data = null) |
| 248 | { |
| 249 | if (is_null($data)) |
| 250 | { |
| 251 | $data = []; |
| 252 | } |
| 253 | |
| 254 | $data = []; |
| 255 | $data['prefix'] = $this->prefix; |
| 256 | $data['total'] = $this->total; |
| 257 | $data['lim0'] = $this->limitstart; |
| 258 | $data['lim'] = $this->limit; |
| 259 | $data['pages'] = $this->limit ? ceil($this->total / $this->limit) : 1; |
| 260 | |
| 261 | // lim0 : page = total : pages |
| 262 | // page = lim0 * pages / total |
| 263 | $data['page'] = floor($this->limitstart * $data['pages'] / $this->total) + 1; |
| 264 | |
| 265 | return $data; |
| 266 | } |
| 267 | |
| 268 | /** |
| 269 | * Creates a dropdown box for selecting how many records to show per page. |
| 270 | * |
| 271 | * @return string The HTML for the limit # input box. |
| 272 | * |
| 273 | * @since 10.1.48 |
| 274 | */ |
| 275 | public function getLimitBox() |
| 276 | { |
| 277 | $limits = []; |
| 278 | |
| 279 | // make the option list |
| 280 | for ($i = 5; $i <= 30; $i += 5) |
| 281 | { |
| 282 | $limits[] = JHtml::fetch('select.option', $i, $i); |
| 283 | } |
| 284 | |
| 285 | $limits[] = JHtml::fetch('select.option', 50, 50); |
| 286 | $limits[] = JHtml::fetch('select.option', 100, 100); |
| 287 | $limits[] = JHtml::fetch('select.option', 0, JText::translate('JALL')); |
| 288 | |
| 289 | if (is_admin()) |
| 290 | { |
| 291 | $onchange = "document.adminForm.submit()"; |
| 292 | } |
| 293 | else |
| 294 | { |
| 295 | $onchange = "this.form.submit()"; |
| 296 | } |
| 297 | |
| 298 | // build the limit dropdown |
| 299 | return '<select name="' . $this->prefix . 'limit" class="form-select" onchange="' . $onchange . '">' |
| 300 | . JHtml::fetch('select.options', $limits, 'value', 'text', $this->limit) |
| 301 | . '</select>'; |
| 302 | } |
| 303 | } |
| 304 |