Completed
Push — develop ( a2b494...664288 )
by Tom
12:01
created

Application::run()   C

Complexity

Conditions 7
Paths 32

Size

Total Lines 37
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 37
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 22
nc 32
nop 2
1
<?php
2
3
namespace N98\Magento;
4
5
use Composer\Autoload\ClassLoader;
6
use Exception;
7
use Magento\Framework\ObjectManager\ObjectManager;
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\Console\Helper\MagentoHelper;
13
use N98\Util\Console\Helper\TwigHelper;
14
use N98\Util\OperatingSystem;
15
use RuntimeException;
16
use Symfony\Component\Console\Application as BaseApplication;
17
use Symfony\Component\Console\Command\Command;
18
use Symfony\Component\Console\Event\ConsoleEvent;
19
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
20
use Symfony\Component\Console\Helper\FormatterHelper;
21
use Symfony\Component\Console\Input\ArgvInput;
22
use Symfony\Component\Console\Input\InputDefinition;
23
use Symfony\Component\Console\Input\InputInterface;
24
use Symfony\Component\Console\Input\InputOption;
25
use Symfony\Component\Console\Output\ConsoleOutput;
26
use Symfony\Component\Console\Output\OutputInterface;
27
use Symfony\Component\EventDispatcher\EventDispatcher;
28
use UnexpectedValueException;
29
30
class Application extends BaseApplication
31
{
32
    /**
33
     * @var string
34
     */
35
    const APP_NAME = 'n98-magerun2';
36
37
    /**
38
     * @var string
39
     */
40
    const APP_VERSION = '1.3.0';
41
42
    /**
43
     * @var int
44
     */
45
    const MAGENTO_MAJOR_VERSION_1 = 1;
46
47
    /**
48
     * @var int
49
     */
50
    const MAGENTO_MAJOR_VERSION_2 = 2;
51
52
    /**
53
     * @var string
54
     */
55
    private static $logo = "
56
     ___ ___                                       ___
57
 _ _/ _ ( _ )___ _ __  __ _ __ _ ___ _ _ _  _ _ _ |_  )
58
| ' \\_, / _ \\___| '  \\/ _` / _` / -_) '_| || | ' \\ / /
59
|_||_/_/\\___/   |_|_|_\\__,_\\__, \\___|_|  \\_,_|_||_/___|
60
                           |___/
61
";
62
    /**
63
     * @var ClassLoader
64
     */
65
    protected $autoloader;
66
67
    /**
68
     * @var Config
69
     */
70
    protected $config;
71
72
    /**
73
     * @see \N98\Magento\Application::setConfigurationLoader()
74
     * @var ConfigurationLoader
75
     */
76
    private $configurationLoaderInjected;
77
78
    /**
79
     * @var string
80
     */
81
    protected $_magentoRootFolder = null;
82
83
    /**
84
     * @var bool
85
     */
86
    protected $_magentoEnterprise = false;
87
88
    /**
89
     * @var int
90
     */
91
    protected $_magentoMajorVersion = self::MAGENTO_MAJOR_VERSION_2;
92
93
    /**
94
     * @var EntryPoint
95
     */
96
    protected $_magento2EntryPoint = null;
97
98
    /**
99
     * @var bool
100
     */
101
    protected $_isPharMode = false;
102
103
    /**
104
     * @var bool
105
     */
106
    protected $_magerunStopFileFound = false;
107
108
    /**
109
     * @var string
110
     */
111
    protected $_magerunStopFileFolder = null;
112
113
    /**
114
     * @var bool
115
     */
116
    protected $_isInitialized = false;
117
118
    /**
119
     * @var EventDispatcher
120
     */
121
    protected $dispatcher;
122
123
    /**
124
     * If root dir is set by root-dir option this flag is true
125
     *
126
     * @var bool
127
     */
128
    protected $_directRootDir = false;
129
130
    /**
131
     * @var bool
132
     */
133
    protected $_magentoDetected = false;
134
135
    /**
136
     * @var ObjectManager
137
     */
