IdeHelperCommand::makeLocators()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 9
nc 3
nop 1
1
<?php
2
/**
3
 * Spiral Framework, IDE Helper
4
 *
5
 * @author    Dmitry Mironov <[email protected]>
6
 * @licence   MIT
7
 */
8
9
namespace Spiral\IdeHelper;
10
11
use Interop\Container\ContainerInterface;
12
use Spiral\Console\Command;
13
use Spiral\Core\FactoryInterface;
14
use Spiral\IdeHelper\Locators\LocatorInterface;
15
use Spiral\IdeHelper\Writers\WriterInterface;
16
use Symfony\Component\Console\Input\InputOption;
17
18
/**
19
 * Class IdeHelperCommand
20
 *
21
 * @package Spiral\IdeHelper
22
 */
23
class IdeHelperCommand extends Command
24
{
25
    const NAME        = 'ide-helper';
26
    const DESCRIPTION = 'Generate IDE help classes';
27
28
    const OPTIONS = [
29
        [
30
            'writers',
31
            'w',
32
            InputOption::VALUE_OPTIONAL,
33
            'Comma-separated writers to use',
34
            null
35
        ],
36
        [
37
            'locators',
38
            'l',
39
            InputOption::VALUE_OPTIONAL,
40
            'Comma-separated locators to use',
41
            null
42
        ],
43
    ];
44
45
    /**
46
     * @var FactoryInterface
47
     */
48
    private $factory;
49
50
    /**
51
     * IdeHelperCommand constructor.
52
     *
53
     * @param ContainerInterface $container
54
     * @param FactoryInterface   $factory
55
     */
56
    public function __construct(ContainerInterface $container, FactoryInterface $factory)
57
    {
58
        parent::__construct($container);
59
60
        $this->factory = $factory;
61
    }
62
63
    /**
64
     * @param IdeHelperConfig $config
65
     */
66
    public function perform(IdeHelperConfig $config)
67
    {
68
        $writers = $this->makeWriters($config->getWriters());
69
        $locators = $this->makeLocators($config->getLocators());
70
71
        if (null === $this->option('writers') && null === $this->option('locators')) {
72
            $scopes = $config->getScopes();
73
        } elseif (null !== $this->option('writers') && null !== $this->option('locators')) {
74
            $scopes = [
75
                'runtime' => [
76
                    'writers'  => explode(',', $this->option('writers')),
77
                    'locators' => explode(',', $this->option('locators')),
78
                ],
79
            ];
80
        } else {
81
            $this->writeln('<error>Both writers and locators options are required</error>');
82
83
            return;
84
        }
85
86
        $this->processScopes($scopes, $writers, $locators);
87
    }
88
89
    /**
90
     * @param array $scopes
91
     * @param array $writers
92
     * @param array $locators
93
     */
94
    private function processScopes(array $scopes, array $writers, array $locators)
95
    {
96
        foreach ($scopes as $scopeName => $scopeParams) {
97
            $this->writeln("<info>Processing scope '<comment>$scopeName</comment>':</info>");
98
99
            /** @var WriterInterface[] $scopeWriters */
100
            $scopeWriters = \array_intersect_key($writers, array_flip($scopeParams['writers']));
101
102
            /** @var LocatorInterface[] $scopeLocators */
103
            $scopeLocators = \array_intersect_key($locators, array_flip($scopeParams['locators']));
104
105
            $classes = [];
106
            foreach ($scopeLocators as $name => $locator) {
107
                $located = $locator->locate();
108
                $classes = array_merge($classes, $located);
109
110
                $countLocated = count($located);
111
                $this->writeln("<fg=cyan>Locating '<comment>$name</comment>', found "
112
                    . "<info>$countLocated</info> classes.</fg=cyan>");
113
            }
114
115
            foreach ($scopeWriters as $name => $writer) {
116
                $this->writeln(
117
                    "<fg=cyan>Generating docs using writer '<comment>$name</comment>'.</fg=cyan>"
118
                );
119
                $writer->write($classes);
120
            }
121
122
            $this->writeln("");
123
        }
124
    }
125
126
    /**
127
     * @param array $config
128
     *
129
     * @return WriterInterface[]
130
     */
131
    private function makeWriters(array $config): array
132
    {
133
        $writers = [];
134
135
        foreach ($config as $name => $binding) {
136
            $writers[$name] = $binding->resolve($this->factory);
137
        }
138
139
        return $writers;
140
    }
141
142
    /**
143
     * @param array $config
144
     *
145
     * @return LocatorInterface[]
146
     */
147
    private function makeLocators(array $config): array
148
    {
149
        $locators = [];
150
151
        foreach ($config as $name => $binding) {
152
            if (is_string($binding)) {
153
                $target = $this->factory->make($binding);
154
            } else {
155
                $target = $binding->resolve($this->factory);
156
            }
157
158
            $locators[$name] = $target;
159
        }
160
161
        return $locators;
162
    }
163
}
164