Passed
Push — master ( 7d22e0...478025 )
by Nils
04:17
created

getNodeInfos()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 46
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 5
eloc 22
c 4
b 0
f 0
nc 5
nop 7
dl 0
loc 46
rs 9.2568
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
 * @version   3.0.0.22
14
 * @file      tree.php
15
 *
16
 * @author    Nils Laumaillé ([email protected])
17
 * @copyright 2009-2023 Teampass.net
18
 * @license   https://spdx.org/licenses/GPL-3.0-only.html#licenseText GPL-3.0
19
 *
20
 * @see       https://www.teampass.net
21
 */
22
23
24
require_once 'SecureHandler.php';
25
session_name('teampass_session');
26
session_start();
27
if (
28
    isset($_SESSION['CPM']) === false
29
    || $_SESSION['CPM'] !== 1
30
    || isset($_SESSION['key']) === false
31
    || empty($_SESSION['key']) === true
32
) {
33
    die('Hacking attempt...');
34
}
35
36
// Load config
37
include __DIR__.'/../includes/config/tp.config.php';
38
39
// includes
40
require_once $SETTINGS['cpassman_dir'] . '/includes/config/include.php';
41
require_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php';
42
require_once $SETTINGS['cpassman_dir'] . '/includes/language/' . $_SESSION['user']['user_language'] . '.php';
43
require_once $SETTINGS['cpassman_dir'] . '/includes/config/settings.php';
44
45
// header
46
header('Content-type: text/html; charset=utf-8');
47
header('Cache-Control: no-cache, must-revalidate');
48
49
// Define Timezone
50
if (isset($SETTINGS['timezone'])) {
51
    date_default_timezone_set($SETTINGS['timezone']);
52
} else {
53
    date_default_timezone_set('UTC');
54
}
55
56
// Connect to mysql server
57
require_once $SETTINGS['cpassman_dir'] . '/includes/libraries/Database/Meekrodb/db.class.php';
58
if (defined('DB_PASSWD_CLEAR') === false) {
59
    define('DB_PASSWD_CLEAR', defuseReturnDecrypted(DB_PASSWD, $SETTINGS));
60
}
61
DB::$host = DB_HOST;
62
DB::$user = DB_USER;
63
DB::$password = DB_PASSWD_CLEAR;
64
DB::$dbName = DB_NAME;
65
DB::$port = DB_PORT;
66
DB::$encoding = DB_ENCODING;
67
DB::$ssl = DB_SSL;
68
DB::$connect_options = DB_CONNECT_OPTIONS;
69
70
// Superglobal load
71
require_once $SETTINGS['cpassman_dir'] . '/includes/libraries/protect/SuperGlobal/SuperGlobal.php';
72
$superGlobal = new protect\SuperGlobal\SuperGlobal();
73
74
// Prepare sanitization
75
$data = [
76
    'forbidenPfs' => isset($_SESSION['forbiden_pfs']) === true ? json_encode($_SESSION['forbiden_pfs']) : '{}',
77
    'visibleFolders' => isset($_SESSION['groupes_visibles']) === true ? json_encode($_SESSION['groupes_visibles']) : '{}',
78
    'userId' => isset($_SESSION['user_id']) === true ? $_SESSION['user_id'] : '',
79
    'userLogin' => isset($_SESSION['login']) === true ? $_SESSION['login'] : '',
80
    'userReadOnly' => isset($_SESSION['user_read_only']) === true ? $_SESSION['user_read_only'] : '',
81
    'limitedFolders' => isset($_SESSION['list_folders_limited']) === true ? json_encode($_SESSION['list_folders_limited']) : '{}',
82
    'readOnlyFolders' => isset($_SESSION['read_only_folders']) === true ? json_encode($_SESSION['read_only_folders']) : '{}',
83
    'personalVisibleFolders' => isset($_SESSION['personal_visible_groups']) === true ? json_encode($_SESSION['personal_visible_groups']) : '{}',
84
    'userTreeLastRefresh' => isset($_SESSION['user_tree_last_refresh_timestamp']) === true ? $_SESSION['user_tree_last_refresh_timestamp'] : '',
85
    'forceRefresh' => isset($_GET['force_refresh']) === true ? $_GET['force_refresh'] : '',
86
    'nodeId' => isset($_GET['id']) === true ? $_GET['id'] : '',
87
    'restrictedFoldersForItems' => isset($_GET['list_restricted_folders_for_items']) === true ? json_encode($_GET['list_restricted_folders_for_items']) : '{}',
88
    'noAccessFolders' => isset($_SESSION['no_access_folders']) === true ? json_encode($_SESSION['no_access_folders']) : '{}',
89
    'personalFolders' => isset($_SESSION['personal_folders']) === true ? json_encode($_SESSION['personal_folders']) : '{}',
90
    'userCanCreateRootFolder' => isset($_SESSION['can_create_root_folder']) === true ? json_encode($_SESSION['can_create_root_folder']) : '{}',
91
    'userTreeLoadStrategy' => isset($_SESSION['user']['user_treeloadstrategy']) === true ? $_SESSION['user']['user_treeloadstrategy'] : '',
92
];
93
94
$filters = [
95
    'forbidenPfs' => 'cast:array',
96
    'visibleFolders' => 'cast:array',
97
    'userId' => 'cast:integer',
98
    'userLogin' => 'trim|escape',
99
    'userReadOnly' => 'cast:boolean',
100
    'limitedFolders' => 'cast:array',
101
    'readOnlyFolders' => 'cast:array',
102
    'personalVisibleFolders' => 'cast:array',
103
    'userTreeLastRefresh' => 'cast:integer',
104
    'forceRefresh' => 'cast:integer',
105
    'nodeId' => 'cast:integer',
106
    'restrictedFoldersForItems' => 'cast:array',
107
    'noAccessFolders' => 'cast:array',
108
    'personalFolders' => 'cast:array',
109
    'userCanCreateRootFolder' => 'cast:array',
110
    'userTreeLoadStrategy' => 'trim|escape',
111
];
112
113
$inputData = dataSanitizer(
114
    $data,
115
    $filters,
116
    $SETTINGS['cpassman_dir']
117
);
118
119
$lastFolderChange = DB::queryfirstrow(
120
    'SELECT valeur FROM ' . prefixTable('misc') . '
121
    WHERE type = %s AND intitule = %s',
122
    'timestamp',
123
    'last_folder_change'
124
);
125
if (DB::count() === 0) {
126
    $lastFolderChange['valeur'] = 0;
127
}
128
129
// Should we use a cache or refresh the tree
130
$goTreeRefresh = loadTreeStrategy(
131
    (int) $lastFolderChange['valeur'],
132
    (int) $inputData['userTreeLastRefresh'],
133
    (array) (is_null($superGlobal->get('user_tree_structure', 'SESSION')) === true || empty($superGlobal->get('user_tree_structure', 'SESSION')) === true) ? [] : $superGlobal->get('user_tree_structure', 'SESSION'),
0 ignored issues
show
Bug introduced by
It seems like (array)is_null($superGlo..._structure', 'SESSION') can also be of type null; however, parameter $userSessionTreeStructure of loadTreeStrategy() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

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