Completed
Push — master ( 880b7a...33b151 )
by Tom
09:34 queued 06:03
created

Config   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 294
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 39
c 0
b 0
f 0
lcom 1
cbo 6
dl 0
loc 294
rs 8.2857

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
B checkConfigCommandAlias() 0 27 5
A registerConfigCommandAlias() 0 17 4
A registerCustomCommands() 0 20 3
A newCommand() 0 16 4
A registerCustomAutoloaders() 0 14 3
A setConfig() 0 4 1
A getConfig() 0 4 1
A setLoader() 0 4 1
A getLoader() 0 9 2
A load() 0 4 1
A loadPartialConfig() 0 5 1
A getDetectSubFolders() 0 8 2
A createLoader() 0 8 1
A debugWriteln() 0 7 2
A getArray() 0 9 2
A traverse() 0 16 4
1
<?php
2
/*
3
 * @author Tom Klingenberg <https://github.com/ktomk>
4
 */
5
6
namespace N98\Magento\Application;
7
8
use Composer\Autoload\ClassLoader;
9
use InvalidArgumentException;
10
use N98\Magento\Application;
11
use N98\Util\ArrayFunctions;
12
use N98\Util\BinaryString;
13
use Symfony\Component\Console\Command\Command;
14
use Symfony\Component\Console\Formatter\OutputFormatter;
15
use Symfony\Component\Console\Input\ArgvInput;
16
use Symfony\Component\Console\Input\InputInterface;
17
use Symfony\Component\Console\Output\NullOutput;
18
use Symfony\Component\Console\Output\OutputInterface;
19
20
/**
21
 * Class Config
22
 *
23
 * Class representing the application configuration. Created to factor out configuration related application
24
 * functionality from @see N98\Magento\Application
25
 *
26
 * @package N98\Magento\Application
27
 */
