Passed
Push — master ( 6791f9...01e57e )
by Adam
02:08
created

Repository::findPackage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2.0116

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 18
ccs 6
cts 7
cp 0.8571
rs 9.4285
cc 2
eloc 9
nc 2
nop 2
crap 2.0116
1
<?php
2
/**
3
 * Repository.php
4
 *
5
 * @copyright      More in license.md
6
 * @license        https://www.ipublikuj.eu
7
 * @author         Adam Kadlec https://www.ipublikuj.eu
8
 * @package        iPublikuj:Packages!
9
 * @subpackage     Repository
10
 * @since          1.0.0
11
 *
12
 * @date           30.05.15
13
 */
14
15
declare(strict_types = 1);
16
17
namespace IPub\Packages\Repository;
18
19
use Nette;
20
use Nette\Utils;
21
22
use IPub\Packages;
23
use IPub\Packages\Caching;
24
use IPub\Packages\Entities;
25
use IPub\Packages\Loaders;
26
27
/**
28
 * Packages repository
29
 *
30
 * @package        iPublikuj:Packages!
31
 * @subpackage     Repository
32
 *
33
 * @author         Adam Kadlec <[email protected]>
34
 */
35 1
final class Repository implements IRepository
36
{
37
	/**
38
	 * Implement nette smart magic
39
	 */
40 1
	use Nette\SmartObject;
41
42
	/**
43
	 * @var array
44
	 */
45
	private $paths = [];
46
47
	/**
48
	 * @var Loaders\ILoader
49
	 */
50
	private $loader;
51
52
	/**
53
	 * @var Entities\IPackage[]
54
	 */
55
	private $packages;
56
57
	/**
58
	 * @param Loaders\ILoader $loader
59
	 */
60
	public function __construct(Loaders\ILoader $loader)
61
	{
62 1
		$this->loader = $loader;
63 1
	}
64
65
	/**
66
	 * {@inheritdoc}
67
	 */
68
	public function findPackage(string $name, string $version = 'latest')
69
	{
70
		// normalize name
71 1
		$name = strtolower($name);
72
73 1
		if ($version === 'latest') {
74 1
			$packages = $this->findPackages($name);
75
76 1
			usort($packages, function (Entities\Package $a, Entities\Package $b) {
77
				return version_compare($a->getVersion(), $b->getVersion());
78 1
			});
79
80 1
			return end($packages);
81
82
		} else {
83
			return current($this->findPackages($name, $version));
84
		}
85
	}
86
87
	/**
88
	 * {@inheritdoc}
89
	 */
90
	public function findPackages(string $name, string $version = NULL) : array
91
	{
92
		// normalize name
93 1
		$name = strtolower($name);
94
95 1
		$packages = [];
96
97 1
		foreach ($this->getPackages() as $package) {
98 1
			if ($package->getName() === $name && ($version === NULL || $version === $package->getVersion())) {
99 1
				$packages[] = $package;
100
			}
101
		}
102
103 1
		return $packages;
104
	}
105
106
	/**
107
	 * {@inheritdoc}
108
	 */
109
	public function hasPackage(Entities\IPackage $package) : bool
110
	{
111
		$packageId = $package->getUniqueName();
112
113
		foreach ($this->getPackages() as $repoPackage) {
114
			if ($packageId === $repoPackage->getUniqueName()) {
115
				return TRUE;
116
			}
117
		}
118
119
		return FALSE;
120
	}
121
122
	/**
123
	 * {@inheritdoc}
124
	 */
125
	public function filterPackages(callable $callback) : array
126
	{
127
		$packages = [];
128
129
		foreach ($this->getPackages() as $package) {
130
			if (call_user_func($callback, $package) === TRUE) {
131
				$packages[$package->getName()] = $package;
132
			}
133
		}
134
135
		return $packages;
136
	}
137
138
	/**
139
	 * {@inheritdoc}
140
	 */
141
	public function getPackages() : array
142
	{
143 1
		if ($this->packages === NULL) {
144 1
			$this->initialize();
145
		}
146
147 1
		return $this->packages;
148
	}
149
150
	/**
151
	 * {@inheritdoc}
152
	 */
153
	public function reload() : void
154
	{
155
		$this->initialize();
156
	}
157
158
	/**
159
	 * {@inheritdoc}
160
	 */
161
	public function getPaths() : array
162
	{
163
		return $this->paths;
164
	}
165
166
	/**
167
	 * {@inheritdoc}
168
	 */
169
	public function addPath($path) : void
170
	{
171 1
		if (!is_array($path)) {
172 1
			$path = [$path];
173
		}
174
175 1
		$this->paths = array_merge($this->paths, $path);
176 1
	}
177
178
	/**
179
	 * {@inheritdoc}
180
	 */
181
	public function count()
182
	{
183
		return count($this->getPackages());
184
	}
185
186
	/**
187
	 * {@inheritdoc}
188
	 */
189
	public function offsetExists($name)
190
	{
191
		return isset($this->packages[$name]);
192
	}
193
194
	/**
195
	 * {@inheritdoc}
196
	 */
197
	public function offsetGet($name)
198
	{
199
		return $this->findPackage($name);
200
	}
201
202
	/**
203
	 * {@inheritdoc}
204
	 */
205
	public function offsetSet($name, $package)
206
	{
207
		$this->packages[$name] = $package;
208
	}
209
210
	/**
211
	 * {@inheritdoc}
212
	 */
213
	public function offsetUnset($name)
214
	{
215
		unset($this->packages[$name]);
216
	}
217
218
	/**
219
	 * {@inheritdoc}
220
	 */
221
	public function getIterator()
222
	{
223
		return new \ArrayIterator($this->packages);
224
	}
225
226
	/**
227
	 * Initializes the packages array. Mostly meant as an extension point
228
	 */
229
	private function initialize()
230
	{
231 1
		$this->packages = [];
232
233 1
		foreach ($this->paths as $path) {
234 1
			$files = glob($path . DIRECTORY_SEPARATOR . '*' . DIRECTORY_SEPARATOR . '*' . DIRECTORY_SEPARATOR . 'composer.json', GLOB_NOSORT) ?: [];
235
236 1
			foreach ($files as $file) {
237
				/** @var Entities\IPackage $package */
238 1
				if ($package = $this->loader->load($file)) {
239 1
					$this->packages[$package->getName()] = $package;
240
				}
241
			}
242
		}
243 1
	}
244
}
245