Completed
Push — master ( 76d231...c2873c )
by Jeroen
18:44 queued 09:27
created

navigation.php ➔ elgg_get_menu_item()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 10
nc 5
nop 2
dl 0
loc 19
ccs 0
cts 4
cp 0
crap 30
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * Elgg navigation library
4
 * Functions for managing menus and other navigational elements
5
 *
6
 * Breadcrumbs
7
 * Elgg uses a breadcrumb stack. The page handlers (controllers in MVC terms)
8
 * push the breadcrumb links onto the stack. @see elgg_push_breadcrumb()
9
 *
10
 *
11
 * Pagination
12
 * Automatically handled by Elgg when using elgg_list_entities* functions.
13
 * @see elgg_list_entities()
14
 *
15
 *
16
 * Tabs
17
 * @see navigation/tabs view
18
 *
19
 *
20
 * Menus
21
 * Elgg uses a single interface to manage its menus. Menu items are added with
22
 * {@link elgg_register_menu_item()}. This is generally used for menus that
23
 * appear only once per page. For dynamic menus (such as the hover
24
 * menu for user's avatar), a plugin hook is emitted when the menu is being
25
 * created. The hook is 'register', 'menu:<menu_name>'. For more details on this,
26
 * @see elgg_view_menu().
27
 *
28
 * Menus supported by the Elgg core
29
 * Standard menus:
30
 *     site   Site navigation shown on every page.
31
 *     page   Page menu usually shown in a sidebar. Uses Elgg's context.
32
 *     topbar Topbar menu shown on every page. The default has two sections.
33
 *     footer Like the topbar but in the footer.
34
 *
35
 * Dynamic menus (also called just-in-time menus):
36
 *     user_hover  Avatar hover menu. The user entity is passed as a parameter.
37
 *     entity      The set of links shown in the summary of an entity.
38
 *     river       Links shown on river items.
39
 *     owner_block Links shown for a user or group in their owner block.
40
 *     filter      The tab filter for content (all, mine, friends)
41
 *     title       The buttons shown next to a content title.
42
 *     longtext    The links shown above the input/longtext view.
43
 *     login       Menu of links at bottom of login box
44
 *
45
 * @package    Elgg.Core
46
 * @subpackage Navigation
47
 */
48
49
/**
50
 * Register an item for an Elgg menu
51
 *
52
 * @warning Generally you should not use this in response to the plugin hook:
53
 * 'register', 'menu:<menu_name>'. If you do, you may end up with many incorrect
54
 * links on a dynamic menu.
55
 *
56
 * @warning A menu item's name must be unique per menu. If more than one menu
57
 * item with the same name are registered, the last menu item takes priority.
58
 *
59
 * @see elgg_view_menu() for the plugin hooks available for modifying a menu as
60
 * it is being rendered.
61
 *
62
 * @see ElggMenuItem::factory() is used to turn an array value of $menu_item into an
63
 * ElggMenuItem object.
64
 *
65
 * @param string $menu_name The name of the menu: site, page, userhover,
66
 *                          userprofile, groupprofile, or any custom menu
67
 * @param mixed  $menu_item A \ElggMenuItem object or an array of options in format:
68
 *                          name        => STR  Menu item identifier (required)
69
 *                          text        => STR  Menu item display text as HTML (required)
70
 *                          href        => STR  Menu item URL (required)
71
 *                                              false = do not create a link.
72
 *                                              null = current URL.
73
 *                                              "" = current URL.
74
 *                                              "/" = site home page.
75
 *                                              @warning If href is false, the <a> tag will
76
 *                                              not appear, so the link_class will not apply. If you
77
 *                                              put <a> tags in manually through the 'text' option
78
 *                                              the default CSS selector .elgg-menu-$menu > li > a
79
 *                                              may affect formatting. Wrap in a <span> if it does.)
80
 *                          contexts    => ARR  Page context strings
81
 *                          section     => STR  Menu section identifier
82
 *                          title       => STR  Menu item tooltip
83
 *                          selected    => BOOL Is this menu item currently selected
84
 *                          parent_name => STR  Identifier of the parent menu item
85
 *                          link_class  => STR  A class or classes for the <a> tag
86
 *                          item_class  => STR  A class or classes for the <li> tag
87
 *                          deps     => STR  One or more AMD modules to require
88
 *
89
 *                          Additional options that the view output/url takes can be
90
 *							passed in the array. Custom options can be added by using
91
 *							the 'data' key with the	value being an associative array.
92
 *
93
 * @return bool False if the item could not be added
94
 * @since 1.8.0
95
 */
96
function elgg_register_menu_item($menu_name, $menu_item) {
97 1
	if (is_array($menu_item)) {
98 1
		$options = $menu_item;
99 1
		$menu_item = \ElggMenuItem::factory($options);
100 1
		if (!$menu_item) {
101 1
			$menu_item_name = elgg_extract('name', $options, 'MISSING NAME');
102 1
			elgg_log("Unable to add menu item '{$menu_item_name}' to '$menu_name' menu", 'WARNING');
103 1
			return false;
104
		}
105
	}
106
107 1
	if (!$menu_item instanceof ElggMenuItem) {
108 1
		elgg_log('Second argument of elgg_register_menu_item() must be an instance of '
109 1
			. 'ElggMenuItem or an array of menu item factory options', 'ERROR');
110 1
		return false;
111
	}
112
113 1
	$menus = _elgg_config()->menus;
114 1
	if (!$menus) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $menus of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
115 1
		$menus = [];
116
	}
117 1
118
	$menus[$menu_name][] = $menu_item;
119
	_elgg_config()->menus = $menus;
120
121
	return true;
122
}
123
124
/**
125
 * Remove an item from a menu
126
 *
127
 * @param string $menu_name The name of the menu
128
 * @param string $item_name The unique identifier for this menu item
129
 *
130
 * @return \ElggMenuItem|null
131
 * @since 1.8.0
132
 */
133
function elgg_unregister_menu_item($menu_name, $item_name) {
134
	$menus = _elgg_config()->menus;
135
	if (!$menus) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $menus of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
136
		return null;
137
	}
138
139
	foreach ($menus[$menu_name] as $index => $menu_object) {
140
		/* @var \ElggMenuItem $menu_object */
141
		if ($menu_object instanceof ElggMenuItem && $menu_object->getName() == $item_name) {
142
			$item = $menus[$menu_name][$index];
143
			unset($menus[$menu_name][$index]);
144
			elgg_set_config('menus', $menus);
145
			return $item;
146
		}
147
	}
148
149
	return null;
150
}
151
152
/**
153
 * Check if a menu item has been registered
154
 *
155
 * @param string $menu_name The name of the menu
156
 * @param string $item_name The unique identifier for this menu item
157
 *
158
 * @return bool
159
 * @since 1.8.0
160
 */
161
function elgg_is_menu_item_registered($menu_name, $item_name) {
162
	$menus = _elgg_config()->menus;
163
	if (!$menus) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $menus of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
164
		return false;
165
	}
166
167
	if (!isset($menus[$menu_name])) {
168
		return false;
169
	}
170
171
	foreach ($menus[$menu_name] as $menu_object) {
172
		/* @var \ElggMenuItem $menu_object */
173
		if ($menu_object->getName() == $item_name) {
174
			return true;
175
		}
176
	}
177
178
	return false;
179
}
180
181
/**
182
 * Get a menu item registered for a menu
183
 *
184
 * @param string $menu_name The name of the menu
185
 * @param string $item_name The unique identifier for this menu item
186
 *
187
 * @return ElggMenuItem|null
188
 * @since 1.9.0
189
 */
190
function elgg_get_menu_item($menu_name, $item_name) {
191
	$menus = _elgg_config()->menus;
192
	if (!$menus) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $menus of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
193
		return null;
194
	}
195
196
	if (!isset($menus[$menu_name])) {
197
		return null;
198
	}
199
200
	foreach ($menus[$menu_name] as $index => $menu_object) {
201
		/* @var \ElggMenuItem $menu_object */
202
		if ($menu_object->getName() == $item_name) {
203
			return $menus[$menu_name][$index];
204
		}
205
	}
206
207
	return null;
208
}
209
210
/**
211
 * Convenience function for registering a button to the title menu
212
 *
213
 * The URL must be $handler/$name/$guid where $guid is the guid of the page owner.
214
 * The label of the button is "$handler:$name" so that must be defined in a
215
 * language file.
216
 *
217
 * This is used primarily to support adding an add content button
218
 *
219
 * @param string $handler        The handler to use or null to autodetect from context
220
 * @param string $name           Name of the button (defaults to 'add')
221
 * @param string $entity_type    Optional entity type to be added (used to verify canWriteToContainer permission)
222
 * @param string $entity_subtype Optional entity subtype to be added (used to verify canWriteToContainer permission)
223
 * @return void
224
 * @since 1.8.0
225
 */
226
function elgg_register_title_button($handler = null, $name = 'add', $entity_type = 'all', $entity_subtype = 'all') {
227
	
228
	if (!$handler) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $handler of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
229
		$handler = elgg_get_context();
230
	}
231
232
	$owner = elgg_get_page_owner_entity();
233
	if (!$owner) {
234
		// noone owns the page so this is probably an all site list page
235
		$owner = elgg_get_logged_in_user_entity();
236
	}
237
	if (!$owner || !$owner->canWriteToContainer(0, $entity_type, $entity_subtype)) {
238
		return;
239
	}
240
241
	elgg_register_menu_item('title', [
242
		'name' => $name,
243
		'href' => "$handler/$name/$owner->guid",
244
		'text' => elgg_echo("$handler:$name"),
245
		'link_class' => 'elgg-button elgg-button-action',
246
	]);
247
}
248
249
/**
250
 * Adds a breadcrumb to the breadcrumbs stack.
251
 *
252
 * See elgg_get_breadcrumbs() and the navigation/breadcrumbs view.
253 3
 *
254 3
 * @param string $title The title to display. During rendering this is HTML encoded.
255 3
 * @param string $link  Optional. The link for the title. During rendering links are
256 3
 *                      normalized via elgg_normalize_url().
257
 *
258
 * @return void
259
 * @since 1.8.0
260
 * @see elgg_get_breadcrumbs
261
 */
262
function elgg_push_breadcrumb($title, $link = null) {
263
	$breadcrumbs = (array) _elgg_config()->breadcrumbs;
264
	$breadcrumbs[] = ['title' => $title, 'link' => $link];
265 1
	elgg_set_config('breadcrumbs', $breadcrumbs);
266
}
267 1
268
/**
269
 * Removes last breadcrumb entry.
270
 *
271 1
 * @return array popped breadcrumb array or empty array
272 1
 * @since 1.8.0
273
 */
274 1
function elgg_pop_breadcrumb() {
275
	$breadcrumbs = (array) _elgg_config()->breadcrumbs;
276
277
	if (empty($breadcrumbs)) {
278
		return [];
279
	}
280
281
	$popped = array_pop($breadcrumbs);
282
	elgg_set_config('breadcrumbs', $breadcrumbs);
283
284
	return $popped;
285
}
286
287
/**
288
 * Returns all breadcrumbs as an array
289
 * <code>
290
 * [
291
 *    [
292
 *       'title' => 'Breadcrumb title',
293
 *       'link' => '/path/to/page',
294
 *    ]
295
 * ]
296
 * </code>
297
 *
298 3
 * Breadcrumbs are filtered through the plugin hook [prepare, breadcrumbs] before
299
 * being returned.
300 3
 *
301
 * @param array $breadcrumbs An array of breadcrumbs
302
 *                           If set, will override breadcrumbs in the stack
303 3
 * @return array
304
 * @since 1.8.0
305
 * @see elgg_prepare_breadcrumbs
306
 */
307
function elgg_get_breadcrumbs(array $breadcrumbs = null) {
308
	if (!isset($breadcrumbs)) {
309 3
		// if no crumbs set, still allow hook to populate it
310
		$breadcrumbs = (array) _elgg_config()->breadcrumbs;
311
	}
312 3
313 3
	if (!is_array($breadcrumbs)) {
314 3
		_elgg_services()->logger->error(__FUNCTION__ . ' expects breadcrumbs as an array');
315
		$breadcrumbs = [];
316 3
	}
317 3
	
318
	$params = [
319
		'breadcrumbs' => $breadcrumbs,
320
	];
321
322 3
	$params['identifier'] = _elgg_services()->request->getFirstUrlSegment();
323
	$params['segments'] = _elgg_services()->request->getUrlSegments();
324
	array_shift($params['segments']);
325
326
	$breadcrumbs = elgg_trigger_plugin_hook('prepare', 'breadcrumbs', $params, $breadcrumbs);
327
	if (!is_array($breadcrumbs)) {
328
		_elgg_services()->logger->error('"prepare, breadcrumbs" hook must return an array of breadcrumbs');
329
		return [];
330
	}
331
332
	return $breadcrumbs;
333
}
334
335
/**
336
 * Prepare breadcrumbs before display. This turns titles into 100-character excerpts, and also
337
 * removes the last crumb if it's not a link.
338
 *
339
 * @param string $hook        "prepare"
340
 * @param string $type        "breadcrumbs"
341
 * @param array  $breadcrumbs Breadcrumbs to be altered
342
 * @param array  $params      Hook parameters
343
 *
344
 * @return array
345
 * @since 1.11
346
 */
347
function elgg_prepare_breadcrumbs($hook, $type, $breadcrumbs, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $params is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
348
	// remove last crumb if not a link
349
	$last_crumb = end($breadcrumbs);
350
	if (empty($last_crumb['link'])) {
351
		array_pop($breadcrumbs);
352
	}
353
354
	// apply excerpt to titles
355
	foreach (array_keys($breadcrumbs) as $i) {
356
		$breadcrumbs[$i]['title'] = elgg_get_excerpt($breadcrumbs[$i]['title'], 100);
357
	}
358
	return $breadcrumbs;
359
}
360
361
/**
362
 * Returns default filter tabs (All, Mine, Friends) for the user
363
 *
364
 * @param string   $context  Context to be used to prefix tab URLs
365
 * @param string   $selected Name of the selected tab
366
 * @param ElggUser $user     User who owns the layout (defaults to logged in user)
367
 * @param array    $vars     Additional vars
368
 * @return ElggMenuItem[]
369
 * @since 2.3
370
 */
371
function elgg_get_filter_tabs($context = null, $selected = null, ElggUser $user = null, array $vars = []) {
372
373
	if (!isset($selected)) {
374
		$selected = 'all';
375
	}
376
377
	if (!$user) {
378
		$user = elgg_get_logged_in_user_entity();
379
	}
380
381
	$items = [];
382
	if ($user) {
383
		$items[] = ElggMenuItem::factory([
384
			'name' => 'all',
385
			'text' => elgg_echo('all'),
386
			'href' => (isset($vars['all_link'])) ? $vars['all_link'] : "$context/all",
387
			'selected' => ($selected == 'all'),
388
			'priority' => 200,
389
		]);
390
		$items[] = ElggMenuItem::factory([
391
			'name' => 'mine',
392
			'text' => elgg_echo('mine'),
393
			'href' => (isset($vars['mine_link'])) ? $vars['mine_link'] : "$context/owner/{$user->username}",
394
			'selected' => ($selected == 'mine'),
395
			'priority' => 300,
396
		]);
397
	}
398
399
	$params = [
400
		'selected' => $selected,
401
		'user' => $user,
402
		'vars' => $vars,
403
	];
404
	$items = _elgg_services()->hooks->trigger('filter_tabs', $context, $params, $items);
405
406
	return $items;
407
}
408
409
/**
410
 * Set up the site menu
411
 *
412
 * Handles default, featured, and custom menu items
413
 *
414
 * @access private
415
 */
416
function _elgg_site_menu_setup($hook, $type, $return, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $params is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
417
418
	$featured_menu_names = _elgg_config()->site_featured_menu_names;
419
	$custom_menu_items = _elgg_config()->site_custom_menu_items;
420
	if ($featured_menu_names || $custom_menu_items) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $featured_menu_names of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
Bug Best Practice introduced by
The expression $custom_menu_items of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
421
		// we have featured or custom menu items
422
423
		$registered = isset($return['default']) ? $return['default'] : [];
424
		/* @var \ElggMenuItem[] $registered */
425
426
		// set up featured menu items
427
		$featured = [];
428
		foreach ($featured_menu_names as $name) {
429
			foreach ($registered as $index => $item) {
430
				if ($item->getName() == $name) {
431
					$featured[] = $item;
432
					unset($registered[$index]);
433
				}
434
			}
435
		}
436
437
		// add custom menu items
438
		$n = 1;
439
		foreach ($custom_menu_items as $title => $url) {
440
			$item = new \ElggMenuItem("custom$n", $title, $url);
441
			$featured[] = $item;
442
			$n++;
443
		}
444
445
		$return['default'] = $featured;
446
		if (count($registered) > 0) {
447
			$return['more'] = $registered;
448
		}
449
	} else {
450
		// no featured menu items set
451
		$max_display_items = 5;
452
453
		// the first n are shown, rest added to more list
454
		// if only one item on more menu, stick it with the rest
455
		$num_menu_items = count($return['default']);
456
		if ($num_menu_items > ($max_display_items + 1)) {
457
			$return['more'] = array_splice($return['default'], $max_display_items);
458
		}
459
	}
460
	
461
	// check if we have anything selected
462
	$selected = false;
463
	foreach ($return as $section) {
464
		/* @var \ElggMenuItem[] $section */
465
466
		foreach ($section as $item) {
467
			if ($item->getSelected()) {
468
				$selected = true;
469
				break 2;
470
			}
471
		}
472
	}
473
	
474
	if (!$selected) {
475
		// nothing selected, match name to context or match url
476
		$current_url = current_page_url();
477
		foreach ($return as $section_name => $section) {
478
			foreach ($section as $key => $item) {
479
				// only highlight internal links
480
				if (strpos($item->getHref(), elgg_get_site_url()) === 0) {
481
					if ($item->getName() == elgg_get_context()) {
482
						$return[$section_name][$key]->setSelected(true);
483
						break 2;
484
					}
485
					if ($item->getHref() == $current_url) {
486
						$return[$section_name][$key]->setSelected(true);
487
						break 2;
488
					}
489
				}
490
			}
491
		}
492
	}
493
494
	return $return;
495
}
496
497
/**
498
 * Prepare page menu
499
 * Sets the display child menu option to "toggle" if not set
500
 * Recursively marks parents of the selected item as selected (expanded)
501
 *
502
 * @param \Elgg\Hook $hook
503
 * @access private
504
 */
505
function _elgg_page_menu_setup(\Elgg\Hook $hook) {
506
	$menu = $hook->getValue();
507
508
	foreach ($menu as $section => $menu_items) {
509
		foreach ($menu_items as $menu_item) {
510
			if ($menu_item instanceof ElggMenuItem) {
511
				$child_menu_vars = $menu_item->getChildMenuOptions();
512
				if (empty($child_menu_vars['display'])) {
513
					$child_menu_vars['display'] = 'toggle';
514
				}
515
				$menu_item->setChildMenuOptions($child_menu_vars);
516
			}
517
		}
518
	}
519
520
	$selected_item = $hook->getParam('selected_item');
521
	if ($selected_item instanceof \ElggMenuItem) {
522
		$parent = $selected_item->getParent();
523
		while ($parent instanceof \ElggMenuItem) {
524
			$parent->setSelected();
525
			$parent = $parent->getParent();
526
		}
527
	}
528
529
	return $menu;
530
}
531
532
/**
533
 * Add the comment and like links to river actions menu
534
 * @access private
535
 */
536
function _elgg_river_menu_setup($hook, $type, $return, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
537
	if (elgg_is_logged_in()) {
538
		$item = $params['item'];
539
		/* @var \ElggRiverItem $item */
540
		$object = $item->getObjectEntity();
541
		// add comment link but annotations cannot be commented on
542
		if ($item->annotation_id == 0) {
543 View Code Duplication
			if ($object->canComment()) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
544
				$options = [
545
					'name' => 'comment',
546
					'href' => "#comments-add-{$object->guid}-{$item->id}",
547
					'text' => elgg_view_icon('speech-bubble'),
548
					'title' => elgg_echo('comment:this'),
549
					'rel' => 'toggle',
550
					'priority' => 50,
551
				];
552
				$return[] = \ElggMenuItem::factory($options);
553
			}
554
		}
555
		
556
		if ($item->canDelete()) {
557
			$options = [
558
				'name' => 'delete',
559
				'href' => elgg_add_action_tokens_to_url("action/river/delete?id={$item->id}"),
560
				'text' => elgg_view_icon('delete'),
561
				'title' => elgg_echo('river:delete'),
562
				'confirm' => elgg_echo('deleteconfirm'),
563
				'priority' => 200,
564
			];
565
			$return[] = \ElggMenuItem::factory($options);
566
		}
567
	}
568
569
	return $return;
570
}
571
572
/**
573
 * Entity menu is list of links and info on any entity
574
 * @access private
575
 */
576
function _elgg_entity_menu_setup($hook, $type, $return, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
577
	if (elgg_in_context('widgets')) {
578
		return $return;
579
	}
580
	
581
	$entity = $params['entity'];
582
	/* @var \ElggEntity $entity */
583
	$handler = elgg_extract('handler', $params, false);
584
	
585
	if ($entity->canEdit() && $handler) {
586
		// edit link
587
		$options = [
588
			'name' => 'edit',
589
			'text' => elgg_echo('edit'),
590
			'title' => elgg_echo('edit:this'),
591
			'href' => "$handler/edit/{$entity->getGUID()}",
592
			'priority' => 200,
593
		];
594
		$return[] = \ElggMenuItem::factory($options);
595
	}
596
597
	if ($entity->canDelete() && $handler) {
598
		// delete link
599
		if (elgg_action_exists("$handler/delete")) {
600
			$action = "action/$handler/delete";
601
		} else {
602
			$action = "action/entity/delete";
603
		}
604
		$options = [
605
			'name' => 'delete',
606
			'text' => elgg_view_icon('delete'),
607
			'title' => elgg_echo('delete:this'),
608
			'href' => "$action?guid={$entity->getGUID()}",
609
			'confirm' => elgg_echo('deleteconfirm'),
610
			'priority' => 300,
611
		];
612
		$return[] = \ElggMenuItem::factory($options);
613
	}
614
615
	return $return;
616
}
617
618
/**
619
 * Entity navigation menu is previous/next link for an entity
620
 *
621
 * @param \Elgg\Hook hook
622
 *
623
 * @access private
624
 */
625
function _elgg_entity_navigation_menu_setup(\Elgg\Hook $hook) {
626
	$entity = $hook->getEntityParam();
627
	if (!$entity) {
628
		return;
629
	}
630
631
	$return = $hook->getValue();
632
633
	$options = [
634
		'type' => $entity->getType(),
635
		'subtype' => $entity->getSubtype(),
636
		'container_guid' => $entity->container_guid,
637
		'wheres' => ["e.guid != {$entity->guid}"],
638
		'limit' => 1,
639
	];
640
	
641
	$previous_options = $options;
642
	$previous_options['created_time_upper'] = $entity->time_created;
643
	$previous_options['order_by'] = 'e.time_created DESC, e.guid DESC';
644
	
645
	$previous = elgg_get_entities($previous_options);
646 View Code Duplication
	if ($previous) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
647
		$previous = $previous[0];
648
		$return[] = \ElggMenuItem::factory([
649
			'name' => 'previous',
650
			'text' => elgg_echo('previous'),
651
			'href' => $previous->getUrl(),
652
			'title' => $previous->getDisplayName(),
653
		]);
654
	}
655
	
656
	$next_options = $options;
657
	$next_options['created_time_lower'] = $entity->time_created;
658
	$next_options['order_by'] = 'e.time_created ASC, e.guid ASC';
659
	
660
	$next = elgg_get_entities($next_options);
661 View Code Duplication
	if ($next) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
662
		$next = $next[0];
663
		$return[] = \ElggMenuItem::factory([
664
			'name' => 'next',
665
			'text' => elgg_echo('next'),
666
			'href' => $next->getUrl(),
667
			'title' => $next->getDisplayName(),
668
		]);
669
	}
670
	
671
	return $return;
672
}
673
674
/**
675
 * Widget menu is a set of widget controls
676
 * @access private
677
 */
678
function _elgg_widget_menu_setup($hook, $type, $return, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
679
680
	$widget = elgg_extract('entity', $params);
681
	if (!($widget instanceof \ElggWidget)) {
682
		return;
683
	}
684
	
685
	if ($widget->canDelete()) {
686
		$return[] = \ElggMenuItem::factory([
687
			'name' => 'delete',
688
			'text' => elgg_view_icon('delete-alt'),
689
			'title' => elgg_echo('widget:delete', [$widget->getTitle()]),
690
			'href' => "action/widgets/delete?widget_guid=$widget->guid",
691
			'is_action' => true,
692
			'link_class' => 'elgg-widget-delete-button',
693
			'id' => "elgg-widget-delete-button-$widget->guid",
694
			'data-elgg-widget-type' => $widget->handler,
695
			'priority' => 900,
696
		]);
697
	}
698
	
699
	$show_edit = elgg_extract('show_edit', $params, $widget->canEdit());
700 View Code Duplication
	if ($show_edit) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
701
		$return[] = \ElggMenuItem::factory([
702
			'name' => 'settings',
703
			'text' => elgg_view_icon('settings-alt'),
704
			'title' => elgg_echo('widget:edit'),
705
			'href' => "#widget-edit-$widget->guid",
706
			'link_class' => "elgg-widget-edit-button",
707
			'rel' => 'toggle',
708
			'priority' => 800,
709
		]);
710
	}
711
712
	return $return;
713
}
714
715
/**
716
 * Add the register and forgot password links to login menu
717
 * @access private
718
 */
719
function _elgg_login_menu_setup($hook, $type, $return, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $params is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
720
721
	if (_elgg_config()->allow_registration) {
722
		$return[] = \ElggMenuItem::factory([
723
			'name' => 'register',
724
			'href' => elgg_get_registration_url(),
725
			'text' => elgg_echo('register'),
726
			'link_class' => 'registration_link',
727
		]);
728
	}
729
730
	$return[] = \ElggMenuItem::factory([
731
		'name' => 'forgotpassword',
732
		'href' => 'forgotpassword',
733
		'text' => elgg_echo('user:password:lost'),
734
		'link_class' => 'forgot_link',
735
	]);
736
737
	return $return;
738
}
739
740
/**
741
 * Add the RSS link to the menu
742
 * @access private
743
 */
744
function _elgg_rss_menu_setup($hook, $type, $return, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $params is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
745
746
	if (!elgg_is_logged_in()) {
747
		return;
748
	}
749
	
750
	if (!_elgg_has_rss_link()) {
751
		return;
752
	}
753
754
	$url = current_page_url();
755
	$return[] = ElggMenuItem::factory([
756
		'name' => 'rss',
757
		'text' => elgg_echo('feed:rss'),
758
		'icon' => 'rss',
759
		'href' => elgg_http_add_url_query_elements($url, [
760
			'view' => 'rss',
761
		]),
762
		'title' => elgg_echo('feed:rss:title'),
763
	]);
764
765
	return $return;
766
}
767
768
/**
769
 * Navigation initialization
770
 * @access private
771
 */
772
function _elgg_nav_init() {
773
	elgg_register_plugin_hook_handler('prepare', 'breadcrumbs', 'elgg_prepare_breadcrumbs');
774
775
	elgg_register_plugin_hook_handler('prepare', 'menu:site', '_elgg_site_menu_setup');
776
	elgg_register_plugin_hook_handler('prepare', 'menu:page', '_elgg_page_menu_setup', 999);
777
778
	elgg_register_plugin_hook_handler('register', 'menu:river', '_elgg_river_menu_setup');
779
	elgg_register_plugin_hook_handler('register', 'menu:entity', '_elgg_entity_menu_setup');
780
	elgg_register_plugin_hook_handler('register', 'menu:widget', '_elgg_widget_menu_setup');
781
	elgg_register_plugin_hook_handler('register', 'menu:login', '_elgg_login_menu_setup');
782
	elgg_register_plugin_hook_handler('register', 'menu:footer', '_elgg_rss_menu_setup');
783
	elgg_register_plugin_hook_handler('register', 'menu:entity_navigation', '_elgg_entity_navigation_menu_setup');
784
785
	elgg_register_plugin_hook_handler('public_pages', 'walled_garden', '_elgg_nav_public_pages');
786
787
	elgg_register_menu_item('footer', \ElggMenuItem::factory([
788
		'name' => 'powered',
789
		'text' => elgg_echo("elgg:powered"),
790
		'href' => 'http://elgg.org',
791
		'title' => 'Elgg ' . elgg_get_version(true),
792
		'section' => 'meta',
793
		'priority' => 600,
794
	]));
795
796
	elgg_register_ajax_view('navigation/menu/user_hover/contents');
797
798
	// Using a view extension to ensure that themes that have replaced the item view
799
	// still load the required AMD modules
800
	elgg_extend_view('navigation/menu/elements/item', 'navigation/menu/elements/item_deps');
801
}
802
803
/**
804
 * Extend public pages
805
 *
806
 * @param string   $hook_name    "public_pages"
807
 * @param string   $entity_type  "walled_garden"
808
 * @param string[] $return_value Paths accessible outside the "walled garden"
809
 * @param mixed    $params       unused
810
 *
811
 * @return string[]
812
 * @access private
813
 * @since 1.11.0
814
 */
815
function _elgg_nav_public_pages($hook_name, $entity_type, $return_value, $params) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook_name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $entity_type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $params is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
816
	if (is_array($return_value)) {
817
		$return_value[] = 'navigation/menu/user_hover/contents';
818
	}
819
820
	return $return_value;
821
}
822
823
return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
0 ignored issues
show
Unused Code introduced by
The parameter $hooks is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
824
	$events->registerHandler('init', 'system', '_elgg_nav_init');
825
};
826