Completed
Push — master ( e193c7...4949c6 )
by Bob Olde
05:30
created

Schematic::getPluginData()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
cc 3
eloc 2
nc 4
nop 3
crap 3
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
 * @link      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
     *
70
     * @return Result
71
     */
72 1
    public function importFromYaml($file, $override = null, $force = false)
73
    {
74 1
        Craft::app()->config->maxPowerCaptain();
75 1
        Craft::app()->setComponent('userSession', $this);
76
77 1
        $yaml = IOHelper::getFileContents($file);
78 1
        $yaml_override = IOHelper::getFileContents($override);
79 1
        $dataModel = Data::fromYaml($yaml, $yaml_override);
80
81 1
        return $this->importDataModel($dataModel, $force);
82
    }
83
84
    /**
85
     * Export to Yaml file.
86
     *
87
     * @param string $file
88
     * @param bool   $autoCreate
89
     *
90
     * @return Result
91
     */
92 3
    public function exportToYaml($file, $dataTypes = 'all', $autoCreate = true)
93
    {
94 3
        Craft::app()->config->maxPowerCaptain();
95 3
        Craft::app()->setComponent('userSession', $this);
96
97 3
        $result = new Result();
98 3
        $dataModel = $this->exportDataModel($dataTypes);
99 3
        $yaml = Data::toYaml($dataModel);
100
101 3
        if (!IOHelper::writeToFile($file, $yaml, $autoCreate)) { // Do not auto create
102 1
            $result->addError('errors', "Failed to write contents to \"$file\"");
103 1
        }
104
105 3
        return $result;
106
    }
107
108
    /**
109
     * Import data model.
110
     *
111
     * @param Data $model
112
     * @param bool $force if set to true items not in the import will be deleted
113
     *
114
     * @return Result
115
     */
116 1
    private function importDataModel(Data $model, $force)
117
    {
118
        // Import schema
119 1
        $locales = $model->getAttribute('locales', $force);
120 1
        $localesImportResult = Craft::app()->schematic_locales->import($locales);
121
122 1
        $plugins = $model->getAttribute('plugins', $force);
123 1
        $pluginImportResult = Craft::app()->schematic_plugins->import($plugins);
124
125 1
        $fields = $model->getAttribute('fields');
126 1
        $fieldImportResult = Craft::app()->schematic_fields->import($fields, $force);
127
128 1
        $assetSources = $model->getAttribute('assetSources');
129 1
        $assetSourcesImportResult = Craft::app()->schematic_assetSources->import($assetSources, $force);
130
131 1
        $assetTransforms = $model->getAttribute('assetTransforms');
132 1
        $assetTransformsImportResult = Craft::app()->schematic_assetTransforms->import($assetTransforms, $force);
133
134 1
        $globalSets = $model->getAttribute('globalSets');
135 1
        $globalSetsImportResult = Craft::app()->schematic_globalSets->import($globalSets, $force);
136
137 1
        $sections = $model->getAttribute('sections');
138 1
        $sectionImportResult = Craft::app()->schematic_sections->import($sections, $force);
139
140 1
        $categoryGroups = $model->getAttribute('categoryGroups');
141 1
        $categoryGroupImportResult = Craft::app()->schematic_categoryGroups->import($categoryGroups, $force);
142
143 1
        $tagGroups = $model->getAttribute('tagGroups');
144 1
        $tagGroupImportResult = Craft::app()->schematic_tagGroups->import($tagGroups, $force);
145
146 1
        $userGroups = $model->getAttribute('userGroups');
147 1
        $userGroupImportResult = Craft::app()->schematic_userGroups->import($userGroups, $force);
148
149 1
        $users = $model->getAttribute('users');
150 1
        $userImportResult = Craft::app()->schematic_users->import($users, true);
151
152 1
        $fields = $model->getAttribute('fields');
153 1
        $fieldImportResultFinal = Craft::app()->schematic_fields->import($fields, $force);
154
155
        // Element index settings are supported from Craft 2.5
156 1
        if (version_compare(CRAFT_VERSION, '2.5', '>=')) {
157 1
            $elementIndexSettingsImportResult = Craft::app()->schematic_elementIndexSettings->import(
158 1
                $model->getAttribute('elementIndexSettings'),
159
                $force
160 1
            );
161 1
        }
162
163
        // Verify results
164 1
        $result = new Result();
165 1
        $result->consume($localesImportResult);
166 1
        $result->consume($pluginImportResult);
167 1
        $result->consume($fieldImportResult);
168 1
        $result->consume($assetSourcesImportResult);
169 1
        $result->consume($assetTransformsImportResult);
170 1
        $result->consume($globalSetsImportResult);
171 1
        $result->consume($sectionImportResult);
172 1
        $result->consume($categoryGroupImportResult);
173 1
        $result->consume($tagGroupImportResult);
174 1
        $result->consume($userGroupImportResult);
175 1
        $result->consume($userImportResult);
176 1
        $result->consume($fieldImportResultFinal);
177
178
        // Element index settings are supported from Craft 2.5
179 1
        if (version_compare(CRAFT_VERSION, '2.5', '>=')) {
180 1
            $result->consume($elementIndexSettingsImportResult);
0 ignored issues
show
Bug introduced by
The variable $elementIndexSettingsImportResult does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
181 1
        }
182
183 1
        $services = Craft::app()->plugins->call('registerMigrationService');
184 1
        $this->doImport($result, $model->pluginData, $services, $force);
185
186 1
        return $result;
187
    }
188
189
    /**
190
     * Handles importing.
191
     *
192
     * @param Result       $result
193
     * @param array        $data
194
     * @param array|Base[] $services
195
     * @param bool         $force
196
     */
