From 52f3e4e48fc521245273723e1156295969a51d21 Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Fri, 4 Jan 2019 22:26:39 +0100 Subject: [PATCH 0001/1831] Making CategoryNode and MenuItem ImmutableNodes --- libraries/src/Categories/CategoryNode.php | 33 +++- libraries/src/Menu/MenuItem.php | 173 ++++++++++++++---- libraries/src/Menu/SiteMenu.php | 3 + libraries/src/Tree/ImmutableNodeInterface.php | 2 +- 4 files changed, 175 insertions(+), 36 deletions(-) diff --git a/libraries/src/Categories/CategoryNode.php b/libraries/src/Categories/CategoryNode.php index 7d1c4d8c6d474..825185547ce39 100644 --- a/libraries/src/Categories/CategoryNode.php +++ b/libraries/src/Categories/CategoryNode.php @@ -12,6 +12,7 @@ use Joomla\CMS\Factory; use Joomla\CMS\Object\CMSObject; +use Joomla\CMS\Tree\NodeInterface; use Joomla\Registry\Registry; /** @@ -19,7 +20,7 @@ * * @since 1.6 */ -class CategoryNode extends CMSObject +class CategoryNode extends CMSObject implements NodeInterface { /** * Primary key @@ -296,7 +297,7 @@ class CategoryNode extends CMSObject /** * Constructor of this tree * - * @var CategoryNode + * @var Categories * @since 1.6 */ protected $_constructor = null; @@ -304,8 +305,8 @@ class CategoryNode extends CMSObject /** * Class constructor * - * @param array $category The category data. - * @param CategoryNode $constructor The tree constructor. + * @param array $category The category data. + * @param Categories $constructor The tree constructor. * * @since 1.6 */ @@ -581,6 +582,30 @@ public function getPath() return $this->_path; } + /** + * Get the root of the tree + * + * @return CategoryNode + * + * @since __DEPLOY_VERSION__ + */ + public function getRoot() + { + $root = $this->getParent(); + + if (!$root) + { + return $this; + } + + while ($root->getParent()) + { + $root = $root->getParent(); + } + + return $root; + } + /** * Returns the user that created the category * diff --git a/libraries/src/Menu/MenuItem.php b/libraries/src/Menu/MenuItem.php index 0aa78b0eb8471..e7fb31c45d8a3 100644 --- a/libraries/src/Menu/MenuItem.php +++ b/libraries/src/Menu/MenuItem.php @@ -10,6 +10,8 @@ defined('JPATH_PLATFORM') or die; +use Joomla\CMS\Menu\AbstractMenu; +use Joomla\CMS\Tree\ImmutableNodeInterface; use Joomla\Registry\Registry; /** @@ -18,7 +20,7 @@ * @since 3.7.0 * @note This class will no longer extend stdClass in Joomla 4 */ -class MenuItem extends \stdClass +class MenuItem extends \stdClass implements ImmutableNodeInterface { /** * Primary key @@ -189,6 +191,14 @@ class MenuItem extends \stdClass */ public $query = array(); + /** + * The constructor of this node to retrieve other parts of the tree + * + * @var AbstractMenu + * @since __DEPLOY_VERSION__ + */ + protected $constructor; + /** * Class constructor * @@ -205,66 +215,167 @@ public function __construct($data = array()) } /** - * Method to get certain otherwise inaccessible properties from the form field object. + * Method to clean up the object before serialisation + * + * @return array An array of object vars + * + * @since __DEPLOY_VERSION__ + */ + public function __sleep() + { + $this->constructor = null; + + return array_keys(get_object_vars($this)); + } + + /** + * Method to set the constructor of this node to retrieve other parts of the tree * - * @param string $name The property name for which to get the value. + * @param AbstractMenu $constructor Constructor * - * @return mixed The property value or null. + * @return void * - * @since 3.7.0 - * @deprecated 4.0 Access the item parameters through the `getParams()` method + * @since __DEPLOY_VERSION__ + */ + public function setMenuConstructor(AbstractMenu $constructor) + { + $this->constructor = $constructor; + } + + /** + * Get the children of this node + * + * @param boolean $recursive False by default + * + * @return NodeInterface[] The children + * + * @since __DEPLOY_VERSION__ */ - public function __get($name) + public function &getChildren($recursive = false) { - if ($name === 'params') + $children = $this->constructor->getItems('parent_id', $this->id); + + if ($recursive) { - return $this->getParams(); + $items = array(); + + foreach ($children as $child) + { + $items[] = $child; + $items = array_merge($items, $child->getChildren(true)); + } + + return $items; } - return $this->get($name); + return $children; } /** - * Method to set certain otherwise inaccessible properties of the form field object. - * - * @param string $name The property name for which to set the value. - * @param mixed $value The value of the property. + * Get the parent of this node * - * @return void + * @return NodeInterface|null * - * @since 3.7.0 - * @deprecated 4.0 Set the item parameters through the `setParams()` method + * @since __DEPLOY_VERSION__ + */ + public function getParent() + { + if ($this->parent_id != 1) + { + return $this->constructor->getItem($this->parent_id); + } + + return null; + } + + /** + * Get the root of the tree + * + * @return NodeInterface + * + * @since __DEPLOY_VERSION__ */ - public function __set($name, $value) + public function getRoot() { - if ($name === 'params') + $root = $this->getParent(); + + if (!$root) { - $this->setParams($value); + return $this; + } - return; + while ($root->getParent()) + { + $root = $root->getParent(); } - $this->set($name, $value); + return $root; + } + + /** + * Test if this node has children + * + * @return boolean True if there is a child + * + * @since __DEPLOY_VERSION__ + */ + public function hasChildren() + { + return (bool) count($this->getChildren()); + } + + /** + * Test if this node has a parent + * + * @return boolean True if there is a parent + * + * @since __DEPLOY_VERSION__ + */ + public function hasParent() + { + return $this->parent_id > 1 ? true : false; } /** - * Method check if a certain otherwise inaccessible properties of the form field object is set. + * Returns the right or left sibling of a node * - * @param string $name The property name to check. + * @param boolean $right If set to false, returns the left sibling * - * @return boolean + * @return NodeInterface|null NodeInterface object of the sibling. * - * @since 3.7.1 - * @deprecated 4.0 Deprecated without replacement + * @since __DEPLOY_VERSION__ */ - public function __isset($name) + public function getSibling($right = true) { - if ($name === 'params') + $children = $this->constructor->getItems('parent_id', $this->parent_id); + + $prev = null; + $found = false; + + foreach ($children as $child) { - return !($this->params instanceof Registry); + // The previous child is our current node and we want the right node + if ($found) + { + return $child; + } + + // We found the current node + if ($child->id == $this->id) + { + // We want the left node + if (!$right) + { + return $prev; + } + + $found = true; + } + + $prev = $child; } - return $this->get($name) !== null; + return null; } /** diff --git a/libraries/src/Menu/SiteMenu.php b/libraries/src/Menu/SiteMenu.php index dc1f4d009702f..65d2ddff3e09d 100644 --- a/libraries/src/Menu/SiteMenu.php +++ b/libraries/src/Menu/SiteMenu.php @@ -124,6 +124,9 @@ public function load() foreach ($this->getMenu() as &$item) { + // Set the constructor + $item->setMenuConstructor($this); + // Get parent information. $parent_tree = array(); diff --git a/libraries/src/Tree/ImmutableNodeInterface.php b/libraries/src/Tree/ImmutableNodeInterface.php index 4a2c296a89113..802b25cb3ed54 100644 --- a/libraries/src/Tree/ImmutableNodeInterface.php +++ b/libraries/src/Tree/ImmutableNodeInterface.php @@ -40,7 +40,7 @@ public function getParent(); /** * Get the root of the tree * - * @return NodeInterface + * @return ImmutableNodeInterface * * @since __DEPLOY_VERSION__ */ From c70602b73c58e6cfdad41bcae68dedd6b02d2dda Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Sat, 5 Jan 2019 00:51:54 +0100 Subject: [PATCH 0002/1831] Adding ImmutableNodeTrait, NodeTrait Optimising CategoryNode, MenuItem Improving menu item discovery in routing --- libraries/src/Categories/CategoryNode.php | 190 ++-------------------- libraries/src/Menu/MenuItem.php | 177 ++++---------------- libraries/src/Menu/SiteMenu.php | 4 +- libraries/src/Router/SiteRouter.php | 77 ++++----- libraries/src/Tree/ImmutableNodeTrait.php | 159 ++++++++++++++++++ libraries/src/Tree/NodeInterface.php | 6 +- libraries/src/Tree/NodeTrait.php | 108 ++++++++++++ 7 files changed, 358 insertions(+), 363 deletions(-) create mode 100644 libraries/src/Tree/ImmutableNodeTrait.php create mode 100644 libraries/src/Tree/NodeTrait.php diff --git a/libraries/src/Categories/CategoryNode.php b/libraries/src/Categories/CategoryNode.php index 825185547ce39..c81b24dd7e8d1 100644 --- a/libraries/src/Categories/CategoryNode.php +++ b/libraries/src/Categories/CategoryNode.php @@ -13,6 +13,7 @@ use Joomla\CMS\Factory; use Joomla\CMS\Object\CMSObject; use Joomla\CMS\Tree\NodeInterface; +use Joomla\CMS\Tree\NodeTrait; use Joomla\Registry\Registry; /** @@ -22,6 +23,8 @@ */ class CategoryNode extends CMSObject implements NodeInterface { + use NodeTrait; + /** * Primary key * @@ -246,22 +249,6 @@ class CategoryNode extends CMSObject implements NodeInterface */ public $assets = null; - /** - * Parent Category object - * - * @var CategoryNode - * @since 1.6 - */ - protected $_parent = null; - - /** - * Array of Children - * - * @var CategoryNode[] - * @since 1.6 - */ - protected $_children = array(); - /** * Path from root to this category * @@ -270,22 +257,6 @@ class CategoryNode extends CMSObject implements NodeInterface */ protected $_path = array(); - /** - * Category left of this one - * - * @var CategoryNode - * @since 1.6 - */ - protected $_leftSibling = null; - - /** - * Category right of this one - * - * @var CategoryNode - * @since 1.6 - */ - protected $_rightSibling = null; - /** * Flag if all children have been loaded * @@ -338,74 +309,31 @@ public function __construct($category = null, $constructor = null) * * @since 1.6 */ - public function setParent($parent) + public function setParent(NodeInterface $parent) { - if ($parent instanceof CategoryNode || is_null($parent)) + if (!is_null($this->_parent)) { - if (!is_null($this->_parent)) - { - $key = array_search($this, $this->_parent->_children); - unset($this->_parent->_children[$key]); - } - - if (!is_null($parent)) - { - $parent->_children[] = & $this; - } - - $this->_parent = $parent; + $key = array_search($this, $this->_parent->_children); + unset($this->_parent->_children[$key]); + } - if ($this->id != 'root') - { - if ($this->parent_id != 1) - { - $this->_path = $parent->getPath(); - } + $this->_parent = $parent; - $this->_path[$this->id] = $this->id . ':' . $this->alias; - } + $this->_parent->_children[] = & $this; - if (count($parent->_children) > 1) - { - end($parent->_children); - $this->_leftSibling = prev($parent->_children); - $this->_leftSibling->_rightsibling = & $this; - } + if (count($this->_parent->_children) > 1) + { + end($this->_parent->_children); + $this->_leftSibling = prev($this->_parent->_children); + $this->_leftSibling->_rightsibling = & $this; } - } - /** - * Add child to this node - * - * If the child already has a parent, the link is unset - * - * @param CategoryNode $child The child to be added. - * - * @return void - * - * @since 1.6 - */ - public function addChild($child) - { - if ($child instanceof CategoryNode) + if ($this->parent_id != 1) { - $child->setParent($this); + $this->_path = $parent->getPath(); } - } - /** - * Remove a specific child - * - * @param integer $id ID of a category - * - * @return void - * - * @since 1.6 - */ - public function removeChild($id) - { - $key = array_search($this, $this->_parent->_children); - unset($this->_parent->_children[$key]); + $this->_path[$this->id] = $this->id . ':' . $this->alias; } /** @@ -448,64 +376,6 @@ public function &getChildren($recursive = false) return $this->_children; } - /** - * Get the parent of this node - * - * @return CategoryNode - * - * @since 1.6 - */ - public function getParent() - { - return $this->_parent; - } - - /** - * Test if this node has children - * - * @return boolean True if there is a child - * - * @since 1.6 - */ - public function hasChildren() - { - return count($this->_children); - } - - /** - * Test if this node has a parent - * - * @return boolean True if there is a parent - * - * @since 1.6 - */ - public function hasParent() - { - return $this->getParent() != null; - } - - /** - * Function to set the left or right sibling of a category - * - * @param CategoryNode $sibling CategoryNode object for the sibling - * @param boolean $right If set to false, the sibling is the left one - * - * @return void - * - * @since 1.6 - */ - public function setSibling($sibling, $right = true) - { - if ($right) - { - $this->_rightSibling = $sibling; - } - else - { - $this->_leftSibling = $sibling; - } - } - /** * Returns the right or left sibling of a category * @@ -582,30 +452,6 @@ public function getPath() return $this->_path; } - /** - * Get the root of the tree - * - * @return CategoryNode - * - * @since __DEPLOY_VERSION__ - */ - public function getRoot() - { - $root = $this->getParent(); - - if (!$root) - { - return $this; - } - - while ($root->getParent()) - { - $root = $root->getParent(); - } - - return $root; - } - /** * Returns the user that created the category * diff --git a/libraries/src/Menu/MenuItem.php b/libraries/src/Menu/MenuItem.php index e7fb31c45d8a3..8f37367a1df0d 100644 --- a/libraries/src/Menu/MenuItem.php +++ b/libraries/src/Menu/MenuItem.php @@ -11,17 +11,19 @@ defined('JPATH_PLATFORM') or die; use Joomla\CMS\Menu\AbstractMenu; -use Joomla\CMS\Tree\ImmutableNodeInterface; +use Joomla\CMS\Tree\NodeInterface; +use Joomla\CMS\Tree\NodeTrait; use Joomla\Registry\Registry; /** * Object representing a menu item * * @since 3.7.0 - * @note This class will no longer extend stdClass in Joomla 4 */ -class MenuItem extends \stdClass implements ImmutableNodeInterface +class MenuItem implements NodeInterface { + use NodeTrait; + /** * Primary key * @@ -191,14 +193,6 @@ class MenuItem extends \stdClass implements ImmutableNodeInterface */ public $query = array(); - /** - * The constructor of this node to retrieve other parts of the tree - * - * @var AbstractMenu - * @since __DEPLOY_VERSION__ - */ - protected $constructor; - /** * Class constructor * @@ -215,167 +209,66 @@ public function __construct($data = array()) } /** - * Method to clean up the object before serialisation + * Method to get certain otherwise inaccessible properties from the form field object. * - * @return array An array of object vars + * @param string $name The property name for which to get the value. * - * @since __DEPLOY_VERSION__ - */ - public function __sleep() - { - $this->constructor = null; - - return array_keys(get_object_vars($this)); - } - - /** - * Method to set the constructor of this node to retrieve other parts of the tree - * - * @param AbstractMenu $constructor Constructor - * - * @return void + * @return mixed The property value or null. * - * @since __DEPLOY_VERSION__ - */ - public function setMenuConstructor(AbstractMenu $constructor) - { - $this->constructor = $constructor; - } - - /** - * Get the children of this node - * - * @param boolean $recursive False by default - * - * @return NodeInterface[] The children - * - * @since __DEPLOY_VERSION__ + * @since 3.7.0 + * @deprecated 4.0 Access the item parameters through the `getParams()` method */ - public function &getChildren($recursive = false) + public function __get($name) { - $children = $this->constructor->getItems('parent_id', $this->id); - - if ($recursive) + if ($name === 'params') { - $items = array(); - - foreach ($children as $child) - { - $items[] = $child; - $items = array_merge($items, $child->getChildren(true)); - } - - return $items; + return $this->getParams(); } - return $children; + return $this->get($name); } /** - * Get the parent of this node + * Method to set certain otherwise inaccessible properties of the form field object. * - * @return NodeInterface|null + * @param string $name The property name for which to set the value. + * @param mixed $value The value of the property. * - * @since __DEPLOY_VERSION__ - */ - public function getParent() - { - if ($this->parent_id != 1) - { - return $this->constructor->getItem($this->parent_id); - } - - return null; - } - - /** - * Get the root of the tree - * - * @return NodeInterface - * - * @since __DEPLOY_VERSION__ + * @return void + * + * @since 3.7.0 + * @deprecated 4.0 Set the item parameters through the `setParams()` method */ - public function getRoot() + public function __set($name, $value) { - $root = $this->getParent(); - - if (!$root) + if ($name === 'params') { - return $this; - } + $this->setParams($value); - while ($root->getParent()) - { - $root = $root->getParent(); + return; } - return $root; - } - - /** - * Test if this node has children - * - * @return boolean True if there is a child - * - * @since __DEPLOY_VERSION__ - */ - public function hasChildren() - { - return (bool) count($this->getChildren()); - } - - /** - * Test if this node has a parent - * - * @return boolean True if there is a parent - * - * @since __DEPLOY_VERSION__ - */ - public function hasParent() - { - return $this->parent_id > 1 ? true : false; + $this->set($name, $value); } /** - * Returns the right or left sibling of a node + * Method check if a certain otherwise inaccessible properties of the form field object is set. * - * @param boolean $right If set to false, returns the left sibling + * @param string $name The property name to check. * - * @return NodeInterface|null NodeInterface object of the sibling. + * @return boolean * - * @since __DEPLOY_VERSION__ + * @since 3.7.1 + * @deprecated 4.0 Deprecated without replacement */ - public function getSibling($right = true) + public function __isset($name) { - $children = $this->constructor->getItems('parent_id', $this->parent_id); - - $prev = null; - $found = false; - - foreach ($children as $child) + if ($name === 'params') { - // The previous child is our current node and we want the right node - if ($found) - { - return $child; - } - - // We found the current node - if ($child->id == $this->id) - { - // We want the left node - if (!$right) - { - return $prev; - } - - $found = true; - } - - $prev = $child; + return !($this->params instanceof Registry); } - return null; + return $this->get($name) !== null; } /** diff --git a/libraries/src/Menu/SiteMenu.php b/libraries/src/Menu/SiteMenu.php index 65d2ddff3e09d..4eeb4af09b429 100644 --- a/libraries/src/Menu/SiteMenu.php +++ b/libraries/src/Menu/SiteMenu.php @@ -124,14 +124,12 @@ public function load() foreach ($this->getMenu() as &$item) { - // Set the constructor - $item->setMenuConstructor($this); - // Get parent information. $parent_tree = array(); if (isset($this->getMenu()[$item->parent_id])) { + $item->setParent($this->getMenu()[$item->parent_id]); $parent_tree = $this->getMenu()[$item->parent_id]->tree; } diff --git a/libraries/src/Router/SiteRouter.php b/libraries/src/Router/SiteRouter.php index b0666252ec423..5949c4940dd78 100644 --- a/libraries/src/Router/SiteRouter.php +++ b/libraries/src/Router/SiteRouter.php @@ -225,55 +225,46 @@ public function parseSefRoute(&$router, &$uri) else { // Get menu items. - $items = $this->menu->getMenu(); + $items = $this->menu->getItems('parent_id', 1); + $lang_tag = $this->app->getLanguage()->getTag(); + $found = null; - $found = false; - $route_lowercase = StringHelper::strtolower($route); - $lang_tag = $this->app->getLanguage()->getTag(); - - // Iterate through all items and check route matches. - foreach ($items as $item) + foreach ($segments as $segment) { - if ($item->route && StringHelper::strpos($route_lowercase . '/', $item->route . '/') === 0 && $item->type !== 'menulink') + $matched = false; + + foreach ($items as $item) { - // Usual method for non-multilingual site. - if (!$this->app->getLanguageFilter()) - { - // Exact route match. We can break iteration because exact item was found. - if ($item->route === $route_lowercase) - { - $found = $item; - break; - } - - // Partial route match. Item with highest level takes priority. - if (!$found || $found->level < $item->level) - { - $found = $item; - } - } - // Multilingual site. - elseif ($item->language === '*' || $item->language === $lang_tag) + if ($item->alias == $segment + && (!$this->app->getLanguageFilter() + || ($item->language === '*' + || $item->language === $lang_tag))) { - // Exact route match. - if ($item->route === $route_lowercase) - { - $found = $item; - - // Break iteration only if language is matched. - if ($item->language === $lang_tag) - { - break; - } - } - - // Partial route match. Item with highest level or same language takes priority. - if (!$found || $found->level < $item->level || $item->language === $lang_tag) - { - $found = $item; - } + $found = $item; + $matched = true; + $items = $item->getChildren(); + break; } } + + if (!$matched) + { + break; + } + } + + // Menu links are not valid URLs. Find the first parent that isn't a menulink + if ($found->type == 'menulink') + { + while ($found->hasParent() && $found->type == 'menulink') + { + $found = $found->getParent(); + } + + if ($found->type == 'menulink') + { + $found = null; + } } if (!$found) diff --git a/libraries/src/Tree/ImmutableNodeTrait.php b/libraries/src/Tree/ImmutableNodeTrait.php new file mode 100644 index 0000000000000..7d153607e4a41 --- /dev/null +++ b/libraries/src/Tree/ImmutableNodeTrait.php @@ -0,0 +1,159 @@ +_children as $child) + { + $items[] = $child; + $items = array_merge($items, $child->getChildren(true)); + } + + return $items; + } + + return $this->_children; + } + + /** + * Get the parent of this node + * + * @return NodeInterface|null + * + * @since __DEPLOY_VERSION__ + */ + public function getParent() + { + return $this->_parent; + } + + /** + * Get the root of the tree + * + * @return ImmutableNodeInterface + * + * @since __DEPLOY_VERSION__ + */ + public function getRoot() + { + $root = $this->getParent(); + + if (!$root) + { + return $this; + } + + while ($root->hasParent()) + { + $root = $root->getParent(); + } + + return $root; + } + + /** + * Test if this node has children + * + * @return boolean True if there is a child + * + * @since __DEPLOY_VERSION__ + */ + public function hasChildren() + { + return (bool) count($this->_children); + } + + /** + * Test if this node has a parent + * + * @return boolean True if there is a parent + * + * @since __DEPLOY_VERSION__ + */ + public function hasParent() + { + return $this->getParent() != null; + } + + /** + * Returns the right or left sibling of a node + * + * @param boolean $right If set to false, returns the left sibling + * + * @return NodeInterface|null NodeInterface object of the sibling. + * + * @since __DEPLOY_VERSION__ + */ + public function getSibling($right = true) + { + if ($right) + { + return $this->_rightSibling; + } + else + { + return $this->_leftSibling; + } + } +} diff --git a/libraries/src/Tree/NodeInterface.php b/libraries/src/Tree/NodeInterface.php index aa29b51385eb9..d709dc4657147 100644 --- a/libraries/src/Tree/NodeInterface.php +++ b/libraries/src/Tree/NodeInterface.php @@ -28,7 +28,7 @@ interface NodeInterface extends ImmutableNodeInterface * * @since __DEPLOY_VERSION__ */ - public function setParent($parent); + public function setParent(NodeInterface $parent); /** * Add child to this node @@ -41,7 +41,7 @@ public function setParent($parent); * * @since __DEPLOY_VERSION__ */ - public function addChild($child); + public function addChild(NodeInterface $child); /** * Remove a specific child @@ -64,5 +64,5 @@ public function removeChild($id); * * @since __DEPLOY_VERSION__ */ - public function setSibling($sibling, $right = true); + public function setSibling(NodeInterface $sibling, $right = true); } diff --git a/libraries/src/Tree/NodeTrait.php b/libraries/src/Tree/NodeTrait.php new file mode 100644 index 0000000000000..b6edea1f6ded6 --- /dev/null +++ b/libraries/src/Tree/NodeTrait.php @@ -0,0 +1,108 @@ +_parent)) + { + $key = array_search($this, $this->_parent->_children); + unset($this->_parent->_children[$key]); + } + + $this->_parent = $parent; + + $this->_parent->_children[] = & $this; + + if (count($this->_parent->_children) > 1) + { + end($this->_parent->_children); + $this->_leftSibling = prev($this->_parent->_children); + $this->_leftSibling->_rightsibling = & $this; + } + } + + /** + * Add child to this node + * + * If the child already has a parent, the link is unset + * + * @param NodeInterface $child The child to be added. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function addChild(NodeInterface $child) + { + $child->setParent($this); + } + + /** + * Remove a specific child + * + * @param integer $id ID of a node + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function removeChild($id) + { + $key = array_search($this, $this->_parent->_children); + unset($this->_parent->_children[$key]); + } + + /** + * Function to set the left or right sibling of a node + * + * @param NodeInterface $sibling NodeInterface object for the sibling + * @param boolean $right If set to false, the sibling is the left one + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function setSibling(NodeInterface $sibling, $right = true) + { + if ($right) + { + $this->_rightSibling = $sibling; + } + else + { + $this->_leftSibling = $sibling; + } + } +} From 0f9040d7033b503344a40af19236c4a871d70d6b Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Sat, 5 Jan 2019 11:31:44 +0100 Subject: [PATCH 0003/1831] Fixing typo --- libraries/src/Tree/NodeTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/Tree/NodeTrait.php b/libraries/src/Tree/NodeTrait.php index b6edea1f6ded6..cb5cb228abb44 100644 --- a/libraries/src/Tree/NodeTrait.php +++ b/libraries/src/Tree/NodeTrait.php @@ -49,7 +49,7 @@ public function setParent(NodeInterface $parent) { end($this->_parent->_children); $this->_leftSibling = prev($this->_parent->_children); - $this->_leftSibling->_rightsibling = & $this; + $this->_leftSibling->_rightSibling = & $this; } } From ac272c7345a39f5f0cfcb30ca391aeb1e98c7ced Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Tue, 8 Jan 2019 09:46:46 +0100 Subject: [PATCH 0004/1831] Fixing reference bug --- libraries/src/Tree/NodeTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/Tree/NodeTrait.php b/libraries/src/Tree/NodeTrait.php index b6edea1f6ded6..6958b59ddc26b 100644 --- a/libraries/src/Tree/NodeTrait.php +++ b/libraries/src/Tree/NodeTrait.php @@ -49,7 +49,7 @@ public function setParent(NodeInterface $parent) { end($this->_parent->_children); $this->_leftSibling = prev($this->_parent->_children); - $this->_leftSibling->_rightsibling = & $this; + $this->_leftSibling->_rightsibling = $this; } } From c288b3144f23d19017094e5ca101b2889becc482 Mon Sep 17 00:00:00 2001 From: fancyFranci Date: Sat, 12 Jan 2019 19:42:28 +0100 Subject: [PATCH 0005/1831] edit upper toolbar buttons and dropdowns --- .../language/en-GB/en-GB.com_categories.ini | 1 + .../language/en-GB/en-GB.mod_status.ini | 8 ++ .../modules/mod_status/tmpl/default.php | 130 +++++++++++++----- .../templates/atum/scss/_variables.scss | 6 +- .../templates/atum/scss/blocks/_header.scss | 36 ++++- 5 files changed, 143 insertions(+), 38 deletions(-) diff --git a/administrator/language/en-GB/en-GB.com_categories.ini b/administrator/language/en-GB/en-GB.com_categories.ini index 8f5b823b67c1b..2f271f149cdc7 100644 --- a/administrator/language/en-GB/en-GB.com_categories.ini +++ b/administrator/language/en-GB/en-GB.com_categories.ini @@ -12,6 +12,7 @@ COM_CATEGORIES_BATCH_TIP="If a category is selected for move/copy, any actions s COM_CATEGORIES_CATEGORIES_BASE_TITLE="Categories" COM_CATEGORIES_CATEGORIES_TITLE="%s: Categories" COM_CATEGORIES_CATEGORY_ADD_TITLE="%s: New Category" +COM_CATEGORIES_CATEGORY_BASE_ADD_TITLE="New Category" COM_CATEGORIES_CATEGORY_EDIT_TITLE="%s: Edit Category" COM_CATEGORIES_CHANGE_CATEGORY="Select or Change Category" COM_CATEGORIES_DELETE_NOT_ALLOWED="Delete not allowed for category %s." diff --git a/administrator/language/en-GB/en-GB.mod_status.ini b/administrator/language/en-GB/en-GB.mod_status.ini index 468884337e67b..457b556066518 100644 --- a/administrator/language/en-GB/en-GB.mod_status.ini +++ b/administrator/language/en-GB/en-GB.mod_status.ini @@ -4,15 +4,23 @@ ; Note : All ini files need to be saved as UTF-8 MOD_STATUS="User Status" +MOD_STATUS_ACCESSIBILITY_SETTINGS="Accessibility Settings" MOD_STATUS_BACKEND_USERS_0="Administrators" MOD_STATUS_BACKEND_USERS_1="Administrator" MOD_STATUS_BACKEND_USERS_MORE="Administrators" +MOD_STATUS_BE_HAPPY="Be Happy" +MOD_STATUS_CREATE_CATEGORY="Create Category" +MOD_STATUS_CREATE_NEWSLETTER="Create Newsletter" +MOD_STATUS_CLEAR_CACHE="Clear Cache" MOD_STATUS_EDIT_ACCOUNT="Edit Account" MOD_STATUS_FIELD_SHOW_LOGGEDIN_USERS_ADMIN_LABEL="Logged-in Backend Users" MOD_STATUS_FIELD_SHOW_LOGGEDIN_USERS_LABEL="Logged-in Users" +MOD_STATUS_QUICKSTART="Quickstart" +MOD_STATUS_QUICKSTART_HEADER="Quickstart" MOD_STATUS_POST_INSTALLATION_MESSAGES="Post-installation messages" MOD_STATUS_PREVIEW="Preview %s" MOD_STATUS_PRIVATE_MESSAGES="Private Messages" +MOD_STATUS_NEW_ARTICLE="New Article" MOD_STATUS_TOTAL_USERS_0="Users" MOD_STATUS_TOTAL_USERS_1="User" MOD_STATUS_TOTAL_USERS_MORE="Users" diff --git a/administrator/modules/mod_status/tmpl/default.php b/administrator/modules/mod_status/tmpl/default.php index 3eefab3ea4aa9..df174fbccd0bf 100644 --- a/administrator/modules/mod_status/tmpl/default.php +++ b/administrator/modules/mod_status/tmpl/default.php @@ -37,21 +37,65 @@ authorise('core.manage', 'com_postinstall')) : ?> @@ -59,45 +103,61 @@ + 0) : ?> - + diff --git a/administrator/templates/atum/scss/_variables.scss b/administrator/templates/atum/scss/_variables.scss index cdd8ce7a3ad83..120d9aa67e5ab 100644 --- a/administrator/templates/atum/scss/_variables.scss +++ b/administrator/templates/atum/scss/_variables.scss @@ -36,8 +36,10 @@ $theme-colors: map-merge(( ), $theme-colors); $colors: ( - primary-dark: #2b5c91, - main-bg: #ebeff5, + primary-dark: #2b5c91, + primary-light: #3a87cb, + primary-bright: #45a0f1, + main-bg: #ebeff5, success-border: darken(theme-color("success"), 5%), info-border: darken(theme-color("info"), 7%), warning-border: darken(theme-color("warning"), 5%), diff --git a/administrator/templates/atum/scss/blocks/_header.scss b/administrator/templates/atum/scss/blocks/_header.scss index b7a3a54384c50..e0f3dee4acbc6 100644 --- a/administrator/templates/atum/scss/blocks/_header.scss +++ b/administrator/templates/atum/scss/blocks/_header.scss @@ -27,10 +27,11 @@ .nav-link { position: relative; padding: 0; + margin: 0 1rem; line-height: $header-height; + min-width: $header-height - 5px; .fa { - width: $header-height + 2px; font-size: 1.2rem; color: var(--primary-dark); vertical-align: middle; @@ -53,21 +54,54 @@ } } + .link-title { + text-decoration: underline; + } + .dropdown-menu { min-width: 280px; padding: 0; border: 0; z-index: 1041; + background-color: var(--primary-light); h2 { font-size: $h5-font-size; } + + .dropdown-message { + font-weight: bold; + color: $gray-900; + } } .dropdown-item { + color: $white; + background-color: var(--primary-light); + @include hover-focus { color: var(--primary-dark); } + + a { + display: inline-block; + width: 100%; + color: $white; + + &:hover { + color: var(--primary-dark); + text-decoration: none; + } + + .fa { + float: right; + } + } + + .fa { + padding: 0.6rem; + background-color: var(--primary-bright); + } } .dropdown-menu::after { From 7f5cdd5fffc494b425df5618028002a25f8e9ac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lavinia=20Popa-R=C3=B6ssel?= Date: Mon, 14 Jan 2019 21:53:18 +0100 Subject: [PATCH 0006/1831] adjusted style for the action buttons in the upper toolbar. Added background to nav-items when hovered and when dropdown-items are shown. Removed icons from dropdown-headers. Positioned and styled icons. Changed order in html-dom for the last dropdown, so the icons are part of the link and the whole line is clickable. --- .../modules/mod_status/tmpl/default.php | 32 +++++++------ .../templates/atum/scss/blocks/_header.scss | 47 ++++++++++++++++--- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/administrator/modules/mod_status/tmpl/default.php b/administrator/modules/mod_status/tmpl/default.php index df174fbccd0bf..6485dd3a01b35 100644 --- a/administrator/modules/mod_status/tmpl/default.php +++ b/administrator/modules/mod_status/tmpl/default.php @@ -52,7 +52,6 @@