Completed
Push — master ( 27039d...db9c49 )
by Bart
13s
created

Schematic::importDataModel()   F

Complexity

Conditions 32
Paths > 20000

Size

Total Lines 112
Code Lines 68

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 64
CRAP Score 32.092

Importance

Changes 0
Metric Value
dl 0
loc 112
ccs 64
cts 67
cp 0.9552
rs 2
c 0
b 0
f 0
cc 32
eloc 68
nc 201326593
nop 3
crap 32.092

How to fix   Long Method    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 NerdsAndCompany\Schematic\Services;
4
5
use Craft\Craft;
6
use Craft\BaseApplicationComponent as BaseApplication;
7
use Craft\Exception;
8
use Craft\IOHelper;
9
use NerdsAndCompany\Schematic\Models\Data;
10
use NerdsAndCompany\Schematic\Models\Result;
11
12
/**
13
 * Schematic Service.
14
 *
15
 * Sync Craft Setups.
16
 *
17
 * @author    Nerds & Company
18
 * @copyright Copyright (c) 2015-2017, Nerds & Company
19
 * @license   MIT
20
 *
21
 * @see      http://www.nerds.company
22
 */
23
class Schematic extends BaseApplication
24
{
25
    const SCHEMATIC_METHOD_IMPORT = 'import';
26
    const SCHEMATIC_METHOD_EXPORT = 'export';
27
28
    protected static $exportableDataTypes = [
29
        'locales',
30
        'assetSources',
31
        'assetTransforms',
32
        'fields',
33
        'plugins',
34
        'sections',
35
        'globalSets',
36
        'userGroups',
37
        'users',
38
        'categoryGroups',
39
        'tagGroups',
40
        'elementIndexSettings',
41
        'pluginData',
42
    ];
43
44
    public static function getExportableDataTypes()
45
    {
46
        return self::$exportableDataTypes;
47
    }
48
49
    /**
50
     * Returns data from import model or default.
51
     *
52
     * @param array  $data
53
     * @param string $handle
54
     * @param array  $default
55
     *
56
     * @return array
57
     */
58 1
    private function getPluginData(array $data, $handle, array $default = [])
59
    {
60 1
        return (array_key_exists($handle, $data) && !is_null($data[$handle])) ? $data[$handle] : $default;
61
    }
62
63
    /**
64
     * Import from Yaml file.
65
     *
66
     * @param string $file
67
     * @param string $override
68
     * @param bool   $force if set to true items not included in import will be deleted
69
     * @param string $dataTypes The data types to import
70
     *
71
     * @return Result
72 1
     * @throws Exception
73
     */
74 1
    public function importFromYaml($file, $override = null, $force = false, $dataTypes = 'all')
75 1
    {
76
        Craft::app()->config->maxPowerCaptain();
77 1
        Craft::app()->setComponent('userSession', $this);
78 1
79 1
        $yaml = IOHelper::getFileContents($file);
80
        $yaml_override = IOHelper::getFileContents($override);
81 1
        $dataModel = Data::fromYaml($yaml, $yaml_override);
82
83
        return $this->importDataModel($dataModel, $force, $dataTypes);
84
    }
85
86
    /**
87
     * Export to Yaml file.
88
     *
89
     * @param string $file
90
     * @param bool   $autoCreate
91
     *
92 3
     * @return Result
93
     */
94 3
    public function exportToYaml($file, $dataTypes = 'all', $autoCreate = true)
95 3
    {
96
        Craft::app()->config->maxPowerCaptain();
97 3
        Craft::app()->setComponent('userSession', $this);
98 3
99 3
        $result = new Result();
100
        $dataModel = $this->exportDataModel($dataTypes);
101 3
        $yaml = Data::toYaml($dataModel);
102 1
103 1
        if (!IOHelper::writeToFile($file, $yaml, $autoCreate)) { // Do not auto create
104
            $result->addError('errors', "Failed to write contents to \"$file\"");
105 3
        }
106
107
        return $result;
108
    }
109
110
    /**
111
     * Import data model.
112
     *
113
     * @param Data         $model
114
     * @param bool         $force     if set to true items not in the import will be deleted
115
     * @param string|array $dataTypes The data types to export
116 1
     *
117
     * @return Result
118
     * @throws Exception
119 1
     */
120 1
    private function importDataModel(Data $model, $force, $dataTypes = 'all')
121
    {
122 1
        // If all data types should be imported, get all the available data types that can be imported.
123 1
        if (is_array($dataTypes)) {
124
            // Validate that each data type specified to be imported is reconized.
125 1
            foreach ($dataTypes as $dataType) {
126 1
                if (!in_array($dataType, $this->exportableDataTypes)) {
127
                    $errorMessage = 'Invalid export type "'.$dataType.'". Accepted types are '
128 1
                                    .implode(', ', $this->exportableDataTypes);
129 1
                    throw new Exception($errorMessage);
130
                }
131 1
            }
132 1
        } else {
133
            $dataTypes = $this->exportableDataTypes;
134 1
        }
135 1
136
        // Import schema
137 1
        if (in_array('locales', $dataTypes)) {
138 1
            $locales = $model->getAttribute('locales', $force);
139
            $localesImportResult = Craft::app()->schematic_locales->import($locales);
140 1
        }
141 1
142
        if (in_array('plugins', $dataTypes)) {
143 1
            $plugins = $model->getAttribute('plugins', $force);
144 1
            $pluginImportResult = Craft::app()->schematic_plugins->import($plugins);
145
        }
146 1
147 1
        if (in_array('fields', $dataTypes)) {
148
            $fields = $model->getAttribute('fields');
149 1
            $fieldImportResult = Craft::app()->schematic_fields->import($fields, $force);
150 1
        }
151
152 1
        if (in_array('assetSources', $dataTypes)) {
153 1
            $assetSources = $model->getAttribute('assetSources');
154
            $assetSourcesImportResult = Craft::app()->schematic_assetSources->import($assetSources, $force);
155
        }
156 1
157 1
        if (in_array('assetTransforms', $dataTypes)) {
158 1
            $assetTransforms = $model->getAttribute('assetTransforms');
159
            $assetTransformsImportResult = Craft::app()->schematic_assetTransforms->import($assetTransforms, $force);
160 1
        }
161 1
162
        if (in_array('globalSets', $dataTypes)) {
163
            $globalSets = $model->getAttribute('globalSets');
164 1
            $globalSetsImportResult = Craft::app()->schematic_globalSets->import($globalSets, $force);
165 1
        }
166 1
167 1
        if (in_array('sections', $dataTypes)) {
168 1
            $sections = $model->getAttribute('sections');
169 1
            $sectionImportResult = Craft::app()->schematic_sections->import($sections, $force);
170 1
        }
171 1
172 1
        if (in_array('categoryGroups', $dataTypes)) {
173 1
            $categoryGroups = $model->getAttribute('categoryGroups');
174 1
            $categoryGroupImportResult = Craft::app()->schematic_categoryGroups->import($categoryGroups, $force);
175 1
        }
176 1
177
        if (in_array('tagGroups', $dataTypes)) {
178
            $tagGroups = $model->getAttribute('tagGroups');
179 1
            $tagGroupImportResult = Craft::app()->schematic_tagGroups->import($tagGroups, $force);
180 1
        }
181 1
182
        if (in_array('userGroups', $dataTypes)) {
183 1
            $userGroups = $model->getAttribute('userGroups');
184 1
            $userGroupImportResult = Craft::app()->schematic_userGroups->import($userGroups, $force);
185
        }
186 1
187
        if (in_array('users', $dataTypes)) {
188
            $users = $model->getAttribute('users');
189
            $userImportResult = Craft::app()->schematic_users->import($users, true);
190
        }
191
192
        if (in_array('fields', $dataTypes)) {
193
            $fields = $model->getAttribute('fields');
194
            $fieldImportResultFinal = Craft::app()->schematic_fields->import($fields, $force);
195
        }
196
197 1
        if (in_array('elementIndexSettings', $dataTypes)) {
198
            // Element index settings are supported from Craft 2.5
199 1
            if (version_compare(CRAFT_VERSION, '2.5', '>=')) {
200 1
                $elementIndexSettingsImportResult = Craft::app()->schematic_elementIndexSettings->import(
201 1
                    $model->getAttribute('elementIndexSettings'),
202 1
                    $force
203 1
                );
204 1
            }
205 1
        }
206 1
207 1
        // Verify results
208 1
        $result = new Result();
209
        empty($localesImportResult) ?: $result->consume($localesImportResult);
210
        empty($pluginImportResult) ?: $result->consume($pluginImportResult);
211
        empty($fieldImportResult) ?: $result->consume($fieldImportResult);
212
        empty($assetSourcesImportResult) ?: $result->consume($assetSourcesImportResult);
213
        empty($assetTransformsImportResult) ?: $result->consume($assetTransformsImportResult);
214
        empty($globalSetsImportResult) ?: $result->consume($globalSetsImportResult);
215
        empty($sectionImportResult) ?: $result->consume($sectionImportResult);
216
        empty($categoryGroupImportResult) ?: $result->consume($categoryGroupImportResult);
217
        empty($tagGroupImportResult) ?: $result->consume($tagGroupImportResult);
218
        empty($userGroupImportResult) ?: $result->consume($userGroupImportResult);
219 3
        empty($userImportResult) ?: $result->consume($userImportResult);
220
        empty($fieldImportResultFinal) ?: $result->consume($fieldImportResultFinal);
221
222 3
        // Element index settings are supported from Craft 2.5
223
        if (!empty($elementIndexSettingsImportResult) && version_compare(CRAFT_VERSION, '2.5', '>=')) {
224 1
            $result->consume($elementIndexSettingsImportResult);
225 1
        }
226
227
        $services = Craft::app()->plugins->call('registerMigrationService');
228
        $this->doImport($result, $model->pluginData, $services, $force);
229
230 1
        return $result;
231 1
    }
232 2
233
    /**
234
     * Handles importing.
235 3
     *
236 3
     * @param Result       $result
237 3
     * @param array        $data
238 3
     * @param array|Base[] $services
239
     * @param bool         $force
240 3
     */
241
    private function doImport(Result $result, array $data, $services, $force)
242 3
    {
243 3
        foreach ($services as $handle => $service) {
244 3
            if (is_array($service)) {
245
                $this->doImport($result, $data, $service, $force);
246 3
            } elseif ($service instanceof Base) {
247 3
                $pluginData = $this->getPluginData($data, $handle);
248 3
                $hookResult = $service->import($pluginData, $force);
249
                $result->consume($hookResult);
250 3
            }
251 3
        }
252 3
    }
253
254 3
    /**
255 3
     * Export data model.
256 3
     *
257 3
     * @param string|array $dataTypes The data types to export
258
     *
259 3
     * @return array
260 3
     *
261 3
     * @throws Exception
262
     */
263 3
    private function exportDataModel($dataTypes = 'all')
264 3
    {
265 3
        // If all data types should be exported, get all the available data types that can be exported.
266 3
        if (is_array($dataTypes)) {
267
            // Validate that each data type specified to be exported is reconized.
268 3
            foreach ($dataTypes as $dataType) {
269 3
                if (!in_array($dataType, $this->exportableDataTypes)) {
270 3
                    $errorMessage = 'Invalid export type "'.$dataType.'". Accepted types are '
271 3
                        .implode(', ', $this->exportableDataTypes);
272
                    throw new Exception($errorMessage);
273 3
                }
274 3
            }
275 3
        } else {
276 3
            $dataTypes = $this->exportableDataTypes;
277
        }
278 3
279 3
        $assetSources = Craft::app()->assetSources->getAllSources();
280 3
        $assetTransforms = Craft::app()->assetTransforms->getAllTransforms();
281
        $categoryGroups = Craft::app()->categories->getAllGroups();
282 3
        $tagGroups = Craft::app()->tags->getAllTagGroups();
283 3
284 3
        $export = [];
285
286 3
        if (in_array('locales', $dataTypes)) {
287 3
            $export['locales'] = Craft::app()->schematic_locales->export();
288 3
        }
289
290
        if (in_array('assetSources', $dataTypes)) {
291 3
            $export['assetSources'] = Craft::app()->schematic_assetSources->export($assetSources);
292 3
        }
293 3
294
        if (in_array('assetTransforms', $dataTypes)) {
295 3
            $export['assetTransforms'] = Craft::app()->schematic_assetTransforms->export($assetTransforms);
296 2
        }
297 2
298 2
        if (in_array('fields', $dataTypes)) {
299 2
            $fieldGroups = Craft::app()->fields->getAllGroups();
300
            $export['fields'] = Craft::app()->schematic_fields->export($fieldGroups);
301 3
        }
302
303
        if (in_array('plugins', $dataTypes)) {
304
            $export['plugins'] = Craft::app()->schematic_plugins->export();
305
        }
306
307
        if (in_array('sections', $dataTypes)) {
308
            $sections = Craft::app()->sections->getAllSections();
309
            $export['sections'] = Craft::app()->schematic_sections->export($sections);
310 2
        }
311
312 2
        if (in_array('globalSets', $dataTypes)) {
313 2
            $globals = Craft::app()->globals->getAllSets();
314 2
            $export['globalSets'] = Craft::app()->schematic_globalSets->export($globals);
315 2
        }
316 2
317 2
        if (in_array('userGroups', $dataTypes)) {
318 2
            $userGroups = Craft::app()->userGroups->getAllGroups();
319 2
            $export['userGroups'] = Craft::app()->schematic_userGroups->export($userGroups);
320 2
        }
321 2
322
        if (in_array('users', $dataTypes)) {
323
            $export['users'] = Craft::app()->schematic_users->export();
324
        }
325
326
        if (in_array('categoryGroups', $dataTypes)) {
327
            $export['categoryGroups'] = Craft::app()->schematic_categoryGroups->export($categoryGroups);
328
        }
329
330
        if (in_array('tagGroups', $dataTypes)) {
331
            $export['tagGroups'] = Craft::app()->schematic_tagGroups->export($tagGroups);
332
        }
333
334
        // Element index settings are supported from Craft 2.5
335
        if (in_array('elementIndexSettings', $dataTypes) && version_compare(CRAFT_VERSION, '2.5', '>=')) {
336
            $export['elementIndexSettings'] = Craft::app()->schematic_elementIndexSettings->export();
337
        }
338
339
        if (in_array('pluginData', $dataTypes)) {
340
            $export['pluginData'] = [];
341
            $services = Craft::app()->plugins->call('registerMigrationService');
342
            $this->doExport($services, $export['pluginData']);
343
        }
344
345
        return $export;
346
    }
347
348
    /**
349
     * Handles exporting.
350
     *
351
     * @param array $services
352
     * @param array $data
353
     */
354
    private function doExport(array $services, array &$data)
355
    {
356
        foreach ($services as $handle => $service) {
357
            if (is_array($service)) {
358
                $this->doExport($service, $data);
359
            } elseif ($service instanceof Base) {
360
                if ($service instanceof Base) {
361
                    $data[$handle] = $service->export();
362
                }
363
            }
364
        }
365
    }
366
367
    /**
368
     * Always return the super user.
369
     *
370
     * @return Craft\UserModel
371
     */
372
    public function getUser()
373
    {
374
        return Craft::app()->users->getUserById(1);
375
    }
376
377
    /**
378
     * Assume schematic can do anything.
379
     *
380
     * @return bool
381
     */
382
    public function checkPermission()
383
    {
384
        return true;
385
    }
386
}
387