Completed
Push — 6.3 ( 27f2b3...4e06bb )
by
unknown
20:25
created

Role   F

Complexity

Total Complexity 85

Size/Duplication

Total Lines 845
Duplicated Lines 6.63 %

Coupling/Cohesion

Components 1
Dependencies 30

Importance

Changes 3
Bugs 3 Features 0
Metric Value
wmc 85
c 3
b 3
f 0
lcom 1
cbo 30
dl 56
loc 845
rs 1.0434

31 Methods

Rating   Name   Duplication   Size   Complexity  
C createRole() 0 46 8
B createRoleDraft() 0 18 5
A updateRoleDraft() 0 20 2
A deleteRoleDraft() 0 8 1
A deletePolicies() 0 10 2
B addPolicy() 0 31 3
B addPolicyByRoleDraft() 0 24 2
A getLastAddedPolicy() 0 13 3
C updatePolicy() 24 43 8
B updatePolicyByRoleDraft() 12 25 4
C deletePolicy() 0 40 8
A removePolicyByRoleDraft() 20 20 4
A publishRoleDraft() 0 17 2
A __construct() 0 9 1
C listRoles() 0 23 7
A loadRole() 0 4 1
A loadRoleDraft() 0 11 2
A updateRole() 0 14 1
A deleteRole() 0 8 1
A loadPolicies() 0 6 1
A loadPolicy() 0 11 3
A assignRoleToUser() 0 22 2
B assignRoleToUserGroup() 0 25 2
A unassignRoleFromUser() 0 11 1
A unassignRoleFromUserGroup() 0 13 1
A loadRoleAssignmentsForUser() 0 8 1
A loadRoleAssignmentsForUserGroup() 0 10 1
A loadRoleAssignmentForUser() 0 13 3
A loadRoleAssignmentForUserGroup() 0 15 3
A listPoliciesForUser() 0 9 1
A mapToUpdateStruct() 0 8 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Role often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Role, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * File containing the Role controller class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 *
9
 * @version //autogentag//
10
 */
11
namespace eZ\Publish\Core\REST\Server\Controller;
12
13
use eZ\Publish\API\Repository\Exceptions\LimitationValidationException;
14
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
15
use eZ\Publish\Core\Base\Exceptions\ForbiddenException;
16
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException;
17
use eZ\Publish\Core\Base\Exceptions\UnauthorizedException;
18
use eZ\Publish\Core\REST\Common\Message;
19
use eZ\Publish\Core\REST\Common\Exceptions;
20
use eZ\Publish\Core\REST\Server\Exceptions\BadRequestException;
21
use eZ\Publish\Core\REST\Server\Values;
22
use eZ\Publish\Core\REST\Server\Controller as RestController;
23
use eZ\Publish\API\Repository\RoleService;
24
use eZ\Publish\API\Repository\UserService;
25
use eZ\Publish\API\Repository\LocationService;
26
use eZ\Publish\API\Repository\Values\User\RoleCreateStruct;
27
use eZ\Publish\API\Repository\Values\User\RoleUpdateStruct;
28
use eZ\Publish\API\Repository\Exceptions\NotFoundException as APINotFoundException;
29
use Symfony\Component\HttpFoundation\Request;
30
31
/**
32
 * Role controller.
33
 */
34
class Role extends RestController
35
{
36
    /**
37
     * Role service.
38
     *
39
     * @var \eZ\Publish\API\Repository\RoleService
40
     */
41
    protected $roleService;
42
43
    /**
44
     * User service.
45
     *
46
     * @var \eZ\Publish\API\Repository\UserService
47
     */
48
    protected $userService;
49
50
    /**
51
     * Location service.
52
     *
53
     * @var \eZ\Publish\API\Repository\LocationService
54
     */
55
    protected $locationService;
56
57
    /**
58
     * Construct controller.
59
     *
60
     * @param \eZ\Publish\API\Repository\RoleService $roleService
61
     * @param \eZ\Publish\API\Repository\UserService $userService
62
     * @param \eZ\Publish\API\Repository\LocationService $locationService
63
     */
64
    public function __construct(
65
        RoleService $roleService,
66
        UserService $userService,
67
        LocationService $locationService
68
    ) {
69
        $this->roleService = $roleService;
70
        $this->userService = $userService;
71
        $this->locationService = $locationService;
72
    }
73
74
    /**
75
     * Create new role.
76
     *
77
     * Defaults to publishing the role, but you can create a draft instead by setting the POST parameter publish=false
78
     *
79
     * @return \eZ\Publish\Core\REST\Server\Values\CreatedRole
80
     */
81
    public function createRole(Request $request)
82
    {
83
        $publish = (
84
            !$request->query->has('publish') ||
85
            ($request->query->has('publish') && $request->query->get('publish') === 'true')
86
        );
87
88
        try {
89
            $roleDraft = $this->roleService->createRole(
90
                $this->inputDispatcher->parse(
0 ignored issues
show
Compatibility introduced by
$this->inputDispatcher->...request->getContent())) of type object<eZ\Publish\API\Re...ory\Values\ValueObject> is not a sub-type of object<eZ\Publish\API\Re...\User\RoleCreateStruct>. It seems like you assume a child class of the class eZ\Publish\API\Repository\Values\ValueObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
91
                    new Message(
92
                        [
93
                            'Content-Type' => $request->headers->get('Content-Type'),
94
                            // @todo Needs refactoring! Temporary solution so parser has access to get parameters
95
                            '__publish' => $publish,
96
                        ],
97
                        $request->getContent()
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, eZ\Publish\Core\REST\Common\Message::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
98
                    )
99
                )
100
            );
101
        } catch (InvalidArgumentException $e) {
102
            throw new ForbiddenException($e->getMessage());
103
        } catch (UnauthorizedException $e) {
104
            throw new ForbiddenException($e->getMessage());
105
        } catch (LimitationValidationException $e) {
106
            throw new BadRequestException($e->getMessage());
107
        } catch (Exceptions\Parser $e) {
108
            throw new BadRequestException($e->getMessage());
109
        }
