From cea3b7eb76d60f779dc57b28026c10ba17df1aca Mon Sep 17 00:00:00 2001 From: Sam Hemelryk Date: Thu, 28 Nov 2013 10:57:14 +1300 Subject: [PATCH] MDL-35597 admin: categories now support localised alphabetical sorting --- lib/adminlib.php | 113 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 3 deletions(-) diff --git a/lib/adminlib.php b/lib/adminlib.php index 41c86ef0012..043e0af6378 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -750,8 +750,8 @@ interface parentable_part_of_admin_tree extends part_of_admin_tree { */ class admin_category implements parentable_part_of_admin_tree { - /** @var mixed An array of part_of_admin_tree objects that are this object's children */ - public $children; + /** @var part_of_admin_tree[] An array of part_of_admin_tree objects that are this object's children */ + protected $children; /** @var string An internal name for this category. Must be unique amongst ALL part_of_admin_tree objects */ public $name; /** @var string The displayed name for this category. Usually obtained through get_string() */ @@ -766,6 +766,15 @@ class admin_category implements parentable_part_of_admin_tree { /** @var array fast lookup category cache, all categories of one tree point to one cache */ protected $category_cache; + /** @var bool If set to true children will be sorted when calling {@link admin_category::get_children()} */ + protected $sort = false; + /** @var bool If set to true children will be sorted in ascending order. */ + protected $sortasc = true; + /** @var bool If set to true sub categories and pages will be split and then sorted.. */ + protected $sortsplit = true; + /** @var bool $sorted True if the children have been sorted and don't need resorting */ + protected $sorted = false; + /** * Constructor for an empty admin category * @@ -830,7 +839,7 @@ class admin_category implements parentable_part_of_admin_tree { */ public function search($query) { $result = array(); - foreach ($this->children as $child) { + foreach ($this->get_children() as $child) { $subsearch = $child->search($query); if (!is_array($subsearch)) { debugging('Incorrect search result from '.$child->name); @@ -991,6 +1000,104 @@ class admin_category implements parentable_part_of_admin_tree { } return false; } + + /** + * Sets sorting on this category. + * + * Please note this function doesn't actually do the sorting. + * It can be called anytime. + * Sorting occurs when the user calls get_children. + * Code using the children array directly won't see the sorted results. + * + * @param bool $sort If set to true children will be sorted, if false they won't be. + * @param bool $asc If true sorting will be ascending, otherwise descending. + * @param bool $split If true we sort pages and sub categories separately. + */ + public function set_sorting($sort, $asc = true, $split = true) { + $this->sort = (bool)$sort; + $this->sortasc = (bool)$asc; + $this->sortsplit = (bool)$split; + } + + /** + * Returns the children associated with this category. + * + * @return part_of_admin_tree[] + */ + public function get_children() { + // If we should sort and it hasn't already been sorted. + if ($this->sort && !$this->sorted) { + if ($this->sortsplit) { + $categories = array(); + $pages = array(); + foreach ($this->children as $child) { + if ($child instanceof admin_category) { + $categories[] = $child; + } else { + $pages[] = $child; + } + } + core_collator::asort_objects_by_property($categories, 'visiblename'); + core_collator::asort_objects_by_property($pages, 'visiblename'); + if (!$this->sortasc) { + $categories = array_reverse($categories); + $pages = array_reverse($pages); + } + $this->children = array_merge($pages, $categories); + } else { + core_collator::asort_objects_by_property($this->children, 'visiblename'); + if (!$this->sortasc) { + $this->children = array_reverse($this->children); + } + } + $this->sorted = true; + } + return $this->children; + } + + /** + * Magically gets a property from this object. + * + * @param $property + * @return part_of_admin_tree[] + * @throws coding_exception + */ + public function __get($property) { + if ($property === 'children') { + return $this->get_children(); + } + throw new coding_exception('Invalid property requested.'); + } + + /** + * Magically sets a property against this object. + * + * @param string $property + * @param mixed $value + * @throws coding_exception + */ + public function __set($property, $value) { + if ($property === 'children') { + $this->sorted = false; + $this->children = $value; + } else { + throw new coding_exception('Invalid property requested.'); + } + } + + /** + * Checks if an inaccessible property is set. + * + * @param string $property + * @return bool + * @throws coding_exception + */ + public function __isset($property) { + if ($property === 'children') { + return isset($this->children); + } + throw new coding_exception('Invalid property requested.'); + } }