Completed
Push — develop ( 21139f...eaa140 )
by Tom
12s
created

Application::add()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
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'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
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'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
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'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
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)
0 ignored issues
show
Coding Style introduced by
checkConfigCommandAlias uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
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