Completed
Push — develop ( 29460b...49af45 )
by Tom
04:59
created

Application::outputMagerunCompatibilityNotice()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 35
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 35
rs 8.8571
cc 2
eloc 16
nc 2
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\Config;
10
use N98\Magento\Application\ConfigurationLoader;
11
use N98\Magento\Application\Console\Events;
12
use N98\Util\AutoloadRestorer;
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\OutputInterface;
28
use Symfony\Component\EventDispatcher\EventDispatcher;
29
use UnexpectedValueException;
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 Config
70
     */
71
    protected $config;
72
73
    /**
74
     * @see \N98\Magento\Application::setConfigurationLoader()
75
     * @var ConfigurationLoader
76
     */
77
    private $configurationLoaderInjected;
78
79
    /**
80
     * @var string
81
     */
82
    protected $_magentoRootFolder = null;
83
84
    /**
85
     * @var bool
86
     */
87
    protected $_magentoEnterprise = false;
88
89
    /**
90
     * @var int
91
     */
92
    protected $_magentoMajorVersion = self::MAGENTO_MAJOR_VERSION_1;
93
94
    /**
95
     * @var EntryPoint
96
     */
97
    protected $_magento2EntryPoint = null;
98
99
    /**
100
     * @var bool
101
     */
102
    protected $_isPharMode = false;
103
104
    /**
105
     * @var bool
106
     */
107
    protected $_magerunStopFileFound = false;
108
109
    /**
110
     * @var string
111
     */
112
    protected $_magerunStopFileFolder = null;
113
114
    /**
115
     * @var bool
116
     */
117
    protected $_isInitialized = false;
118
119
    /**
120
     * @var EventDispatcher
121
     */
122
    protected $dispatcher;
123
124
    /**
125
     * If root dir is set by root-dir option this flag is true
126
     *
127
     * @var bool
128
     */
129
    protected $_directRootDir = false;
130
131
    /**
132
     * @var bool
133
     */
134
    protected $_magentoDetected = false;
135
136
    /**
137
     * @param ClassLoader $autoloader
0 ignored issues
show
Documentation introduced by
Should the type for parameter $autoloader not be ClassLoader|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
138
     */
139
    public function __construct($autoloader = null)
140
    {
141
        $this->autoloader = $autoloader;
142
        parent::__construct(self::APP_NAME, self::APP_VERSION);
143
    }
144
145
    /**
146
     * @return InputDefinition
147
     */
148
    protected function getDefaultInputDefinition()
149
    {
150
        $inputDefinition = parent::getDefaultInputDefinition();
151
152
        /**
153
         * Root dir
154
         */
155
        $rootDirOption = new InputOption(
156
            '--root-dir',
157
            '',
158
            InputOption::VALUE_OPTIONAL,
159
            'Force magento root dir. No auto detection'
160
        );
161
        $inputDefinition->addOption($rootDirOption);
162
163
        /**
164
         * Skip config
165
         */
166
        $skipExternalConfig = new InputOption(
167
            '--skip-config',
168
            '',
169
            InputOption::VALUE_NONE,
170
            'Do not load any custom config.'
171
        );
172
        $inputDefinition->addOption($skipExternalConfig);
173
174
        /**
175
         * Skip root check
176
         */
177
        $skipExternalConfig = new InputOption(
178
            '--skip-root-check',
179
            '',
180
            InputOption::VALUE_NONE,
181
            'Do not check if n98-magerun runs as root'
182
        );
183
        $inputDefinition->addOption($skipExternalConfig);
184
185
        return $inputDefinition;
186
    }
187
188
    /**
189
     * Search for magento root folder
190
     *
191
     * @param InputInterface $input [optional]
0 ignored issues
show
Documentation introduced by
Should the type for parameter $input not be null|InputInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
192
     * @param OutputInterface $output [optional]
0 ignored issues
show
Documentation introduced by
Should the type for parameter $output not be null|OutputInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
193
     * @return void
194
     */
195
    public function detectMagento(InputInterface $input = null, OutputInterface $output = null)