138
    protected $_objectManager = null;
139
140
    /**
141
     * @var boolean
142
     */
143
    private $autoExit = true;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
144
145
    /**
146
     * @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...
147
     */
148
    public function __construct($autoloader = null)
149
    {
150
        $this->autoloader = $autoloader;
151
        parent::__construct(self::APP_NAME, self::APP_VERSION);
152
    }
153
154
    /**
155
     * @return InputDefinition
156
     */
157
    protected function getDefaultInputDefinition()
158
    {
159
        $inputDefinition = parent::getDefaultInputDefinition();
160
161
        /**
162
         * Root dir
163
         */
164
        $rootDirOption = new InputOption(
165
            '--root-dir',
166
            '',
167
            InputOption::VALUE_OPTIONAL,
168
            'Force magento root dir. No auto detection'
169
        );
170
        $inputDefinition->addOption($rootDirOption);
171
172
        /**
173
         * Skip config
174
         */
175
        $skipExternalConfig = new InputOption(
176
            '--skip-config',
177
            '',
178
            InputOption::VALUE_NONE,
179
            'Do not load any custom config.'
180
        );
181
        $inputDefinition->addOption($skipExternalConfig);
182
183
        /**
184
         * Skip root check
185
         */
186
        $skipExternalConfig = new InputOption(
187
            '--skip-root-check',
188
            '',
189
            InputOption::VALUE_NONE,
190
            'Do not check if n98-magerun runs as root'
191
        );
192
        $inputDefinition->addOption($skipExternalConfig);
193
194
        /**
195
         * Skip core commands
196
         */
197
        $skipMagento2CoreCommands = new InputOption(
198
            '--skip-core-commands',
199
            '',
200
            InputOption::VALUE_OPTIONAL,
201
            'Do not include Magento 2 core commands'
202
        );
203
        $inputDefinition->addOption($skipMagento2CoreCommands);
204
205
        return $inputDefinition;
206
    }
207
208
    /**
209
     * Sets whether to automatically exit after a command execution or not.
210
     *
211
     * Implemented on this level to allow early exit on configuration exceptions
212
     * @see run()
213
     *
214
     * @param bool $boolean Whether to automatically exit after a command execution or not
215
     */
216
    public function setAutoExit($boolean)
217
    {
218
        $this->autoExit = (bool) $boolean;
219
        parent::setAutoExit($boolean);
220
    }
221
222
    /**
223
     * Search for magento root folder
224
     *
225
     * @param InputInterface $input [optional]
226
     * @param OutputInterface $output [optional]
227
     * @return void
228
     */
229
    public function detectMagento(InputInterface $input = null, OutputInterface $output = null)
230
    {
231
        // do not detect magento twice
232
        if ($this->_magentoDetected) {
233
            return;
234
        }
235
236
        if (null === $input) {
237
            $input = new ArgvInput();
238
        }
239
240
        if (null === $output) {
241
            $output = new ConsoleOutput();
242
        }
243
244
        if ($this->getMagentoRootFolder() === null) {
245
            $this->_checkRootDirOption($input);
246
            $folder = OperatingSystem::getCwd();
247
        } else {
248
            $folder = $this->getMagentoRootFolder();
249
        }
250
251
        $this->getHelperSet()->set(new MagentoHelper($input, $output), 'magento');
252
        /* @var $magentoHelper MagentoHelper */
253
        $magentoHelper = $this->getHelperSet()->get('magento');
254
        if (!$this->_directRootDir) {
255
            $subFolders = $this->config->getDetectSubFolders();
256
        } else {
257
            $subFolders = array($folder);
258
        }
259
260
        $this->_magentoDetected = $magentoHelper->detect($folder, $subFolders);
261
        $this->_magentoRootFolder = $magentoHelper->getRootFolder();
262
        $this->_magentoEnterprise = $magentoHelper->isEnterpriseEdition();
263
        $this->_magentoMajorVersion = $magentoHelper->getMajorVersion();
264
        $this->_magerunStopFileFound = $magentoHelper->isMagerunStopFileFound();
265
        $this->_magerunStopFileFolder = $magentoHelper->getMagerunStopFileFolder();
266
    }
