Completed
Push — develop ( 0674b4...4b2fd1 )
by Serg
06:28
created

nodes.functions.inc.php ➔ dbug()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 2
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
if( ! defined('IN_MANAGER_MODE') || IN_MANAGER_MODE !== true) {
3
	die('<b>INCLUDE_ORDERING_ERROR</b><br /><br />Please use the EVO Content Manager instead of accessing this file directly.');
4
}
5
6
/**
7
 * @param int $indent
8
 * @param int $parent
9
 * @param int $expandAll
10
 * @param string $theme Not needed???????????
11
 * @param string $hereid
12
 * @return string
13
 */
14
function makeHTML($indent, $parent, $expandAll, $theme, $hereid = '') {
0 ignored issues
show
Coding Style introduced by
makeHTML uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
15
	global $modx;
16
	global $icons, $iconsPrivate, $_style;
17
	global $_lang, $opened, $opened2, $closed2; //added global vars
18
	global $modx_textdir;
19
20
	$output = '';
21
22
	// setup spacer
23
	$level = 0;
24
	$spacer = '<span class="indent">';
25
	for($i = 2; $i <= $indent; $i++) {
26
		$spacer .= '<i></i>';
27
		$level++;
28
	}
29
	$spacer .= '</span>';
30
31
	// manage order-by
32
	if(!isset($_SESSION['tree_sortby']) && !isset($_SESSION['tree_sortdir'])) {
33
		// This is the first startup, set default sort order
34
		$_SESSION['tree_sortby'] = 'menuindex';
35
		$_SESSION['tree_sortdir'] = 'ASC';
36
	}
37
38
	switch($_SESSION['tree_sortby']) {
39
		case 'createdon':
40
		case 'editedon':
41
		case 'publishedon':
42
		case 'pub_date':
43
		case 'unpub_date':
44
			$sortby = sprintf('CASE WHEN %s IS NULL THEN 1 ELSE 0 END, %s', 'sc.' . $_SESSION['tree_sortby'], 'sc.' . $_SESSION['tree_sortby']);
45
			break;
46
		default:
47
			$sortby = 'sc.' . $_SESSION['tree_sortby'];
48
	};
49
50
	$orderby = $modx->db->escape($sortby . ' ' . $_SESSION['tree_sortdir']);
51
52
	// Folder sorting gets special setup ;) Add menuindex and pagetitle
53
	if($_SESSION['tree_sortby'] == 'isfolder') {
54
		$orderby .= ', menuindex ASC, pagetitle';
55
	}
56
57
	$tblsc = $modx->getFullTableName('site_content');
58
	$tbldg = $modx->getFullTableName('document_groups');
59
	$tblst = $modx->getFullTableName('site_templates');
60
	// get document groups for current user
61
	$docgrp = (isset($_SESSION['mgrDocgroups']) && is_array($_SESSION['mgrDocgroups'])) ? implode(',', $_SESSION['mgrDocgroups']) : '';
62
	$showProtected = false;
63
	if(isset ($modx->config['tree_show_protected'])) {
64
		$showProtected = (boolean) $modx->config['tree_show_protected'];
65
	}
66
	$mgrRole = (isset ($_SESSION['mgrRole']) && (string) $_SESSION['mgrRole'] === '1') ? '1' : '0';
67
	if($showProtected == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
68
		$access = "AND (1={$mgrRole} OR sc.privatemgr=0" . (!$docgrp ? ')' : " OR dg.document_group IN ({$docgrp}))");
69
	} else {
70
		$access = '';
71
	}
72
	$docgrp_cond = $docgrp ? "OR dg.document_group IN ({$docgrp})" : '';
73
	$field = "DISTINCT sc.id, pagetitle, longtitle, menutitle, parent, isfolder, published, pub_date, unpub_date, richtext, searchable, cacheable, deleted, type, template, templatename, menuindex, donthit, hidemenu, alias, contentType, privateweb, privatemgr,
74
        MAX(IF(1={$mgrRole} OR sc.privatemgr=0 {$docgrp_cond}, 1, 0)) AS hasAccess, GROUP_CONCAT(document_group SEPARATOR ',') AS roles";
75
	$from = "{$tblsc} AS sc LEFT JOIN {$tbldg} dg on dg.document = sc.id LEFT JOIN {$tblst} st on st.id = sc.template";
76
	$where = "(parent={$parent}) {$access} GROUP BY sc.id";
77
	$result = $modx->db->select($field, $from, $where, $orderby);
78
	if($modx->db->getRecordCount($result) == 0) {
79
		$output .= sprintf('<div><a class="empty">%s%s&nbsp;<span class="empty">%s</span></a></div>', $spacer, $_style['tree_deletedpage'], $_lang['empty_folder']);
80
	}
81
82
	$nodeNameSource = $_SESSION['tree_nodename'] == 'default' ? $modx->config['resource_tree_node_name'] : $_SESSION['tree_nodename'];
83
84
	while($row = $modx->db->getRow($result)) {
85
		$node = '';
86
87
		$nodetitle = getNodeTitle($nodeNameSource, $row);
88
		$nodetitleDisplay = $nodetitle;
89
90
		$treeNodeClass = 'node';
91
		$treeNodeClass .= $row['hasAccess'] == 0 ? ' protected' : '';
92
93
		if($row['deleted'] == 1) {
94
			$treeNodeClass .= ' deleted';
95
			//$nodetitleDisplay = sprintf('<span class="deletedNode">%s</span>', $nodetitle);
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
96
		} elseif($row['published'] == 0) {
97
			$treeNodeClass .= ' unpublished';
98
			//$nodetitleDisplay = sprintf('<span class="unpublishedNode">%s</span>', $nodetitle);
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
99
		} elseif($row['hidemenu'] == 1) {
100
			$treeNodeClass .= ' hidemenu';
101
			//$nodetitleDisplay = sprintf('<span class="notInMenuNode%s">%s</span>', $protectedClass, $nodetitle);
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
102
		} else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
103
			//$nodetitleDisplay = sprintf('<span class="publishedNode%s">%s</span>', $protectedClass, $nodetitle);
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
104
		}
105
106
		if($row['id'] == $hereid) {
107
			$treeNodeClass .= ' current';
108
		}
109
110
		$weblinkDisplay = $row['type'] == 'reference' ? sprintf('&nbsp;%s', $_style['tree_linkgo']) : '';
111
		$pageIdDisplay = '<small>(' . ($modx_textdir ? '&rlm;' : '') . $row['id'] . ')</small>';
112
113
		// Prepare displaying user-locks
114
		$lockedByUser = '';
115
		$rowLock = $modx->elementIsLocked(7, $row['id'], true);
116
		if($rowLock && $modx->hasPermission('display_locks')) {
117
			if($rowLock['sid'] == $modx->sid) {
118
				$title = $modx->parseText($_lang["lock_element_editing"], array(
119
					'element_type' => $_lang["lock_element_type_7"],
120
					'lasthit_df' => $rowLock['lasthit_df']
121
				));
122
				$lockedByUser = '<span title="' . $title . '" class="editResource">' . $_style['tree_preview_resource'] . '</span>';
123
			} else {
124
				$title = $modx->parseText($_lang["lock_element_locked_by"], array(
125
					'element_type' => $_lang["lock_element_type_7"],
126
					'username' => $rowLock['username'],
127
					'lasthit_df' => $rowLock['lasthit_df']
128
				));
129 View Code Duplication
				if($modx->hasPermission('remove_locks')) {
130
					$lockedByUser = '<span onclick="modx.tree.unlockElement(7, ' . $row['id'] . ', this);return false;" title="' . $title . '" class="lockedResource">' . $_style['icons_secured'] . '</span>';
131
				} else {
132
					$lockedByUser = '<span title="' . $title . '" class="lockedResource">' . $_style['icons_secured'] . '</span>';
133
				}
134
			}
135
		}
136
137
		$url = $modx->makeUrl($row['id']);
138
139
		$title = '';
140
		if(isDateNode($nodeNameSource)) {
141
			$title = $_lang['pagetitle'] . ': ' . $row['pagetitle'] . '[+lf+]';
142
		}
143
		$title .= $_lang['id'] . ': ' . $row['id'];
144
		$title .= '[+lf+]' . $_lang['resource_opt_menu_title'] . ': ' . $row['menutitle'];
145
		$title .= '[+lf+]' . $_lang['resource_opt_menu_index'] . ': ' . $row['menuindex'];
146
		$title .= '[+lf+]' . $_lang['alias'] . ': ' . (!empty($row['alias']) ? $row['alias'] : '-');
147
		$title .= '[+lf+]' . $_lang['template'] . ': ' . $row['templatename'];
148
		$title .= '[+lf+]' . $_lang['publish_date'] . ': ' . $modx->toDateFormat($row['pub_date']);
149
		$title .= '[+lf+]' . $_lang['unpublish_date'] . ': ' . $modx->toDateFormat($row['unpub_date']);
150
		$title .= '[+lf+]' . $_lang['page_data_web_access'] . ': ' . ($row['privateweb'] ? $_lang['private'] : $_lang['public']);
151
		$title .= '[+lf+]' . $_lang['page_data_mgr_access'] . ': ' . ($row['privatemgr'] ? $_lang['private'] : $_lang['public']);
152
		$title .= '[+lf+]' . $_lang['resource_opt_richtext'] . ': ' . ($row['richtext'] == 0 ? $_lang['no'] : $_lang['yes']);
153
		$title .= '[+lf+]' . $_lang['page_data_searchable'] . ': ' . ($row['searchable'] == 0 ? $_lang['no'] : $_lang['yes']);
154
		$title .= '[+lf+]' . $_lang['page_data_cacheable'] . ': ' . ($row['cacheable'] == 0 ? $_lang['no'] : $_lang['yes']);
155
		$title = $modx->htmlspecialchars($title);
156
		$title = str_replace('[+lf+]', ' &#13;', $title);   // replace line-breaks with empty space as fall-back
157
158
		$data = array(
159
			'id' => $row['id'],
160
			'pagetitle' => $row['pagetitle'],
161
			'longtitle' => $row['longtitle'],
162
			'menutitle' => $row['menutitle'],
163
			'parent' => $parent,
164
			'isfolder' => $row['isfolder'],
165
			'published' => $row['published'],
166
			'deleted' => $row['deleted'],
167
			'type' => $row['type'],
168
			'menuindex' => $row['menuindex'],
169
			'donthit' => $row['donthit'],
170
			'hidemenu' => $row['hidemenu'],
171
			'alias' => $row['alias'],
172
			'contenttype' => $row['contentType'],
173
			'privateweb' => $row['privateweb'],
174
			'privatemgr' => $row['privatemgr'],
175
			'hasAccess' => $row['hasAccess'],
176
			'template' => $row['template'],
177
			'nodetitle' => $nodetitle,
178
			'url' => $url,
179
			'title' => $title,
180
			'nodetitleDisplay' => $nodetitleDisplay,
181
			'weblinkDisplay' => $weblinkDisplay,
182
			'pageIdDisplay' => $pageIdDisplay,
183
			'lockedByUser' => $lockedByUser,
184
			'treeNodeClass' => $treeNodeClass,
185
			'treeNodeSelected' => $row['id'] == $hereid ? ' treeNodeSelected' : '',
186
			'tree_page_click' => $modx->config['tree_page_click'],
187
			'showChildren' => 1,
188
			'openFolder' => 1,
189
			'contextmenu' => '',
190
			'tree_minusnode' => $_style['tree_minusnode'],
191
			'tree_plusnode' => $_style['tree_plusnode'],
192
			'spacer' => $spacer,
193
			'subMenuState' => '',
194
			'level' => $level,
195
			'isPrivate' => 0,
196
			'roles' => ($row['roles'] ? $row['roles'] : '')
197
		);
198
199
		$ph = $data;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ph. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
200
		$ph['nodetitle_esc'] = addslashes($nodetitle);
201
		$ph['indent'] = $indent + 1;
202
		$ph['expandAll'] = $expandAll;
203
		$ph['isPrivate'] = ($row['privateweb'] || $row['privatemgr']) ? 1 : 0;
204
205
		if(!$row['isfolder']) {
206
			$tpl = getTplSingleNode();
207
			switch($row['id']) {
208
				case $modx->config['site_start']            :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
209
					$icon = $_style['tree_page_home'];
210
					break;
211
				case $modx->config['error_page']            :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
212
					$icon = $_style['tree_page_404'];
213
					break;
214
				case $modx->config['site_unavailable_page'] :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
215
					$icon = $_style['tree_page_hourglass'];
216
					break;
217
				case $modx->config['unauthorized_page']     :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
218
					$icon = $_style['tree_page_info'];
219
					break;
220
				default:
221 View Code Duplication
					if(isset($icons[$row['contentType']])) {
222
						$icon = $icons[$row['contentType']];
223
					} else {
224
						$icon = $_style['tree_page'];
225
					}
226
			}
227
			$ph['icon'] = $icon;
228
229
			// invoke OnManagerNodePrerender event
230
			$prenode = $modx->invokeEvent("OnManagerNodePrerender", array('ph' => $ph));
231 View Code Duplication
			if(is_array($prenode)) {
232
				$phnew = array();
233
				foreach($prenode as $pnode) {
234
					$phnew = array_merge($phnew, unserialize($pnode));
235
				}
236
				$ph = (count($phnew) > 0) ? $phnew : $ph;
237
			}
238
239 View Code Duplication
			if($ph['contextmenu']) {
240
				$ph['contextmenu'] = ' data-contextmenu="' . _htmlentities($ph['contextmenu']) . '"';
241
			}
242
243
			if($_SESSION['tree_show_only_folders']) {
244
				if($row['parent'] == 0) {
245
					$node .= $modx->parseText($tpl, $ph);
246
				} else {
247
					$node .= '';
248
				}
249
			} else {
250
				$node .= $modx->parseText($tpl, $ph);
251
			}
252
253
		} else {
254
			$ph['icon_folder_open'] = $_style['tree_folderopen_new'];
255
			$ph['icon_folder_close'] = $_style['tree_folder_new'];
256
257
			if($_SESSION['tree_show_only_folders']) {
258
				$tpl = getTplFolderNodeNotChildren();
259
				$checkFolders = checkIsFolder($row['id'], 1) ? 1 : 0; // folders
260
				$checkDocs = checkIsFolder($row['id'], 0) ? 1 : 0; // no folders
261
				$ph['tree_page_click'] = 3;
262
263
				// expandAll: two type for partial expansion
264
				if($expandAll == 1 || ($expandAll == 2 && in_array($row['id'], $opened))) {
265
					if($expandAll == 1) {
266
						$opened2[] = $row['id'];
267
					}
268
					$ph['icon'] = $ph['icon_folder_open'];
269
					$ph['icon_node_toggle'] = $ph['tree_minusnode'];
270
					$ph['node_toggle'] = 1;
271
					$ph['subMenuState'] = ' open';
272
273
					if(($checkDocs && !$checkFolders) || (!$checkDocs && !$checkFolders)) {
274
						$ph['showChildren'] = 1;
275
						$ph['icon_node_toggle'] = '';
276
						$ph['icon'] = $ph['icon_folder_close'];
277
					} elseif(!$checkDocs && $checkFolders) {
278
						$ph['showChildren'] = 0;
279
						$ph['openFolder'] = 2;
280
					} else {
281
						$ph['openFolder'] = 2;
282
					}
283
284
					// invoke OnManagerNodePrerender event
285
					$prenode = $modx->invokeEvent("OnManagerNodePrerender", array(
286
						'ph' => $ph,
287
						'opened' => '1'
288
					));
289 View Code Duplication
					if(is_array($prenode)) {
290
						$phnew = array();
291
						foreach($prenode as $pnode) {
292
							$phnew = array_merge($phnew, unserialize($pnode));
293
						}
294
						$ph = (count($phnew) > 0) ? $phnew : $ph;
295
					}
296
297 View Code Duplication
					if($ph['contextmenu']) {
298
						$ph['contextmenu'] = ' data-contextmenu="' . _htmlentities($ph['contextmenu']) . '"';
299
					}
300
301
					$node .= $modx->parseText($tpl, $ph);
302
					if($checkFolders) {
303
						$node .= makeHTML($indent + 1, $row['id'], $expandAll, $theme, $hereid);
304
					}
305
					$node .= '</div></div>';
306
				} else {
307
					$closed2[] = $row['id'];
308
					$ph['icon'] = $ph['icon_folder_close'];
309
					$ph['icon_node_toggle'] = $ph['tree_plusnode'];
310
					$ph['node_toggle'] = 0;
311
312
					if(($checkDocs && !$checkFolders) || (!$checkDocs && !$checkFolders)) {
313
						$ph['showChildren'] = 1;
314
						$ph['icon_node_toggle'] = '';
315
					} elseif(!$checkDocs && $checkFolders) {
316
						$ph['showChildren'] = 0;
317
						$ph['openFolder'] = 2;
318
					} else {
319
						$ph['openFolder'] = 2;
320
					}
321
322
					// invoke OnManagerNodePrerender event
323
					$prenode = $modx->invokeEvent("OnManagerNodePrerender", array(
324
						'ph' => $ph,
325
						'opened' => '0'
326
					));
327 View Code Duplication
					if(is_array($prenode)) {
328
						$phnew = array();
329
						foreach($prenode as $pnode) {
330
							$phnew = array_merge($phnew, unserialize($pnode));
331
						}
332
						$ph = (count($phnew) > 0) ? $phnew : $ph;
333
					}
334
335 View Code Duplication
					if($ph['contextmenu']) {
336
						$ph['contextmenu'] = ' data-contextmenu="' . _htmlentities($ph['contextmenu']) . '"';
337
					}
338
339
					$node .= $modx->parseText($tpl, $ph);
340
					$node .= '</div></div>';
341
				}
342
			} else {
343
				$tpl = getTplFolderNode();
344
				// expandAll: two type for partial expansion
345
				if($expandAll == 1 || ($expandAll == 2 && in_array($row['id'], $opened))) {
346
					if($expandAll == 1) {
347
						$opened2[] = $row['id'];
348
					}
349
					$ph['icon'] = $ph['icon_folder_open'];
350
					$ph['icon_node_toggle'] = $ph['tree_minusnode'];
351
					$ph['node_toggle'] = 1;
352
					$ph['subMenuState'] = ' open';
353
354 View Code Duplication
					if($ph['donthit'] == 1) {
355
						$ph['tree_page_click'] = 3;
356
						$ph['icon_node_toggle'] = '';
357
						$ph['icon'] = $ph['icon_folder_close'];
358
						$ph['showChildren'] = 0;
359
					}
360
361
					// invoke OnManagerNodePrerender event
362
					$prenode = $modx->invokeEvent("OnManagerNodePrerender", array(
363
						'ph' => $ph,
364
						'opened' => '1'
365
					));
366
					if(is_array($prenode)) {
367
						$phnew = array();
368
						foreach($prenode as $pnode) {
369
							$phnew = array_merge($phnew, unserialize($pnode));
370
						}
371
						$ph = (count($phnew) > 0) ? $phnew : $ph;
372
						if($ph['showChildren'] == 0) {
373
							unset($opened2[$row['id']]);
374
							$ph['node_toggle'] = 0;
375
							$ph['subMenuState'] = '';
376
						}
377
					}
378
379 View Code Duplication
					if($ph['showChildren'] == 0) {
380
						$ph['icon_node_toggle'] = '';
381
						$ph['donthit'] = 1;
382
						$ph['icon'] = $ph['icon_folder_close'];
383
						$tpl = getTplFolderNodeNotChildren();
384
					}
385
386 View Code Duplication
					if($ph['contextmenu']) {
387
						$ph['contextmenu'] = ' data-contextmenu="' . _htmlentities($ph['contextmenu']) . '"';
388
					}
389
390
					$node .= $modx->parseText($tpl, $ph);
391
					if($ph['donthit'] == 0) {
392
						$node .= makeHTML($indent + 1, $row['id'], $expandAll, $theme, $hereid);
393
					}
394
					$node .= '</div></div>';
395
				} else {
396
					$closed2[] = $row['id'];
397
					$ph['icon'] = $ph['icon_folder_close'];
398
					$ph['icon_node_toggle'] = $ph['tree_plusnode'];
399
					$ph['node_toggle'] = 0;
400
401 View Code Duplication
					if($ph['donthit'] == 1) {
402
						$ph['tree_page_click'] = 3;
403
						$ph['icon_node_toggle'] = '';
404
						$ph['icon'] = $ph['icon_folder_close'];
405
						$ph['showChildren'] = 0;
406
					}
407
408
					// invoke OnManagerNodePrerender event
409
					$prenode = $modx->invokeEvent("OnManagerNodePrerender", array(
410
						'ph' => $ph,
411
						'opened' => '0'
412
					));
413 View Code Duplication
					if(is_array($prenode)) {
414
						$phnew = array();
415
						foreach($prenode as $pnode) {
416
							$phnew = array_merge($phnew, unserialize($pnode));
417
						}
418
						$ph = (count($phnew) > 0) ? $phnew : $ph;
419
					}
420
421 View Code Duplication
					if($ph['showChildren'] == 0) {
422
						$ph['icon_node_toggle'] = '';
423
						$ph['donthit'] = 1;
424
						$ph['icon'] = $ph['icon_folder_close'];
425
						$tpl = getTplFolderNodeNotChildren();
426
					}
427
428 View Code Duplication
					if($ph['contextmenu']) {
429
						$ph['contextmenu'] = ' data-contextmenu="' . _htmlentities($ph['contextmenu']) . '"';
430
					}
431
432
					$node .= $modx->parseText($tpl, $ph);
433
					$node .= '</div></div>';
434
				}
435
			}
436
		}
437
438
		// invoke OnManagerNodeRender event
439
		$data['node'] = $node;
440
		$evtOut = $modx->invokeEvent('OnManagerNodeRender', $data);
441
		if(is_array($evtOut)) {
442
			$evtOut = implode("\n", $evtOut);
443
		}
444
		if($evtOut != '') {
445
			$node = trim($evtOut);
446
		}
447
448
		$output .= $node;
449
	}
