Completed
Push — ezp-24830_REST_for_role_drafts ( 7038df...e2f179 )
by
unknown
26:43
created

Role::createRoleDraft()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 4
rs 10
cc 1
eloc 1
nc 1
nop 1
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
     * @return \eZ\Publish\Core\REST\Server\Values\CreatedRole
78
     */
79
    public function createRole(Request $request)
80
    {
81
        $publish = ($request->query->has('publish') && $request->query->get('publish') === 'true');
82
83
        try {
84
            $roleDraft = $this->roleService->createRole(
85
                $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...
86
                    new Message(
87
                        [
88
                            'Content-Type' => $request->headers->get('Content-Type'),
89
                            // @todo Needs refactoring! Temporary solution so parser has access to get parameters
90
                            '__publish' => $publish,
91
                        ],
92
                        $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...
93
                    )
94
                )
95
            );
96
        } catch (InvalidArgumentException $e) {
97
            throw new ForbiddenException($e->getMessage());
98
        } catch (UnauthorizedException $e) {
99
            throw new ForbiddenException($e->getMessage());
100
        } catch (LimitationValidationException $e) {
101
            throw new BadRequestException($e->getMessage());
102
        } catch (Exceptions\Parser $e) {
103
            throw new BadRequestException($e->getMessage());
104
        }
105
106
        if ($publish) {
107
            $this->roleService->publishRoleDraft($roleDraft);
108
109
            $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...
110
111
            return new Values\CreatedRole(['role' => new Values\RestRole($role)]);
112
        }
113
114
        return new Values\CreatedRole(['role' => new Values\RestRole($roleDraft)]);
115
    }
116
117
    /**
118
     * Creates a new RoleDraft for an existing Role.
119
     *
120
     * @since 6.1
121
     *
122
     * @return \eZ\Publish\Core\REST\Server\Values\CreatedRoleDraft
123
     */
124
    public function createRoleDraft(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...
125
    {
126
        //TODO implement
127
    }
128
129
    /**
130
     * Loads list of roles.
131
     *
132
     * @return \eZ\Publish\Core\REST\Server\Values\RoleList
133
     */
134
    public function listRoles(Request $request)
135
    {
136
        $roles = array();
137
        if ($request->query->has('identifier')) {
138
            try {
139
                $role = $this->roleService->loadRoleByIdentifier($request->query->get('identifier'));
140
                $roles[] = $role;
141
            } catch (APINotFoundException $e) {
142
                // Do nothing
143
            }
144
        } else {
145
            $offset = $request->query->has('offset') ? (int)$request->query->get('offset') : 0;
146
            $limit = $request->query->has('limit') ? (int)$request->query->get('limit') : -1;
147
148
            $roles = array_slice(
149
                $this->roleService->loadRoles(),
150
                $offset >= 0 ? $offset : 0,
151
                $limit >= 0 ? $limit : null
152
            );
153
        }
154
155
        return new Values\RoleList($roles, $request->getPathInfo());
156
    }
157
158
    /**
159
     * Loads role.
160
     *
161
     * @param $roleId
162
     *
163
     * @return \eZ\Publish\API\Repository\Values\User\Role
164
     */
165
    public function loadRole($roleId)
166
    {
167
        return $this->roleService->loadRole($roleId);
168
    }
169
170
    /**
171
     * Loads a role draft.
172
     *
173
     * @param mixed $roleId Original role ID, or ID of the role draft itself
174
     *
175
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
176
     */
177
    public function loadRoleDraft($roleId)
178
    {
179
        try {
180
            // First try to load the draft for given role.
181
            return $this->roleService->loadRoleDraftByRoleId($roleId);
182
        } catch (NotFoundException $e) {
183
            // We might want a newly created role, so try to load it by its ID.
184
            // loadRoleDraft() might throw a NotFoundException (wrong $roleId). If so, let it bubble up.
185
            return $this->roleService->loadRoleDraft($roleId);
186
        }
187
    }
188
189
    /**
190
     * Updates a role.
191
     *
192
     * @param $roleId
193
     *
194
     * @return \eZ\Publish\API\Repository\Values\User\Role
195
     */
196
    public function updateRole($roleId, Request $request)
197
    {
198
        $createStruct = $this->inputDispatcher->parse(
199
            new Message(
200
                array('Content-Type' => $request->headers->get('Content-Type')),
201
                $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...
202
            )
203
        );
204
205
        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...
206
            $this->roleService->loadRole($roleId),
207
            $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...
208
        );
209
    }
