Passed
Push — master ( 6b492a...848728 )
by Gaetano
08:50
created

UserGroupManager::getReferencesValues()   C

Complexity

Conditions 12
Paths 10

Size

Total Lines 40
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 12.1591

Importance

Changes 0
Metric Value
cc 12
eloc 32
nc 10
nop 3
dl 0
loc 40
ccs 26
cts 29
cp 0.8966
crap 12.1591
rs 6.9666
c 0
b 0
f 0

How to fix   Complexity   

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\Content\Content;
6
use eZ\Publish\API\Repository\Values\User\UserGroup;
7
use Kaliop\eZMigrationBundle\Core\Matcher\UserGroupMatcher;
8
use Kaliop\eZMigrationBundle\API\Collection\UserGroupCollection;
9
use Kaliop\eZMigrationBundle\Core\Matcher\RoleMatcher;
10
use Kaliop\eZMigrationBundle\Core\Matcher\SectionMatcher;
11
12
/**
13
 * Handles user-group migrations.
14
 */
15
class UserGroupManager extends RepositoryExecutor
16
{
17
    protected $supportedStepTypes = array('user_group');
18
    protected $supportedActions = array('create', 'load', 'update', 'delete');
19
20
    protected $userGroupMatcher;
21
    protected $roleMatcher;
22
    protected $sectionMatcher;
23
24 96
    public function __construct(UserGroupMatcher $userGroupMatcher, RoleMatcher $roleMatcher, SectionMatcher $sectionMatcher)
25
    {
26 96
        $this->userGroupMatcher = $userGroupMatcher;
27 96
        $this->roleMatcher = $roleMatcher;
28 96
        $this->sectionMatcher = $sectionMatcher;
29 96
    }
30
31
    /**
32
     * Method to handle the create operation of the migration instructions
33
     */
34 1
    protected function create($step)
35
    {
36 1
        $userService = $this->repository->getUserService();
37
38 1
        $parentGroupId = $step->dsl['parent_group_id'];
39 1
        $parentGroupId = $this->referenceResolver->resolveReference($parentGroupId);
40 1
        $parentGroup = $this->userGroupMatcher->matchOneByKey($parentGroupId);
41
42 1
        $contentType = $this->repository->getContentTypeService()->loadContentTypeByIdentifier("user_group");
43
44 1
        $userGroupCreateStruct = $userService->newUserGroupCreateStruct($this->getLanguageCode($step), $contentType);
45 1
        $userGroupCreateStruct->setField('name', $step->dsl['name']);
46
47 1
        if (isset($step->dsl['remote_id'])) {
48
            $userGroupCreateStruct->remoteId = $step->dsl['remote_id'];
49
        }
50
51 1
        if (isset($step->dsl['description'])) {
52 1
            $userGroupCreateStruct->setField('description', $step->dsl['description']);
53
        }
54
55 1
        if (isset($step->dsl['section'])) {
56
            $sectionKey = $this->referenceResolver->resolveReference($step->dsl['section']);
57
            $section = $this->sectionMatcher->matchOneByKey($sectionKey);
58
            $userGroupCreateStruct->sectionId = $section->id;
59
        }
60
61 1
        $userGroup = $userService->createUserGroup($userGroupCreateStruct, $parentGroup);
62
63 1
        if (isset($step->dsl['roles'])) {
64 1
            $roleService = $this->repository->getRoleService();
65
            // we support both Ids and Identifiers
66 1
            foreach ($step->dsl['roles'] as $roleId) {
67 1
                $roleId = $this->referenceResolver->resolveReference($roleId);
68 1
                $role = $this->roleMatcher->matchOneByKey($roleId);
69 1
                $roleService->assignRoleToUserGroup($role, $userGroup);
70
            }
71
        }
72
73 1
        $this->setReferences($userGroup, $step);
74
75 1
        return $userGroup;
76
    }
77
78 1
    protected function load($step)
79
    {
80 1
        $userGroupCollection = $this->matchUserGroups('load', $step);
81
82 1
        $this->setReferences($userGroupCollection, $step);
83
84 1
        return $userGroupCollection;
85
    }
86
87
    /**
88
     * Method to handle the update operation of the migration instructions
89
     *
90
     * @throws \Exception When the ID of the user group is missing from the migration definition.
91
     */
92 1
    protected function update($step)
93
    {
94 1
        $userGroupCollection = $this->matchUserGroups('update', $step);
95
96 1
        if (count($userGroupCollection) > 1 && isset($step->dsl['references'])) {
97
            throw new \Exception("Can not execute Group update because multiple groups match, and a references section is specified in the dsl. References can be set when only 1 group matches");
98
        }
99
100 1
        $userService = $this->repository->getUserService();
101 1
        $contentService = $this->repository->getContentService();
102
103 1
        foreach ($userGroupCollection as $key => $userGroup) {
104
105
            /** @var $updateStruct \eZ\Publish\API\Repository\Values\User\UserGroupUpdateStruct */
106 1
            $updateStruct = $userService->newUserGroupUpdateStruct();
107
108
            /** @var $contentUpdateStruct \eZ\Publish\API\Repository\Values\Content\ContentUpdateStruct */
109 1
            $contentUpdateStruct = $contentService->newContentUpdateStruct();
110
111 1
            if (isset($step->dsl['name'])) {
112 1
                $contentUpdateStruct->setField('name', $step->dsl['name']);
113
            }
114
115 1
            if (isset($step->dsl['remote_id'])) {
116
                $contentUpdateStruct->remoteId = $step->dsl['remote_id'];
117
            }
118
119 1
            if (isset($step->dsl['description'])) {
120 1
                $contentUpdateStruct->setField('description', $step->dsl['description']);
121
            }
122
123 1
            $updateStruct->contentUpdateStruct = $contentUpdateStruct;
124
125 1
            $userGroup = $userService->updateUserGroup($userGroup, $updateStruct);
126
127 1
            if (isset($step->dsl['parent_group_id'])) {
128 1
                $parentGroupId = $step->dsl['parent_group_id'];
129 1
                $parentGroupId = $this->referenceResolver->resolveReference($parentGroupId);
130 1
                $newParentGroup = $this->userGroupMatcher->matchOneByKey($parentGroupId);
131
132
                // Move group to new parent
133 1
                $userService->moveUserGroup($userGroup, $newParentGroup);
134
135
                // reload user group to be able to set refs correctly
136 1
                $userGroup = $userService->loadUserGroup($userGroup->id);
137
            }
138
139 1
            if (isset($step->dsl['section'])) {
140
                $this->setSection($userGroup, $step->dsl['section']);
141
142
                /// @todo if we allow to set references to the group's section, here we should reload it
143
            }
144
145 1
            $userGroupCollection[$key] = $userGroup;
146
        }
147
148 1
        $this->setReferences($userGroupCollection, $step);
149
150 1
        return $userGroupCollection;
151
    }
152
153
    /**
154
     * Method to handle the delete operation of the migration instructions
155
     *
156
     * @throws \Exception When there are no groups specified for deletion.
157
     */
158 1
    protected function delete($step)
159
    {
160 1
        $userGroupCollection = $this->matchUserGroups('delete', $step);
161
162 1
        $this->setReferences($userGroupCollection, $step);
163
164 1
        $userService = $this->repository->getUserService();
165
166 1
        foreach ($userGroupCollection as $userGroup) {
167 1
            $userService->deleteUserGroup($userGroup);
168
        }
169
170 1
        return $userGroupCollection;
171
    }
172
173
    /**
174
     * @param string $action
175
     * @return UserGroupCollection
176
     * @throws \Exception
177
     */
178 1
    protected function matchUserGroups($action, $step)
179
    {
180 1
        if (!isset($step->dsl['id']) && !isset($step->dsl['group']) && !isset($step->dsl['match'])) {
181
            throw new \Exception("The id of a user group or a match condition is required to $action it");
182
        }
183
184
        // Backwards compat
185 1
        if (isset($step->dsl['match'])) {
186 1
            $match = $step->dsl['match'];
187
        } else {
188 1
            if (isset($step->dsl['id'])) {
189 1
                $match = array('id' => $step->dsl['id']);
190
            }
191 1
            if (isset($step->dsl['group'])) {
192
                $match = array('id' => $step->dsl['group']);
193
            }
194
        }
195
196
        // convert the references passed in the match
197 1
        $match = $this->resolveReferencesRecursively($match);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $match does not seem to be defined for all execution paths leading up to this point.
Loading history...
198
199 1
        return $this->userGroupMatcher->match($match);
200
    }
201
202
    /**
203
     * @param UserGroup $userGroup
204
     * @param array $references the definitions of the references to set
205
     * @throws \InvalidArgumentException When trying to assign a reference to an unsupported attribute
206
     * @return array key: the reference names, values: the reference values
207
     *
208
     * @todo allow setting refs to all the attributes that can be gotten for Contents
209
     */
210 1
    protected function getReferencesValues($userGroup, array $references, $step)
211
    {
212 1
        $refs = array();
213
214 1
        foreach ($references as $reference) {
215 1
            switch ($reference['attribute']) {
216 1
                case 'object_id':
217 1
                case 'content_id':
218 1
                case 'user_group_id':
219 1
                case 'id':
220 1
                    $value = $userGroup->id;
221 1
                    break;
222 1
                case 'parent_id':
223 1
                case 'parent_user_group_id':
224 1
                    $value = $userGroup->parentId;
225 1
                    break;
226 1
                case 'remote_id':
227 1
                    $value = $userGroup->contentInfo->remoteId;
228 1
                    break;
229 1
                case 'users_ids':
230 1
                    $value = [];
231
                    $userService = $this->repository->getUserService();
232 1
                    $limit = 100;
233 1
                    $offset = 0;
234
                    do {
235
                        $users = $userService->loadUsersOfUserGroup($userGroup, $offset, $limit);
236 1
                        foreach ($users as $user) {
237 1
                            $value[] = $user->id;
238 1
                        }
239
                        $offset += $limit;
240
                    } while (count($users));
241
                    break;
242
                default:
243 1
                    throw new \InvalidArgumentException('User Group Manager does not support setting references for attribute ' . $reference['attribute']);
244
            }
245
246 1
            $refs[$reference['identifier']] = $value;
247
        }
248
249
        return $refs;
250
    }
251
252
    protected function setSection(Content $content, $sectionKey)
253
    {
254
        $sectionKey = $this->referenceResolver->resolveReference($sectionKey);
255
        $section = $this->sectionMatcher->matchOneByKey($sectionKey);
256
257
        $sectionService = $this->repository->getSectionService();
258
        $sectionService->assignSection($content->contentInfo, $section);
259
    }
260
}
261