GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 7dd4fa...6a3c70 )
by Miles
07:33
created

Vars   B

Complexity

Total Complexity 42

Size/Duplication

Total Lines 359
Duplicated Lines 4.46 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 100%

Importance

Changes 7
Bugs 2 Features 2
Metric Value
wmc 42
c 7
b 2
f 2
lcom 1
cbo 5
dl 16
loc 359
ccs 126
cts 126
cp 1
rs 8.2951

17 Methods

Rating   Name   Duplication   Size   Complexity  
A getResources() 0 4 1
B __construct() 0 24 3
B parseOptions() 0 22 5
A makeCache() 0 5 1
A makePaths() 0 9 3
A makeLoader() 0 5 1
A makeVariables() 0 14 3
A loadFromCache() 0 23 3
A getBasePath() 0 4 1
A setBasePath() 16 16 3
A addResource() 0 7 1
A updateResource() 0 5 1
B resourceImported() 0 11 6
A getResource() 0 10 3
A getVariables() 0 4 1
A getCache() 0 4 1
B pathsLoadedCheck() 0 18 5

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Vars often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Vars, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * This file is part of the m1\vars library
5
 *
6
 * (c) m1 <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * @package     m1/vars
12
 * @version     0.1.0
13
 * @author      Miles Croxford <[email protected]>
14
 * @copyright   Copyright (c) Miles Croxford <[email protected]>
15
 * @license     http://github.com/m1/vars/blob/master/LICENSE
16
 * @link        http://github.com/m1/vars/blob/master/README.MD Documentation
17
 */
18
19
namespace M1\Vars;
20
21
use M1\Vars\Cache\CacheProvider;
22
use M1\Vars\Loader\LoaderProvider;
23
use M1\Vars\Resource\AbstractResource;
24
use M1\Vars\Resource\ResourceProvider;
25
use M1\Vars\Resource\VariableResource;
26
27
/**
28
 * Vars core class
29
 *
30
 * @since 0.1.0
31
 */