210
211
    /**
212
     * Updates a role draft.
213
     *
214
     * @param mixed $roleId Original role ID, or ID of the role draft itself
215
     *
216
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
217
     */
218
    public function updateRoleDraft($roleId, Request $request)
219
    {
220
        $createStruct = $this->inputDispatcher->parse(
221
            new Message(
222
                array('Content-Type' => $request->headers->get('Content-Type')),
223
                $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...
224
            )
225
        );
226
227
        try {
228
            // First try to load the draft for given role.
229
            $roleDraft = $this->roleService->loadRoleDraftByRoleId($roleId);
230
        } catch (NotFoundException $e) {
231
            // We might want a newly created role, so try to load it by its ID.
232
            // loadRoleDraft() might throw a NotFoundException (wrong $roleId). If so, let it bubble up.
233
            $roleDraft = $this->roleService->loadRoleDraft($roleId);
234
        }
235
236
        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...
237
    }
238
239
    /**
240
     * Publishes a role draft.
241
     *
242
     * @param mixed $roleId Original role ID, or ID of the role draft itself
243
     * @return Values\RestRole
244
     */
245
    public function publishRoleDraft($roleId)
246
    {
247
        try {
248
            // First try to load the draft for given role.
249
            $roleDraft = $this->roleService->loadRoleDraftByRoleId($roleId);
250
        } catch (NotFoundException $e) {
251
            // We might want a newly created role, so try to load it by its ID.
252
            // loadRoleDraft() might throw a NotFoundException (wrong $roleId). If so, let it bubble up.
253
            $roleDraft = $this->roleService->loadRoleDraft($roleId);
254
        }
255
256
        $this->roleService->publishRoleDraft($roleDraft);
257
        $publishedRole = $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...
258
259
        return new Values\RestRole($publishedRole);
260
    }
261
262
    /**
263
     * Delete a role by ID.
264
     *
265
     * @param $roleId
266
     *
267
     * @return \eZ\Publish\Core\REST\Server\Values\NoContent
268
     */
269
    public function deleteRole($roleId)
270
    {
271
        $this->roleService->deleteRole(
272
            $this->roleService->loadRole($roleId)
273
        );
274
275
        return new Values\NoContent();
276
    }
277
278
    /**
279
     * Loads the policies for the role.
280
     *
281
     * @param $roleId
282
     *
283
     * @return \eZ\Publish\Core\REST\Server\Values\PolicyList
284
     */
285
    public function loadPolicies($roleId, Request $request)
286
    {
287
        $loadedRole = $this->roleService->loadRole($roleId);
288
289
        return new Values\PolicyList($loadedRole->getPolicies(), $request->getPathInfo());
290
    }
291
292
    /**
293
     * Deletes all policies from a role.
294
     *
295
     * @param $roleId
296
     *
297
     * @return \eZ\Publish\Core\REST\Server\Values\NoContent
298
     */
299
    public function deletePolicies($roleId)
300
    {
301
        $loadedRole = $this->roleService->loadRole($roleId);
302
303
        foreach ($loadedRole->getPolicies() as $policy) {
304
            $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...
305
        }
306
307
        return new Values\NoContent();
308
    }
309
310
    /**
311
     * Loads a policy.
312
     *
313
     * @param $roleId
314
     * @param $policyId
315
     *
316
     * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException
317
     *
318
     * @return \eZ\Publish\API\Repository\Values\User\Policy
319
     */
