Completed
Push — 7.0_deprecation_removal ( e8d685...a29025 )
by André
11:11
created

RoleService::validateRoleCreateStruct()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 1
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing the eZ\Publish\Core\Repository\RoleService 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
namespace eZ\Publish\Core\Repository;
10
11
use eZ\Publish\API\Repository\Exceptions\NotFoundException as APINotFoundException;
12
use eZ\Publish\API\Repository\Repository as RepositoryInterface;
13
use eZ\Publish\API\Repository\RoleService as RoleServiceInterface;
14
use eZ\Publish\API\Repository\Values\User\Limitation;
15
use eZ\Publish\API\Repository\Values\User\Limitation\RoleLimitation;
16
use eZ\Publish\API\Repository\Values\User\Policy as APIPolicy;
17
use eZ\Publish\API\Repository\Values\User\PolicyCreateStruct as APIPolicyCreateStruct;
18
use eZ\Publish\API\Repository\Values\User\PolicyDraft;
19
use eZ\Publish\API\Repository\Values\User\PolicyUpdateStruct as APIPolicyUpdateStruct;
20
use eZ\Publish\API\Repository\Values\User\Role as APIRole;
21
use eZ\Publish\API\Repository\Values\User\RoleAssignment;
22
use eZ\Publish\API\Repository\Values\User\RoleCreateStruct as APIRoleCreateStruct;
23
use eZ\Publish\API\Repository\Values\User\RoleDraft as APIRoleDraft;
24
use eZ\Publish\API\Repository\Values\User\RoleUpdateStruct;
25
use eZ\Publish\API\Repository\Values\User\User;
26
use eZ\Publish\API\Repository\Values\User\UserGroup;
27
use eZ\Publish\Core\Base\Exceptions\BadStateException;
28
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException;
29
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentValue;
30
use eZ\Publish\Core\Base\Exceptions\LimitationValidationException;
31
use eZ\Publish\Core\Base\Exceptions\NotFoundException;
32
use eZ\Publish\Core\Base\Exceptions\NotFound\LimitationNotFoundException;
33
use eZ\Publish\Core\Base\Exceptions\UnauthorizedException;
34
use eZ\Publish\Core\Repository\Values\User\Policy;
35
use eZ\Publish\Core\Repository\Values\User\PolicyCreateStruct;
36
use eZ\Publish\Core\Repository\Values\User\PolicyUpdateStruct;
37
use eZ\Publish\Core\Repository\Values\User\Role;
38
use eZ\Publish\Core\Repository\Values\User\RoleCreateStruct;
39
use eZ\Publish\Core\Repository\Values\User\RoleDraft;
40
use eZ\Publish\SPI\Persistence\User\Handler;
41
use eZ\Publish\SPI\Persistence\User\Role as SPIRole;
42
use eZ\Publish\SPI\Persistence\User\RoleUpdateStruct as SPIRoleUpdateStruct;
43
use Exception;
44
45
/**
46
 * This service provides methods for managing Roles and Policies.
47
 */