196
    {
197
        // do not detect magento twice
198
        if ($this->_magentoDetected) {
199
            return;
200
        }
201
202
        if (null === $input) {
203
            $input = new ArgvInput();
204
        }
205
206
        if (null === $output) {
207
            $output = new ConsoleOutput();
208
        }
209
210
        if ($this->getMagentoRootFolder() === null) {
211
            $this->_checkRootDirOption($input);
212
            $folder = OperatingSystem::getCwd();
213
        } else {
214
            $folder = $this->getMagentoRootFolder();
215
        }
216
217
        $this->getHelperSet()->set(new MagentoHelper($input, $output), 'magento');
218
        $magentoHelper = $this->getHelperSet()->get('magento');
219
        /* @var $magentoHelper MagentoHelper */
220
        if (!$this->_directRootDir) {
221
            $subFolders = $this->config->getDetectSubFolders();
222
        } else {
223
            $subFolders = array();
224
        }
225
226
        $this->_magentoDetected = $magentoHelper->detect($folder, $subFolders);
227
        $this->_magentoRootFolder = $magentoHelper->getRootFolder();
228
        $this->_magentoEnterprise = $magentoHelper->isEnterpriseEdition();
229
        $this->_magentoMajorVersion = $magentoHelper->getMajorVersion();
230
        $this->_magerunStopFileFound = $magentoHelper->isMagerunStopFileFound();
231
        $this->_magerunStopFileFolder = $magentoHelper->getMagerunStopFileFolder();
232
    }
233
234
    /**
235
     * Add own helpers to helperset.
236
     *
237
     * @return void
238
     */
239
    protected function registerHelpers()
240
    {
241
        $helperSet = $this->getHelperSet();
242
        $config = $this->config->getConfig();
243
244
        // Twig
245
        $twigBaseDirs = array(
246
            __DIR__ . '/../../../res/twig',
247
        );
248
        if (isset($config['twig']['baseDirs']) && is_array($config['twig']['baseDirs'])) {
249
            $twigBaseDirs = array_merge(array_reverse($config['twig']['baseDirs']), $twigBaseDirs);
250
        }
251
        $helperSet->set(new TwigHelper($twigBaseDirs), 'twig');
252
253
        foreach ($config['helpers'] as $helperName => $helperClass) {
254
            if (class_exists($helperClass)) {
255
                $helperSet->set(new $helperClass(), $helperName);
256
            }
257
        }
258
    }
259
260
    /**
261
     * @param InputInterface $input
262
     *
263
     * @return ArgvInput|InputInterface
264
     */
265
    protected function checkConfigCommandAlias(InputInterface $input)
266
    {
267
        trigger_error(__METHOD__ . ' moved, use getConfig()->checkConfigCommandAlias()', E_USER_DEPRECATED);
268
269
        return $this->config->checkConfigCommandAlias($input);
270
    }
271
272
    /**
273
     * @param Command $command
274
     */
275
    protected function registerConfigCommandAlias(Command $command)
276
    {
277
        trigger_error(__METHOD__ . ' moved, use getConfig()->registerConfigCommandAlias() instead', E_USER_DEPRECATED);
278
279
        return $this->config->registerConfigCommandAlias($command);
280
    }
281
282
    /**
283
     * Adds autoloader prefixes from user's config
284
     */
285
    protected function registerCustomAutoloaders()
286
    {
287
        trigger_error(__METHOD__ . ' moved, use getConfig()->registerCustomAutoloaders() instead', E_USER_DEPRECATED);
288
289
        $this->config->registerCustomAutoloaders($this->autoloader);
290
    }
291
292
    /**
293
     * @return bool
294
     */
295
    protected function hasCustomCommands()
296
    {
297
        trigger_error(__METHOD__ . ' moved, use config directly instead', E_USER_DEPRECATED);
298
299
        $config = $this->config->getConfig();
300
        return isset($config['commands']['customCommands']) && is_array($config['commands']['customCommands']);
301
    }
302
303
    /**
304
     * @return void
305
     */
306
    protected function registerCustomCommands()
307
    {
308
        trigger_error(__METHOD__ . ' moved, use getConfig()->registerCustomCommands() instead', E_USER_DEPRECATED);
309
310
        $this->config->registerCustomCommands($this);
311
    }
312
313
    /**
314
     * @param string $class
315
     * @return bool
316
     */
317
    protected function isCommandDisabled($class)
318
    {
319
        trigger_error(__METHOD__ . ' moved, use config directly instead', E_USER_DEPRECATED);
320
321
        $config = $this->config->getConfig();
322
        return in_array($class, $config['commands']['disabled']);
323
    }
