Completed
Push — 1.0 ( 0d48a1...9224b3 )
by Valentin
01:29
created

UserManager::update()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 25
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 2

Importance

Changes 4
Bugs 0 Features 1
Metric Value
c 4
b 0
f 1
dl 0
loc 25
ccs 11
cts 11
cp 1
rs 8.8571
cc 2
eloc 11
nc 2
nop 1
crap 2
1
<?php
2
3
/**
4
 * This file is part of Transfer.
5
 *
6
 * For the full copyright and license information, please view the LICENSE file located
7
 * in the root directory.
8
 */
9
namespace Transfer\EzPlatform\Repository\Manager;
10
11
use eZ\Publish\API\Repository\ContentTypeService;
12
use eZ\Publish\API\Repository\UserService;
13
use eZ\Publish\API\Repository\Values\User\User;
14
use eZ\Publish\API\Repository\Values\User\UserGroup;
15
use Psr\Log\LoggerAwareInterface;
16
use Psr\Log\LoggerInterface;
17
use Transfer\Data\ObjectInterface;
18
use Transfer\Data\ValueObject;
19
use Transfer\EzPlatform\Exception\ObjectNotFoundException;
20
use Transfer\EzPlatform\Exception\UnsupportedObjectOperationException;
21
use Transfer\EzPlatform\Repository\Values\UserGroupObject;
22
use Transfer\EzPlatform\Repository\Values\UserObject;
23
use Transfer\EzPlatform\Repository\Manager\Type\CreatorInterface;
24
use Transfer\EzPlatform\Repository\Manager\Type\FinderInterface;
25
use Transfer\EzPlatform\Repository\Manager\Type\RemoverInterface;
26
use Transfer\EzPlatform\Repository\Manager\Type\UpdaterInterface;
27
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
28
use eZ\Publish\API\Repository\Exceptions\InvalidArgumentException;
29
30
/**
31
 * User manager.
32
 *
33
 * @internal
34
 */