110
111
        if ($publish) {
112
            @trigger_error(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
113
                "Create and publish role in the same operation is deprecated, and will be removed in the future.\n" .
114
                'Instead, publish the role draft using Role::publishRoleDraft().',
115
                E_USER_DEPRECATED
116
            );
117
118
            $this->roleService->publishRoleDraft($roleDraft);
119
120
            $role = $this->roleService->loadRole($roleDraft->id);
0 ignored issues
show
Documentation introduced by
The property $id is declared protected in eZ\Publish\API\Repository\Values\User\Role. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
121
122
            return new Values\CreatedRole(['role' => new Values\RestRole($role)]);
123
        }
124
125
        return new Values\CreatedRole(['role' => new Values\RestRole($roleDraft)]);
126
    }
127
128
    /**
129
     * Creates a new RoleDraft for an existing Role.
130
     *
131
     * @since 6.2
132
     *
133
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException if the Role already has a Role Draft that will need to be removed first,
134
     *                                                                  or if the authenticated user is not allowed to create a role
135
     * @throws \eZ\Publish\Core\REST\Server\Exceptions\BadRequestException if a policy limitation in the $roleCreateStruct is not valid
136
     *
137
     * @return \eZ\Publish\Core\REST\Server\Values\CreatedRole
138
     */