320
    public function loadPolicy($roleId, $policyId, Request $request)
321
    {
322
        $loadedRole = $this->roleService->loadRole($roleId);
323
        foreach ($loadedRole->getPolicies() as $policy) {
324
            if ($policy->id == $policyId) {
325
                return $policy;
326
            }
327
        }
328
329
        throw new Exceptions\NotFoundException("Policy not found: '{$request->getPathInfo()}'.");
330
    }
331
332
    /**
333
     * Adds a policy to role.
334
     *
335
     * @param $roleId
336
     *
337
     * @return \eZ\Publish\Core\REST\Server\Values\CreatedPolicy
338
     */
339
    public function addPolicy($roleId, Request $request)
340
    {
341
        $createStruct = $this->inputDispatcher->parse(
342
            new Message(
343
                array('Content-Type' => $request->headers->get('Content-Type')),
344
                $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...
345
            )
346
        );
347
348
        try {
349
            $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...
350
                $this->roleService->loadRole($roleId),
351
                $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...
352
            );
353
        } catch (LimitationValidationException $e) {
354
            throw new BadRequestException($e->getMessage());
355
        }
356
357
        $policies = $role->getPolicies();
358
359
        $policyToReturn = $policies[0];
360
        for ($i = 1, $count = count($policies); $i < $count; ++$i) {
361
            if ($policies[$i]->id > $policyToReturn->id) {
362
                $policyToReturn = $policies[$i];
363
            }
364
        }
365
366
        return new Values\CreatedPolicy(
367
            array(
368
                'policy' => $policyToReturn,
369
            )
370
        );
371
    }
372
373
    /**
374
     * Updates a policy.
375
     *
376
     * @param $roleId
377
     * @param $policyId
378
     *
379
     * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException
380
     *
381
     * @return \eZ\Publish\API\Repository\Values\User\Policy
382
     */
383
    public function updatePolicy($roleId, $policyId, Request $request)
384
    {
385
        $updateStruct = $this->inputDispatcher->parse(
386
            new Message(
387
                array('Content-Type' => $request->headers->get('Content-Type')),
388
                $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...
389
            )
390
        );
391
392
        $role = $this->roleService->loadRole($roleId);
393
        foreach ($role->getPolicies() as $policy) {
394
            if ($policy->id == $policyId) {
395
                try {
396
                    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...
397
                        $policy,
398
                        $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...
399
                    );
400
                } catch (LimitationValidationException $e) {
401
                    throw new BadRequestException($e->getMessage());
402
                }
403
            }
404
        }
405
406
        throw new Exceptions\NotFoundException("Policy not found: '{$request->getPathInfo()}'.");
407
    }
408
409
    /**
410
     * Delete a policy from role.
411
     *
412
     * @param $roleId
413
     * @param $policyId
414
     *
415
     * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException
416
     *
417
     * @return \eZ\Publish\Core\REST\Server\Values\NoContent
418
     */
419 View Code Duplication
    public function deletePolicy($roleId, $policyId, Request $request)
420
    {
421
        $role = $this->roleService->loadRole($roleId);
422
423
        $policy = null;
424
        foreach ($role->getPolicies() as $rolePolicy) {
425
            if ($rolePolicy->id == $policyId) {
426
                $policy = $rolePolicy;
427
                break;
428
            }
429
        }
430
431
        if ($policy !== null) {
432
            $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...
433
434
            return new Values\NoContent();
435
        }
436
437
        throw new Exceptions\NotFoundException("Policy not found: '{$request->getPathInfo()}'.");
438
    }
439
440
    /**
441
     * Assigns role to user.
442
     *
443
     * @param $userId
444
     *
445
     * @return \eZ\Publish\Core\REST\Server\Values\RoleAssignmentList
446
     */
447
    public function assignRoleToUser($userId, Request $request)
448
    {
449
        $roleAssignment = $this->inputDispatcher->parse(
450
            new Message(
451
                array('Content-Type' => $request->headers->get('Content-Type')),
452
                $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...
453
            )
454
        );
455
456
        $user = $this->userService->loadUser($userId);
457
        $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...
458
459
        try {
460
            $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...
461
        } catch (LimitationValidationException $e) {
462
            throw new BadRequestException($e->getMessage());
463
        }
464
465
        $roleAssignments = $this->roleService->getRoleAssignmentsForUser($user);
466
467
        return new Values\RoleAssignmentList($roleAssignments, $user->id);
468
    }
469
470
    /**
471
     * Assigns role to user group.
472
     *
473
     * @param $groupPath
474
     *
475
     * @return \eZ\Publish\Core\REST\Server\Values\RoleAssignmentList
476
     */
477
    public function assignRoleToUserGroup($groupPath, Request $request)
478
    {
479
        $roleAssignment = $this->inputDispatcher->parse(
480
            new Message(
481
                array('Content-Type' => $request->headers->get('Content-Type')),
482
                $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...
483
            )
484
        );
485
486
        $groupLocationParts = explode('/', $groupPath);
487
        $groupLocation = $this->locationService->loadLocation(array_pop($groupLocationParts));
488
        $userGroup = $this->userService->loadUserGroup($groupLocation->contentId);
489
490
        $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...
491
492
        try {
493
            $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...
494
        } catch (LimitationValidationException $e) {
495
            throw new BadRequestException($e->getMessage());
496
        }
497
498
        $roleAssignments = $this->roleService->getRoleAssignmentsForUserGroup($userGroup);
499
500
        return new Values\RoleAssignmentList($roleAssignments, $groupPath, true);
501
    }
502
503
    /**
504
     * Un-assigns role from user.
505
     *
506
     * @param $userId
507
     * @param $roleId
508
     *
509
     * @return \eZ\Publish\Core\REST\Server\Values\RoleAssignmentList
510
     */
511
    public function unassignRoleFromUser($userId, $roleId)
512
    {
513
        $user = $this->userService->loadUser($userId);
514
        $role = $this->roleService->loadRole($roleId);
515
516
        $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...
517
518
        $roleAssignments = $this->roleService->getRoleAssignmentsForUser($user);
519
520
        return new Values\RoleAssignmentList($roleAssignments, $user->id);
521
    }
522
523
    /**
524
     * Un-assigns role from user group.
525
     *
526
     * @param $groupPath
527
     * @param $roleId
528
     *
529
     * @return \eZ\Publish\Core\REST\Server\Values\RoleAssignmentList
530
     */
531
    public function unassignRoleFromUserGroup($groupPath, $roleId)
532
    {
533
        $groupLocationParts = explode('/', $groupPath);
534
        $groupLocation = $this->locationService->loadLocation(array_pop($groupLocationParts));
535
        $userGroup = $this->userService->loadUserGroup($groupLocation->contentId);
536
537
        $role = $this->roleService->loadRole($roleId);
538
        $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...
539
540
        $roleAssignments = $this->roleService->getRoleAssignmentsForUserGroup($userGroup);
541
542
        return new Values\RoleAssignmentList($roleAssignments, $groupPath, true);
543
    }
544
545
    /**
546
     * Loads role assignments for user.
547
     *
548
     * @param $userId
549
     *
550
     * @return \eZ\Publish\Core\REST\Server\Values\RoleAssignmentList
551
     */
552
    public function loadRoleAssignmentsForUser($userId)
553
    {
554
        $user = $this->userService->loadUser($userId);
555
556
        $roleAssignments = $this->roleService->getRoleAssignmentsForUser($user);
557
558
        return new Values\RoleAssignmentList($roleAssignments, $user->id);
559
    }
560
561
    /**
562
     * Loads role assignments for user group.
563
     *
564
     * @param $groupPath
565
     *
566
     * @return \eZ\Publish\Core\REST\Server\Values\RoleAssignmentList
567
     */