450
451
	return $output;
452
}
453
454
/**
455
 * @param array $_style
456
 * @return array
457
 */
458
function getIconInfo($_style) {
459
	if(!isset($_style['tree_page_gif'])) {
460
		$_style['tree_page_gif'] = $_style['tree_page'];
461
	}
462
	if(!isset($_style['tree_page_jpg'])) {
463
		$_style['tree_page_jpg'] = $_style['tree_page'];
464
	}
465
	if(!isset($_style['tree_page_png'])) {
466
		$_style['tree_page_png'] = $_style['tree_page'];
467
	}
468
	$icons = array(
469
		'text/html' => $_style['tree_page_html'],
470
		'text/plain' => $_style['tree_page'],
471
		'text/xml' => $_style['tree_page_xml'],
472
		'text/css' => $_style['tree_page_css'],
473
		'text/javascript' => $_style['tree_page_js'],
474
		'application/rss+xml' => $_style['tree_page_rss'],
475
		'application/pdf' => $_style['tree_page_pdf'],
476
		'application/vnd.ms-word' => $_style['tree_page_word'],
477
		'application/vnd.ms-excel' => $_style['tree_page_excel'],
478
		'image/gif' => $_style['tree_page_gif'],
479
		'image/jpg' => $_style['tree_page_jpg'],
480
		'image/png' => $_style['tree_page_png']
481
	);
482
	return $icons;
483
}
484
485
/**
486
 * @param array $_style
487
 * @return array
488
 */