197 1
    private function doImport(Result $result, array $data, $services, $force)
198
    {
199 1
        foreach ($services as $handle => $service) {
200 1
            if (is_array($service)) {
201 1
                $this->doImport($result, $data, $service, $force);
202 1
            } elseif ($service instanceof Base) {
203 1
                $pluginData = $this->getPluginData($data, $handle);
204 1
                $hookResult = $service->import($pluginData, $force);
205 1
                $result->consume($hookResult);
206 1
            }
207 1
        }
208 1
    }
209
210
    /**
211
     * Export data model.
212
     *
213
     * @param string|array $dataTypes The data types to export
214
     *
215
     * @return array
216
     *
217
     * @throws Exception
218
     */
219 3
    private function exportDataModel($dataTypes = 'all')
220
    {
221
        // If all data types should be exported, get all the available data types that can be exported.
222 3
        if (is_array($dataTypes)) {
223
            // Validate that each data type specified to be exported is reconized.
224 1
            foreach ($dataTypes as $dataType) {
225 1
                if (!in_array($dataType, $this->exportableDataTypes)) {
226
                    $errorMessage = 'Invalid export type "'.$dataType.'". Accepted types are '
227
                        .implode(', ', $this->exportableDataTypes);
228
                    throw new Exception($errorMessage);
229
                }
230 1
            }
231 1
        } else {
232 2
            $dataTypes = $this->exportableDataTypes;
233
        }
234
235 3
        $assetSources = Craft::app()->assetSources->getAllSources();
236 3
        $assetTransforms = Craft::app()->assetTransforms->getAllTransforms();
237 3
        $categoryGroups = Craft::app()->categories->getAllGroups();
238 3
        $tagGroups = Craft::app()->tags->getAllTagGroups();
239
240 3
        $export = [];
241
242 3
        if (in_array('locales', $dataTypes)) {
243 3
            $export['locales'] = Craft::app()->schematic_locales->export();
244 3
        }
245
246 3
        if (in_array('assetSources', $dataTypes)) {
247 3
            $export['assetSources'] = Craft::app()->schematic_assetSources->export($assetSources);
248 3
        }
249
250 3
        if (in_array('assetTransforms', $dataTypes)) {
251 3
            $export['assetTransforms'] = Craft::app()->schematic_assetTransforms->export($assetTransforms);
252 3
        }
253
254 3
        if (in_array('fields', $dataTypes)) {
255 3
            $fieldGroups = Craft::app()->fields->getAllGroups();
256 3
            $export['fields'] = Craft::app()->schematic_fields->export($fieldGroups);
257 3
        }
258
259 3
        if (in_array('plugins', $dataTypes)) {
260 3
            $export['plugins'] = Craft::app()->schematic_plugins->export();
261 3
        }
262
263 3
        if (in_array('sections', $dataTypes)) {
264 3
            $sections = Craft::app()->sections->getAllSections();
265 3
            $export['sections'] = Craft::app()->schematic_sections->export($sections);
266 3
        }
267
268 3
        if (in_array('globalSets', $dataTypes)) {
269 3
            $globals = Craft::app()->globals->getAllSets();
270 3
            $export['globalSets'] = Craft::app()->schematic_globalSets->export($globals);
271 3
        }
272
273 3
        if (in_array('userGroups', $dataTypes)) {
274 3
            $userGroups = Craft::app()->userGroups->getAllGroups();
275 3
            $export['userGroups'] = Craft::app()->schematic_userGroups->export($userGroups);
276 3
        }
277
278 3
        if (in_array('users', $dataTypes)) {
279 3
            $export['users'] = Craft::app()->schematic_users->export();
280 3
        }
281
282 3
        if (in_array('categoryGroups', $dataTypes)) {
283 3
            $export['categoryGroups'] = Craft::app()->schematic_categoryGroups->export($categoryGroups);
284 3
        }
285
286 3
        if (in_array('tagGroups', $dataTypes)) {
287 3
            $export['tagGroups'] = Craft::app()->schematic_tagGroups->export($tagGroups);
288 3
        }
289
290
        // Element index settings are supported from Craft 2.5
291 3
        if (in_array('elementIndexSettings', $dataTypes) && version_compare(CRAFT_VERSION, '2.5', '>=')) {
292 3
            $export['elementIndexSettings'] = Craft::app()->schematic_elementIndexSettings->export();
293 3
        }
294
295 3
        if (in_array('pluginData', $dataTypes)) {
296 2
            $export['pluginData'] = [];
297 2
            $services = Craft::app()->plugins->call('registerMigrationService');
298 2
            $this->doExport($services, $export['pluginData']);
299 2
        }
300
301 3
        return $export;
302
    }
303
304
    /**
305
     * Handles exporting.
306
     *
307
     * @param array $services
308
     * @param array $data
309
     */
310 2
    private function doExport(array $services, array &$data)
311
    {
312 2
        foreach ($services as $handle => $service) {
313 2
            if (is_array($service)) {
314 2
                $this->doExport($service, $data);
315 2
            } elseif ($service instanceof Base) {
316 2
                if ($service instanceof Base) {
317 2
                    $data[$handle] = $service->export();
318 2
                }
319 2
            }
320 2
        }
321 2
    }
322
323
    /**
324
     * Always return the super user.
325
     *
326
     * @return Craft\UserModel
327
     */
328
    public function getUser()
329
    {
330
        return Craft::app()->users->getUserById(1);
331
    }
332
333
    /**
334
     * Assume schematic can do anything.
335
     *
336
     * @return bool
337
     */
338
    public function checkPermission()
339
    {
340
        return true;
341
    }
342
}
343