Completed
Push — master ( d07a45...da6ba5 )
by
unknown
02:06
created

src/Execution/ConfigurationManager.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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\Configuration\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\Configuration\ConfigurationInterface
42
     */
43
    private $configuration;
44
45
    /**
46
     * Mapping for entity type (for configuration purposes only).
47
     *
48
     * @var array
49
     */
50
    private $entityTypeMapping = array('none' => 'general');
51
52
    /**
53
     * Mapping for entity type to edition mapping (for configuration purposes only).
54
     *
55
     * @var array
56
     */
57
    private $entityTypeToEditionMapping = array(
58
        'eav_attribute'                 => 'general',
59
        'eav_attribute_set'             => 'general',
60
        'catalog_product_inventory_msi' => 'general',
61
        'catalog_product_tier_price'    => 'general',
62
        'catalog_product_url'           => 'general',
63
        'customer_address'              => 'general',
64
        'customer'                      => 'general',
65
        'general'                       => 'general',
66
        'none'                          => 'general',
67
        'debug'                         => 'general'
68
    );
69
70
    /**
71
     * Initializes the manager with the configuration instance.
72
     *
73
     * @param \TechDivision\Import\Configuration\ConfigurationInterface $configuration The configuration instance
74
     */
75
    public function __construct(ConfigurationInterface $configuration)
76
    {
77
        $this->configuration = $configuration;
78
    }
79
80
    /**
81
     * Return's the managed configuration instance.
82
     *
83
     * @return \TechDivision\Import\Configuration\ConfigurationInterface The configuration instance
84
     */
85
    public function getConfiguration()
86
    {
87
        return $this->configuration;
88
    }
89
90
    /**
91
     * Return's an array with the configurations of the operations that has to be executed.
92
     *
93
     * @return \TechDivision\Import\Configuration\OperationConfigurationInterface[] The operation configurations
94
     */
95
    public function getOperations()
96
    {
97
98
        // load the configuration instance
99
        $configuration = $this->getConfiguration();
100
101
        // initialize the array for the operations that has to be executed
102
        $execute = array();
103
104
        // load the shortcuts from the configuration
105
        $shortcuts = $configuration->getShortcuts();
106
107
        // map the entity type code, if necessary
108
        $entityTypeCode = $this->mapEntityType($configuration->getEntityTypeCode());
109
110
        // query whether or not a shortcut has been passed
111
        if ($shortcut = $configuration->getShortcut()) {
112
            // load the entity type code and map it to the Magento edition
113
            $magentoEdition = $this->mapEntityTypeToMagentoEdition($entityTypeCode);
114
            // load the operation names from the shorcuts
115
            foreach ($shortcuts[$magentoEdition][$entityTypeCode] as $shortcutName => $opNames) {
116
                // query whether or not the operation has to be executed or not
117
                if ($shortcutName === $shortcut) {
118
                    foreach ($opNames as $opName) {
119
                        $configuration->addOperationName($opName);
120
                    }
121
                }
122
            }
123
        }
124
125
        // load the operation names that has to be executed
126
        $operationNames = $configuration->getOperationNames();
127
128
        // load and initialize the operations by their name
129
        foreach ($operationNames as $operationName) {
130
            $execute[] = $this->getOperation($operationName);
131
        }
132
133
        // return the array with the operations
134
        return $execute;
135
    }
136
137
    /**
138
     * Return's the array with the configurations of the plugins that has to be executed.
139
     *
140
     * @return \TechDivision\Import\Configuration\PluginConfigurationInterface[] The plugin configurations
141
     * @throws \Exception Is thrown, if no plugins are available for the actual operation
142
     */
143
    public function getPlugins()
