Completed
Push — develop ( ca40eb...664159 )
by Tom
04:30
created

Config   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 263
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 3
Bugs 1 Features 1
Metric Value
wmc 35
c 3
b 1
f 1
lcom 1
cbo 10
dl 0
loc 263
rs 9

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
B checkConfigCommandAlias() 0 27 5
A registerConfigCommandAlias() 0 17 4
A registerCustomCommands() 0 16 3
A registerCustomAutoloaders() 0 14 3
A setConfig() 0 4 1
A getConfig() 0 4 1
A setConfigurationLoader() 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 8 2
A traverse() 0 14 4
1
<?php
2
/*
3
 * @author Tom Klingenberg <[email protected]>
4
 */
5
6
namespace N98\Magento\Application;
7
8
use Composer\Autoload\ClassLoader;
9
use N98\Magento\Application;
10
use N98\Util\ArrayFunctions;
11
use N98\Util\BinaryString;
12
use Symfony\Component\Console\Command\Command;
13
use Symfony\Component\Console\Input\ArgvInput;
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Output\NullOutput;
16
use Symfony\Component\Console\Output\OutputInterface;
17
18
/**
19
 * Class Config
20
 *
21
 * Class representing the application configuration. Created to factor out configuration related application
22
 * functionality from @see N98\Magento\Application
23
 *
24
 * @package N98\Magento\Application
25
 */