568
    public function loadRoleAssignmentsForUserGroup($groupPath)
569
    {
570
        $groupLocationParts = explode('/', $groupPath);
571
        $groupLocation = $this->locationService->loadLocation(array_pop($groupLocationParts));
572
        $userGroup = $this->userService->loadUserGroup($groupLocation->contentId);
573
574
        $roleAssignments = $this->roleService->getRoleAssignmentsForUserGroup($userGroup);
575
576
        return new Values\RoleAssignmentList($roleAssignments, $groupPath, true);
577
    }
578
579
    /**
580
     * Returns a role assignment to the given user.
581
     *
582
     * @param $userId
583
     * @param $roleId
584
     *
585
     * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException
586
     *
587
     * @return \eZ\Publish\Core\REST\Server\Values\RestUserRoleAssignment
588
     */
589
    public function loadRoleAssignmentForUser($userId, $roleId, Request $request)
590
    {
591
        $user = $this->userService->loadUser($userId);
592
        $roleAssignments = $this->roleService->getRoleAssignmentsForUser($user);
593
594
        foreach ($roleAssignments as $roleAssignment) {
595
            if ($roleAssignment->getRole()->id == $roleId) {
596
                return new Values\RestUserRoleAssignment($roleAssignment, $userId);
0 ignored issues
show
Bug introduced by
It seems like $roleAssignment defined by $roleAssignment on line 594 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...
597
            }
598
        }
599
600
        throw new Exceptions\NotFoundException("Role assignment not found: '{$request->getPathInfo()}'.");
601
    }
602
603
    /**
604
     * Returns a role assignment to the given user group.
605
     *
606
     * @param $groupPath
607
     * @param $roleId
608
     *
609
     * @throws \eZ\Publish\Core\REST\Common\Exceptions\NotFoundException
610
     *
611
     * @return \eZ\Publish\Core\REST\Server\Values\RestUserGroupRoleAssignment
612
     */
613
    public function loadRoleAssignmentForUserGroup($groupPath, $roleId, Request $request)
614
    {
615
        $groupLocationParts = explode('/', $groupPath);
616
        $groupLocation = $this->locationService->loadLocation(array_pop($groupLocationParts));
617
        $userGroup = $this->userService->loadUserGroup($groupLocation->contentId);
618
619
        $roleAssignments = $this->roleService->getRoleAssignmentsForUserGroup($userGroup);
620
        foreach ($roleAssignments as $roleAssignment) {
621
            if ($roleAssignment->getRole()->id == $roleId) {
622
                return new Values\RestUserGroupRoleAssignment($roleAssignment, $groupPath);
623
            }
624
        }
625
626
        throw new Exceptions\NotFoundException("Role assignment not found: '{$request->getPathInfo()}'.");
627
    }
628
629
    /**
630
     * Search all policies which are applied to a given user.
631
     *
632
     * @return \eZ\Publish\Core\REST\Server\Values\PolicyList
633
     */
634
    public function listPoliciesForUser(Request $request)
635
    {
636
        return new Values\PolicyList(
637
            $this->roleService->loadPoliciesByUserId(
638
                $request->query->get('userId')
639
            ),
640
            $request->getPathInfo()
641
        );
642
    }
643
644
    /**
645
     * Maps a RoleCreateStruct to a RoleUpdateStruct.
646
     *
647
     * Needed since both structs are encoded into the same media type on input.
648
     *
649
     * @param \eZ\Publish\API\Repository\Values\User\RoleCreateStruct $createStruct
650
     *
651
     * @return \eZ\Publish\API\Repository\Values\User\RoleUpdateStruct
652
     */
653
    protected function mapToUpdateStruct(RoleCreateStruct $createStruct)
654
    {
655
        return new RoleUpdateStruct(
656
            array(
657
                'identifier' => $createStruct->identifier,
658
            )
659
        );
660
    }
661
}
662