489
function getPrivateIconInfo($_style) {
490
	if(!isset($_style['tree_page_gif_secure'])) {
491
		$_style['tree_page_gif_secure'] = $_style['tree_page_secure'];
492
	}
493
	if(!isset($_style['tree_page_jpg_secure'])) {
494
		$_style['tree_page_jpg_secure'] = $_style['tree_page_secure'];
495
	}
496
	if(!isset($_style['tree_page_png_secure'])) {
497
		$_style['tree_page_png_secure'] = $_style['tree_page_secure'];
498
	}
499
	$iconsPrivate = array(
500
		'text/html' => $_style['tree_page_html_secure'],
501
		'text/plain' => $_style['tree_page_secure'],
502
		'text/xml' => $_style['tree_page_xml_secure'],
503
		'text/css' => $_style['tree_page_css_secure'],
504
		'text/javascript' => $_style['tree_page_js_secure'],
505
		'application/rss+xml' => $_style['tree_page_rss_secure'],
506
		'application/pdf' => $_style['tree_page_pdf_secure'],
507
		'application/vnd.ms-word' => $_style['tree_page_word_secure'],
508
		'application/vnd.ms-excel' => $_style['tree_page_excel_secure'],
509
		'image/gif' => $_style['tree_page_gif_secure'],
510
		'image/jpg' => $_style['tree_page_jpg_secure'],
511
		'image/png' => $_style['tree_page_png_secure']
512
	);
513
	return $iconsPrivate;
514
}
515
516
/**
517
 * @param string $nodeNameSource
518
 * @param array $row
519
 * @return string
520
 */
