Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
62.79% covered (warning)
62.79%
27 / 43
25.00% covered (danger)
25.00%
1 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
PermissionsStrategyAbstract
62.79% covered (warning)
62.79%
27 / 43
25.00% covered (danger)
25.00%
1 / 4
57.20
0.00% covered (danger)
0.00%
0 / 1
 arrayDiffRecursive
92.86% covered (success)
92.86%
13 / 14
0.00% covered (danger)
0.00%
0 / 1
9.03
 arrayIntersectRecursive
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
72
 isAssociative
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDeltaPermissions
81.25% covered (warning)
81.25%
13 / 16
0.00% covered (danger)
0.00%
0 / 1
7.32
1<?php
2
3/**
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; under version 2
7 * of the License (non-upgradable).
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 *
18 * Copyright (c) 2020-2023 (original work) Open Assessment Technologies SA;
19 */
20
21declare(strict_types=1);
22
23namespace oat\taoDacSimple\model;
24
25use RuntimeException;
26
27abstract class PermissionsStrategyAbstract implements PermissionsStrategyInterface
28{
29    protected function arrayDiffRecursive(array $array1, array $array2): array
30    {
31        $outputDiff = [];
32
33        if (!($this->isAssociative($array1) || $this->isAssociative($array2))) {
34            return array_values(array_diff($array1, $array2));
35        }
36
37        foreach ($array1 as $array1key => $array1value) {
38            if (array_key_exists($array1key, $array2)) {
39                if (is_array($array1value) && is_array($array2[$array1key])) {
40                    $outputDiff[$array1key] = $this->arrayDiffRecursive($array1value, $array2[$array1key]);
41                } else {
42                    throw new RuntimeException('Inconsistent data');
43                }
44            } else {
45                $outputDiff[$array1key] = $array1value;
46            }
47        }
48
49        $result = [];
50
51        foreach ($outputDiff as $i => $key) {
52            if (!empty($key)) {
53                $result[$i] = $key;
54            }
55        }
56
57        return $result;
58    }
59
60    protected function arrayIntersectRecursive(array $array1, array $array2): array
61    {
62        $return = [];
63
64        if (!($this->isAssociative($array1) || $this->isAssociative($array2))) {
65            return array_intersect($array1, $array2);
66        }
67
68        $commonKeys = array_intersect(array_keys($array1), array_keys($array2));
69
70        foreach ($commonKeys as $key) {
71            if (is_array($array1[$key]) && is_array($array2[$key])) {
72                $intersection = $this->arrayIntersectRecursive($array1[$key], $array2[$key]);
73
74                if ($intersection) {
75                    $return[$key] = $intersection;
76                }
77            } elseif ($array1[$key] === $array2[$key]) {
78                $return[$key] = $array1[$key];
79            }
80        }
81
82        return $return;
83    }
84
85    private function isAssociative(array $array): bool
86    {
87        return count(array_filter(array_keys($array), 'is_string')) > 0;
88    }
89
90    /**
91     * get the delta between existing permissions and new permissions
92     *
93     * @param array $currentPrivileges
94     * @param array $privilegesToSet associative array $user_id => $permissions
95     *
96     * @return array
97     */
98    public function getDeltaPermissions(array $currentPrivileges, array $privilegesToSet): array
99    {
100        $add = [];
101        $remove = [];
102
103        foreach ($privilegesToSet as $userId => $privilegeIds) {
104            //if privileges are in request but not in db we add then
105            if (!isset($currentPrivileges[$userId])) {
106                if ($privilegeIds) {
107                    $add[$userId] = $privilegeIds;
108                }
109            } else { // compare privileges in db and request
110                $tmp = array_values(array_diff($privilegeIds, $currentPrivileges[$userId]));
111                if ($tmp) {
112                    $add[$userId] = $tmp;
113                }
114
115                $tmp = array_values(array_diff($currentPrivileges[$userId], $privilegeIds));
116
117                if ($tmp) {
118                    $remove[$userId] = $tmp;
119                }
120                // unset already compare db variable
121                unset($currentPrivileges[$userId]);
122            }
123        }
124
125        //remaining privileges has to be removed
126        foreach ($currentPrivileges as $userId => $privilegeIds) {
127            $remove[$userId] = $privilegeIds;
128        }
129
130        return compact('remove', 'add');
131    }
132}