aboutsummaryrefslogtreecommitdiff
path: root/engine/classes/ElggMenuBuilder.php
diff options
context:
space:
mode:
Diffstat (limited to 'engine/classes/ElggMenuBuilder.php')
-rw-r--r--engine/classes/ElggMenuBuilder.php106
1 files changed, 74 insertions, 32 deletions
diff --git a/engine/classes/ElggMenuBuilder.php b/engine/classes/ElggMenuBuilder.php
index b57ea6e18..b463143d8 100644
--- a/engine/classes/ElggMenuBuilder.php
+++ b/engine/classes/ElggMenuBuilder.php
@@ -4,11 +4,13 @@
*
* @package Elgg.Core
* @subpackage Navigation
- *
- * @since 1.8.0
+ * @since 1.8.0
*/
class ElggMenuBuilder {
+ /**
+ * @var ElggMenuItem[]
+ */
protected $menu = array();
protected $selected = null;
@@ -16,25 +18,23 @@ class ElggMenuBuilder {
/**
* ElggMenuBuilder constructor
*
- * @param string $name Identifier of the menu
+ * @param ElggMenuItem[] $menu Array of ElggMenuItem objects
*/
- public function __construct($name) {
- global $CONFIG;
-
- $this->menu = $CONFIG->menus[$name];
+ public function __construct(array $menu) {
+ $this->menu = $menu;
}
/**
* Get a prepared menu array
*
- * @param mixed $sort_by
+ * @param mixed $sort_by Method to sort the menu by. @see ElggMenuBuilder::sort()
* @return array
*/
- public function getMenu($sort_by) {
+ public function getMenu($sort_by = 'text') {
$this->selectFromContext();
- $selected = $this->findSelected();
+ $this->selected = $this->findSelected();
$this->setupSections();
@@ -68,6 +68,10 @@ class ElggMenuBuilder {
// get menu items for this context
$selected_menu = array();
foreach ($this->menu as $menu_item) {
+ if (!is_object($menu_item)) {
+ elgg_log("A non-object was passed to ElggMenuBuilder", "ERROR");
+ continue;
+ }
if ($menu_item->inContext()) {
$selected_menu[] = $menu_item;
}
@@ -78,6 +82,7 @@ class ElggMenuBuilder {
/**
* Group the menu items into sections
+ *
* @return void
*/
protected function setupSections() {
@@ -105,6 +110,7 @@ class ElggMenuBuilder {
$children = array();
// divide base nodes from children
foreach ($section as $menu_item) {
+ /* @var ElggMenuItem $menu_item */
$parent_name = $menu_item->getParentName();
if (!$parent_name) {
$parents[$menu_item->getName()] = $menu_item;
@@ -116,13 +122,16 @@ class ElggMenuBuilder {
// attach children to parents
$iteration = 0;
$current_gen = $parents;
+ $next_gen = null;
while (count($children) && $iteration < 5) {
foreach ($children as $index => $menu_item) {
$parent_name = $menu_item->getParentName();
if (array_key_exists($parent_name, $current_gen)) {
$next_gen[$menu_item->getName()] = $menu_item;
- $current_gen[$parent_name]->addChild($menu_item);
- $menu_item->setParent($current_gen[$parent_name]);
+ if (!in_array($menu_item, $current_gen[$parent_name]->getData('children'))) {
+ $current_gen[$parent_name]->addChild($menu_item);
+ $menu_item->setParent($current_gen[$parent_name]);
+ }
unset($children[$index]);
}
}
@@ -155,8 +164,8 @@ class ElggMenuBuilder {
// scan looking for a selected item
foreach ($this->menu as $menu_item) {
- if ($menu_item->getURL()) {
- if (elgg_http_url_is_identical(full_url(), $menu_item->getURL())) {
+ if ($menu_item->getHref()) {
+ if (elgg_http_url_is_identical(current_page_url(), $menu_item->getHref())) {
$menu_item->setSelected(true);
return $menu_item;
}
@@ -178,14 +187,17 @@ class ElggMenuBuilder {
ksort($this->menu);
switch ($sort_by) {
- case 'title':
- $sort_callback = array('ElggMenuBuilder', 'compareByTitle');
+ case 'text':
+ $sort_callback = array('ElggMenuBuilder', 'compareByText');
break;
- case 'name';
+ case 'name':
$sort_callback = array('ElggMenuBuilder', 'compareByName');
break;
- case 'order':
- // use registration order
+ case 'priority':
+ $sort_callback = array('ElggMenuBuilder', 'compareByWeight');
+ break;
+ case 'register':
+ // use registration order - usort breaks this
return;
break;
default:
@@ -199,6 +211,9 @@ class ElggMenuBuilder {
// sort each section
foreach ($this->menu as $index => $section) {
+ foreach ($section as $key => $node) {
+ $section[$key]->setData('original_order', $key);
+ }
usort($section, $sort_callback);
$this->menu[$index] = $section;
@@ -208,42 +223,69 @@ class ElggMenuBuilder {
array_push($stack, $root);
while (!empty($stack)) {
$node = array_pop($stack);
+ /* @var ElggMenuItem $node */
$node->sortChildren($sort_callback);
$children = $node->getChildren();
if ($children) {
$stack = array_merge($stack, $children);
}
- $p = count($stack);
}
}
}
}
/**
- * Compare two menu items by their titles
+ * Compare two menu items by their display text
*
- * @param ElggMenuItem $a
- * @param ElggMenuItem $b
+ * @param ElggMenuItem $a Menu item
+ * @param ElggMenuItem $b Menu item
* @return bool
*/
- public static function compareByTitle($a, $b) {
- $a = $a->getTitle();
- $b = $b->getTitle();
+ public static function compareByText($a, $b) {
+ $at = $a->getText();
+ $bt = $b->getText();
- return strnatcmp($a, $b);
+ $result = strnatcmp($at, $bt);
+ if ($result === 0) {
+ return $a->getData('original_order') - $b->getData('original_order');
+ }
+ return $result;
}
/**
* Compare two menu items by their identifiers
*
- * @param ElggMenuItem $a
- * @param ElggMenuItem $b
+ * @param ElggMenuItem $a Menu item
+ * @param ElggMenuItem $b Menu item
* @return bool
*/
public static function compareByName($a, $b) {
- $a = $a->getName();
- $b = $b->getName();
+ $an = $a->getName();
+ $bn = $b->getName();
+
+ $result = strcmp($an, $bn);
+ if ($result === 0) {
+ return $a->getData('original_order') - $b->getData('original_order');
+ }
+ return $result;
+ }
- return strcmp($a, $b);
+ /**
+ * Compare two menu items by their priority
+ *
+ * @param ElggMenuItem $a Menu item
+ * @param ElggMenuItem $b Menu item
+ * @return bool
+ *
+ * @todo change name to compareByPriority
+ */
+ public static function compareByWeight($a, $b) {
+ $aw = $a->getWeight();
+ $bw = $b->getWeight();
+
+ if ($aw == $bw) {
+ return $a->getData('original_order') - $b->getData('original_order');
+ }
+ return $aw - $bw;
}
}