Passed
Push — teampass_3.0 ( 9ad4f0...66a471 )
by Nils
05:09
created

recursiveTree()   C

Complexity

Conditions 14
Paths 7

Size

Total Lines 115
Code Lines 68

Duplication

Lines 0
Ratio 0 %

Importance

Changes 10
Bugs 0 Features 0
Metric Value
cc 14
eloc 68
c 10
b 0
f 0
nc 7
nop 19
dl 0
loc 115
rs 5.7115

How to fix   Long Method    Complexity    Many Parameters   

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:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Teampass - a collaborative passwords manager.
7
 * ---
8
 * This library is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * @project   Teampass
13
 * @file      tree.php
14
 *
15
 * @author    Nils Laumaillé ([email protected])
16
 * @copyright 2009-2021 Teampass.net
17
 * @license   https://spdx.org/licenses/GPL-3.0-only.html#licenseText GPL-3.0
18
 *
19
 * @see       https://www.teampass.net
20
 */
21
22
23
require_once 'SecureHandler.php';
24
session_name('teampass_session');
25
session_start();
26
if (
27
    isset($_SESSION['CPM']) === false
28
    || $_SESSION['CPM'] !== 1
29
    || isset($_SESSION['key']) === false
30
    || empty($_SESSION['key']) === true
31
) {
32
    die('Hacking attempt...');
33
}
34
35
// Load config
36
if (file_exists('../includes/config/tp.config.php')) {
37
    include_once '../includes/config/tp.config.php';
38
} elseif (file_exists('./includes/config/tp.config.php')) {
39
    include_once './includes/config/tp.config.php';
40
} else {
41
    throw new Exception("Error file '/includes/config/tp.config.php' not exists", 1);
42
}
43
44
// includes
45
require_once $SETTINGS['cpassman_dir'] . '/includes/config/include.php';
46
require_once $SETTINGS['cpassman_dir'] . '/sources/SplClassLoader.php';
47
require_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php';
48
require_once $SETTINGS['cpassman_dir'] . '/includes/language/' . $_SESSION['user_language'] . '.php';
49
require_once $SETTINGS['cpassman_dir'] . '/includes/config/settings.php';
50
51
// header
52
header('Content-type: text/html; charset=utf-8');
53
header('Cache-Control: no-cache, must-revalidate');
54
55
// Define Timezone
56
if (isset($SETTINGS['timezone'])) {
57
    date_default_timezone_set($SETTINGS['timezone']);
58
} else {
59
    date_default_timezone_set('UTC');
60
}
61
62
// Connect to mysql server
63
require_once $SETTINGS['cpassman_dir'] . '/includes/libraries/Database/Meekrodb/db.class.php';
64
if (defined('DB_PASSWD_CLEAR') === false) {
65
    define('DB_PASSWD_CLEAR', defuseReturnDecrypted(DB_PASSWD, $SETTINGS));
66
}
67
DB::$host = DB_HOST;
68
DB::$user = DB_USER;
69
DB::$password = DB_PASSWD_CLEAR;
70
DB::$dbName = DB_NAME;
71
DB::$port = DB_PORT;
72
DB::$encoding = DB_ENCODING;
73
74
// Superglobal load
75
require_once $SETTINGS['cpassman_dir'] . '/includes/libraries/protect/SuperGlobal/SuperGlobal.php';
76
$superGlobal = new protect\SuperGlobal\SuperGlobal();
77
$get = [];
78
$get['user_tree_structure'] = $superGlobal->get('user_tree_structure', 'GET');
79
$get['user_tree_last_refresh_timestamp'] = $superGlobal->get('user_tree_last_refresh_timestamp', 'GET');
80
$get['force_refresh'] = $superGlobal->get('force_refresh', 'GET');
81
$get['id'] = $superGlobal->get('id', 'GET');
82
$session = [];
83
$session['forbiden_pfs'] = $superGlobal->get('forbiden_pfs', 'SESSION');
84
$session['groupes_visibles'] = $superGlobal->get('groupes_visibles', 'SESSION');
85
$session['list_restricted_folders_for_items'] = $superGlobal->get('list_restricted_folders_for_items', 'SESSION');
86
$session['user_id'] = $superGlobal->get('user_id', 'SESSION');
87
$session['login'] = $superGlobal->get('login', 'SESSION');
88
$session['user_read_only'] = $superGlobal->get('user_read_only', 'SESSION');
89
$session['personal_folder'] = $superGlobal->get('personal_folder', 'SESSION');
90
$session['list_folders_limited'] = $superGlobal->get('list_folders_limited', 'SESSION');
91
$session['read_only_folders'] = $superGlobal->get('read_only_folders', 'SESSION');
92
$session['personal_visible_groups'] = $superGlobal->get('personal_visible_groups', 'SESSION');
93
94
95
$lastFolderChange = DB::query(
96
    'SELECT * FROM ' . prefixTable('misc') . '
97
    WHERE type = %s AND intitule = %s',
98
    'timestamp',
99
    'last_folder_change'
100
);
101
if (
102
    empty($get['user_tree_structure']) === true
103
    || ($get['user_tree_last_refresh_timestamp'] !== null && strtotime($lastFolderChange) > strtotime($get['user_tree_last_refresh_timestamp']))
104
    || (isset($get['force_refresh']) === true && (int) $get['force_refresh'] === 1)
105
) {
106
    // Build tree
107
    $tree = new SplClassLoader('Tree\NestedTree', $SETTINGS['cpassman_dir'] . '/includes/libraries');
108
    $tree->register();
109
    $tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
110
111
    if (
112
        isset($_SESSION['list_folders_limited']) === true
113
        && count($_SESSION['list_folders_limited']) > 0
114
    ) {
115
        $listFoldersLimitedKeys = array_keys($_SESSION['list_folders_limited']);
116
    } else {
117
        $listFoldersLimitedKeys = array();
118
    }
119
    // list of items accessible but not in an allowed folder
120
    if (
121
        isset($_SESSION['list_restricted_folders_for_items']) === true
122
        && count($_SESSION['list_restricted_folders_for_items']) > 0
123
    ) {
124
        $listRestrictedFoldersForItemsKeys = @array_keys($_SESSION['list_restricted_folders_for_items']);
125
    } else {
126
        $listRestrictedFoldersForItemsKeys = array();
127
    }
128
129
    $ret_json = array();
130
    $last_visible_parent = -1;
131
    $last_visible_parent_level = 1;
132
133
    // build the tree to be displayed
134
    if (
135
        isset($get['id']) === true
136
        && is_numeric(intval($get['id'])) === true
137
        && isset($_SESSION['user']['treeloadstrategy']) === true
138
        && $_SESSION['user']['treeloadstrategy'] === 'sequential'
139
    ) {
140
        $ret_json = buildNodeTree(
141
            $get['id'],
142
            $listFoldersLimitedKeys,
143
            $listRestrictedFoldersForItemsKeys,
144
            /** @scrutinizer ignore-type */ $tree,
145
            $SETTINGS
146
        );
147
    } elseif (
148
        isset($_SESSION['user']['treeloadstrategy']) === true
149
        && $_SESSION['user']['treeloadstrategy'] === 'sequential'
150
    ) {
151
        $ret_json = buildNodeTree(
152
            0,
153
            $listFoldersLimitedKeys,
154
            $listRestrictedFoldersForItemsKeys,
155
            /** @scrutinizer ignore-type */ $tree,
156
            $SETTINGS
157
        );
158
    } else {
159
        $completTree = $tree->getTreeWithChildren();
160
        foreach ($completTree[0]->children as $child) {
161
            recursiveTree(
162
                $child,
163
                $completTree,
164
                /** @scrutinizer ignore-type */ $tree,
165
                $listFoldersLimitedKeys,
166
                $listRestrictedFoldersForItemsKeys,
167
                $last_visible_parent,
168
                $last_visible_parent_level,
169
                $SETTINGS,
170
                $ret_json,
171
                $session['forbiden_pfs'],
172
                $session['groupes_visibles'],
173
                $session['list_restricted_folders_for_items'],
174
                $session['user_id'],
175
                $session['login'],
176
                $session['user_read_only'],
177
                $session['personal_folder'],
178
                $session['list_folders_limited'],
179
                $session['read_only_folders'],
180
                $session['personal_visible_groups']
181
            );
182
        }
183
    }
184
185
    // Save in SESSION
186
    $superGlobal->put('user_tree_structure', $ret_json, 'SESSION');
187
    $superGlobal->put('user_tree_last_refresh_timestamp', time(), 'SESSION');
188
189
    // Send back
190
    echo json_encode($ret_json);
191
} else {
192
    //echo '['.$get['user_tree_structure'].']';
193
    echo $get['user_tree_structure'];
194
}
195
196
/**
197
 * Get through asked folders.
198
 *
199
 * @param int   $nodeId                            Id
200
 * @param array $listFoldersLimitedKeys            Limited
201
 * @param array $listRestrictedFoldersForItemsKeys Restricted
202
 * @param array $tree                              The tree
203
 * @param array $SETTINGS                          Teampass settings
204
 *
205
 * @return array
206
 */
