Completed
Pull Request — master (#114)
by Bart
01:47
created

Schematic   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 196
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 3
dl 0
loc 196
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
B init() 0 39 1
A getDataType() 0 17 3
A checkMapper() 0 15 3
B getConverter() 0 23 5
A error() 0 4 1
A warning() 0 4 1
A info() 0 4 1
A importError() 0 15 4
1
<?php
2
3
namespace NerdsAndCompany\Schematic;
4
5
use Craft;
6
use craft\base\Model;
7
use yii\base\Module;
8
use yii\helpers\Console;
9
use NerdsAndCompany\Schematic\DataTypes\AssetTransformDataType;
10
use NerdsAndCompany\Schematic\DataTypes\CategoryGroupDataType;
11
use NerdsAndCompany\Schematic\DataTypes\ElementIndexDataType;
12
use NerdsAndCompany\Schematic\DataTypes\FieldDataType;
13
use NerdsAndCompany\Schematic\DataTypes\GlobalSetDataType;
14
use NerdsAndCompany\Schematic\DataTypes\PluginDataType;
15
use NerdsAndCompany\Schematic\DataTypes\SectionDataType;
16
use NerdsAndCompany\Schematic\DataTypes\SiteDataType;
17
use NerdsAndCompany\Schematic\DataTypes\TagGroupDataType;
18
use NerdsAndCompany\Schematic\DataTypes\UserGroupDataType;
19
use NerdsAndCompany\Schematic\DataTypes\UserSettingsDataType;
20
use NerdsAndCompany\Schematic\DataTypes\VolumeDataType;
21
use NerdsAndCompany\Schematic\Mappers\ElementIndexMapper;
22
use NerdsAndCompany\Schematic\Mappers\ModelMapper;
23
use NerdsAndCompany\Schematic\Mappers\PluginMapper;
24
use NerdsAndCompany\Schematic\Mappers\UserSettingsMapper;
25
use NerdsAndCompany\Schematic\Interfaces\ConverterInterface;
26
use NerdsAndCompany\Schematic\Interfaces\DataTypeInterface;
27
use NerdsAndCompany\Schematic\Interfaces\MapperInterface;
28
29
/**
30
 * Schematic.
31
 *
32
 * Sync Craft Setups.
33
 *
34
 * @author    Nerds & Company
35
 * @copyright Copyright (c) 2015-2018, Nerds & Company
36
 * @license   MIT
37
 *
38
 * @see      http://www.nerds.company
39
 *
40
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
41
 */
42
class Schematic extends Module
43
{
44
    /**
45
     * @var string
46
     */
47
    public $controllerNamespace = 'NerdsAndCompany\Schematic\Controllers';
48
49
    /**
50
     * @var array
51
     */
52
    public $dataTypes = [];
53
54
    /**
55
     * Initialize the module.
56
     */
57
    public function init()
58
    {
59
        Craft::setAlias('@NerdsAndCompany/Schematic', __DIR__);
60
61
        $config = [
62
            'components' => [
63
                'elementIndexMapper' => [
64
                    'class' => ElementIndexMapper::class,
65
                ],
66
                'modelMapper' => [
67
                    'class' => ModelMapper::class,
68
                ],
69
                'pluginMapper' => [
70
                    'class' => PluginMapper::class,
71
                ],
72
                'userSettingsMapper' => [
73
                    'class' => UserSettingsMapper::class,
74
                ],
75
            ],
76
            'dataTypes' => [
77
                'plugins' => PluginDataType::class,
78
                'sites' => SiteDataType::class,
79
                'volumes' => VolumeDataType::class,
80
                'assetTransforms' => AssetTransformDataType::class,
81
                'fields' => FieldDataType::class,
82
                'sections' => SectionDataType::class,
83
                'globalSets' => GlobalSetDataType::class,
84
                'categoryGroups' => CategoryGroupDataType::class,
85
                'tagGroups' => TagGroupDataType::class,
86
                'userGroups' => UserGroupDataType::class,
87
                'userSettings' => UserSettingsDataType::class,
88
                'elementIndexSettings' => ElementIndexDataType::class,
89
            ],
90
        ];
91
92
        Craft::configure($this, $config);
93
94
        parent::init();
95
    }
96
97
    /**
98
     * Get datatype by handle.
99
     *
100
     * @param string $dataTypeHandle
101
     *
102
     * @return DateTypeInterface
103
     */
104
    public function getDataType(string $dataTypeHandle): DataTypeInterface
105
    {
106
        $dataTypeClass = $this->dataTypes[$dataTypeHandle];
107
        if (!class_exists($dataTypeClass)) {
108
            Schematic::error('Class '.$dataTypeClass.' does not exist');
109
110
            return null;
111
        }
112
        $dataType = new $dataTypeClass();
113
        if (!$dataType instanceof DataTypeInterface) {
114
            Schematic::error($dataTypeClass.' does not implement DataTypeInterface');
115
116
            return null;
117
        }
118
119
        return $dataType;
120
    }
121
122
    /**
123
     * Check mapper handle is valid.
124
     *
125
     * @param string $mapper
126
     *
127
     * @return bool
128
     */
129
    public function checkMapper(string $mapper): bool
130
    {
131
        if (!isset($this->$mapper)) {
132
            Schematic::error('Mapper '.$mapper.' not found');
133
134
            return false;
135
        }
136
        if (!$this->$mapper instanceof MapperInterface) {
137
            Schematic::error(get_class($this->$mapper).' does not implement MapperInterface');
138
139
            return false;
140
        }
141
142
        return true;
143
    }
144
145
    /**
146
     * Find converter for model class.
147
     *
148
     * @param string $modelClass
149
     *
150
     * @return BaseConverter
151
     */
152
    public function getConverter(string $modelClass, string $originalClass = ''): ConverterInterface
153
    {
154
        if ('' === $originalClass) {
155
            $originalClass = $modelClass;
156
        }
157
158
        $converterClass = 'NerdsAndCompany\\Schematic\\Converters\\'.ucfirst(str_replace('craft\\', '', $modelClass));
159
        if (class_exists($converterClass)) {
160
            $converter = new $converterClass();
161
            if ($converter instanceof ConverterInterface) {
162
                return $converter;
163
            }
164
        }
165
166
        $parentClass = get_parent_class($modelClass);
167
        if (!$parentClass) {
168
            Schematic::error('No converter found for '.$originalClass);
169
170
            return null;
171
        }
172
173
        return $this->getConverter($parentClass, $originalClass);
174
    }
175
176
    /**
177
     * Is force enabled?
178
     *
179
     * @var bool
180
     */
181
    public static $force = false;
182
183
    /**
184
     * Logs an error message.
185
     *
186
     * @param string|array $message the message to be logged. This can be a simple string or a more
187
     *                              complex data structure, such as array.
188
     */
189
    public static function error($message): void
190
    {
191
        Craft::$app->controller->stdout($message.PHP_EOL, Console::FG_RED);
192
    }
193
194
    /**
195
     * Logs a warning message.
196
     *
197
     * @param string|array $message the message to be logged. This can be a simple string or a more
198
     *                              complex data structure, such as array.
199
     */
200
    public static function warning($message): void
201
    {
202
        Craft::$app->controller->stdout($message.PHP_EOL, Console::FG_YELLOW);
203
    }
204
205
    /**
206
     * Logs an info message.
207
     *
208
     * @param string|array $message the message to be logged. This can be a simple string or a more
209
     *                              complex data structure, such as array.
210
     */
211
    public static function info($message): void
212
    {
213
        Craft::$app->controller->stdout($message.PHP_EOL);
214
    }
215
216
    /**
217
     * Log an import error.
218
     *
219
     * @param Model  $record
220
     * @param string $handle
221
     */
222
    public static function importError(Model $record, string $handle): void
223
    {
224
        static::warning('- Error importing '.get_class($record).' '.$handle);
225
        $errors = $record->getErrors();
226
        if (!is_array($errors)) {
227
            static::error('   - An unknown error has occurred');
228
229
            return;
230
        }
231
        foreach ($errors as $subErrors) {
232
            foreach ($subErrors as $error) {
233
                static::error('   - '.$error);
234
            }
235
        }
236
    }
237
}
238