139
    public function createRoleDraft($roleId, Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
140
    {
141
        try {
142
            $roleDraft = $this->roleService->createRoleDraft(
143
                $this->roleService->loadRole($roleId)
144
            );
145
        } catch (InvalidArgumentException $e) {
146
            throw new ForbiddenException($e->getMessage());
147
        } catch (UnauthorizedException $e) {
148
            throw new ForbiddenException($e->getMessage());
149
        } catch (LimitationValidationException $e) {
150
            throw new BadRequestException($e->getMessage());
151
        } catch (Exceptions\Parser $e) {
152
            throw new BadRequestException($e->getMessage());
153
        }
154
155
        return new Values\CreatedRole(['role' => new Values\RestRole($roleDraft)]);
156
    }
157
158
    /**
159
     * Loads list of roles.
160
     *
161
     * @return \eZ\Publish\Core\REST\Server\Values\RoleList
162
     */
163
    public function listRoles(Request $request)
164
    {
165
        $roles = array();
166
        if ($request->query->has('identifier')) {
167
            try {
168
                $role = $this->roleService->loadRoleByIdentifier($request->query->get('identifier'));
169
                $roles[] = $role;
170
            } catch (APINotFoundException $e) {
171
                // Do nothing
172
            }
173
        } else {
174
            $offset = $request->query->has('offset') ? (int)$request->query->get('offset') : 0;
175
            $limit = $request->query->has('limit') ? (int)$request->query->get('limit') : -1;
176
177
            $roles = array_slice(
178
                $this->roleService->loadRoles(),
179
                $offset >= 0 ? $offset : 0,
180
                $limit >= 0 ? $limit : null
181
            );
182
        }
183
184
        return new Values\RoleList($roles, $request->getPathInfo());
185
    }
186
187
    /**
188
     * Loads role.
189
     *
190
     * @param $roleId
191
     *
192
     * @return \eZ\Publish\API\Repository\Values\User\Role
193
     */
194
    public function loadRole($roleId)
195
    {
196
        return $this->roleService->loadRole($roleId);
197
    }
198
199
    /**
200
     * Loads a role draft.
201
     *
202
     * @param mixed $roleId Original role ID, or ID of the role draft itself
203
     *
204
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
205
     */
206
    public function loadRoleDraft($roleId)
207
    {
208
        try {
209
            // First try to load the draft for given role.
210
            return $this->roleService->loadRoleDraftByRoleId($roleId);
211
        } catch (NotFoundException $e) {
212
            // We might want a newly created role, so try to load it by its ID.
213
            // loadRoleDraft() might throw a NotFoundException (wrong $roleId). If so, let it bubble up.
214
            return $this->roleService->loadRoleDraft($roleId);
215
        }
216
    }
217
218
    /**
219
     * Updates a role.
220
     *
221
     * @param $roleId
222
     *
223
     * @return \eZ\Publish\API\Repository\Values\User\Role
224
     */
225
    public function updateRole($roleId, Request $request)
226
    {
227
        $createStruct = $this->inputDispatcher->parse(
228
            new Message(
229
                array('Content-Type' => $request->headers->get('Content-Type')),
230
                $request->getContent()
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, eZ\Publish\Core\REST\Common\Message::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
231
            )
232
        );
233
234
        return $this->roleService->updateRole(
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...leService::updateRole() has been deprecated with message: since 6.0, use {@see updateRoleDraft}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
235
            $this->roleService->loadRole($roleId),
236
            $this->mapToUpdateStruct($createStruct)
0 ignored issues
show
Compatibility introduced by
$createStruct of type object<eZ\Publish\API\Re...ory\Values\ValueObject> is not a sub-type of object<eZ\Publish\API\Re...\User\RoleCreateStruct>. It seems like you assume a child class of the class eZ\Publish\API\Repository\Values\ValueObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
237
        );
238
    }
239
240
    /**
241
     * Updates a role draft.
242
     *
243
     * @param mixed $roleId Original role ID, or ID of the role draft itself
244
     *
245
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
246
     */
247
    public function updateRoleDraft($roleId, Request $request)
248
    {
249
        $createStruct = $this->inputDispatcher->parse(
250
            new Message(
251
                array('Content-Type' => $request->headers->get('Content-Type')),
252
                $request->getContent()
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, eZ\Publish\Core\REST\Common\Message::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
253
            )
254
        );
255
256
        try {
257
            // First try to load the draft for given role.
258
            $roleDraft = $this->roleService->loadRoleDraftByRoleId($roleId);
259
        } catch (NotFoundException $e) {
260
            // We might want a newly created role, so try to load it by its ID.
261
            // loadRoleDraft() might throw a NotFoundException (wrong $roleId). If so, let it bubble up.
262
            $roleDraft = $this->roleService->loadRoleDraft($roleId);
263
        }
264
265
        return $this->roleService->updateRoleDraft($roleDraft, $this->mapToUpdateStruct($createStruct));
0 ignored issues
show
Compatibility introduced by
$createStruct of type object<eZ\Publish\API\Re...ory\Values\ValueObject> is not a sub-type of object<eZ\Publish\API\Re...\User\RoleCreateStruct>. It seems like you assume a child class of the class eZ\Publish\API\Repository\Values\ValueObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
266
    }
267
268
    /**
269
     * Publishes a role draft.
270
     *
271
     * @param mixed $roleId Original role ID, or ID of the role draft itself
272
     *
273
     * @return \eZ\Publish\Core\REST\Server\Values\PublishedRole
274
     */
275
    public function publishRoleDraft($roleId)
276
    {
277
        try {
278
            // First try to load the draft for given role.
279
            $roleDraft = $this->roleService->loadRoleDraftByRoleId($roleId);
280
        } catch (NotFoundException $e) {
281
            // We might want a newly created role, so try to load it by its ID.
282
            // loadRoleDraft() might throw a NotFoundException (wrong $roleId). If so, let it bubble up.
283
            $roleDraft = $this->roleService->loadRoleDraft($roleId);
284
        }
285
286
        $this->roleService->publishRoleDraft($roleDraft);
287
288
        $role = $this->roleService->loadRole($roleId);
289
290
        return new Values\PublishedRole(['role' => new Values\RestRole($role)]);
291
    }
292
293
    /**
294
     * Delete a role by ID.
295
     *
296
     * @param $roleId
297
     *
298
     * @return \eZ\Publish\Core\REST\Server\Values\NoContent
299
     */
300
    public function deleteRole($roleId)
301
    {
302
        $this->roleService->deleteRole(
303
            $this->roleService->loadRole($roleId)
304
        );
305
306
        return new Values\NoContent();
307
    }
308
309
    /**
310
     * Delete a role draft by ID.
311
     *
312
     * @since 6.2
313
     *
314
     * @param $roleId
315
     *
316
     * @return \eZ\Publish\Core\REST\Server\Values\NoContent
317
     */
318
    public function deleteRoleDraft($roleId)
319
    {
320
        $this->roleService->deleteRoleDraft(
321
            $this->roleService->loadRoleDraft($roleId)
322
        );
323
324
        return new Values\NoContent();
325
    }
326
327
    /**
328
     * Loads the policies for the role.
329
     *
330
     * @param $roleId
331
     *
332
     * @return \eZ\Publish\Core\REST\Server\Values\PolicyList
333
     */
334
    public function loadPolicies($roleId, Request $request)
335
    {
336
        $loadedRole = $this->roleService->loadRole($roleId);
337
338
        return new Values\PolicyList($loadedRole->getPolicies(), $request->getPathInfo());
339
    }
340
341
    /**
342
     * Deletes all policies from a role.
343
     *
344
     * @param $roleId
345
     *
346
     * @return \eZ\Publish\Core\REST\Server\Values\NoContent
347
     */
348
    public function deletePolicies($roleId)
349
    {
350
        $loadedRole = $this->roleService->loadRole($roleId);
351
352
        foreach ($loadedRole->getPolicies() as $policy) {
353
            $this->roleService->deletePolicy($policy);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...Service::deletePolicy() has been deprecated with message: since 6.0, use {@link removePolicyByRoleDraft()} instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
354
        }
355
356
        return new Values\NoContent();
357
    }
358
359
    /**
360
     * Loads a policy.
361
     *
362
     * @param $roleId
363
     * @param $policyId
364
     *
365
     * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException
366
     *
367
     * @return \eZ\Publish\API\Repository\Values\User\Policy
368
     */
369
    public function loadPolicy($roleId, $policyId, Request $request)
370
    {
371
        $loadedRole = $this->roleService->loadRole($roleId);
372
        foreach ($loadedRole->getPolicies() as $policy) {
373
            if ($policy->id == $policyId) {
374
                return $policy;
375
            }
376
        }
377
378
        throw new Exceptions\NotFoundException("Policy not found: '{$request->getPathInfo()}'.");
379
    }
380
381
    /**
382
     * Adds a policy to role.
383
     *
384
     * @param $roleId int ID of a role or a role draft
385
     *
386
     * @return \eZ\Publish\Core\REST\Server\Values\CreatedPolicy
387
     */
388
    public function addPolicy($roleId, Request $request)
389
    {
390
        $createStruct = $this->inputDispatcher->parse(
391
            new Message(
392
                array('Content-Type' => $request->headers->get('Content-Type')),
393
                $request->getContent()
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, eZ\Publish\Core\REST\Common\Message::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
394
            )
395
        );
396
397
        try {
398
            // First try to treat $roleId as a role draft ID.
399
            $role = $this->roleService->addPolicyByRoleDraft(
400
                $this->roleService->loadRoleDraft($roleId),
401
                $createStruct
0 ignored issues
show
Compatibility introduced by
$createStruct of type object<eZ\Publish\API\Re...ory\Values\ValueObject> is not a sub-type of object<eZ\Publish\API\Re...ser\PolicyCreateStruct>. It seems like you assume a child class of the class eZ\Publish\API\Repository\Values\ValueObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
402
            );
403
        } catch (NotFoundException $e) {
404
            // Then try to treat $roleId as a role ID.
405
            $role = $this->roleService->addPolicy(
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\RoleService::addPolicy() has been deprecated with message: since 6.0, use {@see addPolicyByRoleDraft}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
406
                $this->roleService->loadRole($roleId),
407
                $createStruct
0 ignored issues
show
Compatibility introduced by
$createStruct of type object<eZ\Publish\API\Re...ory\Values\ValueObject> is not a sub-type of object<eZ\Publish\API\Re...ser\PolicyCreateStruct>. It seems like you assume a child class of the class eZ\Publish\API\Repository\Values\ValueObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
408
            );
409
        } catch (LimitationValidationException $e) {
410
            throw new BadRequestException($e->getMessage());
411
        }
412
413
        return new Values\CreatedPolicy(
414
            array(
415
                'policy' => $this->getLastAddedPolicy($role),
416
            )
417
        );
418
    }
419
420
    /**
421
     * Adds a policy to a role draft.
422
     *
423
     * @since 6.2
424
     * @deprecated since 6.3, use {@see addPolicy}
425
     *
426
     * @param $roleId
427
     *
428
     * @return \eZ\Publish\Core\REST\Server\Values\CreatedPolicy
429
     */
430
    public function addPolicyByRoleDraft($roleId, Request $request)
431
    {
432
        $createStruct = $this->inputDispatcher->parse(
433
            new Message(
434
                array('Content-Type' => $request->headers->get('Content-Type')),
435
                $request->getContent()
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, eZ\Publish\Core\REST\Common\Message::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
436
            )
437
        );
438
439
        try {
440
            $role = $this->roleService->addPolicyByRoleDraft(
441
                $this->roleService->loadRoleDraft($roleId),
442
                $createStruct
0 ignored issues
show
Compatibility introduced by
$createStruct of type object<eZ\Publish\API\Re...ory\Values\ValueObject> is not a sub-type of object<eZ\Publish\API\Re...ser\PolicyCreateStruct>. It seems like you assume a child class of the class eZ\Publish\API\Repository\Values\ValueObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
443
            );
444
        } catch (LimitationValidationException $e) {
445
            throw new BadRequestException($e->getMessage());
446
        }
447
448
        return new Values\CreatedPolicy(
449
            array(
450
                'policy' => $this->getLastAddedPolicy($role),
451
            )
452
        );
453
    }
454
455
    /**
456
     * Get the last added policy for $role.
457
     *
458
     * This is needed because the RoleService addPolicy() and addPolicyByRoleDraft() methods return the role,
459
     * not the policy.
460
     *
461
     * @param $role \eZ\Publish\API\Repository\Values\User\Role
462
     *
463
     * @return \eZ\Publish\API\Repository\Values\User\Policy
464
     */
465
    private function getLastAddedPolicy($role)
466
    {
467
        $policies = $role->getPolicies();
468
469
        $policyToReturn = $policies[0];
470
        for ($i = 1, $count = count($policies); $i < $count; ++$i) {
471
            if ($policies[$i]->id > $policyToReturn->id) {
472
                $policyToReturn = $policies[$i];
473
            }
474
        }
475
476
        return $policyToReturn;
477
    }
478
479
    /**
480
     * Updates a policy.
481
     *
482
     * @param $roleId int ID of a role or a role draft
483
     * @param $policyId int ID of a policy
484
     *
485
     * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException
486
     *
487
     * @return \eZ\Publish\API\Repository\Values\User\Policy
488
     */
489
    public function updatePolicy($roleId, $policyId, Request $request)
490
    {
491
        $updateStruct = $this->inputDispatcher->parse(
492
            new Message(
493
                array('Content-Type' => $request->headers->get('Content-Type')),
494
                $request->getContent()
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, eZ\Publish\Core\REST\Common\Message::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
495
            )
496
        );
497
498
        try {
499
            // First try to treat $roleId as a role draft ID.
500
            $role = $this->roleService->loadRoleDraft($roleId);
501 View Code Duplication
            foreach ($role->getPolicies() as $policy) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
502
                if ($policy->id == $policyId) {
503
                    try {
504
                        return $this->roleService->updatePolicy(
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...Service::updatePolicy() has been deprecated with message: since 6.0, use {@link updatePolicyByRoleDraft()} instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
505
                            $policy,
506
                            $updateStruct
0 ignored issues
show
Compatibility introduced by
$updateStruct of type object<eZ\Publish\API\Re...ory\Values\ValueObject> is not a sub-type of object<eZ\Publish\API\Re...ser\PolicyUpdateStruct>. It seems like you assume a child class of the class eZ\Publish\API\Repository\Values\ValueObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
507
                        );
508
                    } catch (LimitationValidationException $e) {
509
                        throw new BadRequestException($e->getMessage());
510
                    }
511
                }
512
            }
513
        } catch (NotFoundException $e) {
514
            // Then try to treat $roleId as a role ID.
515
            $role = $this->roleService->loadRole($roleId);
516 View Code Duplication
            foreach ($role->getPolicies() as $policy) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
517
                if ($policy->id == $policyId) {
518
                    try {
519
                        return $this->roleService->updatePolicy(
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...Service::updatePolicy() has been deprecated with message: since 6.0, use {@link updatePolicyByRoleDraft()} instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
520
                            $policy,
521
                            $updateStruct
0 ignored issues
show
Compatibility introduced by
$updateStruct of type object<eZ\Publish\API\Re...ory\Values\ValueObject> is not a sub-type of object<eZ\Publish\API\Re...ser\PolicyUpdateStruct>. It seems like you assume a child class of the class eZ\Publish\API\Repository\Values\ValueObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
522
                        );
523
                    } catch (LimitationValidationException $e) {
524
                        throw new BadRequestException($e->getMessage());
525
                    }
526
                }
527
            }
528
        }