35
class UserManager implements LoggerAwareInterface, CreatorInterface, UpdaterInterface, RemoverInterface, FinderInterface
36
{
37
    /**
38
     * @var LoggerInterface
39
     */
40
    private $logger;
41
42
    /**
43
     * @var array
44
     */
45
    private $options;
46
47
    /**
48
     * @var UserService
49
     */
50
    private $userService;
51
52
    /**
53
     * @var ContentTypeService
54
     */
55
    private $contentTypeService;
56
57
    /**
58
     * @var UserGroupManager
59
     */
60
    private $userGroupManager;
61
62
    /**
63
     * @param array              $options
64
     * @param UserService        $userService
65
     * @param ContentTypeService $contentTypeService
66
     * @param UserGroupManager   $userGroupManager
67
     */
68 5
    public function __construct(array $options, UserService $userService, ContentTypeService $contentTypeService, UserGroupManager $userGroupManager)
69
    {
70 5
        $this->options = $options;
71 5
        $this->userService = $userService;
72 5
        $this->contentTypeService = $contentTypeService;
73 5
        $this->userGroupManager = $userGroupManager;
74 5
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79 23
    public function setLogger(LoggerInterface $logger)
80
    {
81 23
        $this->logger = $logger;
82 23
    }
83
84
    /**
85
     * {@inheritdoc}
86
     */
87 10
    public function find(ValueObject $object)
88
    {
89
        try {
90 10
            if (isset($object->data['username'])) {
91 10
                $user = $this->userService->loadUserByLogin($object->data['username']);
92 8
            }
93 10
        } catch (NotFoundException $notFoundException) {
94
            // We'll throw our own exception later instead.
95
        }
96
97 10
        if (!isset($user)) {
98 5
            throw new ObjectNotFoundException(User::class, array('username'));
99
        }
100
101 8
        return $user;
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107 10
    public function create(ObjectInterface $object)
108
    {
109 6
        if (!$object instanceof UserObject) {
110 1
            throw new UnsupportedObjectOperationException(UserObject::class, get_class($object));
111
        }
112
113 5
        $this->ensureDefaults($object);
114
115 5
        $userCreateStruct = $this->userService->newUserCreateStruct(
116 5
            $object->data['username'],
117 5
            $object->data['email'],
118 5
            $object->data['password'],
119 5
            $object->data['main_language_code'],
120 5
            $this->getContentType($object)
121 5
        );
122
123 5
        $object->getMapper()->mapObjectToCreateStruct($userCreateStruct);
124
125 5
        $groups = [];
126 5
        foreach ($object->data['parents'] as $userGroup) {
127 5
            $userGroup = $this->userGroupManager->createOrUpdate($userGroup);
128 10
            if ($userGroup instanceof UserGroupObject) {
129 5
                $groups[] = $this->userGroupManager->find($userGroup);
130 5
            }
131 5
        }
132
133 5
        $user = $this->userService->createUser($userCreateStruct, $groups);
134 5
        $object->data['id'] = $user->getUserId();
135
136 5
        return $object;
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     */
142 10
    public function update(ObjectInterface $object)
143
    {
144 8
        if (!$object instanceof UserObject) {
145 1
            throw new UnsupportedObjectOperationException(UserObject::class, get_class($object));
146
        }
147
148 10
        $this->ensureDefaults($object);
149
150 8
        $user = $this->find($object);
151
152
        // Populate struct
153 8
        $userUpdateStruct = $this->userService->newUserUpdateStruct();
154 8
        $object->getMapper()->mapObjectToUpdateStruct($userUpdateStruct);
155
156
        // Update user
157 8
        $user = $this->userService->updateUser($user, $userUpdateStruct);
158
159
        // Assign user to usergroups
160 8
        $userGroups = $this->assignUserToUserGroups($user, $object->data['parents']);
161
162
        // Unassign user from usergroups
163 8
        $this->unassignUserFromUserGroups($user, $userGroups);
164
165 8
        return $object;
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171 10
    public function createOrUpdate(ObjectInterface $object)
172
    {
173 10
        if (!$object instanceof UserObject) {
174 1
            throw new UnsupportedObjectOperationException(UserObject::class, get_class($object));
175
        }
176
177
        try {
178 10
            $this->find($object);
179
180 8
            return $this->update($object);
181 5
        } catch (NotFoundException $notFound) {
182 5
            return $this->create($object);
183
        }
184
    }
185
186
    /**
187
     * {@inheritdoc}
188
     */
189 2
    public function remove(ObjectInterface $object)
190
    {
191 2
        if (!$object instanceof UserObject) {
192 1
            throw new UnsupportedObjectOperationException(UserObject::class, get_class($object));
193
        }
194
195 1
        $user = $this->find($object);
196
197 1
        if ($user) {
198 1
            $this->userService->deleteUser($user);
199 1
        }
200
201 1
        return true;
202
    }
203
204
    /**
205
     * Assigns a collection of Transfer user groups from an eZ user, and returns the once who were added.
206
     *
207
     * @param User              $user
208
     * @param UserGroupObject[] $userGroupObjects
209
     *
210
     * @return UserGroup[]
211
     */
212 8
    protected function assignUserToUserGroups(User $user, array $userGroupObjects)
213
    {
214 8
        $ezUserGroups = [];
215 8
        foreach ($userGroupObjects as $userGroup) {
216 8
            $userGroup = $this->userGroupManager->createOrUpdate($userGroup);
217 8
            if ($userGroup instanceof UserGroupObject) {
218 8
                $ezUserGroup = $this->userGroupManager->find($userGroup);
219 8
                if ($ezUserGroup) {
220 8
                    $ezUserGroups[$ezUserGroup->id] = $ezUserGroup;
221
                    try {
222 8
                        $this->userService->assignUserToUserGroup($user, $ezUserGroup);
223 8
                    } catch (InvalidArgumentException $alreadyAssignedException) {
224
                        // Ignore error about: user already assigned to usergroup.
225
                    }
226 8
                }
227 8
            }
228 8
        }
229
230 8
        return $ezUserGroups;
231
    }
232
233
    /**
234
     * Unassigns a collection of eZ UserGroups from an eZ User.
235
     *
236
     * @param User        $user
237
     * @param UserGroup[] $userGroups
238
     */
239 8
    protected function unassignUserFromUserGroups(User $user, array $userGroups)
240
    {
241 8
        $existingUserGroups = $this->userService->loadUserGroupsOfUser($user);
242 8
        foreach ($existingUserGroups as $existingUserGroup) {
243 8
            if (!array_key_exists($existingUserGroup->id, $userGroups)) {
244 7
                $this->userService->unAssignUserFromUserGroup($user, $existingUserGroup);
245 7
            }
246 8
        }
247 8
    }
248
249
    /**
250
     * @param UserObject $object
251
     *
252
     * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType|null
253
     */
254 5
    protected function getContentType(UserObject $object)
255
    {
256 5
        if (isset($object->data['content_type'])) {
257 1
            return $this->contentTypeService->loadContentTypeByIdentifier($object->data['content_type']);
258
        }
259
260 4
        return;
261
    }
262
263
    /**
264
     * @param UserObject $object
265
     */
266 10
    private function ensureDefaults(UserObject $object)
267
    {
268 10
        $defaultData = ['main_language_code'];
269
270 10
        foreach ($defaultData as $defaultOption) {
271 10
            if (!isset($object->data[$defaultOption])) {
272 1
                $object->data[$defaultOption] = $this->options[$defaultOption];
273 1
            }
274 10
        }
275 10
    }
276
}
277