1: <?php
2: 3: 4: 5: 6: 7: 8:
9: class {
10:
11: 12: 13:
14: protected = array();
15:
16: protected $selected = null;
17:
18: 19: 20: 21: 22:
23: public function __construct(array $menu) {
24: $this->menu = $menu;
25: }
26:
27: 28: 29: 30: 31: 32:
33: public function ($sort_by = 'text') {
34:
35: $this->selectFromContext();
36:
37: $this->selected = $this->findSelected();
38:
39: $this->setupSections();
40:
41: $this->setupTrees();
42:
43: $this->sort($sort_by);
44:
45: return $this->menu;
46: }
47:
48: 49: 50: 51: 52:
53: public function getSelected() {
54: return $this->selected;
55: }
56:
57: 58: 59: 60: 61:
62: protected function selectFromContext() {
63: if (!isset($this->menu)) {
64: $this->menu = array();
65: return;
66: }
67:
68:
69: $selected_menu = array();
70: foreach ($this->menu as $menu_item) {
71: if (!is_object($menu_item)) {
72: elgg_log("A non-object was passed to ElggMenuBuilder", "ERROR");
73: continue;
74: }
75: if ($menu_item->inContext()) {
76: $selected_menu[] = $menu_item;
77: }
78: }
79:
80: $this->menu = $selected_menu;
81: }
82:
83: 84: 85: 86: 87:
88: protected function setupSections() {
89: $sectioned_menu = array();
90: foreach ($this->menu as $menu_item) {
91: if (!isset($sectioned_menu[$menu_item->getSection()])) {
92: $sectioned_menu[$menu_item->getSection()] = array();
93: }
94: $sectioned_menu[$menu_item->getSection()][] = $menu_item;
95: }
96: $this->menu = $sectioned_menu;
97: }
98:
99: 100: 101: 102: 103: 104:
105: protected function setupTrees() {
106: $menu_tree = array();
107:
108: foreach ($this->menu as $key => $section) {
109: $parents = array();
110: $children = array();
111:
112: foreach ($section as $menu_item) {
113:
114: $parent_name = $menu_item->getParentName();
115: if (!$parent_name) {
116: $parents[$menu_item->getName()] = $menu_item;
117: } else {
118: $children[] = $menu_item;
119: }
120: }
121:
122:
123: $iteration = 0;
124: $current_gen = $parents;
125: $next_gen = null;
126: while (count($children) && $iteration < 5) {
127: foreach ($children as $index => $menu_item) {
128: $parent_name = $menu_item->getParentName();
129: if (array_key_exists($parent_name, $current_gen)) {
130: $next_gen[$menu_item->getName()] = $menu_item;
131: if (!in_array($menu_item, $current_gen[$parent_name]->getData('children'))) {
132: $current_gen[$parent_name]->addChild($menu_item);
133: $menu_item->setParent($current_gen[$parent_name]);
134: }
135: unset($children[$index]);
136: }
137: }
138: $current_gen = $next_gen;
139: $iteration += 1;
140: }
141:
142:
143: $parents = array_values($parents);
144:
145: $menu_tree[$key] = $parents;
146: }
147:
148: $this->menu = $menu_tree;
149: }
150:
151: 152: 153: 154: 155:
156: protected function findSelected() {
157:
158:
159: foreach ($this->menu as $menu_item) {
160: if ($menu_item->getSelected()) {
161: return $menu_item;
162: }
163: }
164:
165:
166: foreach ($this->menu as $menu_item) {
167: if ($menu_item->getHref()) {
168: if (elgg_http_url_is_identical(full_url(), $menu_item->getHref())) {
169: $menu_item->setSelected(true);
170: return $menu_item;
171: }
172: }
173: }
174:
175: return null;
176: }
177:
178: 179: 180: 181: 182: 183:
184: protected function sort($sort_by) {
185:
186:
187: ksort($this->menu);
188:
189: switch ($sort_by) {
190: case 'text':
191: $sort_callback = array('ElggMenuBuilder', 'compareByText');
192: break;
193: case 'name':
194: $sort_callback = array('ElggMenuBuilder', 'compareByName');
195: break;
196: case 'priority':
197: $sort_callback = array('ElggMenuBuilder', 'compareByWeight');
198: break;
199: case 'register':
200:
201: return;
202: break;
203: default:
204: if (is_callable($sort_by)) {
205: $sort_callback = $sort_by;
206: } else {
207: return;
208: }
209: break;
210: }
211:
212:
213: foreach ($this->menu as $index => $section) {
214: foreach ($section as $key => $node) {
215: $section[$key]->setData('original_order', $key);
216: }
217: usort($section, $sort_callback);
218: $this->menu[$index] = $section;
219:
220:
221: foreach ($section as $root) {
222: $stack = array();
223: array_push($stack, $root);
224: while (!empty($stack)) {
225: $node = array_pop($stack);
226:
227: $node->sortChildren($sort_callback);
228: $children = $node->getChildren();
229: if ($children) {
230: $stack = array_merge($stack, $children);
231: }
232: }
233: }
234: }
235: }
236:
237: 238: 239: 240: 241: 242: 243:
244: public static function compareByText($a, $b) {
245: $at = $a->getText();
246: $bt = $b->getText();
247:
248: $result = strnatcmp($at, $bt);
249: if ($result === 0) {
250: return $a->getData('original_order') - $b->getData('original_order');
251: }
252: return $result;
253: }
254:
255: 256: 257: 258: 259: 260: 261:
262: public static function compareByName($a, $b) {
263: $an = $a->getName();
264: $bn = $b->getName();
265:
266: $result = strcmp($an, $bn);
267: if ($result === 0) {
268: return $a->getData('original_order') - $b->getData('original_order');
269: }
270: return $result;
271: }
272:
273: 274: 275: 276: 277: 278: 279: 280: 281:
282: public static function compareByWeight($a, $b) {
283: $aw = $a->getWeight();
284: $bw = $b->getWeight();
285:
286: if ($aw == $bw) {
287: return $a->getData('original_order') - $b->getData('original_order');
288: }
289: return $aw - $bw;
290: }
291: }
292: