Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

engine/classes/Elgg/Menu/Service.php (1 issue)

1
<?php
2
namespace Elgg\Menu;
3
4
use Elgg\PluginHooksService;
5
use Elgg\Config;
6
use ElggMenuBuilder;
7
use ElggMenuItem;
8
9
/**
10
 * Methods to construct and prepare menus for rendering
11
 */
12
class Service {
13
14
	/**
15
	 * @var PluginHooksService
16
	 */
17
	private $hooks;
18
19
	/**
20
	 * @var Config
21
	 */
22
	private $config;
23
24
	/**
25
	 * Constructor
26
	 *
27
	 * @param PluginHooksService $hooks  Plugin hooks
28
	 * @param Config             $config Elgg config
29
	 * @access private
30
	 * @internal Do not use. Use `elgg()->menus`.
31
	 */
32 3
	public function __construct(PluginHooksService $hooks, Config $config) {
33 3
		$this->hooks = $hooks;
34 3
		$this->config = $config;
35 3
	}
36
37
	/**
38
	 * Build a full menu, pulling items from configuration and the "register" menu hooks.
39
	 *
40
	 * Parameters are filtered by the "parameters" hook.
41
	 *
42
	 * @param string $name   Menu name
43
	 * @param array  $params Hook/view parameters
44
	 *
45
	 * @return Menu
46
	 */
47 33
	public function getMenu($name, array $params = []) {
48 33
		return $this->prepareMenu($this->getUnpreparedMenu($name, $params));
49
	}
50
51
	/**
52
	 * Build an unprepared menu.
53
	 *
54
	 * @param string $name   Menu name
55
	 * @param array  $params Hook/view parameters
56
	 *
57
	 * @return UnpreparedMenu
58
	 */
59 33
	public function getUnpreparedMenu($name, array $params = []) {
60 33
		$menus = $this->config->menus;
61
62 33
		$items = $this->prepareMenuItems(elgg_extract('items', $params, []));
63 33
		unset($params['items']);
64
		
65 33
		if ($menus && isset($menus[$name])) {
0 ignored issues
show
Bug Best Practice introduced by Steve Clay
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...
66 12
			$registered_items = elgg_extract($name, $menus, []);
67 12
			$items = array_merge($items, $registered_items);
68
		}
69
70 33
		$params['name'] = $name;
71
72 33
		$params = $this->hooks->trigger('parameters', "menu:$name", $params, $params);
73
74 33
		if (!isset($params['sort_by'])) {
75 17
			$params['sort_by'] = 'text';
76
		}
77
78 33
		$items = $this->hooks->trigger('register', "menu:$name", $params, $items);
79
80 33
		return new UnpreparedMenu($params, $items);
81
	}
82
83
	/**
84
	 * Split a menu into sections, and pass it through the "prepare" hook
85
	 *
86
	 * @param UnpreparedMenu $menu Menu
87
	 *
88
	 * @return Menu
89
	 */
90 33
	public function prepareMenu(UnpreparedMenu $menu) {
91 33
		$name = $menu->getName();
92 33
		$params = $menu->getParams();
93 33
		$sort_by = $menu->getSortBy();
94
95 33
		$builder = new ElggMenuBuilder($menu->getItems());
96 33
		$params['menu'] = $builder->getMenu($sort_by);
97 33
		$params['selected_item'] = $builder->getSelected();
98
99 33
		$params['menu'] = $this->hooks->trigger('prepare', "menu:$name", $params, $params['menu']);
100
101 33
		return new Menu($params);
102
	}
103
104
	/**
105
	 * Combine several menus into one
106
	 *
107
	 * Unprepared menus will be built separately, then combined, with items reassigned to sections
108
	 * named after their origin menu. The returned menu must be prepared before display.
109
	 *
110
	 * @param string[] $names    Menu names
111
	 * @param array    $params   Menu params
112
	 * @param string   $new_name Combined menu name (used for the prepare hook)
113
	 *
114
	 * @return UnpreparedMenu
115
	 */
116
	function combineMenus(array $names = [], array $params = [], $new_name = '') {
117
		if (!$new_name) {
118
			$new_name = implode('__', $names);
119
		}
120
121
		$all_items = [];
122
		foreach ($names as $name) {
123
			$items = $this->getUnpreparedMenu($name, $params)->getItems();
124
125
			foreach ($items as $item) {
126
				$section = $item->getSection();
127
				if ($section == 'default') {
128
					$item->setSection($name);
129
				}
130
				$item->setData('menu_name', $name);
131
				$all_items[] = $item;
132
			}
133
		}
134
135
		$params['name'] = $new_name;
136
137
		return new UnpreparedMenu($params, $all_items);
138
	}
139
140
	/**
141
	 * Prepare menu items
142
	 *
143
	 * @param array $items An array of ElggMenuItem instances or menu item factory options
144
	 * @return ElggMenuItem[]
145
	 */
146 33
	public function prepareMenuItems(array $items = []) {
147 33
		$prepared_items = [];
148
		
149 33
		foreach ($items as $item) {
150 2
			if (is_array($item)) {
151 2
				$options = $item;
152 2
				$item = ElggMenuItem::factory($options);
153
			}
154
155 2
			if (!$item instanceof ElggMenuItem) {
156
				continue;
157
			}
158
			
159 2
			$prepared_items[] = $item;
160
		}
161
162 33
		return $prepared_items;
163
	}
164
}
165