521
function getNodeTitle($nodeNameSource, $row) {
522
	global $modx;
523
524
	switch($nodeNameSource) {
525
		case 'menutitle':
526
			$nodetitle = $row['menutitle'] ? $row['menutitle'] : $row['pagetitle'];
527
			break;
528
		case 'alias':
529
			$nodetitle = $row['alias'] ? $row['alias'] : $row['id'];
530
			if(strpos($row['alias'], '.') === false) {
531
				if($row['isfolder'] != 1 || $modx->config['make_folders'] != 1) {
532
					$nodetitle .= $modx->config['friendly_url_suffix'];
533
				}
534
			}
535
			$nodetitle = $modx->config['friendly_url_prefix'] . $nodetitle;
536
			break;
537
		case 'pagetitle':
538
			$nodetitle = $row['pagetitle'];
539
			break;
540
		case 'longtitle':
541
			$nodetitle = $row['longtitle'] ? $row['longtitle'] : $row['pagetitle'];
542
			break;
543
		case 'createdon':
544
		case 'editedon':
545
		case 'publishedon':
546
		case 'pub_date':
547
		case 'unpub_date':
548
			$doc = $modx->getDocumentObject('id', $row['id']);
549
			$date = $doc[$nodeNameSource];
550
			if(!empty($date)) {
551
				$nodetitle = $modx->toDateFormat($date);
552
			} else {
553
				$nodetitle = '- - -';
554
			}
555
			break;
556
		default:
557
			$nodetitle = $row['pagetitle'];
558
	}
559
	$nodetitle = $modx->htmlspecialchars(str_replace(array(
560
		"\r\n",
561
		"\n",
562
		"\r"
563
	), ' ', $nodetitle), ENT_COMPAT);
564
	return $nodetitle;
565
}
566
567
/**
568
 * @param string $nodeNameSource
569
 * @return bool
570
 */