26
class Config
27
{
28
    /**
29
     * @var array config data
30
     */
31
    private $config = array();
32
33
    /**
34
     * @var array
35
     */
36
    private $partialConfig = array();
37
38
    /**
39
     * @var ConfigurationLoader
40
     */
41
    private $loader;
42
43
    /**
44
     * @var array
45
     */
46
    private $initConfig;
47
48
    /**
49
     * @var boolean
50
     */
51
    private $isPharMode;
52
53
    /**
54
     * @var OutputInterface
55
     */
56
    private $output;
57
58
59
    /**
60
     * Config constructor.
61
     * @param array $initConfig
62
     * @param bool $isPharMode
63
     * @param OutputInterface $output [optional]
0 ignored issues
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...
64
     */
65
    public function __construct(array $initConfig = array(), $isPharMode = false, OutputInterface $output = null)
66
    {
67
        $this->initConfig = $initConfig;
68
        $this->isPharMode = (bool)$isPharMode;
69
        $this->output = $output ?: new NullOutput();
70
    }
71
72
    /**
73
     * alias magerun command in input from config
74
     *
75
     * @param InputInterface $input
76
     * @return ArgvInput|InputInterface
77
     */
78
    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...
79
    {
80
        foreach ($this->getArray(array('commands', 'aliases')) as $alias) {
81
            if (!is_array($alias)) {
82
                continue;
83
            }
84
            $aliasCommandName = key($alias);
85
            if ($input->getFirstArgument() !== $aliasCommandName) {
86
                continue;
87
            }
88
            $aliasCommandParams = array_slice(
89
                BinaryString::trimExplodeEmpty(' ', $alias[$aliasCommandName]),
90
                1
91
            );
92
            if (count($aliasCommandParams) > 0) {
93
                // replace with aliased data
94
                $mergedParams = array_merge(
95
                    array_slice($_SERVER['argv'], 0, 2),
96
                    $aliasCommandParams,
97
                    array_slice($_SERVER['argv'], 2)
98
                );
99
                $input = new ArgvInput($mergedParams);
100
            }
101
        }
102
103
        return $input;
104
    }
105
106
    /**
107
     * @param Command $command
108
     */
109
    public function registerConfigCommandAlias(Command $command)
110
    {
111
        foreach ($this->getArray(array('commands', 'aliases')) as $alias) {
112
            if (!is_array($alias)) {
113
                continue;
114
            }
115
116
            $aliasCommandName = key($alias);
117
            $commandString = $alias[$aliasCommandName];
118
            list($originalCommand) = explode(' ', $commandString, 2);
119
            if ($command->getName() !== $originalCommand) {
120
                continue;
121
            }
122
123
            $command->setAliases(array_merge($command->getAliases(), array($aliasCommandName)));
124
        }
125
    }
126
127
    /**
128
     * @param Application $application
129
     */
130
    public function registerCustomCommands(Application $application)
131
    {
132
        foreach ($this->getArray(array('commands', 'customCommands')) as $commandClass) {
133
            if (is_array($commandClass)) { // Support for key => value (name -> class)
134
                $resolvedCommandClass = current($commandClass);
135
                /** @var Command $command */
136
                $command = new $resolvedCommandClass();
137
                $command->setName(key($commandClass));
138
            } else {
139
                /** @var Command $command */
140
                $command = new $commandClass();
141
            }
142
            $this->debugWriteln(sprintf('<debug>Add command </debug><comment>%s</comment>', get_class($command)));
143
            $application->add($command);
144
        }
145
    }
146
147
    /**
148
     * Adds autoloader prefixes from user's config
149
     *
150
     * @param ClassLoader $autoloader
151
     */
152
    public function registerCustomAutoloaders(ClassLoader $autoloader)
153
    {
154
        $mask = '<debug>Registered %s autoloader </debug> <info>%s</info> -> <comment>%s</comment>';
155
156
        foreach ($this->getArray('autoloaders') as $prefix => $path) {
157
            $autoloader->add($prefix, $path);
158
            $this->debugWriteln(sprintf($mask, 'PSR-2', $prefix, $path));
159
        }
160
161
        foreach ($this->getArray('autoloaders_psr4') as $prefix => $path) {
162
            $autoloader->addPsr4($prefix, $path);
163
            $this->debugWriteln(sprintf($mask, 'PSR-4', $prefix, $path));
164
        }
165
    }
166
167
    /**
168
     * @param array $config
169
     */
170
    public function setConfig(array $config)
171
    {
172
        $this->config = $config;
173
    }
174
175
    /**
176
     * @return array
177
     */
178
    public function getConfig()
179
    {
180
        return $this->config;
181
    }
182
183
    /**
184
     * @param ConfigurationLoader $configurationLoader
185
     */
186
    public function setConfigurationLoader(ConfigurationLoader $configurationLoader)
187
    {
188
        $this->loader = $configurationLoader;
189
    }
190
191
    /**
192
     * @return ConfigurationLoader
193
     */
194
    public function getLoader()
195
    {
196
        if (!$this->loader) {
197
            $this->loader = $this->createLoader($this->initConfig, $this->isPharMode, $this->output);
198
            $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...
199
        }
200
201
        return $this->loader;
202
    }
203
204
    public function load()
205
    {
206
        $this->config = $this->getLoader()->toArray();
207
    }
208
209
    /**
210
     * @param bool $loadExternalConfig
211
     */
212
    public function loadPartialConfig($loadExternalConfig)
213
    {
214
        $loader = $this->getLoader();
215
        $this->partialConfig = $loader->getPartialConfig($loadExternalConfig);
216
    }
217
218
    /**
219
     * Get names of sub-folders to be scanned during Magento detection
220
     * @return array
221
     */
222
    public function getDetectSubFolders()
223
    {
224
        if (isset($this->partialConfig['detect']['subFolders'])) {
225
            return $this->partialConfig['detect']['subFolders'];
226
        }
227
228
        return array();
229
    }
230
231
    /**
232
     * @param array $initConfig
233
     * @param bool $isPharMode
234
     * @param OutputInterface $output
235
     *
236
     * @return ConfigurationLoader
237
     */
238
    public function createLoader(array $initConfig, $isPharMode, OutputInterface $output)
239
    {
240
        $config = ArrayFunctions::mergeArrays($this->config, $initConfig);
241
242
        $loader = new ConfigurationLoader($config, $isPharMode, $output);
243
244
        return $loader;
245
    }
246
247
    /**
248
     * @param string $message
249
     */
250
    private function debugWriteln($message)
251
    {
252
        $output = $this->output;
253
        if (OutputInterface::VERBOSITY_DEBUG <= $output->getVerbosity()) {
254
            $output->writeln($message);
255
        }
256
    }
257
258
    /**
259
     * Get array from config, default to an empty array if not set
260
     *
261
     * @param string|array $key
262
     * @param array $default [optional]
263
     * @return array
264
     */
265
    private function getArray($key, $default = array())
266
    {
267
        $result = $this->traverse((array)$key);
268
        if (null === $result) {
269
            return $default;
270
        }
271
        return $result;
272
    }
273
274
    private function traverse(array $keys)
275
    {
276
        $anchor = &$this->config;
277
        foreach ($keys as $key) {
278
            if (!isset($anchor[$key])) {
279
                return null;
280
            }
281
            $anchor = &$anchor[$key];
282
            if (!is_array($anchor)) {
283
                return null;
284
            }
285
        }
286
        return $anchor;
287
    }
288
}
289