Test Setup Failed
Push — master ( 43ee18...a50601 )
by Josh
04:51
created

MigrationsCreator   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 433
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 46
eloc 151
dl 0
loc 433
rs 8.72
c 0
b 0
f 0

28 Methods

Rating   Name   Duplication   Size   Complexity  
A getServerType() 0 3 1
A createBlankMigrationClassFile() 0 3 1
A setServerType() 0 4 1
A setDescription() 0 4 1
A getVersion() 0 3 1
A setVersion() 0 4 1
A setPathTimeStamp() 0 5 1
A getPathTimeStamp() 0 3 1
A __construct() 0 11 1
A getName() 0 3 1
A setBaseMigrationsPath() 0 5 1
B writeMigrationClassFile() 0 67 6
B setSeedsPath() 0 19 7
A createSiteMigrationClassFile() 0 6 1
A createResourceMigrationClassFile() 0 9 1
A createChunkMigrationClassFile() 0 8 1
A getLogData() 0 3 1
A createPluginMigrationClassFile() 0 8 1
A getDescription() 0 3 1
A setLog() 0 4 1
A out() 0 7 2
A createMediaSourceMigrationClassFile() 0 8 1
A createTemplateMigrationClassFile() 0 8 1
A createSystemSettingsMigrationClassFile() 0 8 1
A createContextMigrationClassFile() 0 8 1
A createSnippetMigrationClassFile() 0 8 1
A setName() 0 4 1
B setMigrationsPath() 0 19 7

How to fix   Complexity   

Complex Class

Complex classes like MigrationsCreator often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use MigrationsCreator, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace LCI\Blend\Migrations;
4
5
use LCI\Blend\Helpers\Format;
6
use LCI\MODX\Console\Helpers\UserInteractionHandler;
7
8
/**
9
 * Class MigrationsCreator ~ will create Migrations
10
 * @package xPDO\Migrations
11
 */
