Completed
Push — develop ( d18ffa...e0ceaf )
by Tom
04:48
created

DevUrnCatalogAutoPath::autosetIdeaMiscXmlPath()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 41
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 41
rs 6.7272
cc 7
eloc 24
nc 7
nop 1
1
<?php
2
/*
3
 * @author Tom Klingenberg <https://github.com/ktomk>
4
 */
5
6
namespace N98\Magento\Application\Console\EventSubscriber;
7
8
use Magento\Developer\Console\Command\XmlCatalogGenerateCommand;
9
use ReflectionException;
10
use ReflectionObject;
11
use Symfony\Component\Console\ConsoleEvents;
12
use Symfony\Component\Console\Event\ConsoleCommandEvent;
13
use Symfony\Component\Console\Input\ArgvInput;
14
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15
16
/**
17
 * Class DevUrnCatalogAutoPath
18
 *
19
 * Comfort option to automatically set path to ".idea/misc.xml
20
 *
21
 * @package N98\Magento\Application\Console\EventSubscriber
22
 */
23
class DevUrnCatalogAutoPath implements EventSubscriberInterface
24
{
25
    /**
26
     * Returns an array of event names this subscriber wants to listen to.
27
     *
28
     * @return array The event names to listen to
29
     *
30
     * @api
31
     */
32
    public static function getSubscribedEvents()
33
    {
34
        return [
35
            ConsoleEvents::COMMAND => 'autosetIdeaMiscXmlPath',
36
        ];
37
    }
38
39
    /**
40
     * Display a warning if a running n98-magerun as root user
41
     *
42
     * @param ConsoleCommandEvent $event
43
     *
44
     * @return void
45
     */
46
    public function autosetIdeaMiscXmlPath(ConsoleCommandEvent $event)
47
    {
48
        if (!$event->getCommand() instanceof XmlCatalogGenerateCommand) {
1 ignored issue
show
Bug introduced by
The class Magento\Developer\Consol...lCatalogGenerateCommand does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
49
            return;
50
        }
51
52
        $input = clone $event->getInput();
53
        if (!$input instanceof ArgvInput) {
54
            return;
55
        }
56
57
        $command = clone $event->getCommand();
58
59
        $input->bind($command->getDefinition());
60
61
        $path = null;
62
        try {
63
            $path = $input->getArgument('path');
64
        } catch (\Exception $e) {
65
            return;
66
        }
67
68
        if ('dev:urn-catalog:generate' !== $path) {
69
            return;
70
        }
71
72
        $file = $this->detectFile($event);
73
        if (null === $file) {
74
            return;
75
        }
76
77
        $argv = $event->getInput();
78
79
        if (!$this->canAddToken($argv)) {
0 ignored issues
show
Compatibility introduced by
$argv of type object<Symfony\Component...e\Input\InputInterface> is not a sub-type of object<Symfony\Component\Console\Input\ArgvInput>. It seems like you assume a concrete implementation of the interface Symfony\Component\Console\Input\InputInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
80
            $event->getOutput()->writeln("<info>Path hint <comment>'$file'</comment></info>");
81
            return;
82
        }
83
84
        $event->getOutput()->writeln("<info>automatically setting path to <comment>'$file'</comment></info>");
85
        $this->addToken($argv, $file);
0 ignored issues
show
Compatibility introduced by
$argv of type object<Symfony\Component...e\Input\InputInterface> is not a sub-type of object<Symfony\Component\Console\Input\ArgvInput>. It seems like you assume a concrete implementation of the interface Symfony\Component\Console\Input\InputInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
86
    }
87
88
    /**
89
     * @param ConsoleCommandEvent $event
90
     * @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...
91
     */
92
    private function detectFile(ConsoleCommandEvent $event)
93
    {
94
        /** @var \N98\Magento\Application $app */
95
        $app = $event->getCommand()->getApplication();
96
97
        $root = $app->getMagentoRootFolder();
98
        $down = 2;
99
        do {
100
            if (is_dir($root . '/.idea')) {
101
                return $root . '/.idea/misc.xml';
102
            }
103
            $root .= '/..';
104
        } while (is_dir($root) && $down--);
105
    }
106
107
    /**
108
     * Check if capable to manipulate tokens as needed
109
     *
110
     * @link https://github.com/netz98/n98-magerun2/issues/233
111
     *
112
     * @param ArgvInput $arg
113
     * @return bool
114
     */
115
    private function canAddToken(ArgvInput $arg)
116
    {
117
        $refl = new ReflectionObject($arg);
118
119
        return $refl->hasProperty('tokens');
120
    }
121
122
    /**
123
     * @param ArgvInput $arg
124
     * @param string $file
125
     * @return void
126
     * @throws ReflectionException
127
     */
128
    private function addToken(ArgvInput $arg, $file)
129
    {
130
        $refl = new ReflectionObject($arg);
131
        $prop = $refl->getProperty('tokens');
132
        $prop->setAccessible(true);
133
        $tokens = $prop->getValue($arg);
134
        $tokens[] = $file;
135
        $prop->setValue($arg, $tokens);
136
    }
137
}
138