Completed
Pull Request — master (#148)
by
unknown
03:22
created

Config   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 244
Duplicated Lines 0 %

Coupling/Cohesion

Dependencies 2

Importance

Changes 19
Bugs 13 Features 2
Metric Value
wmc 37
c 19
b 13
f 2
cbo 2
dl 0
loc 244
rs 8.6

18 Methods

Rating   Name   Duplication   Size   Complexity  
C __construct() 0 23 7
A getScripts() 0 4 1
A getBasePackagesUrl() 0 4 1
A getAllPackagesUrl() 0 4 1
A getCacheDir() 0 4 1
A getInstallDir() 0 4 1
A isSaveToBowerJsonFile() 0 4 1
A setSaveToBowerJsonFile() 0 4 1
A initBowerJsonFile() 0 7 1
A updateBowerJsonFile() 0 13 2
A updateBowerJsonFile2() 0 7 1
A getBowerFileContent() 0 12 4
A getOverridesSection() 0 11 4
A getOverrideFor() 0 9 2
A getPackageBowerFileContent() 0 14 3
A bowerFileExists() 0 4 1
A createAClearBowerFile() 0 14 1
A getHomeDir() 0 17 4
1
<?php
2
3
/*
4
 * This file is part of Bowerphp.
5
 *
6
 * (c) Massimiliano Arione <[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
12
namespace Bowerphp\Config;
13
14
use Bowerphp\Package\PackageInterface;
15
use Bowerphp\Util\Filesystem;
16
use RuntimeException;
17
18
/**
19
 * Config
20
 */
21
class Config implements ConfigInterface
22
{
23
    protected $cacheDir;
24
    protected $installDir;
25
    protected $filesystem;
26
    protected $basePackagesUrl = 'http://bower.herokuapp.com/packages/';
27
    protected $allPackagesUrl = 'https://bower-component-list.herokuapp.com/';
28
    protected $saveToBowerJsonFile = false;
29
    protected $bowerFileNames = ['bower.json', 'package.json'];
30
    protected $stdBowerFileName = 'bower.json';
31
    protected $scripts = ['preinstall'=>[],'postinstall'=>[],'preuninstall'=>[]];
32
33
    /**
34
     * @param Filesystem $filesystem
35
     */
36
    public function __construct(Filesystem $filesystem)
37
    {
38
        $this->filesystem = $filesystem;
39
        $this->cacheDir = $this->getHomeDir() . '/.cache/bowerphp';
40
        $this->installDir = getcwd() . '/bower_components';
41
        $rc = getcwd() . '/.bowerrc';
42
        if ($this->filesystem->exists($rc)) {
43
            $json = json_decode($this->filesystem->read($rc), true);
44
            if (is_null($json)) {
45
                throw new RuntimeException('Invalid .bowerrc file.');
46
            }
47
            if (isset($json['directory'])) {
48
                $this->installDir = getcwd() . '/' . $json['directory'];
49
            }
50
            if (isset($json['storage']) && isset($json['storage']['packages'])) {
51
                $this->cacheDir = $json['storage']['packages'];
52
            }
53
            if (isset($json['scripts'])){
54
				$this->scripts = (array)$json['scripts']+$this->scripts;
55
			}
56
			
57
        }
58
    }
59
	
60
	/**
61
     * {@inheritdoc}
62
     */
63
    public function getScripts()
64
    {
65
        return $this->scripts;
66
    }
67
	
68
    /**
69
     * {@inheritdoc}
70
     */
71
    public function getBasePackagesUrl()
72
    {
73
        return $this->basePackagesUrl;
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79
    public function getAllPackagesUrl()
80
    {
81
        return $this->allPackagesUrl;
82
    }
83
84
    /**
85
     * {@inheritdoc}
86
     */
87
    public function getCacheDir()
88
    {
89
        return $this->cacheDir;
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95
    public function getInstallDir()
96
    {
97
        return $this->installDir;
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103
    public function isSaveToBowerJsonFile()
104
    {
105
        return $this->saveToBowerJsonFile;
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     */
111
    public function setSaveToBowerJsonFile($flag = true)
112
    {
113
        $this->saveToBowerJsonFile = $flag;
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function initBowerJsonFile(array $params)
120
    {
121
        $file = getcwd() . '/' . $this->stdBowerFileName;
122
        $json = json_encode($this->createAClearBowerFile($params), JSON_PRETTY_PRINT);
123
124
        return $this->filesystem->write($file, $json);
125
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130
    public function updateBowerJsonFile(PackageInterface $package)
131
    {
132
        if (!$this->isSaveToBowerJsonFile()) {
133
            return 0;
134
        }
135
136
        $decode = $this->getBowerFileContent();
137
        $decode['dependencies'][$package->getName()] = $package->getRequiredVersion();
138
        $file = getcwd() . '/' . $this->stdBowerFileName;
139
        $json = json_encode($decode, JSON_PRETTY_PRINT);
140
141
        return $this->filesystem->write($file, $json);
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147
    public function updateBowerJsonFile2(array $old, array $new)
148
    {
149
        $json = json_encode(array_merge($old, $new), JSON_PRETTY_PRINT);
150
        $file = getcwd() . '/' . $this->stdBowerFileName;
151
152
        return $this->filesystem->write($file, $json);
153
    }
154
155
    /**
156
     * {@inheritdoc}
157
     */
158
    public function getBowerFileContent()
159
    {
160
        if (!$this->bowerFileExists()) {
161
            throw new RuntimeException('No ' . $this->stdBowerFileName . ' found. You can run "init" command to create it.');
162
        }
163
        $bowerJson = $this->filesystem->read(getcwd() . '/' . $this->stdBowerFileName);
164
        if (empty($bowerJson) || !is_array($decode = json_decode($bowerJson, true))) {
165
            throw new RuntimeException(sprintf('Malformed JSON in %s: %s.', $this->stdBowerFileName, $bowerJson));
166
        }
167
168
        return $decode;
169
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174
    public function getOverridesSection()
175
    {
176
        if ($this->bowerFileExists()) {
177
            $bowerData = $this->getBowerFileContent();
178
            if ($bowerData && array_key_exists('overrides', $bowerData)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $bowerData of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
179
                return $bowerData['overrides'];
180
            }
181
        }
182
183
        return [];
184
    }
185
186
    /**
187
     * {@inheritdoc}
188
     */
189
    public function getOverrideFor($packageName)
190
    {
191
        $overrides = $this->getOverridesSection();
192
        if (array_key_exists($packageName, $overrides)) {
193
            return $overrides[$packageName];
194
        }
195
196
        return [];
197
    }
198
199
    /**
200
     * {@inheritdoc}
201
     */
202
    public function getPackageBowerFileContent(PackageInterface $package)
203
    {
204
        $file = $this->getInstallDir() . '/' . $package->getName() . '/.bower.json';
205
        if (!$this->filesystem->exists($file)) {
206
            throw new RuntimeException(sprintf('Could not find .bower.json file for package %s.', $package->getName()));
207
        }
208
        $bowerJson = $this->filesystem->read($file);
209
        $bower = json_decode($bowerJson, true);
210
        if (is_null($bower)) {
211
            throw new RuntimeException(sprintf('Invalid content in .bower.json for package %s.', $package->getName()));
212
        }
213
214
        return $bower;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $bower; (object|integer|double|string|array|boolean) is incompatible with the return type declared by the interface Bowerphp\Config\ConfigIn...PackageBowerFileContent of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
215
    }
216
217
    /**
218
     * {@inheritdoc}
219
     */
220
    public function bowerFileExists()
221
    {
222
        return $this->filesystem->exists(getcwd() . '/' . $this->stdBowerFileName);
223
    }
224
225
    /**
226
     * @param  array $params
227
     * @return array
228
     */
229
    protected function createAClearBowerFile(array $params)
230
    {
231
        $structure = [
232
            'name'    => $params['name'],
233
            'authors' => [
234
                0 => 'Beelab <[email protected]>',
235
                1 => $params['author'],
236
            ],
237
            'private'      => true,
238
            'dependencies' => new \StdClass(),
239
        ];
240
241
        return $structure;
242
    }
243
244
    /**
245
     * @return string
246
     */
247
    protected function getHomeDir()
248
    {
249
        if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
250
            $appData = getenv('APPDATA');
251
            if (empty($appData)) {
252
                throw new \RuntimeException('The APPDATA environment variable must be set for bowerphp to run correctly');
253
            }
254
255
            return strtr($appData, '\\', '/');
256
        }
257
        $home = getenv('HOME');
258
        if (empty($home)) {
259
            throw new \RuntimeException('The HOME environment variable must be set for bowerphp to run correctly');
260
        }
261
262
        return rtrim($home, '/');
263
    }
264
}
265