Completed
Pull Request — develop (#1)
by Tom
13:24 queued 06:18
created

Application::checkVarDir()   B

Complexity

Conditions 8
Paths 7

Size

Total Lines 53
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
c 2
b 0
f 2
dl 0
loc 53
rs 7.1199
cc 8
eloc 37
nc 7
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

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...
337
     */
338
    public function checkVarDir(OutputInterface $output)
339
    {
340
        if (OutputInterface::VERBOSITY_NORMAL <= $output->getVerbosity()) {
341
            $tempVarDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'magento' . DIRECTORY_SEPARATOR . 'var';
342
343
            if (is_dir($tempVarDir)) {
344
                $this->detectMagento(null, $output);
345
                /* If magento is not installed yet, don't check */
346
                if ($this->_magentoRootFolder === null
347
                    || !file_exists($this->_magentoRootFolder . '/app/etc/local.xml')
348
                ) {
349
                    return;
350
                }
351
352
                try {
353
                    $this->initMagento();
354
                } catch (\Exception $e) {
355
                    $message = 'Cannot initialize Magento. Please check your configuration. '
356
                        . 'Some n98-magerun command will not work. Got message: ';
357
                    if (OutputInterface::VERBOSITY_VERY_VERBOSE <= $output->getVerbosity()) {
358
                        $message .= $e->getTraceAsString();
359
                    } else {
360
                        $message .= $e->getMessage();
361
                    }
362
                    $output->writeln($message);
363
364
                    return;
365
                }
366
367
                $configOptions = new \Mage_Core_Model_Config_Options();
368
                $currentVarDir = $configOptions->getVarDir();
369
370
                if ($currentVarDir == $tempVarDir) {
371
                    $output->writeln(sprintf('<warning>Fallback folder %s is used in n98-magerun</warning>',
372
                        $tempVarDir));
373
                    $output->writeln('');
374
                    $output->writeln('n98-magerun is using the fallback folder. If there is another folder configured for Magento, this can cause serious problems.');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 166 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
375
                    $output->writeln('Please refer to https://github.com/netz98/n98-magerun/wiki/File-system-permissions for more information.');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 145 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
376
                    $output->writeln('');
377
                } else {
378
                    $output->writeln(sprintf('<warning>Folder %s found, but not used in n98-magerun</warning>',
379
                        $tempVarDir));
380
                    $output->writeln('');
381
                    $output->writeln(sprintf('This might cause serious problems. n98-magerun is using the configured var-folder <comment>%s</comment>',
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 151 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
382
                        $currentVarDir));
383
                    $output->writeln('Please refer to https://github.com/netz98/n98-magerun/wiki/File-system-permissions for more information.');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 145 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
384
                    $output->writeln('');
385
386
                    return false;
387
                }
388
            }
389
        }
390
    }
391
392
    public function initMagento()
393
    {
394
        if ($this->getMagentoRootFolder() !== null) {
395
            if ($this->_magentoMajorVersion == self::MAGENTO_MAJOR_VERSION_2) {
396
                $this->_initMagento2();
397
            } else {
398
                $this->_initMagento1();
399
            }
400
401
            return true;
402
        }
403
404
        return false;
405
    }
406
407
    /**
408
     * @return string
409
     */
410
    public function getHelp()
411
    {
412
        return self::$logo . parent::getHelp();
413
    }
414
415
    public function getLongVersion()
416
    {
417
        return parent::getLongVersion() . ' by <info>netz98 new media GmbH</info>';
418
    }
419
420
    /**
421
     * @return boolean
422
     */
423
    public function isMagentoEnterprise()
424
    {
425
        return $this->_magentoEnterprise;
426
    }
427
428
    /**
429
     * @return string
430
     */
431
    public function getMagentoRootFolder()
432
    {
433
        return $this->_magentoRootFolder;
434
    }
435
436
    /**
437
     * @param string $magentoRootFolder
438
     */
439
    public function setMagentoRootFolder($magentoRootFolder)
440
    {
441
        $this->_magentoRootFolder = $magentoRootFolder;
442
    }
443
444
    /**
445
     * @return int
446
     */
447
    public function getMagentoMajorVersion()
448
    {
449
        return $this->_magentoMajorVersion;
450
    }
451
452
    /**
453
     * @return ClassLoader
454
     */
455
    public function getAutoloader()
456
    {
457
        return $this->autoloader;
458
    }
459
460
    /**
461
     * @param ClassLoader $autoloader
462
     */
463
    public function setAutoloader(ClassLoader $autoloader)
464
    {
465
        $this->autoloader = $autoloader;
466
    }
467
468
    /**
469
     * @return array
470
     */
471
    public function getConfig()
472
    {
473
        return $this->config->getConfig();
474
    }
475
476
    /**
477
     * @param array $config
478
     */
479
    public function setConfig($config)
480
    {
481
        $this->config->setConfig($config);
482
    }
483
484
    /**
485
     * @return boolean
486
     */
487
    public function isMagerunStopFileFound()
488
    {
489
        return $this->_magerunStopFileFound;
490
    }
491
492
    /**
493
     * Runs the current application with possible command aliases
494
     *
495
     * @param InputInterface $input   An Input instance
496
     * @param OutputInterface $output An Output instance
497
     *
498
     * @return integer 0 if everything went fine, or an error code
499
     */
500
    public function doRun(InputInterface $input, OutputInterface $output)
501
    {
502
        $event = new Application\Console\Event($this, $input, $output);
503
        $this->dispatcher->dispatch(Events::RUN_BEFORE, $event);
504
505
        /**
506
         * only for compatibility to old versions.
507
         */
508
        $event = new ConsoleEvent(new Command('dummy'), $input, $output);
509
        $this->dispatcher->dispatch('console.run.before', $event);
510
511
        $input = $this->config->checkConfigCommandAlias($input);
512
        if ($output instanceof ConsoleOutput) {
513
            $this->checkVarDir($output->getErrorOutput());
514
        }
515
516
        if (OutputInterface::VERBOSITY_DEBUG <= $output->getVerbosity()) {
517
            $output->writeln('DEBUG');
518
        }
519
520
        return parent::doRun($input, $output);
521
    }
522
523
    /**
524
     * @param InputInterface $input
1 ignored issue
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...
525
     * @param OutputInterface $output
1 ignored issue
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...
526
     * @return int
527
     */
528
    public function run(InputInterface $input = null, OutputInterface $output = null)
529
    {
530
        if (null === $input) {
531
            $input = new ArgvInput();
532
        }
533
534
        if (null === $output) {
535
            $output = new ConsoleOutput();
536
        }
537
        $this->_addOutputStyles($output);
538
        if ($output instanceof ConsoleOutput) {
539
            $this->_addOutputStyles($output->getErrorOutput());
540
        }
541
542
        $this->configureIO($input, $output);
543
544
        try {
545
            $this->init(array(), $input, $output);
546
        } catch (\Exception $e) {
547
            $output = new ConsoleOutput();
548
            $this->renderException($e, $output);
549
        }
550
551
        $return = parent::run($input, $output);
552
553
        // Fix for no return values -> used in interactive shell to prevent error output
554
        if ($return === null) {
555
            return 0;
556
        }
557
558
        return $return;
559
    }
560
561
    /**
562
     * @param array $initConfig
563
     * @param InputInterface $input
1 ignored issue
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...
564
     * @param OutputInterface $output
1 ignored issue
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...
565
     *
566
     * @return void
567
     */
568
    public function init($initConfig = array(), InputInterface $input = null, OutputInterface $output = null)
569
    {
570
        if (!$this->_isInitialized) {
571
            // Suppress DateTime warnings
572
            date_default_timezone_set(@date_default_timezone_get());
573
574
            $loadExternalConfig = !$this->_checkSkipConfigOption();
575
576
            if ($output === null) {
577
                $output = new NullOutput();
578
            }
579
580
            if (null !== $this->config) {
581
                throw new UnexpectedValueException(sprintf('Config already initialized'));
582
            }
583
584
            $config = new Config($initConfig, $this->isPharMode(), $output);
585
            $configLoader = $config->getLoader();
586
            $this->partialConfig = $configLoader->getPartialConfig($loadExternalConfig);
587
            $this->detectMagento($input, $output);
588
            $configLoader->loadStageTwo($this->_magentoRootFolder, $loadExternalConfig, $this->_magerunStopFileFolder);
589
            $config->load();
590
            $this->config = $config;
591
            $this->dispatcher = new EventDispatcher();
592
            $this->setDispatcher($this->dispatcher);
593
594
            if ($autoloader = $this->autoloader) {
595
596
                /**
597
                 * Include commands shipped by Magento 2 core
598
                 */
599
                if (!$this->_checkSkipMagento2CoreCommandsOption()) {
600
                    $this->registerMagentoCoreCommands($output);
601
                }
602
603
                $this->config->registerCustomAutoloaders($autoloader);
604
                $this->registerEventSubscribers();
605
                $config->registerCustomCommands($this);
606
            }
607
            $this->registerHelpers();
608
609
610
            $this->_isInitialized = true;
611
        }
612
    }
613
614
    /**
615
     * @param array $initConfig
616
     * @param InputInterface $input
1 ignored issue
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...
617
     * @param OutputInterface $output
1 ignored issue
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...
618
     */
619
    public function reinit($initConfig = array(), InputInterface $input = null, OutputInterface $output = null)
620
    {
621
        $this->_isInitialized = false;
622
        $this->init($initConfig, $input, $output);
623
    }
624
625
    /**
626
     * @return void
627
     */
628
    protected function registerEventSubscribers()
629
    {
630
        foreach ($this->config->getConfig()['event']['subscriber'] as $subscriberClass) {
631
            $subscriber = new $subscriberClass();
632
            $this->dispatcher->addSubscriber($subscriber);
633
        }
634
    }
635
636
    /**
637
     * @return bool
638
     */
639
    protected function _checkSkipConfigOption()
640
    {
641
        $skipConfigOption = getopt('', array('skip-config'));
642
643
        return count($skipConfigOption) > 0;
644
    }
645
646
    /**
647
     * @return bool
648
     */
649
    protected function _checkSkipMagento2CoreCommandsOption()
650
    {
651
        $skipConfigOption = getopt('', array('skip-core-commands'));
652
653
        getenv('MAGERUN_SKIP_CORE_COMMANDS') && $skipConfigOption[] = 1;
654
655
        return count($skipConfigOption) > 0;
656
    }
657
658
    /**
659
     * @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...
660
     */
661
    protected function _checkRootDirOption()
662
    {
663
        $specialGlobalOptions = getopt('', array('root-dir:'));
664
665
        if (count($specialGlobalOptions) > 0) {
666
            if (isset($specialGlobalOptions['root-dir'][0])
667
                && $specialGlobalOptions['root-dir'][0] == '~'
668
            ) {
669
                $specialGlobalOptions['root-dir'] = OperatingSystem::getHomeDir() . substr($specialGlobalOptions['root-dir'],
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 125 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
670
                        1);
671
            }
672
            $folder               = realpath($specialGlobalOptions['root-dir']);
673
            $this->_directRootDir = true;
674
            if (is_dir($folder)) {
675
                \chdir($folder);
676
677
                return;
678
            }
679
        }
680
    }
681
682
    protected function _initMagento1()
683
    {
684
        $magento1Hint = <<<'MAGENTO1HINT'
685
You are running a Magento 1.x instance. This version of n98-magerun is not compatible
686
with Magento 1.x. Please use n98-magerun (version 1) for this shop.
687
688
A current version of the software can be downloaded on github.
689
690
<info>Download with curl
691
------------------</info>
692
693
    <comment>curl -o n98-magerun.phar https://raw.githubusercontent.com/netz98/n98-magerun/master/n98-magerun.phar</comment>
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 124 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
694
695
<info>Download with wget
696
------------------</info>
697
698
    <comment>curl -o n98-magerun.phar https://raw.githubusercontent.com/netz98/n98-magerun/master/n98-magerun.phar</comment>
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 124 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
699
700
MAGENTO1HINT;
701
702
        $output = new ConsoleOutput();
703
704
        $output->writeln(array(
705
            '',
706
            $this->getHelperSet()->get('formatter')->formatBlock('Compatibility Notice', 'bg=blue;fg=white', true),
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Component\Console\Helper\HelperInterface as the method formatBlock() does only exist in the following implementations of said interface: Symfony\Component\Console\Helper\FormatterHelper.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
707
            ''
708
        ));
709
710
        $output->writeln($magento1Hint);
711
        exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method _initMagento1() 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...
712
    }
713
714
    /**
715
     * @return void
716
     */
717
    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...
718
    {
719
        require_once $this->getMagentoRootFolder() . '/app/bootstrap.php';
720
721
        $params                                                       = $_SERVER;
722
        $params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE]    = 'admin';
723
        $params[\Magento\Store\Model\Store::CUSTOM_ENTRY_POINT_PARAM] = true;
724
        $params['entryPoint']                                         = basename(__FILE__);
725
726
        $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
727
        /** @var \Magento\Framework\App\Cron $app */
728
        $app = $bootstrap->createApplication('N98\Magento\Framework\App\Magerun', []);
729
        /* @var $app \N98\Magento\Framework\App\Magerun */
730
        $app->launch();
731
732
        $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...
733
    }
734
735
    /**
736
     * @return EventDispatcher
737
     */
738
    public function getDispatcher()
739
    {
740
        return $this->dispatcher;
741
    }
742
743
    /**
744
     * @param ConfigurationLoader $configurationLoader
745
     */
746
    public function setConfigurationLoader(ConfigurationLoader $configurationLoader)
747
    {
748
        $this->config->setConfigurationLoader($configurationLoader);
749
    }
750
751
    /**
752
     * @param OutputInterface $output
753
     */
754
    protected function _addOutputStyles(OutputInterface $output)
755
    {
756
        $output->getFormatter()->setStyle('debug', new OutputFormatterStyle('magenta', 'white'));
757
        $output->getFormatter()->setStyle('warning', new OutputFormatterStyle('red', 'yellow', array('bold')));
758
    }
759
760
    /**
761
     * @return ObjectManager
762
     */
763
    public function getObjectManager()
764
    {
765
        return $this->_objectManager;
766
    }
767
}
768