Test Failed
Push — master ( 0f4ab2...23ed4b )
by Justin
30:36 queued 26:53
created

Menu::getMenuByParent()   D

Complexity

Conditions 17
Paths 138

Size

Total Lines 80
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 2 Features 5
Metric Value
c 8
b 2
f 5
dl 0
loc 80
rs 4.7009
cc 17
eloc 48
nc 138
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Copyright (c) 2018 Justin Kuenzel (jukusoft.com)
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
20
/**
21
 * Project: JuKuCMS
22
 * License: Apache 2.0 license
23
 * User: Justin
24
 * Date: 10.03.2018
25
 * Time: 20:52
26
 */
27
28
class Menu {
29
30
	//menu ID (table menu_names)
31
	protected $menuID = -1;
32
33
	//name of template
34
	protected $template = "";
35
36
	//menu structure
37
	protected static $menuID_array = array();
38
39
	protected $menus = array();
40
41
	public function __construct (int $menuID = -1, string $template = "menu") {
42
		$this->menuID = (int) $menuID;
43
		$this->template = $template;
44
	}
45
46
	public function loadMenu (int $menuID = -1) {
47
		if ($menuID == -1) {
48
			$menuID = $this->menuID;
49
		}
50
51
		if ($menuID == -1) {
52
			//we dont need to load anything, because no menu is selected
53
			$this->menus = array();
54
		}
55
56
		Events::throwEvent("before_load_menu", array(
57
			'menuID' => &$menuID,
58
			'instance' => &$this
59
		));
60
61
		//load menuID if absent
62
		self::loadMenuID($menuID);
63
64
		if (Cache::contains("menus", "menu_" . $menuID)) {
65
			$this->menus = Cache::get("menus", "menu_" . $menuID);
66
		} else {
67
			$menu_cache = self::$menuID_array[$menuID];
68
69
			//get menu by parent -y, this means root menu
70
			$this->menus = $this->getMenuByParent($menu_cache, -1);
71
72
			Events::throwEvent("after_load_menu", array(
73
				'menuID' => &$menuID,
74
				'instance' => &$this,
75
				'menus' => &$this->menus,
76
				'menu_cache' => $menu_cache
77
			));
78
79
			Cache::put("menus", "menu_" . $menuID, $this->menus);
80
		}
81
82
		$this->menuID = $menuID;
83
	}
84
85
	protected function getMenuByParent (array &$menu_array, int $parentID) : array {
86
		if (!isset($menu_array[$parentID])) {
87
			//menu doesnt have submenus
88
			return array();
89
		}
90
91
		$array = array();
92
93
		foreach ($menu_array[$parentID] as $row) {
94
			//check login_required
95
			if ($row['login_required'] == 1 && !User::current()->isLoggedIn()) {
96
				//dont show this menu
97
				continue;
98
			}
99
100
			//check permissions
101
			$permissions = explode("|", $row['permissions']);
102
			$has_permission = false;
103
104
			foreach ($permissions as $permission) {
105
				if (PermissionChecker::current()->hasRight($permission)) {
106
					$has_permission = true;
107
					break;
108
				}
109
			}
110
111
			if (!$has_permission) {
112
				//dont show this menu, because user doesnt have permission for this menu
113
				continue;
114
			}
115
116
			$entry = array();
117
118
			$href = "";
119
			$entry['append'] = "";
120
			$entry['title'] = $row['title'];
121
			$entry['text'] = $row['title'];
122
			$entry['icon'] = $row['icon'];
123
			$entry['icon_class'] = " " . $row['icon'];
124
			$entry['permissions'] = explode("|", $row['permissions']);
125
			$entry['append'] = "";
126
			$entry['extension_code'] = "";
127
128
			if (strpos($row['url'], "LOGIN_URL") !== FALSE) {
129
				$row['url'] = Registry::singleton()->getSetting("login_url");
130
			}
131
132
			if (strpos($row['url'], "LOGOUT_URL") !== FALSE) {
133
				$row['url'] = Registry::singleton()->getSetting("logout_url");
134
			}
135
136
			if ($row['type'] == "page") {
137
				$href = DomainUtils::generateURL($row['url']);
138
			} else if ($row['type'] == "link") {
139
				$href = DomainUtils::generateURL($row['url']);
140
			} else if ($row['type'] == "external_link") {
141
				$href = $row['url'];
142
			} else if ($row['type'] == "js_link") {
143
				$href = "#";
144
				$entry['append'] = " onclick=\"" . $row['url'] . "\"";
145
			} else if ($row['type'] == "no_link") {
146
				$href = "#";
147
			} else {
148
				throw new IllegalStateException("Unknown menu type: " . $row['type']);
149
			}
150
151
			$entry['href'] = $href;
152
153
			if (!empty($row['icon']) && $row['icon'] != "none") {
154
				$entry['text'] = "<img src=\"" . $row['icon'] . "\" alt=\"" . $row['title'] . "\" title=\"" . $row['title'] . "\" style=\"max-width:32px; max-height:32px; \" /> " . $row['title'];
155
			}
156
157
			//get submenus
158
			$entry['submenus'] = $this->getMenuByParent($menu_array, $row['id']);
159
			$entry['has_submenus'] = sizeof($entry['submenus']) > 0;
160
161
			$array[] = $entry;
162
		}
163
164
		return $array;
165
	}
166
167
	/**
168
	 * get HTML code of menu
169
	 */
170
	public function getCode () : string {
171
		$template = new DwooTemplate($this->template);
172
173
		$template->assign("menu_array", $this->menus);
174
175
		/*$template = new Template($this->template);
176
177
		$this->parseMenu($this->menus, $template);
178
179
		//parse main block
180
		$template->parse("main");*/
181
182
		$html = $template->getCode();
183
184
		Events::throwEvent("get_menu_code", array(
185
			'menuID' => $this->menuID,
186
			'menus' => &$this->menus,
187
			'html' => &$html
188
		));
189
190
		return $html;
191
	}
192
193
	/*protected function parseMenu (array $menu_array, Template &$template) {
194
		//TODO: check permissions & login required
195
196
		foreach ($menu_array as $menu) {
197
			//check, if menu has sub menus
198
			if (sizeof($menu['submenus']) > 0) {
199
				//TODO: add code here
200
201
				foreach ($menu as $key=>$value) {
202
					$template->assign(strtoupper($key), $value);
203
				}
204
205
				$template->parse("main.treeview");
206
			} else {
207
				//menu doesnt have sub menus
208
209
				foreach ($menu as $key=>$value) {
210
					$template->assign(strtoupper($key), $value);
211
				}
212
213
				$template->parse("main.menu");
214
			}
215
		}
216
	}*/
217
218
	protected static function loadMenuID (int $menuID) {
219
		if (isset(self::$menuID_array[$menuID])) {
220
			return;
221
		}
222
223
		if (Cache::contains("menus", "menuID_" . $menuID)) {
224
			self::$menuID_array[$menuID] = Cache::get("menus", "menuID_" . $menuID);
225
		} else {
226
			$rows = Database::getInstance()->listRows("SELECT * FROM `{praefix}menu` WHERE `menuID` = :menuID AND `activated` = '1' ORDER BY `order`; ", array('menuID' => array(
227
				'type' => PDO::PARAM_INT,
228
				'value' => $menuID
229
			)));
230
231
			$array = array();
232
233
			foreach ($rows as $row) {
234
				$parentID = $row['parent'];
235
236
				if (!isset($array[$parentID])) {
237
					$array[$parentID] = array();
238
				}
239
240
				$array[$parentID][] = $row;
241
			}
242
243
			self::$menuID_array[$menuID] = $array;
244
245
			Cache::put("menus", "menuID_" . $menuID, $array);
246
		}
247
248
		//var_dump(self::$menuID_array);
249
	}
250
251
	public static function createMenuName (string $title, string $unique_name = null) : int {
252
		Events::throwEvent("before_create_menu_name", array(
253
			'title' => &$title
254
		));
255
256
		if ($unique_name == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $unique_name of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
257
			$unique_name = md5(PHPUtils::randomString(100));
258
		}
259
260
		$unique_name = Validator_String::get($unique_name);
261
262
		Database::getInstance()->execute("INSERT INTO `{praefix}menu_names` (
263
			`menuID`, `title`, `unique_name`, `activated`
264
		) VALUES (
265
			NULL, :title, :name, '1'
266
		) ON DUPLICATE KEY UPDATE `title` = :title, `activated` = '1'; ", array(
267
			'title' => $title,
268
			'name' => $unique_name
269
		));
270
271
		Cache::clear("menus");
272
273
		//get menuID of inserted menu name
274
		$menuID = Database::getInstance()->lastInsertId();
275
276
		Events::throwEvent("after_created_menu_name", array(
277
			'menuID' => $menuID,
278
			'title' => &$title
279
		));
280
281
		return $menuID;
282
	}
283
284
	public static function deleteMenuName (int $menuID) {
285
		Database::getInstance()->execute("DELETE FROM `{praefix}menu_names` WHERE `menuID` = :menuID; ", array(
286
			'menuID' => array(
287
				'type' => PDO::PARAM_INT,
288
				'value' => $menuID
289
			)
290
		));
291
292
		//clear cache
293
		Cache::clear("menus", "menuID_" . $menuID);
294
	}
295
296
	public static function createMenu (int $id, int $menuID, string $title, string $url, int $parent = -1, string $unique_name = "", $type = "page", $permissions = array("all"), $login_required = false, string $icon = "none", int $order = 100, string $owner = "user") {
297
		if (!is_array($permissions)) {
298
			$permissions = array($permissions);
299
		}
300
301
		//validate values
302
		$id = Validator_Int::get($id);
303
		$menuID = Validator_Int::get($menuID);
304
		$title = Validator_String::get($title);
305
		$parent = Validator_Int::get($parent);
306
		$type = Validator_String::get($type);
307
		$login_required = (bool) $login_required;
308
309
		$permissions = implode("|", $permissions);
310
311
		if (is_null($unique_name) || empty($unique_name)) {
312
			$unique_name = md5(PHPUtils::randomString(100));
313
		}
314
315
		$insertID = Database::getInstance()->execute("INSERT INTO `{praefix}menu` (
316
			`id`, `menuID`, `title`, `url`, `type`, `icon`, `permissions`, `login_required`, `parent`, `unique_name`, `extensions`, `order`, `owner`, `activated`
317
		) VALUES (
318
			:id, :menuID, :title, :url, :url_type, :icon, :permissions, :login_required, :parent, :unique_name, :extensions, :menu_order, :owner, '1'
319
		) ON DUPLICATE KEY UPDATE `menuID` = :menuID, `permissions` = :permissions, `login_required` = :login_required, `parent` = :parent, `icon` = :icon, `activated` = '1'; ", array(
320
			'id' => $id,
321
			'menuID' => $menuID,
322
			'title' => $title,
323
			'url' => $url,
324
			'url_type' => $type,
325
			'icon' => $icon,
326
			'permissions' => $permissions,
327
			'login_required' => ($login_required ? 1 : 0),
328
			'parent' => $parent,
329
			'unique_name' => $unique_name,
330
			'extensions' => "none",
331
			'menu_order' => $order,
332
			'owner' => $owner
333
		));
334
335
		//clear cache
336
		Cache::clear("menus", "menuID_" . $menuID);
337
338
		return $insertID;
339
	}
340
341
}
342
343
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
344