Completed
Push — ezp-24830_REST_for_role_drafts ( a3bc83 )
by
unknown
46:27 queued 18:11
created

RoleService::addPolicyByRoleDraft()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 22

Duplication

Lines 35
Ratio 100 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 35
loc 35
rs 8.8571
cc 1
eloc 22
nc 1
nop 2
1
<?php
2
3
/**
4
 * File containing the 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
 * @version //autogentag//
10
 */
11
namespace eZ\Publish\Core\REST\Client;
12
13
use eZ\Publish\API\Repository\RoleService as APIRoleService;
14
use eZ\Publish\API\Repository\Values\User\Limitation\RoleLimitation;
15
use eZ\Publish\API\Repository\Values\User\Policy as APIPolicy;
16
use eZ\Publish\API\Repository\Values\User\PolicyCreateStruct as APIPolicyCreateStruct;
17
use eZ\Publish\API\Repository\Values\User\PolicyDraft;
18
use eZ\Publish\API\Repository\Values\User\PolicyUpdateStruct as APIPolicyUpdateStruct;
19
use eZ\Publish\API\Repository\Values\User\Role as APIRole;
20
use eZ\Publish\API\Repository\Values\User\RoleAssignment as APIRoleAssignment;
21
use eZ\Publish\API\Repository\Values\User\RoleDraft as APIRoleDraft;
22
use eZ\Publish\API\Repository\Values\User\RoleCreateStruct as APIRoleCreateStruct;
23
use eZ\Publish\API\Repository\Values\User\RoleUpdateStruct;
24
use eZ\Publish\API\Repository\Values\User\User;
25
use eZ\Publish\API\Repository\Values\User\UserGroup;
26
use eZ\Publish\Core\Repository\Values\User\RoleDraft;
27
use eZ\Publish\Core\Repository\Values\User\UserRoleAssignment;
28
use eZ\Publish\Core\Repository\Values\User\UserGroupRoleAssignment;
29
use eZ\Publish\Core\REST\Client\Values\User\PolicyCreateStruct;
30
use eZ\Publish\Core\REST\Client\Values\User\PolicyUpdateStruct;
31
use eZ\Publish\Core\REST\Client\Values\User\Role;
32
use eZ\Publish\Core\REST\Client\Values\User\Policy;
33
use eZ\Publish\Core\REST\Client\Values\User\RoleAssignment;
34
use eZ\Publish\Core\REST\Common\RequestParser;
35
use eZ\Publish\Core\REST\Common\Input\Dispatcher;
36
use eZ\Publish\Core\REST\Common\Output\Visitor;
37
use eZ\Publish\Core\REST\Common\Message;
38
39
/**
40
 * Implementation of the {@link \eZ\Publish\API\Repository\RoleService}
41
 * interface.
42
 *
43
 * @see \eZ\Publish\API\Repository\RoleService
44
 */