571
function isDateNode($nodeNameSource) {
572
	switch($nodeNameSource) {
573
		case 'createdon':
574
		case 'editedon':
575
		case 'publishedon':
576
		case 'pub_date':
577
		case 'unpub_date':
578
			return true;
579
		default:
580
			return false;
581
	}
582
}
583
584
/**
585
 * @param int $parent
586
 * @param int $isfolder
587
 * @return int
588
 */
589
function checkIsFolder($parent = 0, $isfolder = 1) {
590
	global $modx;
591
592
	return (int) $modx->db->getValue($modx->db->query('SELECT count(*) FROM ' . $modx->getFullTableName('site_content') . ' WHERE parent=' . $parent . ' AND isfolder=' . $isfolder . ' '));
593
}
594
595
/**
596
 * @param mixed $array
597
 * @return string
598
 */
599
function _htmlentities($array) {
600
	global $modx;
601
602
	$array = json_encode($array, JSON_UNESCAPED_UNICODE);
0 ignored issues
show
Unused Code introduced by
The call to json_encode() has too many arguments starting with JSON_UNESCAPED_UNICODE.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
603
	$array = htmlentities($array, ENT_COMPAT, $modx->config['modx_charset']);
604
605
	return $array;
606
}
607
608
/**
609
 * @return string
610
 */
