1 | <?php |
||
52 | abstract class AbstractImportCommand extends Command implements ImportCommandInterface |
||
53 | { |
||
54 | |||
55 | /** |
||
56 | * Configures the current command. |
||
57 | * |
||
58 | * @return void |
||
59 | * @see \Symfony\Component\Console\Command\Command::configure() |
||
60 | */ |
||
61 | protected function configure() |
||
62 | { |
||
63 | |||
64 | // initialize the command with the required/optional options |
||
65 | $this->addArgument( |
||
66 | InputArgumentKeys::OPERATION_NAME, |
||
67 | InputArgument::OPTIONAL, |
||
68 | 'The operation that has to be used for the import, one of "add-update", "replace" or "delete"', |
||
69 | $this->getDefaultOperation() |
||
70 | ) |
||
71 | ->addOption( |
||
72 | InputOptionKeys::CONFIGURATION, |
||
73 | null, |
||
74 | InputOption::VALUE_REQUIRED, |
||
75 | 'Specify the pathname to the configuration file to use', |
||
76 | $this->getDefaultConfiguration() |
||
77 | ) |
||
78 | ->addOption( |
||
79 | InputOptionKeys::INSTALLATION_DIR, |
||
80 | null, |
||
81 | InputOption::VALUE_OPTIONAL, |
||
82 | 'The Magento installation directory to which the files has to be imported', |
||
83 | $this->getMagentoInstallationDir() |
||
84 | ) |
||
85 | ->addOption( |
||
86 | InputOptionKeys::ENTITY_TYPE_CODE, |
||
87 | null, |
||
88 | InputOption::VALUE_REQUIRED, |
||
89 | 'Specify the entity type code to use' |
||
90 | ) |
||
91 | ->addOption( |
||
92 | InputOptionKeys::SOURCE_DIR, |
||
93 | null, |
||
94 | InputOption::VALUE_REQUIRED, |
||
95 | 'The directory that has to be watched for new files' |
||
96 | ) |
||
97 | ->addOption( |
||
98 | InputOptionKeys::TARGET_DIR, |
||
99 | null, |
||
100 | InputOption::VALUE_REQUIRED, |
||
101 | 'The target directory with the files that has been imported' |
||
102 | ) |
||
103 | ->addOption( |
||
104 | InputOptionKeys::UTILITY_CLASS_NAME, |
||
105 | null, |
||
106 | InputOption::VALUE_REQUIRED, |
||
107 | 'The utility class name with the SQL statements' |
||
108 | ) |
||
109 | ->addOption( |
||
110 | InputOptionKeys::PREFIX, |
||
111 | null, |
||
112 | InputOption::VALUE_REQUIRED, |
||
113 | 'The prefix of the CSV source file(s) that has/have to be imported' |
||
114 | ) |
||
115 | ->addOption( |
||
116 | InputOptionKeys::MAGENTO_EDITION, |
||
117 | null, |
||
118 | InputOption::VALUE_REQUIRED, |
||
119 | 'The Magento edition to be used, either one of CE or EE' |
||
120 | ) |
||
121 | ->addOption( |
||
122 | InputOptionKeys::MAGENTO_VERSION, |
||
123 | null, |
||
124 | InputOption::VALUE_REQUIRED, |
||
125 | 'The Magento version to be used, e. g. 2.1.2' |
||
126 | ) |
||
127 | ->addOption( |
||
128 | InputOptionKeys::SOURCE_DATE_FORMAT, |
||
129 | null, |
||
130 | InputOption::VALUE_REQUIRED, |
||
131 | 'The date format used in the CSV file(s)' |
||
132 | ) |
||
133 | ->addOption( |
||
134 | InputOptionKeys::USE_DB_ID, |
||
135 | null, |
||
136 | InputOption::VALUE_REQUIRED, |
||
137 | 'The explicit database ID used for the actual import process' |
||
138 | ) |
||
139 | ->addOption( |
||
140 | InputOptionKeys::DB_PDO_DSN, |
||
141 | null, |
||
142 | InputOption::VALUE_REQUIRED, |
||
143 | 'The DSN used to connect to the Magento database where the data has to be imported, e. g. mysql:host=127.0.0.1;dbname=magento;charset=utf8' |
||
144 | ) |
||
145 | ->addOption( |
||
146 | InputOptionKeys::DB_USERNAME, |
||
147 | null, |
||
148 | InputOption::VALUE_REQUIRED, |
||
149 | 'The username used to connect to the Magento database' |
||
150 | ) |
||
151 | ->addOption( |
||
152 | InputOptionKeys::DB_PASSWORD, |
||
153 | null, |
||
154 | InputOption::VALUE_REQUIRED, |
||
155 | 'The password used to connect to the Magento database' |
||
156 | ) |
||
157 | ->addOption( |
||
158 | InputOptionKeys::LOG_LEVEL, |
||
159 | null, |
||
160 | InputOption::VALUE_REQUIRED, |
||
161 | 'The log level to use' |
||
162 | ) |
||
163 | ->addOption( |
||
164 | InputOptionKeys::DEBUG_MODE, |
||
165 | null, |
||
166 | InputOption::VALUE_REQUIRED, |
||
167 | 'Whether use the debug mode or not' |
||
168 | ) |
||
169 | ->addOption( |
||
170 | InputOptionKeys::PID_FILENAME, |
||
171 | null, |
||
172 | InputOption::VALUE_REQUIRED, |
||
173 | 'The explicit PID filename to use', |
||
174 | sprintf('%s/%s', sys_get_temp_dir(), Configuration::PID_FILENAME) |
||
175 | ); |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * Executes the current command. |
||
180 | * |
||
181 | * This method is not abstract because you can use this class |
||
182 | * as a concrete class. In this case, instead of defining the |
||
183 | * execute() method, you set the code to execute by passing |
||
184 | * a Closure to the setCode() method. |
||
185 | * |
||
186 | * @param \Symfony\Component\Console\Input\InputInterface $input An InputInterface instance |
||
187 | * @param \Symfony\Component\Console\Output\OutputInterface $output An OutputInterface instance |
||
188 | * |
||
189 | * @return null|int null or 0 if everything went fine, or an error code |
||
190 | * @throws \LogicException When this abstract method is not implemented |
||
191 | * @see \Symfony\Component\Console\Command\Command::execute() |
||
192 | */ |
||
193 | protected function execute(InputInterface $input, OutputInterface $output) |
||
194 | { |
||
195 | |||
196 | // load the actual vendor directory |
||
197 | $vendorDirectory = $this->getVendorDir(); |
||
198 | |||
199 | // the path of the JMS serializer directory, relative to the vendor directory |
||
200 | $jmsDirectory = DIRECTORY_SEPARATOR . 'jms' . DIRECTORY_SEPARATOR . 'serializer' . DIRECTORY_SEPARATOR . 'src'; |
||
201 | |||
202 | // try to find the path to the JMS Serializer annotations |
||
203 | if (!file_exists($annotationDirectory = $vendorDirectory . DIRECTORY_SEPARATOR . $jmsDirectory)) { |
||
204 | // stop processing, if the JMS annotations can't be found |
||
205 | throw new \Exception( |
||
206 | sprintf( |
||
207 | 'The jms/serializer libarary can not be found in one of %s', |
||
208 | implode(', ', $this->getVendorDir()) |
||
209 | ) |
||
210 | ); |
||
211 | } |
||
212 | |||
213 | // register the autoloader for the JMS serializer annotations |
||
214 | \Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace( |
||
215 | 'JMS\Serializer\Annotation', |
||
216 | $annotationDirectory |
||
217 | ); |
||
218 | |||
219 | // load the importer configuration and set the entity type code |
||
220 | $configuration = ConfigurationFactory::load($input); |
||
221 | |||
222 | // initialize the DI container |
||
223 | $container = new ContainerBuilder(); |
||
224 | |||
225 | // initialize the default loader and load the DI configuration for the this library |
||
226 | $defaultLoader = new XmlFileLoader($container, new FileLocator($vendorDirectory)); |
||
227 | |||
228 | // load the DI configuration for all the extension libraries |
||
229 | foreach ($this->getExtensionLibraries($configuration) as $library) { |
||
230 | if (file_exists($diConfiguration = sprintf('%s/%s/symfony/Resources/config/services.xml', $vendorDirectory, $library))) { |
||
231 | $defaultLoader->load($diConfiguration); |
||
232 | } |
||
233 | } |
||
234 | |||
235 | // register autoloaders for additional vendor directories |
||
236 | $customLoader = new XmlFileLoader($container, new FileLocator()); |
||
237 | foreach ($configuration->getAdditionalVendorDirs() as $additionalVendorDir) { |
||
238 | // load the vendor directory's auto loader |
||
239 | if (file_exists($autoLoader = $additionalVendorDir->getVendorDir() . '/autoload.php')) { |
||
240 | require $autoLoader; |
||
241 | } |
||
242 | |||
243 | // load the DI configuration for the extension libraries |
||
244 | foreach ($additionalVendorDir->getLibraries() as $library) { |
||
245 | $customLoader->load(realpath(sprintf('%s/%s/symfony/Resources/config/services.xml', $additionalVendorDir->getVendorDir(), $library))); |
||
246 | } |
||
247 | } |
||
248 | |||
249 | // add the configuration as well as input/outut instances to the DI container |
||
250 | $container->set(SynteticServiceKeys::INPUT, $input); |
||
251 | $container->set(SynteticServiceKeys::OUTPUT, $output); |
||
252 | $container->set(SynteticServiceKeys::CONFIGURATION, $configuration); |
||
253 | $container->set(SynteticServiceKeys::APPLICATION, $this->getApplication()); |
||
|
|||
254 | |||
255 | // initialize the PDO connection |
||
256 | $dsn = $configuration->getDatabase()->getDsn(); |
||
257 | $username = $configuration->getDatabase()->getUsername(); |
||
258 | $password = $configuration->getDatabase()->getPassword(); |
||
259 | $connection = new \PDO($dsn, $username, $password); |
||
260 | $connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); |
||
261 | |||
262 | // add the PDO connection to the DI container |
||
263 | $container->set(SynteticServiceKeys::CONNECTION, $connection); |
||
264 | |||
265 | // initialize the system logger |
||
266 | $loggers = array(); |
||
267 | |||
268 | // initialize the default system logger |
||
269 | $systemLogger = new Logger('techdivision/import'); |
||
270 | $systemLogger->pushHandler( |
||
271 | new ErrorLogHandler( |
||
272 | ErrorLogHandler::OPERATING_SYSTEM, |
||
273 | $configuration->getLogLevel() |
||
274 | ) |
||
275 | ); |
||
276 | |||
277 | // add it to the array |
||
278 | $loggers[LoggerKeys::SYSTEM] = $systemLogger; |
||
279 | |||
280 | // append the configured loggers or override the default one |
||
281 | foreach ($configuration->getLoggers() as $loggerConfiguration) { |
||
282 | // load the factory class that creates the logger instance |
||
283 | $loggerFactory = $loggerConfiguration->getFactory(); |
||
284 | // create the logger instance and add it to the available loggers |
||
285 | $loggers[$loggerConfiguration->getName()] = $loggerFactory::factory($loggerConfiguration); |
||
286 | } |
||
287 | |||
288 | // add the system loggers to the DI container |
||
289 | $container->set(SynteticServiceKeys::LOGGERS, $loggers); |
||
290 | |||
291 | // start the import process |
||
292 | $container->get(SynteticServiceKeys::SIMPLE)->process(); |
||
293 | } |
||
294 | |||
295 | /** |
||
296 | * Return's the array with the magento specific extension libraries. |
||
297 | * |
||
298 | * @param \TechDivision\Import\ConfigurationInterface $configuration The configuration instance |
||
299 | * |
||
300 | * @return array The magento edition specific extension libraries |
||
301 | */ |
||
302 | public function getExtensionLibraries(ConfigurationInterface $configuration) |
||
303 | { |
||
304 | |||
305 | // return the array with the Magento Edition specific libraries |
||
306 | return array_merge( |
||
307 | Simple::getDefaultLibraries($configuration->getMagentoEdition()), |
||
308 | $configuration->getExtensionLibraries() |
||
309 | ); |
||
310 | } |
||
311 | |||
312 | /** |
||
313 | * Return's the absolute path to the actual vendor directory. |
||
314 | * |
||
315 | * @return string The absolute path to the actual vendor directory |
||
316 | * @throws \Exception Is thrown, if none of the possible vendor directories can be found |
||
317 | */ |
||
318 | public function getVendorDir() |
||
319 | { |
||
320 | |||
321 | // the possible paths to the vendor directory |
||
322 | $possibleVendorDirectories = array( |
||
323 | dirname(dirname(dirname(dirname(dirname(__DIR__))))) . DIRECTORY_SEPARATOR . 'vendor', |
||
324 | dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'vendor' |
||
325 | ); |
||
326 | |||
327 | // try to find the path to the JMS Serializer annotations |
||
328 | foreach ($possibleVendorDirectories as $possibleVendorDirectory) { |
||
329 | // return the directory as vendor directory if available |
||
330 | if (is_dir($possibleVendorDirectory)) { |
||
331 | return $possibleVendorDirectory; |
||
332 | } |
||
333 | } |
||
334 | |||
335 | // stop processing, if NO vendor directory is available |
||
336 | throw new \Exception( |
||
337 | sprintf( |
||
338 | 'None of the possible vendor directories %s is available', |
||
339 | implode(', ', $possibleVendorDirectories) |
||
340 | ) |
||
341 | ); |
||
342 | } |
||
343 | |||
344 | /** |
||
345 | * Return's the Magento installation directory, assuming that this is the |
||
346 | * actual directory. |
||
347 | * |
||
348 | * @return string The Magento installation directory |
||
349 | */ |
||
350 | public function getMagentoInstallationDir() |
||
354 | |||
355 | /** |
||
356 | * Return's the given entity type's specific default configuration file. |
||
357 | * |
||
358 | * @return string The name of the library to query for the default configuration file |
||
359 | * @throws \Exception Is thrown, if no default configuration for the passed entity type is available |
||
360 | */ |
||
361 | public function getDefaultImportDir() |
||
365 | |||
366 | /** |
||
367 | * Return's the given entity type's specific default configuration file. |
||
368 | * |
||
369 | * @return string The name of the library to query for the default configuration file |
||
370 | * @throws \Exception Is thrown, if no default configuration for the passed entity type is available |
||
371 | */ |
||
372 | public function getDefaultConfiguration() |
||
380 | |||
381 | /** |
||
382 | * Return's the default operation. |
||
383 | * |
||
384 | * @return string The default operation |
||
385 | */ |
||
386 | public function getDefaultOperation() |
||
390 | } |
||
391 |
Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code: