From 3dbe5d61e6c95e26a3956c1066500e2e6c61b385 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Tue, 15 Nov 2016 14:20:47 +0100 Subject: [PATCH] Allow to override sorting flags for page header-based or default ordering. If the `intl` PHP extension is loaded, only these flags are available: https://secure.php.net/manual/en/collator.asort.php. Otherwise, you can use the PHP standard sorting flags (https://secure.php.net/manual/en/array.constants.php) [#1169](https://github.com/getgrav/grav/issues/1169) --- CHANGELOG.md | 3 ++- system/src/Grav/Common/Page/Collection.php | 6 +++--- system/src/Grav/Common/Page/Page.php | 9 ++++++++- system/src/Grav/Common/Page/Pages.php | 22 +++++++++++++--------- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fd7dc63f..44b5bf9c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,13 @@ * Added `getTaxonomyItemKeys` to the Taxonomy object [#1124](https://github.com/getgrav/grav/issues/1124) * Added a `redirect_me` Twig function [#1124](https://github.com/getgrav/grav/issues/1124) * Added a Caddyfile for newer Caddy versions [#1115](https://github.com/getgrav/grav/issues/1115) + * Allow to override sorting flags for page header-based or default ordering. If the `intl` PHP extension is loaded, only these flags are available: https://secure.php.net/manual/en/collator.asort.php. Otherwise, you can use the PHP standard sorting flags (https://secure.php.net/manual/en/array.constants.php) [#1169](https://github.com/getgrav/grav/issues/1169) 1. [](#bugfix) * Fixed an issue with site redirects/routes, not processing with extension (.html, .json, etc.) * Don't truncate HTML if content length is less than summary size [#1125](https://github.com/getgrav/grav/issues/1125) * Return max available number when calling random() on a collection passing an int > available items [#1135](https://github.com/getgrav/grav/issues/1135) * Use correct ratio when applying image filters to image alternatives [#1147](https://github.com/getgrav/grav/issues/1147) - * Fixed URI path in multi-site when query parameters were used in front page + * Fixed URI path in multi-site when query parameters were used in front page # v1.1.8 ## 10/22/2016 diff --git a/system/src/Grav/Common/Page/Collection.php b/system/src/Grav/Common/Page/Collection.php index 5a70ba99c..53baf620d 100644 --- a/system/src/Grav/Common/Page/Collection.php +++ b/system/src/Grav/Common/Page/Collection.php @@ -84,7 +84,6 @@ public function copy() public function setParams(array $params) { $this->params = array_merge($this->params, $params); - return $this; } @@ -172,12 +171,13 @@ public function remove($key = null) * @param string $by * @param string $dir * @param array $manual + * @param string $sort_flags * * @return $this */ - public function order($by, $dir = 'asc', $manual = null) + public function order($by, $dir = 'asc', $manual = null, $sort_flags = null) { - $this->items = $this->pages->sortCollection($this, $by, $dir, $manual); + $this->items = $this->pages->sortCollection($this, $by, $dir, $manual, $sort_flags); return $this; } diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index fbf3ebdc3..eb83808b6 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -2291,7 +2291,14 @@ public function collection($params = 'content', $pagination = true) $by = isset($params['order']['by']) ? $params['order']['by'] : 'default'; $dir = isset($params['order']['dir']) ? $params['order']['dir'] : 'asc'; $custom = isset($params['order']['custom']) ? $params['order']['custom'] : null; - $collection->order($by, $dir, $custom); + $sort_flags = isset($params['order']['sort_flags']) ? $params['order']['sort_flags'] : null; + + if (is_array($sort_flags)) { + $sort_flags = array_map('constant', $sort_flags); //transform strings to constant value + $sort_flags = array_reduce($sort_flags, function($a, $b) { return $a | $b; }, 0); //merge constant values using bit or + } + + $collection->order($by, $dir, $custom, $sort_flags); } /** @var Grav $grav */ diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 0b7691b4a..02a3f1e88 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -21,6 +21,7 @@ use RocketTheme\Toolbox\Event\Event; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; use Whoops\Exception\ErrorException; +use Collator as Collator; class Pages { @@ -197,7 +198,7 @@ public function addPage(Page $page, $route = null) * * @return array */ - public function sort(Page $page, $order_by = null, $order_dir = null) + public function sort(Page $page, $order_by = null, $order_dir = null, $sort_flags = null) { if ($order_by === null) { $order_by = $page->orderBy(); @@ -214,7 +215,7 @@ public function sort(Page $page, $order_by = null, $order_dir = null) } if (!isset($this->sort[$path][$order_by])) { - $this->buildSort($path, $children, $order_by, $page->orderManual()); + $this->buildSort($path, $children, $order_by, $page->orderManual(), $sort_flags); } $sort = $this->sort[$path][$order_by]; @@ -235,7 +236,7 @@ public function sort(Page $page, $order_by = null, $order_dir = null) * @return array * @internal */ - public function sortCollection(Collection $collection, $orderBy, $orderDir = 'asc', $orderManual = null) + public function sortCollection(Collection $collection, $orderBy, $orderDir = 'asc', $orderManual = null, $sort_flags = null) { $items = $collection->toArray(); if (!$items) { @@ -244,7 +245,7 @@ public function sortCollection(Collection $collection, $orderBy, $orderDir = 'as $lookup = md5(json_encode($items) . json_encode($orderManual) . $orderBy . $orderDir); if (!isset($this->sort[$lookup][$orderBy])) { - $this->buildSort($lookup, $items, $orderBy, $orderManual); + $this->buildSort($lookup, $items, $orderBy, $orderManual, $sort_flags); } $sort = $this->sort[$lookup][$orderBy]; @@ -1023,12 +1024,11 @@ protected function buildRoutes() * @throws \RuntimeException * @internal */ - protected function buildSort($path, array $pages, $order_by = 'default', $manual = null) + protected function buildSort($path, array $pages, $order_by = 'default', $manual = null, $sort_flags = null) { $list = []; $header_default = null; $header_query = null; - $sort_flags = SORT_NATURAL | SORT_FLAG_CASE; // do this header query work only once if (strpos($order_by, 'header.') === 0) { @@ -1070,16 +1070,20 @@ protected function buildSort($path, array $pages, $order_by = 'default', $manual } else { $list[$key] = $header_default ?: $key; } - $sort_flags = SORT_REGULAR; + $sort_flags = $sort_flags ?: SORT_REGULAR; break; case 'manual': case 'default': default: $list[$key] = $key; - $sort_flags = SORT_REGULAR; + $sort_flags = $sort_flags ?: SORT_REGULAR; } } + if (!$sort_flags) { + $sort_flags = SORT_NATURAL | SORT_FLAG_CASE; + } + // handle special case when order_by is random if ($order_by == 'random') { $list = $this->arrayShuffle($list); @@ -1087,7 +1091,7 @@ protected function buildSort($path, array $pages, $order_by = 'default', $manual // else just sort the list according to specified key if (extension_loaded('intl')) { $locale = setlocale(LC_COLLATE, 0); //`setlocale` with a 0 param returns the current locale set - $col = \Collator::create($locale); + $col = Collator::create($locale); if ($col) { $col->asort($list, $sort_flags); } else {