267
268
    /**
269
     * Add own helpers to helperset.
270
     *
271
     * @return void
272
     */
273
    protected function registerHelpers()
274
    {
275
        $helperSet = $this->getHelperSet();
276
        $config = $this->config->getConfig();
277
278
        // Twig
279
        $twigBaseDirs = array(
280
            __DIR__ . '/../../../res/twig',
281
        );
282
        if (isset($config['twig']['baseDirs']) && is_array($config['twig']['baseDirs'])) {
283
            $twigBaseDirs = array_merge(array_reverse($config['twig']['baseDirs']), $twigBaseDirs);
284
        }
285
        $helperSet->set(new TwigHelper($twigBaseDirs), 'twig');
286
287
        foreach ($config['helpers'] as $helperName => $helperClass) {
288
            if (class_exists($helperClass)) {
289
                $helperSet->set(new $helperClass(), $helperName);
290
            }
291
        }
292
    }
293
294
    /**
295
     * Try to bootstrap magento 2 and load cli application
296
     *
297
     * @param OutputInterface $output
298
     */
299
    protected function registerMagentoCoreCommands(OutputInterface $output)
300
    {
301
        if (!$this->getMagentoRootFolder()) {
302
            return;
303
        }
304
305
        // Magento was found -> register core cli commands
306
        $this->requireOnce($this->_magentoRootFolder . '/app/bootstrap.php');
307
308
        $coreCliApplication = new \Magento\Framework\Console\Cli();
309
        $coreCliApplicationCommands = $coreCliApplication->all();
310
311
        foreach ($coreCliApplicationCommands as $coreCliApplicationCommand) {
312
            if (OutputInterface::VERBOSITY_DEBUG <= $output->getVerbosity()) {
313
                $output->writeln(
314
                    sprintf(
315
                        '<debug>Add core command </debug> <info>%s</info> -> <comment>%s</comment>',
316
                        $coreCliApplicationCommand->getName(),
317
                        get_class($coreCliApplicationCommand)
318
                    )
319
                );
320
            }
321
            $this->add($coreCliApplicationCommand);
322
        }
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/env.php')
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
        $directoryList = $this->_objectManager->get('\Magento\Framework\App\Filesystem\DirectoryList');
394
        $currentVarDir = $directoryList->getPath('var');
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-magerun2 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-magerun2 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 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]
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
0 ignored issues
show
Documentation introduced by
Should the return type not be null|integer?

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...
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
            $exitCode = max(1, min(255, (int) $e->getCode()));
584
            if ($this->autoExit) {
585
                die($exitCode);
1 ignored issue
show
Coding Style Compatibility introduced by
The method run() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
586
            }
587
            return $exitCode;
588
        }
589
590
        $return = parent::run($input, $output);
591
592
        // Fix for no return values -> used in interactive shell to prevent error output
593
        if ($return === null) {
594
            return 0;
595
        }
596
597
        return $return;
598
    }
599
600
    /**
601
     * @param array $initConfig [optional]
602
     * @param InputInterface $input [optional]
603
     * @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...
604
     *
605
     * @return void
606
     */
607
    public function init(array $initConfig = array(), InputInterface $input = null, OutputInterface $output = null)
