Passed
Push — master ( a565e0...939e78 )
by Gaetano
09:53
created

UserManager::create()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 52
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 6.0146

Importance

Changes 0
Metric Value
cc 6
eloc 29
c 0
b 0
f 0
nc 9
nop 1
dl 0
loc 52
rs 8.8337
ccs 25
cts 27
cp 0.9259
crap 6.0146

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Kaliop\eZMigrationBundle\Core\Executor;
4
5
use eZ\Publish\API\Repository\Values\User\User;
6
use Kaliop\eZMigrationBundle\API\Collection\UserCollection;
7
use Kaliop\eZMigrationBundle\API\Exception\InvalidStepDefinitionException;
8
use Kaliop\eZMigrationBundle\Core\Matcher\UserGroupMatcher;
9
use Kaliop\eZMigrationBundle\Core\Matcher\UserMatcher;
10
11
/**
12
 * Handles user migrations.
13
 */
14
class UserManager extends RepositoryExecutor
15
{
16
    protected $supportedStepTypes = array('user');
17
    protected $supportedActions = array('create', 'load', 'update', 'delete');
18
19
    protected $userMatcher;
20
21
    protected $userGroupMatcher;
22 96
23
    public function __construct(UserMatcher $userMatcher, UserGroupMatcher $userGroupMatcher)
24 96
    {
25 96
        $this->userMatcher = $userMatcher;
26 96
        $this->userGroupMatcher = $userGroupMatcher;
27
    }
28
29
    /**
30
     * Creates a user based on the DSL instructions.
31
     *
32
     * @todo allow setting extra profile attributes!
33 2
     */
34
    protected function create($step)
35 2
    {
36
        if (!isset($step->dsl['groups'])) {
37
            throw new InvalidStepDefinitionException('No user groups set to create user in.');
38
        }
39 2
40
        if (!is_array($step->dsl['groups'])) {
41
            $step->dsl['groups'] = array($step->dsl['groups']);
42
        }
43 2
44 2
        $userService = $this->repository->getUserService();
45
        $contentTypeService = $this->repository->getContentTypeService();
46 2
47 2
        $userGroups = array();
48 2
        foreach ($step->dsl['groups'] as $groupId) {
49 2
            $groupId = $this->referenceResolver->resolveReference($groupId);
50
            $userGroup = $this->userGroupMatcher->matchOneByKey($groupId);
51
52
            // q: in which case can we have no group? And should we throw an exception?
53 2
            //if ($userGroup) {
54
                $userGroups[] = $userGroup;
55
            //}
56
        }
57 2
58
        $userContentType = $contentTypeService->loadContentTypeByIdentifier($this->getUserContentType($step));
59 2
60 2
        $userCreateStruct = $userService->newUserCreateStruct(
61 2
            $this->referenceResolver->resolveReference($step->dsl['username']),
62 2
            $this->referenceResolver->resolveReference($step->dsl['email']),
63 2
            $this->referenceResolver->resolveReference($step->dsl['password']),
64 2
            $this->getLanguageCode($step),
65
            $userContentType
66 2
        );
67 2
        $userCreateStruct->setField('first_name', $this->referenceResolver->resolveReference($step->dsl['first_name']));
68
        $userCreateStruct->setField('last_name', $this->referenceResolver->resolveReference($step->dsl['last_name']));
69
70 2
        // Create the user
71
        $user = $userService->createUser($userCreateStruct, $userGroups);
72 2
73
        if (isset($step->dsl['roles'])) {
74 2
            $roleService = $this->repository->getRoleService();
75
            // we support both Ids and Identifiers
76
            foreach ($step->dsl['roles'] as $roleId) {
77 1
                $roleId = $this->referenceResolver->resolveReference($roleId);
78
                $role = $this->roleMatcher->matchOneByKey($roleId);
0 ignored issues
show
Bug Best Practice introduced by
The property roleMatcher does not exist on Kaliop\eZMigrationBundle\Core\Executor\UserManager. Did you maybe forget to declare it?
Loading history...
79 1
                $roleService->assignRoleToUser($role, $user);
80
            }
81 1
        }
82
83 1
        $this->setReferences($user, $step);
84
85
        return $user;
86
    }
87
88
    protected function load($step)
89
    {
90
        $userCollection = $this->matchUsers('load', $step);
91 1
92
        $this->validateResultsCount($userCollection, $step);
93 1
94
        $this->setReferences($userCollection, $step);
95 1
96
        return $userCollection;
97
    }
98
99 1
    /**
100
     * Method to handle the update operation of the migration instructions
101
     *
102
     * @todo allow setting extra profile attributes!
103 1
     */
104
    protected function update($step)
105 1
    {
106
        $userCollection = $this->matchUsers('user', $step);
107 1
108
        $this->validateResultsCount($userCollection, $step);
109 1
110 1
        if (count($userCollection) > 1 && isset($step->dsl['email'])) {
111
            throw new \Exception("Can not execute User update because multiple users match, and an email section is specified in the dsl.");
112 1
        }
113 1
114
        $userService = $this->repository->getUserService();
115 1
116 1
        foreach ($userCollection as $key => $user) {
117
118
            $userUpdateStruct = $userService->newUserUpdateStruct();
119 1
120
            if (isset($step->dsl['email'])) {
121 1
                $userUpdateStruct->email = $this->referenceResolver->resolveReference($step->dsl['email']);
122 1
            }
123
            if (isset($step->dsl['password'])) {
124 1
                $userUpdateStruct->password = (string)$this->referenceResolver->resolveReference($step->dsl['password']);
125 1
            }
126
            if (isset($step->dsl['enabled'])) {
127
                $userUpdateStruct->enabled = $this->referenceResolver->resolveReference($step->dsl['enabled']);
128 1
            }
129
130 1
            $user = $userService->updateUser($user, $userUpdateStruct);
131
132 1
            if (isset($step->dsl['groups'])) {
133 1
                $groups = $step->dsl['groups'];
134 1
135 1
                if (!is_array($groups)) {
136
                    $groups = array($groups);
137 1
                }
138 1
139
                $assignedGroups = $userService->loadUserGroupsOfUser($user);
140 1
141 1
                $targetGroupIds = [];
142 1
                // Assigning new groups to the user
143
                foreach ($groups as $groupToAssignId) {
144
                    $groupId = $this->referenceResolver->resolveReference($groupToAssignId);
145 1
                    $groupToAssign = $this->userGroupMatcher->matchOneByKey($groupId);
146 1
                    $targetGroupIds[] = $groupToAssign->id;
147
148
                    $present = false;
149
                    foreach ($assignedGroups as $assignedGroup) {
150
                        // Make sure we assign the user only to groups he isn't already assigned to
151 1
                        if ($assignedGroup->id == $groupToAssign->id) {
152 1
                            $present = true;
153 1
                            break;
154
                        }
155
                    }
156
                    if (!$present) {
157
                        $userService->assignUserToUserGroup($user, $groupToAssign);
158 1
                    }
159
                }
160
161 1
                // Unassigning groups that are not in the list in the migration
162
                foreach ($assignedGroups as $assignedGroup) {
163 1
                    if (!in_array($assignedGroup->id, $targetGroupIds)) {
164
                        $userService->unAssignUserFromUserGroup($user, $assignedGroup);
165
                    }
166
                }
167
            }
168
169 2
            $userCollection[$key] = $user;
170
        }
171 2
172
        $this->setReferences($userCollection, $step);
173 2
174
        return $userCollection;
175 2
    }
176
177 2
    /**
178 2
     * Method to handle the delete operation of the migration instructions
179
     */
180
    protected function delete($step)
181 2
    {
182
        $userCollection = $this->matchUsers('delete', $step);
183
184
        $this->validateResultsCount($userCollection, $step);
185
186
        $this->setReferences($userCollection, $step);
187
188
        $userService = $this->repository->getUserService();
189 2
190
        foreach ($userCollection as $user) {
191 2
            $userService->deleteUser($user);
192
        }
193
194
        return $userCollection;
195
    }
196 2
197 2
    /**
198
     * @param string $action
199 1
     * @return UserCollection
200 1
     * @throws \Exception
201 1
     */
202
    protected function matchUsers($action, $step)
203 1
    {
204
        if (!isset($step->dsl['id']) && !isset($step->dsl['user_id']) && !isset($step->dsl['email']) && !isset($step->dsl['username']) && !isset($step->dsl['match'])) {
205
            throw new InvalidStepDefinitionException("The id, email or username of a user or a match condition is required to $action it");
206 1
        }
207
208
        // Backwards compat
209 1
        if (isset($step->dsl['match'])) {
210
            $match = $step->dsl['match'];
211
        } else {
212 1
            $conds = array();
213
            if (isset($step->dsl['id'])) {
214
                $conds['id'] = $step->dsl['id'];
215
            }
216 2
            if (isset($step->dsl['user_id'])) {
217
                $conds['id'] = $step->dsl['user_id'];
218 2
            }
219
            if (isset($step->dsl['email'])) {
220
                $conds['email'] = $step->dsl['email'];
221
            }
222
            if (isset($step->dsl['username'])) {
223
                $conds['login'] = $step->dsl['username'];
224
            }
225
            $match = $conds;
226
        }
227
228
        // convert the references passed in the match
229 2
        $match = $this->resolveReferencesRecursively($match);
230
231 2
        $tolerateMisses = isset($step->dsl['match_tolerate_misses']) ? $this->referenceResolver->resolveReference($step->dsl['match_tolerate_misses']) : false;
232
233 2
        return $this->userMatcher->match($match, $tolerateMisses);
234
    }
235 2
236 2
    /**
237 2
     * @param User $user
238 2
     * @param array $references the definitions of the references to set
239 2
     * @throws InvalidStepDefinitionException
240 1
     * @return array key: the reference names, values: the reference values
241 1
     *
242 1
     * @todo allow setting refs to all the attributes that can be gotten for Contents
243 1
     */
244 1
    protected function getReferencesValues($user, array $references, $step)
245 1
    {
246 1
        $refs = array();
247 1
248 1
        foreach ($references as $key => $reference) {
249 1
250 1
            $reference = $this->parseReferenceDefinition($key, $reference);
251 1
252 1
            switch ($reference['attribute']) {
253 1
                case 'user_id':
254 1
                case 'id':
255
                    $value = $user->id;
256 1
                    break;
257
                case 'email':
258
                    $value = $user->email;
259
                    break;
260
                case 'enabled':
261 2
                    $value = $user->enabled;
262
                    break;
263
                case 'login':
264 2
                    $value = $user->login;
265
                    break;
266
                case 'groups_ids':
267
                    $value = [];
268
                    $userService = $this->repository->getUserService();
269
                    $userGroups = $userService->loadUserGroupsOfUser($user);
270
                    foreach ($userGroups as $userGroup) {
271
                        $value[] = $userGroup->id;
272
                    }
273
                    break;
274
                default:
275
                    throw new InvalidStepDefinitionException('User Manager does not support setting references for attribute ' . $reference['attribute']);
276
            }
277
278
            $refs[$reference['identifier']] = $value;
279
        }
280
281
        return $refs;
282
    }
283
}
284