324
325
    /**
326
     * Override standard command registration. We want alias support.
327
     *
328
     * @param Command $command
329
     *
330
     * @return Command
0 ignored issues
show
Documentation introduced by
Should the return type not be Command|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
331
     */
332
    public function add(Command $command)
333
    {
334
        if ($this->config) {
335
            $this->config->registerConfigCommandAlias($command);
336
        }
337
338
        return parent::add($command);
339
    }
340
341
    /**
342
     * @param bool $mode
343
     */
344
    public function setPharMode($mode)
345
    {
346
        $this->_isPharMode = $mode;
347
    }
348
349
    /**
350
     * @return bool
351
     */
352
    public function isPharMode()
353
    {
354
        return $this->_isPharMode;
355
    }
356
357
    /**
358
     * @TODO Move logic into "EventSubscriber"
359
     *
360
     * @param OutputInterface $output
361
     * @return null|false
362
     */
363
    public function checkVarDir(OutputInterface $output)
364
    {
365
        $tempVarDir = sys_get_temp_dir() . '/magento/var';
366
        if (!OutputInterface::VERBOSITY_NORMAL <= $output->getVerbosity() && !is_dir($tempVarDir)) {
367
            return;
368
        }
369
370
        $this->detectMagento(null, $output);
371
        /* If magento is not installed yet, don't check */
372
        if ($this->_magentoRootFolder === null
373
            || !file_exists($this->_magentoRootFolder . '/app/etc/local.xml')
374
        ) {
375
            return;
376
        }
377
378
        try {
379
            $this->initMagento();
380
        } catch (Exception $e) {
381
            $message = 'Cannot initialize Magento. Please check your configuration. '
382
                . 'Some n98-magerun command will not work. Got message: ';
383
            if (OutputInterface::VERBOSITY_VERY_VERBOSE <= $output->getVerbosity()) {
384
                $message .= $e->getTraceAsString();
385
            } else {
386
                $message .= $e->getMessage();
387
            }
388
            $output->writeln($message);
389
390
            return;
391
        }
392
393
        $configOptions = new \Mage_Core_Model_Config_Options();
394
        $currentVarDir = $configOptions->getVarDir();
395
396
        if ($currentVarDir == $tempVarDir) {
397
            $output->writeln(array(
398
                sprintf('<warning>Fallback folder %s is used in n98-magerun</warning>', $tempVarDir),
399
                '',
400
                'n98-magerun is using the fallback folder. If there is another folder configured for Magento, this ' .
401
                'can cause serious problems.',
402
                'Please refer to https://github.com/netz98/n98-magerun/wiki/File-system-permissions ' .
403
                'for more information.',
404
                '',
405
            ));
406
        } else {
407
            $output->writeln(array(
408
                sprintf('<warning>Folder %s found, but not used in n98-magerun</warning>', $tempVarDir),
409
                '',
410
                "This might cause serious problems. n98-magerun is using the configured var-folder " .
411
                "<comment>$currentVarDir</comment>",
412
                'Please refer to https://github.com/netz98/n98-magerun/wiki/File-system-permissions ' .
413
                'for more information.',
414
                '',
415
            ));
416
417
            return false;
418
        }
419
    }
420
421
    /**
422
     * Loads and initializes the Magento application
423
     *
424
     * @param bool $soft
425
     *
426
     * @return bool false if magento root folder is not set, true otherwise
427
     */
428
    public function initMagento($soft = false)
429
    {
430
        if ($this->getMagentoRootFolder() === null) {
431
            return false;
432
        }
433
434
        $isMagento2 = $this->_magentoMajorVersion === self::MAGENTO_MAJOR_VERSION_2;
435
        if ($isMagento2) {
436
            $this->_initMagento2();
437
        } else {
438
            $this->_initMagento1($soft);
439
        }
440
441
        return true;
442
    }
443
444
    /**
445
     * @return string
446
     */
447
    public function getHelp()
448
    {
449
        return self::$logo . parent::getHelp();
450
    }
451
452
    public function getLongVersion()
453
    {
454
        return parent::getLongVersion() . ' by <info>netz98 new media GmbH</info>';
455
    }
456
457
    /**
458
     * @return boolean
459
     */
