Test Failed
Push — master ( 7c671f...3d53a5 )
by Justin
04:02 queued 18s
created

Menu::getMenuByParent()   D

Complexity

Conditions 20
Paths 210

Size

Total Lines 94
Code Lines 57

Duplication

Lines 0
Ratio 0 %

Importance

Changes 12
Bugs 4 Features 7
Metric Value
c 12
b 4
f 7
dl 0
loc 94
rs 4.2873
cc 20
eloc 57
nc 210
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 . "_" . User::current()->getID())) {
65
			$this->menus = Cache::get("menus", "menu_" . $menuID . "_" . User::current()->getID());
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 . "_" . User::current()->getID(), $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
			//translate title
119
			$row['title'] = Translator::translateTitle($row['title']);
120
121
			$href = "";
122
			$entry['append'] = "";
123
			$entry['title'] = $row['title'];
124
			$entry['text'] = $row['title'];
125
			$entry['icon'] = $row['icon'];
126
			$entry['icon_class'] = " " . $row['icon'];
127
			$entry['permissions'] = explode("|", $row['permissions']);
128
			$entry['append'] = "";
129
			$entry['extension_code'] = "";
130
131
			if (strpos($row['url'], "LOGIN_URL") !== FALSE) {
132
				$row['url'] = Registry::singleton()->getSetting("login_url");
133
			}
134
135
			if (strpos($row['url'], "LOGOUT_URL") !== FALSE) {
136
				$row['url'] = Registry::singleton()->getSetting("logout_url");
137
			}
138
139
			if ($row['type'] == "page") {
140
				$href = DomainUtils::generateURL($row['url']);
141
			} else if ($row['type'] == "link") {
142
				//TODO: add base url
143
				$href = $row['url'];
144
			} else if ($row['type'] == "external_link") {
145
				$href = $row['url'];
146
			} else if ($row['type'] == "js_link") {
147
				$href = "#";
148
				$entry['append'] = " onclick=\"" . $row['url'] . "\"";
149
			} else if ($row['type'] == "no_link") {
150
				$href = "#";
151
			} else if ($row['type'] == "dynamic_link") {
152
				$href = "#";
153
154
				if (PHPUtils::startsWith($row['url'], "settings:")) {
155
					$array1 = explode(":", $row['url']);
156
					$href = Settings::get($array1[1], "#");
157
				} else if (PHPUtils::startsWith($row['url'], "registry:")) {
158
					$array1 = explode(":", $row['url']);
159
					$href = Registry::singleton()->getSetting($array1[1], "#");
160
				}
161
			} else {
162
				throw new IllegalStateException("Unknown menu type: " . $row['type']);
163
			}
164
165
			$entry['href'] = $href;
166
167
			if (!empty($row['icon']) && $row['icon'] != "none") {
168
				$entry['text'] = "<img src=\"" . $row['icon'] . "\" alt=\"" . $row['title'] . "\" title=\"" . $row['title'] . "\" style=\"max-width:32px; max-height:32px; \" /> " . $row['title'];
169
			}
170
171
			//get submenus
172
			$entry['submenus'] = $this->getMenuByParent($menu_array, $row['id']);
173
			$entry['has_submenus'] = sizeof($entry['submenus']) > 0;
174
175
			$array[] = $entry;
176
		}
177
178
		return $array;
179
	}
180
181
	/**
182
	 * get HTML code of menu
183
	 */
184
	public function getCode () : string {
185
		$template = new DwooTemplate($this->template);
186
187
		$template->assign("menu_array", $this->menus);
188
189
		/*$template = new Template($this->template);
190
191
		$this->parseMenu($this->menus, $template);
192
193
		//parse main block
194
		$template->parse("main");*/
195
196
		$html = $template->getCode();
197
198
		Events::throwEvent("get_menu_code", array(
199
			'menuID' => $this->menuID,
200
			'menus' => &$this->menus,
201
			'html' => &$html
202
		));
203
204
		return $html;
205
	}
206
207
	protected static function loadMenuID (int $menuID) {
208
		if (isset(self::$menuID_array[$menuID])) {
209
			return;
210
		}
211
212
		if (Cache::contains("menus", "menuID_" . $menuID)) {
213
			self::$menuID_array[$menuID] = Cache::get("menus", "menuID_" . $menuID);
214
		} else {
215
			$rows = Database::getInstance()->listRows("SELECT * FROM `{praefix}menu` WHERE `menuID` = :menuID AND `activated` = '1' ORDER BY `order`; ", array('menuID' => array(
216
				'type' => PDO::PARAM_INT,
217
				'value' => $menuID
218
			)));
219
220
			$array = array();
221
222
			foreach ($rows as $row) {
223
				$parentID = $row['parent'];
224
225
				if (!isset($array[$parentID])) {
226
					$array[$parentID] = array();
227
				}
228
229
				$array[$parentID][] = $row;
230
			}
231
232
			self::$menuID_array[$menuID] = $array;
233
234
			Cache::put("menus", "menuID_" . $menuID, $array);
235
		}
236
237
		//var_dump(self::$menuID_array);
238
	}
239
240
	public static function createMenuName (string $title, string $unique_name = null) : int {
241
		Events::throwEvent("before_create_menu_name", array(
242
			'title' => &$title
243
		));
244
245
		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...
246
			$unique_name = md5(PHPUtils::randomString(100));
247
		}
248
249
		$unique_name = Validator_String::get($unique_name);
250
251
		Database::getInstance()->execute("INSERT INTO `{praefix}menu_names` (
252
			`menuID`, `title`, `unique_name`, `activated`
253
		) VALUES (
254
			NULL, :title, :name, '1'
255
		) ON DUPLICATE KEY UPDATE `title` = :title, `activated` = '1'; ", array(
256
			'title' => $title,
257
			'name' => $unique_name
258
		));
259
260
		Cache::clear("menus");
261
262
		//get menuID of inserted menu name
263
		$menuID = Database::getInstance()->lastInsertId();
264
265
		Events::throwEvent("after_created_menu_name", array(
266
			'menuID' => $menuID,
267
			'title' => &$title
268
		));
269
270
		return $menuID;
271
	}
272
273
	public static function deleteMenuName (int $menuID) {
274
		Database::getInstance()->execute("DELETE FROM `{praefix}menu_names` WHERE `menuID` = :menuID; ", array(
275
			'menuID' => array(
276
				'type' => PDO::PARAM_INT,
277
				'value' => $menuID
278
			)
279
		));
280
281
		//clear cache
282
		Cache::clear("menus", "menuID_" . $menuID);
283
	}
284
285
	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") {
286
		if (!is_array($permissions)) {
287
			$permissions = array($permissions);
288
		}
289
290
		//validate values
291
		$id = Validator_Int::get($id);
292
		$menuID = Validator_Int::get($menuID);
293
		$title = Validator_String::get($title);
294
		$parent = Validator_Int::get($parent);
295
		$type = Validator_String::get($type);
296
		$login_required = (bool) $login_required;
297
298
		$permissions = implode("|", $permissions);
299
300
		if (is_null($unique_name) || empty($unique_name)) {
301
			$unique_name = md5(PHPUtils::randomString(100) . time());
302
		}
303
304
		$insertID = Database::getInstance()->execute("INSERT INTO `{praefix}menu` (
305
			`id`, `menuID`, `title`, `url`, `type`, `icon`, `permissions`, `login_required`, `parent`, `unique_name`, `extensions`, `order`, `owner`, `activated`
306
		) VALUES (
307
			:id, :menuID, :title, :url, :url_type, :icon, :permissions, :login_required, :parent, :unique_name, :extensions, :menu_order, :owner, '1'
308
		) ON DUPLICATE KEY UPDATE `menuID` = :menuID, `title` = :title, `url` = :url, `type` = :url_type, `permissions` = :permissions, `login_required` = :login_required, `parent` = :parent, `icon` = :icon, `activated` = '1'; ", array(
309
			'id' => $id,
310
			'menuID' => $menuID,
311
			'title' => $title,
312
			'url' => $url,
313
			'url_type' => $type,
314
			'icon' => $icon,
315
			'permissions' => $permissions,
316
			'login_required' => ($login_required ? 1 : 0),
317
			'parent' => $parent,
318
			'unique_name' => $unique_name,
319
			'extensions' => "none",
320
			'menu_order' => $order,
321
			'owner' => $owner
322
		));
323
324
		//clear cache
325
		Cache::clear("menus", "menuID_" . $menuID);
326
327
		return $insertID;
328
	}
329
330
}
331
332
?>
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...
333