608
    {
609
        if ($this->_isInitialized) {
610
            return;
611
        }
612
613
        // Suppress DateTime warnings
614
        date_default_timezone_set(@date_default_timezone_get());
615
616
        // Initialize EventDispatcher early
617
        $this->dispatcher = new EventDispatcher();
618
        $this->setDispatcher($this->dispatcher);
619
620
        if (null === $input) {
621
            $input = new ArgvInput();
622
        }
623
624
        if (null === $output) {
625
            $output = new ConsoleOutput();
626
        }
627
628
        if (null !== $this->config) {
629
            throw new UnexpectedValueException(sprintf('Config already initialized'));
630
        }
631
632
        $loadExternalConfig = !$this->_checkSkipConfigOption($input);
633
634
        $this->config = $config = new Config($initConfig, $this->isPharMode(), $output);
635
        if ($this->configurationLoaderInjected) {
636
            $config->setLoader($this->configurationLoaderInjected);
637
        }
638
        $config->loadPartialConfig($loadExternalConfig);
639
        $this->detectMagento($input, $output);
640
        $configLoader = $config->getLoader();
641
        $configLoader->loadStageTwo($this->_magentoRootFolder, $loadExternalConfig, $this->_magerunStopFileFolder);
642
        $config->load();
643
644
        if ($autoloader = $this->autoloader) {
645
            /**
646
             * Include commands shipped by Magento 2 core
647
             */
648
            if (!$this->_checkSkipMagento2CoreCommandsOption($input)) {
649
                $this->registerMagentoCoreCommands($output);
650
            }
651
            $config->registerCustomAutoloaders($autoloader);
652
            $this->registerEventSubscribers();
653
            $config->registerCustomCommands($this);
654
        }
655
656
        $this->registerHelpers();
657
658
        $this->_isInitialized = true;
659
    }
660
661
    /**
662
     * @param array $initConfig [optional]
663
     * @param InputInterface $input [optional]
664
     * @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...
665
     */
666
    public function reinit($initConfig = array(), InputInterface $input = null, OutputInterface $output = null)
667
    {
668
        $this->_isInitialized = false;
669
        $this->_magentoDetected = false;
670
        $this->_magentoRootFolder = null;
671
        $this->config = null;
672
        $this->init($initConfig, $input, $output);
673
    }
674
675
    /**
676
     * @return void
677
     */
678
    protected function registerEventSubscribers()
679
    {
680
        $config = $this->config->getConfig();
681
        $subscriberClasses = $config['event']['subscriber'];
682
        foreach ($subscriberClasses as $subscriberClass) {
683
            $subscriber = new $subscriberClass();
684
            $this->dispatcher->addSubscriber($subscriber);
685
        }
686
    }
687
688
    /**
689
     * @param InputInterface $input
690
     * @return bool
691
     */
692
    protected function _checkSkipConfigOption(InputInterface $input)
693
    {
694
        return $input->hasParameterOption('--skip-config');
695
    }
696
697
    /**
698
     * @return bool
699
     */
700
    protected function _checkSkipMagento2CoreCommandsOption(InputInterface $input)
701
    {
702
        return $input->hasParameterOption('--skip-core-commands') || getenv('MAGERUN_SKIP_CORE_COMMANDS');
703
    }
704
705
    /**
706
     * @param InputInterface $input
707
     * @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...
708
     */
709
    protected function _checkRootDirOption(InputInterface $input)
710
    {
711
        $rootDir = $input->getParameterOption('--root-dir');
712
        if (is_string($rootDir)) {
713
            $this->setRootDir($rootDir);
714
        }
715
    }
716
717
    /**
718
     * Set root dir (chdir()) of magento directory
719
     *
720
     * @param string $path to Magento directory
721
     */
722
    private function setRootDir($path)
723
    {
724
        if (isset($path[0]) && '~' === $path[0]) {
725
            $path = OperatingSystem::getHomeDir() . substr($path, 1);
726
        }
727
728
        $folder = realpath($path);
729
        $this->_directRootDir = true;
730
        if (is_dir($folder)) {
731
            chdir($folder);
732
        }
733
    }
734
735
    /**
736
     * use require-once inside a function with it's own variable scope w/o any other variables
737
     * and $this unbound.
738
     *
739
     * @param string $path
740
     */
741
    private function requireOnce($path)
742
    {
743
        $requireOnce = function () {
744
            require_once func_get_arg(0);
745
        };
746
        if (50400 <= PHP_VERSION_ID) {
747
            $requireOnce->bindTo(null);
748
        }
749
750
        $requireOnce($path);
751
    }
752
753
    /**
754
     * @param bool $soft
755
     *
756
     * @return void
757
     */
