Completed
Push — ezp-24830_REST_for_role_drafts ( 70e67c...4d1b35 )
by
unknown
34:56 queued 07:07
created

Role::deleteRoleDraft()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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