Completed
Push — master ( 60e59a...334051 )
by Adam
06:35
created

Repository   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 210
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 31
c 0
b 0
f 0
lcom 1
cbo 3
dl 0
loc 210
rs 9.8

16 Methods

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