529
530
        throw new Exceptions\NotFoundException("Policy not found: '{$request->getPathInfo()}'.");
531
    }
532
533
    /**
534
     * Updates a policy.
535
     *
536
     * @since 6.2
537
     * @deprecated since 6.3, use {@see updatePolicy}
538
     *
539
     * @param $roleId
540
     * @param $policyId
541
     *
542
     * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException
543
     *
544
     * @return \eZ\Publish\API\Repository\Values\User\Policy
545
     */
546
    public function updatePolicyByRoleDraft($roleId, $policyId, Request $request)
547
    {
548
        $updateStruct = $this->inputDispatcher->parse(
549
            new Message(
550
                array('Content-Type' => $request->headers->get('Content-Type')),
551
                $request->getContent()
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, eZ\Publish\Core\REST\Common\Message::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
552
            )
553
        );
554
555
        $role = $this->roleService->loadRoleDraft($roleId);
556 View Code Duplication
        foreach ($role->getPolicies() as $policy) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
557
            if ($policy->id == $policyId) {
558
                try {
559
                    return $this->roleService->updatePolicy(
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...Service::updatePolicy() has been deprecated with message: since 6.0, use {@link updatePolicyByRoleDraft()} instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
560
                        $policy,
561
                        $updateStruct
0 ignored issues
show
Compatibility introduced by
$updateStruct of type object<eZ\Publish\API\Re...ory\Values\ValueObject> is not a sub-type of object<eZ\Publish\API\Re...ser\PolicyUpdateStruct>. It seems like you assume a child class of the class eZ\Publish\API\Repository\Values\ValueObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
562
                    );
563
                } catch (LimitationValidationException $e) {
564
                    throw new BadRequestException($e->getMessage());
565
                }
566
            }
567
        }
