Completed
Push — master ( ac3b8b...3c857d )
by Gaetano
18:21
created

ObjectStateManager::delete()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
c 0
b 0
f 0
rs 9.4285
cc 2
eloc 6
nc 2
nop 1
1
<?php
2
3
namespace Kaliop\eZMigrationBundle\Core\Executor;
4
5
use Kaliop\eZMigrationBundle\Core\Matcher\ObjectStateGroupMatcher;
6
use Kaliop\eZMigrationBundle\Core\Matcher\ObjectStateMatcher;
7
use Kaliop\eZMigrationBundle\API\Collection\ObjectStateCollection;
8
use Kaliop\eZMigrationBundle\API\MigrationGeneratorInterface;
9
10
/**
11
 * Handles object-state migrations.
12
 */
13
class ObjectStateManager extends RepositoryExecutor implements MigrationGeneratorInterface
14
{
15
    /**
16
     * @var array
17
     */
18
    protected $supportedStepTypes = array('object_state');
19
20
    /**
21
     * @var ObjectStateMatcher
22
     */
23
    protected $objectStateMatcher;
24
25
    /**
26
     * @var ObjectStateGroupMatcher
27
     */
28
    protected $objectStateGroupMatcher;
29
30
    /**
31
     * @param ObjectStateMatcher      $objectStateMatcher
32
     * @param ObjectStateGroupMatcher $objectStateGroupMatcher
33
     */
34
    public function __construct(ObjectStateMatcher $objectStateMatcher, ObjectStateGroupMatcher $objectStateGroupMatcher)
35
    {
36
        $this->objectStateMatcher = $objectStateMatcher;
37
        $this->objectStateGroupMatcher = $objectStateGroupMatcher;
38
    }
39
40
    /**
41
     * Handles the create step of object state migrations.
42
     *
43
     * @throws \Exception
44
     */
45
    protected function create($step)
46
    {
47 View Code Duplication
        foreach (array('object_state_group', 'names', 'identifier') as $key) {
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...
48
            if (!isset($step->dsl[$key])) {
49
                throw new \Exception("The '$key' key is missing in a object state creation definition");
50
            }
51
        }
52
53
        if (!count($step->dsl['names'])) {
54
            throw new \Exception('No object state names have been defined. Need to specify at least one to create the state.');
55
        }
56
57
        $objectStateService = $this->repository->getObjectStateService();
58
59
        $objectStateGroupId = $step->dsl['object_state_group'];
60
        $objectStateGroupId = $this->referenceResolver->resolveReference($objectStateGroupId);
61
        $objectStateGroup = $this->objectStateGroupMatcher->matchOneByKey($objectStateGroupId);
62
63
        $objectStateCreateStruct = $objectStateService->newObjectStateCreateStruct($step->dsl['identifier']);
64
        $objectStateCreateStruct->defaultLanguageCode = self::DEFAULT_LANGUAGE_CODE;
65
66
        foreach ($step->dsl['names'] as $languageCode => $name) {
67
            $objectStateCreateStruct->names[$languageCode] = $name;
68
        }
69
        if (isset($step->dsl['descriptions'])) {
70
            foreach ($step->dsl['descriptions'] as $languageCode => $description) {
71
                $objectStateCreateStruct->descriptions[$languageCode] = $description;
72
            }
73
        }
74
75
        $objectState = $objectStateService->createObjectState($objectStateGroup, $objectStateCreateStruct);
76
77
        $this->setReferences($objectState, $step);
78
79
        return $objectState;
80
    }
81
82
    /**
83
     * Handles the update step of object state migrations.
84
     *
85
     * @throws \Exception
86
     */
87 View Code Duplication
    protected function update($step)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
88
    {
89
        $stateCollection = $this->matchObjectStates('update', $step);
90
91
        if (count($stateCollection) > 1 && array_key_exists('references', $step->dsl)) {
92
            throw new \Exception("Can not execute Object State update because multiple states match, and a references section is specified in the dsl. References can be set when only 1 state matches");
93
        }
94
95
        if (count($stateCollection) > 1 && isset($step->dsl['identifier'])) {
96
            throw new \Exception("Can not execute Object State update because multiple states match, and an identifier is specified in the dsl.");
97
        }
98
99
        $objectStateService = $this->repository->getObjectStateService();
100
101
        foreach ($stateCollection as $state) {
0 ignored issues
show
Bug introduced by
The expression $stateCollection of type object<Kaliop\eZMigratio...ctStateCollection>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
102
            $objectStateUpdateStruct = $objectStateService->newObjectStateUpdateStruct();
103
104
            if (isset($step->dsl['identifier'])) {
105
                $objectStateUpdateStruct->identifier = $step->dsl['identifier'];
106
            }
107
            if (isset($step->dsl['names'])) {
108
                foreach ($step->dsl['names'] as $name) {
109
                    $objectStateUpdateStruct->names[$name['languageCode']] = $name['name'];
110
                }
111
            }
112
            if (isset($step->dsl['descriptions'])) {
113
                foreach ($step->dsl['descriptions'] as $languageCode => $description) {
114
                    $objectStateUpdateStruct->descriptions[$languageCode] = $description;
115
                }
116
            }
117
            $state = $objectStateService->updateObjectState($state, $objectStateUpdateStruct);
118
119
            $this->setReferences($state, $step);
120
        }
121
122
        return $stateCollection;
123
    }
124
125
    /**
126
     * Handles the deletion step of object state migrations.
127
     */
128
    protected function delete($step)
129
    {
130
        $stateCollection = $this->matchObjectStates('delete', $step);
131
132
        $objectStateService = $this->repository->getObjectStateService();
133
134
        foreach ($stateCollection as $state) {
0 ignored issues
show
Bug introduced by
The expression $stateCollection of type object<Kaliop\eZMigratio...ctStateCollection>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
135
            $objectStateService->deleteObjectState($state);
136
        }
137
138
        return $stateCollection;
139
    }
140
141
    /**
142
     * @param string $action
143
     * @return ObjectStateCollection
144
     * @throws \Exception
145
     */
146 View Code Duplication
    protected function matchObjectStates($action, $step)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
147
    {
148
        if (!isset($step->dsl['match'])) {
149
            throw new \Exception("A match condition is required to $action an object state");
150
        }
151
152
        // convert the references passed in the match
153
        $match = $this->resolveReferencesRecursively($step->dsl['match']);
0 ignored issues
show
Deprecated Code introduced by
The method Kaliop\eZMigrationBundle...ReferencesRecursively() has been deprecated with message: will be moved into the reference resolver classes

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
154
155
        return $this->objectStateMatcher->match($match);
156
    }
157
158
    /**
159
     * {@inheritdoc}
160
     * @param \eZ\Publish\API\Repository\Values\ObjectState\ObjectState $objectState
161
     */
162 View Code Duplication
    protected function setReferences($objectState, $step)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
163
    {
164
        if (!array_key_exists('references', $step->dsl)) {
165
            return false;
166
        }
167
168
        foreach ($step->dsl['references'] as $reference) {
169
            switch ($reference['attribute']) {
170
                case 'object_state_id':
171
                case 'id':
172
                    $value = $objectState->id;
173
                    break;
174
                case 'priority':
175
                    $value = $objectState->priority;
176
                    break;
177
                default:
178
                    throw new \InvalidArgumentException('Object State Manager does not support setting references for attribute ' . $reference['attribute']);
179
            }
180
181
            $overwrite = false;
182
            if (isset($reference['overwrite'])) {
183
                $overwrite = $reference['overwrite'];
184
            }
185
            $this->referenceResolver->addReference($reference['identifier'], $value, $overwrite);
186
        }
187
188
        return true;
189
    }
190
191
    /**
192
     * @param array $matchCondition
193
     * @param string $mode
194
     * @param array $context
195
     * @throws \Exception
196
     * @return array
197
     */
198
    public function generateMigration(array $matchCondition, $mode, array $context = array())
199
    {
200
        $previousUserId = $this->loginUser($this->getAdminUserIdentifierFromContext($context));
201
        $objectStateCollection = $this->objectStateMatcher->match($matchCondition);
202
        $data = array();
203
204
        /** @var \eZ\Publish\API\Repository\Values\ObjectState\ObjectState $objectState */
205
        foreach ($objectStateCollection as $objectState) {
0 ignored issues
show
Bug introduced by
The expression $objectStateCollection of type object<Kaliop\eZMigratio...ctStateCollection>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
206
207
            $groupData = array(
208
                'type' => reset($this->supportedStepTypes),
209
                'mode' => $mode,
210
            );
211
212
            switch ($mode) {
213
                case 'create':
214
                    $groupData = array_merge(
215
                        $groupData,
216
                        array(
217
                            'object_state_group' => $objectState->getObjectStateGroup()->identifier,
218
                            'identifier' => $objectState->identifier,
219
                        )
220
                    );
221
                    break;
222 View Code Duplication
                case 'update':
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...
223
                    $groupData = array_merge(
224
                        $groupData,
225
                        array(
226
                            'match' => array(
227
                                ObjectStateMatcher::MATCH_OBJECTSTATE_IDENTIFIER =>
228
                                    $objectState->getObjectStateGroup()->identifier . '/' . $objectState->identifier
229
                            ),
230
                            'identifier' => $objectState->identifier,
231
                        )
232
                    );
233
                    break;
234 View Code Duplication
                case 'delete':
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...
235
                    $groupData = array_merge(
236
                        $groupData,
237
                        array(
238
                            'match' => array(
239
                                ObjectStateMatcher::MATCH_OBJECTSTATE_IDENTIFIER =>
240
                                    $objectState->getObjectStateGroup()->identifier . '/' . $objectState->identifier
241
                            )
242
                        )
243
                    );
244
                    break;
245
                default:
246
                    throw new \Exception("Executor 'object_state_group' doesn't support mode '$mode'");
247
            }
248
249 View Code Duplication
            if ($mode != 'delete') {
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...
250
                $names = array();
251
                $descriptions = array();
252
                foreach($objectState->languageCodes as $languageCode) {
253
                    $names[$languageCode] =  $objectState->getName($languageCode);
254
                }
255
                foreach($objectState->languageCodes as $languageCode) {
256
                    $descriptions[$languageCode] =  $objectState->getDescription($languageCode);
257
                }
258
                $groupData = array_merge(
259
                    $groupData,
260
                    array(
261
                        'names' => $names,
262
                        'descriptions' => $descriptions,
263
                    )
264
                );
265
            }
266
267
            $data[] = $groupData;
268
        }
269
270
        $this->loginUser($previousUserId);
271
        return $data;
272
    }
273
}
274