Completed
Pull Request — master (#10)
by Robbert
02:03
created

GrantsTree::switchUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 5
Bugs 0 Features 1
Metric Value
c 5
b 0
f 1
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 2
crap 1
1
<?php
2
3
/*
4
 * This file is part of the Ariadne Component Library.
5
 *
6
 * (c) Muze <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
13
namespace arc\grants;
14
15
/**
16
 * Class GrantsTree
17
 * @package arc\grants
18
 */
19
final class GrantsTree
20
{
21
    use \arc\traits\Proxy {
22
        \arc\traits\Proxy::__construct as private ProxyConstruct;
23
    }
24
25
    private $tree = null;
26
    private $user   = null;
27
    private $groups = array();
28
29
    /**
30
     * @param \arc\tree\NamedNode $tree The tree storage for event listeners.
31
     * @param string $user
32
     * @param array $groups
33
     */
34 2
    public function __construct( $tree, $user, $groups = array() )
35
    {
36 2
        $this->ProxyConstruct( $tree );
37 2
        $this->tree = $tree;
38 2
        $this->user = $user;
39 2
        $this->groups = $groups;
40 2
    }
41
42
    /**
43
     * Change to a different node
44
     * @param $path
45
     * @return GrantsTree
46
     */
47 1
    public function cd($path)
48
    {
49 1
        return new GrantsTree( $this->tree->cd( $path ), $this->user );
50
    }
51
52
    /**
53
     * Switch default user to check and set grants.
54
     * @param $user
55
     * @param array $groups
56
     * @return GrantsTree this
57
     */
58 1
    public function switchUser( $user, $groups = [] )
59
    {
60 1
        return new GrantsTree( $this->tree, $user, $groups );
61
    }
62
63
    /**
64
     * Set new grants for the current user.
65
     * @param null $grants
66
     * @return GrantsTree this
67
     */
68 1
    public function set($grants = null)
69
    {
70 1
        if ( isset( $grants ) ) {
71 1
            if ( !isset($this->tree->nodeValue['users'])) {
72 1
                $this->tree->nodeValue['users'] = [];
73 1
            }
74 1
            $this->tree->nodeValue['users'][$this->user ] = ' ' . trim( $grants ) . ' ';
75 1
        } else {
76
            unset( $this->tree->nodeValue['users'][$this->user ] );
77
        }
78 1
        return $this;
79
    }
80
81
82
    /**
83
     * Deprecated. Use set() instead.
84
     * @param null $grants
85
     */
86 1
    public function setUserGrants( $grants = null ){
87 1
        $this->set($grants);
88 1
    }
89
90
    /**
91
     * Deprecated. Use setForGroup instead.
92
     * @param $group
93
     * @param null $grants
94
     */
95 1
    public function setGroupGrants( $group, $grants = null ){
96
        $this->setForGroup($group, $grants);
97 1
    }
98
99
    /**
100
     * Set new grants for the given user.
101
     * @param $user
102
     * @param null $grants
103
     * @return GrantsTree this
104
     */
105
    public function setForUser( $user, $grants = null ) {
106
        $this->switchUser($user)->set($grants);
107
        return $this;
108
    }
109
110
    /**
111
     * Set new grants for the given group.
112
     * @param $group
113
     * @param null $grants
114
     * @return GrantsTree this
115
     */
116
    public function setForGroup( $group, $grants = null ) {
117
        if ( isset( $grants ) ) {
118
            if ( !isset($this->tree->nodeValue['groups'])) {
119
                $this->tree->nodeValue['groups'] = [];
120
            }
121
            $this->tree->nodeValue['groups'][$group ] = ' ' . trim( $grants ) . ' ';
122
        } else {
123
            unset( $this->tree->nodeValue['groups'][$group ] );
124
        }
125
        return $this;
126
    }
127
128
    /**
129
     * Return the grants for the current user.
130
     * @return mixed
131
     */
132
    public function grants() {
133
        return \arc\hash::get('/users/'.$this->user.'/', $this->tree->nodeValue, '');
134
    }
135
136
    /**
137
     * Return the grants for a specific user.
138
     * @param $user
139
     * @return mixed
140
     */
141
    public function grantsForUser($user, $groups = []) {
142
        return $this->switchUser($user, $groups)->grants();
143
    }
144
145
    /**
146
     * Returns an array with the grants for all users.
147
     * @return array
148
     */
149
    public function grantsForAllUsers() {
150
        return \arc\hash::get('/users/', $this->tree->nodeValue, array() );
151
    }
152
153
    /**
154
     * Return the grants for a specific group.
155
     * @param $group
156
     * @return mixed
157
     */
158
    public function grantsForGroup($group) {
159
        return \arc\hash::get("/groups/$group/", $this->tree->nodeValue, '');
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $group instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
160
    }
161
162
    /**
163
     * Returns an array with the grants for all groups.
164
     * @return array
165
     */
166
    public function grantsForAllGroups() {
167
        return \arc\hash::get('/groups/', $this->tree->nodeValue, array() );
168
    }
169
170
    /**
171
     * @param $grant
172
     * @return bool
173
     */
174 2
    public function check($grant)
175
    {
176
        // uses strpos since it is twice as fast as preg_match for the most common cases
177 2
        $grants = $this->fetchGrants();
178
179 2
        if ( strpos( $grants, $grant.' ' ) === false ) { // exit early if no possible match is found
180 2
            return false;
181
        }
182
183 2
        return ( strpos( $grants, ' '.$grant.' ') !== false
184 2
            || strpos( $grants, ' ='.$grant.' ') !== false );
185
    }
186
187
    /**
188
     * Check grant for a specific user.
189
     * @param $user
190
     * @param $grant
191
     * @return bool
192
     */
193
    public function checkForUser($grant, $user, $groups = []) {
194
        return $this->switchUser($user, $groups)->check($grant);
195
    }
196
197
    /**
198
     * @return string
199
     */
200 2
    private function fetchGrants()
201
    {
202 2
        $user = $this->user;
203 2
        $groups = array_fill_keys( $this->groups, 1 );
204 2
        $grants = (string) \arc\tree::dive(
205 2
            $this->tree,
0 ignored issues
show
Documentation introduced by
$this->tree is of type object<arc\tree\NamedNode>, but the function expects a object<arc\tree\Node>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
206
            function ($node) use ($user) {
207 2
                if ( isset( $node->nodeValue['users'][$user] ) ) {
208 2
                    return $node->nodeValue['users'][$user];
209
                }
210 2
            },
211 2
            function ($node, $grants) use (&$user, $groups) {
212 2
                if (!$user) { // don't do this for user grants the first time
213 1
                    $grants = preg_replace(
214 1
                        array( '/\=[^ ]*/', '/\>([^ ]*)/' ),
215 1
                        array( '', '$1' ),
216
                        $grants
217 1
                    );
218 1
                }
219 2
                $user = false;
220 2
                foreach ($groups as $group) {
221
                    if ( isset( $node->nodeValue['groups'][$group] ) ) {
222
                        $grants .= $node->nodeValue['groups'][$group];
223
                    }
224 2
                }
225
226 2
                return $grants;
227
            }
228 2
        );
229
230 2
        return $grants;
231
    }
232
}
233