568
569
        throw new Exceptions\NotFoundException("Policy not found: '{$request->getPathInfo()}'.");
570
    }
571
572
    /**
573
     * Delete a policy from role.
574
     *
575
     * @param $roleId int ID of a role or a role draft
576
     * @param $policyId int ID of a policy
577
     *
578
     * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException
579
     *
580
     * @return \eZ\Publish\Core\REST\Server\Values\NoContent
581
     */
582
    public function deletePolicy($roleId, $policyId, Request $request)
583
    {
584
        try {
585
            // First try to treat $roleId as a role draft ID.
586
            $roleDraft = $this->roleService->loadRoleDraft($roleId);
587
588
            $policy = null;
589
            foreach ($roleDraft->getPolicies() as $rolePolicy) {
590
                if ($rolePolicy->id == $policyId) {
591
                    $policy = $rolePolicy;
592
                    break;
593
                }
594
            }
595
596
            if ($policy !== null) {
597
                $this->roleService->removePolicyByRoleDraft($roleDraft, $policy);
0 ignored issues
show
Compatibility introduced by
$policy of type object<eZ\Publish\API\Re...ory\Values\User\Policy> is not a sub-type of object<eZ\Publish\API\Re...alues\User\PolicyDraft>. It seems like you assume a child class of the class eZ\Publish\API\Repository\Values\User\Policy to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
598
599
                return new Values\NoContent();
600
            }
601
        } catch (NotFoundException $e) {
602
            // Then try to treat $roleId as a role ID.
603
            $role = $this->roleService->loadRole($roleId);
604
605
            $policy = null;
606
            foreach ($role->getPolicies() as $rolePolicy) {
607
                if ($rolePolicy->id == $policyId) {
608
                    $policy = $rolePolicy;
609
                    break;
610
                }
611
            }
612
613
            if ($policy !== null) {
614
                $this->roleService->deletePolicy($policy);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...Service::deletePolicy() has been deprecated with message: since 6.0, use {@link removePolicyByRoleDraft()} instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
615
616
                return new Values\NoContent();
617
            }
618
        }
619
620
        throw new Exceptions\NotFoundException("Policy not found: '{$request->getPathInfo()}'.");
621
    }