611
function getTplSingleNode() {
612
	return '<div id="node[+id+]"><a class="[+treeNodeClass+]"
613
        onclick="modx.tree.treeAction(event,[+id+]);"
614
        oncontextmenu="modx.tree.showPopup(event,[+id+],\'[+nodetitle_esc+]\');"
615
        data-id="[+id+]"
616
        data-title-esc="[+nodetitle_esc+]"
617
        data-published="[+published+]"
618
        data-deleted="[+deleted+]"
619
        data-isfolder="[+isfolder+]"
620
        data-href="[+url+]"
621
        data-private="[+isPrivate+]"
622
        data-roles="[+roles+]"
623
        data-level="[+level+]"
624
        data-treepageclick="[+tree_page_click+]"
625
        [+contextmenu+]
626
        >[+spacer+]<span
627
        class="icon"
628
        onclick="modx.tree.showPopup(event,[+id+],\'[+nodetitle_esc+]\');return false;"
629
        oncontextmenu="this.onclick(event);return false;"
630
        >[+icon+]</span>[+lockedByUser+]<span
631
        class="title"
632
        title="[+title+]">[+nodetitleDisplay+][+weblinkDisplay+]</span>[+pageIdDisplay+]</a></div>';
633
}
634
635
/**
636
 * @return string
637
 */
