Passed
Push — master ( a06116...c43f53 )
by Pascal
01:13 queued 12s
created

PackageFilter::isMatchingFirmwareVersionPre7()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SSpkS\Package;
4
5
use \SSpkS\Device\DeviceList;
6
use \SSpkS\Package\Package;
7
8
/**
9
 * SPK PackageFinder class
10
 */
11
class PackageFilter
12
{
13
    private $config;
14
    private $pkgList;
15
    /** @var bool|string[] $filterArch Array of allowed architectures, or FALSE to ignore. */
16
    private $filterArch = false;
17
    /** @var bool|string $filterFwVersion Target firmware version, or FALSE to ignore. */
18
    private $filterFwVersion = false;
19
    /** @var bool|string $filterChannel Channel 'stable' or 'beta', or FALSE to ignore. */
20
    private $filterChannel = false;
21
    /** @var bool $filterOldVersions TRUE to return unique packages with latest version only. */
22
    private $filterOldVersions = false;
23
24
    /**
25
     * @param \SSpkS\Config $config Config object
26
     * @param \SSpkS\Package\Package[] $pkgList List of Package objects to filter
27
     */
28 5
    public function __construct(\SSpkS\Config $config, array $pkgList)
29
    {
30 5
        $this->config = $config;
31 5
        $this->pkgList = $pkgList;
32 5
    }
33
34
    /**
35
     * Sets the architecture to filter for.
36
     *
37
     * @param string $arch Architecture.
38
     */
39 1
    public function setArchitectureFilter($arch)
40
    {
41
        // Specific corner case
42 1
        if ($arch == '88f6282') {
43
            $arch = '88f6281';
44
        }
45
      
46 1
        $dl = new DeviceList($this->config);
47 1
        $family = $dl->getFamily($arch);
48 1
        $this->filterArch = array_unique(array('noarch', $arch, $family));
49 1
    }
50
51
    /**
52
     * Sets the firmware version to filter for.
53
     *
54
     * @param string|bool $version Firmware version in dotted notation ('1.2.3456') or FALSE to ignore.
55
     */
56 1
    public function setFirmwareVersionFilter($version)
57
    {
58 1
        $this->filterFwVersion = $version;
59 1
    }
60
61
    /**
62
     * Sets the channel to filter for.
63
     *
64
     * @param string $channel Channel ('stable' or 'beta')
65
     */
66 1
    public function setChannelFilter($channel)
67
    {
68 1
        $this->filterChannel = $channel;
69 1
    }
70
71
    /**
72
     * Enables or disables omitting older versions of the same package from the result set.
73
     *
74
     * @param bool $status TRUE to enable the filter, FALSE to disable.
75
     */
76 1
    public function setOldVersionFilter($status)
77
    {
78 1
        $this->filterOldVersions = $status;
79 1
    }
80
81
    /**
82
     * If filter is enabled, checks if architecture of $package is compatible to requested one.
83
     *
84
     * @param \SSpkS\Package\Package $package Package to test.
85
     * @return bool TRUE if matching, or FALSE.
86
     */
87 5
    public function isMatchingArchitecture($package)
88
    {
89 5
        if ($this->filterArch === false) {
90 4
            return true;
91
        }
92 1
        $matches = array_intersect(/** @scrutinizer ignore-type */ $this->filterArch, $package->arch);
93 1
        return (count($matches) > 0);
94
    }
95
96
    /**
97
     * If filter is enabled, checks if minimal firmware required of $package is
98
     * smaller or equal to system firmware.
99
     *
100
     * @param \SSpkS\Package\Package $package Package to test.
101
     * @return bool TRUE if matching, or FALSE.
102
     */
103 5
    public function isMatchingFirmwareVersion(\SSpkS\Package\Package $package): bool
104
    {
105 5
        if ($this->filterFwVersion === false) {
106 4
            return true;
107
        }
108 1
        if(version_compare(/** @scrutinizer ignore-type */ $this->filterFwVersion, '7', '<'))
109 1
            return $this->isMatchingFirmwareVersionPre7($package);
110 1
        return $this->isMatchingFirmwareVersionPost7($package);
111
    }
112
113 1
    private function isMatchingFirmwareVersionPre7(\SSpkS\Package\Package $package): bool
114
    {
115
        // on DSM6 or less, package must be <= to filter
116 1
        return version_compare($package->firmware, /** @scrutinizer ignore-type */ $this->filterFwVersion, '<=');
117
    }
118
119 1
    private function isMatchingFirmwareVersionPost7(\SSpkS\Package\Package $package): bool
120
    {
121
        // on DSM7 or above (hypothetically), package must be <= to filter
122 1
        return version_compare($package->firmware, /** @scrutinizer ignore-type */ '7', '>=')
123 1
        && version_compare($package->firmware, /** @scrutinizer ignore-type */ $this->filterFwVersion, '<=');
124
    }
125
126
    /**
127
     * If filter is enabled, checks if channel of $package matches requested one.
128
     * 'beta' will show ALL packages, also those from 'stable'.
129
     *
130
     * @param \SSpkS\Package\Package $package Package to test.
131
     * @return bool TRUE if matching, or FALSE.
132
     */
133 5
    public function isMatchingChannel($package)
134
    {
135 5
        if ($this->filterChannel === false) {
136 4
            return true;
137
        }
138 1
        if ($this->filterChannel == 'stable' && $package->isBeta() === false) {
139 1
            return true;
140 1
        } elseif ($this->filterChannel == 'beta') {
141 1
            return true;
142
        }
143 1
        return false;
144
    }
145
146
    /**
147
     * Removes older versions of same package from $pkgList.
148
     *
149
     * @param \SSpkS\Package\Package[] $pkgList List of packages
150
     * @return \SSpkS\Package\Package[] List of unique packages
151
     */
152 1
    public function removeObsoleteVersions($pkgList)
153
    {
154 1
        $uniqueList = array();
155 1
        foreach ($pkgList as $package) {
156 1
            $pkgId = $package->package;
157 1
            if (isset($uniqueList[$pkgId]) && version_compare($uniqueList[$pkgId]->version, $package->version, '>=')) {
158 1
                continue;
159
            }
160 1
            $uniqueList[$pkgId] = $package;
161
        }
162 1
        return array_values($uniqueList);
163
    }
164
165
    /**
166
     * Returns the list of packages matching the currently set filters.
167
     *
168
     * @return \SSpkS\Package\Package[] List of Package objects matching filters.
169
     */
170 5
    public function getFilteredPackageList()
171
    {
172 5
        $filteredPackages = array();
173 5
        foreach ($this->pkgList as $package) {
174 5
            if (!$this->isMatchingArchitecture($package)) {
175 1
                continue;
176
            }
177 5
            if (!$this->isMatchingFirmwareVersion($package)) {
178 1
                continue;
179
            }
180 5
            if (!$this->isMatchingChannel($package)) {
181 1
                continue;
182
            }
183 5
            $filteredPackages[] = $package;
184
        }
185 5
        if ($this->filterOldVersions) {
186
            // remove older versions of duplicate packages from $filteredPackages
187 1
            $filteredPackages = $this->removeObsoleteVersions($filteredPackages);
188
        }
189 5
        return $filteredPackages;
190
    }
191
}
192