Completed
Push — master ( 41033a...b5b2fa )
by Andrii
06:05 queued 03:01
created

AssetPackage::splitFullName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 7
ccs 0
cts 0
cp 0
rs 9.4285
cc 1
eloc 4
nc 1
nop 1
crap 2
1
<?php
2
3
/*
4
 * Asset Packagist
5
 *
6
 * @link      https://github.com/hiqdev/asset-packagist
7
 * @package   asset-packagist
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2016, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hiqdev\assetpackagist\models;
13
14
use Composer\Composer;
15
use Composer\Factory;
16
use Composer\IO\NullIO;
17
use Composer\Package\Link;
18
use Exception;
19
use Fxp\Composer\AssetPlugin\Repository\AssetVcsRepository;
20
use hiqdev\assetpackagist\components\Storage;
21
use hiqdev\assetpackagist\registry\BowerRegistry;
22
use hiqdev\assetpackagist\registry\NpmRegistry;
23
use hiqdev\assetpackagist\registry\RegistryFactory;
24
use Yii;
25
use yii\base\Object;
26
27
class AssetPackage extends Object
28
{
29
    protected $_type;
30
    protected $_name;
31
    protected $_hash;
32
    protected $_releases = [];
33
    protected $_saved;
34
    /**
35
     * @var AssetVcsRepository|BowerRegistry|NpmRegistry
36
     */
37
    protected $_registry;
38
39
    /**
40
     * @var integer UNIX Epoch timestamp of the latest package update
41
     */
42
    protected $_updateTime;
43
44
    /**
45
     * @var NullIO
46
     */
47
    protected $_io;
48
    /**
49
     * @var Composer
50
     */
51
    protected $_composer;
52
    /**
53
     * @var Composer
54
     */
55
    protected static $_commonComposer;
56
57
    public static function normalizeName($name)
58
    {
59
        return strtolower($name);
60
    }
61
62 1
    public function __construct($type, $name, $config = [])
63
    {
64 1
        parent::__construct($config);
65
66 1
        if (!$this->checkType($type)) {
67
            throw new Exception('wrong type');
68
        }
69 1
        if (!$this->checkName($name)) {
70
            throw new Exception('wrong name');
71
        }
72 1
        $this->_type = $type;
73 1
        $this->_name = $name;
74 1
    }
75
76
    public function getRegistry()
77
    {
78
        if ($this->_registry === null) {
79
            $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...
80
        }
81
82
        return $this->_registry;
83
    }
84
85 1
    public function checkType($type)
86
    {
87 1
        return $type === 'bower' || $type === 'npm';
88
    }
89
90 1
    public function checkName($name)
91
    {
92 1
        return strlen($name) > 0;
93
    }
94
95 1
    public function getFullName()
96
    {
97 1
        return static::buildFullName($this->_type, $this->_name);
98
    }
99
100 1
    public static function buildFullName($type, $name)
101
    {
102 1
        return $type . '-asset/' . $name;
103
    }
104
105
    public static function splitFullName($full)
106
    {
107
        list($temp, $name) = explode('/', $full);
108
        list($type) = explode('-', $temp);
109
110
        return [$type, $name];
111
    }
112
113
    public function getType()
114
    {
115
        return $this->_type;
116
    }
117
118
    public function getNormalName()
119
    {
120
        return static::buildFullName($this->_type, static::normalizeName($this->_name));
121
    }
122
123
    public function getName()
124
    {
125
        return $this->_name;
126
    }
127
128
    public function getHash()
129
    {
130
        return $this->_hash;
131
    }
132
133
    /**
134
     * @return Composer
135
     */
136
    public static function getCommonComposer()
137
    {
138
        if (static::$_commonComposer === null) {
139
            static::$_commonComposer = (new Factory())->createComposer(
140
                new NullIO(),
141
                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...
142
                false,
143
                Yii::getAlias('@composer')
144
            );
145
        }
146
147
        return static::$_commonComposer;
148
    }
149
150
    public function setComposer($value)
151
    {
152
        $this->_composer = $value;
153
    }
154
155
    /**
156
     * @return Composer
157
     */
158
    public function getComposer()
159
    {
160
        if ($this->_composer === null) {
161
            $this->_composer = static::getCommonComposer();
162
        }
163
164
        return $this->_composer;
165
    }