207
function buildNodeTree(
208
    $nodeId,
209
    $listFoldersLimitedKeys,
210
    $listRestrictedFoldersForItemsKeys,
211
    $tree,
212
    $SETTINGS
213
) {
214
    // Load library
215
    include_once $SETTINGS['cpassman_dir'] . '/includes/libraries/protect/SuperGlobal/SuperGlobal.php';
216
    $superGlobal = new protect\SuperGlobal\SuperGlobal();
217
218
    // Prepare superGlobal variables
219
    $session_forbiden_pfs = $superGlobal->get('forbiden_pfs', 'SESSION');
220
    $session_groupes_visibles = $superGlobal->get('groupes_visibles', 'SESSION');
221
    $session_list_restricted_folders_for_items = $superGlobal->get('list_restricted_folders_for_items', 'SESSION');
222
    $session_user_id = $superGlobal->get('user_id', 'SESSION');
223
    $session_login = $superGlobal->get('login', 'SESSION');
224
    $session_no_access_folders = $superGlobal->get('no_access_folders', 'SESSION');
225
    $session_list_folders_limited = $superGlobal->get('list_folders_limited', 'SESSION');
226
    $session_read_only_folders = $superGlobal->get('read_only_folders', 'SESSION');
227
    $session_personal_folders = $superGlobal->get('personal_folders', 'SESSION');
228
    $session_personal_visible_groups = $superGlobal->get('personal_visible_groups', 'SESSION');
229
    $session_user_read_only = $superGlobal->get('user_read_only', 'SESSION');
230
231
    $ret_json = array();
232
233
    // Be sure that user can only see folders he/she is allowed to
234
    if (
235
        in_array($nodeId, $session_forbiden_pfs) === false
236
        || in_array($nodeId, $session_groupes_visibles) === true
237
        || in_array($nodeId, $listFoldersLimitedKeys) === true
238
        || in_array($nodeId, $listRestrictedFoldersForItemsKeys) === true
239
    ) {
240
        $nbChildrenItems = 0;
241
242
        // Check if any allowed folder is part of the descendants of this node
243
        $nodeDescendants = $tree->getDescendants($nodeId, false, true, false);
244
        foreach ($nodeDescendants as $node) {
245
            $displayThisNode = false;
246
            if ((in_array($node->id, $session_forbiden_pfs) === false
247
                    || in_array($node->id, $session_groupes_visibles) === true
248
                    || in_array($node->id, $listFoldersLimitedKeys) === true
249
                    || in_array($node->id, $listRestrictedFoldersForItemsKeys)) === true
250
                && (in_array(
251
                    $node->id,
252
                    array_merge($session_groupes_visibles, $session_list_restricted_folders_for_items)
253
                ) === true
254
                    || (is_array($listFoldersLimitedKeys) === true && in_array($node->id, $listFoldersLimitedKeys) === true)
255
                    || (is_array($listRestrictedFoldersForItemsKeys) === true && in_array($node->id, $listRestrictedFoldersForItemsKeys) === true)
256
                    || in_array($node->id, $session_no_access_folders) === true)
257
            ) {
258
                $displayThisNode = true;
259
            }
260
261
            if ($displayThisNode === true) {
262
                $hide_node = $show_but_block = false;
263
                $text = '';
264
                $title = '';
265
266
                // get count of Items in this folder
267
                DB::query(
268
                    'SELECT *
269
                    FROM ' . prefixTable('items') . '
270
                    WHERE inactif=%i AND id_tree = %i',
271
                    0,
272
                    $node->id
273
                );
274
                $itemsNb = DB::count();
275
276
                // get info about current folder
277
                DB::query(
278
                    'SELECT *
279
                    FROM ' . prefixTable('nested_tree') . '
280
                    WHERE parent_id = %i',
281
                    $node->id
282
                );
283
                $childrenNb = DB::count();
284
285
                // If personal Folder, convert id into user name
286
                $node->title = $node->title === $session_user_id && (int) $node->nlevel === 1 ?
287
                    $session_login :
288
                    ($node->title === null ? '' : htmlspecialchars_decode($node->title, ENT_QUOTES));
289
290
                // prepare json return for current node
291
                $parent = $node->parent_id === 0 ? '#' : 'li_' . $node->parent_id;
292
293
                // special case for READ-ONLY folder
294
                $title = $session_user_read_only === true && in_array($node->id, $session_personal_folders) === false ? langHdl('read_only_account') : $title;
295
                $text .= str_replace('&', '&amp;', $node->title);
296
                $restricted = '0';
297
                $folderClass = 'folder';
298
299
                if (in_array($node->id, $session_groupes_visibles)) {
300
                    if (in_array($node->id, $session_read_only_folders)) {
301
                        $text = "<i class='far fa-eye fa-xs mr-1'></i>" . $text;
302
                        $title = langHdl('read_only_account');
303
                        $restricted = 1;
304
                        $folderClass = 'folder_not_droppable';
305
                    } elseif ($session_user_read_only === true && !in_array($node->id, $session_personal_visible_groups)) {
306
                        $text = "<i class='far fa-eye fa-xs mr-1'></i>" . $text;
307
                    }
308
                    $text .=
309
                        ' <span class=\'badge badge-danger ml-2 items_count\' id=\'itcount_' . $node->id . '\'>' . $itemsNb . '</span>'
310
                        .(isset($SETTINGS['tree_counters']) && $SETTINGS['tree_counters'] === 1 ?
311
                            '/'.$nbChildrenItems .'/'.(count($nodeDescendants) - 1)  :
312
                            '')
313
                        .'</span>';
314
                } elseif (in_array($node->id, $listFoldersLimitedKeys)) {
315
                    $restricted = 1;
316
                    $text .= 
317
                        $session_user_read_only === true ?
318
                            "<i class='far fa-eye fa-xs mr-1'></i>" :
319
                            '<span class="badge badge-danger ml-2 items_count" id="itcount_' . $node->id . '">' . count($session_list_folders_limited[$node->id]) . '</span>';
320
                } elseif (in_array($node->id, $listRestrictedFoldersForItemsKeys)) {
321
                    $restricted = 1;
322
                    if ($session_user_read_only === true) {
323
                        $text = "<i class='far fa-eye fa-xs mr-1'></i>" . $text;
324
                    }
325
                    $text .= $session_user_read_only === true ? 
326
                        "<i class='far fa-eye fa-xs mr-1'></i>" :
327
                        '<span class="badge badge-danger ml-2 items_count" id="itcount_' . $node->id . '">' . count($session_list_restricted_folders_for_items[$node->id]) . '</span>';
328
                } else {
329
                    $restricted = 1;
330
                    $folderClass = 'folder_not_droppable';
331
                    if (isset($SETTINGS['show_only_accessible_folders']) && (int) $SETTINGS['show_only_accessible_folders'] === 1) {
332
                        // folder is not visible
333
                        $nodeDirectDescendants = $tree->getDescendants($nodeId, false, true, true);
334
                        if (count($nodeDirectDescendants) > 0) {
335
                            // show it but block it
336
                            $hide_node = false;
337
                            $show_but_block = true;
338
                        } else {
339
                            // hide it
340
                            $hide_node = true;
341
                        }
342
                    } else {
343
                        // folder is visible but not accessible by user
344
                        $show_but_block = true;
345
                    }
346
                }
347
348
                // json
349
                if ($hide_node === false && $show_but_block === false) {
350
                    array_push(
351
                        $ret_json,
352
                        array(
353
                            'id' => 'li_' . $node->id,
354
                            'parent' => $parent,
355
                            'text' => $text,
356
                            'children' => $childrenNb === 0 ? false : true,
357
                            'li_attr' => array(
358
                                'class' => 'jstreeopen',
359
                                'title' => 'ID [' . $node->id . '] ' . $title,
360
                            ),
361
                            'a_attr' => array(
362
                                'id' => 'fld_' . $node->id,
363
                                'class' => $folderClass,
364
                                'onclick' => 'ListerItems(' . $node->id . ', ' . $restricted . ', 0, 1)',
365
                                'data-title' => $node->title,
366
                            ),
367
                        )
368
                    );
369
                } elseif ($show_but_block === true) {
370
                    array_push(
371
                        $ret_json,
372
                        array(
373
                            'id' => 'li_' . $node->id,
374
                            'parent' =>  $parent,
375
                            'children' => $childrenNb === 0 ? false : true,
376
                            'text' => '<i class="fas fa-times fa-xs text-danger mr-1"></i>' . $text,
377
                            'li_attr' => array(
378
                                'class' => '',
379
                                'title' => 'ID [' . $node->id . '] ' . langHdl('no_access'),
380
                            ),
381
                        )
382
                    );
383
                }
384
            }
385
        }
386
    }
387
    return $ret_json;
388
}
389
390
391
/**
392
 * Get through complete tree
393
 *
394
 * @param int     $nodeId                            Id
395
 * @param array   $completTree                       Tree info
396
 * @param array   $tree                              The tree
397
 * @param array   $listFoldersLimitedKeys            Limited
398
 * @param array   $listRestrictedFoldersForItemsKeys Restricted
399
 * @param int     $last_visible_parent               Visible parent
400
 * @param int     $last_visible_parent_level         Parent level
401
 * @param array   $SETTINGS                          Teampass settings
402
 * @param array   $ret_json                          Array
403
 * @param string  $session_forbiden_pfs,
404
 * @param string  $session_groupes_visibles,
405
 * @param string  $session_list_restricted_folders_for_items,
406
 * @param int     $session_user_id,
407
 * @param string  $session_login,
408
 * @param string  $session_user_read_only,
409
 * @param int     $session_personal_folder,
410
 * @param string  $session_list_folders_limited,
411
 * @param string  $session_read_only_folders,
412
 * @param string  $session_personal_visible_groups
413
 *
414
 * @return array
415
 */
