PackagistSecurityChecker::hasBugs()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
/**
4
 * MIT License
5
 *
6
 * Copyright (c) 2016 Bernardo Secades
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated documentation files (the "Software"), to deal
10
 * in the Software without restriction, including without limitation the rights
11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
 * copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in all
16
 * copies or substantial portions of the Software.
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 * SOFTWARE.
24
 */
25
26
namespace BernardoSecades\Packagist\SecurityChecker;
27
28
use BernardoSecades\Packagist\SecurityChecker\Api\Client;
29
use BernardoSecades\Packagist\SecurityChecker\Exception\Packagist\NotFollowSemanticVersioningException;
30
use BernardoSecades\Packagist\SecurityChecker\Exception\File\FileNotFoundException;
31
use BernardoSecades\Packagist\SecurityChecker\ValueObject\Package;
32
use BernardoSecades\Packagist\SecurityChecker\ValueObject\FilterCheck;
33
34
/**
35
 * @author bernardosecades <[email protected]>
36
 */
37
class PackagistSecurityChecker
38
{
39
    /** @var  Client */
40
    protected $client;
41
42
    /** @var bool */
43
    protected $bugs = false;
44
45
    /**
46
     * @param Client|null $client
47
     */
48 10
    public function __construct(Client $client = null)
49
    {
50 10
        $this->client = is_null($client) ? new Client() : $client;
51 10
    }
52
53
    /**
54
     * @param string   $composerFileLock
55
     * @param int|null $filter
56
     * @return array Packages Loaded with data from packagist API
57
     */
58 7
    public function check($composerFileLock, $filter = null)
59
    {
60 7
        $packages = $this->getPackagesInstalled($composerFileLock);
61
62 6
        $this->updatePackagesFromAPI($packages);
63
64 6
        if (FilterCheck::BUG === $filter) {
65 2
            return array_filter($packages, [$this, 'filterOnlyBugs']);
66
        }
67
68 4
        return $packages;
69 1
    }
70
71
    /**
72
     * @param string $url
73
     */
74
    public function setPackagistUrl($url)
75
    {
76
        $this->client->setPackagistUrl($url);
77
    }
78
79
    /**
80
     * @return bool
81
     */
82 5
    public function hasBugs()
83
    {
84 5
        return $this->bugs;
85
    }
86
87
    /**
88
     * @param array $infoPackage
89
     * @param Package[] $packages
90
     * @return null|Package
91
     */
92 6
    protected function searchPackage($infoPackage, $packages)
93
    {
94 6
        $package = null;
95 6
        foreach ($packages as $p) {
96 6
            if (isset($infoPackage['packages'][$p->getName()][$p->getVersion()])) {
97 6
                $package = $p;
98 6
                break;
99
            }
100 6
        }
101
102 6
        return $package;
103
    }
104
105
    /**
106
     * @param Package[] $packages
107
     * @return Package[]            Return packages array updated from API
108
     */
109 6
    protected function updatePackagesFromAPI(array $packages)
110
    {
111 6
        $infoPackages = $this->client->getMultipleRequest($packages);
0 ignored issues
show
Documentation introduced by
$packages is of type array<integer,object<Ber...r\ValueObject\Package>>, but the function expects a array<integer,object<GuzzleHttp\Promise\Promise>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
112
113 6
        foreach ($infoPackages as $infoPackage) {
114 6
            $package = $this->searchPackage($infoPackage, $packages);
115 6
            $package->setPackagist(true);
116
            // Overwrite data from packagist API
117 6
            $package->fromArray($infoPackage['packages'][$package->getName()][$package->getVersion()]);
118
119
            try {
120 6
                $versionWithNextPatchVersion = $package->getVersionWithNextPatchVersion();
121 6
                $package->setSemanticVersioning(true);
122 6
            } catch (NotFollowSemanticVersioningException $exception) {
123 3
                continue;
124
            }
125
126 6
            if (array_key_exists($versionWithNextPatchVersion, $infoPackage['packages'][$package->getName()])) {
127 3
                $this->bugs = true;
128 3
                $package->setBug(true);
129 3
            }
130 6
        }
131
132 6
        return $packages;
133
    }
134
135
    /**
136
     * @param string $composerLockFile
137
     * @return array Packages Loaded with data from composer.lock
138
     */
139 7
    protected function getPackagesInstalled($composerLockFile)
140
    {
141 7
        if (false === is_file($composerLockFile)) {
142 1
            throw new FileNotFoundException(sprintf('%s file does not exist', $composerLockFile));
143
        }
144
145 6
        $composerLockRawContent = file_get_contents($composerLockFile);
146 6
        $composerLockcontent = json_decode($composerLockRawContent, true);
147
148 6
        $packages = [];
149 6
        foreach ($composerLockcontent['packages'] as $infoPackage) {
150 6
            $package = new Package();
151 6
            $package->fromArray($infoPackage);
152 6
            $packages[$package->getName()] = $package;
153 6
        }
154
155 6
        return $packages;
156
    }
157
158
    /**
159
     * @param Package $package
160
     * @return bool
161
     */
162 2
    protected function filterOnlyBugs(Package $package)
163
    {
164 2
        return $package->hasBug();
165
    }
166
}
167