|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* TechDivision\Import\Execution\ConfigurationManager |
|
5
|
|
|
* |
|
6
|
|
|
* NOTICE OF LICENSE |
|
7
|
|
|
* |
|
8
|
|
|
* This source file is subject to the Open Software License (OSL 3.0) |
|
9
|
|
|
* that is available through the world-wide-web at this URL: |
|
10
|
|
|
* http://opensource.org/licenses/osl-3.0.php |
|
11
|
|
|
* |
|
12
|
|
|
* PHP version 5 |
|
13
|
|
|
* |
|
14
|
|
|
* @author Tim Wagner <[email protected]> |
|
15
|
|
|
* @copyright 2019 TechDivision GmbH <[email protected]> |
|
16
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
|
17
|
|
|
* @link https://github.com/techdivision/import |
|
18
|
|
|
* @link http://www.techdivision.com |
|
19
|
|
|
*/ |
|
20
|
|
|
|
|
21
|
|
|
namespace TechDivision\Import\Execution; |
|
22
|
|
|
|
|
23
|
|
|
use TechDivision\Import\ConfigurationInterface; |
|
24
|
|
|
use TechDivision\Import\ConfigurationManagerInterface; |
|
25
|
|
|
|
|
26
|
|
|
/** |
|
27
|
|
|
* A simle configuration manager implementation. |
|
28
|
|
|
* |
|
29
|
|
|
* @author Tim Wagner <[email protected]> |
|
30
|
|
|
* @copyright 2019 TechDivision GmbH <[email protected]> |
|
31
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
|
32
|
|
|
* @link https://github.com/techdivision/import |
|
33
|
|
|
* @link http://www.techdivision.com |
|
34
|
|
|
*/ |
|
35
|
|
|
class ConfigurationManager implements ConfigurationManagerInterface |
|
36
|
|
|
{ |
|
37
|
|
|
|
|
38
|
|
|
/** |
|
39
|
|
|
* The configuration instance we want to handle. |
|
40
|
|
|
* |
|
41
|
|
|
* @var \TechDivision\Import\ConfigurationInterface |
|
42
|
|
|
*/ |
|
43
|
|
|
private $configuration; |
|
44
|
|
|
|
|
45
|
|
|
/** |
|
46
|
|
|
* Mapping for entity type to edition mapping (for configuration purposes only). |
|
47
|
|
|
* |
|
48
|
|
|
* @var array |
|
49
|
|
|
*/ |
|
50
|
|
|
private $entityTypeToEditionMapping = array( |
|
51
|
|
|
'eav_attribute' => 'general', |
|
52
|
|
|
'eav_attribte_set' => 'general', |
|
53
|
|
|
'catalog_product_inventory_msi' => 'general', |
|
54
|
|
|
'catalog_product_tier_price' => 'general', |
|
55
|
|
|
'customer_address' => 'general', |
|
56
|
|
|
'customer' => 'general' |
|
57
|
|
|
); |
|
58
|
|
|
|
|
59
|
|
|
/** |
|
60
|
|
|
* Initializes the manager with the configuration instance. |
|
61
|
|
|
* |
|
62
|
|
|
* @param \TechDivision\Import\ConfigurationInterface $configuration The configuration instance |
|
63
|
|
|
*/ |
|
64
|
|
|
public function __construct(ConfigurationInterface $configuration) |
|
65
|
|
|
{ |
|
66
|
|
|
$this->configuration = $configuration; |
|
67
|
|
|
} |
|
68
|
|
|
|
|
69
|
|
|
/** |
|
70
|
|
|
* Return's the managed configuration instance. |
|
71
|
|
|
* |
|
72
|
|
|
* @return \TechDivision\Import\ConfigurationInterface The configuration instance |
|
73
|
|
|
*/ |
|
74
|
|
|
public function getConfiguration() |
|
75
|
|
|
{ |
|
76
|
|
|
return $this->configuration; |
|
77
|
|
|
} |
|
78
|
|
|
|
|
79
|
|
|
/** |
|
80
|
|
|
* Return's an array with the configurations of the operations that has to be executed. |
|
81
|
|
|
* |
|
82
|
|
|
* @return \TechDivision\Import\Configuration\OperationConfigurationInterface[] The operation configurations |
|
83
|
|
|
*/ |
|
84
|
|
|
public function getOperations() |
|
85
|
|
|
{ |
|
86
|
|
|
|
|
87
|
|
|
// load the configuration instance |
|
88
|
|
|
$configuration = $this->getConfiguration(); |
|
89
|
|
|
|
|
90
|
|
|
// initialize the array for the operations that has to be executed |
|
91
|
|
|
$execute = array(); |
|
92
|
|
|
|
|
93
|
|
|
// load the shortcuts, the operations and the operation names from the configuration |
|
94
|
|
|
$shortcuts = $configuration->getShortcuts(); |
|
95
|
|
|
$operations = $configuration->getOperations(); |
|
96
|
|
|
$operationNames = $configuration->getOperationNames(); |
|
97
|
|
|
|
|
98
|
|
|
// query whether or not a shortcut has been passed |
|
99
|
|
|
if ($shortcut = $configuration->getShortcut()) { |
|
100
|
|
|
// load the Entity Type Code and map it to the Magento Edition |
|
101
|
|
|
$magentoEdition = $this->mapEntityTypeToMagentoEdition($entityTypeCode = $configuration->getEntityTypeCode()); |
|
102
|
|
|
// load the operation names from the shorcuts |
|
103
|
|
|
foreach ($shortcuts[$magentoEdition][$entityTypeCode] as $shortcutName => $opNames) { |
|
104
|
|
|
// query whether or not the operation has to be executed or nt |
|
105
|
|
|
if ($shortcutName === $shortcut) { |
|
106
|
|
|
foreach ($opNames as $operationName) { |
|
107
|
|
|
$operationNames[] = $operationName; |
|
108
|
|
|
} |
|
109
|
|
|
} |
|
110
|
|
|
} |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
// load and initialize the operations by their name |
|
114
|
|
|
foreach ($operationNames as $operationName) { |
|
115
|
|
|
// explode the shortcut to get Magento Edition, Entity Type Code and Operation Name |
|
116
|
|
|
list($edition, $type, $name) = explode('/', $operationName); |
|
117
|
|
|
// initialize the execution context with the Magento Edition + Entity Type Code |
|
118
|
|
|
$executionContext = new ExecutionContext($edition, $type); |
|
119
|
|
|
// load the operations we want to execute |
|
120
|
|
|
foreach ($operations[$edition][$type] as $operation) { |
|
121
|
|
|
// query whether or not the operation is in the array of operation that has to be executed |
|
122
|
|
|
if ($operation->getName() === $name) { |
|
123
|
|
|
// pass the execution context to the operation configuration |
|
124
|
|
|
$operation->setExecutionContext($executionContext); |
|
125
|
|
|
// finally add the operation to the array |
|
126
|
|
|
$execute[] = $operation; |
|
127
|
|
|
} |
|
128
|
|
|
} |
|
129
|
|
|
} |
|
130
|
|
|
|
|
131
|
|
|
// return the array with the operations |
|
132
|
|
|
return $execute; |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
|
|
/** |
|
136
|
|
|
* Return's the array with the configurations of the plugins that has to be executed. |
|
137
|
|
|
* |
|
138
|
|
|
* @return \TechDivision\Import\Configuration\PluginConfigurationInterface[] The plugin configurations |
|
139
|
|
|
* @throws \Exception Is thrown, if no plugins are available for the actual operation |
|
140
|
|
|
*/ |
|
141
|
|
|
public function getPlugins() |
|
142
|
|
|
{ |
|
143
|
|
|
|
|
144
|
|
|
// initialize the array with the plugins that have to be executed |
|
145
|
|
|
$plugins = array(); |
|
146
|
|
|
|
|
147
|
|
|
// load the operations that has to be executed |
|
148
|
|
|
$operations = $this->getOperations(); |
|
149
|
|
|
|
|
150
|
|
|
// load the configuration instance |
|
151
|
|
|
$configuration = $this->getConfiguration(); |
|
152
|
|
|
|
|
153
|
|
|
// initialize the plugin configurations of the selected operations |
|
154
|
|
|
foreach ($operations as $operation) { |
|
155
|
|
|
// iterate over the operation's plugins and initialize their configuration |
|
156
|
|
|
/** @var \TechDivision\Import\Configuration\PluginConfigurationInterface $plugin */ |
|
157
|
|
|
foreach ($operation->getPlugins() as $plugin) { |
|
158
|
|
|
// pass the operation configuration instance to the plugin configuration |
|
159
|
|
|
$plugin->setConfiguration($configuration); |
|
160
|
|
|
$plugin->setOperationConfiguration($operation); |
|
161
|
|
|
// if NO prefix for the move files subject has been set, we use the prefix from the first plugin's subject |
|
162
|
|
|
if ($configuration->getMoveFilesPrefix() === null) { |
|
163
|
|
|
// use the prefix of the first subject |
|
164
|
|
|
/** @var \TechDivision\Import\Configuration\SubjectConfigurationInterface $subject */ |
|
165
|
|
|
foreach ($plugin->getSubjects() as $subject) { |
|
166
|
|
|
$configuration->setMoveFilesPrefix($subject->getFileResolver()->getPrefix()); |
|
167
|
|
|
break; |
|
168
|
|
|
} |
|
169
|
|
|
} |
|
170
|
|
|
|
|
171
|
|
|
// query whether or not the plugin has subjects configured |
|
172
|
|
|
if ($subjects = $plugin->getSubjects()) { |
|
173
|
|
|
// extend the plugin's subjects with the main configuration instance |
|
174
|
|
|
/** @var \TechDivision\Import\Cli\Configuration\Subject $subject */ |
|
175
|
|
|
foreach ($subjects as $subject) { |
|
176
|
|
|
// set the configuration instance on the subject |
|
177
|
|
|
$subject->setConfiguration($configuration); |
|
178
|
|
|
} |
|
179
|
|
|
} |
|
180
|
|
|
|
|
181
|
|
|
// finally append the plugin |
|
182
|
|
|
$plugins[] = $plugin; |
|
183
|
|
|
} |
|
184
|
|
|
} |
|
185
|
|
|
|
|
186
|
|
|
// query whether or not we've at least ONE plugin to be executed |
|
187
|
|
|
if (sizeof($plugins) > 0) { |
|
188
|
|
|
return $plugins; |
|
|
|
|
|
|
189
|
|
|
} |
|
190
|
|
|
|
|
191
|
|
|
// throw an exception if no plugins are available |
|
192
|
|
|
throw new \Exception(sprintf('Can\'t find any plugins for operation(s) %s', implode(' > ', $configuration->getOperationNames()))); |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
/** |
|
196
|
|
|
* Return's the Entity Type to the configuration specific Magento Edition. |
|
197
|
|
|
* |
|
198
|
|
|
* @param string $entityType The Entity Type fot map |
|
199
|
|
|
* |
|
200
|
|
|
* @return string The mapped configuration specific Magento Edition |
|
201
|
|
|
*/ |
|
202
|
|
|
protected function mapEntityTypeToMagentoEdition($entityType) |
|
203
|
|
|
{ |
|
204
|
|
|
|
|
205
|
|
|
// load the actual Magento Edition |
|
206
|
|
|
$magentoEdition = strtolower($this->getConfiguration()->getMagentoEdition()); |
|
207
|
|
|
|
|
208
|
|
|
// map the Entity Type to the configuration specific Magento Edition |
|
209
|
|
|
if (isset($this->entityTypeToEditionMapping[$entityType])) { |
|
210
|
|
|
$magentoEdition = $this->entityTypeToEditionMapping[$entityType]; |
|
211
|
|
|
} |
|
212
|
|
|
|
|
213
|
|
|
// return the Magento Edition |
|
214
|
|
|
return $magentoEdition; |
|
215
|
|
|
} |
|
216
|
|
|
} |
|
217
|
|
|
|
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.