622
623
    /**
624
     * Remove a policy from a role draft.
625
     *
626
     * @since 6.2
627
     * @deprecated since 6.3, use {@see deletePolicy}
628
     *
629
     * @param $roleId
630
     * @param $policyId
631
     *
632
     * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException
633
     *
634
     * @return \eZ\Publish\Core\REST\Server\Values\NoContent
635
     */
636 View Code Duplication
    public function removePolicyByRoleDraft($roleId, $policyId, Request $request)
637
    {
638
        $roleDraft = $this->roleService->loadRoleDraft($roleId);
639
640
        $policy = null;
641
        foreach ($roleDraft->getPolicies() as $rolePolicy) {
642
            if ($rolePolicy->id == $policyId) {
643
                $policy = $rolePolicy;
644
                break;
645
            }
646
        }
647
648
        if ($policy !== null) {
649
            $this->roleService->removePolicyByRoleDraft($roleDraft, $policy);
0 ignored issues
show
Compatibility introduced by
$policy of type object<eZ\Publish\API\Re...ory\Values\User\Policy> is not a sub-type of object<eZ\Publish\API\Re...alues\User\PolicyDraft>. It seems like you assume a child class of the class eZ\Publish\API\Repository\Values\User\Policy to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
650
651
            return new Values\NoContent();
652
        }
653
654
        throw new Exceptions\NotFoundException("Policy not found: '{$request->getPathInfo()}'.");
655
    }
