|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Kaliop\eZMigrationBundle\Core\Executor; |
|
4
|
|
|
|
|
5
|
|
|
use Kaliop\eZMigrationBundle\API\Value\MigrationStep; |
|
6
|
|
|
use Kaliop\eZMigrationBundle\API\MatcherInterface; |
|
7
|
|
|
use Kaliop\eZMigrationBundle\API\ReferenceBagInterface; |
|
8
|
|
|
use Kaliop\eZMigrationBundle\API\MigrationGeneratorInterface; |
|
9
|
|
|
use JmesPath\Env as JmesPath; |
|
10
|
|
|
|
|
11
|
|
|
class MigrationDefinitionExecutor extends AbstractExecutor |
|
12
|
|
|
{ |
|
13
|
|
|
protected $supportedStepTypes = array('migration_definition'); |
|
14
|
|
|
protected $supportedActions = array('generate'); |
|
15
|
|
|
|
|
16
|
|
|
/** @var \Kaliop\eZMigrationBundle\Core\MigrationService $migrationService */ |
|
17
|
|
|
protected $migrationService; |
|
18
|
|
|
/** @var ReferenceBagInterface $referenceResolver */ |
|
19
|
|
|
protected $referenceResolver; |
|
20
|
|
|
|
|
21
|
|
|
public function __construct($migrationService, ReferenceBagInterface $referenceResolver) |
|
22
|
|
|
{ |
|
23
|
|
|
$this->migrationService = $migrationService; |
|
24
|
|
|
$this->referenceResolver = $referenceResolver; |
|
25
|
|
|
} |
|
26
|
|
|
|
|
27
|
|
|
/** |
|
28
|
|
|
* @param MigrationStep $step |
|
29
|
|
|
* @return mixed |
|
30
|
|
|
* @throws \Exception |
|
31
|
|
|
*/ |
|
32
|
|
View Code Duplication |
public function execute(MigrationStep $step) |
|
|
|
|
|
|
33
|
|
|
{ |
|
34
|
|
|
parent::execute($step); |
|
35
|
|
|
|
|
36
|
|
|
if (!isset($step->dsl['mode'])) { |
|
37
|
|
|
throw new \Exception("Invalid step definition: missing 'mode'"); |
|
38
|
|
|
} |
|
39
|
|
|
|
|
40
|
|
|
$action = $step->dsl['mode']; |
|
41
|
|
|
|
|
42
|
|
|
if (!in_array($action, $this->supportedActions)) { |
|
43
|
|
|
throw new \Exception("Invalid step definition: value '$action' is not allowed for 'mode'"); |
|
44
|
|
|
} |
|
45
|
|
|
|
|
46
|
|
|
return $this->$action($step->dsl, $step->context); |
|
47
|
|
|
} |
|
48
|
|
|
|
|
49
|
|
|
/** |
|
50
|
|
|
* @todo allow to save to disk |
|
51
|
|
|
* @param array $dsl |
|
52
|
|
|
* @param array $context |
|
53
|
|
|
* @return array |
|
54
|
|
|
* @throws \Exception |
|
55
|
|
|
*/ |
|
56
|
|
|
protected function generate($dsl, $context) |
|
|
|
|
|
|
57
|
|
|
{ |
|
58
|
|
|
if (!isset($dsl['migration_type'])) { |
|
59
|
|
|
throw new \Exception("Invalid step definition: miss 'migration_type'"); |
|
60
|
|
|
} |
|
61
|
|
|
$migrationType = $dsl['migration_type']; |
|
62
|
|
|
if (!isset($dsl['migration_mode'])) { |
|
63
|
|
|
throw new \Exception("Invalid step definition: miss 'migration_mode'"); |
|
64
|
|
|
} |
|
65
|
|
|
$migrationMode = $dsl['migration_mode']; |
|
66
|
|
View Code Duplication |
if (!isset($dsl['match']) || !is_array($dsl['match'])) { |
|
|
|
|
|
|
67
|
|
|
throw new \Exception("Invalid step definition: miss 'match' to determine what to generate migration definition for"); |
|
68
|
|
|
} |
|
69
|
|
|
$match = $dsl['match']; |
|
70
|
|
|
|
|
71
|
|
|
$executors = $this->getGeneratingExecutors(); |
|
72
|
|
|
if (!in_array($migrationType, $executors)) { |
|
73
|
|
|
throw new \Exception("It is not possible to generate a migration of type '$migrationType': executor not found or not a generator"); |
|
74
|
|
|
} |
|
75
|
|
|
$executor = $this->migrationService->getExecutor($migrationType); |
|
76
|
|
|
|
|
77
|
|
|
$context = array(); |
|
78
|
|
View Code Duplication |
if (isset($dsl['lang']) && $dsl['lang'] != '') { |
|
|
|
|
|
|
79
|
|
|
$context['defaultLanguageCode'] = $dsl['lang']; |
|
80
|
|
|
} |
|
81
|
|
|
|
|
82
|
|
|
$matchCondition = array($match['type'] => $match['value']); |
|
83
|
|
|
if (isset($match['except']) && $match['except']) { |
|
84
|
|
|
$matchCondition = array(MatcherInterface::MATCH_NOT => $matchCondition); |
|
85
|
|
|
} |
|
86
|
|
|
$result = $executor->generateMigration($matchCondition, $migrationMode, $context); |
|
87
|
|
|
|
|
88
|
|
|
$this->setReferences($result, $dsl); |
|
89
|
|
|
|
|
90
|
|
|
return $result; |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
protected function setReferences($result, $dsl) |
|
94
|
|
|
{ |
|
95
|
|
|
if (!array_key_exists('references', $dsl)) { |
|
96
|
|
|
return false; |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
foreach ($dsl['references'] as $reference) { |
|
100
|
|
|
if (!isset($reference['json_path'])) { |
|
101
|
|
|
throw new \InvalidArgumentException('MigrationDefinition Executor does not support setting references if not using a json_path expression'); |
|
102
|
|
|
} |
|
103
|
|
|
|
|
104
|
|
|
$overwrite = false; |
|
105
|
|
|
if (isset($reference['overwrite'])) { |
|
106
|
|
|
$overwrite = $reference['overwrite']; |
|
107
|
|
|
} |
|
108
|
|
|
$value = JmesPath::search($reference['json_path'], $result); |
|
109
|
|
|
$this->referenceResolver->addReference($reference['identifier'], $value, $overwrite); |
|
110
|
|
|
} |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
/** |
|
114
|
|
|
* @todo cache this for faster access |
|
115
|
|
|
* @return array |
|
116
|
|
|
*/ |
|
117
|
|
View Code Duplication |
protected function getGeneratingExecutors() |
|
|
|
|
|
|
118
|
|
|
{ |
|
119
|
|
|
$migrationService = $this->migrationService; |
|
120
|
|
|
$executors = $migrationService->listExecutors(); |
|
121
|
|
|
foreach($executors as $key => $name) { |
|
122
|
|
|
$executor = $migrationService->getExecutor($name); |
|
123
|
|
|
if (!$executor instanceof MigrationGeneratorInterface) { |
|
124
|
|
|
unset($executors[$key]); |
|
125
|
|
|
} |
|
126
|
|
|
} |
|
127
|
|
|
return $executors; |
|
128
|
|
|
} |
|
129
|
|
|
} |
|
130
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.