PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/sort.php

https://github.com/phpbb/customisation-db
PHP | 499 lines | 273 code | 70 blank | 156 comment | 39 complexity | 3c44228254e9b569b4dec8f571ee6d7c MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * This file is part of the phpBB Customisation Database package.
  5. *
  6. * @copyright (c) phpBB Limited <https://www.phpbb.com>
  7. * @license GNU General Public License, version 2 (GPL-2.0)
  8. *
  9. * For full copyright and license information, please see
  10. * the docs/CREDITS.txt file.
  11. *
  12. */
  13. namespace phpbb\titania;
  14. /**
  15. * Class to generate pagination
  16. */
  17. class sort extends entity\base
  18. {
  19. /** @var \phpbb\db\driver\driver_interface */
  20. protected $db;
  21. /** @var \phpbb\user */
  22. protected $user;
  23. /** @var \phpbb\template\template */
  24. protected $template;
  25. /** @var \phpbb\request\request_interface */
  26. protected $request;
  27. /** @var \phpbb\pagination */
  28. protected $pagination;
  29. /** @var \phpbb\path_helper */
  30. protected $path_helper;
  31. /**
  32. * Constants
  33. */
  34. const OFFSET_LIMIT_DEFAULT = 25;
  35. const OFFSET_LIMIT_MAX = 100;
  36. /**
  37. * URL Location/Parameters
  38. * Setting these will over-ride the settings sent in build_pagination
  39. *
  40. * @var mixed
  41. */
  42. public $url_location = false;
  43. public $url_parameters = false;
  44. /**
  45. * Have we requested the sort data already?
  46. *
  47. * @var bool
  48. */
  49. public $request_completed = false;
  50. /**
  51. * Constructor
  52. *
  53. * @param \phpbb\db\driver\driver_interface $db
  54. * @param \phpbb\user $user
  55. * @param \phpbb\template\template $template
  56. * @param \phpbb\request\request_interface $request
  57. * @param \phpbb\pagination $pagination
  58. * @param \phpbb\path_helper $path_helper
  59. */
  60. public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, \phpbb\template\template $template, \phpbb\request\request_interface $request, \phpbb\pagination $pagination, \phpbb\path_helper $path_helper)
  61. {
  62. $this->db = $db;
  63. $this->user = $user;
  64. $this->template = $template;
  65. $this->request = $request;
  66. $this->pagination = $pagination;
  67. $this->path_helper = $path_helper;
  68. $this->configure_properties();
  69. }
  70. /**
  71. * Set some default variables, set template_vars default values
  72. *
  73. * @return $this
  74. */
  75. public function configure_properties()
  76. {
  77. // Configure object properties
  78. $this->object_config = array_merge($this->object_config, array(
  79. 'start' => array('default' => 0),
  80. 'start_name' => array('default' => 'start'),
  81. 'limit' => array('default' => self::OFFSET_LIMIT_DEFAULT),
  82. 'limit_name' => array('default' => 'limit'),
  83. 'default_limit' => array('default' => self::OFFSET_LIMIT_DEFAULT),
  84. 'max_limit' => array('default' => self::OFFSET_LIMIT_MAX),
  85. 'sort_key_ary' => array('default' => array()),
  86. 'sort_key' => array('default' => ''),
  87. 'default_sort_key' => array('default' => ''),
  88. 'sort_key_name' => array('default' => 'sk'),
  89. 'sort_dir' => array('default' => 'a'),
  90. 'default_sort_dir' => array('default' => 'a'),
  91. 'sort_dir_name' => array('default' => 'sd'),
  92. 'status' => array('default' => ''),
  93. 'status_name' => array('default' => 'status'),
  94. 'total' => array('default' => 0),
  95. 'result_lang' => array('default' => 'NUM_RESULTS'), // sprintf'd into 'TOTAL_RESULTS' output; Should have TOTAL_RESULTS and TOTAL_RESULTS_ONE strings
  96. 'template_block' => array('default' => 'pagination'),
  97. 'template_vars' => array(
  98. 'default' => array(
  99. 'S_CONTENT_FLOW_BEGIN' => 'S_CONTENT_FLOW_BEGIN',
  100. 'S_CONTENT_FLOW_END' => 'S_CONTENT_FLOW_END',
  101. 'S_PAGINATION_ACTION' => 'S_PAGINATION_ACTION',
  102. 'S_SORT_ACTION' => 'S_SORT_ACTION',
  103. 'S_NUM_POSTS' => 'S_NUM_POSTS',
  104. 'S_SELECT_SORT_KEY' => 'S_SELECT_SORT_KEY',
  105. 'S_SELECT_SORT_DIR' => 'S_SELECT_SORT_DIR',
  106. 'SORT_KEYS_NAME' => 'SORT_KEYS_NAME',
  107. 'SORT_DIR_NAME' => 'SORT_DIR_NAME',
  108. 'PER_PAGE' => 'PER_PAGE',
  109. 'ON_PAGE' => 'ON_PAGE',
  110. 'PREVIOUS_PAGE' => 'PREVIOUS_PAGE',
  111. 'NEXT_PAGE' => 'NEXT_PAGE',
  112. 'TOTAL_PAGES' => 'TOTAL_PAGES',
  113. 'TOTAL_ITEMS' => 'TOTAL_ITEMS',
  114. 'TOTAL_RESULTS' => 'TOTAL_RESULTS',
  115. ),
  116. ),
  117. ));
  118. return $this;
  119. }
  120. /**
  121. * Set some defaults
  122. *
  123. * @param int $limit Default limit, false to not change
  124. * @param string|bool $sort_key Default sort key, false to not change
  125. * @param string|bool $sort_dir (a|d) for ascending/descending, false to not change
  126. * @return $this
  127. */
  128. public function set_defaults($limit, $sort_key = false, $sort_dir = false)
  129. {
  130. if ($limit !== false)
  131. {
  132. $this->default_limit = (int) $limit;
  133. }
  134. if ($sort_key !== false)
  135. {
  136. $this->default_sort_key = $sort_key;
  137. }
  138. if ($sort_dir !== false)
  139. {
  140. $this->default_sort_dir = ($sort_dir == 'a') ? 'a' : 'd';
  141. }
  142. return $this;
  143. }
  144. /**
  145. * Request function to run the start and limit grabbing functions
  146. *
  147. * @return $this
  148. */
  149. public function request()
  150. {
  151. if ($this->request_completed)
  152. {
  153. return $this;
  154. }
  155. $this->get_start();
  156. $this->get_limit();
  157. $this->get_sort_key();
  158. $this->get_sort_dir();
  159. $this->get_status();
  160. $this->request_completed = true;
  161. return $this;
  162. }
  163. /**
  164. * Set start variable for pagination
  165. *
  166. * @param int $default custom start param
  167. *
  168. * @return int start
  169. */
  170. public function get_start($default = 0)
  171. {
  172. $this->start = $this->request->variable($this->start_name, (int) $default);
  173. return $this->start;
  174. }
  175. /**
  176. * Set limit variable for pagination
  177. *
  178. * @param int|bool $default Default Offset/Limit -- uses the constant if false is given
  179. * @return int $limit
  180. */
  181. public function get_limit($default = false)
  182. {
  183. if ($default !== false)
  184. {
  185. $this->default_limit = $default;
  186. }
  187. $limit = $this->request->variable($this->limit_name, (int) $this->default_limit);
  188. // Don't allow limits of 0 which is unlimited results. Instead use the max limit.
  189. $limit = ($limit == 0) ? $this->max_limit : $limit;
  190. // We don't allow the user to specify a limit higher than the maximum.
  191. $this->limit = ($limit > $this->max_limit) ? $this->max_limit : $limit;
  192. return $this->limit;
  193. }
  194. /**
  195. * Set sort key
  196. *
  197. * @return string
  198. */
  199. public function get_sort_key()
  200. {
  201. $this->sort_key = $this->request->variable($this->sort_key_name, (string) $this->default_sort_key);
  202. if (!isset($this->sort_key_ary[$this->sort_key]))
  203. {
  204. $this->sort_key = $this->default_sort_key;
  205. }
  206. return $this->sort_key;
  207. }
  208. /**
  209. * Set sort direction
  210. *
  211. * @return string
  212. */
  213. public function get_sort_dir()
  214. {
  215. $this->sort_dir = ($this->request->variable($this->sort_dir_name, (string) $this->default_sort_dir) == $this->default_sort_dir) ? $this->default_sort_dir : (($this->default_sort_dir == 'a') ? 'd' : 'a');
  216. return $this->sort_dir;
  217. }
  218. /**
  219. * Filter for contribution status
  220. * @return string
  221. */
  222. public function get_status()
  223. {
  224. $this->status = $this->request->variable($this->status_name, '');
  225. return $this->status;
  226. }
  227. /**
  228. * Count the number of results
  229. *
  230. * @param mixed $sql_ary
  231. * @param mixed $field
  232. * @return int
  233. */
  234. public function sql_count($sql_ary, $field)
  235. {
  236. $sql_ary['SELECT'] = "COUNT($field) AS cnt";
  237. unset($sql_ary['ORDER_BY']);
  238. $count_sql = $this->db->sql_build_query('SELECT', $sql_ary);
  239. $this->db->sql_query($count_sql);
  240. $this->total = (int) $this->db->sql_fetchfield('cnt');
  241. $this->db->sql_freeresult();
  242. return $this->total;
  243. }
  244. /**
  245. * Setup the list of possible sort options using an array
  246. *
  247. * Example: Setting the sort keys, text, and default key
  248. * <code>
  249. * $sort->set_sort_keys(array(
  250. * 'a' => array('SORT_LANG_KEY1', 't.some_sql_field'),
  251. * 'b' => array('SORT_LANG_KEY2', 't.another_sql', true), // this is the default
  252. * 'c' => array('ANOTHER_LANG', 'a.sql_field'),
  253. * ));
  254. * </code>
  255. *
  256. * @param array $sort_keys
  257. * @return $this
  258. */
  259. public function set_sort_keys($sort_keys)
  260. {
  261. foreach ($sort_keys as $key => $options)
  262. {
  263. if (!isset($options[0]) || !isset($options[1]))
  264. {
  265. unset($sort_keys[$key]);
  266. continue;
  267. }
  268. // if the third array increment is set to true, this key is set to default
  269. if ((isset($options[2]) && $options[2]))
  270. {
  271. $this->default_sort_key = $key;
  272. }
  273. }
  274. $this->sort_key_ary = $sort_keys;
  275. return $this;
  276. }
  277. /**
  278. * Set the URL info
  279. *
  280. * @param string $location
  281. * @param array $params
  282. * @return $this
  283. */
  284. public function set_url($location, $params = array())
  285. {
  286. $this->url_location = $location;
  287. if (is_array($params))
  288. {
  289. $this->url_parameters = $params;
  290. }
  291. return $this;
  292. }
  293. /**
  294. * Grab the sort key option list for usage within template
  295. *
  296. * @return string
  297. */
  298. public function get_sort_key_list()
  299. {
  300. $s_sort_key = '';
  301. foreach ($this->sort_key_ary as $key => $options)
  302. {
  303. $selected = ($this->sort_key == $key) ? ' selected="selected"' : '';
  304. $value = $options[0];
  305. $s_sort_key .= '<option value="' . $key . '"' . $selected . '>' . ((isset($this->user->lang[$value])) ? $this->user->lang[$value] : $value) . '</option>';
  306. }
  307. return $s_sort_key;
  308. }
  309. /**
  310. * Grab the sort direction option list for usage within template
  311. *
  312. * @return string
  313. */
  314. public function get_sort_dir_list()
  315. {
  316. $sort_dir = array(
  317. 'a' => 'ASCENDING',
  318. 'd' => 'DESCENDING',
  319. );
  320. $s_sort_dir = '';
  321. foreach ($sort_dir as $key => $value)
  322. {
  323. $selected = ($this->sort_dir == $key) ? ' selected="selected"' : '';
  324. $s_sort_dir .= '<option value="' . $key . '"' . $selected . '>' . ((isset($this->user->lang[$value])) ? $this->user->lang[$value] : $value) . '</option>';
  325. }
  326. return $s_sort_dir;
  327. }
  328. /**
  329. * Get order string for ORDER BY sql statement
  330. *
  331. * @return string SQL ORDER BY
  332. */
  333. public function get_order_by()
  334. {
  335. // If the sort_request function was not run yet we shall run it
  336. if (!$this->sort_key || !$this->sort_dir)
  337. {
  338. $this->request();
  339. }
  340. return $this->sort_key_ary[$this->sort_key][1] . ' ' . (($this->sort_dir == 'a') ? 'ASC' : 'DESC');
  341. }
  342. /**
  343. * Build a canonical URL
  344. */
  345. public function build_canonical()
  346. {
  347. $params = $this->url_parameters;
  348. if ($this->start)
  349. {
  350. $params[$this->start_name] = $this->start;
  351. }
  352. if ($this->limit != $this->default_limit)
  353. {
  354. $params[$this->limit_name] = $this->limit;
  355. }
  356. if ($this->sort_key != $this->default_sort_key)
  357. {
  358. $params[$this->sort_key_name] = $this->sort_key;
  359. }
  360. if ($this->sort_dir != $this->default_sort_dir)
  361. {
  362. $params[$this->sort_dir_name] = $this->sort_dir;
  363. }
  364. return $this->path_helper->append_url_params($this->url_location, $params);
  365. }
  366. /**
  367. * Build pagination and send to template
  368. * $this->url_location and $this->url_parameters will over-ride the settings given here for $page, $params.
  369. * The reason is that the place that calls build_pagination is typically in a completely different area, in an area that can't say for certain the correct URL (other than the current page)
  370. *
  371. * @param string $page path/page to be used in pagination url
  372. * @param array $params to be used in pagination url
  373. * @return $this
  374. */
  375. public function build_pagination($page, $params = array())
  376. {
  377. if ($this->url_location)
  378. {
  379. $page = $this->url_location;
  380. }
  381. if ($this->url_parameters)
  382. {
  383. $params = $this->url_parameters;
  384. }
  385. // Spring cleaning
  386. unset($params[$this->start_name], $params[$this->limit_name], $params[$this->sort_key_name], $params[$this->sort_dir_name]);
  387. // Add the limit to the URL if required
  388. if ($this->limit != $this->default_limit)
  389. {
  390. $params[$this->limit_name] = $this->limit;
  391. }
  392. // Don't include the sort key/dir in the sort action url
  393. $sort_url = $this->path_helper->append_url_params($page, $params);
  394. // Add the sort key to the URL if required
  395. if ($this->sort_key != $this->default_sort_key)
  396. {
  397. $params[$this->sort_key_name] = $this->sort_key;
  398. }
  399. // Add the sort dir to the URL if required
  400. if ($this->sort_dir != $this->default_sort_dir)
  401. {
  402. $params[$this->sort_dir_name] = $this->sort_dir;
  403. }
  404. // Add status to the URL
  405. if ($this->status != '')
  406. {
  407. $params[$this->status_name] = $this->status;
  408. }
  409. $pagination_url = $this->path_helper->append_url_params($page, $params);
  410. $this->pagination->generate_template_pagination($pagination_url, $this->template_block, 'start', $this->total, $this->limit, $this->start);
  411. if ($this->template_block == 'pagination')
  412. {
  413. $this->template->assign_vars(array(
  414. $this->template_vars['S_SORT_ACTION'] => $sort_url,
  415. $this->template_vars['S_PAGINATION_ACTION'] => $pagination_url,
  416. $this->template_vars['S_NUM_POSTS'] => $this->total,
  417. $this->template_vars['S_CONTENT_FLOW_BEGIN']=> $this->user->lang['DIRECTION'] === 'ltr' ? 'left' : 'right',
  418. $this->template_vars['S_CONTENT_FLOW_END'] => $this->user->lang['DIRECTION'] === 'ltr' ? 'right' : 'left',
  419. $this->template_vars['S_SELECT_SORT_KEY'] => $this->get_sort_key_list(),
  420. $this->template_vars['S_SELECT_SORT_DIR'] => $this->get_sort_dir_list(),
  421. $this->template_vars['SORT_KEYS_NAME'] => $this->sort_key_name,
  422. $this->template_vars['SORT_DIR_NAME'] => $this->sort_dir_name,
  423. $this->template_vars['TOTAL_ITEMS'] => $this->total,
  424. $this->template_vars['TOTAL_RESULTS'] => $this->user->lang($this->result_lang, $this->total),
  425. ));
  426. }
  427. return $this;
  428. }
  429. }