Completed
Push — master ( 3260ca...0c0ec5 )
by Christian
02:12
created

ConsoleCommand::loadArea()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace N98\Magento\Command\Developer;
4
5
use Exception;
6
use Magento\Framework\App\Area;
7
use Magento\Framework\App\AreaList;
8
use Magento\Framework\App\ProductMetadataInterface;
9
use Magento\Framework\App\State as AppState;
10
use Magento\Framework\ObjectManager\ConfigLoaderInterface;
11
use N98\Magento\Command\AbstractMagentoCommand;
12
use N98\Magento\Command\Developer\Console\Shell;
13
use N98\Util\Unicode\Charset;
14
use PhpParser\Lexer;
15
use PhpParser\Parser;
16
use Psy\CodeCleaner;
17
use Psy\Configuration;
18
use Psy\Output\ShellOutput;
19
use Symfony\Component\Console\Input\InputArgument;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Input\InputOption;
22
use Symfony\Component\Console\Output\OutputInterface;
23
24
/**
25
 * Class ConsoleCommand
26
 * @package N98\Magento\Command\Developer
27
 */
28
class ConsoleCommand extends AbstractMagentoCommand
29
{
30
    /**
31
     * @var ProductMetadataInterface
32
     */
33
    private $productMeta;
34
35
    /**
36
     * @var AppState
37
     */
38
    private $appState;
39
40
    /**
41
     * @var ConfigLoaderInterface
42
     */
43
    private $configLoader;
44
45
    /**
46
     * @var AreaList
47
     */
48
    private $areaList;
49
50
    protected function configure()
51
    {
52
        $this
53
            ->setName('dev:console')
54
            ->addArgument('cmd', InputArgument::OPTIONAL, 'Direct code to run')
55
            ->addOption('area', 'a', InputOption::VALUE_REQUIRED, 'Area to initialize')
56
            ->setDescription(
57
                'Opens PHP interactive shell with initialized Mage::app() <comment>(Experimental)</comment>'
58
            );
59
    }
60
61
    /**
62
     * @param ProductMetadataInterface $productMetadata
63
     * @param AppState $appState
64
     * @param ConfigLoaderInterface $configLoader
65
     * @param AreaList $areaList
66
     */
67
    public function inject(
68
        ProductMetadataInterface $productMetadata,
69
        AppState $appState,
70
        ConfigLoaderInterface $configLoader,
71
        AreaList $areaList
72
    ) {
73
        $this->productMeta = $productMetadata;
74
        $this->appState = $appState;
75
        $this->configLoader = $configLoader;
76
        $this->areaList = $areaList;
77
    }
78
79
    /**
80
     * @param InputInterface $input
81
     * @param OutputInterface $output
82
     *
83
     * @return int|void
84
     * @throws \Magento\Framework\Exception\LocalizedException
85
     */
86
    protected function execute(InputInterface $input, OutputInterface $output)
87
    {
88
        $initialized = false;
89
        try {
90
            $this->detectMagento($output);
91
            $initialized = $this->initMagento();
92
        } catch (Exception $e) {
93
            // do nothing
94
        }
95
96
        $config = new Configuration();
97
98
        $php5Parser = new Parser\Php5(new Lexer\Emulative());
99
        $php7Parser = new Parser\Php7(new Lexer\Emulative());
100
101
        $parser = new Parser\Multiple([$php5Parser, $php7Parser]);
102
        $cleaner = new CodeCleaner($parser);
103
        $config->setCodeCleaner($cleaner);
104
105
        $consoleOutput = new ShellOutput();
106
107
        $commandConfig = $this->getCommandConfig();
108
        $commandsToAdd = [];
109
        foreach ($commandConfig['commands'] as $command) {
110
            $commandsToAdd[] = new $command();
111
        }
112
113
        $config->addCommands($commandsToAdd);
114
115
        $shell = new Shell($config);
116
        $shell->setScopeVariables([
117
            'di'              => $this->getObjectManager(),
118
            'magentoVersion'  => $this->getObjectManager()->get(ProductMetadataInterface::class),
119
            'magerun'         => $this->getApplication(),
120
            'magerunInternal' => (object) ['currentModule' => ''],
121
        ]);
122
123
        if ($initialized) {
124
            $ok = Charset::convertInteger(Charset::UNICODE_CHECKMARK_CHAR);
125
126
            $areaToLoad = $input->getOption('area');
127
128
            if ($areaToLoad) {
129
                $this->loadArea($areaToLoad);
130
            }
131
132
            $edition = $this->productMeta->getEdition();
133
            $magentoVersion = $this->productMeta->getVersion();
134
135
            $statusMessage = sprintf(
136
                '<fg=black;bg=green>Magento %s %s initialized %s</fg=black;bg=green>',
137
                $magentoVersion,
138
                $edition,
139
                $ok
140
            );
141
142
            $consoleOutput->writeln($statusMessage);
143
144
            if ($areaToLoad) {
145
                $areaMessage = sprintf(
146
                    '<fg=black;bg=white>Area: %s</fg=black;bg=white>',
147
                    $this->appState->getAreaCode()
148
                );
149
                $consoleOutput->writeln($areaMessage);
150
            }
151
        } else {
152
            $consoleOutput->writeln('<fg=black;bg=yellow>Magento is not initialized.</fg=black;bg=yellow>');
153
        }
154
155
        $help = <<<'help'
156
At the prompt, type <comment>help</comment> for some help.
157
158
To exit the shell, type <comment>^D</comment>.
159
help;
160
161
        $consoleOutput->writeln($help);
162
163
        $cmd = $input->getArgument('cmd');
164
165
        if ($cmd === '-') {
166
            $cmd = 'php://stdin';
167
            $cmd = @\file_get_contents($cmd);
168
        }
169
170
        if (!empty($cmd)) {
171
            $code = preg_split('/[\n;]+/', $cmd);
172
            $shell->addInput($code);
173
        }
174
175
        $shell->run($input, $consoleOutput);
176
    }
177
178
    /**
179
     * @param string $areaToLoad
180
     * @throws \Magento\Framework\Exception\LocalizedException
181
     */
182
    private function loadArea($areaToLoad): void
183
    {
184
        $this->appState->setAreaCode($areaToLoad);
185
186
        // load di.xml config of the defined area
187
        $this->getObjectManager()->configure(
188
            $this->configLoader->load($areaToLoad)
189
        );
190
191
        // load all configs of the defined are
192
        $this->areaList->getArea($areaToLoad)
193
            ->load(Area::PART_CONFIG)
194
            ->load(Area::PART_TRANSLATE);
195
    }
196
}
197