460
    public function isMagentoEnterprise()
461
    {
462
        return $this->_magentoEnterprise;
463
    }
464
465
    /**
466
     * @return string
467
     */
468
    public function getMagentoRootFolder()
469
    {
470
        return $this->_magentoRootFolder;
471
    }
472
473
    /**
474
     * @param string $magentoRootFolder
475
     */
476
    public function setMagentoRootFolder($magentoRootFolder)
477
    {
478
        $this->_magentoRootFolder = $magentoRootFolder;
479
    }
480
481
    /**
482
     * @return int
483
     */
484
    public function getMagentoMajorVersion()
485
    {
486
        return $this->_magentoMajorVersion;
487
    }
488
489
    /**
490
     * @return ClassLoader
491
     */
492
    public function getAutoloader()
493
    {
494
        return $this->autoloader;
495
    }
496
497
    /**
498
     * @param ClassLoader $autoloader
499
     */
500
    public function setAutoloader(ClassLoader $autoloader)
501
    {
502
        $this->autoloader = $autoloader;
503
    }
504
505
    /**
506
     * @return array
507
     */
508
    public function getConfig()
509
    {
510
        return $this->config->getConfig();
511
    }
512
513
    /**
514
     * @param array $config
515
     */
516
    public function setConfig($config)
517
    {
518
        $this->config->setConfig($config);
519
    }
520
521
    /**
522
     * @return boolean
523
     */
524
    public function isMagerunStopFileFound()
525
    {
526
        return $this->_magerunStopFileFound;
527
    }
528
529
    /**
530
     * Runs the current application with possible command aliases
531
     *
532
     * @param InputInterface $input An Input instance
533
     * @param OutputInterface $output An Output instance
534
     *
535
     * @return integer 0 if everything went fine, or an error code
536
     */
537
    public function doRun(InputInterface $input, OutputInterface $output)
538
    {
539
        $event = new Application\Console\Event($this, $input, $output);
540
        $this->dispatcher->dispatch(Events::RUN_BEFORE, $event);
541
542
        /**
543
         * only for compatibility to old versions.
544
         */
545
        $event = new ConsoleEvent(new Command('dummy'), $input, $output);
546
        $this->dispatcher->dispatch('console.run.before', $event);
547
548
        $input = $this->config->checkConfigCommandAlias($input);
549
        if ($output instanceof ConsoleOutput) {
550
            $this->checkVarDir($output->getErrorOutput());
551
        }
552
553
        return parent::doRun($input, $output);
554
    }
555
556
    /**
557
     * @param InputInterface $input [optional]
0 ignored issues
show
Documentation introduced by
Should the type for parameter $input not be null|InputInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
558
     * @param OutputInterface $output [optional]
0 ignored issues
show
Documentation introduced by
Should the type for parameter $output not be null|OutputInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
559
     *
560
     * @return int
561
     */
562
    public function run(InputInterface $input = null, OutputInterface $output = null)
563
    {
564
        if (null === $input) {
565
            $input = new ArgvInput();
566
        }
567
568
        if (null === $output) {
569
            $output = new ConsoleOutput();
570
        }
571
        $this->_addOutputStyles($output);
572
        if ($output instanceof ConsoleOutput) {
573
            $this->_addOutputStyles($output->getErrorOutput());
574
        }
575
576
        $this->configureIO($input, $output);
577
578
        try {
579
            $this->init(array(), $input, $output);
580
        } catch (Exception $e) {
581
            $output = new ConsoleOutput();
582
            $this->renderException($e, $output->getErrorOutput());
583
        }
584
585
        $return = parent::run($input, $output);
586
587
        // Fix for no return values -> used in interactive shell to prevent error output
588
        if ($return === null) {
589
            return 0;
590
        }
591
592
        return $return;
593
    }
594
595
    /**
596
     * @param array $initConfig [optional]
597
     * @param InputInterface $input [optional]
0 ignored issues
show
Documentation introduced by
Should the type for parameter $input not be null|InputInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
598
     * @param OutputInterface $output [optional]
0 ignored issues
show
Documentation introduced by
Should the type for parameter $output not be null|OutputInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
599
     *
600
     * @return void
601
     */
602
    public function init(array $initConfig = array(), InputInterface $input = null, OutputInterface $output = null)