45
class RoleService implements APIRoleService, Sessionable
46
{
47
    /**
48
     * @var \eZ\Publish\Core\REST\Client\UserService
49
     */
50
    private $userService;
51
52
    /**
53
     * @var \eZ\Publish\Core\REST\Client\HttpClient
54
     */
55
    private $client;
56
57
    /**
58
     * @var \eZ\Publish\Core\REST\Common\Input\Dispatcher
59
     */
60
    private $inputDispatcher;
61
62
    /**
63
     * @var \eZ\Publish\Core\REST\Common\Output\Visitor
64
     */
65
    private $outputVisitor;
66
67
    /**
68
     * @var \eZ\Publish\Core\REST\Common\RequestParser
69
     */
70
    private $requestParser;
71
72
    /**
73
     * @param \eZ\Publish\Core\REST\Client\UserService $userService
74
     * @param \eZ\Publish\Core\REST\Client\HttpClient $client
75
     * @param \eZ\Publish\Core\REST\Common\Input\Dispatcher $inputDispatcher
76
     * @param \eZ\Publish\Core\REST\Common\Output\Visitor $outputVisitor
77
     * @param \eZ\Publish\Core\REST\Common\RequestParser $requestParser
78
     */
79 View Code Duplication
    public function __construct(UserService $userService, HttpClient $client, Dispatcher $inputDispatcher, Visitor $outputVisitor, RequestParser $requestParser)
80
    {
81
        $this->userService = $userService;
82
        $this->client = $client;
83
        $this->inputDispatcher = $inputDispatcher;
84
        $this->outputVisitor = $outputVisitor;
85
        $this->requestParser = $requestParser;
86
    }
87
88
    /**
89
     * Set session ID.
90
     *
91
     * Only for testing
92
     *
93
     * @param mixed $id
94
     *
95
     * @private
96
     */
97
    public function setSession($id)
98
    {
99
        if ($this->outputVisitor instanceof Sessionable) {
100
            $this->outputVisitor->setSession($id);
101
        }
102
    }
103
104
    /**
105
     * Creates a new RoleDraft for existing Role.
106
     *
107
     * @since 6.0
108
     *
109
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to create a role
110
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the Role already has a Role Draft that will need to be removed first
111
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a policy limitation in the $roleCreateStruct is not valid
112
     *
113
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
114
     *
115
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
116
     */
117
    public function createRoleDraft(APIRole $role)
118
    {
119
        $roleUpdateStruct = $this->newRoleUpdateStruct();
120
        $roleUpdateStruct->identifier = $role->identifier;
121
        $inputMessage = $this->outputVisitor->visit($roleUpdateStruct);
122
        $inputMessage->headers['Accept'] = $this->outputVisitor->getMediaType('Role');
123
124
        $result = $this->client->request(
125
            'POST',
126
            $this->requestParser->generate('roles'),
127
            $inputMessage
0 ignored issues
show
Documentation introduced by
$inputMessage is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a null|object<eZ\Publish\Core\REST\Common\Message>.

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...
128
        );
129
130
        $createdRole = $this->inputDispatcher->parse($result);
131
        $createdRoleValues = $this->requestParser->parse('role', $createdRole->id);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
132
133
        $createdPolicies = array();
134 View Code Duplication
        foreach ($roleCreateStruct->getPolicies() as $policyCreateStruct) {
0 ignored issues
show
Bug introduced by
The variable $roleCreateStruct does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
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...
135
            $inputMessage = $this->outputVisitor->visit($policyCreateStruct);
136
            $inputMessage->headers['Accept'] = $this->outputVisitor->getMediaType('Policy');
137
138
            $result = $this->client->request(
139
                'POST',
140
                $this->requestParser->generate('policies', array('role' => $createdRoleValues['role'])),
141
                $inputMessage
0 ignored issues
show
Documentation introduced by
$inputMessage is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a null|object<eZ\Publish\Core\REST\Common\Message>.

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...
142
            );
143
144
            $createdPolicy = $this->inputDispatcher->parse($result);
145
146
            // @todo Workaround for missing roleId in Policy XSD definition
147
            $createdPolicyArray = array(
148
                'id' => $createdPolicy->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
149
                'roleId' => $createdRole->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
150
                'module' => $createdPolicy->module,
0 ignored issues
show
Documentation introduced by
The property module does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
151
                'function' => $createdPolicy->function,
0 ignored issues
show
Documentation introduced by
The property function does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
152
            );
153
154
            $createdPolicy = new Policy($createdPolicyArray);
155
            $createdPolicies[] = $createdPolicy;
156
        }
157
158
        return new RoleDraft(
159
            array(
160
                'id' => $createdRole->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
161
                'identifier' => $createdRole->identifier,
0 ignored issues
show
Documentation introduced by
The property identifier does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
162
            ),
163
            $createdPolicies
164
        );
165
    }
166
167
    /**
168
     * Loads a RoleDraft for the given id.
169
     *
170
     * @since 6.0
171
     *
172
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role
173
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a role with the given id was not found
174
     *
175
     * @param mixed $id
176
     *
177
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
178
     */
179 View Code Duplication
    public function loadRoleDraft($id)
180
    {
181
        $response = $this->client->request(
182
            'GET',
183
            $id,
184
            new Message(
185
                array('Accept' => $this->outputVisitor->getMediaType('RoleDraft'))
186
            )
187
        );
188
189
        $loadedRoleDraft = $this->inputDispatcher->parse($response);
190
        $loadedRoleDraftValues = $this->requestParser->parse('role', $loadedRoleDraft->id);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
191
        $response = $this->client->request(
192
            'GET',
193
            $this->requestParser->generate('policies', array('role' => $loadedRoleDraftValues['role'])),
194
            new Message(
195
                array('Accept' => $this->outputVisitor->getMediaType('PolicyList'))
196
            )
197
        );
198
199
        $policies = $this->inputDispatcher->parse($response);
200
201
        return new RoleDraft(
202
            array(
203
                'id' => $loadedRoleDraft->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
204
                'identifier' => $loadedRoleDraft->identifier,
0 ignored issues
show
Documentation introduced by
The property identifier does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
205
            ),
206
            $policies
207
        );
208
    }
209
210
    /**
211
     * Loads a RoleDraft by the ID of the role it was created from.
212
     *
213
     * @param mixed $roleId ID of the role the draft was created from.
214
     *
215
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role
216
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a RoleDraft with the given id was not found
217
     *
218
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
219
     */
220
    public function loadRoleDraftByRoleId($roleId)
221
    {
222
        throw new \Exception('@todo: Implement.');
223
    }
224
225
    /**
226
     * Updates the properties of a role draft.
227
     *
228
     * @since 6.0
229
     *
230
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to update a role
231
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the identifier of the role already exists
232
     *
233
     * @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft
234
     * @param \eZ\Publish\API\Repository\Values\User\RoleUpdateStruct $roleUpdateStruct
235
     *
236
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
237
     */
238
    public function updateRoleDraft(APIRoleDraft $roleDraft, RoleUpdateStruct $roleUpdateStruct)
239
    {
240
        $inputMessage = $this->outputVisitor->visit($roleUpdateStruct);
241
        $inputMessage->headers['Accept'] = $this->outputVisitor->getMediaType('RoleDraft');
242
        $inputMessage->headers['X-HTTP-Method-Override'] = 'PATCH';
243
244
        $result = $this->client->request(
245
            'POST',
246
            $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...
247
            $inputMessage
0 ignored issues
show
Documentation introduced by
$inputMessage is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a null|object<eZ\Publish\Core\REST\Common\Message>.

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...
248
        );
249
250
        return $this->inputDispatcher->parse($result);
251
    }
252
253
    /**
254
     * Adds a new policy to the role draft.
255
     *
256
     * @since 6.0
257
     *
258
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to add  a policy
259
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if limitation of the same type is repeated in policy create
260
     *                                                                        struct or if limitation is not allowed on module/function
261
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a limitation in the $policyCreateStruct is not valid
262
     *
263
     * @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft
264
     * @param \eZ\Publish\API\Repository\Values\User\PolicyCreateStruct $policyCreateStruct
265
     *
266
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
267
     */
268 View Code Duplication
    public function addPolicyByRoleDraft(APIRoleDraft $roleDraft, APIPolicyCreateStruct $policyCreateStruct)
269
    {
270
        $values = $this->requestParser->parse('role', $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...
271
        $inputMessage = $this->outputVisitor->visit($policyCreateStruct);
272
        $inputMessage->headers['Accept'] = $this->outputVisitor->getMediaType('Policy');
273
274
        $result = $this->client->request(
275
            'POST',
276
            $this->requestParser->generate('policies', array('role' => $values['role'])),
277
            $inputMessage
0 ignored issues
show
Documentation introduced by
$inputMessage is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a null|object<eZ\Publish\Core\REST\Common\Message>.

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...
278
        );
279
280
        $createdPolicy = $this->inputDispatcher->parse($result);
281
282
        // @todo Workaround for missing roleId in Policy XSD definition
283
        $createdPolicyArray = array(
284
            'id' => $createdPolicy->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
285
            'roleId' => $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
            'module' => $createdPolicy->module,
0 ignored issues
show
Documentation introduced by
The property module does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
287
            'function' => $createdPolicy->function,
0 ignored issues
show
Documentation introduced by
The property function does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
288
        );
289
290
        $createdPolicy = new Policy($createdPolicyArray);
291
292
        $existingPolicies = $roleDraft->getPolicies();
293
        $existingPolicies[] = $createdPolicy;
294
295
        return new RoleDraft(
296
            array(
297
                'id' => $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...
298
                'identifier' => $roleDraft->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...
299
            ),
300
            $existingPolicies
301
        );
302
    }
303
304
    /**
305
     * Removes a policy from a role draft.
306
     *
307
     * @since 6.0
308
     *
309
     *
310
     * @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft
311
     * @param PolicyDraft $policyDraft the policy to remove from the role
312
     * @return APIRoleDraft if the authenticated user is not allowed to remove a policy
313
     */
314 View Code Duplication
    public function removePolicyByRoleDraft(APIRoleDraft $roleDraft, PolicyDraft $policyDraft)
315
    {
316
        $values = $this->requestParser->parse('role', $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...
317
        $response = $this->client->request(
318
            'DELETE',
319
            $this->requestParser->generate(
320
                'policy',
321
                array(
322
                    'role' => $values['role'],
323
                    'policy' => $policyDraft->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...
324
                )
325
            ),
326
            new Message(
327
            // @todo: What media-type should we set here? Actually, it should be
328
            // all expected exceptions + none? Or is "PolicyDraft" correct,
329
            // since this is what is to be expected by the resource
330
            // identified by the URL?
331
                array('Accept' => $this->outputVisitor->getMediaType('PolicyDraft'))
332
            )
333
        );
334
335
        if (!empty($response->body)) {
336
            $this->inputDispatcher->parse($response);
337
        }
338
339
        return $this->loadRole($roleDraft->id);
0 ignored issues
show
Documentation introduced by
The property $id is declared protected in eZ\Publish\API\Repository\Values\User\Role. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
Bug Best Practice introduced by
The return type of return $this->loadRole($roleDraft->id); (eZ\Publish\Core\REST\Client\Values\User\Role) is incompatible with the return type declared by the interface eZ\Publish\API\Repositor...removePolicyByRoleDraft of type eZ\Publish\API\Repository\Values\User\RoleDraft.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
340
    }
341
342
    /**
343
     * Updates the limitations of a policy. The module and function cannot be changed and
344
     * the limitations are replaced by the ones in $roleUpdateStruct.
345
     *
346
     * @since 6.0
347
     *
348
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to update a policy
349
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if limitation of the same type is repeated in policy update
350
     *                                                                        struct or if limitation is not allowed on module/function
351
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a limitation in the $policyUpdateStruct is not valid
352
     *
353
     * @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft
354
     * @param \eZ\Publish\API\Repository\Values\User\PolicyDraft $policy
355
     * @param \eZ\Publish\API\Repository\Values\User\PolicyUpdateStruct $policyUpdateStruct
356
     *
357
     * @return \eZ\Publish\API\Repository\Values\User\PolicyDraft
358
     */
359 View Code Duplication
    public function updatePolicyByRoleDraft(APIRoleDraft $roleDraft, PolicyDraft $policy, APIPolicyUpdateStruct $policyUpdateStruct)
360
    {
361
        $values = $this->requestParser->parse('role', $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...
362
        $inputMessage = $this->outputVisitor->visit($policyUpdateStruct);
363
        $inputMessage->headers['Accept'] = $this->outputVisitor->getMediaType('Policy');
364
        $inputMessage->headers['X-HTTP-Method-Override'] = 'PATCH';
365
366
        $result = $this->client->request(
367
            'POST',
368
            $this->requestParser->generate(
369
                'policy',
370
                array(
371
                    'role' => $values['role'],
372
                    'policy' => $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...
373
                )
374
            ),
375
            $inputMessage
0 ignored issues
show
Documentation introduced by
$inputMessage is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a null|object<eZ\Publish\Core\REST\Common\Message>.

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...
376
        );
377
378
        return $this->inputDispatcher->parse($result);
379
    }
380
381
    /**
382
     * Deletes the given role.
383
     *
384
     * @since 6.0
385
     *
386
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to delete this role
387
     *
388
     * @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft
389
     */
390 View Code Duplication
    public function deleteRoleDraft(APIRoleDraft $roleDraft)
391
    {
392
        $response = $this->client->request(
393
            'DELETE',
394
            $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...
395
            new Message(
396
            // @todo: What media-type should we set here? Actually, it should be
397
            // all expected exceptions + none? Or is "RoleDraft" correct,
398
            // since this is what is to be expected by the resource
399
            // identified by the URL?
400
                array('Accept' => $this->outputVisitor->getMediaType('RoleDraft'))
401
            )
402
        );
403
404
        if (!empty($response->body)) {
405
            $this->inputDispatcher->parse($response);
406
        }
407
    }
408
409
    /**
410
     * Publishes a given Role draft.
411
     *
412
     * @since 6.0
413
     *
414
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to delete this role
415
     *
416
     * @param \eZ\Publish\API\Repository\Values\User\RoleDraft $roleDraft
417
     */
418
    public function publishRoleDraft(APIRoleDraft $roleDraft)
419
    {
420
        throw new \Exception('@todo: Implement.');
421
    }
422
423
    /**
424
     * Creates a new RoleDraft.
425
     *
426
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to create a role
427
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the name of the role already exists or if limitation of the
428
     *                                                                        same type is repeated in the policy create struct or if
429
     *                                                                        limitation is not allowed on module/function
430
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a policy limitation in the $roleCreateStruct is not valid
431
     *
432
     * @param \eZ\Publish\API\Repository\Values\User\RoleCreateStruct $roleCreateStruct
433
     *
434
     * @return \eZ\Publish\API\Repository\Values\User\RoleDraft
435
     */
436
    public function createRole(APIRoleCreateStruct $roleCreateStruct)
437
    {
438
        $inputMessage = $this->outputVisitor->visit($roleCreateStruct);
439
        $inputMessage->headers['Accept'] = $this->outputVisitor->getMediaType('Role');
440
441
        $result = $this->client->request(
442
            'POST',
443
            $this->requestParser->generate('roles'),
444
            $inputMessage
0 ignored issues
show
Documentation introduced by
$inputMessage is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a null|object<eZ\Publish\Core\REST\Common\Message>.

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...
445
        );
446
447
        $createdRole = $this->inputDispatcher->parse($result);
448
        $createdRoleValues = $this->requestParser->parse('role', $createdRole->id);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
449
450
        $createdPolicies = array();
451 View Code Duplication
        foreach ($roleCreateStruct->getPolicies() as $policyCreateStruct) {
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...
452
            $inputMessage = $this->outputVisitor->visit($policyCreateStruct);
453
            $inputMessage->headers['Accept'] = $this->outputVisitor->getMediaType('Policy');
454
455
            $result = $this->client->request(
456
                'POST',
457
                $this->requestParser->generate('policies', array('role' => $createdRoleValues['role'])),
458
                $inputMessage
0 ignored issues
show
Documentation introduced by
$inputMessage is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a null|object<eZ\Publish\Core\REST\Common\Message>.

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...
459
            );
460
461
            $createdPolicy = $this->inputDispatcher->parse($result);
462
463
            // @todo Workaround for missing roleId in Policy XSD definition
464
            $createdPolicyArray = array(
465
                'id' => $createdPolicy->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
466
                'roleId' => $createdRole->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
467
                'module' => $createdPolicy->module,
0 ignored issues
show
Documentation introduced by
The property module does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
468
                'function' => $createdPolicy->function,
0 ignored issues
show
Documentation introduced by
The property function does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
469
            );
470
471
            $createdPolicy = new Policy($createdPolicyArray);
472
            $createdPolicies[] = $createdPolicy;
473
        }
474
475
        return new RoleDraft(
476
            array(
477
                'id' => $createdRole->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
478
                'identifier' => $createdRole->identifier,
0 ignored issues
show
Documentation introduced by
The property identifier does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
479
            ),
480
            $createdPolicies
481
        );
482
    }
483
484
    /**
485
     * Updates the name of the role.
486
     *
487
     * @deprecated since 6.0, use {@see updateRoleDraft}
488
     *
489
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to update a role
490
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if the name of the role already exists
491
     *
492
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
493
     * @param \eZ\Publish\API\Repository\Values\User\RoleUpdateStruct $roleUpdateStruct
494
     *
495
     * @return \eZ\Publish\API\Repository\Values\User\Role
496
     */
497
    public function updateRole(APIRole $role, RoleUpdateStruct $roleUpdateStruct)
498
    {
499
        $inputMessage = $this->outputVisitor->visit($roleUpdateStruct);
500
        $inputMessage->headers['Accept'] = $this->outputVisitor->getMediaType('Role');
501
        $inputMessage->headers['X-HTTP-Method-Override'] = 'PATCH';
502
503
        $result = $this->client->request(
504
            'POST',
505
            $role->id,
506
            $inputMessage
0 ignored issues
show
Documentation introduced by
$inputMessage is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a null|object<eZ\Publish\Core\REST\Common\Message>.

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...
507
        );
508
509
        return $this->inputDispatcher->parse($result);
510
    }
511
512
    /**
513
     * Adds a new policy to the role.
514
     *
515
     * @deprecated since 6.0, use {@see addPolicyByRoleDraft}
516
     *
517
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to add  a policy
518
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if limitation of the same type is repeated in policy create
519
     *                                                                        struct or if limitation is not allowed on module/function
520
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a limitation in the $policyCreateStruct is not valid
521
     *
522
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
523
     * @param \eZ\Publish\API\Repository\Values\User\PolicyCreateStruct $policyCreateStruct
524
     *
525
     * @return \eZ\Publish\API\Repository\Values\User\Role
526
     */
527 View Code Duplication
    public function addPolicy(APIRole $role, APIPolicyCreateStruct $policyCreateStruct)
528
    {
529
        $values = $this->requestParser->parse('role', $role->id);
530
        $inputMessage = $this->outputVisitor->visit($policyCreateStruct);
531
        $inputMessage->headers['Accept'] = $this->outputVisitor->getMediaType('Policy');
532
533
        $result = $this->client->request(
534
            'POST',
535
            $this->requestParser->generate('policies', array('role' => $values['role'])),
536
            $inputMessage
0 ignored issues
show
Documentation introduced by
$inputMessage is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a null|object<eZ\Publish\Core\REST\Common\Message>.

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...
537
        );
538
539
        $createdPolicy = $this->inputDispatcher->parse($result);
540
541
        // @todo Workaround for missing roleId in Policy XSD definition
542
        $createdPolicyArray = array(
543
            'id' => $createdPolicy->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
544
            'roleId' => $role->id,
545
            'module' => $createdPolicy->module,
0 ignored issues
show
Documentation introduced by
The property module does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
546
            'function' => $createdPolicy->function,
0 ignored issues
show
Documentation introduced by
The property function does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
547
        );
548
549
        $createdPolicy = new Policy($createdPolicyArray);
550
551
        $existingPolicies = $role->getPolicies();
552
        $existingPolicies[] = $createdPolicy;
553
554
        return new Role(
555
            array(
556
                'id' => $role->id,
557
                'identifier' => $role->identifier,
558
            ),
559
            $existingPolicies
560
        );
561
    }
562
563
    /**
564
     * Removes a policy from the role.
565
     *
566
     * @deprecated since 5.3, use {@link removePolicyByRoleDraft()} instead.
567
     *
568
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a policy
569
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if policy does not belong to the given role
570
     *
571
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
572
     * @param \eZ\Publish\API\Repository\Values\User\Policy $policy the policy to remove from the role
573
     *
574
     * @return \eZ\Publish\API\Repository\Values\User\Role the updated role
575
     */
576 View Code Duplication
    public function removePolicy(APIRole $role, APIPolicy $policy)
577
    {
578
        $values = $this->requestParser->parse('role', $role->id);
579
        $response = $this->client->request(
580
            'DELETE',
581
            $this->requestParser->generate(
582
                'policy',
583
                array(
584
                    'role' => $values['role'],
585
                    'policy' => $policy->id,
586
                )
587
            ),
588
            new Message(
589
                // @todo: What media-type should we set here? Actually, it should be
590
                // all expected exceptions + none? Or is "Policy" correct,
591
                // since this is what is to be expected by the resource
592
                // identified by the URL?
593
                array('Accept' => $this->outputVisitor->getMediaType('Policy'))
594
            )
595
        );
596
597
        if (!empty($response->body)) {
598
            $this->inputDispatcher->parse($response);
599
        }
600
601
        return $this->loadRole($role->id);
602
    }
603
604
    /**
605
     * Deletes a policy.
606
     *
607
     * @deprecated since 6.0, use {@link removePolicyByRoleDraft()} instead.
608
     *
609
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a policy
610
     *
611
     * @param \eZ\Publish\API\Repository\Values\User\Policy $policy the policy to delete
612
     */
613
    public function deletePolicy(APIPolicy $policy)
614
    {
615
        throw new \Exception('@todo: Implement.');
616
    }
617
618
    /**
619
     * Updates the limitations of a policy. The module and function cannot be changed and
620
     * the limitations are replaced by the ones in $roleUpdateStruct.
621
     *
622
     * @deprecated since 6.0, use {@link updatePolicyByRoleDraft()} instead.
623
     *
624
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to update a policy
625
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException if limitation of the same type is repeated in policy update
626
     *                                                                        struct or if limitation is not allowed on module/function
627
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if a limitation in the $policyUpdateStruct is not valid
628
     *
629
     * @param \eZ\Publish\API\Repository\Values\User\PolicyUpdateStruct $policyUpdateStruct
630
     * @param \eZ\Publish\API\Repository\Values\User\Policy $policy
631
     *
632
     * @return \eZ\Publish\API\Repository\Values\User\Policy
633
     */
634 View Code Duplication
    public function updatePolicy(APIPolicy $policy, APIPolicyUpdateStruct $policyUpdateStruct)
635
    {
636
        $values = $this->requestParser->parse('role', $policy->roleId);
637
        $inputMessage = $this->outputVisitor->visit($policyUpdateStruct);
638
        $inputMessage->headers['Accept'] = $this->outputVisitor->getMediaType('Policy');
639
        $inputMessage->headers['X-HTTP-Method-Override'] = 'PATCH';
640
641
        $result = $this->client->request(
642
            'POST',
643
            $this->requestParser->generate(
644
                'policy',
645
                array(
646
                    'role' => $values['role'],
647
                    'policy' => $policy->id,
648
                )
649
            ),
650
            $inputMessage
0 ignored issues
show
Documentation introduced by
$inputMessage is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a null|object<eZ\Publish\Core\REST\Common\Message>.

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...
651
        );
652
653
        return $this->inputDispatcher->parse($result);
654
    }
655
656
    /**
657
     * Loads a role for the given id.
658
     *
659
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role
660
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a role with the given name was not found
661
     *
662
     * @param mixed $id
663
     *
664
     * @return \eZ\Publish\API\Repository\Values\User\Role
665
     */
666 View Code Duplication
    public function loadRole($id)
667
    {
668
        $response = $this->client->request(
669
            'GET',
670
            $id,
671
            new Message(
672
                array('Accept' => $this->outputVisitor->getMediaType('Role'))
673
            )
674
        );
675
676
        $loadedRole = $this->inputDispatcher->parse($response);
677
        $loadedRoleValues = $this->requestParser->parse('role', $loadedRole->id);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
678
        $response = $this->client->request(
679
            'GET',
680
            $this->requestParser->generate('policies', array('role' => $loadedRoleValues['role'])),
681
            new Message(
682
                array('Accept' => $this->outputVisitor->getMediaType('PolicyList'))
683
            )
684
        );
685
686
        $policies = $this->inputDispatcher->parse($response);
687
688
        return new Role(
689
            array(
690
                'id' => $loadedRole->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
691
                'identifier' => $loadedRole->identifier,
0 ignored issues
show
Documentation introduced by
The property identifier does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
692
            ),
693
            $policies
0 ignored issues
show
Documentation introduced by
$policies is of type object<eZ\Publish\API\Re...ory\Values\ValueObject>, but the function expects a array<integer,object<eZ\...ry\Values\User\Policy>>.

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...
694
        );
695
    }
696
697
    /**
698
     * Loads a role for the given name.
699
     *
700
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role
701
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a role with the given name was not found
702
     *
703
     * @param string $name
704
     *
705
     * @return \eZ\Publish\API\Repository\Values\User\Role
706
     */
707 View Code Duplication
    public function loadRoleByIdentifier($name)
708
    {
709
        $response = $this->client->request(
710
            'GET',
711
            $this->requestParser->generate('roleByIdentifier', array('role' => $name)),
712
            new Message(
713
                array('Accept' => $this->outputVisitor->getMediaType('RoleList'))
714
            )
715
        );
716
717
        $result = $this->inputDispatcher->parse($response);
718
719
        return reset($result);
720
    }
721
722
    /**
723
     * Loads all roles.
724
     *
725
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read the roles
726
     *
727
     * @return \eZ\Publish\API\Repository\Values\User\Role[]
728
     */
729
    public function loadRoles()
730
    {
731
        $response = $this->client->request(
732
            'GET',
733
            $this->requestParser->generate('roles'),
734
            new Message(
735
                array('Accept' => $this->outputVisitor->getMediaType('RoleList'))
736
            )
737
        );
738
739
        return $this->inputDispatcher->parse($response);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->inputDispatcher->parse($response); (eZ\Publish\API\Repository\Values\ValueObject) is incompatible with the return type declared by the interface eZ\Publish\API\Repository\RoleService::loadRoles of type eZ\Publish\API\Repository\Values\User\Role[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
740
    }
741
742
    /**
743
     * Deletes the given role.
744
     *
745
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to delete this role
746
     *
747
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
748
     */
749 View Code Duplication
    public function deleteRole(APIRole $role)
750
    {
751
        $response = $this->client->request(
752
            'DELETE',
753
            $role->id,
754
            new Message(
755
                // @todo: What media-type should we set here? Actually, it should be
756
                // all expected exceptions + none? Or is "Role" correct,
757
                // since this is what is to be expected by the resource
758
                // identified by the URL?
759
                array('Accept' => $this->outputVisitor->getMediaType('Role'))
760
            )
761
        );
762
763
        if (!empty($response->body)) {
764
            $this->inputDispatcher->parse($response);
765
        }
766
    }
767
768
    /**
769
     * Loads all policies from roles which are assigned to a user or to user groups to which the user belongs.
770
     *
771
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if a user with the given id was not found
772
     *
773
     * @param mixed $userId
774
     *
775
     * @return \eZ\Publish\API\Repository\Values\User\Policy[]
776
     */
777 View Code Duplication
    public function loadPoliciesByUserId($userId)
778
    {
779
        $values = $this->requestParser->parse('user', $userId);
780
        $response = $this->client->request(
781
            'GET',
782
            $this->requestParser->generate('userPolicies', array('user' => $values['user'])),
783
            new Message(
784
                array('Accept' => $this->outputVisitor->getMediaType('PolicyList'))
785
            )
786
        );
787
788
        return $this->inputDispatcher->parse($response);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->inputDispatcher->parse($response); (eZ\Publish\API\Repository\Values\ValueObject) is incompatible with the return type declared by the interface eZ\Publish\API\Repositor...e::loadPoliciesByUserId of type eZ\Publish\API\Repository\Values\User\Policy[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
789
    }
790
791
    /**
792
     * Assigns a role to the given user group.
793
     *
794
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to assign a role
795
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if $roleLimitation is not valid
796
     *
797
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
798
     * @param \eZ\Publish\API\Repository\Values\User\UserGroup $userGroup
799
     * @param \eZ\Publish\API\Repository\Values\User\Limitation\RoleLimitation $roleLimitation an optional role limitation (which is either a subtree limitation or section limitation)
800
     */
801 View Code Duplication
    public function assignRoleToUserGroup(APIRole $role, UserGroup $userGroup, RoleLimitation $roleLimitation = null)
802
    {
803
        $roleAssignment = new RoleAssignment(
804
            array(
805
                'role' => $role,
806
                'limitation' => $roleLimitation,
807
            )
808
        );
809
810
        $inputMessage = $this->outputVisitor->visit($roleAssignment);
811
        $inputMessage->headers['Accept'] = $this->outputVisitor->getMediaType('RoleAssignmentList');
812
813
        $result = $this->client->request(
814
            'POST',
815
            $this->requestParser->generate('groupRoleAssignments', array('group' => $userGroup->id)),
816
            $inputMessage
0 ignored issues
show
Documentation introduced by
$inputMessage is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a null|object<eZ\Publish\Core\REST\Common\Message>.

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...
817
        );
818
819
        $this->inputDispatcher->parse($result);
820
    }
821
822
    /**
823
     * removes a role from the given user group.
824
     *
825
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a role
826
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException  If the role is not assigned to the given user group
827
     *
828
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
829
     * @param \eZ\Publish\API\Repository\Values\User\UserGroup $userGroup
830
     */
831 View Code Duplication
    public function unassignRoleFromUserGroup(APIRole $role, UserGroup $userGroup)
832
    {
833
        $values = $this->requestParser->parse('group', $userGroup->id);
834
        $userGroupId = $values['group'];
835
836
        $values = $this->requestParser->parse('role', $role->id);
837
        $roleId = $values['role'];
838
839
        $response = $this->client->request(
840
            'DELETE',
841
            $this->requestParser->generate('groupRoleAssignment', array('group' => $userGroupId, 'role' => $roleId)),
842
            new Message(
843
                // @todo: What media-type should we set here? Actually, it should be
844
                // all expected exceptions + none? Or is "RoleAssignmentList" correct,
845
                // since this is what is to be expected by the resource
846
                // identified by the URL?
847
                array('Accept' => $this->outputVisitor->getMediaType('RoleAssignmentList'))
848
            )
849
        );
850
851
        if (!empty($response->body)) {
852
            $this->inputDispatcher->parse($response);
853
        }
854
    }
855
856
    /**
857
     * Assigns a role to the given user.
858
     *
859
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to assign a role
860
     * @throws \eZ\Publish\API\Repository\Exceptions\LimitationValidationException if $roleLimitation is not valid
861
     *
862
     * @todo add limitations
863
     *
864
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
865
     * @param \eZ\Publish\API\Repository\Values\User\User $user
866
     * @param \eZ\Publish\API\Repository\Values\User\Limitation\RoleLimitation $roleLimitation an optional role limitation (which is either a subtree limitation or section limitation)
867
     */
868 View Code Duplication
    public function assignRoleToUser(APIRole $role, User $user, RoleLimitation $roleLimitation = null)
869
    {
870
        $roleAssignment = new RoleAssignment(
871
            array(
872
                'role' => $role,
873
                'limitation' => $roleLimitation,
874
            )
875
        );
876
877
        $inputMessage = $this->outputVisitor->visit($roleAssignment);
878
        $inputMessage->headers['Accept'] = $this->outputVisitor->getMediaType('RoleAssignmentList');
879
880
        $result = $this->client->request(
881
            'POST',
882
            $this->requestParser->generate('userRoleAssignments', array('user' => $user->id)),
883
            $inputMessage
0 ignored issues
show
Documentation introduced by
$inputMessage is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a null|object<eZ\Publish\Core\REST\Common\Message>.

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...
884
        );
885
886
        $this->inputDispatcher->parse($result);
887
    }
888
889
    /**
890
     * removes a role from the given user.
891
     *
892
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a role
893
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If the role is not assigned to the user
894
     *
895
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
896
     * @param \eZ\Publish\API\Repository\Values\User\User $user
897
     */
898 View Code Duplication
    public function unassignRoleFromUser(APIRole $role, User $user)
899
    {
900
        $values = $this->requestParser->parse('user', $user->id);
901
        $userId = $values['user'];
902
903
        $values = $this->requestParser->parse('role', $role->id);
904
        $roleId = $values['role'];
905
906
        $response = $this->client->request(
907
            'DELETE',
908
            $this->requestParser->generate('userRoleAssignment', array('user' => $userId, 'role' => $roleId)),
909
            new Message(
910
                // @todo: What media-type should we set here? Actually, it should be
911
                // all expected exceptions + none? Or is "RoleAssignmentList" correct,
912
                // since this is what is to be expected by the resource
913
                // identified by the URL?
914
                array('Accept' => $this->outputVisitor->getMediaType('RoleAssignmentList'))
915
            )
916
        );
917
918
        if (!empty($response->body)) {
919
            $this->inputDispatcher->parse($response);
920
        }
921
    }
922
923
    /**
924
     * Removes the given role assignment.
925
     *
926
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to remove a role assignment
927
     *
928
     * @param \eZ\Publish\API\Repository\Values\User\RoleAssignment $roleAssignment
929
     */
930
    public function removeRoleAssignment(APIRoleAssignment $roleAssignment)
931
    {
932
        throw new \Exception('@todo: Implement.');
933
    }
934
935
    /**
936
     * Loads a user assignment for the given id.
937
     *
938
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read this role
939
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If the role assignment was not found
940
     *
941
     * @param mixed $roleAssignmentId
942
     *
943
     * @return \eZ\Publish\API\Repository\Values\User\RoleAssignment
944
     */
945
    public function loadRoleAssignment($roleAssignmentId)
946
    {
947
        throw new \Exception('@todo: Implement.');
948
    }
949
950
    /**
951
     * Returns the assigned user and user groups to this role.
952
     *
953
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read a role
954
     *
955
     * @param \eZ\Publish\API\Repository\Values\User\Role $role
956
     *
957
     * @return \eZ\Publish\API\Repository\Values\User\RoleAssignment[]
958
     */
959
    public function getRoleAssignments(APIRole $role)
960
    {
961
        throw new \Exception('@todo: Implement.');
962
    }
963
964
    /**
965
     * @see \eZ\Publish\API\Repository\RoleService::getRoleAssignmentsForUser()
966
     */
967 View Code Duplication
    public function getRoleAssignmentsForUser(User $user, $inherited = false)
968
    {
969
        $response = $this->client->request(
970
            'GET',
971
            $this->requestParser->generate('userRoleAssignments'),
972
            new Message(
973
                array('Accept' => $this->outputVisitor->getMediaType('RoleAssignmentList'))
974
            )
975
        );
976
977
        $roleAssignments = $this->inputDispatcher->parse($response);
978
979
        $userRoleAssignments = array();
980
        foreach ($roleAssignments as $roleAssignment) {
0 ignored issues
show
Bug introduced by
The expression $roleAssignments of type object<eZ\Publish\API\Re...ory\Values\ValueObject> is not traversable.
Loading history...
981
            $userRoleAssignments[] = new UserRoleAssignment(
982
                array(
983
                    'limitation' => $roleAssignment->getRoleLimitation(),
984
                    'role' => $roleAssignment->getRole(),
985
                    'user' => $user,
986
                )
987
            );
988
        }
989
990
        return $userRoleAssignments;
991
    }
992
993
    /**
994
     * Returns the roles assigned to the given user group.
995
     *
996
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException if the authenticated user is not allowed to read a user group
997
     *
998
     * @param \eZ\Publish\API\Repository\Values\User\UserGroup $userGroup
999
     *
1000
     * @return \eZ\Publish\API\Repository\Values\User\UserGroupRoleAssignment[]
1001
     */
1002 View Code Duplication
    public function getRoleAssignmentsForUserGroup(UserGroup $userGroup)
1003
    {
1004
        $response = $this->client->request(
1005
            'GET',
1006
            $this->requestParser->generate('groupRoleAssignments'),
1007
            new Message(
1008
                array('Accept' => $this->outputVisitor->getMediaType('RoleAssignmentList'))
1009
            )
1010
        );
1011
1012
        $roleAssignments = $this->inputDispatcher->parse($response);
1013
1014
        $userGroupRoleAssignments = array();
1015
        foreach ($roleAssignments as $roleAssignment) {
0 ignored issues
show
Bug introduced by
The expression $roleAssignments of type object<eZ\Publish\API\Re...ory\Values\ValueObject> is not traversable.
Loading history...
1016
            $userGroupRoleAssignments[] = new UserGroupRoleAssignment(
1017
                array(
1018
                    'limitation' => $roleAssignment->getRoleLimitation(),
1019
                    'role' => $roleAssignment->getRole(),
1020
                    'userGroup' => $userGroup,
1021
                )
1022
            );
1023
        }
1024
1025
        return $userGroupRoleAssignments;
1026
    }
1027
1028
    /**
1029
     * Instantiates a role create class.
1030
     *
1031
     * @param string $name
1032
     *
1033
     * @return \eZ\Publish\API\Repository\Values\User\RoleCreateStruct
1034
     */
1035
    public function newRoleCreateStruct($name)
1036
    {
1037
        return new Values\User\RoleCreateStruct($name);
1038
    }
1039
1040
    /**
1041
     * Instantiates a policy create class.
1042
     *
1043
     * @param string $module
1044
     * @param string $function
1045
     *
1046
     * @return \eZ\Publish\API\Repository\Values\User\PolicyCreateStruct
1047
     */
1048
    public function newPolicyCreateStruct($module, $function)
1049
    {
1050
        return new PolicyCreateStruct($module, $function);
1051
    }
1052
1053
    /**
1054
     * Instantiates a policy update class.
1055
     *
1056
     * @return \eZ\Publish\API\Repository\Values\User\PolicyUpdateStruct
1057
     */
1058
    public function newPolicyUpdateStruct()
1059
    {
1060
        return new PolicyUpdateStruct();
1061
    }
1062
1063
    /**
1064
     * Instantiates a policy update class.
1065
     *
1066
     * @return \eZ\Publish\API\Repository\Values\User\RoleUpdateStruct
1067
     */
1068
    public function newRoleUpdateStruct()
1069
    {
1070
        return new RoleUpdateStruct();
1071
    }
1072
1073
    /**
1074
     * Returns the LimitationType registered with the given identifier.
1075
     *
1076
     * @param string $identifier
1077
     *
1078
     * @return \eZ\Publish\SPI\Limitation\Type
1079
     *
1080
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException if there is no LimitationType with $identifier
1081
     */
1082
    public function getLimitationType($identifier)
1083
    {
1084
        throw new \eZ\Publish\API\Repository\Exceptions\NotImplementedException(__METHOD__);
1085
    }
1086
1087
    /**
1088
     * Returns the LimitationType's assigned to a given module/function.
1089
     *
1090
     * Typically used for:
1091
     *  - Internal validation limitation value use on Policies
1092
     *  - Role admin gui for editing policy limitations incl list limitation options via valueSchema()
1093
     *
1094
     * @param string $module Legacy name of "controller", it's a unique identifier like "content"
1095
     * @param string $function Legacy name of a controller "action", it's a unique within the controller like "read"
1096
     *
1097
     * @return \eZ\Publish\SPI\Limitation\Type[]
1098
     *
1099
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException If module/function to limitation type mapping
1100
     *                                                                 refers to a non existing identifier.
1101
     */
1102
    public function getLimitationTypesByModuleFunction($module, $function)
1103
    {
1104
        throw new \eZ\Publish\API\Repository\Exceptions\NotImplementedException(__METHOD__);
1105
    }
1106
}
1107