Passed
Pull Request — master (#3790)
by
unknown
04:51
created

prepareNodeJson()   C

Complexity

Conditions 13
Paths 40

Size

Total Lines 72
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 13
eloc 40
c 4
b 0
f 0
nc 40
nop 10
dl 0
loc 72
rs 6.6166

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-2023 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
include __DIR__.'/../includes/config/tp.config.php';
37
38
// includes
39
require_once $SETTINGS['cpassman_dir'] . '/includes/config/include.php';
40
require_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php';
41
require_once $SETTINGS['cpassman_dir'] . '/includes/language/' . $_SESSION['user']['user_language'] . '.php';
42
require_once $SETTINGS['cpassman_dir'] . '/includes/config/settings.php';
43
44
// header
45
header('Content-type: text/html; charset=utf-8');
46
header('Cache-Control: no-cache, must-revalidate');
47
48
// Define Timezone
49
if (isset($SETTINGS['timezone'])) {
50
    date_default_timezone_set($SETTINGS['timezone']);
51
} else {
52
    date_default_timezone_set('UTC');
53
}
54
55
// Connect to mysql server
56
require_once $SETTINGS['cpassman_dir'] . '/includes/libraries/Database/Meekrodb/db.class.php';
57
if (defined('DB_PASSWD_CLEAR') === false) {
58
    define('DB_PASSWD_CLEAR', defuseReturnDecrypted(DB_PASSWD, $SETTINGS));
59
}
60
DB::$host = DB_HOST;
61
DB::$user = DB_USER;
62
DB::$password = DB_PASSWD_CLEAR;
63
DB::$dbName = DB_NAME;
64
DB::$port = DB_PORT;
65
DB::$encoding = DB_ENCODING;
66
DB::$ssl = DB_SSL;
67
DB::$connect_options = DB_CONNECT_OPTIONS;
68
69
// Superglobal load
70
require_once $SETTINGS['cpassman_dir'] . '/includes/libraries/protect/SuperGlobal/SuperGlobal.php';
71
$superGlobal = new protect\SuperGlobal\SuperGlobal();
72
73
// Prepare sanitization
74
$data = [
75
    'forbidenPfs' => isset($_SESSION['forbiden_pfs']) === true ? json_encode($_SESSION['forbiden_pfs']) : '{}',
76
    'visibleFolders' => isset($_SESSION['groupes_visibles']) === true ? json_encode($_SESSION['groupes_visibles']) : '{}',
77
    'userId' => isset($_SESSION['user_id']) === true ? $_SESSION['user_id'] : '',
78
    'userLogin' => isset($_SESSION['login']) === true ? $_SESSION['login'] : '',
79
    'userReadOnly' => isset($_SESSION['user_read_only']) === true ? $_SESSION['user_read_only'] : '',
80
    'limitedFolders' => isset($_SESSION['list_folders_limited']) === true ? json_encode($_SESSION['list_folders_limited']) : '{}',
81
    'readOnlyFolders' => isset($_SESSION['read_only_folders']) === true ? json_encode($_SESSION['read_only_folders']) : '{}',
82
    'personalVisibleFolders' => isset($_SESSION['personal_visible_groups']) === true ? json_encode($_SESSION['personal_visible_groups']) : '{}',
83
    'userTreeLastRefresh' => isset($_SESSION['user_tree_last_refresh_timestamp']) === true ? $_SESSION['user_tree_last_refresh_timestamp'] : '',
84
    'forceRefresh' => isset($_GET['force_refresh']) === true ? $_GET['force_refresh'] : '',
85
    'nodeId' => isset($_GET['id']) === true ? $_GET['id'] : '',
86
    'restrictedFoldersForItems' => isset($_GET['list_restricted_folders_for_items']) === true ? json_encode($_GET['list_restricted_folders_for_items']) : '{}',
87
    'noAccessFolders' => isset($_SESSION['no_access_folders']) === true ? json_encode($_SESSION['no_access_folders']) : '{}',
88
    'personalFolders' => isset($_SESSION['personal_folders']) === true ? json_encode($_SESSION['personal_folders']) : '{}',
89
    'userCanCreateRootFolder' => isset($_SESSION['can_create_root_folder']) === true ? json_encode($_SESSION['can_create_root_folder']) : '{}',
90
    'userTreeLoadStrategy' => isset($_SESSION['user']['user_treeloadstrategy']) === true ? $_SESSION['user']['user_treeloadstrategy'] : '',
91
];
92
93
$filters = [
94
    'forbidenPfs' => 'cast:array',
95
    'visibleFolders' => 'cast:array',
96
    'userId' => 'cast:integer',
97
    'userLogin' => 'trim|escape',
98
    'userReadOnly' => 'cast:boolean',
99
    'limitedFolders' => 'cast:array',
100
    'readOnlyFolders' => 'cast:array',
101
    'personalVisibleFolders' => 'cast:array',
102
    'userTreeLastRefresh' => 'cast:integer',
103
    'forceRefresh' => 'cast:integer',
104
    'nodeId' => 'cast:integer',
105
    'restrictedFoldersForItems' => 'cast:array',
106
    'noAccessFolders' => 'cast:array',
107
    'personalFolders' => 'cast:array',
108
    'userCanCreateRootFolder' => 'cast:array',
109
    'userTreeLoadStrategy' => 'trim|escape',
110
];
111
112
$inputData = dataSanitizer(
113
    $data,
114
    $filters,
115
    $SETTINGS['cpassman_dir']
116
);
117
118
$lastFolderChange = DB::queryfirstrow(
119
    'SELECT valeur FROM ' . prefixTable('misc') . '
120
    WHERE type = %s AND intitule = %s',
121
    'timestamp',
122
    'last_folder_change'
123
);
124
if (DB::count() === 0) {
125
    $lastFolderChange['valeur'] = 0;
126
}
127
128
// Should we use a cache or refresh the tree
129
$goTreeRefresh = loadTreeStrategy(
130
    (int) $lastFolderChange['valeur'],
131
    (int) $inputData['userTreeLastRefresh'],
132
    /** @scrutinizer ignore-type */(array) (is_null($superGlobal->get('user_tree_structure', 'SESSION')) === true || empty($superGlobal->get('user_tree_structure', 'SESSION')) === true) ? [] : $superGlobal->get('user_tree_structure', 'SESSION'),
133
    (int) $inputData['userId'],
134
    (int) $inputData['forceRefresh']
135
);
136
137
// We don't use the cache if an ID of folder is provided
138
if ($goTreeRefresh['state'] === true || empty($inputData['nodeId']) === false || $inputData['userTreeLoadStrategy'] === 'sequential') {
139
    // Build tree
140
    require_once $SETTINGS['cpassman_dir'] . '/includes/libraries/Tree/NestedTree/NestedTree.php';
141
    $tree = new Tree\NestedTree\NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
142
143
    if (
144
        isset($inputData['limitedFolders']) === true
145
        && is_array($inputData['limitedFolders']) === true
146
        && count($inputData['limitedFolders']) > 0
147
    ) {
148
        $listFoldersLimitedKeys = array_keys($inputData['limitedFolders']);
149
    } else {
150
        $listFoldersLimitedKeys = array();
151
    }
152
    
153
    // list of items accessible but not in an allowed folder
154
    if (
155
        isset($inputData['restrictedFoldersForItems']) === true
156
        && count($inputData['restrictedFoldersForItems']) > 0
157
    ) {
158
        $listRestrictedFoldersForItemsKeys = @array_keys($inputData['restrictedFoldersForItems']);
159
    } else {
160
        $listRestrictedFoldersForItemsKeys = array();
161
    }
162
    
163
    $ret_json = array();
164
    $last_visible_parent = -1;
165
    $last_visible_parent_level = 1;
166
    $nodeId = isset($inputData['nodeId']) === true && is_int($inputData['nodeId']) === true ? $inputData['nodeId'] : 0;
167
168
    // build the tree to be displayed
169
    if (showFolderToUser(
170
        $nodeId,
171
        $inputData['forbidenPfs'],
172
        $inputData['visibleFolders'],
173
        $listFoldersLimitedKeys,
174
        $listRestrictedFoldersForItemsKeys
175
    ) === true)
176
    {
177
        if ($inputData['userTreeLoadStrategy'] === 'sequential') {
178
            // SEQUENTIAL MODE
179
            $completTree = $tree->getDescendants(empty($nodeId) === true ? 0 : (int) $nodeId, false, true, false);
180
            foreach ($completTree as $child) {
181
                recursiveTree(
182
                    (int) $child->id,
183
                    $child,
184
                    /** @scrutinizer ignore-type */ $tree,
185
                    $listFoldersLimitedKeys,
186
                    $listRestrictedFoldersForItemsKeys,
187
                    $last_visible_parent,
188
                    $last_visible_parent_level,
189
                    $SETTINGS,
190
                    $inputData,
191
                    $ret_json
192
                );
193
            }
194
195
        } else {
196
            // FULL MODE
197
            $completTree = $tree->getTreeWithChildren();
198
            foreach ($completTree[0]->children as $child) {
199
                recursiveTree(
200
                    (int) $child,
201
                    $completTree[$child],
202
                    /** @scrutinizer ignore-type */ $tree,
203
                    $listFoldersLimitedKeys,
204
                    $listRestrictedFoldersForItemsKeys,
205
                    $last_visible_parent,
206
                    $last_visible_parent_level,
207
                    $SETTINGS,
208
                    $inputData,
209
                    $ret_json
210
                );
211
            }
212
        }
213
    }
214
215
    // Save in SESSION
216
    $superGlobal->put('user_tree_structure', $ret_json, 'SESSION');
217
    $superGlobal->put('user_tree_last_refresh_timestamp', time(), 'SESSION');
218
219
    $ret_json = json_encode($ret_json);
220
221
    // Save user folders tree
222
    cacheTreeUserHandler(
223
        (int) $inputData['userId'],
224
        $ret_json,
225
        $SETTINGS
226
    );
227
228
    // Send back
229
    echo $ret_json;
230
} else {
231
    echo $goTreeRefresh['data'];
232
}
233
234
235
/**
236
 * Check if user can see this folder based upon rights
237
 *
238
 * @param integer $nodeId
239
 * @param array $session_forbiden_pfs
240
 * @param array $session_groupes_visibles
241
 * @param array $listFoldersLimitedKeys
242
 * @param array $listRestrictedFoldersForItemsKeys
243
 * @return boolean
244
 */
245
function showFolderToUser(
246
    int $nodeId,
247
    array $session_forbiden_pfs,
248
    array $session_groupes_visibles,
249
    array $listFoldersLimitedKeys,
250
    array $listRestrictedFoldersForItemsKeys
251
): bool
252
{
253
    $big_array = array_diff(
254
        array_unique(
255
            array_merge(
256
                $session_groupes_visibles, 
257
                $listFoldersLimitedKeys, 
258
                $listRestrictedFoldersForItemsKeys
259
            ), 
260
            SORT_NUMERIC
261
        ), 
262
        $session_forbiden_pfs
263
    );
264
    if ($nodeId === 0 || in_array($nodeId, $big_array) === true) {
265
        return true;
266
    }
267
    return false;
268
}
269
270
271
272
/**
273
 * Get through complete tree
274
 *
275
 * @param int     $nodeId                            Id
276
 * @param stdClass   $currentNode                       Tree info
277
 * @param Tree\NestedTree\NestedTree   $tree                              The tree
278
 * @param array   $listFoldersLimitedKeys            Limited
279
 * @param array   $listRestrictedFoldersForItemsKeys Restricted
280
 * @param int     $last_visible_parent               Visible parent
281
 * @param int     $last_visible_parent_level         Parent level
282
 * @param array   $SETTINGS                          Teampass settings
283
 * @param array   $inputData,
284
 * @param array   $ret_json
285
 *
286
 * @return array
287
 */
288
function recursiveTree(
289
    int $nodeId,
290
    stdClass $currentNode,
291
    Tree\NestedTree\NestedTree $tree,
292
    array $listFoldersLimitedKeys,
293
    array $listRestrictedFoldersForItemsKeys,
294
    int $last_visible_parent,
295
    int $last_visible_parent_level,
296
    array $SETTINGS,
297
    array $inputData,
298
    array &$ret_json = array()
299
) {
300
    $text = '';
301
    $title = '';
302
    $show_but_block = false;
303
    
304
    // Load config
305
    include __DIR__.'/../includes/config/tp.config.php';
306
307
    $displayThisNode = false;
308
    $nbItemsInSubfolders = $nbSubfolders = $nbItemsInFolder = 0;
309
    $nodeDescendants = $tree->getDescendants($nodeId, true, false, false);
310
    
311
    foreach ($nodeDescendants as $node) {
312
        if (
313
            in_array($node->id, array_merge($inputData['personalFolders'], $inputData['visibleFolders'])) === true
314
        ) {
315
            // Final check - is PF allowed?
316
            if (
317
                (int) $node->personal_folder === 1
318
                && (int) $SETTINGS['enable_pf_feature'] === 1
319
                && in_array($node->id, $inputData['personalFolders']) === false
320
            ) {
321
                $displayThisNode = false;
322
            } else {
323
                $displayThisNode = true;
324
                $nbItemsInSubfolders = (int) $node->nb_items_in_subfolders;
325
                $nbItemsInFolder = (int) $node->nb_items_in_folder;
326
                $nbSubfolders = (int) $node->nb_subfolders;
327
                break;
328
            }
329
        }
330
    }
331
    
332
    if ($displayThisNode === true) {
333
        handleNode(
334
            (int) $nodeId,
335
            $currentNode,
336
            $tree,
337
            $listFoldersLimitedKeys,
338
            $listRestrictedFoldersForItemsKeys,
339
            $last_visible_parent,
340
            $last_visible_parent_level,
341
            $SETTINGS,
342
            $inputData,
343
            $text,
344
            $nbItemsInSubfolders,
345
            $nbSubfolders,
346
            $nbItemsInFolder,
347
            $ret_json
348
        );
349
    }
350
    
351
    return $ret_json;
352
}
353
354
/**
355
 * Permits to get the Node definition
356
 *
357
 * @param integer $nodeId
358
 * @param stdClass $currentNode
359
 * @param Tree\NestedTree\NestedTree $tree
360
 * @param array $listFoldersLimitedKeys
361
 * @param array $listRestrictedFoldersForItemsKeys
362
 * @param integer $last_visible_parent
363
 * @param integer $last_visible_parent_level
364
 * @param array $SETTINGS
365
 * @param array $inputData
366
 * @param string $text
367
 * @param integer $nbItemsInSubfolders
368
 * @param integer $nbSubfolders
369
 * @param integer $nbItemsInFolder
370
 * @param array $ret_json
371
 * @return void
372
 */
373
function handleNode(
374
    int $nodeId,
375
    stdClass $currentNode,
376
    Tree\NestedTree\NestedTree $tree,
377
    array $listFoldersLimitedKeys,
378
    array $listRestrictedFoldersForItemsKeys,
379
    int $last_visible_parent,
380
    int $last_visible_parent_level,
381
    array $SETTINGS,
382
    array $inputData,
383
    string $text,
384
    int $nbItemsInSubfolders,
385
    int $nbSubfolders,
386
    int $nbItemsInFolder,
387
    array &$ret_json = array()
388
)
389
{
390
    // If personal Folder, convert id into user name
391
    if ((int) $currentNode->title === (int) $inputData['userId'] && (int) $currentNode->nlevel === 1) {
392
        $currentNode->title = $inputData['userLogin'];
393
    }
394
395
    // Decode if needed
396
    $currentNode->title = htmlspecialchars_decode($currentNode->title, ENT_QUOTES);
397
398
    $nodeData = prepareNodeData(
399
        (int) $nodeId,
400
        $inputData['visibleFolders'],
401
        $inputData['readOnlyFolders'],
402
        $inputData['personalVisibleFolders'],
403
        (int) $nbItemsInFolder,
404
        (int) $nbItemsInSubfolders,
405
        (int) $nbSubfolders,
406
        $inputData['limitedFolders'],
407
        (int) $SETTINGS['show_only_accessible_folders'],
408
        isset($SETTINGS['tree_counters']) === true && isset($SETTINGS['enable_tasks_manager']) === true && (int) $SETTINGS['enable_tasks_manager'] === 1 && (int) $SETTINGS['tree_counters'] === 1 ? 1 : 0,
409
        (bool) $inputData['userReadOnly'],
410
        $listFoldersLimitedKeys,
411
        $listRestrictedFoldersForItemsKeys,
412
        $inputData['restrictedFoldersForItems'],
413
        $inputData['personalFolders'],
414
        $tree
415
    );
416
417
    // Prepare JSON 
418
    $tmpRetArray = prepareNodeJson(
419
        $currentNode,
420
        $nodeData,
421
        $inputData,
422
        $ret_json,
423
        $last_visible_parent,
424
        $last_visible_parent_level,
425
        $nodeId,
426
        $text,
427
        $nbSubfolders,
428
        $SETTINGS
429
    );    
430
    $last_visible_parent = $tmpRetArray['last_visible_parent'];
431
    $last_visible_parent_level = $tmpRetArray['last_visible_parent_level'];
432
    $ret_json = $tmpRetArray['ret_json'];
433
434
    // ensure we get the children of the folder
435
    if (isset($currentNode->children) === false) {
436
        $currentNode->children = $tree->getDescendants($nodeId, false, true, true);
437
    }
438
    if ($inputData['userTreeLoadStrategy'] === 'full' && isset($currentNode->children) === true) {
439
        foreach ($currentNode->children as $child) {
440
            recursiveTree(
441
                (int) $child,
442
                $tree->getNode($child),// get node info for this child
443
                /** @scrutinizer ignore-type */ $tree,
444
                $listFoldersLimitedKeys,
445
                $listRestrictedFoldersForItemsKeys,
446
                $last_visible_parent,
447
                $last_visible_parent_level,
448
                $SETTINGS,
449
                $inputData,
450
                $ret_json
451
            );
452
        }
453
    }
454
}
455
456
/**
457
 * Permits to prepare the node data
458
 *
459
 * @param stdClass $currentNode
460
 * @param array $nodeData
461
 * @param array $inputData
462
 * @param array $ret_json
463
 * @param integer $last_visible_parent
464
 * @param integer $last_visible_parent_level
465
 * @param integer $nodeId
466
 * @param string $text
467
 * @param integer $nbSubfolders
468
 * @param array $SETTINGS
469
 * @return array
470
 */
471
function prepareNodeJson(
472
    stdClass $currentNode,
473
    array $nodeData,
474
    array $inputData,
475
    array &$ret_json,
476
    int &$last_visible_parent,
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_VARIABLE, expecting T_STRING or T_NAME_QUALIFIED or T_NAME_FULLY_QUALIFIED or T_NAME_RELATIVE on line 476 at column 9
Loading history...
477
    int &$last_visible_parent_level,
478
    int $nodeId,
479
    string $text,
480
    int $nbSubfolders,
481
    array $SETTINGS
482
): array
483
{
484
    // prepare json return for current node
485
    $parent = $currentNode->parent_id === '0' ? '#' : 'li_' . $currentNode->parent_id;
486
487
    // handle displaying
488
    if (isKeyExistingAndEqual('show_only_accessible_folders', 1, $SETTINGS) === true) {
489
        if ($nodeData['hide_node'] === true) {
490
            $last_visible_parent = (int) $parent;
491
            $last_visible_parent_level = $currentNode->nlevel--;
492
        } elseif ($currentNode->nlevel < $last_visible_parent_level) {
493
            $last_visible_parent = -1;
494
        }
495
    }
496
497
    // json
498
    if ($nodeData['hide_node'] === false && $nodeData['show_but_block'] === false) {
499
        array_push(
500
            $ret_json,
501
            array(
502
                'id' => 'li_' . $nodeId,
503
                'parent' => $last_visible_parent === -1 ? $parent : $last_visible_parent,
504
                'text' => '<i class="'.$currentNode->fa_icon.' tree-folder mr-2" data-folder="'.$currentNode->fa_icon.'"  data-folder-selected="'.$currentNode->fa_icon_selected.'"></i>'.$text.$currentNode->title.$nodeData['html'],
505
                'li_attr' => array(
506
                    'class' => 'jstreeopen',
507
                    'title' => 'ID [' . $nodeId . '] ' . $nodeData['title'],
508
                ),
509
                'a_attr' => array(
510
                    'id' => 'fld_' . $nodeId,
511
                    'class' => $nodeData['folderClass'],
512
                    'onclick' => 'ListerItems(' . $nodeId . ', ' . $nodeData['restricted'] . ', 0, 1)',
513
                    'data-title' => $currentNode->title,
514
                ),
515
                'is_pf' => in_array($nodeId, $inputData['personalFolders']) === true ? 1 : 0,
516
                'can_edit' => (int) $inputData['userCanCreateRootFolder'],
517
            )
518
        );
519
        
520
        if ($inputData['userTreeLoadStrategy'] === 'sequential') {
521
            $ret_json[count($ret_json) - 1]['children'] = $nbSubfolders > 0 ? true : false;
522
        }
523
524
    } elseif ($nodeData['show_but_block'] === true) {
525
        array_push(
526
            $ret_json,
527
            array(
528
                'id' => 'li_' . $nodeId,
529
                'parent' => $last_visible_parent === -1 ? $parent : $last_visible_parent,
530
                'text' => '<i class="'.$currentNode->fa_icon.' tree-folder mr-2" data-folder="'.$currentNode->fa_icon.'"  data-folder-selected="'.$currentNode->fa_icon_selected.'"></i>'.'<i class="fas fa-times fa-xs text-danger mr-1 ml-1"></i>'.$text.$currentNode->title.$nodeData['html'],
531
                'li_attr' => array(
532
                    'class' => '',
533
                    'title' => 'ID [' . $nodeId . '] ' . langHdl('no_access'),
534
                ),
535
            )
536
        );
537
    }
538
539
    return [
540
        'last_visible_parent' => (int) $last_visible_parent,
541
        'last_visible_parent_level' => (int) $last_visible_parent_level,
542
        'ret_json' => $ret_json
543
    ];
544
}
545
546
/**
547
 * Get the context of the folder
548
 *
549
 * @param integer $nodeId
550
 * @param array $session_groupes_visibles
551
 * @param array $session_read_only_folders
552
 * @param array $session_personal_visible_groups
553
 * @param integer $nbItemsInFolder
554
 * @param integer $nbItemsInSubfolders
555
 * @param integer $nbSubfolders
556
 * @param integer $session_list_folders_limited
557
 * @param integer $show_only_accessible_folders
558
 * @param integer $tree_counters
559
 * @param bool $session_user_read_only
560
 * @param array $listFoldersLimitedKeys
561
 * @param array $listRestrictedFoldersForItemsKeys
562
 * @param array $session_list_restricted_folders_for_items
563
 * @param array $session_personal_folder
564
 * @param Tree\NestedTree\NestedTree $tree
565
 * @return array
566
 */
567
function prepareNodeData(
568
    int $nodeId,
569
    array $session_groupes_visibles,
570
    array $session_read_only_folders,
571
    array $session_personal_visible_groups,
572
    int $nbItemsInFolder,
573
    int $nbItemsInSubfolders,
574
    int $nbSubfolders,
575
    array $session_list_folders_limited,
576
    int $show_only_accessible_folders,
577
    int $tree_counters,
578
    bool $session_user_read_only,
579
    array $listFoldersLimitedKeys,
580
    array $listRestrictedFoldersForItemsKeys,
581
    array $session_list_restricted_folders_for_items,
582
    array $session_personal_folder,
583
    Tree\NestedTree\NestedTree $tree
584
): array
585
{
586
    if (in_array($nodeId, $session_groupes_visibles) === true) {
587
        // special case for READ-ONLY folder
588
        if (in_array($nodeId, $session_read_only_folders) === true) {
589
            return [
590
                'html' => '<i class="far fa-eye fa-xs mr-1 ml-1"></i>'.
591
                    ($tree_counters === 1 ? '<span class="badge badge-pill badge-light ml-2 items_count" id="itcount_' . $nodeId . '">' . $nbItemsInFolder .'/'.$nbItemsInSubfolders .'/'.$nbSubfolders. '</span>'  : ''),
592
                'title' => langHdl('read_only_account'),
593
                'restricted' => 1,
594
                'folderClass' => 'folder_not_droppable',
595
                'show_but_block' => false,
596
                'hide_node' => false,
597
                'is_pf' => in_array($nodeId, $session_personal_folder) === true ? 1 : 0,
598
            ];
599
600
        } elseif (
601
            $session_user_read_only === true
602
            && in_array($nodeId, $session_personal_visible_groups) === false
603
        ) {
604
            return [
605
                'html' => '<i class="far fa-eye fa-xs mr-1"></i>'.
606
                    ($tree_counters === 1 ? '<span class="badge badge-pill badge-light ml-2 items_count" id="itcount_' . $nodeId . '">' . $nbItemsInFolder .'/'.$nbItemsInSubfolders .'/'.$nbSubfolders. '</span>'  : ''),
607
                'title' => langHdl('read_only_account'),
608
                'restricted' => 0,
609
                'folderClass' => 'folder',
610
                'show_but_block' => false,
611
                'hide_node' => false,
612
                'is_pf' => in_array($nodeId, $session_personal_folder) === true ? 1 : 0,
613
            ];
614
        }
615
        
616
        return [
617
            'html' => ($tree_counters === 1 ? '<span class="badge badge-pill badge-light ml-2 items_count" id="itcount_' . $nodeId . '">' . $nbItemsInFolder .'/'.$nbItemsInSubfolders .'/'.$nbSubfolders. '</span>'  : ''),
618
            'title' => '',
619
            'restricted' => 0,
620
            'folderClass' => 'folder',
621
            'show_but_block' => false,
622
            'hide_node' => false,
623
            'is_pf' => in_array($nodeId, $session_personal_folder) === true ? 1 : 0,
624
        ];
625
626
    } elseif (in_array($nodeId, $listFoldersLimitedKeys) === true) {
627
        return [
628
            'html' => ($session_user_read_only === true ? '<i class="far fa-eye fa-xs mr-1"></i>' : '') .
629
                ($tree_counters === 1 ? '<span class="badge badge-pill badge-light ml-2 items_count" id="itcount_' . $nodeId . '">' . count($session_list_folders_limited[$nodeId]) . '</span>' : ''),
630
            'title' => '',
631
            'restricted' => 1,
632
            'folderClass' => 'folder',
633
            'show_but_block' => false,
634
            'hide_node' => false,
635
            'is_pf' => in_array($nodeId, $session_personal_folder) === true ? 1 : 0,
636
        ];
637
638
    } elseif (in_array($nodeId, $listRestrictedFoldersForItemsKeys) === true) {
639
        return [
640
            'html' => $session_user_read_only === true ? '<i class="far fa-eye fa-xs mr-1"></i>' : '' .
641
                '<span class="badge badge-pill badge-light ml-2 items_count" id="itcount_' . $nodeId . '">' . count($session_list_restricted_folders_for_items[$nodeId]) . '</span>',
642
            'title' => '',
643
            'restricted' => 1,
644
            'folderClass' => 'folder',
645
            'show_but_block' => false,
646
            'hide_node' => false,
647
            'is_pf' => in_array($nodeId, $session_personal_folder) === true ? 1 : 0,
648
        ];
649
650
    } elseif ((int) $nbSubfolders === 0
651
        //&& (int) $show_only_accessible_folders === 1
652
    ) {
653
        // folder should not be visible
654
        // only if it has no descendants
655
        $nodeDirectDescendants = $tree->getDescendants($nodeId, false, false, true);
656
        if (
657
            count(
658
                array_diff(
659
                    $nodeDirectDescendants,
660
                    array_merge(
661
                        $session_groupes_visibles,
662
                        array_keys($session_list_restricted_folders_for_items)
663
                    )
664
                )
665
            ) !== count($nodeDirectDescendants)
666
        ) {
667
            // show it but block it
668
            return [
669
                'html' => '',
670
                'title' => '',
671
                'restricted' => 1,
672
                'folderClass' => 'folder_not_droppable',
673
                'show_but_block' => true,
674
                'hide_node' => false,
675
                'is_pf' => in_array($nodeId, $session_personal_folder) === true ? 1 : 0,
676
            ];
677
        }
678
        
679
        // hide it
680
        return [
681
            'html' => '',
682
            'title' => '',
683
            'restricted' => 1,
684
            'folderClass' => 'folder_not_droppable',
685
            'show_but_block' => false,
686
            'hide_node' => true,
687
            'is_pf' => in_array($nodeId, $session_personal_folder) === true ? 1 : 0,
688
        ];
689
    }
690
691
    return [
692
        'html' => '',
693
        'title' => isset($title) === true ? $title : '',
694
        'restricted' => 1,
695
        'folderClass' => 'folder_not_droppable',
696
        'show_but_block' => true,
697
        'hide_node' => false,
698
        'is_pf' => in_array($nodeId, $session_personal_folder) === true ? 1 : 0,
699
    ];
700
}
701
702
703
/**
704
 * Permits to check if we can user a cache instead of loading from DB
705
 *
706
 * @param integer $lastTreeChange
707
 * @param integer $userTreeLastRefresh
708
 * @param array $userSessionTreeStructure
709
 * @param integer $userId
710
 * @param integer $forceRefresh
711
 * @param array $SETTINGS
712
 * @return array
713
 */
714
function loadTreeStrategy(
715
    int $lastTreeChange,
716
    int $userTreeLastRefresh,
717
    array $userSessionTreeStructure,
718
    int $userId,
719
    int $forceRefresh
720
): array
721
{
722
    // Case when refresh is EXPECTED / MANDATORY
723
    if ((int) $forceRefresh === 1) {
724
        return [
725
            'state' => true,
726
            'data' => [],
727
        ];
728
    }
729
730
    // Case when an update in the tree has been done
731
    // Refresh is then mandatory
732
    if ((int) $lastTreeChange > (int) $userTreeLastRefresh) {
733
        return [
734
            'state' => true,
735
            'data' => [],
736
        ];
737
    }
738
739
    // Does this user has the tree structure in session?
740
    // If yes then use it
741
    if (count($userSessionTreeStructure) > 0) {
742
        return [
743
            'state' => false,
744
            'data' => json_encode($userSessionTreeStructure),
745
        ];
746
    }
747
748
    // Does this user has a tree cache
749
    $userCacheTree = DB::queryfirstrow(
750
        'SELECT data
751
        FROM ' . prefixTable('cache_tree') . '
752
        WHERE user_id = %i',
753
        $userId
754
    );
755
    if (empty($userCacheTree['data']) === false && $userCacheTree['data'] !== '[]') {
756
        return [
757
            'state' => false,
758
            'data' => $userCacheTree['data'],
759
        ];
760
    }
761
762
    return [
763
        'state' => true,
764
        'data' => [],
765
    ];
766
}