Completed
Pull Request — master (#34)
by Edgard
02:17
created

AssetPackage::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
ccs 0
cts 4
cp 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
/**
3
 * Asset Packagist.
4
 *
5
 * @see      https://github.com/hiqdev/asset-packagist
6
 * @package   asset-packagist
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2016-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\assetpackagist\models;
12
13
use Composer\Composer;
14
use Composer\Factory;
15
use Composer\IO\NullIO;
16
use Composer\Package\Link;
17
use Exception;
18
use Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository;
19
use hiqdev\assetpackagist\components\Storage;
20
use hiqdev\assetpackagist\registry\BowerRegistry;
21
use hiqdev\assetpackagist\registry\NpmRegistry;
22
use hiqdev\assetpackagist\registry\RegistryFactory;
23
use Yii;
24
use yii\base\Object;
25
26
class AssetPackage extends Object
27
{
28
    protected $_type;
29
    protected $_name;
30
    protected $_hash;
31
    /**
32
     * @var array
33
     */
34
    protected $_releases = [];
35
    protected $_saved;
36
    /**
37
     * @var AssetVcsRepository|BowerRegistry|NpmRegistry
38
     */
39
    protected $_registry;
40
41
    /**
42
     * @var integer UNIX Epoch timestamp of the latest package update
43
     */
44
    protected $_updateTime;
45
46
    /**
47
     * @var NullIO
48
     */
49
    protected $_io;
50
    /**
51
     * @var Composer
52
     */
53
    protected $_composer;
54
    /**
55
     * @var Composer
56
     */
57
    protected static $_commonComposer;
58
59
    public static function normalizeName($name)
60
    {
61
        return strtolower($name);
62 1
    }
63
64 1
    /**
65
     * AssetPackage constructor.
66 1
     * @param string $type
67
     * @param string $name
68
     * @param array $config
69 1
     * @throws Exception
70
     */
71
    public function __construct($type, $name, $config = [])
72 1
    {
73 1
        parent::__construct($config);
74 1
75
        if (!$this->checkType($type)) {
76
            throw new Exception('wrong type');
77
        }
78
        if (!$this->checkName($name)) {
79
            throw new Exception('wrong name');
80
        }
81
        $this->_type = $type;
82
        $this->_name = $name;
83
    }
84
85 1
    public function getRegistry()
86
    {
87 1
        if ($this->_registry === null) {
88
            $this->_registry = RegistryFactory::getRegistry($this->getType(), $this->getComposer()->getRepositoryManager());
0 ignored issues
show
Documentation Bug introduced by
It seems like \hiqdev\assetpackagist\r...getRepositoryManager()) of type object<Fxp\Composer\Asse...stractAssetsRepository> is incompatible with the declared type object<Fxp\Composer\Asse...t\registry\NpmRegistry> of property $_registry.

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...
89
        }
90 1
91
        return $this->_registry;
92 1
    }
93
94
    public function checkType($type)
95 1
    {
96
        return $type === 'bower' || $type === 'npm';
97 1
    }
98
99
    public function checkName($name)
100 1
    {
101
        return strlen($name) > 0;
102 1
    }
103
104
    public function getFullName()
105
    {
106
        return static::buildFullName($this->_type, $this->_name);
107
    }
108
109
    public static function buildFullName($type, $name)
110
    {
111
        return $type . '-asset/' . $name;
112
    }
113
114
    public static function splitFullName($full)
115
    {
116
        list($temp, $name) = explode('/', $full);
117
        list($type) = explode('-', $temp);
118
119
        return [$type, $name];
120
    }
121
122
    /**
123
     * @param string $full package name
124
     * @return static
125
     */
126
    public static function fromFullName($full)
127
    {
128
        list($type, $name) = static::splitFullName($full);
129
        return new static($type, $name);
130
    }
131
132
    public function getType()
133
    {
134
        return $this->_type;
135
    }
136
137
    public function getNormalName()
138
    {
139
        return static::buildFullName($this->_type, static::normalizeName($this->_name));
140
    }
141
142
    public function getName()
143
    {
144
        return $this->_name;
145
    }
146
147
    public function getHash()
148
    {
149
        return $this->_hash;
150
    }
151
152
    /**
153
     * @return Composer
154
     */
155
    public static function getCommonComposer()
156
    {
157
        if (static::$_commonComposer === null) {
158
            static::$_commonComposer = (new Factory())->createComposer(
159
                new NullIO(),
160
                Yii::getAlias('@composer/composer.json'),
0 ignored issues
show
Bug introduced by
It seems like \Yii::getAlias('@composer/composer.json') targeting yii\BaseYii::getAlias() can also be of type boolean; however, Composer\Factory::createComposer() does only seem to accept array|string|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
161
                false,
162
                Yii::getAlias('@composer')
163
            );
164
        }
165
166
        return static::$_commonComposer;
167
    }
168
169
    public function setComposer($value)
170
    {
171
        $this->_composer = $value;
172
    }
173
174
    /**
175
     * @return Composer
176
     */
177
    public function getComposer()
178
    {
179
        if ($this->_composer === null) {
180
            $this->_composer = static::getCommonComposer();
181
        }
182
183
        return $this->_composer;
184
    }
185
186
    public function getIO()
