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

Blender::logCreatedMigration()   A

Complexity

Conditions 3
Paths 5

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 11
rs 10
c 0
b 0
f 0
nc 5
nop 1
cc 3
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: jgulledge
5
 * Date: 9/29/2017
6
 * Time: 3:33 PM
7
 */
8
9
namespace LCI\Blend;
10
11
use LCI\Blend\Helpers\Format;
12
use LCI\Blend\Migrations\MigrationsCreator;
13
use LCI\Blend\Model\xPDO\BlendMigrations;
14
use modX;
0 ignored issues
show
Bug introduced by
The type modX was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use LCI\Blend\Blendable\Chunk;
16
use LCI\Blend\Blendable\Context;
17
use LCI\Blend\Blendable\MediaSource;
18
use LCI\Blend\Blendable\Plugin;
19
use LCI\Blend\Blendable\Resource;
20
use LCI\Blend\Blendable\Snippet;
21
use LCI\Blend\Blendable\SystemSetting;
22
use LCI\Blend\Blendable\Template;
23
use LCI\Blend\Blendable\TemplateVariable;
24
use LCI\Blend\Helpers\SimpleCache;
25
use LCI\MODX\Console\Helpers\UserInteractionHandler;
26
use PHPUnit\Runner\Exception;
27
28
class Blender
29
{
30
    /** @var string ~ version number of the project */
31
    private $version = '1.0.0 beta';
32
33
    /** @var array a list of valid upgrade migrations */
34
    protected $update_migrations = [
35
        '0.9.7' => 'v0_9_7_update',
36
        '0.9.8' => 'v0_9_8_update',
37
        '0.9.9' => 'v0_9_9_update',
38
        '0.9.10' => 'v0_9_10_update',
39
        '0.9.11' => 'v0_9_11_update',
40
        '1.0.0 beta' => 'v1_0_0_beta_update'
41
    ];
42
43
    /** @var  \modx */
0 ignored issues
show
Bug introduced by
The type modx was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
44
    protected $modx;
45
46
    /** @var array  */
47
    protected $modx_version_info = [];
48
49
    /** @var \LCI\MODX\Console\Helpers\UserInteractionHandler */
50
    protected $userInteractionHandler;
51
52
    /** @var array  */
53
    protected $config = [];
54
55
    /** @var boolean|array  */
56
    protected $blendMigrations = false;
57
58
    /** @var  \Tagger */
0 ignored issues
show
Bug introduced by
The type Tagger was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
59
    protected $tagger;
60
61
    protected $resource_id_map = [];
62
63
    protected $resource_seek_key_map = [];
64
65
    protected $category_map = [];
66
67
    /** @var string date('Y_m_d_His') */
68
    protected $seeds_dir = '';
69
70
    /** @var int  */
71
    protected $xpdo_version = 3;
72
73
    protected $blend_class_object = 'BlendMigrations';
74
75
    protected $blend_package = 'blend';
76
77
    /**
78
     * Stockpile constructor.
79
     *
80
     * @param \modX $modx
81
     * @param UserInteractionHandler $userInteractionHandler
82
     * @param array $config
83
     */
84
    public function __construct(modX $modx, UserInteractionHandler $userInteractionHandler, $config=[])
85
    {
86
        $this->modx = $modx;
87
88
        $this->modx_version_info = $this->modx->getVersionData();
89
90
        $this->userInteractionHandler = $userInteractionHandler;
91
92
        if (version_compare($this->modx_version_info['full_version'], '3.0') >= 0 ) {
93
            $this->xpdo_version = 3;
94
            $this->blend_class_object = 'LCI\\Blend\\Model\\xPDO\\BlendMigrations';
95
            $this->blend_package = 'LCI\\Blend\\Model\\xPDO';
96
97
        } else {
98
            $this->xpdo_version = 2;
99
        }
100
101
        $blend_modx_migration_dir = dirname(__DIR__);
102
        if (isset($config['blend_modx_migration_dir'])) {
103
            $blend_modx_migration_dir = $config['blend_modx_migration_dir'];
104
        }
105
106
        $this->config = [
107
            'migration_templates_path' => __DIR__. '/Migrations/templates/',
108
            'migrations_path' => $blend_modx_migration_dir.'database/migrations/',
109
            'seeds_path' => $blend_modx_migration_dir.'database/seeds/',
110
            'model_dir' => __DIR__ . ($this->xpdo_version >= 3 ? '/' : '/xpdo2/'),
111
            'extras' => [
112
                'tagger' => false
113
            ]
114
        ];
115
        $this->config = array_merge($this->config, $config);
116
117
        $this->seeds_dir = date('Y_m_d_His');
118
119
        $tagger_path = $this->modx->getOption('tagger.core_path', null, $this->modx->getOption('core_path') . 'components/tagger/') . 'model/tagger/';
120
        if (is_dir($tagger_path)) {
121
            $this->config['extras']['tagger'] = true;
122
            /** @var \Tagger $tagger */
123
            $this->tagger = $this->modx->getService('tagger', 'Tagger', $tagger_path, []);
124
        }
125
126
        if ($this->xpdo_version >= 3) {
127
            $this->modx->setPackage($this->blend_package, $this->config['model_dir']);
128
129
        } else {
130
            $this->modx->addPackage($this->blend_package, $this->config['model_dir']);
131
        }
132
    }
133
134
    /**
135
     * @return string
136
     */
137
    public function getBlendClassObject()
138
    {
139
        return $this->blend_class_object;
140
    }
141
142
    /**
143
     * @return UserInteractionHandler
144
     */
145
    public function getUserInteractionHandler()
146
    {
147
        return $this->userInteractionHandler;
148
    }
149
150
    /**
151
     * @return string
152
     */
153
    public function getVersion()
154
    {
155
        return $this->version;
156
    }
157
158
    /**
159
     * @return string
160
     */
161
    public function getSeedsDir()
162
    {
163
        return $this->seeds_dir;
164
    }
165
166
    /**
167
     * @param string $seeds_dir ~ local folder
168
     *
169
     * @return Blender
170
     */
171
    public function setSeedsDir($seeds_dir)
172
    {
173
        $this->seeds_dir = $seeds_dir;
174
        return $this;
175
    }
176
177
    /**
178
     * @param null $directory_key
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $directory_key is correct as it would always require null to be passed?
Loading history...
179
     * @return string
180
     */
181
    public function getSeedsPath($directory_key=null)
182
    {
183
        $seed_path = $this->config['seeds_path'];
184
        if (!empty($directory_key)) {
185
            $seed_path .= trim($directory_key, '/') . DIRECTORY_SEPARATOR;
186
        }
187
        return $seed_path;
188
    }
189
190
    /**
191
     * @return string
192
     */
193
    public function getMigrationPath()
194
    {
195
        return $this->config['migrations_path'];
196
    }
197
198
    /**
199
     * @param bool $reload
200
     * @param string $dir
201
     * @param int $count
202
     * @param int $id
203
     * @param string $name
204
     *
205
     * @return array ~ array of \BlendMigrations
206
     */
207
    public function getBlendMigrationCollection($reload=false, $dir='ASC', $count=0, $id=0, $name=null)
208
    {
209
        if (!$this->blendMigrations || $reload) {
210
            $blendMigrations = [];
211
212
            /** @var \xPDOQuery $query */
213
            $query = $this->modx->newQuery($this->blend_class_object);
214
            if ($id > 0 ) {
215
                $query->where(['id' => $id]);
216
            } elseif (!empty($name)) {
217
                $query->where(['name' => $name]);
218
            }
219
            // @TODO need a ran sequence column to better order of down
220
            $query->sortBy('name', $dir);
221
            if ($count > 0 ) {
222
                $query->limit($count);
223
            }
224
            $query->prepare();
225
            //echo 'SQL: '.$query->toSQL();
226
            $migrationCollection = $this->modx->getCollection($this->blend_class_object, $query);
227
228
            /** @var \BlendMigrations $migration */
229
            foreach ($migrationCollection as $migration) {
230
                $blendMigrations[$migration->get('name')] = $migration;
231
            }
232
            $this->blendMigrations = $blendMigrations;
233
        }
234
        return $this->blendMigrations;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->blendMigrations also could return the type true which is incompatible with the documented return type array.
Loading history...
235
    }
236
237
    /**
238
     * @return \Tagger
239
     */
240
    public function getTagger()
241
    {
242
        return $this->tagger;
243
    }
244
245
    public function getCategoryMap($refresh=false)
246
    {
247
        if (count($this->category_map) == 0 || $refresh) {
248
            $this->category_map = [
249
                'ids' => [],
250
                'names' => [],
251
                'lineage' => []
252
            ];
253
            $query = $this->modx->newQuery('modCategory');
254
            $query->sortBy('parent');
255
            $query->sortBy('rank');
256
            $categories = $this->modx->getCollection('modCategory', $query);
257
            foreach ($categories as $category) {
258
                $category_data = $category->toArray();
259
260
                $this->category_map['ids'][$category->get('id')] = $category_data;
261
262
                $key = trim($category->get('category'));
263
                // This is not unique!
264
                $this->category_map['names'][$key] = $category_data;
265
266
                // Get the lineage: Parent=>Child=>Grand Child as key
267
                $lineage = $key;
268
                if ($category_data['parent'] > 0 && isset($this->category_map['ids'][$category_data['parent']]) && isset($this->category_map['ids'][$category_data['parent']]['lineage'])) {
269
                    $lineage = $this->category_map['ids'][$category_data['parent']]['lineage'].'=>'.$key;
270
                } elseif ($category_data['parent'] > 0) {
271
                    //$this->out('DID NOT FIND PARENT?? '. print_r($category_data, true), true);
272
                }
273
274
                $this->category_map['ids'][$category->get('id')]['lineage'] = $lineage;
275
276
                $this->category_map['lineage'][$lineage] = $category->toArray();
277
            }
278
        }
279
        return $this->category_map;
280
    }
281
282
    /**
283
     * Use this method with your IDE to help manually build a Chunk with PHP
284
     * @param string $name
285
     * @return Chunk
286
     */
287
    public function getBlendableChunk($name)
288
    {
289
        /** @var \LCI\Blend\Blendable\Chunk $chunk */
290
        $chunk =  new Chunk($this->modx, $this, $name);
291
        return $chunk->setSeedsDir($this->getSeedsDir());
292
    }
293
    /**
294
     * @param array $chunks
295
     * @param string $seeds_dir
296
     */
297
    public function blendManyChunks($chunks=[], $seeds_dir='')
298
    {
299
        // will update if element does exist or create new
300
        foreach ($chunks as $seed_key) {
301
            /** @var \LCI\Blend\Blendable\Chunk $blendChunk */
302
            $blendChunk = new Chunk($this->modx, $this, $this->getNameFromSeedKey($seed_key));
303
            if (!empty($seeds_dir)) {
304
                $blendChunk->setSeedsDir($seeds_dir);
305
            }
306
            if ($blendChunk->blendFromSeed($seed_key)) {
307
                $this->out($seed_key.' has been blended into ID: ');
308
309
            } elseif($blendChunk->isExists()) {
310
                // @TODO prompt Do you want to blend Y/N/Compare
311
                $this->out($seed_key.' chunk already exists', true);
312
                if ($this->prompt('Would you like to update?', 'Y') === 'Y') {
313
                    if ($blendChunk->blendFromSeed($seed_key, true)) {
314
                        $this->out($seed_key.' has been blended');
315
                    }
316
                }
317
            } else {
318
                $this->out('There was an error saving '.$seed_key, true);
319
            }
320
        }
321
    }
322
323
    /**
324
     * @param array $chunks
325
     * @param string $seeds_dir
326
     */
327
    public function revertBlendManyChunks($chunks=[], $seeds_dir='')
328
    {
329
        // will update if system setting does exist or create new
330
        foreach ($chunks as $seed_key) {
331
            /** @var \LCI\Blend\Blendable\Chunk $blendChunk */
332
            $blendChunk = new Chunk($this->modx, $this, $this->getNameFromSeedKey($seed_key));
333
            if (!empty($seeds_dir)) {
334
                $blendChunk->setSeedsDir($seeds_dir);
335
            }
336
337
            if ( $blendChunk->revertBlend() ) {
338
                $this->out($blendChunk->getFieldName().' chunk has been reverted to '.$seeds_dir);
339
340
            } else {
341
                $this->out($blendChunk->getFieldName().' chunk was not reverted', true);
342
            }
343
        }
344
    }
345
346
    /**
347
     * Use this method with your IDE to help manually build a Chunk with PHP
348
     * @param string $key
349
     * @return Context
350
     */
351
    public function getBlendableContext($key)
352
    {
353
        /** @var \LCI\Blend\Blendable\Context $chunk */
354
        $context =  new Context($this->modx, $this, $key);
355
        return $context->setSeedsDir($this->getSeedsDir());
356
    }
357
358
    /**
359
     * @param array $contexts
360
     * @param string $seeds_dir
361
     */
362
    public function blendManyContexts($contexts=[], $seeds_dir='')
363
    {
364
        // will update if element does exist or create new
365
        foreach ($contexts as $seed_key) {
366
            /** @var \LCI\Blend\Blendable\Context $blendContext */
367
            $blendContext = new Context($this->modx, $this, $this->getNameFromSeedKey($seed_key));
368
            if (!empty($seeds_dir)) {
369
                $blendContext->setSeedsDir($seeds_dir);
370
            }
371
            if ($blendContext->blendFromSeed($seed_key)) {
372
                $this->out($seed_key.' has been blended ');
373
374
            } elseif($blendContext->isExists()) {
375
                // @TODO prompt Do you want to blend Y/N/Compare
376
                $this->out($seed_key.' chunk already exists', true);
377
                if ($this->prompt('Would you like to update?', 'Y') === 'Y') {
378
                    if ($blendContext->blendFromSeed($seed_key, true)) {
379
                        $this->out($seed_key.' has been blended');
380
                    }
381
                }
382
            } else {
383
                $this->out('There was an error saving '.$seed_key, true);
384
            }
385
        }
386
    }
387
388
    /**
389
     * @param array $contexts
390
     * @param string $seeds_dir
391
     */
392
    public function revertBlendManyContexts($contexts=[], $seeds_dir='')
393
    {
394
        // will update if system setting does exist or create new
395
        foreach ($contexts as $seed_key) {
396
            /** @var \LCI\Blend\Blendable\Context $blendContext */
397
            $blendContext = new Context($this->modx, $this, $this->getNameFromSeedKey($seed_key));
398
            if (!empty($seeds_dir)) {
399
                $blendContext->setSeedsDir($seeds_dir);
400
            }
401
402
            if ( $blendContext->revertBlend() ) {
403
                $this->out($blendContext->getFieldKey().' context has been reverted to '.$seeds_dir);
404
405
            } else {
406
                $this->out($blendContext->getFieldKey().' context was not reverted', true);
407
            }
408
        }
409
    }
410
411
412
    /**
413
     * @param string $name
414
     * @return \LCI\Blend\Blendable\MediaSource
415
     */
416
    public function getBlendableMediaSource($name)
417
    {
418
        /** @var \LCI\Blend\Blendable\MediaSource $mediaSource */
419
        $mediaSource =  new MediaSource($this->modx, $this, $name);
420
        return $mediaSource
421
            ->setFieldName($name)
422
            ->setSeedsDir($this->getSeedsDir());
423
    }
424
425
    /**
426
     * @param array $media_sources
427
     * @param string $seeds_dir
428
     */
429
    public function blendManyMediaSources($media_sources=[], $seeds_dir='')
430
    {
431
        // will update if element does exist or create new
432
        foreach ($media_sources as $seed_key) {
433
            /** @var \LCI\Blend\Blendable\MediaSource $blendMediaSource */
434
            $blendMediaSource = new MediaSource($this->modx, $this);
435
            if (!empty($seeds_dir)) {
436
                $blendMediaSource->setSeedsDir($seeds_dir);
437
            }
438
            if ($blendMediaSource->blendFromSeed($seed_key)) {
439
                $this->out($seed_key.' has been blended into ID: ');
440
441
            } elseif($blendMediaSource->isExists()) {
442
                // @TODO add Compare as option
443
                $this->out($seed_key.' media source already exists', true);
444
                if ($this->prompt('Would you like to update?', 'Y') === 'Y') {
445
                    if ($blendMediaSource->blendFromSeed($seed_key, true)) {
446
                        $this->out($seed_key.' has been blended');
447
                    }
448
                }
449
            } else {
450
                $this->out('There was an error saving '.$seed_key, true);
451
            }
452
        }
453
    }
454
455
    /**
456
     * @param array $media_sources
457
     * @param string $seeds_dir
458
     */
459
    public function revertBlendManyMediaSources($media_sources=[], $seeds_dir='')
460
    {
461
        // will update if system setting does exist or create new
462
        foreach ($media_sources as $seed_key) {
463
            /** @var \LCI\Blend\Blendable\MediaSource $blendMediaSource */
464
            $blendMediaSource = new MediaSource($this->modx, $this, $this->getNameFromSeedKey($seed_key));
465
            if (!empty($seeds_dir)) {
466
                $blendMediaSource->setSeedsDir($seeds_dir);
467
            }
468
469
            if ( $blendMediaSource->revertBlend() ) {
470
                $this->out($blendMediaSource->getFieldName().' media source has been reverted to '.$seeds_dir);
471
472
            } else {
473
                $this->out($blendMediaSource->getFieldName().' media source was not reverted', true);
474
            }
475
        }
476
    }
477
478
    /**
479
     * Use this method with your IDE to help manually build a Plugin with PHP
480
     * @param string $name
481
     * @return \LCI\Blend\Blendable\Plugin
482
     */
483
    public function getBlendablePlugin($name)
484
    {
485
        /** @var \LCI\Blend\Blendable\Plugin $plugin */
486
        $plugin =  new Plugin($this->modx, $this, $name);
487
        return $plugin->setSeedsDir($this->getSeedsDir());
488
    }
489
490
    /**
491
     * @param array $plugins
492
     * @param string $seeds_dir
493
     */
494
    public function blendManyPlugins($plugins=[], $seeds_dir='')
495
    {
496
        // will update if element does exist or create new
497
        foreach ($plugins as $seed_key) {
498
            /** @var \LCI\Blend\Blendable\Plugin $blendPlugin */
499
            $blendPlugin = new Plugin($this->modx, $this, $this->getNameFromSeedKey($seed_key));
500
            if (!empty($seeds_dir)) {
501
                $blendPlugin->setSeedsDir($seeds_dir);
502
            }
503
            if ($blendPlugin->blendFromSeed($seed_key)) {
504
                $this->out($seed_key.' has been blended into ID: ');
505
506
            } elseif($blendPlugin->isExists()) {
507
                // @TODO prompt Do you want to blend Y/N/Compare
508
                $this->out($seed_key.' plugin already exists', true);
509
                if ($this->prompt('Would you like to update?', 'Y') === 'Y') {
510
                    if ($blendPlugin->blendFromSeed($seed_key, true)) {
511
                        $this->out($seed_key.' has been blended');
512
                    }
513
                }
514
            } else {
515
                $this->out('There was an error saving '.$seed_key, true);
516
            }
517
        }
518
    }
519
520
    /**
521
     * @param array $plugins
522
     * @param string $seeds_dir
523
     */
524
    public function revertBlendManyPlugins($plugins=[], $seeds_dir='')
525
    {
526
        // will update if system setting does exist or create new
527
        foreach ($plugins as $seed_key) {
528
            /** @var \LCI\Blend\Blendable\Plugin $blendPlugin */
529
            $blendPlugin = new Plugin($this->modx, $this);
530
            if (!empty($seeds_dir)) {
531
                $blendPlugin->setSeedsDir($seeds_dir);
532
            }
533
534
            if ( $blendPlugin->revertBlend() ) {
535
                $this->out($blendPlugin->getFieldName().' plugin has been reverted to '.$seeds_dir);
536
537
            } else {
538
                $this->out($blendPlugin->getFieldName().' plugin was not reverted', true);
539
            }
540
        }
541
    }
542
543
    /**
544
     * Use this method with your IDE to help manually build a Snippet with PHP
545
     * @param string $name
546
     * @return \LCI\Blend\Blendable\Snippet
547
     */
548
    public function getBlendableSnippet($name)
549
    {
550
        /** @var Snippet $snippet */
551
        $snippet =  new Snippet($this->modx, $this, $name);
552
        return $snippet->setSeedsDir($this->getSeedsDir());
553
    }
554
555
    /**
556
     * @param array $snippets
557
     * @param string $seeds_dir
558
     */
559
    public function blendManySnippets($snippets=[], $seeds_dir='')
560
    {
561
        // will update if element does exist or create new
562
        foreach ($snippets as $seed_key) {
563
            /** @var \LCI\Blend\Blendable\Snippet $blendSnippet */
564
            $blendSnippet = new Snippet($this->modx, $this, $this->getNameFromSeedKey($seed_key));
565
            if (!empty($seeds_dir)) {
566
                $blendSnippet->setSeedsDir($seeds_dir);
567
            }
568
            if ($blendSnippet->blendFromSeed($seed_key)) {
569
                $this->out($seed_key.' has been blended');
570
571
            } elseif($blendSnippet->isExists()) {
572
                // @TODO prompt Do you want to blend Y/N/Compare
573
                $this->out($seed_key.' snippet already exists', true);
574
                if ($this->prompt('Would you like to update?', 'Y') === 'Y') {
575
                    if ($blendSnippet->blendFromSeed($seed_key, true)) {
576
                        $this->out($seed_key.' has been blended');
577
                    }
578
                }
579
            } else {
580
                $this->out('There was an error saving '.$seed_key, true);
581
            }
582
        }
583
    }
584
    /**
585
     * @param array $snippets
586
     * @param string $seeds_dir
587
     */
588
    public function revertBlendManySnippets($snippets=[], $seeds_dir='')
589
    {
590
        // will update if system setting does exist or create new
591
        foreach ($snippets as $seed_key) {
592
            /** @var Snippet $blendSnippet */
593
            $blendSnippet = new Snippet($this->modx, $this, $this->getNameFromSeedKey($seed_key));
594
            if (!empty($seeds_dir)) {
595
                $blendSnippet->setSeedsDir($seeds_dir);
596
            }
597
598
            if ( $blendSnippet->revertBlend() ) {
599
                $this->out($blendSnippet->getFieldName().' snippet has been reverted to '.$seeds_dir);
600
601
            } else {
602
                $this->out($blendSnippet->getFieldName().' snippet was not reverted', true);
603
            }
604
        }
605
    }
606
607
    /**
608
     * Use this method with your IDE to manually build a template
609
     * @param string $name
610
     * @return \LCI\Blend\Blendable\Template
611
     */
612
    public function getBlendableTemplate($name)
613
    {
614
        /** @var \LCI\Blend\Blendable\Template $template */
615
        $template =  new Template($this->modx, $this, $name);
616
        return $template->setSeedsDir($this->seeds_dir);
617
    }
618
619
    /**
620
     * @param array $templates
621
     * @param string $seeds_dir
622
     * @param bool $overwrite
623
     */
624
    public function blendManyTemplates($templates=[], $seeds_dir='', $overwrite=false)
625
    {
626
        // will update if template does exist or create new
627
        foreach ($templates as $seed_key) {
628
629
            /** @var \LCI\Blend\Blendable\Template $blendTemplate */
630
            $blendTemplate = new Template($this->modx, $this, $this->getNameFromSeedKey($seed_key));
631
            if (!empty($seeds_dir)) {
632
                $blendTemplate->setSeedsDir($seeds_dir);
633
            }
634
            if ($blendTemplate->blendFromSeed($seed_key, $overwrite)) {
635
                $this->out($seed_key.' has been blended');
636
637
            } elseif($blendTemplate->isExists()) {
638
                $this->out($seed_key.' template already exists', true);
639
                if ($this->prompt('Would you like to update?', 'Y') === 'Y') {
640
                    if ($blendTemplate->blendFromSeed($seed_key, true)) {
641
                        $this->out($seed_key.' has been blended');
642
                    }
643
                }
644
            } else {
645
                $this->out('There was an error saving '.$seed_key, true);
646
            }
647
        }
648
    }
649
650
    /**
651
     * @param array $templates
652
     * @param string $seeds_dir
653
     */
654
    public function revertBlendManyTemplates($templates=[], $seeds_dir='')
655
    {
656
        // will update if system setting does exist or create new
657
        foreach ($templates as $seed_key) {
658
            /** @var \LCI\Blend\Blendable\Template $blendTemplate */
659
            $blendTemplate = new Template($this->modx, $this, $this->getNameFromSeedKey($seed_key));
660
            if (!empty($seeds_dir)) {
661
                $blendTemplate->setSeedsDir($seeds_dir);
662
            }
663
664
            if ( $blendTemplate->revertBlend() ) {
665
                $this->out($blendTemplate->getFieldName().' template has been reverted to '.$seeds_dir);
666
667
            } else {
668
                $this->out($blendTemplate->getFieldName().' template was not reverted', true);
669
            }
670
        }
671
    }
672
673
    /**
674
     * Use this method with your IDE to manually build a template variable
675
     * @param string $name
676
     * @return TemplateVariable
677
     */
678
    public function getBlendableTemplateVariable($name)
679
    {
680
        /** @var \LCI\Blend\Blendable\TemplateVariable $tv */
681
        $tv =  new TemplateVariable($this->modx, $this, $name);
682
        return $tv->setSeedsDir($this->seeds_dir);
683
    }
684
685
    /**
686
     * @param string $alias
687
     * @param  string $context
688
     * @return \LCI\Blend\Blendable\Resource
689
     */
690
    public function getBlendableResource($alias, $context='web')
691
    {
692
        /** @var \LCI\Blend\Blendable\Resource $resource */
693
        $resource =  new Resource($this->modx, $this, $alias, $context);
694
        return $resource
695
            ->setSeedsDir($this->getSeedsDir());
696
    }
697
    /**
698
     * @param array $resources
699
     * @param string $seeds_dir
700
     * @param bool $overwrite
701
     *
702
     * @return bool
703
     */
704
    public function blendManyResources($resources=[], $seeds_dir='', $overwrite=false)
705
    {
706
        $saved = true;
707
        // will update if resource does exist or create new
708
        foreach ($resources as $context => $seeds) {
709
            foreach ($seeds as $seed_key) {
710
                /** @var \LCI\Blend\Blendable\Resource $blendResource */
711
                $blendResource = new Resource($this->modx, $this, $this->getAliasFromSeedKey($seed_key), $context);
712
713
                if (!empty($seeds_dir)) {
714
                    $blendResource->setSeedsDir($seeds_dir);
715
                }
716
717
                if ($blendResource->blendFromSeed($seed_key, $overwrite)) {
718
                    $this->out($seed_key . ' has been blended into ID: ');
719
720
                } elseif ($blendResource->isExists()) {
721
                    // @TODO prompt Do you want to blend Y/N/Compare
722
                    $this->out($seed_key . ' already exists', true);
723
                    if ($this->prompt('Would you like to update?', 'Y') === 'Y') {
724
                        if ($blendResource->blendFromSeed($seed_key, true)) {
725
                            $this->out($seed_key . ' has been blended into ID: ');
726
                        }
727
                    }
728
                } else {
729
                    $this->out('There was an error saving ' . $seed_key, true);
730
                    echo 'There was an error saving ' . $seed_key; exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
731
                    $saved = false;
0 ignored issues
show
Unused Code introduced by
$saved = false is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
732
                }
733
            }
734
        }
735
736
        return $saved;
737
    }
738
739
    /**
740
     * @param array $resources
741
     * @param string $seeds_dir
742
     * @param bool $overwrite
743
     *
744
     * @return bool
745
     */
746
    public function revertBlendManyResources($resources=[], $seeds_dir='', $overwrite=false)
0 ignored issues
show
Unused Code introduced by
The parameter $overwrite is not used and could be removed. ( Ignorable by Annotation )

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

746
    public function revertBlendManyResources($resources=[], $seeds_dir='', /** @scrutinizer ignore-unused */ $overwrite=false)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
747
    {
748
        $saved = true;
749
        // will update if resource does exist or create new
750
        foreach ($resources as $context => $seeds) {
751
            foreach ($seeds as $seed_key) {
752
                /** @var \LCI\Blend\Blendable\Resource $blendResource */
753
                $blendResource = new Resource($this->modx, $this, $this->getAliasFromSeedKey($seed_key), $context);
754
755
                if (!empty($seeds_dir)) {
756
                    $blendResource->setSeedsDir($seeds_dir);
757
                }
758
                if ($blendResource->revertBlend()) {
759
                    $this->out($seed_key . ' has been reverted ');
760
761
                } else {
762
                    $this->out('There was an error reverting resource ' . $seed_key, true);
763
                    $saved = false;
764
                }
765
            }
766
        }
767
768
        return $saved;
769
    }
770
771
    /**
772
     * @param string $key
773
     * @return \LCI\Blend\Blendable\SystemSetting
774
     */
775
    public function getBlendableSystemSetting($key='')
776
    {
777
        /** @var \LCI\Blend\Blendable\SystemSetting $systemSetting */
778
        $systemSetting =  new SystemSetting($this->modx, $this, $key);
779
        return $systemSetting->setSeedsDir($this->getSeedsDir());
780
    }
781
782
    /**
783
     * @param array $settings ~ [ ['name' => 'mySystemSetting', 'value' => 'myValue'], ..]
784
     * @param string $seeds_dir
785
     *
786
     * @return bool
787
     */
788
    public function blendManySystemSettings($settings=[], $seeds_dir='')
789
    {
790
        $success = true;
791
        // will update if system setting does exist or create new
792
        foreach ($settings as $data) {
793
            if (isset($data['columns'])) {
794
                $setting = $data['columns'];
795
            } else {
796
                $setting = $data;
797
                $data['columns'] = $data;
798
            }
799
800
            if (isset($setting['key'])) {
801
                $key = $setting['key'];
802
803
            } elseif (isset($setting['name'])) {
804
                $key = $setting['name'];
805
806
            } else {
807
                // Error: no name/key
808
                $success = false;
809
                continue;
810
            }
811
812
            $systemSetting = $this->getBlendableSystemSetting($key);
813
            if (!empty($seeds_dir)) {
814
                $systemSetting->setSeedsDir($seeds_dir);
815
            }
816
817
            if ($systemSetting->blendFromArray($data, true)) {
818
                $this->out($systemSetting->getFieldName().' setting has been blended');
819
            } else {
820
                $success = false;
821
            }
822
        }
823
824
        return $success;
825
    }
826
827
    /**
828
     * @param array $settings ~ [ ['name' => 'mySystemSetting', 'value' => 'myValue'], ..]
829
     * @param string $seeds_dir
830
     *
831
     * @return bool
832
     */
833
    public function revertBlendManySystemSettings($settings=[], $seeds_dir='')
834
    {
835
        $success = true;
836
        // will update if system setting does exist or create new
837
        foreach ($settings as $data) {
838
            if (isset($data['columns'])) {
839
                $setting = $data['columns'];
840
            } else {
841
                $setting = $data;
842
                $data['columns'] = $data;
843
            }
844
845
            if (isset($setting['key'])) {
846
                $key = $setting['key'];
847
848
            } elseif (isset($setting['name'])) {
849
                $key = $setting['name'];
850
851
            } else {
852
                // Error: no name/key
853
                $success = false;
854
                continue;
855
            }
856
857
            $systemSetting = $this->getBlendableSystemSetting($key);
858
859
            if (!empty($seeds_dir)) {
860
                $systemSetting->setSeedsDir($seeds_dir);
861
            }
862
863
            if ( $systemSetting->revertBlend() ) {
864
                $this->out($systemSetting->getFieldName().' setting has been reverted to '.$seeds_dir);
865
866
            } else {
867
                $this->out($systemSetting->getFieldName().' setting was not reverted', true);
868
                $success = false;
869
            }
870
        }
871
872
        return $success;
873
    }
874
875
    /**
876
     * @param string $question
877
     * @param string $default
878
     *
879
     * @return mixed
880
     */
881
    protected function prompt($question, $default='')
882
    {
883
        return $this->userInteractionHandler->promptInput($question, $default);
884
    }
885
886
    /**
887
     * @param string $question
888
     * @param bool $default
889
     * @return bool
890
     */
891
    protected function promptConfirm($question, $default=true)
892
    {
893
        return $this->userInteractionHandler->promptConfirm($question, $default);
894
    }
895
896
    /**
897
     * @param string $question
898
     * @param string|mixed $default
899
     * @param array $options ~ ex: ['Option1' => 'value', 'Option2' => 'value2', ...]
900
     * @return mixed ~ selected value
901
     */
902
    protected function promptSelectOneOption($question, $default, $options=[])
903
    {
904
        return $this->userInteractionHandler->promptSelectOneOption($question, $default, $options);
905
    }
906
907
    /**
908
     * @param string $question
909
     * @param string|mixed $default
910
     * @param array $options ~ ex: ['Option1' => 'value', 'Option2' => 'value2', ...]
911
     * @return array ~ array of selected values
912
     */
913
    protected function promptSelectMultipleOptions($question, $default, $options=[])
914
    {
915
        return $this->userInteractionHandler->promptSelectMultipleOptions($question, $default, $options);
916
    }
917
918
    /**
919
     * @param string $message
920
     * @param bool $error
921
     */
922
    public function out($message, $error=false)
923
    {
924
        if ($error) {
925
            $this->userInteractionHandler->tellUser($message, userInteractionHandler::MASSAGE_ERROR);
926
927
        } else {
928
            $this->userInteractionHandler->tellUser($message, userInteractionHandler::MASSAGE_STRING);
929
        }
930
    }
931
932
    /**
933
     * @param string $message
934
     */
935
    public function outSuccess($message)
936
    {
937
        $this->userInteractionHandler->tellUser($message, userInteractionHandler::MASSAGE_SUCCESS);
938
    }
939
940
    /**
941
     * @param string $name
942
     * @param string $server_type
943
     * @param string|null $migration_path
944
     *
945
     * @return bool
946
     */
947
    public function createBlankMigrationClassFile($name, $server_type='master', $migration_path=null)
948
    {
949
        $migrationCreator = new MigrationsCreator($this->userInteractionHandler);
950
951
        if (empty($migration_path)) {
952
            $migration_path = $this->getMigrationPath();
953
        }
954
955
        echo PHP_EOL.__METHOD__.PHP_EOL;
956
        echo '----- P: '.$migration_path.PHP_EOL;
957
958
        $success = $migrationCreator
959
            ->setPathTimeStamp($this->getSeedsDir())
960
            ->setName($name)
961
            ->setDescription('')
962
            ->setServerType($server_type)
963
            ->setMigrationsPath($migration_path)
964
            ->createBlankMigrationClassFile();
965
966
        $this->logCreatedMigration($migrationCreator->getLogData());
967
        return $success;
968
    }
969
970
    /**
971
     * @param \xPDOQuery|array|null $criteria
0 ignored issues
show
Bug introduced by
The type xPDOQuery was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
972
     * @param string $server_type
973
     * @param string $name
974
     * @param bool $create_migration_file
975
     *
976
     * @return array
977
     */
978
    public function makeChunkSeeds($criteria, $server_type='master', $name=null, $create_migration_file=true)
979
    {
980
        $keys = [];
981
        $collection = $this->modx->getCollection('modChunk', $criteria);
982
983
        foreach ($collection as $chunk) {
984
            /** @var \LCI\Blend\Blendable\Chunk $blendChunk */
985
            $blendChunk = new Chunk($this->modx, $this, $chunk->get('name'));
986
            $seed_key = $blendChunk
987
                ->setSeedsDir($this->getMigrationName('chunk', $name))
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type string; however, parameter $name of LCI\Blend\Blender::getMigrationName() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

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

987
                ->setSeedsDir($this->getMigrationName('chunk', /** @scrutinizer ignore-type */ $name))
Loading history...
988
                ->seed();
989
            $this->out("Chunk: ".$chunk->get('name').' Key: '.$seed_key);
990
            $keys[] = $seed_key;
991
        }
992
993
        if ($create_migration_file) {
994
            /** @var MigrationsCreator $migrationCreator */
995
            $migrationCreator = new MigrationsCreator($this->userInteractionHandler, $keys);
996
997
            $migrationCreator
998
                ->setPathTimeStamp($this->getSeedsDir())
999
                ->setName($name)
1000
                ->setDescription('')
1001
                ->setServerType($server_type)
1002
                ->setMigrationsPath($this->getMigrationPath())
1003
                ->createChunkMigrationClassFile();
1004
1005
            $this->logCreatedMigration($migrationCreator->getLogData());
1006
        }
1007
        return $keys;
1008
    }
1009
1010
    /**
1011
     * @param \xPDOQuery|array|null $criteria
1012
     * @param string $server_type
1013
     * @param string $name
1014
     * @param bool $create_migration_file
1015
     *
1016
     * @return array
1017
     */
1018
    public function makeContextSeeds($criteria, $server_type='master', $name=null, $create_migration_file=true)
1019
    {
1020
        $keys = [];
1021
        $collection = $this->modx->getCollection('modContext', $criteria);
1022
1023
        foreach ($collection as $context) {
1024
            /** @var Context $blendContext */
1025
            $blendContext = new Context($this->modx, $this, $context->get('key'));
1026
            $seed_key = $blendContext
1027
                ->setSeedsDir($this->getMigrationName('context', $name))
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type string; however, parameter $name of LCI\Blend\Blender::getMigrationName() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

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

1027
                ->setSeedsDir($this->getMigrationName('context', /** @scrutinizer ignore-type */ $name))
Loading history...
1028
                ->seed();
1029
            $this->out("Context: ".$context->get('name').' Key: '.$seed_key);
1030
            $keys[] = $seed_key;
1031
        }
1032
1033
        if ($create_migration_file) {
1034
            /** @var MigrationsCreator $migrationCreator */
1035
            $migrationCreator = new MigrationsCreator($this->userInteractionHandler, $keys);
1036
1037
            $migrationCreator
1038
                ->setPathTimeStamp($this->getSeedsDir())
1039
                ->setName($name)
1040
                ->setDescription('')
1041
                ->setServerType($server_type)
1042
                ->setMigrationsPath($this->getMigrationPath())
1043
                ->createContextMigrationClassFile();
1044
1045
            $this->logCreatedMigration($migrationCreator->getLogData());
1046
        }
1047
        return $keys;
1048
    }
1049
1050
    /**
1051
     * @param \xPDOQuery|array|null $criteria
1052
     * @param string $server_type
1053
     * @param string $name
1054
     * @param bool $create_migration_file
1055
     *
1056
     * @return array
1057
     */
1058
    public function makeMediaSourceSeeds($criteria, $server_type='master', $name=null, $create_migration_file=true)
1059
    {
1060
        $keys = [];
1061
        $collection = $this->modx->getCollection('modMediaSource', $criteria);
1062
1063
        foreach ($collection as $mediaSource) {
1064
            /** @var MediaSource $blendMediaSource */
1065
            $blendMediaSource = new MediaSource($this->modx, $this, $mediaSource->get('name'));
1066
            $seed_key = $blendMediaSource
1067
                ->setSeedsDir($this->getMigrationName('mediaSource', $name))
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type string; however, parameter $name of LCI\Blend\Blender::getMigrationName() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

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

1067
                ->setSeedsDir($this->getMigrationName('mediaSource', /** @scrutinizer ignore-type */ $name))
Loading history...
1068
                ->seed();
1069
            $this->out("Media Source: ".$mediaSource->get('name').' Key: '.$seed_key);
1070
            $keys[] = $seed_key;
1071
        }
1072
1073
        if ($create_migration_file) {
1074
            /** @var MigrationsCreator $migrationCreator */
1075
            $migrationCreator = new MigrationsCreator($this->userInteractionHandler, $keys);
1076
1077
            $migrationCreator
1078
                ->setPathTimeStamp($this->getSeedsDir())
1079
                ->setName($name)
1080
                ->setDescription('')
1081
                ->setServerType($server_type)
1082
                ->setMigrationsPath($this->getMigrationPath())
1083
                ->createMediaSourceMigrationClassFile();
1084
1085
            $this->logCreatedMigration($migrationCreator->getLogData());
1086
        }
1087
        return $keys;
1088
    }
1089
1090
    /**
1091
     * @param \xPDOQuery|array|null $criteria
1092
     * @param string $server_type
1093
     * @param string $name
1094
     * @param bool $create_migration_file
1095
     *
1096
     * @return array
1097
     */
1098
    public function makePluginSeeds($criteria, $server_type='master', $name=null, $create_migration_file=true)
1099
    {
1100
        $keys = [];
1101
        $collection = $this->modx->getCollection('modPlugin', $criteria);
1102
1103
        foreach ($collection as $plugin) {
1104
            /** @var \LCI\Blend\Blendable\Plugin $blendPlugin */
1105
            $blendPlugin = new Plugin($this->modx, $this, $plugin->get('name'));
1106
            $seed_key = $blendPlugin
1107
                ->setSeedsDir($this->getMigrationName('plugin', $name))
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type string; however, parameter $name of LCI\Blend\Blender::getMigrationName() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

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

1107
                ->setSeedsDir($this->getMigrationName('plugin', /** @scrutinizer ignore-type */ $name))
Loading history...
1108
                ->seed();
1109
            $this->out("Plugin: ".$plugin->get('name').' Key: '.$seed_key);
1110
            $keys[] = $seed_key;
1111
        }
1112
1113
        if ($create_migration_file) {
1114
            /** @var MigrationsCreator $migrationCreator */
1115
            $migrationCreator = new MigrationsCreator($this->userInteractionHandler, $keys);
1116
1117
            $migrationCreator
1118
                ->setPathTimeStamp($this->getSeedsDir())
1119
                ->setName($name)
1120
                ->setDescription('')
1121
                ->setServerType($server_type)
1122
                ->setMigrationsPath($this->getMigrationPath())
1123
                ->createPluginMigrationClassFile();
1124
1125
            $this->logCreatedMigration($migrationCreator->getLogData());
1126
        }
1127
        return $keys;
1128
    }
1129
1130
    /**
1131
     * @param \xPDOQuery|array|null $criteria
1132
     * @param string $server_type
1133
     * @param string $name
1134
     * @param bool $create_migration_file
1135
     *
1136
     * @return array
1137
     */
1138
    public function makeResourceSeeds($criteria, $server_type='master', $name=null, $create_migration_file=true)
1139
    {
1140
        $keys = [
1141
            'web' => []
1142
        ];
1143
1144
        $collection = $this->modx->getCollection('modResource', $criteria);
1145
        foreach ($collection as $resource) {
1146
            $blendResource = new Resource($this->modx, $this, $resource->get('alias'), $resource->get('context_key'));
1147
            $seed_key = $blendResource
1148
                ->setSeedsDir($this->getMigrationName('resource', $name))
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type string; however, parameter $name of LCI\Blend\Blender::getMigrationName() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

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

1148
                ->setSeedsDir($this->getMigrationName('resource', /** @scrutinizer ignore-type */ $name))
Loading history...
1149
                ->seed($resource);
1150
            $this->out("ID: ".$resource->get('id').' Key: '.$seed_key);
1151
1152
            if (!isset($keys[$resource->get('context_key')])) {
1153
                $keys[$resource->get('context_key')] = [];
1154
            }
1155
1156
            $keys[$resource->get('context_key')][] = $seed_key;
1157
        }
1158
1159
        if ($create_migration_file) {
1160
            /** @var MigrationsCreator $migrationCreator */
1161
            $migrationCreator = new MigrationsCreator($this->userInteractionHandler, $keys);
1162
1163
            $migrationCreator
1164
                ->setPathTimeStamp($this->getSeedsDir())
1165
                ->setName($name)
1166
                ->setDescription('')
1167
                ->setServerType($server_type)
1168
                ->setMigrationsPath($this->getMigrationPath())
1169
                ->createResourceMigrationClassFile();
1170
1171
            $this->logCreatedMigration($migrationCreator->getLogData());
1172
        }
1173
        return $keys;
1174
    }
1175
1176
    /**
1177
     * @param \xPDOQuery|array|null $criteria
1178
     * @param string $server_type
1179
     * @param string $name
1180
     * @param bool $create_migration_file
1181
     *
1182
     * @return array
1183
     */
1184
    public function makeSnippetSeeds($criteria, $server_type='master', $name=null, $create_migration_file=true)
1185
    {
1186
        $keys = [];
1187
        $collection = $this->modx->getCollection('modSnippet', $criteria);
1188
1189
        foreach ($collection as $snippet) {
1190
            /** @var \LCI\Blend\Blendable\Snippet $blendSnippet */
1191
            $blendSnippet = new Snippet($this->modx, $this, $snippet->get('name'));
1192
            $seed_key = $blendSnippet
1193
                ->setSeedsDir($this->getMigrationName('snippet', $name))
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type string; however, parameter $name of LCI\Blend\Blender::getMigrationName() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

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

1193
                ->setSeedsDir($this->getMigrationName('snippet', /** @scrutinizer ignore-type */ $name))
Loading history...
1194
                ->seed();
1195
            $this->out("Snippet: ".$snippet->get('name').' Key: '.$seed_key);
1196
            $keys[] = $seed_key;
1197
        }
1198
1199
        if ($create_migration_file) {
1200
            /** @var MigrationsCreator $migrationCreator */
1201
            $migrationCreator = new MigrationsCreator($this->userInteractionHandler, $keys);
1202
1203
            $migrationCreator
1204
                ->setPathTimeStamp($this->getSeedsDir())
1205
                ->setName($name)
1206
                ->setDescription('')
1207
                ->setServerType($server_type)
1208
                ->setMigrationsPath($this->getMigrationPath())
1209
                ->createSnippetMigrationClassFile();
1210
1211
            $this->logCreatedMigration($migrationCreator->getLogData());
1212
        }
1213
        return $keys;
1214
    }
1215
1216
    /**
1217
     * @param \xPDOQuery|array|null $criteria
1218
     * @param string $server_type
1219
     * @param string $name
1220
     * @param bool $create_migration_file
1221
     *
1222
     * @return array
1223
     */
1224
    public function makeSystemSettingSeeds($criteria, $server_type='master', $name=null, $create_migration_file=true)
1225
    {
1226
        $collection = $this->modx->getCollection('modSystemSetting', $criteria);
1227
1228
        $setting_data = [];
1229
        foreach ($collection as $setting) {
1230
            /** @var \LCI\Blend\Blendable\SystemSetting $blendableSetting */
1231
            $blendableSetting = $this->getBlendableSystemSetting($setting->get('key'));
1232
            $setting_data[] = $blendableSetting->seedToArray();
1233
        }
1234
1235
        // https://docs.modx.com/revolution/2.x/developing-in-modx/other-development-resources/class-reference/modx/modx.invokeevent
1236
        $this->modx->invokeEvent(
1237
            'OnBlendSeedSystemSettings',
1238
            [
1239
                'blender' => $this,
1240
                'data' => &$setting_data
1241
            ]
1242
        );
1243
1244
        if ($create_migration_file) {
1245
            /** @var MigrationsCreator $migrationCreator */
1246
            $migrationCreator = new MigrationsCreator($this->userInteractionHandler, $setting_data);
1247
1248
            $migrationCreator
1249
                ->setPathTimeStamp($this->getSeedsDir())
1250
                ->setName($name)
1251
                ->setDescription('')
1252
                ->setServerType($server_type)
1253
                ->setMigrationsPath($this->getMigrationPath())
1254
                ->createSystemSettingsMigrationClassFile();
1255
1256
            $this->logCreatedMigration($migrationCreator->getLogData());
1257
        }
1258
        return $setting_data;
1259
    }
1260
1261
    /**
1262
     * @param \xPDOQuery|array|null $criteria
1263
     * @param string $server_type
1264
     * @param string $name
1265
     * @param bool $create_migration_file
1266
     *
1267
     * @return array
1268
     */
1269
    public function makeTemplateSeeds($criteria, $server_type='master', $name=null, $create_migration_file=true)
1270
    {
1271
        $keys = [];
1272
        $collection = $this->modx->getCollection('modTemplate', $criteria);
1273
1274
        foreach ($collection as $template) {
1275
            //exit();
1276
            /** @var \LCI\Blend\Blendable\Template $blendTemplate */
1277
            $blendTemplate = new Template($this->modx, $this, $template->get('templatename'));
1278
            $seed_key = $blendTemplate
1279
                ->setSeedsDir($this->getMigrationName('template', $name))
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type string; however, parameter $name of LCI\Blend\Blender::getMigrationName() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

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

1279
                ->setSeedsDir($this->getMigrationName('template', /** @scrutinizer ignore-type */ $name))
Loading history...
1280
                ->seed();
1281
            $this->out("Template ID: ".$template->get('id').' Key: '.$seed_key);
1282
            $keys[] = $seed_key;
1283
        }
1284
1285
        if ($create_migration_file) {
1286
            /** @var MigrationsCreator $migrationCreator */
1287
            $migrationCreator = new MigrationsCreator($this->userInteractionHandler, $keys);
1288
1289
            $migrationCreator
1290
                ->setPathTimeStamp($this->getSeedsDir())
1291
                ->setName($name)
1292
                ->setDescription('')
1293
                ->setServerType($server_type)
1294
                ->setMigrationsPath($this->getMigrationPath())
1295
                ->createTemplateMigrationClassFile();
1296
1297
            $this->logCreatedMigration($migrationCreator->getLogData());
1298
        }
1299
        return $keys;
1300
    }
1301
1302
    /**
1303
     * @param string $server_type
1304
     * @param null|string $name
1305
     */
1306
    public function makeSiteSeed($server_type='master', $name=null)
1307
    {
1308
        $site_data = [
1309
            'mediaSources' => $this->makeMediaSourceSeeds(null, $server_type, $name, false),
1310
            'contexts' => $this->makeContextSeeds(null, $server_type, $name, false),
1311
            'chunks' => $this->makeChunkSeeds(null, $server_type, $name, false),
1312
            'plugins' => $this->makePluginSeeds(null, $server_type, $name, false),
1313
            'resources' => $this->makeResourceSeeds(null, $server_type, $name, false),
1314
            'snippets' => $this->makeSnippetSeeds(null, $server_type, $name, false),
1315
            'systemSettings' => $this->makeSystemSettingSeeds(null, $server_type, $name, false),
1316
            'templates' => $this->makeTemplateSeeds(null, $server_type, $name, false)
1317
        ];
1318
1319
        /** @var MigrationsCreator $migrationCreator */
1320
        $migrationCreator = new MigrationsCreator($this->userInteractionHandler, $site_data);
1321
1322
        $migrationCreator
1323
            ->setPathTimeStamp($this->getSeedsDir())
1324
            ->setName($name)
1325
            ->setDescription('')
1326
            ->setServerType($server_type)
1327
            ->setMigrationsPath($this->getMigrationPath())
1328
            ->createSiteMigrationClassFile();
1329
1330
        $this->logCreatedMigration($migrationCreator->getLogData());
1331
    }
1332
1333
    /**
1334
     * @param string $method
1335
     * @param bool $prompt
1336
     */
1337
    public function install($method='up', $prompt=false)
1338
    {
1339
        $migration_name = 'install_blender';
1340
        $custom_migration_dir = __DIR__.'/Migrations/Blend/';
1341
1342
        $this->runInstallMigration($migration_name, $custom_migration_dir, null, $method, $prompt);
1343
    }
1344
1345
    /**
1346
     * @param string $migration_name
1347
     * @param string|null $custom_migration_path
1348
     * @param string|null $seed_root_path
1349
     * @param string $method
1350
     * @param bool $prompt
1351
     */
1352
    protected function runInstallMigration($migration_name, $custom_migration_path=null, $seed_root_path=null, $method='up', $prompt=false)
1353
    {
1354
        // new blender for each instance
1355
        $config = $this->config;
1356
1357
        if (!empty($custom_migration_path)) {
1358
            $config['migrations_path'] = $custom_migration_path;
1359
        }
1360
        if (!empty($seed_root_path)) {
1361
            $config['seeds_path'] = $seed_root_path;
1362
        }
1363
1364
        $blender = new Blender($this->modx, $this->getUserInteractionHandler(), $config);
1365
1366
        /** @var Migrations $migrationProcessClass */
1367
        $migrationProcessClass = $blender->loadMigrationClass($migration_name, $blender);
1368
1369
        if (!$migrationProcessClass instanceof Migrations) {
0 ignored issues
show
introduced by
$migrationProcessClass is always a sub-type of LCI\Blend\Migrations. If $migrationProcessClass can have other possible types, add them to src/Blender.php:1366.
Loading history...
1370
            $this->out('File is not an instance of LCI\Blend\Migrations: '.$migration_name, true);
1371
            $this->out('Did not process, verify it is in the proper directory', true);
1372
1373
        } elseif ($method == 'up' && !$this->isBlendInstalledInModx()) {
1374
1375
            $migrationProcessClass->up();
1376
1377
            /** @var \BlendMigrations $migration */
1378
            $migration = $this->modx->newObject($this->blend_class_object);
1379
            if ($migration) {
0 ignored issues
show
introduced by
$migration is of type BlendMigrations, thus it always evaluated to true. If $migration can have other possible types, add them to src/Blender.php:1377
Loading history...
1380
                $migration->set('name', $migration_name);
1381
                $migration->set('type', 'master');
1382
                $migration->set('description', $migrationProcessClass->getDescription());
1383
                $migration->set('version', $migrationProcessClass->getVersion());
1384
                $migration->set('status', 'up_complete');
1385
                $migration->set('created_at', date('Y-m-d H:i:s'));
1386
                $migration->set('processed_at', date('Y-m-d H:i:s'));
1387
                if ($migration->save() ) {
1388
                    $this->outSuccess($migration_name.' ran and logged');
1389
                } else {
1390
                    $this->out($migration_name . ' did not log correctly', true);
1391
                }
1392
1393
                // does the migration directory exist?
1394
                if (!file_exists($this->getMigrationPath())) {
1395
                    $create = true;
1396
                    if ($prompt) {
1397
                        $response = $this->prompt('Create the following directory for migration files? (y/n) '.PHP_EOL
1398
                            .$this->getMigrationPath(), 'y');
1399
                        if (strtolower(trim($response)) != 'y') {
1400
                            $create = false;
1401
                        }
1402
                    }
1403
                    if ($create) {
1404
                        mkdir($this->getMigrationPath(), 0700, true);
1405
                        $this->outSuccess('Created migration directory: '. $this->getMigrationPath());
1406
                    }
1407
                }
1408
1409
            } else {
1410
                $this->out($migration_name . ' did not log correctly', true);
1411
            }
1412
1413
        } elseif ($method == 'down') {
1414
            $migrationProcessClass->down();
1415
1416
            /** @var \BlendMigrations $migration */
1417
            $migration = $this->modx->getObject($this->blend_class_object, ['name' => $migration_name]);
1418
            if ($migration) {
0 ignored issues
show
introduced by
$migration is of type BlendMigrations, thus it always evaluated to true. If $migration can have other possible types, add them to src/Blender.php:1416
Loading history...
1419
                $migration->set('name', $migration_name);
1420
                $migration->set('description', $migrationProcessClass->getDescription());
1421
                $migration->set('version', $migrationProcessClass->getVersion());
1422
                $migration->set('status', 'down_complete');
1423
                $migration->set('processed_at', date('Y-m-d H:i:s'));
1424
                $migration->save();
1425
            }
1426
1427
        }
1428
    }
1429
1430
    /**
1431
     * @param string $branch
1432
     */
1433
    public function runModxInstallGitBranchMigration($branch, $config=[])
1434
    {
1435
        $version = '';
1436
        switch ($branch) {
1437
            case '3.x':
1438
                $version = 'v3_0_0_dev_install';
1439
                break;
1440
1441
        }
1442
1443
        $this->cacheUserInstallConfig($version, $config);
1444
        $this->runModxInstallMigration($version);
1445
    }
1446
1447
    /**
1448
     * @param string $release
1449
     */
1450
    public function runModxInstallGitReleaseMigration($release, $config=[])
1451
    {
1452
        $release = str_replace(['.', '-'], '_', $release);
1453
1454
        $this->cacheUserInstallConfig($release, $config);
1455
        $this->runModxInstallMigration($release);
1456
    }
1457
1458
    /**
1459
     * @param string $migration_name
1460
     * @param string $method
1461
     * @param bool $prompt
1462
     */
1463
    protected function runModxInstallMigration($migration_name= 'v3_0_0_dev_install', $method='up', $prompt=false)
1464
    {
1465
        $custom_migration_dir = __DIR__.'/database/modx/migration/';
1466
        $seeds_root_path = __DIR__.'/database/modx/seeds/';
1467
1468
        $this->runInstallMigration($migration_name, $custom_migration_dir, $seeds_root_path, $method, $prompt);
1469
    }
1470
1471
    /**
1472
     * @param string $version_key
1473
     */
1474
    protected function cacheUserInstallConfig($version_key, $config=[])
1475
    {
1476
        $simpleCache = new SimpleCache(BLEND_CACHE_DIR . 'modx/');
0 ignored issues
show
Bug introduced by
The constant LCI\Blend\BLEND_CACHE_DIR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1477
        $simpleCache->set('install-config-'.$version_key, $config);
1478
    }
1479
1480
    /**
1481
     * @param string $method
1482
     */
1483
    public function update($method='up')
1484
    {
1485
        $current_vesion = $this->modx->getOption('blend.version');
1486
1487
        // new blender for each instance
1488
        $config = $this->config;
1489
        $config['migrations_path'] = __DIR__.'/Migrations/Blend/';
1490
1491
        $blender = new Blender($this->modx, $this->getUserInteractionHandler(), $config);
1492
1493
        foreach ($this->update_migrations as $v => $migration_name) {
1494
            if (version_compare($v, $current_vesion) === 1 ) {
1495
                // can not use as xPDO get queries fill the SELECT with the DB fields and since we are adding one this is a SQL error
1496
                //$blender->runMigration($method, 'master', 0, 0, $migration_name);
1497
1498
                /** @var Migrations $migrationProcessClass */
1499
                $migrationProcessClass = $this->loadMigrationClass($migration_name, $blender);
1500
1501
                if (!$migrationProcessClass instanceof Migrations) {
1502
                    $this->out('File is not an instance of LCI\Blend\Migrations: '.$migration_name, true);
1503
                    $this->out('Did not process, verify it is in the proper directory', true);
1504
1505
                } elseif ($method == 'up' && $this->isBlendInstalledInModx()) {
1506
1507
                    $migrationProcessClass->up();
1508
1509
                    /** @var \BlendMigrations $migration */
1510
                    $migration = $this->modx->newObject($this->blend_class_object);
1511
                    if ($migration) {
1512
                        $migration->set('name', $migration_name);
1513
                        $migration->set('type', 'master');
1514
                        $migration->set('description', $migrationProcessClass->getDescription());
1515
                        $migration->set('version', $migrationProcessClass->getVersion());
1516
                        $migration->set('status', 'up_complete');
1517
                        $migration->set('created_at', date('Y-m-d H:i:s'));
1518
                        $migration->set('processed_at', date('Y-m-d H:i:s'));
1519
                        if ($migration->save() ) {
1520
                            $this->outSuccess('Blend updated to '.$v);
1521
                        } else {
1522
                            $this->out('Blend did not update to '.$v, true);
1523
                        }
1524
1525
                    } else {
1526
                        $this->out('Blender could not save the update to '.$v, true);
1527
                    }
1528
1529
                } elseif ($method == 'down') {
1530
                    $migrationProcessClass->down();
1531
1532
                    /** @var \BlendMigrations $migration */
1533
                    $migration = $this->modx->getObject($this->blend_class_object, ['name' => $migration_name]);
1534
                    if ($migration) {
1535
                        $migration->set('name', $migration_name);
1536
                        $migration->set('description', $migrationProcessClass->getDescription());
1537
                        $migration->set('version', $migrationProcessClass->getVersion());
1538
                        $migration->set('status', 'down_complete');
1539
                        $migration->set('processed_at', date('Y-m-d H:i:s'));
1540
                        $migration->save();
1541
                    }
1542
1543
                }
1544
1545
            }
1546
        }
1547
1548
    }
1549
1550
    /**
1551
     * @return bool
1552
     */
1553
    public function requireUpdate()
1554
    {
1555
        $upgrade = false;
1556
1557
        $current_vesion = $this->modx->getOption('blend.version');
1558
        //                                      FILE version,        DB Version
1559
        if ( $this->isBlendInstalledInModx() && ( !$current_vesion || version_compare($this->getVersion(), $current_vesion)) ) {
1560
            $upgrade = true;
1561
        }
1562
1563
        return $upgrade;
1564
    }
1565
1566
    /**
1567
     * @return bool
1568
     */
1569
    public function isBlendInstalledInModx()
1570
    {
1571
        try {
1572
            $table = $this->modx->getTableName($this->blend_class_object);
1573
            if ($this->modx->query("SELECT 1 FROM {$table} LIMIT 1") === false) {
1574
                return false;
1575
            }
1576
        } catch (Exception $exception) {
1577
            // We got an exception == table not found
1578
            return false;
1579
        }
1580
1581
        /** @var \xPDOQuery $query */
1582
        $query = $this->modx->newQuery($this->blend_class_object);
1583
        $query->select('id');
1584
        $query->where([
1585
            'name' => 'install_blender',
1586
            'status' => 'up_complete'
1587
        ]);
1588
        $query->sortBy('name');
1589
1590
        $installMigration = $this->modx->getObject($this->blend_class_object, $query);
1591
        if ($installMigration instanceof \BlendMigrations || $installMigration instanceof \LCI\Blend\Model\xPDO\BlendMigrations) {
1592
            return true;
1593
        }
1594
1595
        return false;
1596
    }
1597
    /**
1598
     * @param string $method
1599
     * @param string $type
1600
     * @param int $count
1601
     * @param int $id
1602
     * @param string $name
1603
     */
1604
    public function runMigration($method='up', $type='master', $count=0, $id=0, $name=null)
1605
    {
1606
        $dir = 'ASC';
1607
        if ($method == 'down') {
1608
            $dir = 'DESC';
1609
        } else {
1610
            $count = 0;
1611
        }
1612
        // 1. Get all migrations currently in DB:
1613
        $blendMigrations = $this->getBlendMigrationCollection(false, $dir, $count, $id, $name);
1614
1615
        // 2. Load migration files:
1616
        if ($method == 'up') {
1617
            if ($this->retrieveMigrationFiles()) {
1618
                // this is needed just to insure that the order is correct and any new files
1619
                $blendMigrations = $this->getBlendMigrationCollection(true, $dir, $count, $id, $name);
1620
            }
1621
        }
1622
1623
        // 3. now run migration if proper
1624
        /** @var \BlendMigrations $migration */
1625
        foreach ($blendMigrations as $name => $migration) {
1626
            if ($id > 0 && $migration->get('id') != $id) {
1627
                continue;
1628
            }
1629
            /** @var string $name */
1630
            $name = $migration->get('name');
1631
1632
            /** @var string $status ~ ready|up_complete|down_complete*/
1633
            $status = $migration->get('status');
1634
1635
            /** @var string $server_type */
1636
            $server_type = $migration->get('type');
1637
1638
            if ( ($server_type != $type) || ($method == 'up' && $status == 'up_complete') || ($method == 'down' && $status != 'up_complete') ) {
1639
                continue;
1640
            }
1641
1642
            // new blender for each instance
1643
            $blender = new Blender($this->modx, $this->getUserInteractionHandler(), $this->config);
1644
1645
            /** @var Migrations $migrationProcessClass */
1646
            $migrationProcessClass = $this->loadMigrationClass($name, $blender);
1647
1648
            if ($migrationProcessClass instanceof Migrations) {
1649
                $this->out('Load Class: '.$name.' M: '.$method);
1650
                if ($method == 'up') {
1651
                    $migrationProcessClass->up();
1652
                    $this->out('Run up: '.$name);
1653
                    $migration->set('status', 'up_complete');
1654
                    $migration->set('processed_at', date('Y-m-d H:i:s'));
1655
                    $migration->save();
1656
1657
                } elseif ($method == 'down') {
1658
                    $migrationProcessClass->down();
1659
                    $migration->set('status', 'down_complete');
1660
                    $migration->set('processed_at', date('Y-m-d H:i:s'));
1661
                    $migration->save();
1662
1663
                } else {
1664
                    // error
1665
                }
1666
            } else {
1667
                // error
1668
            }
1669
        }
1670
    }
1671
1672
    /**
1673
     * @return bool ~ true if new migrations were found
1674
     */
1675
    public function retrieveMigrationFiles()
1676
    {
1677
        // 1. Get all migrations currently in DB:
1678
        $migrationCollection = $this->modx->getCollection($this->blend_class_object);
1679
1680
        $blendMigrations = [];
1681
1682
        /** @var \BlendMigrations $migration */
1683
        foreach ($migrationCollection as $migration) {
1684
            $blendMigrations[$migration->get('name')] = $migration;
1685
        }
1686
1687
        $migration_dir = $this->getMigrationPath();
1688
        $this->out('Searching '.$migration_dir);
1689
1690
        $reload = false;
1691
        /** @var \DirectoryIterator $file */
1692
        foreach (new \DirectoryIterator($this->getMigrationPath()) as $file) {
1693
            if ($file->isFile() && $file->getExtension() == 'php') {
1694
1695
                $name = $file->getBasename('.php');
1696
                // @TODO query DB! and test this method
1697
                if (!isset($blendMigrations[$name])) {
1698
                    $this->out('Create new '.$name);
1699
                    /** @var Migrations $migrationProcessClass */
1700
                    $migrationProcessClass = $this->loadMigrationClass($name, $this);
1701
1702
                    /** @var \BlendMigrations $migration */
1703
                    $migration = $this->modx->newObject($this->blend_class_object);
1704
                    $migration->set('name', $name);
1705
                    $migration->set('status', 'ready');
1706
                    if ($migrationProcessClass instanceof Migrations) {
1707
                        $migration->set('description', $migrationProcessClass->getDescription());
1708
                        $migration->set('version', $migrationProcessClass->getVersion());
1709
                        $migration->set('author', $migrationProcessClass->getAuthor());
1710
                    }
1711
                    if (!$migration->save()) {
1712
                        exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1713
                    };
1714
1715
                    $reload = true;
1716
                }
1717
            }
1718
        }
1719
        return $reload;
1720
    }
1721
1722
    /**
1723
     * @param string $name
1724
     * @param Blender $blender
1725
     *
1726
     * @return bool|Migrations
1727
     */
1728
    protected function loadMigrationClass($name, Blender $blender)
1729
    {
1730
        $migrationProcessClass = false;
1731
1732
        $file = $blender->getMigrationPath().$name.'.php';
1733
        if (file_exists($file)) {
1734
            require_once $file;
1735
1736
            if(class_exists($name)) {
1737
                /** @var Migrations $migrationProcessClass */
1738
                $migrationProcessClass = new $name($this->modx, $blender);
1739
            }
1740
        }
1741
1742
        return $migrationProcessClass;
1743
    }
1744
1745
    /**
1746
     * @param $type
1747
     * @param null $name
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $name is correct as it would always require null to be passed?
Loading history...
1748
     * @return string
1749
     */
1750
    public function getMigrationName($type, $name=null)
1751
    {
1752
        $format = new Format($this->seeds_dir);
1753
        return $format->getMigrationName($type, $name);
1754
    }
1755
1756
    /**
1757
     * @param string $name
1758
     * @param string $type ~ chunk, plugin, resource, snippet, systemSettings, template, site
1759
     *
1760
     * @return bool
1761
     */
1762
    public function removeMigrationFile($name, $type)
1763
    {
1764
        // @TODO refactor for setting $name
1765
        $class_name = $this->getMigrationName($type, $name);
1766
1767
        $removed = false;
1768
        $migration_file = $this->getMigrationPath() . $class_name . '.php';
1769
        if (file_exists($migration_file)) {
1770
            if (unlink($migration_file)) {
1771
                $removed = true;
1772
                $migration = $this->modx->getObject($this->blend_class_object, ['name' => $class_name]);
1773
                if (is_object($migration) && $migration->remove()) {
1774
                    $this->out($class_name . ' migration has been removed from the blend_migrations table');
1775
1776
                }
1777
            } else {
1778
                $this->out($class_name . ' migration has not been removed from the blend_migrations table', true);
1779
            }
1780
1781
        } else {
1782
            $this->out($this->getMigrationPath() . $class_name . '.php migration could not be found to remove', true);
1783
        }
1784
1785
        return $removed;
1786
    }
1787
    /**
1788
     * @param int $id
1789
     *
1790
     * @return bool|array
1791
     */
1792
    public function getResourceSeedKeyFromID($id)
1793
    {
1794
        if (!isset($this->resource_id_map[$id])) {
1795
            $seed_key = $context = false;
1796
            $resource = $this->modx->getObject('modResource', $id);
1797
            if ($resource) {
1798
                $context = $resource->get('context_key');
1799
                if (!isset($this->resource_seek_key_map[$context])) {
1800
                    $this->resource_seek_key_map[$context] = [];
1801
                }
1802
                $seed_key = $this->getSeedKeyFromAlias($resource->get('alias'));
1803
                $this->resource_seek_key_map[$context][$seed_key] = $id;
1804
            }
1805
            $this->resource_id_map[$id] = [
1806
                'context' => $context,
1807
                'seed_key' => $seed_key
1808
            ];
1809
        }
1810
1811
        return $this->resource_id_map[$id];
1812
    }
1813
1814
    /**
1815
     * @param string $seed_key
1816
     * @param string $context
1817
     *
1818
     * @return bool|int
1819
     */
1820
    public function getResourceIDFromSeedKey($seed_key, $context='web')
1821
    {
1822
        if (!isset($this->resource_seek_key_map[$context])) {
1823
            $this->resource_seek_key_map[$context] = [];
1824
        }
1825
        if (!isset($this->resource_seek_key_map[$context][$seed_key])) {
1826
            $id = false;
1827
            $alias = $this->getAliasFromSeedKey($seed_key);
1828
            $resource = $this->modx->getObject('modResource', ['alias' => $alias, 'context_key' => $context]);
1829
            if ($resource) {
1830
                $id = $resource->get('id');
1831
                $this->resource_seek_key_map[$context][$seed_key] = $id;
1832
                $this->resource_id_map[$id] = [
1833
                    'context' => $context,
1834
                    'seed_key' => $seed_key
1835
                ];
1836
            }
1837
            $this->resource_seek_key_map[$context][$seed_key] = $id;
1838
        }
1839
1840
        return $this->resource_seek_key_map[$context][$seed_key];
1841
    }
1842
1843
    /**
1844
     * @param string $alias
1845
     *
1846
     * @return string
1847
     */
1848
    public function getSeedKeyFromAlias($alias)
1849
    {
1850
        return str_replace('/', '#', $alias);
1851
    }
1852
1853
    /**
1854
     * @param string $seed_key
1855
     *
1856
     * @return string
1857
     */
1858
    public function getAliasFromSeedKey($seed_key)
1859
    {
1860
        return str_replace('#', '/', $seed_key);
1861
    }
1862
1863
    /**
1864
     * @deprecated
1865
     * @param string $name
1866
     * @param string $type ~ template, template-variable, chunk, snippet or plugin
1867
     * @return string
1868
     */
1869
    public function getElementSeedKeyFromName($name, $type)
1870
    {
1871
        return $type.'_'.$this->getSeedKeyFromName($name);
1872
    }
1873
1874
    /**
1875
     * @param string $name
1876
     * @return string
1877
     */
1878
    public function getSeedKeyFromName($name)
1879
    {
1880
        // @TODO review
1881
        return str_replace('/', '#', $name);
1882
    }
1883
1884
    /**
1885
     * @param string $seed_key
1886
     * @return string
1887
     */
1888
    public function getNameFromSeedKey($seed_key)
1889
    {
1890
        return str_replace('#', '/', $seed_key);
1891
    }
1892
1893
    /**
1894
     * @param $data
1895
     */
1896
    protected function logCreatedMigration($data)
1897
    {
1898
        try {
1899
            /** @var BlendMigrations $migration */
1900
            $migration = $this->modx->newObject($this->blend_class_object);
1901
            if ($migration) {
0 ignored issues
show
introduced by
$migration is of type LCI\Blend\Model\xPDO\BlendMigrations, thus it always evaluated to true. If $migration can have other possible types, add them to src/Blender.php:1899
Loading history...
1902
                $migration->fromArray($data);
1903
                $migration->save();
1904
            }
1905
        } catch (Exception $exception) {
1906
            $this->out($exception->getMessage(), true);
1907
        }
1908
    }
1909
}
1910
/**
1911
 * id | element_class | name | data | action ??
1912
 */
1913