1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace N98\Magento; |
4
|
|
|
|
5
|
|
|
use Composer\Autoload\ClassLoader; |
6
|
|
|
use Exception; |
7
|
|
|
use Mage; |
8
|
|
|
use Magento\Mtf\EntryPoint\EntryPoint; |
9
|
|
|
use N98\Magento\Application\ConfigurationLoader; |
10
|
|
|
use N98\Util\ArrayFunctions; |
11
|
|
|
use N98\Util\AutoloadRestorer; |
12
|
|
|
use N98\Util\BinaryString; |
13
|
|
|
use N98\Util\Console\Helper\MagentoHelper; |
14
|
|
|
use N98\Util\Console\Helper\TwigHelper; |
15
|
|
|
use N98\Util\OperatingSystem; |
16
|
|
|
use RuntimeException; |
17
|
|
|
use Symfony\Component\Console\Application as BaseApplication; |
18
|
|
|
use Symfony\Component\Console\Command\Command; |
19
|
|
|
use Symfony\Component\Console\Event\ConsoleEvent; |
20
|
|
|
use Symfony\Component\Console\Formatter\OutputFormatterStyle; |
21
|
|
|
use Symfony\Component\Console\Helper\FormatterHelper; |
22
|
|
|
use Symfony\Component\Console\Input\ArgvInput; |
23
|
|
|
use Symfony\Component\Console\Input\InputDefinition; |
24
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
25
|
|
|
use Symfony\Component\Console\Input\InputOption; |
26
|
|
|
use Symfony\Component\Console\Output\ConsoleOutput; |
27
|
|
|
use Symfony\Component\Console\Output\NullOutput; |
28
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
29
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcher; |
30
|
|
|
|
31
|
|
|
class Application extends BaseApplication |
32
|
|
|
{ |
33
|
|
|
/** |
34
|
|
|
* @var string |
35
|
|
|
*/ |
36
|
|
|
const APP_NAME = 'n98-magerun'; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @var string |
40
|
|
|
*/ |
41
|
|
|
const APP_VERSION = '1.97.23'; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* @var int |
45
|
|
|
*/ |
46
|
|
|
const MAGENTO_MAJOR_VERSION_1 = 1; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @var int |
50
|
|
|
*/ |
51
|
|
|
const MAGENTO_MAJOR_VERSION_2 = 2; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* @var string |
55
|
|
|
*/ |
56
|
|
|
private static $logo = " |
57
|
|
|
___ ___ |
58
|
|
|
_ _/ _ ( _ )___ _ __ __ _ __ _ ___ _ _ _ _ _ _ |
59
|
|
|
| ' \\_, / _ \\___| ' \\/ _` / _` / -_) '_| || | ' \\ |
60
|
|
|
|_||_/_/\\___/ |_|_|_\\__,_\\__, \\___|_| \\_,_|_||_| |
61
|
|
|
|___/ |
62
|
|
|
"; |
63
|
|
|
/** |
64
|
|
|
* @var ClassLoader |
65
|
|
|
*/ |
66
|
|
|
protected $autoloader; |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* @var array |
70
|
|
|
*/ |
71
|
|
|
protected $config = array(); |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* @var ConfigurationLoader |
75
|
|
|
*/ |
76
|
|
|
protected $configurationLoader = null; |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* @var array |
80
|
|
|
*/ |
81
|
|
|
protected $partialConfig = array(); |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* @var string |
85
|
|
|
*/ |
86
|
|
|
protected $_magentoRootFolder = null; |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* @var bool |
90
|
|
|
*/ |
91
|
|
|
protected $_magentoEnterprise = false; |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* @var int |
95
|
|
|
*/ |
96
|
|
|
protected $_magentoMajorVersion = self::MAGENTO_MAJOR_VERSION_1; |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* @var EntryPoint |
100
|
|
|
*/ |
101
|
|
|
protected $_magento2EntryPoint = null; |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* @var bool |
105
|
|
|
*/ |
106
|
|
|
protected $_isPharMode = false; |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* @var bool |
110
|
|
|
*/ |
111
|
|
|
protected $_magerunStopFileFound = false; |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* @var string |
115
|
|
|
*/ |
116
|
|
|
protected $_magerunStopFileFolder = null; |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @var bool |
120
|
|
|
*/ |
121
|
|
|
protected $_isInitialized = false; |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* @var EventDispatcher |
125
|
|
|
*/ |
126
|
|
|
protected $dispatcher; |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* If root dir is set by root-dir option this flag is true |
130
|
|
|
* |
131
|
|
|
* @var bool |
132
|
|
|
*/ |
133
|
|
|
protected $_directRootDir = false; |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* @var bool |
137
|
|
|
*/ |
138
|
|
|
protected $_magentoDetected = false; |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* @param ClassLoader $autoloader |
142
|
|
|
*/ |
143
|
|
|
public function __construct($autoloader = null) |
144
|
|
|
{ |
145
|
|
|
$this->autoloader = $autoloader; |
146
|
|
|
parent::__construct(self::APP_NAME, self::APP_VERSION); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* @return InputDefinition |
151
|
|
|
*/ |
152
|
|
|
protected function getDefaultInputDefinition() |
153
|
|
|
{ |
154
|
|
|
$inputDefinition = parent::getDefaultInputDefinition(); |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* Root dir |
158
|
|
|
*/ |
159
|
|
|
$rootDirOption = new InputOption( |
160
|
|
|
'--root-dir', |
161
|
|
|
'', |
162
|
|
|
InputOption::VALUE_OPTIONAL, |
163
|
|
|
'Force magento root dir. No auto detection' |
164
|
|
|
); |
165
|
|
|
$inputDefinition->addOption($rootDirOption); |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* Skip config |
169
|
|
|
*/ |
170
|
|
|
$skipExternalConfig = new InputOption( |
171
|
|
|
'--skip-config', |
172
|
|
|
'', |
173
|
|
|
InputOption::VALUE_NONE, |
174
|
|
|
'Do not load any custom config.' |
175
|
|
|
); |
176
|
|
|
$inputDefinition->addOption($skipExternalConfig); |
177
|
|
|
|
178
|
|
|
/** |
179
|
|
|
* Skip root check |
180
|
|
|
*/ |
181
|
|
|
$skipExternalConfig = new InputOption( |
182
|
|
|
'--skip-root-check', |
183
|
|
|
'', |
184
|
|
|
InputOption::VALUE_NONE, |
185
|
|
|
'Do not check if n98-magerun runs as root' |
186
|
|
|
); |
187
|
|
|
$inputDefinition->addOption($skipExternalConfig); |
188
|
|
|
|
189
|
|
|
return $inputDefinition; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Get names of sub-folders to be scanned during Magento detection |
194
|
|
|
* |
195
|
|
|
* @return array |
196
|
|
|
*/ |
197
|
|
|
public function getDetectSubFolders() |
198
|
|
|
{ |
199
|
|
|
if (isset($this->partialConfig['detect']) && isset($this->partialConfig['detect']['subFolders'])) { |
200
|
|
|
return $this->partialConfig['detect']['subFolders']; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
return array(); |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
/** |
207
|
|
|
* Search for magento root folder |
208
|
|
|
* |
209
|
|
|
* @param InputInterface $input [optional] |
210
|
|
|
* @param OutputInterface $output [optional] |
211
|
|
|
* @return void |
212
|
|
|
*/ |
213
|
|
|
public function detectMagento(InputInterface $input = null, OutputInterface $output = null) |
214
|
|
|
{ |
215
|
|
|
// do not detect magento twice |
216
|
|
|
if ($this->_magentoDetected) { |
217
|
|
|
return; |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
if (null === $input) { |
221
|
|
|
$input = new ArgvInput(); |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
if (null === $output) { |
225
|
|
|
$output = new ConsoleOutput(); |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
if ($this->getMagentoRootFolder() === null) { |
229
|
|
|
$this->_checkRootDirOption($input); |
230
|
|
|
$folder = OperatingSystem::getCwd(); |
231
|
|
|
} else { |
232
|
|
|
$folder = $this->getMagentoRootFolder(); |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
$this->getHelperSet()->set(new MagentoHelper($input, $output), 'magento'); |
236
|
|
|
$magentoHelper = $this->getHelperSet()->get('magento'); |
237
|
|
|
/* @var $magentoHelper MagentoHelper */ |
238
|
|
|
if (!$this->_directRootDir) { |
239
|
|
|
$subFolders = $this->getDetectSubFolders(); |
240
|
|
|
} else { |
241
|
|
|
$subFolders = array(); |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
$this->_magentoDetected = $magentoHelper->detect($folder, $subFolders); |
245
|
|
|
$this->_magentoRootFolder = $magentoHelper->getRootFolder(); |
246
|
|
|
$this->_magentoEnterprise = $magentoHelper->isEnterpriseEdition(); |
247
|
|
|
$this->_magentoMajorVersion = $magentoHelper->getMajorVersion(); |
248
|
|
|
$this->_magerunStopFileFound = $magentoHelper->isMagerunStopFileFound(); |
249
|
|
|
$this->_magerunStopFileFolder = $magentoHelper->getMagerunStopFileFolder(); |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* Add own helpers to helperset. |
254
|
|
|
* |
255
|
|
|
* @return void |
256
|
|
|
*/ |
257
|
|
|
protected function registerHelpers() |
258
|
|
|
{ |
259
|
|
|
$helperSet = $this->getHelperSet(); |
260
|
|
|
|
261
|
|
|
// Twig |
262
|
|
|
$twigBaseDirs = array( |
263
|
|
|
__DIR__ . '/../../../res/twig', |
264
|
|
|
); |
265
|
|
|
if (isset($this->config['twig']['baseDirs']) && is_array($this->config['twig']['baseDirs'])) { |
266
|
|
|
$twigBaseDirs = array_merge(array_reverse($this->config['twig']['baseDirs']), $twigBaseDirs); |
267
|
|
|
} |
268
|
|
|
$helperSet->set(new TwigHelper($twigBaseDirs), 'twig'); |
269
|
|
|
|
270
|
|
|
foreach ($this->config['helpers'] as $helperName => $helperClass) { |
271
|
|
|
if (class_exists($helperClass)) { |
272
|
|
|
$helperSet->set(new $helperClass(), $helperName); |
273
|
|
|
} |
274
|
|
|
} |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Adds autoloader prefixes from user's config |
279
|
|
|
*/ |
280
|
|
|
protected function registerCustomAutoloaders() |
281
|
|
|
{ |
282
|
|
View Code Duplication |
if (isset($this->config['autoloaders']) && is_array($this->config['autoloaders'])) { |
|
|
|
|
283
|
|
|
foreach ($this->config['autoloaders'] as $prefix => $path) { |
284
|
|
|
$this->autoloader->add($prefix, $path); |
285
|
|
|
} |
286
|
|
|
} |
287
|
|
|
|
288
|
|
View Code Duplication |
if (isset($this->config['autoloaders_psr4']) && is_array($this->config['autoloaders_psr4'])) { |
|
|
|
|
289
|
|
|
foreach ($this->config['autoloaders_psr4'] as $prefix => $path) { |
290
|
|
|
$this->autoloader->addPsr4($prefix, $path); |
291
|
|
|
} |
292
|
|
|
} |
293
|
|
|
|
294
|
|
View Code Duplication |
if (isset($this->config['autoload_files']) && is_array($this->config['autoload_files'])) { |
|
|
|
|
295
|
|
|
foreach ($this->config['autoload_files'] as $file) { |
296
|
|
|
require $file; |
297
|
|
|
} |
298
|
|
|
} |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
/** |
302
|
|
|
* @return bool |
303
|
|
|
*/ |
304
|
|
|
protected function hasCustomCommands() |
305
|
|
|
{ |
306
|
|
|
return isset($this->config['commands']['customCommands']) |
307
|
|
|
&& is_array($this->config['commands']['customCommands']); |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* @return void |
312
|
|
|
*/ |
313
|
|
|
protected function registerCustomCommands() |
314
|
|
|
{ |
315
|
|
|
if (!$this->hasCustomCommands()) { |
316
|
|
|
return; |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
foreach ($this->config['commands']['customCommands'] as $commandClass) { |
320
|
|
|
if (is_array($commandClass)) { // Support for key => value (name -> class) |
321
|
|
|
$resolvedCommandClass = current($commandClass); |
322
|
|
|
if ($this->isCommandDisabled($resolvedCommandClass)) { |
323
|
|
|
continue; |
324
|
|
|
} |
325
|
|
|
$command = new $resolvedCommandClass(); |
326
|
|
|
$command->setName(key($commandClass)); |
327
|
|
|
} elseif ($this->isCommandDisabled($commandClass)) { |
328
|
|
|
continue; |
329
|
|
|
} else { |
330
|
|
|
$command = new $commandClass(); |
331
|
|
|
} |
332
|
|
|
$this->add($command); |
333
|
|
|
} |
334
|
|
|
} |
335
|
|
|
|
336
|
|
|
/** |
337
|
|
|
* @param string $class |
338
|
|
|
* @return bool |
339
|
|
|
*/ |
340
|
|
|
protected function isCommandDisabled($class) |
341
|
|
|
{ |
342
|
|
|
return in_array($class, $this->config['commands']['disabled']); |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
/** |
346
|
|
|
* Override standard command registration. We want alias support. |
347
|
|
|
* |
348
|
|
|
* @param Command $command |
349
|
|
|
* |
350
|
|
|
* @return Command |
351
|
|
|
*/ |
352
|
|
|
public function add(Command $command) |
353
|
|
|
{ |
354
|
|
|
$this->registerConfigCommandAlias($command); |
355
|
|
|
|
356
|
|
|
return parent::add($command); |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* @param Command $command |
361
|
|
|
*/ |
362
|
|
|
protected function registerConfigCommandAlias(Command $command) |
363
|
|
|
{ |
364
|
|
|
if ($this->hasConfigCommandAliases()) { |
365
|
|
|
foreach ($this->config['commands']['aliases'] as $alias) { |
366
|
|
|
if (!is_array($alias)) { |
367
|
|
|
continue; |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
$aliasCommandName = key($alias); |
371
|
|
|
$commandString = $alias[$aliasCommandName]; |
372
|
|
|
|
373
|
|
|
list($originalCommand) = explode(' ', $commandString); |
374
|
|
|
if ($command->getName() == $originalCommand) { |
375
|
|
|
$currentCommandAliases = $command->getAliases(); |
376
|
|
|
$currentCommandAliases[] = $aliasCommandName; |
377
|
|
|
$command->setAliases($currentCommandAliases); |
378
|
|
|
} |
379
|
|
|
} |
380
|
|
|
} |
381
|
|
|
} |
382
|
|
|
|
383
|
|
|
/** |
384
|
|
|
* @return bool |
385
|
|
|
*/ |
386
|
|
|
private function hasConfigCommandAliases() |
387
|
|
|
{ |
388
|
|
|
return isset($this->config['commands']['aliases']) && is_array($this->config['commands']['aliases']); |
389
|
|
|
} |
390
|
|
|
|
391
|
|
|
/** |
392
|
|
|
* @param bool $mode |
393
|
|
|
*/ |
394
|
|
|
public function setPharMode($mode) |
395
|
|
|
{ |
396
|
|
|
$this->_isPharMode = $mode; |
397
|
|
|
} |
398
|
|
|
|
399
|
|
|
/** |
400
|
|
|
* @return bool |
401
|
|
|
*/ |
402
|
|
|
public function isPharMode() |
403
|
|
|
{ |
404
|
|
|
return $this->_isPharMode; |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
/** |
408
|
|
|
* @TODO Move logic into "EventSubscriber" |
409
|
|
|
* |
410
|
|
|
* @param OutputInterface $output |
411
|
|
|
* @return null|false |
412
|
|
|
*/ |
413
|
|
|
public function checkVarDir(OutputInterface $output) |
414
|
|
|
{ |
415
|
|
|
$tempVarDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'magento' . DIRECTORY_SEPARATOR . 'var'; |
416
|
|
|
if (!OutputInterface::VERBOSITY_NORMAL <= $output->getVerbosity() && !is_dir($tempVarDir)) { |
417
|
|
|
return; |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
$this->detectMagento(null, $output); |
421
|
|
|
/* If magento is not installed yet, don't check */ |
422
|
|
|
if ($this->_magentoRootFolder === null |
423
|
|
|
|| !file_exists($this->_magentoRootFolder . '/app/etc/local.xml') |
424
|
|
|
) { |
425
|
|
|
return; |
426
|
|
|
} |
427
|
|
|
|
428
|
|
|
try { |
429
|
|
|
$this->initMagento(); |
430
|
|
|
} catch (Exception $e) { |
431
|
|
|
$message = 'Cannot initialize Magento. Please check your configuration. ' |
432
|
|
|
. 'Some n98-magerun command will not work. Got message: '; |
433
|
|
|
if (OutputInterface::VERBOSITY_VERY_VERBOSE <= $output->getVerbosity()) { |
434
|
|
|
$message .= $e->getTraceAsString(); |
435
|
|
|
} else { |
436
|
|
|
$message .= $e->getMessage(); |
437
|
|
|
} |
438
|
|
|
$output->writeln($message); |
439
|
|
|
|
440
|
|
|
return; |
441
|
|
|
} |
442
|
|
|
|
443
|
|
|
$configOptions = new \Mage_Core_Model_Config_Options(); |
444
|
|
|
$currentVarDir = $configOptions->getVarDir(); |
445
|
|
|
|
446
|
|
|
if ($currentVarDir == $tempVarDir) { |
447
|
|
|
$output->writeln(array( |
448
|
|
|
sprintf('<warning>Fallback folder %s is used in n98-magerun</warning>', $tempVarDir), |
449
|
|
|
'', |
450
|
|
|
'n98-magerun is using the fallback folder. If there is another folder configured for Magento, this ' . |
451
|
|
|
'can cause serious problems.', |
452
|
|
|
'Please refer to https://github.com/netz98/n98-magerun/wiki/File-system-permissions ' . |
453
|
|
|
'for more information.', |
454
|
|
|
'', |
455
|
|
|
)); |
456
|
|
|
} else { |
457
|
|
|
$output->writeln(array( |
458
|
|
|
sprintf('<warning>Folder %s found, but not used in n98-magerun</warning>', $tempVarDir), |
459
|
|
|
'', |
460
|
|
|
"This might cause serious problems. n98-magerun is using the configured var-folder " . |
461
|
|
|
"<comment>$currentVarDir</comment>", |
462
|
|
|
'Please refer to https://github.com/netz98/n98-magerun/wiki/File-system-permissions ' . |
463
|
|
|
'for more information.', |
464
|
|
|
'', |
465
|
|
|
)); |
466
|
|
|
|
467
|
|
|
return false; |
468
|
|
|
} |
469
|
|
|
} |
470
|
|
|
|
471
|
|
|
/** |
472
|
|
|
* Loads and initializes the Magento application |
473
|
|
|
* |
474
|
|
|
* @param bool $soft |
475
|
|
|
* |
476
|
|
|
* @return bool false if magento root folder is not set, true otherwise |
477
|
|
|
*/ |
478
|
|
|
public function initMagento($soft = false) |
479
|
|
|
{ |
480
|
|
|
if ($this->getMagentoRootFolder() === null) { |
481
|
|
|
return false; |
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
$isMagento2 = $this->_magentoMajorVersion === self::MAGENTO_MAJOR_VERSION_2; |
485
|
|
|
if ($isMagento2) { |
486
|
|
|
$this->_initMagento2(); |
487
|
|
|
} else { |
488
|
|
|
$this->_initMagento1($soft); |
489
|
|
|
} |
490
|
|
|
|
491
|
|
|
return true; |
492
|
|
|
} |
493
|
|
|
|
494
|
|
|
/** |
495
|
|
|
* @return string |
496
|
|
|
*/ |
497
|
|
|
public function getHelp() |
498
|
|
|
{ |
499
|
|
|
return self::$logo . parent::getHelp(); |
500
|
|
|
} |
501
|
|
|
|
502
|
|
|
public function getLongVersion() |
503
|
|
|
{ |
504
|
|
|
return parent::getLongVersion() . ' by <info>netz98 new media GmbH</info>'; |
505
|
|
|
} |
506
|
|
|
|
507
|
|
|
/** |
508
|
|
|
* @return boolean |
509
|
|
|
*/ |
510
|
|
|
public function isMagentoEnterprise() |
511
|
|
|
{ |
512
|
|
|
return $this->_magentoEnterprise; |
513
|
|
|
} |
514
|
|
|
|
515
|
|
|
/** |
516
|
|
|
* @return string |
517
|
|
|
*/ |
518
|
|
|
public function getMagentoRootFolder() |
519
|
|
|
{ |
520
|
|
|
return $this->_magentoRootFolder; |
521
|
|
|
} |
522
|
|
|
|
523
|
|
|
/** |
524
|
|
|
* @param string $magentoRootFolder |
525
|
|
|
*/ |
526
|
|
|
public function setMagentoRootFolder($magentoRootFolder) |
527
|
|
|
{ |
528
|
|
|
$this->_magentoRootFolder = $magentoRootFolder; |
529
|
|
|
} |
530
|
|
|
|
531
|
|
|
/** |
532
|
|
|
* @return int |
533
|
|
|
*/ |
534
|
|
|
public function getMagentoMajorVersion() |
535
|
|
|
{ |
536
|
|
|
return $this->_magentoMajorVersion; |
537
|
|
|
} |
538
|
|
|
|
539
|
|
|
/** |
540
|
|
|
* @return ClassLoader |
541
|
|
|
*/ |
542
|
|
|
public function getAutoloader() |
543
|
|
|
{ |
544
|
|
|
return $this->autoloader; |
545
|
|
|
} |
546
|
|
|
|
547
|
|
|
/** |
548
|
|
|
* @param ClassLoader $autoloader |
549
|
|
|
*/ |
550
|
|
|
public function setAutoloader($autoloader) |
551
|
|
|
{ |
552
|
|
|
$this->autoloader = $autoloader; |
553
|
|
|
} |
554
|
|
|
|
555
|
|
|
/** |
556
|
|
|
* @return array |
557
|
|
|
*/ |
558
|
|
|
public function getConfig() |
559
|
|
|
{ |
560
|
|
|
return $this->config; |
561
|
|
|
} |
562
|
|
|
|
563
|
|
|
/** |
564
|
|
|
* @param array $config |
565
|
|
|
*/ |
566
|
|
|
public function setConfig($config) |
567
|
|
|
{ |
568
|
|
|
$this->config = $config; |
569
|
|
|
} |
570
|
|
|
|
571
|
|
|
/** |
572
|
|
|
* @return boolean |
573
|
|
|
*/ |
574
|
|
|
public function isMagerunStopFileFound() |
575
|
|
|
{ |
576
|
|
|
return $this->_magerunStopFileFound; |
577
|
|
|
} |
578
|
|
|
|
579
|
|
|
/** |
580
|
|
|
* Runs the current application with possible command aliases |
581
|
|
|
* |
582
|
|
|
* @param InputInterface $input An Input instance |
583
|
|
|
* @param OutputInterface $output An Output instance |
584
|
|
|
* |
585
|
|
|
* @return integer 0 if everything went fine, or an error code |
586
|
|
|
*/ |
587
|
|
|
public function doRun(InputInterface $input, OutputInterface $output) |
588
|
|
|
{ |
589
|
|
|
$event = new Application\Console\Event($this, $input, $output); |
590
|
|
|
$this->dispatcher->dispatch('n98-magerun.application.console.run.before', $event); |
591
|
|
|
|
592
|
|
|
/** |
593
|
|
|
* only for compatibility to old versions. |
594
|
|
|
*/ |
595
|
|
|
$event = new ConsoleEvent(new Command('dummy'), $input, $output); |
596
|
|
|
$this->dispatcher->dispatch('console.run.before', $event); |
597
|
|
|
|
598
|
|
|
$input = $this->checkConfigCommandAlias($input); |
599
|
|
|
if ($output instanceof ConsoleOutput) { |
600
|
|
|
$this->checkVarDir($output->getErrorOutput()); |
601
|
|
|
} |
602
|
|
|
|
603
|
|
|
return parent::doRun($input, $output); |
604
|
|
|
} |
605
|
|
|
|
606
|
|
|
/** |
607
|
|
|
* @param InputInterface $input |
608
|
|
|
* |
609
|
|
|
* @return ArgvInput|InputInterface |
610
|
|
|
*/ |
611
|
|
|
protected function checkConfigCommandAlias(InputInterface $input) |
|
|
|
|
612
|
|
|
{ |
613
|
|
|
if ($this->hasConfigCommandAliases()) { |
614
|
|
|
foreach ($this->config['commands']['aliases'] as $alias) { |
615
|
|
|
if (is_array($alias)) { |
616
|
|
|
$aliasCommandName = key($alias); |
617
|
|
|
if ($input->getFirstArgument() == $aliasCommandName) { |
618
|
|
|
$aliasCommandParams = array_slice( |
619
|
|
|
BinaryString::trimExplodeEmpty(' ', $alias[$aliasCommandName]), |
620
|
|
|
1 |
621
|
|
|
); |
622
|
|
|
if (count($aliasCommandParams) > 0) { |
623
|
|
|
// replace with aliased data |
624
|
|
|
$mergedParams = array_merge( |
625
|
|
|
array_slice($_SERVER['argv'], 0, 2), |
626
|
|
|
$aliasCommandParams, |
627
|
|
|
array_slice($_SERVER['argv'], 2) |
628
|
|
|
); |
629
|
|
|
$input = new ArgvInput($mergedParams); |
630
|
|
|
} |
631
|
|
|
} |
632
|
|
|
} |
633
|
|
|
} |
634
|
|
|
|
635
|
|
|
return $input; |
636
|
|
|
} |
637
|
|
|
|
638
|
|
|
return $input; |
639
|
|
|
} |
640
|
|
|
|
641
|
|
|
/** |
642
|
|
|
* @param InputInterface $input |
643
|
|
|
* @param OutputInterface $output |
644
|
|
|
* @return int |
645
|
|
|
*/ |
646
|
|
|
public function run(InputInterface $input = null, OutputInterface $output = null) |
647
|
|
|
{ |
648
|
|
|
if (null === $input) { |
649
|
|
|
$input = new ArgvInput(); |
650
|
|
|
} |
651
|
|
|
|
652
|
|
|
if (null === $output) { |
653
|
|
|
$output = new ConsoleOutput(); |
654
|
|
|
} |
655
|
|
|
$this->_addOutputStyles($output); |
656
|
|
|
if ($output instanceof ConsoleOutput) { |
657
|
|
|
$this->_addOutputStyles($output->getErrorOutput()); |
658
|
|
|
} |
659
|
|
|
|
660
|
|
|
$this->configureIO($input, $output); |
661
|
|
|
|
662
|
|
|
try { |
663
|
|
|
$this->init(array(), $input, $output); |
664
|
|
|
} catch (Exception $e) { |
665
|
|
|
$output = new ConsoleOutput(); |
666
|
|
|
$this->renderException($e, $output->getErrorOutput()); |
667
|
|
|
} |
668
|
|
|
|
669
|
|
|
$return = parent::run($input, $output); |
670
|
|
|
|
671
|
|
|
// Fix for no return values -> used in interactive shell to prevent error output |
672
|
|
|
if ($return === null) { |
673
|
|
|
return 0; |
674
|
|
|
} |
675
|
|
|
|
676
|
|
|
return $return; |
677
|
|
|
} |
678
|
|
|
|
679
|
|
|
/** |
680
|
|
|
* @param array $initConfig |
681
|
|
|
* @param InputInterface $input |
682
|
|
|
* @param OutputInterface $output |
683
|
|
|
* |
684
|
|
|
* @return void |
685
|
|
|
*/ |
686
|
|
|
public function init(array $initConfig = array(), InputInterface $input = null, OutputInterface $output = null) |
687
|
|
|
{ |
688
|
|
|
if ($this->_isInitialized) { |
689
|
|
|
return; |
690
|
|
|
} |
691
|
|
|
|
692
|
|
|
// Suppress DateTime warnings |
693
|
|
|
date_default_timezone_set(@date_default_timezone_get()); |
694
|
|
|
|
695
|
|
|
// Initialize EventDispatcher early |
696
|
|
|
$this->dispatcher = new EventDispatcher(); |
697
|
|
|
$this->setDispatcher($this->dispatcher); |
698
|
|
|
|
699
|
|
|
if (null === $input) { |
700
|
|
|
$input = new ArgvInput(); |
701
|
|
|
} |
702
|
|
|
|
703
|
|
|
if (null === $output) { |
704
|
|
|
$output = new NullOutput(); |
705
|
|
|
} |
706
|
|
|
|
707
|
|
|
// initialize config |
708
|
|
|
$configLoader = $this->getConfigurationLoader($initConfig, $output); |
709
|
|
|
$loadExternalConfig = !$this->_checkSkipConfigOption($input); |
710
|
|
|
$this->partialConfig = $configLoader->getPartialConfig($loadExternalConfig); |
711
|
|
|
$this->detectMagento($input, $output); |
712
|
|
|
$configLoader->loadStageTwo($this->_magentoRootFolder, $loadExternalConfig, $this->_magerunStopFileFolder); |
713
|
|
|
|
714
|
|
|
$this->config = $configLoader->toArray(); |
715
|
|
|
|
716
|
|
|
if ($this->autoloader) { |
717
|
|
|
$this->registerCustomAutoloaders(); |
718
|
|
|
$this->registerEventSubscribers(); |
719
|
|
|
$this->registerCustomCommands(); |
720
|
|
|
} |
721
|
|
|
|
722
|
|
|
$this->registerHelpers(); |
723
|
|
|
|
724
|
|
|
$this->_isInitialized = true; |
725
|
|
|
} |
726
|
|
|
|
727
|
|
|
/** |
728
|
|
|
* @param array $initConfig |
729
|
|
|
* @param InputInterface $input |
730
|
|
|
* @param OutputInterface $output |
731
|
|
|
*/ |
732
|
|
|
public function reinit($initConfig = array(), InputInterface $input = null, OutputInterface $output = null) |
733
|
|
|
{ |
734
|
|
|
$this->_isInitialized = false; |
735
|
|
|
$this->_magentoDetected = false; |
736
|
|
|
$this->_magentoRootFolder = null; |
737
|
|
|
$this->init($initConfig, $input, $output); |
738
|
|
|
} |
739
|
|
|
|
740
|
|
|
/** |
741
|
|
|
* @return void |
742
|
|
|
*/ |
743
|
|
|
protected function registerEventSubscribers() |
744
|
|
|
{ |
745
|
|
|
foreach ($this->config['event']['subscriber'] as $subscriberClass) { |
746
|
|
|
$subscriber = new $subscriberClass(); |
747
|
|
|
$this->dispatcher->addSubscriber($subscriber); |
748
|
|
|
} |
749
|
|
|
} |
750
|
|
|
|
751
|
|
|
/** |
752
|
|
|
* @param InputInterface $input |
753
|
|
|
* @return bool |
754
|
|
|
*/ |
755
|
|
|
protected function _checkSkipConfigOption(InputInterface $input) |
756
|
|
|
{ |
757
|
|
|
return $input->hasParameterOption('--skip-config'); |
758
|
|
|
} |
759
|
|
|
|
760
|
|
|
/** |
761
|
|
|
* @param InputInterface $input |
762
|
|
|
* @return string |
763
|
|
|
*/ |
764
|
|
|
protected function _checkRootDirOption(InputInterface $input) |
765
|
|
|
{ |
766
|
|
|
$definedRootDir = $input->getParameterOption('--root-dir'); |
767
|
|
|
|
768
|
|
|
if (!empty($definedRootDir)) { |
769
|
|
|
if ($definedRootDir[0] == '~') { |
770
|
|
|
$definedRootDir = OperatingSystem::getHomeDir() . substr($definedRootDir, 1); |
771
|
|
|
} |
772
|
|
|
|
773
|
|
|
$folder = realpath($definedRootDir); |
774
|
|
|
$this->_directRootDir = true; |
775
|
|
|
if (is_dir($folder)) { |
776
|
|
|
\chdir($folder); |
777
|
|
|
|
778
|
|
|
return; |
779
|
|
|
} |
780
|
|
|
} |
781
|
|
|
} |
782
|
|
|
|
783
|
|
|
/** |
784
|
|
|
* @param bool $soft |
785
|
|
|
* @return void |
786
|
|
|
*/ |
787
|
|
|
protected function _initMagento1($soft = false) |
788
|
|
|
{ |
789
|
|
|
if (!class_exists('Mage', false)) { |
790
|
|
|
// Create a new AutoloadRestorer to capture currenjt auto-öpaders |
791
|
|
|
$restorer = new AutoloadRestorer(); |
792
|
|
|
// require app/Mage.php from Magento in a function of it's own to have it's own variable scope |
793
|
|
|
$this->requireOnce($this->_magentoRootFolder . '/app/Mage.php'); |
794
|
|
|
// Restore auto-loaders that might be removed by extensions that overwrite Varien/Autoload |
795
|
|
|
$restorer->restore(); |
796
|
|
|
} |
797
|
|
|
|
798
|
|
|
// skip Mage::app init routine and return |
799
|
|
|
if ($soft === true) { |
800
|
|
|
return; |
801
|
|
|
} |
802
|
|
|
|
803
|
|
|
$initSettings = $this->config['init']; |
804
|
|
|
|
805
|
|
|
Mage::app($initSettings['code'], $initSettings['type'], $initSettings['options']); |
806
|
|
|
} |
807
|
|
|
|
808
|
|
|
/** |
809
|
|
|
* use require-once inside a function with it's own variable scope w/o any other variables |
810
|
|
|
* and $this unbound. |
811
|
|
|
* |
812
|
|
|
* @param string $path |
813
|
|
|
*/ |
814
|
|
|
private function requireOnce($path) |
815
|
|
|
{ |
816
|
|
|
$requireOnce = function () { |
817
|
|
|
require_once func_get_arg(0); |
818
|
|
|
}; |
819
|
|
|
if (50400 <= PHP_VERSION_ID) { |
820
|
|
|
$requireOnce->bindTo(null); |
821
|
|
|
} |
822
|
|
|
|
823
|
|
|
$requireOnce($path); |
824
|
|
|
} |
825
|
|
|
|
826
|
|
|
/** |
827
|
|
|
* show compatibility notice about Magento 2 |
828
|
|
|
*/ |
829
|
|
|
protected function _initMagento2() |
830
|
|
|
{ |
831
|
|
|
$magento2Hint = <<<'MAGENTO2HINT' |
832
|
|
|
You are running a Magento 2 instance. This version of n98-magerun is not compatible |
833
|
|
|
with Magento 2. Please use n98-magerun2 for this shop. |
834
|
|
|
|
835
|
|
|
A current version of the software can be downloaded on github. |
836
|
|
|
|
837
|
|
|
<info>Download with curl |
838
|
|
|
------------------</info> |
839
|
|
|
|
840
|
|
|
<comment>curl -sS https://files.magerun.net/n98-magerun2.phar -O</comment> |
841
|
|
|
|
842
|
|
|
<info>Download with wget |
843
|
|
|
------------------</info> |
844
|
|
|
|
845
|
|
|
<comment>wget https://files.magerun.net/n98-magerun2.phar</comment> |
846
|
|
|
|
847
|
|
|
MAGENTO2HINT; |
848
|
|
|
|
849
|
|
|
$output = new ConsoleOutput(); |
850
|
|
|
|
851
|
|
|
/** @var $formatter FormatterHelper */ |
852
|
|
|
$formatter = $this->getHelperSet()->get('formatter'); |
853
|
|
|
|
854
|
|
|
$output->writeln(array( |
855
|
|
|
'', |
856
|
|
|
$formatter->formatBlock('Compatibility Notice', 'bg=blue;fg=white', true), |
857
|
|
|
'', |
858
|
|
|
)); |
859
|
|
|
|
860
|
|
|
$output->writeln($magento2Hint); |
861
|
|
|
|
862
|
|
|
throw new RuntimeException('This version of n98-magerun is not compatible with Magento 2'); |
863
|
|
|
} |
864
|
|
|
|
865
|
|
|
/** |
866
|
|
|
* @return EventDispatcher |
867
|
|
|
*/ |
868
|
|
|
public function getDispatcher() |
869
|
|
|
{ |
870
|
|
|
return $this->dispatcher; |
871
|
|
|
} |
872
|
|
|
|
873
|
|
|
/** |
874
|
|
|
* @param array $initConfig |
875
|
|
|
* @param OutputInterface $output |
876
|
|
|
* @return ConfigurationLoader |
877
|
|
|
*/ |
878
|
|
|
public function getConfigurationLoader(array $initConfig, OutputInterface $output) |
879
|
|
|
{ |
880
|
|
|
if ($this->configurationLoader === null) { |
881
|
|
|
$this->configurationLoader = new ConfigurationLoader( |
882
|
|
|
ArrayFunctions::mergeArrays($this->config, $initConfig), |
883
|
|
|
$this->isPharMode(), |
884
|
|
|
$output |
885
|
|
|
); |
886
|
|
|
} |
887
|
|
|
|
888
|
|
|
return $this->configurationLoader; |
889
|
|
|
} |
890
|
|
|
|
891
|
|
|
/** |
892
|
|
|
* @param ConfigurationLoader $configurationLoader |
893
|
|
|
* |
894
|
|
|
* @return $this |
895
|
|
|
*/ |
896
|
|
|
public function setConfigurationLoader($configurationLoader) |
897
|
|
|
{ |
898
|
|
|
$this->configurationLoader = $configurationLoader; |
899
|
|
|
|
900
|
|
|
return $this; |
901
|
|
|
} |
902
|
|
|
|
903
|
|
|
/** |
904
|
|
|
* @param OutputInterface $output |
905
|
|
|
*/ |
906
|
|
|
protected function _addOutputStyles(OutputInterface $output) |
907
|
|
|
{ |
908
|
|
|
$output->getFormatter()->setStyle('debug', new OutputFormatterStyle('magenta', 'white')); |
909
|
|
|
$output->getFormatter()->setStyle('warning', new OutputFormatterStyle('red', 'yellow', array('bold'))); |
910
|
|
|
} |
911
|
|
|
} |
912
|
|
|
|
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.