603
    {
604
        if ($this->_isInitialized) {
605
            return;
606
        }
607
608
        // Suppress DateTime warnings
609
        date_default_timezone_set(@date_default_timezone_get());
610
611
        // Initialize EventDispatcher early
612
        $this->dispatcher = new EventDispatcher();
613
        $this->setDispatcher($this->dispatcher);
614
615
        if (null === $input) {
616
            $input = new ArgvInput();
617
        }
618
619
        if (null === $output) {
620
            $output = new ConsoleOutput();
621
        }
622
623
        if (null !== $this->config) {
624
            throw new UnexpectedValueException(sprintf('Config already initialized'));
625
        }
626
627
        $loadExternalConfig = !$this->_checkSkipConfigOption($input);
628
629
        $this->config = $config = new Config($initConfig, $this->isPharMode(), $output);
630
        if ($this->configurationLoaderInjected) {
631
            $config->setLoader($this->configurationLoaderInjected);
632
        }
633
        $config->loadPartialConfig($loadExternalConfig);
634
        $this->detectMagento($input, $output);
635
        $configLoader = $config->getLoader();
636
        $configLoader->loadStageTwo($this->_magentoRootFolder, $loadExternalConfig, $this->_magerunStopFileFolder);
637
        $config->load();
638
639
        if ($autoloader = $this->autoloader) {
640
            $config->registerCustomAutoloaders($autoloader);
641
            $this->registerEventSubscribers();
642
            $config->registerCustomCommands($this);
643
        }
644
645
        $this->registerHelpers();
646
647
        $this->_isInitialized = true;
648
    }
649
650
    /**
651
     * @param array $initConfig [optional]
652
     * @param InputInterface $input [optional]
0 ignored issues
show
Documentation introduced by
Should the type for parameter $input not be null|InputInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
653
     * @param OutputInterface $output [optional]
0 ignored issues
show
Documentation introduced by
Should the type for parameter $output not be null|OutputInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
654
     */
655
    public function reinit($initConfig = array(), InputInterface $input = null, OutputInterface $output = null)
656
    {
657
        $this->_isInitialized = false;
658
        $this->_magentoDetected = false;
659
        $this->_magentoRootFolder = null;
660
        $this->config = null;
661
        $this->init($initConfig, $input, $output);
662
    }
663
664
    /**
665
     * @return void
666
     */
667
    protected function registerEventSubscribers()
668
    {
669
        $config = $this->config->getConfig();
670
        $subscriberClasses = $config['event']['subscriber'];
671
        foreach ($subscriberClasses as $subscriberClass) {
672
            $subscriber = new $subscriberClass();
673
            $this->dispatcher->addSubscriber($subscriber);
674
        }
675
    }
676
677
    /**
678
     * @param InputInterface $input
679
     * @return bool
680
     */
681
    protected function _checkSkipConfigOption(InputInterface $input)
682
    {
683
        return $input->hasParameterOption('--skip-config');
684
    }
685
686
    /**
687
     * @param InputInterface $input
688
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
689
     */
690
    protected function _checkRootDirOption(InputInterface $input)
691
    {
692
        $rootDir = $input->getParameterOption('--root-dir');
693
        if (is_string($rootDir)) {
694
            $this->setRootDir($rootDir);
695
        }
696
    }
697
698
    /**
699
     * Set root dir (chdir()) of magento directory
700
     *
701
     * @param string $path to Magento directory
702
     */
703
    private function setRootDir($path)
704
    {
705
        if (isset($path[0]) && '~' === $path[0]) {
706
            $path = OperatingSystem::getHomeDir() . substr($path, 1);
707
        }
708
709
        $folder = realpath($path);
710
        $this->_directRootDir = true;
711
        if (is_dir($folder)) {
712
            chdir($folder);
713
        }
714
    }
715
716
    /**
717
     * use require-once inside a function with it's own variable scope w/o any other variables
718
     * and $this unbound.
719
     *
720
     * @param string $path
721
     */
722
    private function requireOnce($path)
723
    {
724
        $requireOnce = function () {
725
            require_once func_get_arg(0);
726
        };
727
        if (50400 <= PHP_VERSION_ID) {
728
            $requireOnce->bindTo(null);
729
        }
730
731
        $requireOnce($path);
732
    }
733
734
    /**
735
     * @param bool $soft
736
     *
737
     * @return void
738
     */