656
657
    /**
658
     * Assigns role to user.
659
     *
660
     * @param $userId
661
     *
662
     * @return \eZ\Publish\Core\REST\Server\Values\RoleAssignmentList
663
     */
664
    public function assignRoleToUser($userId, Request $request)
665
    {
666
        $roleAssignment = $this->inputDispatcher->parse(
667
            new Message(
668
                array('Content-Type' => $request->headers->get('Content-Type')),
669
                $request->getContent()
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, eZ\Publish\Core\REST\Common\Message::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
670
            )
671
        );
672
673
        $user = $this->userService->loadUser($userId);
674
        $role = $this->roleService->loadRole($roleAssignment->roleId);
0 ignored issues
show
Documentation introduced by
The property roleId does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
675
676
        try {
677
            $this->roleService->assignRoleToUser($role, $user, $roleAssignment->limitation);
0 ignored issues
show
Documentation introduced by
The property limitation does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
678
        } catch (LimitationValidationException $e) {
679
            throw new BadRequestException($e->getMessage());
680
        }
681
682
        $roleAssignments = $this->roleService->getRoleAssignmentsForUser($user);
683
684
        return new Values\RoleAssignmentList($roleAssignments, $user->id);
685
    }
686
687
    /**
688
     * Assigns role to user group.
689
     *
690
     * @param $groupPath
691
     *
692
     * @return \eZ\Publish\Core\REST\Server\Values\RoleAssignmentList
693
     */
694
    public function assignRoleToUserGroup($groupPath, Request $request)
695
    {
696
        $roleAssignment = $this->inputDispatcher->parse(
697
            new Message(
698
                array('Content-Type' => $request->headers->get('Content-Type')),
699
                $request->getContent()
0 ignored issues
show
Bug introduced by
It seems like $request->getContent() targeting Symfony\Component\HttpFo...n\Request::getContent() can also be of type resource; however, eZ\Publish\Core\REST\Common\Message::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
700
            )
701
        );
702
703
        $groupLocationParts = explode('/', $groupPath);
704
        $groupLocation = $this->locationService->loadLocation(array_pop($groupLocationParts));
705
        $userGroup = $this->userService->loadUserGroup($groupLocation->contentId);
706
707
        $role = $this->roleService->loadRole($roleAssignment->roleId);
0 ignored issues
show
Documentation introduced by
The property roleId does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
708
709
        try {
710
            $this->roleService->assignRoleToUserGroup($role, $userGroup, $roleAssignment->limitation);
0 ignored issues
show
Documentation introduced by
The property limitation does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
711
        } catch (LimitationValidationException $e) {
712
            throw new BadRequestException($e->getMessage());
713
        }
714
715
        $roleAssignments = $this->roleService->getRoleAssignmentsForUserGroup($userGroup);
716
717
        return new Values\RoleAssignmentList($roleAssignments, $groupPath, true);
718
    }
719
720
    /**
721
     * Un-assigns role from user.
722
     *
723
     * @param $userId
724
     * @param $roleId
725
     *
726
     * @return \eZ\Publish\Core\REST\Server\Values\RoleAssignmentList
727
     */
728
    public function unassignRoleFromUser($userId, $roleId)
729
    {
730
        $user = $this->userService->loadUser($userId);
731
        $role = $this->roleService->loadRole($roleId);
732
733
        $this->roleService->unassignRoleFromUser($role, $user);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...:unassignRoleFromUser() has been deprecated with message: since 6.0, use {@see removeRoleAssignment} instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
734
735
        $roleAssignments = $this->roleService->getRoleAssignmentsForUser($user);
736
737
        return new Values\RoleAssignmentList($roleAssignments, $user->id);
738
    }
739
740
    /**
741
     * Un-assigns role from user group.
742
     *
743
     * @param $groupPath
744
     * @param $roleId
745
     *
746
     * @return \eZ\Publish\Core\REST\Server\Values\RoleAssignmentList
747
     */
748
    public function unassignRoleFromUserGroup($groupPath, $roleId)
749
    {
750
        $groupLocationParts = explode('/', $groupPath);
751
        $groupLocation = $this->locationService->loadLocation(array_pop($groupLocationParts));
752
        $userGroup = $this->userService->loadUserGroup($groupLocation->contentId);
753
754
        $role = $this->roleService->loadRole($roleId);
755
        $this->roleService->unassignRoleFromUserGroup($role, $userGroup);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...signRoleFromUserGroup() has been deprecated with message: since 6.0, use {@see removeRoleAssignment} instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
756
757
        $roleAssignments = $this->roleService->getRoleAssignmentsForUserGroup($userGroup);
758
759
        return new Values\RoleAssignmentList($roleAssignments, $groupPath, true);
760
    }