166
167
    public function getIO()
168
    {
169
        if ($this->_io === null) {
170
            $this->_io = new NullIO();
171
        }
172
173
        return $this->_io;
174
    }
175
176
    /**
177
     * findOne.
178
     *
179
     * @param string $type
180
     * @param string $name
181
     * @return static|null
182
     */
183
    public static function findOne($type, $name)
184
    {
185
        $package = new static($type, $name);
186
        $package->load();
187
188
        return $package;
189
    }
190
191
    public function load()
192
    {
193
        $data = $this->getStorage()->readPackage($this);
194
        if ($data !== null) {
195
            $this->_hash = $data['hash'];
196
            $this->_releases = $data['releases'];
197
            $this->_updateTime = $data['updateTime'];
198
        }
199
    }
200
201
    public function update()
202
    {
203
        $repo = $this->getRegistry()->buildVcsRepository($this->getName());
204
        $this->_releases = $this->prepareReleases($repo);
205
        $this->_hash = $this->getStorage()->writePackage($this);
206
    }
207
208
    /**
209
     * @param AssetVcsRepository $repository
210
     * @return array
211
     */
212
    public function prepareReleases($repository)
213
    {
214
        $releases = [];
215
        foreach ($repository->getPackages() as $package) {
216
            $version = $package->getVersion();
217
            $require = $this->prepareRequire($package->getRequires());
218
            $release = [
219
                'uid' => $this->prepareUid($version),
220
                'name' => $this->getNormalName(),
221
                'version' => $version,
222
            ];
223
            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...
224
                $release['require'] = $require;
225
            }
226
            if ($package->getDistUrl()) {
227
                $release['dist'] = [
228
                    'type' => $package->getDistType(),
229
                    'url' => $package->getDistUrl(),
230
                    'reference' => $package->getDistReference(),
231
                ];
232
            }
233
            if ($package->getSourceUrl()) {
234
                $release['source'] = [
235
                    'type' => $package->getSourceType(),
236
                    'url' => $package->getSourceUrl(),
237
                    'reference' => $package->getSourceReference(),
238
                ];
239
            }
240
            if ((isset($release['dist']) && $release['dist']) || (isset($release['source']) && $release['source'])) {
241
                $releases[$version] = $release;
242
            }
243
        }
244
245
        return $releases;
246
    }
247
248
    /**
249
     * Prepares array of requires: name => constraint.
250
     * @param Link[] array of package requires.
251
     * @return array
252
     */
253
    public function prepareRequire(array $links)
254
    {
255
        $requires = [];
256
        foreach ($links as $name => $link) {
257
            $requires[$name] = $link->getPrettyConstraint();
258
        }
259
260
        return $requires;
261
    }
262
263
    public function prepareUid($version)
264
    {
265
        $known = $this->getSaved()->getRelease($version);
266
267
        return isset($known['uid']) ? $known['uid'] : $this->getStorage()->getNextID();
268
    }
269
270
    public function getReleases()
271
    {
272
        return $this->_releases;
273
    }
274
275
    public function getRelease($version)
276
    {
277
        return isset($this->_releases[$version]) ? $this->_releases[$version] : [];
278
    }
279
280
    public function getSaved()
281
    {
282
        if ($this->_saved === null) {
283
            $this->_saved = static::findOne($this->getType(), $this->getName());
284
        }
285
286
        return $this->_saved;
287
    }
288
289
    /**
290
     * @return Storage
291
     */
292
    public function getStorage()
293
    {
294
        return Yii::$app->get('packageStorage');
295
    }
296
297
    /**
298
     * Returns the latest update time (UNIX Epoch).
299
     * @return int|null
300
     */
301
    public function getUpdateTime()
302
    {
303
        return $this->_updateTime;
304
    }
305
306
    /**
307
     * Package can be updated not more often than once in 10 min.
308
     * @return bool
309
     */
310
    public function canBeUpdated()
311
    {
312
        return time() - $this->getUpdateTime() > 60 * 10; // 10 min
313
    }
314
315
    /**
316
     * Whether tha package should be auth-updated (if it is older than 1 day).
317
     * @return bool
318
     */
319
    public function canAutoUpdate()
320
    {
321
        return time() - $this->getUpdateTime() > 60 * 60 * 24; // 1 day
322
    }
323
}
324