187
    {
188
        if ($this->_io === null) {
189
            $this->_io = new NullIO();
190
        }
191
192
        return $this->_io;
193
    }
194
195
    /**
196
     * findOne.
197
     *
198
     * @param string $type
199
     * @param string $name
200
     * @return static|null
201
     */
202
    public static function findOne($type, $name)
203
    {
204
        $package = new static($type, $name);
205
        $package->load();
206
207
        return $package;
208
    }
209
210
    public function load()
211
    {
212
        $data = $this->getStorage()->readPackage($this);
213
        if ($data !== null) {
214
            $this->_hash = $data['hash'];
215
            $this->_releases = $data['releases'];
216
            $this->_updateTime = $data['updateTime'];
217
        }
218
    }
219
220
    public function update()
221
    {
222
        $repo = $this->getRegistry()->buildVcsRepository($this->getName());
223
        $this->_releases = $this->prepareReleases($repo);
224
        $this->getStorage()->writePackage($this);
225
        $this->load();
226
    }
227
228
    /**
229
     * @param AssetVcsRepository $repository
230
     * @return array
231
     */
232
    public function prepareReleases($repository)
233
    {
234
        $releases = [];
235
236
        /* @var $package \Fxp\Composer\AssetPlugin\Package\AbstractLazyCompletePackage */
237
        foreach ($repository->getPackages() as $package) {
238
            $version = $package->getPrettyVersion();
239
            $require = $this->prepareRequire($package->getRequires());
240
            $type = $this->getType() . '-asset';
241
            $release = [
242
                'uid' => $this->prepareUid($version),
243
                'name' => $this->getNormalName(),
244
                'version' => $version,
245
                'version_normalized' => $package->getVersion(),
246
                'type' => $type,
247
            ];
248
            if ($require) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $require 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...
249
                $release['require'] = $require;
250
            }
251
            if ($package->getExtra()) {
252
                //Remove bower-asset* and npm-asset* attributes
253
                $extra = array_filter($package->getExtra(), function($key) use ($type) {
254
                    return strncmp($type, $key, strlen($type)) !== 0;
255
                }, ARRAY_FILTER_USE_KEY);
256
                
257
                if (!empty($extra)) {
258
                    $release['extra'] = $extra;
259
                }
260
            }
261
            if ($package->getDistUrl()) {
262
                $release['dist'] = [
263
                    'type' => $package->getDistType(),
264
                    'url' => $package->getDistUrl(),
265
                    'reference' => $package->getDistReference(),
266
                ];
267
            }
268
            if ($package->getSourceUrl()) {
269
                $release['source'] = [
270
                    'type' => $package->getSourceType(),
271
                    'url' => $package->getSourceUrl(),
272
                    'reference' => $package->getSourceReference(),
273
                ];
274
            }
275
            if ((isset($release['dist']) && $release['dist']) || (isset($release['source']) && $release['source'])) {
276
                $releases[$version] = $release;
277
            }
278
        }
279
280
        return $releases;
281
    }
282
283
    /**
284
     * Prepares array of requires: name => constraint.
285
     * @param Link[] array of package requires
286
     * @return array
287
     */
288
    public function prepareRequire(array $links)
289
    {
290
        $requires = [];
291
        foreach ($links as $name => $link) {
292
            /** @var Link $link */
293
            $requires[$name] = $link->getPrettyConstraint();
294
        }
295
296
        return $requires;
297
    }
298
299
    public function prepareUid($version)
300
    {
301
        $known = $this->getSaved()->getRelease($version);
302
303
        return isset($known['uid']) ? $known['uid'] : $this->getStorage()->getNextId();
304
    }
305
306
    /**
307
     * @return array
308
     */
309
    public function getReleases()
310
    {
311
        return $this->_releases;
312
    }
313
314
    /**
315
     * @param $version
316
     * @return array
317
     */
318
    public function getRelease($version)
319
    {
320
        return isset($this->_releases[$version]) ? $this->_releases[$version] : [];
321
    }
322
323
    public function getSaved()
324
    {
325
        if ($this->_saved === null) {
326
            $this->_saved = static::findOne($this->getType(), $this->getName());
327
        }
328
329
        return $this->_saved;
330
    }
331
332
    /**
333
     * @return Storage
334
     */
335
    public function getStorage()
336
    {
337
        return Yii::$app->get('packageStorage');
338
    }
339
340
    /**
341
     * Returns the latest update time (UNIX Epoch).
342
     * @return int|null
343
     */
344
    public function getUpdateTime()
345
    {
346
        return $this->_updateTime;
347
    }
348
349
    /**
350
     * Package can be updated not more often than once in 10 min.
351
     * @return bool
352
     */
353
    public function canBeUpdated()
354
    {
355
        return time() - $this->getUpdateTime() > 60 * 10; // 10 min
356
    }
357
358
    /**
359
     * Whether tha package should be auth-updated (if it is older than 1 day).
360
     * @return bool
361
     */
362
    public function canAutoUpdate()
363
    {
364
        return time() - $this->getUpdateTime() > 60 * 60 * 24; // 1 day
365
    }
366
367
    /**
368
     * @return array
369
     */
370
    public function __sleep()
371
    {
372
        return ['_type', '_name', '_hash'];
373
    }
374
}
375