761
762
    /**
763
     * Loads role assignments for user.
764
     *
765
     * @param $userId
766
     *
767
     * @return \eZ\Publish\Core\REST\Server\Values\RoleAssignmentList
768
     */
769
    public function loadRoleAssignmentsForUser($userId)
770
    {
771
        $user = $this->userService->loadUser($userId);
772
773
        $roleAssignments = $this->roleService->getRoleAssignmentsForUser($user);
774
775
        return new Values\RoleAssignmentList($roleAssignments, $user->id);
776
    }
777
778
    /**
779
     * Loads role assignments for user group.
780
     *
781
     * @param $groupPath
782
     *
783
     * @return \eZ\Publish\Core\REST\Server\Values\RoleAssignmentList
784
     */
785
    public function loadRoleAssignmentsForUserGroup($groupPath)
786
    {
787
        $groupLocationParts = explode('/', $groupPath);
788
        $groupLocation = $this->locationService->loadLocation(array_pop($groupLocationParts));
789
        $userGroup = $this->userService->loadUserGroup($groupLocation->contentId);
790
791
        $roleAssignments = $this->roleService->getRoleAssignmentsForUserGroup($userGroup);
792
793
        return new Values\RoleAssignmentList($roleAssignments, $groupPath, true);
794
    }
795
796
    /**
797
     * Returns a role assignment to the given user.
798
     *
799
     * @param $userId
800
     * @param $roleId
801
     *
802
     * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException
803
     *
804
     * @return \eZ\Publish\Core\REST\Server\Values\RestUserRoleAssignment
805
     */
806
    public function loadRoleAssignmentForUser($userId, $roleId, Request $request)
807
    {
808
        $user = $this->userService->loadUser($userId);
809
        $roleAssignments = $this->roleService->getRoleAssignmentsForUser($user);
810
811
        foreach ($roleAssignments as $roleAssignment) {
812
            if ($roleAssignment->getRole()->id == $roleId) {
813
                return new Values\RestUserRoleAssignment($roleAssignment, $userId);
0 ignored issues
show
Bug introduced by
It seems like $roleAssignment defined by $roleAssignment on line 811 can also be of type object<eZ\Publish\API\Re...serGroupRoleAssignment>; however, eZ\Publish\Core\REST\Ser...signment::__construct() does only seem to accept object<eZ\Publish\API\Re...ser\UserRoleAssignment>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
814
            }
815
        }
816
817
        throw new Exceptions\NotFoundException("Role assignment not found: '{$request->getPathInfo()}'.");
818
    }
819
820
    /**
821
     * Returns a role assignment to the given user group.
822
     *
823
     * @param $groupPath
824
     * @param $roleId
825
     *
826
     * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException
827
     *
828
     * @return \eZ\Publish\Core\REST\Server\Values\RestUserGroupRoleAssignment
829
     */
830
    public function loadRoleAssignmentForUserGroup($groupPath, $roleId, Request $request)
831
    {
832
        $groupLocationParts = explode('/', $groupPath);
833
        $groupLocation = $this->locationService->loadLocation(array_pop($groupLocationParts));
834
        $userGroup = $this->userService->loadUserGroup($groupLocation->contentId);
835
836
        $roleAssignments = $this->roleService->getRoleAssignmentsForUserGroup($userGroup);
837
        foreach ($roleAssignments as $roleAssignment) {
838
            if ($roleAssignment->getRole()->id == $roleId) {
839
                return new Values\RestUserGroupRoleAssignment($roleAssignment, $groupPath);
840
            }
841
        }
842
843
        throw new Exceptions\NotFoundException("Role assignment not found: '{$request->getPathInfo()}'.");
844
    }
845
846
    /**
847
     * Search all policies which are applied to a given user.
848
     *
849
     * @return \eZ\Publish\Core\REST\Server\Values\PolicyList
850
     */
851
    public function listPoliciesForUser(Request $request)
852
    {
853
        return new Values\PolicyList(
854
            $this->roleService->loadPoliciesByUserId(
855
                $request->query->get('userId')
856
            ),
857
            $request->getPathInfo()
858
        );
859
    }
860
861
    /**
862
     * Maps a RoleCreateStruct to a RoleUpdateStruct.
863
     *
864
     * Needed since both structs are encoded into the same media type on input.
865
     *
866
     * @param \eZ\Publish\API\Repository\Values\User\RoleCreateStruct $createStruct
867
     *
868
     * @return \eZ\Publish\API\Repository\Values\User\RoleUpdateStruct
869
     */
870
    protected function mapToUpdateStruct(RoleCreateStruct $createStruct)
871
    {
872
        return new RoleUpdateStruct(
873
            array(
874
                'identifier' => $createStruct->identifier,
875
            )
876
        );
877
    }
878
}
879