Completed
Push — master ( 97fb46...770b11 )
by Gaetano
15:34 queued 07:06
created

LanguageManager   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 241
Duplicated Lines 0 %

Test Coverage

Coverage 80%

Importance

Changes 0
Metric Value
eloc 109
dl 0
loc 241
ccs 84
cts 105
cp 0.8
rs 9.76
c 0
b 0
f 0
wmc 33

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A generateMigration() 0 57 5
B getReferencesValues() 0 29 8
A create() 0 21 4
A matchLanguages() 0 10 2
A load() 0 7 1
A listAllowedConditions() 0 3 1
B update() 0 35 8
A delete() 0 17 3
1
<?php
2
3
namespace Kaliop\eZMigrationBundle\Core\Executor;
4
5
use eZ\Publish\API\Repository\Values\Content\Language;
6
use Kaliop\eZMigrationBundle\API\Collection\LanguageCollection;
7
use Kaliop\eZMigrationBundle\API\MigrationGeneratorInterface;
8
use Kaliop\eZMigrationBundle\API\EnumerableMatcherInterface;
9
use Kaliop\eZMigrationBundle\Core\Matcher\LanguageMatcher;
10
11
/**
12
 * Handles language migrations.
13
 */
14
class LanguageManager extends RepositoryExecutor implements MigrationGeneratorInterface, EnumerableMatcherInterface
15
{
16
    protected $supportedStepTypes = array('language');
17
    protected $supportedActions = array('create', 'load', 'update', 'delete');
18
19
    /** @var LanguageMatcher $languageMatcher */
20
    protected $languageMatcher;
21
22
    /**
23
     * @param LanguageMatcher $languageMatcher
24
     */
25 96
    public function __construct(LanguageMatcher $languageMatcher)
26
    {
27 96
        $this->languageMatcher = $languageMatcher;
28 96
    }
29
30
    /**
31
     * Handles the language create migration action
32
     *
33
     * @todo allow creating disabkled languages
34
     */
35 5
    protected function create($step)
36
    {
37 5
        $languageService = $this->repository->getContentLanguageService();
38
39 5
        if (!isset($step->dsl['lang'])) {
40
            throw new \Exception("The 'lang' key is required to create a new language.");
41
        }
42
43 5
        $languageCreateStruct = $languageService->newLanguageCreateStruct();
44 5
        $languageCreateStruct->languageCode = $this->referenceResolver->resolveReference($step->dsl['lang']);
45 5
        if (isset($step->dsl['name'])) {
46 5
            $languageCreateStruct->name = $this->referenceResolver->resolveReference($step->dsl['name']);
47
        }
48 5
        if (isset($step->dsl['enabled'])) {
49
            $languageCreateStruct->enabled = (bool)$this->referenceResolver->resolveReference($step->dsl['enabled']);
50
        }
51 5
        $language = $languageService->createLanguage($languageCreateStruct);
52
53 5
        $this->setReferences($language, $step);
54
55 5
        return $language;
56
    }
57
58 1
    protected function load($step)
59
    {
60 1
        $languageCollection = $this->matchLanguages('load', $step);
61
62 1
        $this->setReferences($languageCollection, $step);
63
64 1
        return $languageCollection;
65
    }
66
67
    /**
68
     * Handles the language update migration action
69
     */
70 1
    protected function update($step)
71
    {
72 1
        if (isset($step->dsl['lang'])) {
73
            // BC
74
            $step->dsl['match'] = array('language_code' => $step->dsl['lang']);
75
        }
76
77 1
        $languageCollection = $this->matchLanguages('delete', $step);
78
79 1
        if (count($languageCollection) > 1 && array_key_exists('references', $step->dsl)) {
80
            throw new \Exception("Can not execute Language update because multiple languages match, and a references section is specified in the dsl. References can be set when only 1 language matches");
81
        }
82
83 1
        $languageService = $this->repository->getContentLanguageService();
84
85 1
        foreach ($languageCollection as $key => $language) {
86
87 1
            if (isset($step->dsl['name'])) {
88 1
                $languageService->updateLanguageName($language, $this->referenceResolver->resolveReference($step->dsl['name']));
89
            }
90
91 1
            if (isset($step->dsl['enabled'])) {
92 1
                if ($this->referenceResolver->resolveReference($step->dsl['enabled'])) {
93
                    $languageService->enableLanguage($language);
94
                } else {
95 1
                    $languageService->disableLanguage($language);
96
                };
97
            }
98
99 1
            $languageCollection[$key] = $languageService->loadLanguageById($key);
100
        }
101
102 1
        $this->setReferences($languageCollection, $step);
103
104 1
        return $languageCollection;
105
    }
106
107
    /**
108
     * Handles the language delete migration action
109
     */
110 1
    protected function delete($step)
111
    {
112 1
        if (isset($step->dsl['lang'])) {
113
            // BC
114
            $step->dsl['match'] = array('language_code' => $step->dsl['lang']);
115
        }
116 1
        $languageCollection = $this->matchLanguages('delete', $step);
117
118 1
        $this->setReferences($languageCollection, $step);
119
120 1
        $languageService = $this->repository->getContentLanguageService();
121
122 1
        foreach ($languageCollection as $language) {
123 1
            $languageService->deleteLanguage($language);
124
        }
125
126 1
        return $languageCollection;
127
    }
128
129
    /**
130
     * @param string $action
131
     * @return LanguageCollection
132
     * @throws \Exception
133
     */
134 1
    protected function matchLanguages($action, $step)
135
    {
136 1
        if (!isset($step->dsl['match'])) {
137
            throw new \Exception("A match condition is required to $action a language");
138
        }
139
140
        // convert the references passed in the match
141 1
        $match = $this->resolveReferencesRecursively($step->dsl['match']);
142
143 1
        return $this->languageMatcher->match($match);
144
    }
145
146
    /**
147
     * @param Language $language
148
     * @param array $references the definitions of the references to set
149
     * @throws \InvalidArgumentException When trying to assign a reference to an unsupported attribute
150
     * @return array key: the reference names, values: the reference values
151
     */
152 1
    protected function getReferencesValues($language, array $references, $step)
153
    {
154 1
        $refs = array();
155
156 1
        foreach ($references as $reference) {
157
158 1
            switch ($reference['attribute']) {
159 1
                case 'language_id':
160 1
                case 'id':
161 1
                    $value = $language->id;
162 1
                    break;
163
                case 'enabled':
164
                    $value = $language->enabled;
165
                    break;
166
                case 'language_code':
167
                    $value = $language->languageCode;
168
                    break;
169
                case 'language_name':
170
                case 'name':
171
                    $value = $language->name;
172
                    break;
173
                default:
174
                    throw new \InvalidArgumentException('Language Manager does not support setting references for attribute ' . $reference['attribute']);
175
            }
176
177 1
            $refs[$reference['identifier']] = $value;
178
        }
179
180 1
        return $refs;
181
    }
182
183
    /**
184
     * @param array $matchCondition
185
     * @param string $mode
186
     * @param array $context
187
     * @throws \Exception
188
     * @return array
189
     */
190 3
    public function generateMigration(array $matchCondition, $mode, array $context = array())
191
    {
192 3
        $previousUserId = $this->loginUser($this->getAdminUserIdentifierFromContext($context));
193 3
        $languageCollection = $this->languageMatcher->match($matchCondition);
194 3
        $data = array();
195
196
        /** @var \eZ\Publish\API\Repository\Values\Content\Language $language */
197 3
        foreach ($languageCollection as $language) {
198
199
            $languageData = array(
200 3
                'type' => reset($this->supportedStepTypes),
201 3
                'mode' => $mode,
202
            );
203
204
            switch ($mode) {
205 3
                case 'create':
206 1
                    $languageData = array_merge(
207 1
                        $languageData,
208
                        array(
209 1
                            'lang' => $language->languageCode,
210 1
                            'name' => $language->name,
211 1
                            'enabled' => $language->enabled
212
                        )
213
                    );
214 1
                    break;
215 2
                case 'update':
216 1
                    $languageData = array_merge(
217 1
                        $languageData,
218
                        array(
219
                            'match' => array(
220 1
                                LanguageMatcher::MATCH_LANGUAGE_ID => $language->id
221
                            ),
222 1
                            'lang' => $language->languageCode,
223 1
                            'name' => $language->name,
224 1
                            'enabled' => $language->enabled
225
                        )
226
                    );
227 1
                    break;
228 1
                case 'delete':
229 1
                    $languageData = array_merge(
230 1
                        $languageData,
231
                        array(
232
                            'match' => array(
233 1
                                LanguageMatcher::MATCH_LANGUAGE_ID => $language->id
234
                            )
235
                        )
236
                    );
237 1
                    break;
238
                default:
239
                    throw new \Exception("Executor 'language' doesn't support mode '$mode'");
240
            }
241
242 3
            $data[] = $languageData;
243
        }
244
245 3
        $this->loginUser($previousUserId);
246 3
        return $data;
247
    }
248
249
    /**
250
     * @return string[]
251
     */
252
    public function listAllowedConditions()
253
    {
254
        return $this->languageMatcher->listAllowedConditions();
255
    }
256
}
257