739
    protected function _initMagento1($soft = false)
740
    {
741
        if (!class_exists('Mage', false)) {
742
            // Create a new AutoloadRestorer to capture currenjt auto-öpaders
743
            $restorer = new AutoloadRestorer();
744
            // require app/Mage.php from Magento in a function of it's own to have it's own variable scope
745
            $this->requireOnce($this->_magentoRootFolder . '/app/Mage.php');
746
            // Restore auto-loaders that might be removed by extensions that overwrite Varien/Autoload
747
            $restorer->restore();
748
        }
749
750
        // skip Mage::app init routine and return
751
        if ($soft === true) {
752
            return;
753
        }
754
755
        $config = $this->config->getConfig();
756
        $initSettings = $config['init'];
757
758
        Mage::app($initSettings['code'], $initSettings['type'], $initSettings['options']);
759
    }
760
761
    /**
762
     * @return void
763
     */
764
    protected function _initMagento2()
765
    {
766
        $this->outputMagerunCompatibilityNotice('2');
767
    }
768
769
    /**
770
     * Show a hint that this is Magento incompatible with Magerun and how to obtain the correct Magerun for it
771
     *
772
     * @param string $version of Magento, "1" or "2", that is incompatible
773
     */
774
    private function outputMagerunCompatibilityNotice($version)
775
    {
776
        $file = $version === '2' ? $version : '';
777
        $magentoHint = <<<MAGENTOHINT
778
You are running a Magento $version.x instance. This version of n98-magerun is not compatible
779
with Magento $version.x. Please use n98-magerun$version (version $version) for this shop.
780
781
A current version of the software can be downloaded on github.
782
783
<info>Download with curl
784
------------------</info>
785
786
    <comment>curl -O https://files.magerun.net/n98-magerun$file.phar</comment>
787
788
<info>Download with wget
789
------------------</info>
790
791
    <comment>wget https://files.magerun.net/n98-magerun$file.phar</comment>
792
793
MAGENTOHINT;
794
795
        $output = new ConsoleOutput();
796
797
        /** @var $formatter FormatterHelper */
798
        $formatter = $this->getHelperSet()->get('formatter');
799
800
        $output->writeln(array(
801
            '',
802
            $formatter->formatBlock('Compatibility Notice', 'bg=blue;fg=white', true),
803
            '',
804
            $magentoHint,
805
        ));
806
807
        throw new RuntimeException('This version of n98-magerun is not compatible with Magento ' . $version);
808
    }
809
810
    /**
811
     * @return EventDispatcher
812
     */
813
    public function getDispatcher()
814
    {
815
        return $this->dispatcher;
816
    }
817
818
    /**
819
     * @param array $initConfig
820
     * @param OutputInterface $output
821
     * @return ConfigurationLoader
822
     */
823
    public function getConfigurationLoader(array $initConfig, OutputInterface $output)
824
    {
825
        trigger_error(__METHOD__ . ' moved, use getConfig()->getLoader()', E_USER_DEPRECATED);
826
827
        unset($initConfig, $output);
828
829
        $loader = $this->config ? $this->config->getLoader() : $this->configurationLoaderInjected;
830
831
        if (!$loader) {
832
            throw new RuntimeException('ConfigurationLoader is not yet available, initialize it or Config first');
833
        }
834
835
        return $loader;
836
    }
837
838
    /**
839
     * @param ConfigurationLoader $configurationLoader
840
     *
841
     * @return $this
842
     */
843
    public function setConfigurationLoader(ConfigurationLoader $configurationLoader)
844
    {
845
        if ($this->config) {
846
            $this->config->setLoader($configurationLoader);
847
        } else {
848
            /* inject loader to be used later when config is created in */
849
            /* @see N98\Magento\Application::init */
850
            $this->configurationLoaderInjected = $configurationLoader;
851
        }
852
853
        return $this;
854
    }
855
856
    /**
857
     * @param OutputInterface $output
858
     */
859
    protected function _addOutputStyles(OutputInterface $output)
860
    {
861
        $output->getFormatter()->setStyle('debug', new OutputFormatterStyle('magenta', 'white'));
862
        $output->getFormatter()->setStyle('warning', new OutputFormatterStyle('red', 'yellow', array('bold')));
863
    }
864
}
865