416
function recursiveTree(
417
    $nodeId,
418
    $completTree,
419
    $tree,
420
    $listFoldersLimitedKeys,
421
    $listRestrictedFoldersForItemsKeys,
422
    $last_visible_parent,
423
    $last_visible_parent_level,
424
    $SETTINGS,
425
    &$ret_json = array(),
426
    $session_forbiden_pfs,
427
    $session_groupes_visibles,
428
    $session_list_restricted_folders_for_items,
429
    $session_user_id,
430
    $session_login,
431
    $session_user_read_only,
432
    $session_personal_folder,
433
    $session_list_folders_limited,
434
    $session_read_only_folders,
435
    $session_personal_visible_groups
436
) {
437
    $text = '';
438
    $title = '';
439
    $show_but_block = false;
440
441
    // Load config
442
    if (file_exists('../includes/config/tp.config.php')) {
443
        include '../includes/config/tp.config.php';
444
    } elseif (file_exists('./includes/config/tp.config.php')) {
445
        include './includes/config/tp.config.php';
446
    } else {
447
        throw new Exception("Error file '/includes/config/tp.config.php' not exists", 1);
448
    }
449
450
    // Be sure that user can only see folders he/she is allowed to
451
    if (
452
        in_array($completTree[$nodeId]->id, $session_forbiden_pfs) === false
453
        || in_array($completTree[$nodeId]->id, $session_groupes_visibles) === true
454
    ) {
455
        $displayThisNode = false;
456
        $hide_node = false;
457
        $nbChildrenItems = 0;
458
459
        // Check if any allowed folder is part of the descendants of this node
460
        $nodeDescendants = $tree->getDescendants($completTree[$nodeId]->id, true, false, true);
461
        foreach ($nodeDescendants as $node) {
462
            // manage tree counters
463
            if (
464
                isset($SETTINGS['tree_counters']) === true
465
                && (int) $SETTINGS['tree_counters'] === 1
466
                && in_array(
467
                    $node,
468
                    array_merge($session_groupes_visibles, $session_list_restricted_folders_for_items)
469
                ) === true
470
            ) {
471
                DB::query(
472
                    'SELECT * FROM ' . prefixTable('items') . '
473
                    WHERE inactif=%i AND id_tree = %i',
474
                    0,
475
                    $node
476
                );
477
                $nbChildrenItems += DB::count();
478
            }
479
480
            if (
481
                in_array($node, $session_groupes_visibles) === true
482
            ) {
483
                // Final check - is PF allowed?
484
                $nodeDetails = $tree->getNode($node);
485
                if (
486
                    (int) $nodeDetails->personal_folder === 1
487
                    && (int) $SETTINGS['enable_pf_feature'] === 1
488
                    && (int) $session_personal_folder === 0
489
                ) {
490
                    $displayThisNode = false;
491
                } else {
492
                    $displayThisNode = true;
493
                    // not adding a break in order to permit a correct count of items
494
                }
495
                $hide_node = $show_but_block = false;
496
                $text = $title = '';
497
            }
498
        }
499
500
        if ($displayThisNode === true) {
501
            handleNode(
502
                $nodeId,
503
                $completTree,
504
                $tree,
505
                $listFoldersLimitedKeys,
506
                $listRestrictedFoldersForItemsKeys,
507
                $last_visible_parent,
508
                $last_visible_parent_level,
509
                $SETTINGS,
510
                $ret_json,
511
                $session_forbiden_pfs,
512
                $session_groupes_visibles,
513
                $session_list_restricted_folders_for_items,
514
                $session_user_id,
515
                $session_login,
516
                $session_user_read_only,
517
                $session_personal_folder,
518
                $session_list_folders_limited,
519
                $session_read_only_folders,
520
                $session_personal_visible_groups,
521
                $text,
522
                $title,
523
                $hide_node,
524
                $show_but_block,
525
                $nbChildrenItems,
526
                $nodeDescendants
527
            );
528
        }
529
    }
530
    return $ret_json;
531
}
532
533
534
function handleNode(
535
    $nodeId,
536
    $completTree,
537
    $tree,
538
    $listFoldersLimitedKeys,
539
    $listRestrictedFoldersForItemsKeys,
540
    $last_visible_parent,
541
    $last_visible_parent_level,
542
    $SETTINGS,
543
    &$ret_json = array(),
544
    $session_forbiden_pfs,
545
    $session_groupes_visibles,
546
    $session_list_restricted_folders_for_items,
547
    $session_user_id,
548
    $session_login,
549
    $session_user_read_only,
550
    $session_personal_folder,
551
    $session_list_folders_limited,
552
    $session_read_only_folders,
553
    $session_personal_visible_groups,
554
    $text,
555
    $title,
556
    $hide_node,
557
    $show_but_block,
558
    $nbChildrenItems,
559
    $nodeDescendants
560
)
561
{
562
    // get info about current folder
563
    DB::query(
564
        'SELECT * FROM ' . prefixTable('items') . '
565
        WHERE inactif=%i AND id_tree = %i',
566
        0,
567
        $completTree[$nodeId]->id
568
    );
569
    $itemsNb = DB::count();
570
571
    // If personal Folder, convert id into user name
572
    if ($completTree[$nodeId]->title === $session_user_id && $completTree[$nodeId]->nlevel === 1) {
573
        $completTree[$nodeId]->title = $session_login;
574
    }
575
576
    // Decode if needed
577
    $completTree[$nodeId]->title = htmlspecialchars_decode($completTree[$nodeId]->title, ENT_QUOTES);
578
579
    // special case for READ-ONLY folder
580
    if (
581
        $session_user_read_only === true
582
        && in_array($completTree[$nodeId]->id, $session_user_read_only) === false
583
    ) {
584
        $title = langHdl('read_only_account');
585
    }
586
    $text .= $completTree[$nodeId]->title;
587
    $restricted = '0';
588
    $folderClass = 'folder';
589
590
    if (in_array($completTree[$nodeId]->id, $session_groupes_visibles) === true) {
591
        if (in_array($completTree[$nodeId]->id, $session_read_only_folders) === true) {
592
            $text = "<i class='far fa-eye fa-xs mr-1'></i>" . $text;
593
            $title = langHdl('read_only_account');
594
            $restricted = 1;
595
            $folderClass = 'folder_not_droppable';
596
        } elseif (
597
            $session_user_read_only === true
598
            && in_array($completTree[$nodeId]->id, $session_personal_visible_groups) === false
599
        ) {
600
            $text = "<i class='far fa-eye fa-xs mr-1'></i>" . $text;
601
        }
602
        $text .= 
603
            '<span class=\'badge badge-pill badge-light ml-2 items_count\' id=\'itcount_' . $completTree[$nodeId]->id . '\'>' . $itemsNb .
604
            ((isset($SETTINGS['tree_counters']) === true && (int) $SETTINGS['tree_counters'] === 1) ?
605
                '/'.$nbChildrenItems .'/'.(count($nodeDescendants) - 1)  :
606
                '')
607
            . '</span>';
608
    } elseif (in_array($completTree[$nodeId]->id, $listFoldersLimitedKeys) === true) {
609
        $restricted = 1;
610
        if ($session_user_read_only === true) {
611
            $text = "<i class='far fa-eye fa-xs mr-1'></i>" . $text;
612
        }
613
        $text .= '<span class=\'badge badge-pill badge-light ml-2 items_count\' id=\'itcount_' . $completTree[$nodeId]->id . '\'>' . count($session_list_folders_limited[$completTree[$nodeId]->id]);
614
    } elseif (in_array($completTree[$nodeId]->id, $listRestrictedFoldersForItemsKeys) === true) {
615
        $restricted = 1;
616
        if ($session_user_read_only === true) {
617
            $text = "<i class='far fa-eye fa-xs mr-1'></i>" . $text;
618
        }
619
        $text .= '<span class=\'badge badge-pill badge-light ml-2 items_count\' id=\'itcount_' . $completTree[$nodeId]->id . '\'>' . count($session_list_restricted_folders_for_items[$completTree[$nodeId]->id]) . '</span>';
620
    } else {
621
        $restricted = 1;
622
        $folderClass = 'folder_not_droppable';
623
        if (
624
            isset($SETTINGS['show_only_accessible_folders']) === true
625
            && (int) $SETTINGS['show_only_accessible_folders'] === 1
626
            && $nbChildrenItems === 0
627
        ) {
628
            // folder should not be visible
629
            // only if it has no descendants
630
            $nodeDirectDescendants = $tree->getDescendants($nodeId, false, false, true);
631
            if (
632
                count(
633
                    array_diff(
634
                        $nodeDirectDescendants,
635
                        array_merge(
636
                            $session_groupes_visibles,
637
                            array_keys($session_list_restricted_folders_for_items)
638
                        )
639
                    )
640
                ) !== count($nodeDirectDescendants)
641
            ) {
642
                // show it but block it
643
                $show_but_block = true;
644
                $hide_node = false;
645
            } else {
646
                // hide it
647
                $hide_node = true;
648
            }
649
        } else {
650
            // folder is visible but not accessible by user
651
            $show_but_block = true;
652
        }
653
    }
654
655
    // prepare json return for current node
656
    $parent = $completTree[$nodeId]->parent_id === '0' ? '#' : 'li_' . $completTree[$nodeId]->parent_id;
657
658
    // handle displaying
659
    if (
660
        isset($SETTINGS['show_only_accessible_folders']) === true
661
        && (int) $SETTINGS['show_only_accessible_folders'] === 1
662
    ) {
663
        if ($hide_node === true) {
664
            $last_visible_parent = (int) $parent;
665
            $last_visible_parent_level = $completTree[$nodeId]->nlevel--;
666
        } elseif ($completTree[$nodeId]->nlevel < $last_visible_parent_level) {
667
            $last_visible_parent = -1;
668
        }
669
    }
670
671
    // json
672
    if ($hide_node === false && $show_but_block === false) {
673
        array_push(
674
            $ret_json,
675
            array(
676
                'id' => 'li_' . $completTree[$nodeId]->id,
677
                'parent' => $last_visible_parent === -1 ? $parent : $last_visible_parent,
678
                'text' => $text,
679
                'li_attr' => array(
680
                    'class' => 'jstreeopen',
681
                    'title' => 'ID [' . $completTree[$nodeId]->id . '] ' . $title,
682
                ),
683
                'a_attr' => array(
684
                    'id' => 'fld_' . $completTree[$nodeId]->id,
685
                    'class' => $folderClass,
686
                    'onclick' => 'ListerItems(' . $completTree[$nodeId]->id . ', ' . $restricted . ', 0, 1)',
687
                    'data-title' => $completTree[$nodeId]->title,
688
                ),
689
            )
690
        );
691
    } elseif ($show_but_block === true) {
692
        array_push(
693
            $ret_json,
694
            array(
695
                'id' => 'li_' . $completTree[$nodeId]->id,
696
                'parent' => $last_visible_parent === -1 ? $parent : $last_visible_parent,
697
                'text' => '<i class="fas fa-times fa-xs text-danger mr-1"></i>' . $text,
698
                'li_attr' => array(
699
                    'class' => '',
700
                    'title' => 'ID [' . $completTree[$nodeId]->id . '] ' . langHdl('no_access'),
701
                ),
702
            )
703
        );
704
    }
705
    foreach ($completTree[$nodeId]->children as $child) {
706
        recursiveTree(
707
            $child,
708
            $completTree,
709
            /** @scrutinizer ignore-type */ $tree,
710
            $listFoldersLimitedKeys,
711
            $listRestrictedFoldersForItemsKeys,
712
            $last_visible_parent,
713
            $last_visible_parent_level,
714
            $SETTINGS,
715
            $ret_json,
716
            $session_forbiden_pfs,
717
            $session_groupes_visibles,
718
            $session_list_restricted_folders_for_items,
719
            $session_user_id,
720
            $session_login,
721
            $session_user_read_only,
722
            $session_personal_folder,
723
            $session_list_folders_limited,
724
            $session_read_only_folders,
725
            $session_personal_visible_groups
726
        );
727
    }
728
}