12
class MigrationsCreator
13
{
14
    /** @var array  */
15
    protected $class_data = [];
16
17
    /** @var string */
18
    protected $description;
19
20
    /** @var string */
21
    protected $name;
22
23
    /** @var array  */
24
    protected $log_data = [];
25
26
    /** @var array  */
27
    protected $placeholders = [];
28
29
    /** @var string  */
30
    protected $server_type = 'master';
31
32
    /** @var false|string  */
33
    protected $path_time_stamp;
34
35
    /** @var string  */
36
    protected $migration_template = 'blank.txt';
37
38
    /** @var string ~ 1.0.0 the version of the migration file or related project */
39
    protected $version = '';
40
41
    /** @var Format */
42
    protected $format;
43
44
    protected $migration_templates_path;
45
    protected $migrations_path;
46
    protected $seeds_path;
47
48
    /** @var \LCI\MODX\Console\Helpers\UserInteractionHandler */
49
    protected $userInteractionHandler;
50
51
    /**
52
     * MigrationsCreator constructor.
53
     * @param UserInteractionHandler $userInteractionHandler
54
     * @param array $class_data
55
     */
56
    public function __construct(UserInteractionHandler $userInteractionHandler, $class_data=[])
57
    {
58
        $this->class_data = $class_data;
59
60
        $this->userInteractionHandler = $userInteractionHandler;
61
62
        $this->path_time_stamp = date('Y_m_d_His');
63
        $this->format = new Format($this->path_time_stamp);
64
65
        $this->migration_templates_path = __DIR__. '/templates/';
66
        $this->setBaseMigrationsPath(dirname(__DIR__) . DIRECTORY_SEPARATOR);
67
    }
68
69
    /**
70
     * @param string $path ~ like /var/www/public/core/components/blend/
71
     * @param bool $append ~ if true will create database/migrations with in the path
72
     * @return $this
73
     */
74
    public function setMigrationsPath($path, $append=false)
75
    {
76
        $this->migrations_path = $path;
77
78
        if (file_exists($path) && $append) {
79
            if (!file_exists($path . 'database')) {
80
                mkdir($path . 'database');
81
            }
82
            if (!file_exists($path . 'database/migrations')) {
83
                mkdir($path . 'database/migrations');
84
            }
85
            $this->migrations_path = $path . 'database/migrations/';
86
87
        } elseif( !file_exists($path) && !$append) {
88
            // @TODO review:
89
            mkdir($path, 0777, true);
90
        }
91
92
        return $this;
93
    }
94
    /**
95
     * @param string $path ~ like /var/www/public/core/components/blend/
96
     * @param bool $append ~ if true will create database/seeds with in the path
97
     * @return $this
98
     */
99
    public function setSeedsPath($path, $append=false)
100
    {
101
        $this->seeds_path = $path;
102
103
        if (file_exists($path) && $append) {
104
            if (!file_exists($path . 'database')) {
105
                mkdir($path . 'database');
106
            }
107
            if (!file_exists($path . 'database/seeds')) {
108
                mkdir($path . 'database/seeds');
109
            }
110
            $this->seeds_path = $path . 'database/seeds/';
111
112
        } elseif( !file_exists($path) && !$append) {
113
            // @TODO review:
114
            mkdir($path, 0777, true);
115
        }
116
117
        return $this;
118
    }
119
120
    /**
121
     * @param string $path ~ like /var/www/public/core/components/blend/ And then will create database/migrations and
122
     *      database/seeds
123
     * @return $this
124
     */
125
    public function setBaseMigrationsPath($path)
126
    {
127
        $this->setMigrationsPath($path, true);
128
        $this->setSeedsPath($path, true);
129
        return $this;
130
    }
131
    /**
132
     * @return bool
133
     */
134
    public function createBlankMigrationClassFile()
135
    {
136
        return $this->writeMigrationClassFile('blank');
0 ignored issues
show
Unused Code introduced by
The call to LCI\Blend\Migrations\Mig...iteMigrationClassFile() has too many arguments starting with 'blank'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

136
        return $this->/** @scrutinizer ignore-call */ writeMigrationClassFile('blank');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
Bug Best Practice introduced by
The expression return $this->writeMigrationClassFile('blank') also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
137
    }
138
139
    /**
140
     * @return bool
141
     */
142
    public function createChunkMigrationClassFile()
143
    {
144
        $this->migration_template = 'chunk.txt';
145
        $this->placeholders['chunkData'] = $this->format->prettyVarExport($this->class_data);
146
        $this->placeholders['classUpInners'] = '$this->blender->blendManyChunks($this->chunks, $this->getSeedsDir());';
147
        $this->placeholders['classDownInners'] = '$this->blender->revertBlendManyChunks($this->chunks, $this->getSeedsDir());';
148
149
        return $this->writeMigrationClassFile();
150
    }
151
152
    /**
153
     * @return bool
154
     */
155
    public function createContextMigrationClassFile()
156
    {
157
        $this->migration_template = 'context.txt';
158
        $this->placeholders['contextData'] = $this->format->prettyVarExport($this->class_data);
159
        $this->placeholders['classUpInners'] = '$this->blender->blendManyContexts($this->contexts, $this->getSeedsDir());';
160
        $this->placeholders['classDownInners'] = '$this->blender->revertBlendManyContexts($this->contexts, $this->getSeedsDir());';
161
162
        return $this->writeMigrationClassFile();
163
    }
164
165
    /**
166
     * @return bool
167
     */
168
    public function createMediaSourceMigrationClassFile()
169
    {
170
        $this->migration_template = 'mediaSource.txt';
171
        $this->placeholders['mediaSourceData'] = $this->format->prettyVarExport($this->class_data);
172
        $this->placeholders['classUpInners'] = '$this->blender->blendManyMediaSources($this->media_sources, $this->getSeedsDir());';
173
        $this->placeholders['classDownInners'] = '$this->blender->revertBlendManyMediaSources($this->media_sources, $this->getSeedsDir());';
174
175
        return $this->writeMigrationClassFile();
176
    }
177
178
    /**
179
     * @return bool
180
     */
181
    public function createPluginMigrationClassFile()
182
    {
183
        $this->migration_template = 'plugin.txt';
184
        $this->placeholders['pluginData'] = $this->format->prettyVarExport($this->class_data);
185
        $this->placeholders['classUpInners'] = '$this->blender->blendManyPlugins($this->plugins, $this->getSeedsDir());';
186
        $this->placeholders['classDownInners'] = '$this->blender->revertBlendManyPlugins($this->plugins, $this->getSeedsDir());';
187
188
        return $this->writeMigrationClassFile();
189
    }
190
191
    /**
192
     * @return bool
193
     */
194
    public function createResourceMigrationClassFile()
195
    {
196
        $this->migration_template = 'resource.txt';
197
198
        $this->placeholders['resourceData'] = $this->format->prettyVarExport($this->class_data);
199
        $this->placeholders['classUpInners'] = '$this->blender->blendManyResources($this->resources, $this->getSeedsDir());';
200
        $this->placeholders['classDownInners'] = '$this->blender->revertBlendManyResources($this->resources, $this->getSeedsDir());';
201
202
        return $this->writeMigrationClassFile();
203
    }
204
205
    /**
206
     * @return bool
207
     */
208
    public function createSnippetMigrationClassFile()
209
    {
210
        $this->migration_template = 'snippet.txt';
211
        $this->placeholders['snippetData'] = $this->format->prettyVarExport($this->class_data);
212
        $this->placeholders['classUpInners'] = '$this->blender->blendManySnippets($this->snippets, $this->getSeedsDir());';
213
        $this->placeholders['classDownInners'] = '$this->blender->revertBlendManySnippets($this->snippets, $this->getSeedsDir());';
214
215
        return $this->writeMigrationClassFile();
216
    }
217
218
    /**
219
     * @return bool
220
     */
221
    public function createSystemSettingsMigrationClassFile()
222
    {
223
        $this->migration_template = 'systemSettings.txt';
224
        $this->placeholders['settingsData'] = $this->format->prettyVarExport($this->class_data);
225
        $this->placeholders['classUpInners'] = '$this->blender->blendManySystemSettings($this->settings, $this->getSeedsDir());';
226
        $this->placeholders['classDownInners'] = '$this->blender->revertBlendManySystemSettings($this->settings, $this->getSeedsDir());';
227
228
        return $this->writeMigrationClassFile();
229
    }
230
231
    public function createTemplateMigrationClassFile()
232
    {
233
        $this->migration_template = 'template.txt';
234
        $this->placeholders['templateData'] = $this->format->prettyVarExport($this->class_data);
235
        $this->placeholders['classUpInners'] = '$this->blender->blendManyTemplates($this->templates, $this->getSeedsDir());';
236
        $this->placeholders['classDownInners'] = '$this->blender->revertBlendManyTemplates($this->templates, $this->getSeedsDir());';
237
238
        return $this->writeMigrationClassFile();
239
    }
240
241
    /**
242
     * @return bool
243
     */
244
    public function createSiteMigrationClassFile()
245
    {
246
        $this->migration_template = 'site.txt';
247
        $this->placeholders['siteData'] = $this->format->prettyVarExport($this->class_data);
248
249
        return $this->writeMigrationClassFile();
250
    }
251
252
    /**
253
     * @return string
254
     */
255
    public function getDescription()
256
    {
257
        return $this->description;
258
    }
259
260
    /**
261
     * @return array
262
     */
263
    public function getLogData()
264
    {
265
        return $this->log_data;
266
    }
267
268
    /**
269
     * @return string
270
     */
271
    public function getName()
272
    {
273
        return $this->name;
274
    }
275
276
    /**
277
     * @return false|string
278
     */
279
    public function getPathTimeStamp()
280
    {
281
        return $this->path_time_stamp;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->path_time_stamp also could return the type boolean which is incompatible with the documented return type false|string.
Loading history...
282
    }
283
284
    /**
285
     * @return string
286
     */
287
    public function getServerType()
288
    {
289
        return $this->server_type;
290
    }
291
292
    /**
293
     * @return string
294
     */
295
    public function getVersion()
296
    {
297
        return $this->version;
298
    }
299
300
301
    /**
302
     * @param string $description
303
     * @return MigrationsCreator
304
     */
305
    public function setDescription($description)
306
    {
307
        $this->description = $description;
308
        return $this;
309
    }
310
311
    /**
312
     * @param bool $log
313
     * @return MigrationsCreator
314
     */
315
    public function setLog($log)
316
    {
317
        $this->log = $log;
0 ignored issues
show
Bug Best Practice introduced by
The property log does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
318
        return $this;
319
    }
320
321
    /**
322
     * @param string $name
323
     * @return $this
324
     */
325
    public function setName($name)
326
    {
327
        $this->name = $name;
328
        return $this;
329
    }
330
331
    /**
332
     * @param false|string $path_time_stamp
333
     * @return MigrationsCreator
334
     */
335
    public function setPathTimeStamp($path_time_stamp)
336
    {
337
        $this->format = new Format($path_time_stamp);
338
        $this->path_time_stamp = $path_time_stamp;
339
        return $this;
340
    }
341
342
    /**
343
     * @param string $server_type
344
     * @return MigrationsCreator
345
     */
346
    public function setServerType($server_type)
347
    {
348
        $this->server_type = $server_type;
349
        return $this;
350
    }
351
352
    /**
353
     * @param string $version
354
     * @return MigrationsCreator
355
     */
356
    public function setVersion($version)
357
    {
358
        $this->version = $version;
359
        return $this;
360
    }
361
362
    /**
363
     * @return bool
364
     */
365
    protected function writeMigrationClassFile()
366
    {
367
        $class_name = $this->format->getMigrationName(substr($this->migration_template, 0,-4), $this->name);
368
369
        $placeholders = array_merge(
370
            [
371
                'classCreateDate' => date('Y/m/d'),
372
                'classCreateTime' => date('G:i:s T P'),
373
                'className' => $class_name,
374
                'classUpInners' => '//@TODO',
375
                'classDownInners' => '//@TODO',
376
                'description' => $this->getDescription(),
377
                'serverType' => $this->getServerType(),
378
                'seeds_dir' => $class_name,
379
                'version' => $this->getVersion()
380
            ],
381
            $this->placeholders
382
        );
383
384
        $file_contents = '';
385
386
        $migration_template = $this->migration_templates_path . $this->migration_template;
387
        if (file_exists($migration_template)) {
388
            $file_contents = file_get_contents($migration_template);
389
        } else {
390
            $this->out('Migration template file not found: ' . $migration_template, true);
391
        }
392
393
        foreach ($placeholders as $name => $value) {
394
            $file_contents = str_replace('[[+'.$name.']]', $value, $file_contents);
395
        }
396
397
        $this->out($this->migrations_path . $class_name.'.php');
398
399
        $write = false;
400
        if (file_exists($this->migrations_path . $class_name . '.php')) {
401
            $this->out($this->migrations_path . $class_name . '.php migration file already exists', true);
402
403
        }
404
        /**
405
         * @TODO refactor this?
406
         elseif (is_object($this->xPDO->getObject($this->migrator->getMigrationClassObject(), ['name' => $class_name]))) {
407
            $this->out($class_name . ' migration already has been created in the xpdo_migrations table', true);
408
409
        } */
410
        else {
411
            try {
412
                $write = file_put_contents($this->migrations_path . $class_name . '.php', $file_contents);
413
                 $this->log_data = [
414
                    'name' => $class_name,
415
                    'type' => $this->getServerType(),
416
                    'description' => $this->getDescription(),
417
                    'version' => $this->getVersion(),
418
                    'status' => 'seed export',
419
                    'created_at' => date('Y-m-d H:i:s')
420
                ];
421
            } catch (\Exception $exception) {
422
                $this->out($exception->getMessage(), true);
423
            }
424
425
            if (!$write) {
426
                $this->out($this->migrations_path . $class_name . '.php Did not write to file', true);
427
                $this->out('Verify that the folders exists and are writable by PHP', true);
428
            }
429
        }
430
431
        return $write;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $write also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
432
    }
433
434
    /**
435
     * @param string $message
436
     * @param bool $error
437
     */
438
    public function out($message, $error=false)
439
    {
440
        if ($error) {
441
            $this->userInteractionHandler->tellUser($message, userInteractionHandler::MASSAGE_ERROR);
442
443
        } else {
444
            $this->userInteractionHandler->tellUser($message, userInteractionHandler::MASSAGE_STRING);
445
        }
446
    }
447
448
}