758
    protected function _initMagento1($soft = false)
0 ignored issues
show
Unused Code introduced by
The parameter $soft is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
759
    {
760
        $this->outputMagerunCompatibilityNotice('1');
761
    }
762
763
    /**
764
     * @return void
765
     */
766
    protected function _initMagento2()
0 ignored issues
show
Coding Style introduced by
_initMagento2 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...
767
    {
768
        $this->requireOnce($this->_magentoRootFolder . '/app/bootstrap.php');
769
770
        $params = $_SERVER;
771
        $params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE] = 'admin';
772
        $params[\Magento\Store\Model\Store::CUSTOM_ENTRY_POINT_PARAM] = true;
773
        $params['entryPoint'] = basename(__FILE__);
774
775
        $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
776
        /** @var \Magento\Framework\App\Cron $app */
777
        $app = $bootstrap->createApplication('N98\Magento\Framework\App\Magerun', []);
778
        /* @var $app \N98\Magento\Framework\App\Magerun */
779
        $app->launch();
780
781
        $this->_objectManager = $app->getObjectManager();
0 ignored issues
show
Documentation Bug introduced by
It seems like $app->getObjectManager() of type object<Magento\Framework\ObjectManagerInterface> is incompatible with the declared type object<Magento\Framework...tManager\ObjectManager> of property $_objectManager.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
782
    }
783
784
    /**
785
     * Show a hint that this is Magento incompatible with Magerun and how to obtain the correct Magerun for it
786
     *
787
     * @param string $version of Magento, "1" or "2", that is incompatible
788
     */
789
    private function outputMagerunCompatibilityNotice($version)
790
    {
791
        $file = $version === '2' ? $version : '';
792
        $magentoHint = <<<MAGENTOHINT
793
You are running a Magento $version.x instance. This version of n98-magerun is not compatible
794
with Magento $version.x. Please use n98-magerun$version (version $version) for this shop.
795
796
A current version of the software can be downloaded on github.
797
798
<info>Download with curl
799
------------------</info>
800
801
    <comment>curl -O https://files.magerun.net/n98-magerun$file.phar</comment>
802
803
<info>Download with wget
804
------------------</info>
805
806
    <comment>wget https://files.magerun.net/n98-magerun$file.phar</comment>
807
808
MAGENTOHINT;
809
810
        $output = new ConsoleOutput();
811
812
        /** @var $formatter FormatterHelper */
813
        $formatter = $this->getHelperSet()->get('formatter');
814
815
        $output->writeln(array(
816
            '',
817
            $formatter->formatBlock('Compatibility Notice', 'bg=blue;fg=white', true),
818
            '',
819
            $magentoHint,
820
        ));
821
822
        throw new RuntimeException('This version of n98-magerun is not compatible with Magento ' . $version);
823
    }
824
825
    /**
826
     * @return EventDispatcher
827
     */
828
    public function getDispatcher()
829
    {
830
        return $this->dispatcher;
831
    }
832
833
    /**
834
     * @param ConfigurationLoader $configurationLoader
835
     */
836
    public function setConfigurationLoader(ConfigurationLoader $configurationLoader)
837
    {
838
        if ($this->config) {
839
            $this->config->setLoader($configurationLoader);
840
        } else {
841
            /* inject loader to be used later when config is created in */
842
            /* @see N98\Magento\Application::init() */
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
843
            $this->configurationLoaderInjected = $configurationLoader;
844
        }
845
    }
846
847
    /**
848
     * @param OutputInterface $output
849
     */
850
    protected function _addOutputStyles(OutputInterface $output)
851
    {
852
        $output->getFormatter()->setStyle('debug', new OutputFormatterStyle('magenta', 'white'));
853
        $output->getFormatter()->setStyle('warning', new OutputFormatterStyle('red', 'yellow', array('bold')));
854
    }
855
856
    /**
857
     * @return ObjectManager
858
     */
859
    public function getObjectManager()
860
    {
861
        return $this->_objectManager;
862
    }
863
}
864