32
class Vars extends AbstractResource
33
{
34
    /**
35
     * The base path for the Vars config and cache folders
36
     *
37
     * @var string $base_path
38
     */
39
    private $base_path;
40
41
    /**
42
     * The cache object if the cache is wanted, else false
43
     *
44
     * @var \M1\Vars\Cache\CacheProvider $cache
45
     */
46
    public $cache;
47
48
    /**
49
     * The default options for Vars
50
     *
51
     * @var array $default_options
52
     */
53
    private $default_options = array(
54
        'base_path' => null,
55
        'cache' => true,
56
        'cache_path' => null,
57
        'cache_expire' => 300, // 5 minutes
58
        'loaders' => array('ini', 'json', 'php', 'toml', 'yaml', 'xml',)
59
    );
60
61
    /**
62
     * The loaderProvider for Vars supplies the file loaders and the extensions that are supported
63
     *
64
     * @var \M1\Vars\Loader\LoaderProvider $loader
65
     */
66
    public $loader;
67
68
    /**
69
     * Have the base and cache paths been set
70
     *
71
     * @var bool $paths_loaded
72
     */
73
    private $paths_loaded = false;
74
75
    /**
76
     * The imported resources
77
     *
78
     * @var array $resources
79
     */
80
    private $resources = array();
81
82
    /**
83
     * The words to be replaced in the config files
84
     *
85
     * @var array $variables
86
     */
87
    private $variables = array();
88
89
    /**
90
     * Creates a new instance of Vars
91
     *
92
     * @param string|array $resource The main configuration resource
93
     * @param array        $options  The options being used for Vars
94
     */
95 66
    public function __construct($resource, $options = array())
96
    {
97 66
        $options = $this->parseOptions($options);
98 66
        $this->makeCache($options, $resource);
99 65
        $this->makePaths($options);
100
101 64
        if (!$this->cache->checkCache()) {
102 64
            $this->makeLoader($options);
103 62
            $this->makeVariables($options);
104
105 61
            $resource = new ResourceProvider($this, $resource);
106 49
        }
107
108 49
        if ($this->cache->isHit()) {
109 2
            $this->loadFromCache();
110 2
        } else {
111 49
            $resource->mergeParentContent();
0 ignored issues
show
Bug introduced by
It seems like $resource is not always an object, but can also be of type string|array. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
112 49
            $this->content = $resource->getContent();
113
114 49
            $this->cache->setTime(time());
115 49
            $this->cache->makeCache($this);
116
117
        }
118 49
    }
119
120
    /**
121
     * Parses the options so Vars can use them
122
     *
123
     * @param array $options  The options being used for Vars
124
     *
125
     * @return array The parsed options
126
     */
127 66
    private function parseOptions(array $options)
128
    {
129 66
        $parsed_options = array_merge($this->default_options, $options);
130
131 66
        if (isset($options['loaders'])) {
132 8
            $loaders = array();
133
134 8
            if (is_array($options['loaders']) && !empty($options['loaders'])) {
135 3
                $loaders = $options['loaders'];
136 8
            } elseif (is_string($options['loaders'])) {
137 4
                $loaders[] = $options['loaders'];
138 4
            } else {
139 1
                $loaders = $this->default_options['loaders'];
140
            }
141
142 8
            $parsed_options['loaders'] = $loaders;
143 8
        } else {
144 58
            $parsed_options['loaders'] = $this->default_options['loaders'];
145
        }
146
147 66
        return $parsed_options;
148
    }
149
150
    /**
151
     * Makes the CacheProvider with the options
152
     *
153
     * @param array        $options  The options being used for Vars
154
     * @param array|string $resource The main configuration resource
155
     */
156 66
    private function makeCache($options, $resource)
157
    {
158 66
        $cache = new CacheProvider($resource, $options);
159 65
        $this->cache = $cache;
160 65
    }
161
162
    /**
163
     * Sets the base path if the options have been set and the cache path if the cache path has not been set but the
164
     * base path has
165
     *
166
     * @param array $options The options being used for Vars
167
     */
168 65
    private function makePaths($options)
169
    {
170 65
        $this->setBasePath($options['base_path']);
171
172 64
        if (is_null($options['cache_path']) && !is_null($options['base_path'])) {
173 1
            $this->cache->setPath($options['base_path']);
174 1
            $this->paths_loaded = true;
175 1
        }
176 64
    }
177
178
    /**
179
     * Makes the LoaderProvider with the options
180
     *
181
     * @param array $options  The options being used for Vars
182
     */
183 64
    private function makeLoader($options)
184
    {
185 64
        $loader = new LoaderProvider($options, $this->default_options['loaders']);
186 62
        $this->loader = $loader;
187 62
    }
188
    /**
189
     * Sets the replacement variables if the option has been set
190
     *
191
     * @param array|null $options The options being used for Vars
192
     */
193 62
    private function makeVariables($options)
194
    {
195 62
        if (isset($options['variables'])) {
196 4
            $variables = new VariableResource($this, $options['variables']);
197
198 3
            $v = array();
199
200 3
            foreach ($variables->getVariables() as $variable_key => $variable_value) {
201 3
                $v["%".$variable_key.'%'] = $variable_value;
202 3
            }
203
204 3
            $this->variables = $v;
205 3
        }
206 61
    }
207
208
    /**
209
     * Loads the cached file into the current class
210
     */
211 2
    private function loadFromCache()
212
    {
213 2
        $this->cache->load();
214
215
        $passed_keys = array(
216 2
            'base_path',
217 2
            'content',
218 2
            'extensions',
219 2
            'loaders',
220 2
            'resources',
221 2
            'variables',
222 2
        );
223
224 2
        $loaded_vars = get_object_vars($this->cache->getLoadedVars());
225
226 2
        foreach ($loaded_vars as $key => $value) {
227 2
            if (in_array($key, $passed_keys)) {
228 2
                $this->$key = $value;
229 2
            }
230 2
        }
231
232 2
        $this->cache->setTime($loaded_vars['cache']->getTime());
233 2
    }
234
235
    /**
236
     * Checks if the base and cache paths have been set, if not set then will use the $resource as the base path
237
     *
238
     * @param string $resource The resource to use to set the paths if they haven't been set
239
     */
240 56
    public function pathsLoadedCheck($resource)
241
    {
242 56
        if (!$this->paths_loaded) {
243 55
            $base_path = $this->getBasePath();
244
245 55
            if (!$base_path) {
246 53
                $file = pathinfo(realpath($resource));
247 53
                $base_path = $file['dirname'];
248 53
                $this->setBasePath($base_path);
249 53
            }
250
251 55
            if ($this->cache->getProvide() && !$this->cache->getPath()) {
252 1
                $this->cache->setPath($base_path);
253 1
            }
254
255 55
            $this->paths_loaded = true;
256 55
        }
257 56
    }
258
259
    /**
260
     * Get the Vars base path
261
     *
262
     * @return string The Vars base path
263
     */
264 56
    public function getBasePath()
265
    {
266 56
        return $this->base_path;
267
    }
268
269
    /**
270
     * Set the Vars base path
271
     *
272
     * @param string $base_path The base path to set
273
     *
274
     * @throws \InvalidArgumentException If the base path does not exist or is not writable
275
     *
276
     * @return \M1\Vars\Vars
277
     */
278 65 View Code Duplication
    public function setBasePath($base_path)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
279
    {
280 65
        if (is_null($base_path)) {
281 61
            return;
282
        }
283
284 57
        if (!is_dir($base_path)) {
285 1
            throw new \InvalidArgumentException(sprintf(
286 1
                "'%s' base path does not exist or is not writable",
287
                $base_path
288 1
            ));
289
        }
290
291 56
        $this->base_path = realpath($base_path);
292 56
        return $this;
293
    }
294
    
295
    /**
296
     * Adds a resource to $this->resources
297
     *
298
     * @param string $resource Resource to add to the stack
299
     *
300
     * @return int The position of the added resource
301
     */
302 56
    public function addResource($resource)
303
    {
304 56
        $r = realpath($resource);
305 56
        $pos = count($this->resources);
306 56
        $this->resources[$pos] = $r;
307 56
        return $pos;
308
    }
309
310
    /**
311
     * Updates the string resource with the FileResource
312
     *
313
     * @param \M1\Vars\Resource\FileResource $resource The FileResource to add
314
     * @param int                            $pos      The position of the string resource
315
     *
316
     * @return \M1\Vars\Vars
317
     */
318 48
    public function updateResource($resource, $pos)
319
    {
320 48
        $this->resources[$pos] = $resource;
321 48
        return $this;
322
    }
323
324
    /**
325
     * Tests to see if the resource has been imported already -- this is to avoid getting into a infinite loop
326
     *
327
     * @param \M1\Vars\Resource\FileResource|string $resource Resource to check
328
     *
329
     * @return bool Has resource already been imported
330
     */
331 56
    public function resourceImported($resource)
332
    {
333 56
        $resource = realpath($resource);
334 56
        foreach ($this->getResources() as $r) {
335 36
            if ((is_a($r, 'M1\Vars\Resource\FileResource') && $resource === $r->getFile()) ||
336 36
                (is_string($r) && $resource === $r)) {
337 1
                return true;
338
            }
339 56
        }
340 56
        return false;
341
    }
342
343
    /**
344
     * Searches the resource stack for a certain resource
345
     *
346
     * @param string $resource The resource to search for
347
     *
348
     * @return bool Returns the resource if found
349
     */
350 3
    public function getResource($resource)
351
    {
352 3
        foreach ($this->getResources() as $r) {
353 3
            if ($resource === $r->getFilename()) {
354 2
                return $r;
355
            }
356 3
        }
357
358 1
        return false;
359
    }
360
361
    /**
362
     * Returns the imported resources
363
     *
364
     * @return array The Vars imported resources
365
     */
366 56
    public function getResources()
367
    {
368 56
        return $this->resources;
369
    }
370
371
    /**
372
     * Returns the Vars replacement variables
373
     *
374
     * @return array The Vars replacement variables
375
     */
376 43
    public function getVariables()
377
    {
378 43
        return $this->variables;
379
    }
380
381
    /**
382
     * Returns the CacheProvider if set, if not return false
383
     *
384
     * @return \M1\Vars\Cache\CacheProvider|false The CacheProvider or false
385
     */
386 6
    public function getCache()
387
    {
388 6
        return $this->cache;
389
    }
390
}
391