638
function getTplFolderNode() {
639
	return '<div id="node[+id+]"><a class="[+treeNodeClass+]"
640
        onclick="modx.tree.treeAction(event,[+id+]);"
641
        oncontextmenu="modx.tree.showPopup(event,[+id+],\'[+nodetitle_esc+]\');"
642
        data-id="[+id+]"
643
        data-title-esc="[+nodetitle_esc+]"
644
        data-published="[+published+]"
645
        data-deleted="[+deleted+]"
646
        data-isfolder="[+isfolder+]"
647
        data-href="[+url+]"
648
        data-private="[+isPrivate+]"
649
        data-roles="[+roles+]"
650
        data-level="[+level+]"
651
        data-icon-expanded="[+tree_plusnode+]"
652
        data-icon-collapsed="[+tree_minusnode+]"
653
        data-icon-folder-open="[+icon_folder_open+]"
654
        data-icon-folder-close="[+icon_folder_close+]"
655
        data-treepageclick="[+tree_page_click+]"
656
        data-showchildren="[+showChildren+]"
657
        data-openfolder="[+openFolder+]"
658
        data-indent="[+indent+]"
659
        data-expandall="[+expandAll+]"
660
        [+contextmenu+]
661
        >[+spacer+]<span
662
        class="toggle"
663
        onclick="modx.tree.toggleNode(event, [+id+]);"
664
        oncontextmenu="this.onclick(event);"
665
        >[+icon_node_toggle+]</span><span
666
        class="icon"
667
        onclick="modx.tree.showPopup(event,[+id+],\'[+nodetitle_esc+]\');return false;"
668
        oncontextmenu="this.onclick(event);return false;"
669
        >[+icon+]</span>[+lockedByUser+]<span
670
        class="title"
671
        title="[+title+]">[+nodetitleDisplay+][+weblinkDisplay+]</span>[+pageIdDisplay+]</a><div>';
672
}
673
674
/**
675
 * @return string
676
 */