144
    {
145
146
        // initialize the array with the plugins that have to be executed
147
        $plugins = array();
148
149
        // load the operations that has to be executed
150
        $operations = $this->getOperations();
151
152
        // load the configuration instance
153
        $configuration = $this->getConfiguration();
154
155
        // initialize the plugin configurations of the selected operations
156
        foreach ($operations as $operation) {
157
            // iterate over the operation's plugins and initialize their configuration
158
            /** @var \TechDivision\Import\Configuration\PluginConfigurationInterface $plugin */
159
            foreach ($operation->getPlugins() as $plugin) {
160
                // pass the operation configuration instance to the plugin configuration
161
                $plugin->setConfiguration($configuration);
162
                $plugin->setOperationConfiguration($operation);
163
                // if NO prefix for the move files subject has been set, we use the prefix from the first plugin's subject
164
                if ($configuration->getMoveFilesPrefix() === null) {
165
                    // use the prefix of the first subject that needs an .OK file
166
                    /** @var \TechDivision\Import\Configuration\SubjectConfigurationInterface $subject */
167
                    foreach ($plugin->getSubjects() as $subject) {
168
                        // we use the subject with the first file resolver that has a custom
169
                        // prefix set to initialize the prefix for the move files subject for
170
                        if ($subject->getFileResolver()->hasPrefix()) {
171
                            $configuration->setMoveFilesPrefix($subject->getFileResolver()->getPrefix());
172
                            break;
173
                        }
174
                    }
175
                }
176
177
                // query whether or not the plugin has subjects configured
178
                if ($subjects = $plugin->getSubjects()) {
179
                    // extend the plugin's subjects with the main configuration instance
180
                    /** @var \TechDivision\Import\Configuration\SubjectConfigurationInterface $subject */
181
                    foreach ($subjects as $subject) {
182
                        // set the configuration instance on the subject
183
                        $subject->setConfiguration($configuration);
184
                    }
185
                }
186
187
                // finally append the plugin
188
                $plugins[] = $plugin;
189
            }
190
        }
191
192
        // query whether or not we've at least ONE plugin to be executed
193
        if (sizeof($plugins) > 0) {
194
            return $plugins;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $plugins; (array) is incompatible with the return type declared by the interface TechDivision\Import\Conf...erInterface::getPlugins of type Doctrine\Common\Collections\ArrayCollection.

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:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
195
        }
196
197
        // throw an exception if no plugins are available
198
        throw new \Exception(sprintf('Can\'t find any plugins for shortcut "%s"', $configuration->getShortcut()));
199
    }
200
201
    /**
202
     * Return's the operation with the given name.
203
     *
204
     * @param string $operationName The name of the operation to return
205
     *
206
     * @return \TechDivision\Import\Configuration\OperationConfigurationInterface The operation instance
207
     * @throws \Exception Is thrown if the operation with the given name is not available
208
     */
209
    protected function getOperation($operationName)
210
    {
211
212
        // explode the shortcut to get Magento Edition, Entity Type Code and Operation Name
213
        list($edition, $type, $name) = explode('/', $operationName);
214
215
        // load the operations from the configuration
216
        $operations = $this->getConfiguration()->getOperations();
217
218
        // query whether or not operations for the Magento edition + entity type code are available
219
        if (isset($operations[$edition][$type][$name])) {
220
            // load the operation
221
            $op = $operations[$edition][$type][$name];
222
            // pass the name to the operation configuration
223
            $op->setName($name);
224
            // initialize and pass the execution context to the operation configuration
225
            $op->setExecutionContext(new ExecutionContext($edition, $type));
226
            // finally add the operation to the array
227
            return $op;
228
        }
229
230
        // throw an exception if the operation is not available
231
        throw new \Exception(sprintf('Operation "%s" is not available in scope "%s/%s"', $name, $edition, $type));
232
    }
233
234
    /**
235
     * Return's the entity type mapping.
236
     *
237
     * @param string $entityType The entity type to map
238
     *
239
     * @return string The mapped entity type
240
     */
241
    protected function mapEntityType($entityType)
242
    {
243
244
        // map the entity type, if a mapping is available
245
        if (isset($this->entityTypeMapping[$entityType])) {
246
            return $this->entityTypeMapping[$entityType];
247
        }
248
249
        // return the entity type
250
        return $entityType;
251
    }
252
253
    /**
254
     * Return's the entity type to the configuration specific Magento edition.
255
     *
256
     * @param string $entityType The entity type to map
257
     *
258
     * @return string The mapped configuration specific Magento edition
259
     */
260
    protected function mapEntityTypeToMagentoEdition($entityType)
261
    {
262
263
        // load the actual Magento edition
264
        $magentoEdition = strtolower($this->getConfiguration()->getMagentoEdition());
265
266
        // map the entity type to the configuration specific Magento edition
267
        if (isset($this->entityTypeToEditionMapping[$entityType])) {
268
            $magentoEdition = $this->entityTypeToEditionMapping[$entityType];
269
        }
270
271
        // return the magento edition
272
        return $magentoEdition;
273
    }
274
}
275