28
class Config
29
{
30
    /**
31
     * @var array config data
32
     */
33
    private $config = array();
34
35
    /**
36
     * @var array
37
     */
38
    private $partialConfig = array();
39
40
    /**
41
     * @var ConfigurationLoader
42
     */
43
    private $loader;
44
45
    /**
46
     * @var array
47
     */
48
    private $initConfig;
49
50
    /**
51
     * @var boolean
52
     */
53
    private $isPharMode;
54
55
    /**
56
     * @var OutputInterface
57
     */
58
    private $output;
59
60
    /**
61
     * Config constructor.
62
     *
63
     * @param array $initConfig
64
     * @param bool $isPharMode
65
     * @param OutputInterface $output [optional]
66
     */
67
    public function __construct(array $initConfig = array(), $isPharMode = false, OutputInterface $output = null)
68
    {
69
        $this->initConfig = $initConfig;
70
        $this->isPharMode = (bool) $isPharMode;
71
        $this->output = $output ?: new NullOutput();
72
    }
73
74
    /**
75
     * alias magerun command in input from config
76
     *
77
     * @param InputInterface $input
78
     * @return ArgvInput|InputInterface
79
     */
80
    public function checkConfigCommandAlias(InputInterface $input)
0 ignored issues
show
Coding Style introduced by
checkConfigCommandAlias 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...
81
    {
82
        foreach ($this->getArray(array('commands', 'aliases')) as $alias) {
83
            if (!is_array($alias)) {
84
                continue;
85
            }
86
            $aliasCommandName = key($alias);
87
            if ($input->getFirstArgument() !== $aliasCommandName) {
88
                continue;
89
            }
90
            $aliasCommandParams = array_slice(
91
                BinaryString::trimExplodeEmpty(' ', $alias[$aliasCommandName]),
92
                1
93
            );
94
            if (count($aliasCommandParams) > 0) {
95
                // replace with aliased data
96
                $mergedParams = array_merge(
97
                    array_slice($_SERVER['argv'], 0, 2),
98
                    $aliasCommandParams,
99
                    array_slice($_SERVER['argv'], 2)
100
                );
101
                $input = new ArgvInput($mergedParams);
102
            }
103
        }
104
105
        return $input;
106
    }
107
108
    /**
109
     * @param Command $command
110
     */
111
    public function registerConfigCommandAlias(Command $command)
112
    {
113
        foreach ($this->getArray(array('commands', 'aliases')) as $alias) {
114
            if (!is_array($alias)) {
115
                continue;
116
            }
117
118
            $aliasCommandName = key($alias);
119
            $commandString = $alias[$aliasCommandName];
120
            list($originalCommand) = explode(' ', $commandString, 2);
121
            if ($command->getName() !== $originalCommand) {
122
                continue;
123
            }
124
125
            $command->setAliases(array_merge($command->getAliases(), array($aliasCommandName)));
126
        }
127
    }
128
129
    /**
130
     * @param Application $application
131
     */
132
    public function registerCustomCommands(Application $application)
133
    {
134
        foreach ($this->getArray(array('commands', 'customCommands')) as $commandClass) {
135
            $commandName = null;
136
            if (is_array($commandClass)) {
137
                // Support for key => value (name -> class)
138
                $commandName = key($commandClass);
139
                $commandClass = current($commandClass);
140
            }
141
            $command = $this->newCommand($commandClass, $commandName);
142
            $this->debugWriteln(
143
                sprintf(
144
                    '<debug>Add command </debug> <info>%s</info> -> <comment>%s</comment>',
145
                    $command->getName(),
146
                    get_class($command)
147
                )
148
            );
149
            $application->add($command);
150
        }
151
    }
152
153
    /**
154
     * @param string $className
155
     * @param string|null $commandName
156
     * @return Command
157
     * @throws InvalidArgumentException
158
     */
159
    private function newCommand($className, $commandName)
160
    {
161
        /** @var Command $command */
162
        if (!(is_string($className) || is_object($className))) {
163
            throw new InvalidArgumentException(
164
                sprintf('Command classname must be string, %s given', gettype($className))
165
            );
166
        }
167
168
        $command = new $className();
169
        if (null !== $commandName) {
170
            $command->setName($commandName);
171
        }
172
173
        return $command;
174
    }
175
176
    /**
177
     * Adds autoloader prefixes from user's config
178
     *
179
     * @param ClassLoader $autoloader
180
     */
181
    public function registerCustomAutoloaders(ClassLoader $autoloader)
182
    {
183
        $mask = '<debug>Registered %s autoloader </debug> <info>%s</info> -> <comment>%s</comment>';
184
185
        foreach ($this->getArray('autoloaders') as $prefix => $path) {
186
            $autoloader->add($prefix, $path);
187
            $this->debugWriteln(sprintf($mask, 'PSR-2', $prefix, $path));
188
        }
189
190
        foreach ($this->getArray('autoloaders_psr4') as $prefix => $path) {
191
            $autoloader->addPsr4($prefix, $path);
192
            $this->debugWriteln(sprintf($mask, 'PSR-4', OutputFormatter::escape($prefix), $path));
193
        }
194
    }
195
196
    /**
197
     * @param array $config
198
     */
199
    public function setConfig(array $config)
200
    {
201
        $this->config = $config;
202
    }
203
204
    /**
205
     * @return array
206
     */
207
    public function getConfig()
208
    {
209
        return $this->config;
210
    }
211
212
    /**
213
     * @param ConfigurationLoader $configurationLoader
214
     */
215
    public function setLoader(ConfigurationLoader $configurationLoader)
216
    {
217
        $this->loader = $configurationLoader;
218
    }
219
220
    /**
221
     * @return ConfigurationLoader
222
     */
223
    public function getLoader()
224
    {
225
        if (!$this->loader) {
226
            $this->loader = $this->createLoader($this->initConfig, $this->isPharMode, $this->output);
227
            $this->initConfig = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $initConfig.

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...
228
        }
229
230
        return $this->loader;
231
    }
232
233
    public function load()
234
    {
235
        $this->config = $this->getLoader()->toArray();
236
    }
237
238
    /**
239
     * @param bool $loadExternalConfig
240
     */
241
    public function loadPartialConfig($loadExternalConfig)
242
    {
243
        $loader = $this->getLoader();
244
        $this->partialConfig = $loader->getPartialConfig($loadExternalConfig);
245
    }
246
247
    /**
248
     * Get names of sub-folders to be scanned during Magento detection
249
     *
250
     * @return array
251
     */
252
    public function getDetectSubFolders()
253
    {
254
        if (isset($this->partialConfig['detect']['subFolders'])) {
255
            return $this->partialConfig['detect']['subFolders'];
256
        }
257
258
        return array();
259
    }
260
261
    /**
262
     * @param array $initConfig
263
     * @param bool $isPharMode
264
     * @param OutputInterface $output
265
     *
266
     * @return ConfigurationLoader
267
     */
268
    public function createLoader(array $initConfig, $isPharMode, OutputInterface $output)
269
    {
270
        $config = ArrayFunctions::mergeArrays($this->config, $initConfig);
271
272
        $loader = new ConfigurationLoader($config, $isPharMode, $output);
273
274
        return $loader;
275
    }
276
277
    /**
278
     * @param string $message
279
     */
280
    private function debugWriteln($message)
281
    {
282
        $output = $this->output;
283
        if (OutputInterface::VERBOSITY_DEBUG <= $output->getVerbosity()) {
284
            $output->writeln($message);
285
        }
286
    }
287
288
    /**
289
     * Get array from config, default to an empty array if not set
290
     *
291
     * @param string|array $key
292
     * @param array $default [optional]
293
     * @return array
294
     */
295
    private function getArray($key, $default = array())
296
    {
297
        $result = $this->traverse((array) $key);
298
        if (null === $result) {
299
            return $default;
300
        }
301
302
        return $result;
303
    }
304
305
    private function traverse(array $keys)
306
    {
307
        $anchor = &$this->config;
308
        foreach ($keys as $key) {
309
            if (!is_array($anchor)) {
310
                return;
311
            }
312
313
            if (!isset($anchor[$key])) {
314
                return;
315
            }
316
            $anchor = &$anchor[$key];
317
        }
318
319
        return $anchor;
320
    }
321
}
322