677
function getTplFolderNodeNotChildren() {
678
	return '<div id="node[+id+]"><a class="[+treeNodeClass+]"
679
        onclick="modx.tree.treeAction(event,[+id+]);"
680
        oncontextmenu="modx.tree.showPopup(event,[+id+],\'[+nodetitle_esc+]\');"
681
        data-id="[+id+]"
682
        data-title-esc="[+nodetitle_esc+]"
683
        data-published="[+published+]"
684
        data-deleted="[+deleted+]"
685
        data-isfolder="[+isfolder+]"
686
        data-href="[+url+]"
687
        data-private="[+isPrivate+]"
688
        data-roles="[+roles+]"
689
        data-level="[+level+]"
690
        data-icon-expanded="[+tree_plusnode+]"
691
        data-icon-collapsed="[+tree_minusnode+]"
692
        data-icon-folder-open="[+icon_folder_open+]"
693
        data-icon-folder-close="[+icon_folder_close+]"
694
        data-treepageclick="[+tree_page_click+]"
695
        data-showchildren="[+showChildren+]"
696
        data-openfolder="[+openFolder+]"
697
        data-indent="[+indent+]"
698
        data-expandall="[+expandAll+]"
699
        [+contextmenu+]
700
        >[+spacer+]<span
701
        class="icon"
702
        onclick="modx.tree.showPopup(event,[+id+],\'[+nodetitle_esc+]\');return false;"
703
        oncontextmenu="this.onclick(event);return false;"
704
        >[+icon+]</span>[+lockedByUser+]<span
705
        class="title"
706
        title="[+title+]">[+nodetitleDisplay+][+weblinkDisplay+]</span>[+pageIdDisplay+]</a><div>';
707
}
708
709
/**
710
 * @param int|string|array $str
711
 * @param bool $flag
712
 */
713
function dbug($str, $flag = false) {
714
	print('<pre>');
715
	print_r($str);
716
	print('</pre>');
717
	if($flag) {
718
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function dbug() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
719
	}
720
}
721