48
class RoleService implements RoleServiceInterface
49
{
50
    /**
51
     * @var \eZ\Publish\API\Repository\Repository
52
     */
53
    protected $repository;
54
55
    /**
56
     * @var \eZ\Publish\SPI\Persistence\User\Handler
57
     */
58
    protected $userHandler;
59
60
    /**
61
     * @var \eZ\Publish\Core\Repository\Helper\LimitationService
62
     */
63
    protected $limitationService;
64
65
    /**
66
     * @var \eZ\Publish\Core\Repository\Helper\RoleDomainMapper
67
     */
68
    protected $roleDomainMapper;
69
70
    /**
71
     * @var array
72
     */
73
    protected $settings;
74
75
    /**
76
     * Setups service with reference to repository object that created it & corresponding handler.
77
     *
78
     * @param \eZ\Publish\API\Repository\Repository $repository
79
     * @param \eZ\Publish\SPI\Persistence\User\Handler $userHandler
80
     * @param \eZ\Publish\Core\Repository\Helper\LimitationService $limitationService
81
     * @param \eZ\Publish\Core\Repository\Helper\RoleDomainMapper $roleDomainMapper
82
     * @param array $settings
83
     */
84
    public function __construct(
85
        RepositoryInterface $repository,
86
        Handler $userHandler,
87
        Helper\LimitationService $limitationService,
88
        Helper\RoleDomainMapper $roleDomainMapper,
89
        array $settings = array()
90
    ) {
91
        $this->repository = $repository;
92
        $this->userHandler = $userHandler;
93
        $this->limitationService = $limitationService;
94
        $this->roleDomainMapper = $roleDomainMapper;
95
        // Union makes sure default settings are ignored if provided in argument
96
        $this->settings = $settings + array(
97
            'policyMap' => array(
98
                'content' => array(
99
                    'read' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Group' => true, 'Node' => true, 'Subtree' => true, 'State' => true),
100
                    'diff' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Node' => true, 'Subtree' => true),
101
                    'view_embed' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Node' => true, 'Subtree' => true),
102
                    'create' => array('Class' => true, 'Section' => true, 'ParentOwner' => true, 'ParentGroup' => true, 'ParentClass' => true, 'ParentDepth' => true, 'Node' => true, 'Subtree' => true, 'Language' => true),
103
                    'edit' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Group' => true, 'Node' => true, 'Subtree' => true, 'Language' => true, 'State' => true),
104
                    'publish' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Group' => true, 'Node' => true, 'Subtree' => true, 'Language' => true, 'State' => true),
105
                    'manage_locations' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Subtree' => true),
106
                    'hide' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Group' => true, 'Node' => true, 'Subtree' => true, 'Language' => true),
107
                    'translate' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Node' => true, 'Subtree' => true, 'Language' => true),
108
                    'remove' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Node' => true, 'Subtree' => true, 'State' => true),
109
                    'versionread' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Status' => true, 'Node' => true, 'Subtree' => true),
110
                    'versionremove' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Status' => true, 'Node' => true, 'Subtree' => true),
111
                    'pdf' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Node' => true, 'Subtree' => true),
112
                ),
113
                'section' => array(
114
                    'assign' => array('Class' => true, 'Section' => true, 'Owner' => true, 'NewSection' => true),
115
                ),
116
                'state' => array(
117
                    'assign' => array('Class' => true, 'Section' => true, 'Owner' => true, 'Group' => true, 'Node' => true, 'Subtree' => true, 'State' => true, 'NewState' => true),
118
                ),
119
                'user' => array(
120
                    'login' => array('SiteAccess' => true),
121
                ),
122
            ),
123
        );
124
    }
125
126
    /**
127
     * Creates a new RoleDraft.
128
     *
129
     * @since 6.0
130
     *
131
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to create a RoleDraft
132
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
133
     *         if the name of the role already exists or if limitation of the same type
134
     *         is repeated in the policy create struct or if limitation is not allowed on module/function
135
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a policy limitation in the $roleCreateStruct is not valid
136
     *
137
     * @param \eZ\Publish\API\Repository\Values\User\RoleCreateStruct $roleCreateStruct
138
     *
139
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
140
     */
141
    public function createRole(APIRoleCreateStruct $roleCreateStruct)
142
    {
143
        if (!is_string($roleCreateStruct->identifier) || empty($roleCreateStruct->identifier)) {
144
            throw new InvalidArgumentValue('identifier', $roleCreateStruct->identifier, 'RoleCreateStruct');
145
        }
146
147
        if ($this->repository->hasAccess('role', 'create') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
148
            throw new UnauthorizedException('role', 'create');
149
        }
150
151
        try {
152
            $existingRole = $this->loadRoleByIdentifier($roleCreateStruct->identifier);
153
154
            throw new InvalidArgumentException(
155
                '$roleCreateStruct',
156
                "Role '{$existingRole->id}' with the specified identifier '{$roleCreateStruct->identifier}' " .
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...
157
                'already exists'
158
            );
159
        } catch (APINotFoundException $e) {
160
            // Do nothing
161
        }
162
163
        $limitationValidationErrors = $this->validateRoleCreateStruct($roleCreateStruct);
164
        if (!empty($limitationValidationErrors)) {
165
            throw new LimitationValidationException($limitationValidationErrors);
0 ignored issues
show
Documentation introduced by
$limitationValidationErrors is of type array<integer,array<inte...ype\ValidationError>>>>, but the function expects a array<integer,object<eZ\...dType\ValidationError>>.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
166
        }
167
168
        $spiRoleCreateStruct = $this->roleDomainMapper->buildPersistenceRoleCreateStruct($roleCreateStruct);
169
170
        $this->repository->beginTransaction();
171
        try {
172
            $spiRole = $this->userHandler->createRole($spiRoleCreateStruct);
173
            $this->repository->commit();
174
        } catch (Exception $e) {
175
            $this->repository->rollback();
176
            throw $e;
177
        }
178
179
        return $this->roleDomainMapper->buildDomainRoleDraftObject($spiRole);
180
    }
181
182
    /**
183
     * Creates a new RoleDraft for an existing Role.
184
     *
185
     * @since 6.0
186
     *
187
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to create a RoleDraft
188
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the Role already has a RoleDraft that will need to be removed first
189
     *
190
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
191
     *
192
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
193
     */
194 View Code Duplication
    public function createRoleDraft(APIRole $role)
195
    {
196
        if ($this->repository->hasAccess('role', 'create') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
197
            throw new UnauthorizedException('role', 'create');
198
        }
199
200
        try {
201
            $this->userHandler->loadRole($role->id, Role::STATUS_DRAFT);
202
203
            // Throw exception, so platformui et al can do conflict management. Follow-up: EZP-24719
204
            throw new InvalidArgumentException(
205
                '$role',
206
                "Cannot create a draft for role '{$role->identifier}' because another draft exists"
207
            );
208
        } catch (APINotFoundException $e) {
209
            $this->repository->beginTransaction();
210
            try {
211
                $spiRole = $this->userHandler->createRoleDraft($role->id);
212
                $this->repository->commit();
213
            } catch (Exception $e) {
214
                $this->repository->rollback();
215
                throw $e;
216
            }
217
        }
218
219
        return $this->roleDomainMapper->buildDomainRoleDraftObject($spiRole);
220
    }
221
222
    /**
223
     * Loads a RoleDraft for the given id.
224
     *
225
     * @since 6.0
226
     *
227
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this RoleDraft
228
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a RoleDraft with the given id was not found
229
     *
230
     * @param mixed $id
231
     *
232
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
233
     */
234 View Code Duplication
    public function loadRoleDraft($id)
235
    {
236
        if ($this->repository->hasAccess('role', 'read') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
237
            throw new UnauthorizedException('role', 'read');
238
        }
239
240
        $spiRole = $this->userHandler->loadRole($id, Role::STATUS_DRAFT);
241
242
        return $this->roleDomainMapper->buildDomainRoleDraftObject($spiRole);
243
    }
244
245
    /**
246
     * Loads a RoleDraft by the ID of the role it was created from.
247
     *
248
     * @param mixed $roleId ID of the role the draft was created from.
249
     *
250
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role
251
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a RoleDraft with the given id was not found
252
     *
253
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
254
     */
255 View Code Duplication
    public function loadRoleDraftByRoleId($roleId)
256
    {
257
        if ($this->repository->hasAccess('role', 'read') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
258
            throw new UnauthorizedException('role', 'read');
259
        }
260
261
        $spiRole = $this->userHandler->loadRoleDraftByRoleId($roleId);
262
263
        return $this->roleDomainMapper->buildDomainRoleDraftObject($spiRole);
264
    }
265
266
    /**
267
     * Updates the properties of a RoleDraft.
268
     *
269
     * @since 6.0
270
     *
271
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to update a RoleDraft
272
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the identifier of the RoleDraft already exists
273
     *
274
     * @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft
275
     * @param \eZ\Publish\API\Repository\Values\User\RoleUpdateStruct $roleUpdateStruct
276
     *
277
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
278
     */
279
    public function updateRoleDraft(APIRoleDraft $roleDraft, RoleUpdateStruct $roleUpdateStruct)
280
    {
281 View Code Duplication
        if ($roleUpdateStruct->identifier !== null && !is_string($roleUpdateStruct->identifier)) {
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...
282
            throw new InvalidArgumentValue('identifier', $roleUpdateStruct->identifier, 'RoleUpdateStruct');
283
        }
284
285
        $loadedRoleDraft = $this->loadRoleDraft($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...
286
287
        if ($this->repository->hasAccess('role', 'update') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
288
            throw new UnauthorizedException('role', 'update');
289
        }
290
291
        if ($roleUpdateStruct->identifier !== null) {
292
            try {
293
                /* Throw exception if:
294
                 * - A published role with the same identifier exists, AND
295
                 * - The ID of the published role does not match the original ID of the draft
296
                */
297
                $existingSPIRole = $this->userHandler->loadRoleByIdentifier($roleUpdateStruct->identifier);
298
                $SPIRoleDraft = $this->userHandler->loadRole($loadedRoleDraft->id, Role::STATUS_DRAFT);
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...
299
                if ($existingSPIRole->id != $SPIRoleDraft->originalId) {
300
                    throw new InvalidArgumentException(
301
                        '$roleUpdateStruct',
302
                        "Role '{$existingSPIRole->id}' with the specified identifier '{$roleUpdateStruct->identifier}' " .
303
                        'already exists'
304
                    );
305
                }
306
            } catch (APINotFoundException $e) {
307
                // Do nothing
308
            }
309
        }
310
311
        $this->repository->beginTransaction();
312
        try {
313
            $this->userHandler->updateRole(
314
                new SPIRoleUpdateStruct(
315
                    array(
316
                        'id' => $loadedRoleDraft->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...
317
                        'identifier' => $roleUpdateStruct->identifier ?: $loadedRoleDraft->identifier,
0 ignored issues
show
Documentation introduced by
The property $identifier 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...
318
                    )
319
                )
320
            );
321
            $this->repository->commit();
322
        } catch (Exception $e) {
323
            $this->repository->rollback();
324
            throw $e;
325
        }
326
327
        return $this->loadRoleDraft($loadedRoleDraft->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...
328
    }
329
330
    /**
331
     * Adds a new policy to the RoleDraft.
332
     *
333
     * @since 6.0
334
     *
335
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to add  a policy
336
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if limitation of the same type is repeated in policy create
337
     *                                                                        struct or if limitation is not allowed on module/function
338
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a limitation in the $policyCreateStruct is not valid
339
     *
340
     * @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft
341
     * @param \eZ\Publish\API\Repository\Values\User\PolicyCreateStruct $policyCreateStruct
342
     *
343
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
344
     */
345 View Code Duplication
    public function addPolicyByRoleDraft(APIRoleDraft $roleDraft, APIPolicyCreateStruct $policyCreateStruct)
346
    {
347
        if (!is_string($policyCreateStruct->module) || empty($policyCreateStruct->module)) {
348
            throw new InvalidArgumentValue('module', $policyCreateStruct->module, 'PolicyCreateStruct');
349
        }
350
351
        if (!is_string($policyCreateStruct->function) || empty($policyCreateStruct->function)) {
352
            throw new InvalidArgumentValue('function', $policyCreateStruct->function, 'PolicyCreateStruct');
353
        }
354
355
        if ($policyCreateStruct->module === '*' && $policyCreateStruct->function !== '*') {
356
            throw new InvalidArgumentValue('module', $policyCreateStruct->module, 'PolicyCreateStruct');
357
        }
358
359
        if ($this->repository->hasAccess('role', 'update') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
360
            throw new UnauthorizedException('role', 'update');
361
        }
362
363
        $loadedRoleDraft = $this->loadRoleDraft($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...
364
365
        $limitations = $policyCreateStruct->getLimitations();
366
        $limitationValidationErrors = $this->validatePolicy(
367
            $policyCreateStruct->module,
368
            $policyCreateStruct->function,
369
            $limitations
370
        );
371
        if (!empty($limitationValidationErrors)) {
372
            throw new LimitationValidationException($limitationValidationErrors);
0 ignored issues
show
Documentation introduced by
$limitationValidationErrors is of type array<integer,array<inte...Type\ValidationError>>>, but the function expects a array<integer,object<eZ\...dType\ValidationError>>.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
373
        }
374
375
        $spiPolicy = $this->roleDomainMapper->buildPersistencePolicyObject(
376
            $policyCreateStruct->module,
377
            $policyCreateStruct->function,
378
            $limitations
379
        );
380
381
        $this->repository->beginTransaction();
382
        try {
383
            $this->userHandler->addPolicyByRoleDraft($loadedRoleDraft->id, $spiPolicy);
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...
384
            $this->repository->commit();
385
        } catch (Exception $e) {
386
            $this->repository->rollback();
387
            throw $e;
388
        }
389
390
        return $this->loadRoleDraft($loadedRoleDraft->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...
391
    }
392
393
    /**
394
     * Removes a policy from a RoleDraft.
395
     *
396
     * @since 6.0
397
     *
398
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a policy
399
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if policy does not belong to the given RoleDraft
400
     *
401
     * @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft
402
     * @param PolicyDraft $policyDraft the policy to remove from the RoleDraft
403
     *
404
     * @return APIRoleDraft if the authenticated user is not allowed to remove a policy
405
     */
406
    public function removePolicyByRoleDraft(APIRoleDraft $roleDraft, PolicyDraft $policyDraft)
407
    {
408
        if ($this->repository->hasAccess('role', 'update') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
409
            throw new UnauthorizedException('role', 'update');
410
        }
411
412
        if ($policyDraft->roleId != $roleDraft->id) {
0 ignored issues
show
Documentation introduced by
The property $roleId is declared protected in eZ\Publish\API\Repository\Values\User\Policy. 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...
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...
413
            throw new InvalidArgumentException('$policy', 'Policy does not belong to the given role');
414
        }
415
416
        $this->internalDeletePolicy($policyDraft);
417
418
        return $this->loadRoleDraft($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...
419
    }
420
421
    /**
422
     * Updates the limitations of a policy. The module and function cannot be changed and
423
     * the limitations are replaced by the ones in $roleUpdateStruct.
424
     *
425
     * @since 6.0
426
     *
427
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to update a policy
428
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if limitation of the same type is repeated in policy update
429
     *                                                                        struct or if limitation is not allowed on module/function
430
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a limitation in the $policyUpdateStruct is not valid
431
     *
432
     * @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft
433
     * @param \eZ\Publish\API\Repository\Values\User\PolicyDraft $policy
434
     * @param \eZ\Publish\API\Repository\Values\User\PolicyUpdateStruct $policyUpdateStruct
435
     *
436
     * @return \eZ\Publish\API\Repository\Values\User\PolicyDraft
437
     */
438
    public function updatePolicyByRoleDraft(APIRoleDraft $roleDraft, PolicyDraft $policy, APIPolicyUpdateStruct $policyUpdateStruct)
439
    {
440
        if (!is_string($policy->module)) {
0 ignored issues
show
Documentation introduced by
The property $module is declared protected in eZ\Publish\API\Repository\Values\User\Policy. 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...
441
            throw new InvalidArgumentValue('module', $policy->module, 'Policy');
0 ignored issues
show
Documentation introduced by
The property $module is declared protected in eZ\Publish\API\Repository\Values\User\Policy. 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...
442
        }
443
444
        if (!is_string($policy->function)) {
0 ignored issues
show
Documentation introduced by
The property $function is declared protected in eZ\Publish\API\Repository\Values\User\Policy. 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...
445
            throw new InvalidArgumentValue('function', $policy->function, 'Policy');
0 ignored issues
show
Documentation introduced by
The property $function is declared protected in eZ\Publish\API\Repository\Values\User\Policy. 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...
446
        }
447
448
        if ($this->repository->hasAccess('role', 'update') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
449
            throw new UnauthorizedException('role', 'update');
450
        }
451
452
        if ($policy->roleId !== $roleDraft->id) {
0 ignored issues
show
Documentation introduced by
The property $roleId is declared protected in eZ\Publish\API\Repository\Values\User\Policy. 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...
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...
453
            throw new InvalidArgumentException('$policy', "doesn't belong to provided role draft");
454
        }
455
456
        $limitations = $policyUpdateStruct->getLimitations();
457
        $limitationValidationErrors = $this->validatePolicy(
458
            $policy->module,
0 ignored issues
show
Documentation introduced by
The property $module is declared protected in eZ\Publish\API\Repository\Values\User\Policy. 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...
459
            $policy->function,
0 ignored issues
show
Documentation introduced by
The property $function is declared protected in eZ\Publish\API\Repository\Values\User\Policy. 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...
460
            $limitations
461
        );
462
        if (!empty($limitationValidationErrors)) {
463
            throw new LimitationValidationException($limitationValidationErrors);
0 ignored issues
show
Documentation introduced by
$limitationValidationErrors is of type array<integer,array<inte...Type\ValidationError>>>, but the function expects a array<integer,object<eZ\...dType\ValidationError>>.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
464
        }
465
466
        $spiPolicy = $this->roleDomainMapper->buildPersistencePolicyObject(
467
            $policy->module,
0 ignored issues
show
Documentation introduced by
The property $module is declared protected in eZ\Publish\API\Repository\Values\User\Policy. 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...
468
            $policy->function,
0 ignored issues
show
Documentation introduced by
The property $function is declared protected in eZ\Publish\API\Repository\Values\User\Policy. 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...
469
            $limitations
470
        );
471
        $spiPolicy->id = $policy->id;
0 ignored issues
show
Documentation introduced by
The property $id is declared protected in eZ\Publish\API\Repository\Values\User\Policy. 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...
472
        $spiPolicy->roleId = $policy->roleId;
0 ignored issues
show
Documentation introduced by
The property $roleId is declared protected in eZ\Publish\API\Repository\Values\User\Policy. 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...
473
        $spiPolicy->originalId = $policy->originalId;
474
475
        $this->repository->beginTransaction();
476
        try {
477
            $this->userHandler->updatePolicy($spiPolicy);
478
            $this->repository->commit();
479
        } catch (Exception $e) {
480
            $this->repository->rollback();
481
            throw $e;
482
        }
483
484
        return $this->roleDomainMapper->buildDomainPolicyObject($spiPolicy);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->roleDomainMapper-...licyObject($spiPolicy); of type eZ\Publish\Core\Reposito...tory\Values\User\Policy adds the type eZ\Publish\Core\Repository\Values\User\Policy to the return on line 484 which is incompatible with the return type declared by the interface eZ\Publish\API\Repositor...updatePolicyByRoleDraft of type eZ\Publish\API\Repository\Values\User\PolicyDraft.
Loading history...
485
    }
486
487
    /**
488
     * Deletes the given RoleDraft.
489
     *
490
     * @since 6.0
491
     *
492
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to delete this RoleDraft
493
     *
494
     * @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft
495
     */
496 View Code Duplication
    public function deleteRoleDraft(APIRoleDraft $roleDraft)
497
    {
498
        $loadedRoleDraft = $this->loadRoleDraft($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...
499
500
        $this->repository->beginTransaction();
501
        try {
502
            $this->userHandler->deleteRole($loadedRoleDraft->id, Role::STATUS_DRAFT);
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...
503
            $this->repository->commit();
504
        } catch (Exception $e) {
505
            $this->repository->rollback();
506
            throw $e;
507
        }
508
    }
509
510
    /**
511
     * Publishes a given RoleDraft.
512
     *
513
     * @since 6.0
514
     *
515
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to publish this RoleDraft
516
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException if the role draft cannot be loaded
517
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the role draft has no policies
518
     *
519
     * @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft
520
     */
521 View Code Duplication
    public function publishRoleDraft(APIRoleDraft $roleDraft)
522
    {
523
        if ($this->repository->hasAccess('role', 'update') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
524
            throw new UnauthorizedException('role', 'update');
525
        }
526
527
        try {
528
            $loadedRoleDraft = $this->loadRoleDraft($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...
529
        } catch (APINotFoundException $e) {
530
            throw new BadStateException(
531
                '$roleDraft',
532
                'The role does not have a draft.',
533
                $e
534
            );
535
        }
536
537
        // TODO: Uncomment when role policy editing is done, see EZP-24711 & EZP-24713
538
        /*if (count($loadedRoleDraft->getPolicies()) === 0) {
539
            throw new InvalidArgumentException(
540
                "\$roleDraft",
541
                'The role draft should have at least one policy.'
542
            );
543
        }*/
544
545
        $this->repository->beginTransaction();
546
        try {
547
            $this->userHandler->publishRoleDraft($loadedRoleDraft->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...
548
            $this->repository->commit();
549
        } catch (Exception $e) {
550
            $this->repository->rollback();
551
            throw $e;
552
        }
553
    }
554
555
    /**
556
     * Updates the name of the role.
557
     *
558
     * @deprecated since 6.0, use {@see updateRoleDraft}
559
     *
560
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to update a role
561
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the name of the role already exists
562
     *
563
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
564
     * @param \eZ\Publish\API\Repository\Values\User\RoleUpdateStruct $roleUpdateStruct
565
     *
566
     * @return \eZ\Publish\API\Repository\Values\User\Role
567
     */
568
    public function updateRole(APIRole $role, RoleUpdateStruct $roleUpdateStruct)
569
    {
570 View Code Duplication
        if ($roleUpdateStruct->identifier !== null && !is_string($roleUpdateStruct->identifier)) {
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...
571
            throw new InvalidArgumentValue('identifier', $roleUpdateStruct->identifier, 'RoleUpdateStruct');
572
        }
573
574
        $loadedRole = $this->loadRole($role->id);
575
576
        if ($this->repository->hasAccess('role', 'update') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
577
            throw new UnauthorizedException('role', 'update');
578
        }
579
580
        if ($roleUpdateStruct->identifier !== null) {
581
            try {
582
                $existingRole = $this->loadRoleByIdentifier($roleUpdateStruct->identifier);
583
584
                if ($existingRole->id != $loadedRole->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...
585
                    throw new InvalidArgumentException(
586
                        '$roleUpdateStruct',
587
                        'Role with provided identifier already exists'
588
                    );
589
                }
590
            } catch (APINotFoundException $e) {
591
                // Do nothing
592
            }
593
        }
594
595
        $this->repository->beginTransaction();
596
        try {
597
            $this->userHandler->updateRole(
598
                new SPIRoleUpdateStruct(
599
                    array(
600
                        'id' => $loadedRole->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...
601
                        'identifier' => $roleUpdateStruct->identifier ?: $loadedRole->identifier,
0 ignored issues
show
Documentation introduced by
The property $identifier 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...
602
                    )
603
                )
604
            );
605
            $this->repository->commit();
606
        } catch (Exception $e) {
607
            $this->repository->rollback();
608
            throw $e;
609
        }
610
611
        return $this->loadRole($loadedRole->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...
612
    }
613
614
    /**
615
     * Adds a new policy to the role.
616
     *
617
     * @deprecated since 6.0, use {@see addPolicyByRoleDraft}
618
     *
619
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to add  a policy
620
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if limitation of the same type is repeated in policy create
621
     *                                                                        struct or if limitation is not allowed on module/function
622
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a limitation in the $policyCreateStruct is not valid
623
     *
624
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
625
     * @param \eZ\Publish\API\Repository\Values\User\PolicyCreateStruct $policyCreateStruct
626
     *
627
     * @return \eZ\Publish\API\Repository\Values\User\Role
628
     */
629 View Code Duplication
    public function addPolicy(APIRole $role, APIPolicyCreateStruct $policyCreateStruct)
630
    {
631
        if (!is_string($policyCreateStruct->module) || empty($policyCreateStruct->module)) {
632
            throw new InvalidArgumentValue('module', $policyCreateStruct->module, 'PolicyCreateStruct');
633
        }
634
635
        if (!is_string($policyCreateStruct->function) || empty($policyCreateStruct->function)) {
636
            throw new InvalidArgumentValue('function', $policyCreateStruct->function, 'PolicyCreateStruct');
637
        }
638
639
        if ($policyCreateStruct->module === '*' && $policyCreateStruct->function !== '*') {
640
            throw new InvalidArgumentValue('module', $policyCreateStruct->module, 'PolicyCreateStruct');
641
        }
642
643
        if ($this->repository->hasAccess('role', 'update') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
644
            throw new UnauthorizedException('role', 'update');
645
        }
646
647
        $loadedRole = $this->loadRole($role->id);
648
649
        $limitations = $policyCreateStruct->getLimitations();
650
        $limitationValidationErrors = $this->validatePolicy(
651
            $policyCreateStruct->module,
652
            $policyCreateStruct->function,
653
            $limitations
654
        );
655
        if (!empty($limitationValidationErrors)) {
656
            throw new LimitationValidationException($limitationValidationErrors);
0 ignored issues
show
Documentation introduced by
$limitationValidationErrors is of type array<integer,array<inte...Type\ValidationError>>>, but the function expects a array<integer,object<eZ\...dType\ValidationError>>.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
657
        }
658
659
        $spiPolicy = $this->roleDomainMapper->buildPersistencePolicyObject(
660
            $policyCreateStruct->module,
661
            $policyCreateStruct->function,
662
            $limitations
663
        );
664
665
        $this->repository->beginTransaction();
666
        try {
667
            $this->userHandler->addPolicy($loadedRole->id, $spiPolicy);
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...
668
            $this->repository->commit();
669
        } catch (Exception $e) {
670
            $this->repository->rollback();
671
            throw $e;
672
        }
673
674
        return $this->loadRole($loadedRole->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...
675
    }
676
677
    /**
678
     * Deletes a policy.
679
     *
680
     * @deprecated since 6.0, use {@link removePolicyByRoleDraft()} instead.
681
     *
682
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a policy
683
     *
684
     * @param \eZ\Publish\API\Repository\Values\User\Policy $policy the policy to delete
685
     */
686
    public function deletePolicy(APIPolicy $policy)
687
    {
688
        if ($this->repository->hasAccess('role', 'update') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
689
            throw new UnauthorizedException('role', 'update');
690
        }
691
692
        $this->internalDeletePolicy($policy);
693
    }
694
695
    /**
696
     * Deletes a policy.
697
     *
698
     * Used by {@link removePolicy()} and {@link deletePolicy()}
699
     *
700
     * @param APIPolicy $policy
701
     *
702
     * @throws \Exception
703
     */
704 View Code Duplication
    protected function internalDeletePolicy(APIPolicy $policy)
705
    {
706
        $this->repository->beginTransaction();
707
        try {
708
            $this->userHandler->deletePolicy($policy->id, $policy->roleId);
709
            $this->repository->commit();
710
        } catch (Exception $e) {
711
            $this->repository->rollback();
712
            throw $e;
713
        }
714
    }
715
716
    /**
717
     * Updates the limitations of a policy. The module and function cannot be changed and
718
     * the limitations are replaced by the ones in $roleUpdateStruct.
719
     *
720
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to update a policy
721
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if limitation of the same type is repeated in policy update
722
     *                                                                        struct or if limitation is not allowed on module/function
723
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a limitation in the $policyUpdateStruct is not valid
724
     *
725
     * @param \eZ\Publish\API\Repository\Values\User\PolicyUpdateStruct $policyUpdateStruct
726
     * @param \eZ\Publish\API\Repository\Values\User\Policy $policy
727
     *
728
     * @return \eZ\Publish\API\Repository\Values\User\Policy
729
     */
730
    public function updatePolicy(APIPolicy $policy, APIPolicyUpdateStruct $policyUpdateStruct)
731
    {
732
        if (!is_string($policy->module)) {
733
            throw new InvalidArgumentValue('module', $policy->module, 'Policy');
734
        }
735
736
        if (!is_string($policy->function)) {
737
            throw new InvalidArgumentValue('function', $policy->function, 'Policy');
738
        }
739
740
        if ($this->repository->hasAccess('role', 'update') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
741
            throw new UnauthorizedException('role', 'update');
742
        }
743
744
        $limitations = $policyUpdateStruct->getLimitations();
745
        $limitationValidationErrors = $this->validatePolicy(
746
            $policy->module,
747
            $policy->function,
748
            $limitations
749
        );
750
        if (!empty($limitationValidationErrors)) {
751
            throw new LimitationValidationException($limitationValidationErrors);
0 ignored issues
show
Documentation introduced by
$limitationValidationErrors is of type array<integer,array<inte...Type\ValidationError>>>, but the function expects a array<integer,object<eZ\...dType\ValidationError>>.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
752
        }
753
754
        $spiPolicy = $this->roleDomainMapper->buildPersistencePolicyObject(
755
            $policy->module,
756
            $policy->function,
757
            $limitations
758
        );
759
        $spiPolicy->id = $policy->id;
760
        $spiPolicy->roleId = $policy->roleId;
761
762
        $this->repository->beginTransaction();
763
        try {
764
            $this->userHandler->updatePolicy($spiPolicy);
765
            $this->repository->commit();
766
        } catch (Exception $e) {
767
            $this->repository->rollback();
768
            throw $e;
769
        }
770
771
        return $this->roleDomainMapper->buildDomainPolicyObject($spiPolicy);
772
    }
773
774
    /**
775
     * Loads a role for the given id.
776
     *
777
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role
778
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a role with the given id was not found
779
     *
780
     * @param mixed $id
781
     *
782
     * @return \eZ\Publish\API\Repository\Values\User\Role
783
     */
784 View Code Duplication
    public function loadRole($id)
785
    {
786
        if ($this->repository->hasAccess('role', 'read') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
787
            throw new UnauthorizedException('role', 'read');
788
        }
789
790
        $spiRole = $this->userHandler->loadRole($id);
791
792
        return $this->roleDomainMapper->buildDomainRoleObject($spiRole);
793
    }
794
795
    /**
796
     * Loads a role for the given identifier.
797
     *
798
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role
799
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a role with the given name was not found
800
     *
801
     * @param string $identifier
802
     *
803
     * @return \eZ\Publish\API\Repository\Values\User\Role
804
     */
805 View Code Duplication
    public function loadRoleByIdentifier($identifier)
806
    {
807
        if (!is_string($identifier)) {
808
            throw new InvalidArgumentValue('identifier', $identifier);
809
        }
810
811
        if ($this->repository->hasAccess('role', 'read') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
812
            throw new UnauthorizedException('role', 'read');
813
        }
814
815
        $spiRole = $this->userHandler->loadRoleByIdentifier($identifier);
816
817
        return $this->roleDomainMapper->buildDomainRoleObject($spiRole);
818
    }
819
820
    /**
821
     * Loads all roles.
822
     *
823
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read the roles
824
     *
825
     * @return \eZ\Publish\API\Repository\Values\User\Role[]
826
     */
827 View Code Duplication
    public function loadRoles()
828
    {
829
        if ($this->repository->hasAccess('role', 'read') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
830
            throw new UnauthorizedException('role', 'read');
831
        }
832
833
        $spiRoles = $this->userHandler->loadRoles();
834
835
        $roles = array();
836
        foreach ($spiRoles as $spiRole) {
837
            $roles[] = $this->roleDomainMapper->buildDomainRoleObject($spiRole);
838
        }
839
840
        return $roles;
841
    }
842
843
    /**
844
     * Deletes the given role.
845
     *
846
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to delete this role
847
     *
848
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
849
     */
850
    public function deleteRole(APIRole $role)
851
    {
852
        if ($this->repository->hasAccess('role', 'delete') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
853
            throw new UnauthorizedException('role', 'delete');
854
        }
855
856
        $loadedRole = $this->loadRole($role->id);
857
858
        $this->repository->beginTransaction();
859
        try {
860
            $this->userHandler->deleteRole($loadedRole->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...
861
            $this->repository->commit();
862
        } catch (Exception $e) {
863
            $this->repository->rollback();
864
            throw $e;
865
        }
866
    }
867
868
    /**
869
     * Loads all policies from roles which are assigned to a user or to user groups to which the user belongs.
870
     *
871
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a user with the given id was not found
872
     *
873
     * @param mixed $userId
874
     *
875
     * @return \eZ\Publish\API\Repository\Values\User\Policy[]
876
     */
877
    public function loadPoliciesByUserId($userId)
878
    {
879
        $spiPolicies = $this->userHandler->loadPoliciesByUserId($userId);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\SPI\Persisten...:loadPoliciesByUserId() has been deprecated with message: Since 6.8, not currently in use as permission system needs to know about role assignment limitations.

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...
880
881
        $policies = array();
882
        foreach ($spiPolicies as $spiPolicy) {
883
            $policies[] = $this->roleDomainMapper->buildDomainPolicyObject($spiPolicy);
884
        }
885
886
        if (empty($policies)) {
887
            $this->userHandler->load($userId);
888
        }// For NotFoundException in case userId is invalid
889
890
        return $policies;
891
    }
892
893
    /**
894
     * Assigns a role to the given user group.
895
     *
896
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to assign a role
897
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if $roleLimitation is not valid
898
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If assignment already exists
899
     *
900
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
901
     * @param \eZ\Publish\API\Repository\Values\User\UserGroup $userGroup
902
     * @param \eZ\Publish\API\Repository\Values\User\Limitation\RoleLimitation $roleLimitation an optional role limitation (which is either a subtree limitation or section limitation)
903
     */
904 View Code Duplication
    public function assignRoleToUserGroup(APIRole $role, UserGroup $userGroup, RoleLimitation $roleLimitation = null)
905
    {
906
        if ($this->repository->canUser('role', 'assign', $userGroup, $role) !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::canUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::canUser() instead. Indicates if the current user is allowed to perform an action given by the function on the given
objects. Example: canUser( 'content', 'edit', $content, $location ); This will check edit permission on content given the specific location, if skipped if will check on all locations. Example2: canUser( 'section', 'assign', $content, $section ); Check if user has access to assign $content to $section.

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...
907
            throw new UnauthorizedException('role', 'assign');
908
        }
909
910
        if ($roleLimitation === null) {
911
            $limitation = null;
912
        } else {
913
            $limitationValidationErrors = $this->limitationService->validateLimitation($roleLimitation);
914
            if (!empty($limitationValidationErrors)) {
915
                throw new LimitationValidationException($limitationValidationErrors);
916
            }
917
918
            $limitation = array($roleLimitation->getIdentifier() => $roleLimitation->limitationValues);
919
        }
920
921
        // Check if objects exists
922
        $spiRole = $this->userHandler->loadRole($role->id);
923
        $loadedUserGroup = $this->repository->getUserService()->loadUserGroup($userGroup->id);
924
925
        $limitation = $this->checkAssignmentAndFilterLimitationValues($loadedUserGroup->id, $spiRole, $limitation);
926
927
        $this->repository->beginTransaction();
928
        try {
929
            $this->userHandler->assignRole(
930
                $loadedUserGroup->id,
931
                $spiRole->id,
932
                $limitation
933
            );
934
            $this->repository->commit();
935
        } catch (Exception $e) {
936
            $this->repository->rollback();
937
            throw $e;
938
        }
939
    }
940
941
    /**
942
     * removes a role from the given user group.
943
     *
944
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a role
945
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException  If the role is not assigned to the given user group
946
     *
947
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
948
     * @param \eZ\Publish\API\Repository\Values\User\UserGroup $userGroup
949
     */
950 View Code Duplication
    public function unassignRoleFromUserGroup(APIRole $role, UserGroup $userGroup)
951
    {
952
        if ($this->repository->canUser('role', 'assign', $userGroup, $role) !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::canUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::canUser() instead. Indicates if the current user is allowed to perform an action given by the function on the given
objects. Example: canUser( 'content', 'edit', $content, $location ); This will check edit permission on content given the specific location, if skipped if will check on all locations. Example2: canUser( 'section', 'assign', $content, $section ); Check if user has access to assign $content to $section.

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...
953
            throw new UnauthorizedException('role', 'assign');
954
        }
955
956
        $spiRoleAssignments = $this->userHandler->loadRoleAssignmentsByGroupId($userGroup->id);
957
        $isAssigned = false;
958
        foreach ($spiRoleAssignments as $spiRoleAssignment) {
959
            if ($spiRoleAssignment->roleId === $role->id) {
960
                $isAssigned = true;
961
                break;
962
            }
963
        }
964
965
        if (!$isAssigned) {
966
            throw new InvalidArgumentException(
967
                '$userGroup',
968
                'Role is not assigned to the given UserGroup'
969
            );
970
        }
971
972
        $this->repository->beginTransaction();
973
        try {
974
            $this->userHandler->unassignRole($userGroup->id, $role->id);
975
            $this->repository->commit();
976
        } catch (Exception $e) {
977
            $this->repository->rollback();
978
            throw $e;
979
        }
980
    }
981
982
    /**
983
     * Assigns a role to the given user.
984
     *
985
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to assign a role
986
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if $roleLimitation is not valid
987
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If assignment already exists
988
     *
989
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
990
     * @param \eZ\Publish\API\Repository\Values\User\User $user
991
     * @param \eZ\Publish\API\Repository\Values\User\Limitation\RoleLimitation $roleLimitation an optional role limitation (which is either a subtree limitation or section limitation)
992
     */
993 View Code Duplication
    public function assignRoleToUser(APIRole $role, User $user, RoleLimitation $roleLimitation = null)
994
    {
995
        if ($this->repository->canUser('role', 'assign', $user, $role) !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::canUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::canUser() instead. Indicates if the current user is allowed to perform an action given by the function on the given
objects. Example: canUser( 'content', 'edit', $content, $location ); This will check edit permission on content given the specific location, if skipped if will check on all locations. Example2: canUser( 'section', 'assign', $content, $section ); Check if user has access to assign $content to $section.

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...
996
            throw new UnauthorizedException('role', 'assign');
997
        }
998
999
        if ($roleLimitation === null) {
1000
            $limitation = null;
1001
        } else {
1002
            $limitationValidationErrors = $this->limitationService->validateLimitation($roleLimitation);
1003
            if (!empty($limitationValidationErrors)) {
1004
                throw new LimitationValidationException($limitationValidationErrors);
1005
            }
1006
1007
            $limitation = array($roleLimitation->getIdentifier() => $roleLimitation->limitationValues);
1008
        }
1009
1010
        // Check if objects exists
1011
        $spiRole = $this->userHandler->loadRole($role->id);
1012
        $spiUser = $this->userHandler->load($user->id);
1013
1014
        $limitation = $this->checkAssignmentAndFilterLimitationValues($spiUser->id, $spiRole, $limitation);
1015
1016
        $this->repository->beginTransaction();
1017
        try {
1018
            $this->userHandler->assignRole(
1019
                $spiUser->id,
1020
                $spiRole->id,
1021
                $limitation
1022
            );
1023
            $this->repository->commit();
1024
        } catch (Exception $e) {
1025
            $this->repository->rollback();
1026
            throw $e;
1027
        }
1028
    }
1029
1030
    /**
1031
     * removes a role from the given user.
1032
     *
1033
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a role
1034
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If the role is not assigned to the user
1035
     *
1036
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
1037
     * @param \eZ\Publish\API\Repository\Values\User\User $user
1038
     */
1039 View Code Duplication
    public function unassignRoleFromUser(APIRole $role, User $user)
1040
    {
1041
        if ($this->repository->canUser('role', 'assign', $user, $role) !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::canUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::canUser() instead. Indicates if the current user is allowed to perform an action given by the function on the given
objects. Example: canUser( 'content', 'edit', $content, $location ); This will check edit permission on content given the specific location, if skipped if will check on all locations. Example2: canUser( 'section', 'assign', $content, $section ); Check if user has access to assign $content to $section.

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...
1042
            throw new UnauthorizedException('role', 'assign');
1043
        }
1044
1045
        $spiRoleAssignments = $this->userHandler->loadRoleAssignmentsByGroupId($user->id);
1046
        $isAssigned = false;
1047
        foreach ($spiRoleAssignments as $spiRoleAssignment) {
1048
            if ($spiRoleAssignment->roleId === $role->id) {
1049
                $isAssigned = true;
1050
                break;
1051
            }
1052
        }
1053
1054
        if (!$isAssigned) {
1055
            throw new InvalidArgumentException(
1056
                '$user',
1057
                'Role is not assigned to the given User'
1058
            );
1059
        }
1060
1061
        $this->repository->beginTransaction();
1062
        try {
1063
            $this->userHandler->unassignRole($user->id, $role->id);
1064
            $this->repository->commit();
1065
        } catch (Exception $e) {
1066
            $this->repository->rollback();
1067
            throw $e;
1068
        }
1069
    }
1070
1071
    /**
1072
     * Removes the given role assignment.
1073
     *
1074
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a role assignment
1075
     *
1076
     * @param \eZ\Publish\API\Repository\Values\User\RoleAssignment $roleAssignment
1077
     */
1078
    public function removeRoleAssignment(RoleAssignment $roleAssignment)
1079
    {
1080
        if ($this->repository->canUser('role', 'assign', $roleAssignment) !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::canUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::canUser() instead. Indicates if the current user is allowed to perform an action given by the function on the given
objects. Example: canUser( 'content', 'edit', $content, $location ); This will check edit permission on content given the specific location, if skipped if will check on all locations. Example2: canUser( 'section', 'assign', $content, $section ); Check if user has access to assign $content to $section.

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...
1081
            throw new UnauthorizedException('role', 'assign');
1082
        }
1083
1084
        $spiRoleAssignment = $this->userHandler->loadRoleAssignment($roleAssignment->id);
0 ignored issues
show
Documentation introduced by
The property $id is declared protected in eZ\Publish\API\Repositor...ues\User\RoleAssignment. 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...
1085
1086
        $this->repository->beginTransaction();
1087
        try {
1088
            $this->userHandler->removeRoleAssignment($spiRoleAssignment->id);
1089
            $this->repository->commit();
1090
        } catch (Exception $e) {
1091
            $this->repository->rollback();
1092
            throw $e;
1093
        }
1094
    }
1095
1096
    /**
1097
     * Loads a role assignment for the given id.
1098
     *
1099
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role
1100
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If the role assignment was not found
1101
     *
1102
     * @param mixed $roleAssignmentId
1103
     *
1104
     * @return \eZ\Publish\API\Repository\Values\User\RoleAssignment
1105
     */
1106
    public function loadRoleAssignment($roleAssignmentId)
1107
    {
1108
        if ($this->repository->hasAccess('role', 'read') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
1109
            throw new UnauthorizedException('role', 'read');
1110
        }
1111
1112
        $spiRoleAssignment = $this->userHandler->loadRoleAssignment($roleAssignmentId);
1113
        $userService = $this->repository->getUserService();
1114
        $role = $this->loadRole($spiRoleAssignment->roleId);
1115
        $roleAssignment = null;
1116
1117
        // First check if the Role is assigned to a User
1118
        // If no User is found, see if it belongs to a UserGroup
1119
        try {
1120
            $user = $userService->loadUser($spiRoleAssignment->contentId);
1121
            $roleAssignment = $this->roleDomainMapper->buildDomainUserRoleAssignmentObject(
1122
                $spiRoleAssignment,
1123
                $user,
1124
                $role
1125
            );
1126
        } catch (APINotFoundException $e) {
1127
            try {
1128
                $userGroup = $userService->loadUserGroup($spiRoleAssignment->contentId);
1129
                $roleAssignment = $this->roleDomainMapper->buildDomainUserGroupRoleAssignmentObject(
1130
                    $spiRoleAssignment,
1131
                    $userGroup,
1132
                    $role
1133
                );
1134
            } catch (APINotFoundException $e) {
1135
                // Do nothing
1136
            }
1137
        }
1138
1139
        return $roleAssignment;
1140
    }
1141
1142
    /**
1143
     * Returns the assigned user and user groups to this role.
1144
     *
1145
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read a role
1146
     *
1147
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
1148
     *
1149
     * @return \eZ\Publish\API\Repository\Values\User\RoleAssignment[]
1150
     */
1151
    public function getRoleAssignments(APIRole $role)
1152
    {
1153
        if ($this->repository->hasAccess('role', 'read') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
1154
            throw new UnauthorizedException('role', 'read');
1155
        }
1156
1157
        $userService = $this->repository->getUserService();
1158
        $spiRoleAssignments = $this->userHandler->loadRoleAssignmentsByRoleId($role->id);
1159
        $roleAssignments = array();
1160
1161
        foreach ($spiRoleAssignments as $spiRoleAssignment) {
1162
            // First check if the Role is assigned to a User
1163
            // If no User is found, see if it belongs to a UserGroup
1164
            try {
1165
                $user = $userService->loadUser($spiRoleAssignment->contentId);
1166
                $roleAssignments[] = $this->roleDomainMapper->buildDomainUserRoleAssignmentObject(
1167
                    $spiRoleAssignment,
1168
                    $user,
1169
                    $role
1170
                );
1171
            } catch (APINotFoundException $e) {
1172
                try {
1173
                    $userGroup = $userService->loadUserGroup($spiRoleAssignment->contentId);
1174
                    $roleAssignments[] = $this->roleDomainMapper->buildDomainUserGroupRoleAssignmentObject(
1175
                        $spiRoleAssignment,
1176
                        $userGroup,
1177
                        $role
1178
                    );
1179
                } catch (APINotFoundException $e) {
1180
                    // Do nothing
1181
                }
1182
            }
1183
        }
1184
1185
        return $roleAssignments;
1186
    }
1187
1188
    /**
1189
     * @see \eZ\Publish\API\Repository\RoleService::getRoleAssignmentsForUser()
1190
     */
1191
    public function getRoleAssignmentsForUser(User $user, $inherited = false)
1192
    {
1193
        if ($this->repository->hasAccess('role', 'read') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
1194
            throw new UnauthorizedException('role', 'read');
1195
        }
1196
1197
        $roleAssignments = array();
1198
        $spiRoleAssignments = $this->userHandler->loadRoleAssignmentsByGroupId($user->id, $inherited);
1199
        foreach ($spiRoleAssignments as $spiRoleAssignment) {
1200
            $role = $this->loadRole($spiRoleAssignment->roleId);
1201
            if (!$inherited || $spiRoleAssignment->contentId == $user->id) {
1202
                $roleAssignments[] = $this->roleDomainMapper->buildDomainUserRoleAssignmentObject(
1203
                    $spiRoleAssignment,
1204
                    $user,
1205
                    $role
1206
                );
1207
            } else {
1208
                $userGroup = $this->repository->getUserService()->loadUserGroup($spiRoleAssignment->contentId);
1209
                $roleAssignments[] = $this->roleDomainMapper->buildDomainUserGroupRoleAssignmentObject(
1210
                    $spiRoleAssignment,
1211
                    $userGroup,
1212
                    $role
1213
                );
1214
            }
1215
        }
1216
1217
        return $roleAssignments;
1218
    }
1219
1220
    /**
1221
     * Returns the roles assigned to the given user group.
1222
     *
1223
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read a role
1224
     *
1225
     * @param \eZ\Publish\API\Repository\Values\User\UserGroup $userGroup
1226
     *
1227
     * @return \eZ\Publish\API\Repository\Values\User\UserGroupRoleAssignment[]
1228
     */
1229
    public function getRoleAssignmentsForUserGroup(UserGroup $userGroup)
1230
    {
1231
        if ($this->repository->hasAccess('role', 'read') !== true) {
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repository\Repository::hasAccess() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::hasAccess() 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...
1232
            throw new UnauthorizedException('role', 'read');
1233
        }
1234
1235
        $roleAssignments = array();
1236
        $spiRoleAssignments = $this->userHandler->loadRoleAssignmentsByGroupId($userGroup->id);
1237
        foreach ($spiRoleAssignments as $spiRoleAssignment) {
1238
            $role = $this->loadRole($spiRoleAssignment->roleId);
1239
            $roleAssignments[] = $this->roleDomainMapper->buildDomainUserGroupRoleAssignmentObject(
1240
                $spiRoleAssignment,
1241
                $userGroup,
1242
                $role
1243
            );
1244
        }
1245
1246
        return $roleAssignments;
1247
    }
1248
1249
    /**
1250
     * Instantiates a role create class.
1251
     *
1252
     * @param string $name
1253
     *
1254
     * @return \eZ\Publish\API\Repository\Values\User\RoleCreateStruct
1255
     */
1256
    public function newRoleCreateStruct($name)
1257
    {
1258
        return new RoleCreateStruct(
1259
            array(
1260
                'identifier' => $name,
1261
                'policies' => array(),
1262
            )
1263
        );
1264
    }
1265
1266
    /**
1267
     * Instantiates a policy create class.
1268
     *
1269
     * @param string $module
1270
     * @param string $function
1271
     *
1272
     * @return \eZ\Publish\API\Repository\Values\User\PolicyCreateStruct
1273
     */
1274
    public function newPolicyCreateStruct($module, $function)
1275
    {
1276
        return new PolicyCreateStruct(
1277
            array(
1278
                'module' => $module,
1279
                'function' => $function,
1280
                'limitations' => array(),
1281
            )
1282
        );
1283
    }
1284
1285
    /**
1286
     * Instantiates a policy update class.
1287
     *
1288
     * @return \eZ\Publish\API\Repository\Values\User\PolicyUpdateStruct
1289
     */
1290
    public function newPolicyUpdateStruct()
1291
    {
1292
        return new PolicyUpdateStruct(
1293
            array(
1294
                'limitations' => array(),
1295
            )
1296
        );
1297
    }
1298
1299
    /**
1300
     * Instantiates a policy update class.
1301
     *
1302
     * @return \eZ\Publish\API\Repository\Values\User\RoleUpdateStruct
1303
     */
1304
    public function newRoleUpdateStruct()
1305
    {
1306
        return new RoleUpdateStruct();
1307
    }
1308
1309
    /**
1310
     * Returns the LimitationType registered with the given identifier.
1311
     *
1312
     * Returns the correct implementation of API Limitation value object
1313
     * based on provided identifier
1314
     *
1315
     * @param string $identifier
1316
     *
1317
     * @return \eZ\Publish\SPI\Limitation\Type
1318
     *
1319
     * @throws \RuntimeException if there is no LimitationType with $identifier
1320
     */
1321
    public function getLimitationType($identifier)
1322
    {
1323
        return $this->limitationService->getLimitationType($identifier);
1324
    }
1325
1326
    /**
1327
     * Returns the LimitationType's assigned to a given module/function.
1328
     *
1329
     * Typically used for:
1330
     *  - Internal validation limitation value use on Policies
1331
     *  - Role admin gui for editing policy limitations incl list limitation options via valueSchema()
1332
     *
1333
     * @param string $module Legacy name of "controller", it's a unique identifier like "content"
1334
     * @param string $function Legacy name of a controller "action", it's a unique within the controller like "read"
1335
     *
1336
     * @return \eZ\Publish\SPI\Limitation\Type[]
1337
     *
1338
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException If module/function to limitation type mapping
1339
     *                                                                 refers to a non existing identifier.
1340
     */
1341
    public function getLimitationTypesByModuleFunction($module, $function)
1342
    {
1343
        if (empty($this->settings['policyMap'][$module][$function])) {
1344
            return array();
1345
        }
1346
1347
        $types = array();
1348
        try {
1349
            foreach (array_keys($this->settings['policyMap'][$module][$function]) as $identifier) {
1350
                $types[$identifier] = $this->limitationService->getLimitationType($identifier);
1351
            }
1352
        } catch (LimitationNotFoundException $e) {
1353
            throw new BadStateException(
1354
                "{$module}/{$function}",
1355
                "policyMap configuration is referring to non existing identifier: {$identifier}",
1356
                $e
1357
            );
1358
        }
1359
1360
        return $types;
1361
    }
1362
1363
    /**
1364
     * Validates Policies and Limitations in Role create struct.
1365
     *
1366
     * @uses ::validatePolicy()
1367
     *
1368
     * @param \eZ\Publish\API\Repository\Values\User\RoleCreateStruct $roleCreateStruct
1369
     *
1370
     * @return \eZ\Publish\Core\FieldType\ValidationError[][][]
1371
     */
1372
    protected function validateRoleCreateStruct(APIRoleCreateStruct $roleCreateStruct)
1373
    {
1374
        $allErrors = array();
1375
        foreach ($roleCreateStruct->getPolicies() as $key => $policyCreateStruct) {
1376
            $errors = $this->validatePolicy(
1377
                $policyCreateStruct->module,
1378
                $policyCreateStruct->function,
1379
                $policyCreateStruct->getLimitations()
1380
            );
1381
1382
            if (!empty($errors)) {
1383
                $allErrors[$key] = $errors;
1384
            }
1385
        }
1386
1387
        return $allErrors;
1388
    }
1389
1390
    /**
1391
     * Validates Policy context: Limitations on a module and function.
1392
     *
1393
     * @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException If the same limitation is repeated or if
1394
     *                                                                   limitation is not allowed on module/function
1395
     *
1396
     * @param string $module
1397
     * @param string $function
1398
     * @param \eZ\Publish\API\Repository\Values\User\Limitation[] $limitations
1399
     *
1400
     * @return \eZ\Publish\Core\FieldType\ValidationError[][]
1401
     */
1402
    protected function validatePolicy($module, $function, array $limitations)
1403
    {
1404
        if ($module !== '*' && $function !== '*' && !empty($limitations)) {
1405
            $limitationSet = array();
1406
            foreach ($limitations as $limitation) {
1407
                if (isset($limitationSet[$limitation->getIdentifier()])) {
1408
                    throw new InvalidArgumentException(
1409
                        'limitations',
1410
                        "'{$limitation->getIdentifier()}' was found several times among the limitations"
1411
                    );
1412
                }
1413
1414
                if (!isset($this->settings['policyMap'][$module][$function][$limitation->getIdentifier()])) {
1415
                    throw new InvalidArgumentException(
1416
                        'policy',
1417
                        "The limitation '{$limitation->getIdentifier()}' is not applicable on '{$module}/{$function}'"
1418
                    );
1419
                }
1420
1421
                $limitationSet[$limitation->getIdentifier()] = true;
1422
            }
1423
        }
1424
1425
        return $this->limitationService->validateLimitations($limitations);
1426
    }
1427
1428
    /**
1429
     * Validate that assignments not already exists and filter validations against existing.
1430
     *
1431
     * @param mixed $contentId
1432
     * @param SPIRole $spiRole
1433
     * @param array|null $limitation
1434
     *
1435
     * @return array[]|null Filtered version of $limitation
1436
     *
1437
     * @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException If assignment already exists
1438
     */
1439
    protected function checkAssignmentAndFilterLimitationValues($contentId, SPIRole $spiRole, array $limitation = null)
1440
    {
1441
        $spiRoleAssignments = $this->userHandler->loadRoleAssignmentsByGroupId($contentId);
1442
        foreach ($spiRoleAssignments as $spiAssignment) {
1443
            // Ignore assignments to other roles
1444
            if ($spiAssignment->roleId !== $spiRole->id) {
1445
                continue;
1446
            }
1447
1448
            // Throw if Role is already assigned without limitations
1449
            if ($spiAssignment->limitationIdentifier === null) {
1450
                throw new InvalidArgumentException(
1451
                    '$role',
1452
                    "Role '{$spiRole->id}' already assigned without limitations"
1453
                );
1454
            }
1455
1456
            // Ignore if we are going to assign without limitations
1457
            if ($limitation === null) {
1458
                continue;
1459
            }
1460
1461
            // Ignore if not assigned with same limitation identifier
1462
            if (!isset($limitation[$spiAssignment->limitationIdentifier])) {
1463
                continue;
1464
            }
1465
1466
            // Throw if Role is already assigned with all the same limitations
1467
            $newValues = array_diff($limitation[$spiAssignment->limitationIdentifier], $spiAssignment->values);
1468
            if (empty($newValues)) {
1469
                throw new InvalidArgumentException(
1470
                    '$role',
1471
                    "Role '{$spiRole->id}' already assigned with same '{$spiAssignment->limitationIdentifier}' value"
1472
                );
1473
            }
1474
1475
            // Continue using the filtered list of limitations
1476
            $limitation[$spiAssignment->limitationIdentifier] = $newValues;
1477
        }
1478
1479
        return $limitation;
1480
    }
1481
}
1482