Passed
Push — master ( b0e99a...74682a )
by Alain
02:34
created
src/PHPFeature.php 1 patch
Indentation   +370 added lines, -370 removed lines patch added patch discarded remove patch
@@ -1,13 +1,13 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 /**
3
- * PHPFeature Class.
4
- *
5
- * @package   brightnucleus/phpfeature
6
- * @author    Alain Schlesser <[email protected]>
7
- * @license   MIT
8
- * @link      http://www.brightnucleus.com/
9
- * @copyright 2016 Alain Schlesser, Bright Nucleus
10
- */
3
+	 * PHPFeature Class.
4
+	 *
5
+	 * @package   brightnucleus/phpfeature
6
+	 * @author    Alain Schlesser <[email protected]>
7
+	 * @license   MIT
8
+	 * @link      http://www.brightnucleus.com/
9
+	 * @copyright 2016 Alain Schlesser, Bright Nucleus
10
+	 */
11 11
 
12 12
 use BrightNucleus_Config as Config;
13 13
 use BrightNucleus_ConfigInterface as ConfigInterface;
@@ -25,366 +25,366 @@  discard block
 block discarded – undo
25 25
 class PHPFeature implements FeatureInterface
26 26
 {
27 27
 
28
-    /**
29
-     * RegEx pattern that matches the comparison string.
30
-     *
31
-     * @since 0.1.0
32
-     *
33
-     * @var string
34
-     */
35
-    const COMPARISON_PATTERN = '/^(?:(<=|lt|<|le|>=|gt|>|ge|=|==|eq|!=|<>|ne))([0-9].*)$/';
36
-
37
-    /**
38
-     * Reference to the Configuration object.
39
-     *
40
-     * @since 0.1.0
41
-     *
42
-     * @var ConfigInterface
43
-     */
44
-    protected $config;
45
-
46
-    /**
47
-     * Reference to the Version object.
48
-     *
49
-     * @since 0.1.0
50
-     *
51
-     * @var SemanticVersion
52
-     */
53
-    protected $version;
54
-
55
-    /**
56
-     * Reference to the PHP releases.
57
-     *
58
-     * @since 0.2.4
59
-     *
60
-     * @var PHPReleases
61
-     */
62
-    protected $releases;
63
-
64
-    /**
65
-     * Instantiate a PHPFeature object.
66
-     *
67
-     * @since 0.1.0
68
-     *
69
-     * @param SemanticVersion|string|int|null $phpVersion Version of PHP to check the features for.
70
-     * @param ConfigInterface|null            $config     Configuration that contains the known features.
71
-     *
72
-     * @throws RuntimeException If the PHP version could not be validated.
73
-     */
74
-    public function __construct($phpVersion = null, ConfigInterface $config = null)
75
-    {
76
-
77
-        // TODO: Better way to bootstrap this while still allowing DI?
78
-        if ( ! $config) {
79
-            $config = new Config(include(dirname(__FILE__) . '/../config/known_features.php'));
80
-        }
81
-
82
-        $this->config = $config;
83
-
84
-        if (null === $phpVersion) {
85
-            $phpVersion = phpversion();
86
-        }
87
-
88
-        if (is_int($phpVersion)) {
89
-            $phpVersion = (string)$phpVersion;
90
-        }
91
-
92
-        if (is_string($phpVersion)) {
93
-            $phpVersion = new SemanticVersion($phpVersion, true);
94
-        }
95
-
96
-        $this->version = $phpVersion;
97
-    }
98
-
99
-    /**
100
-     * Check whether a feature or a collection of features is supported.
101
-     *
102
-     * Accepts either a string or an array of strings. Returns true if all the passed-in features are supported, or
103
-     * false if at least one of them is not.
104
-     *
105
-     * @since 0.1.0
106
-     *
107
-     * @param string|array $features What features to check the support of.
108
-     *
109
-     * @return bool Whether the set of features as a whole is supported.
110
-     * @throws InvalidArgumentException If the wrong type of argument is passed in.
111
-     * @throws RuntimeException         If a requirement could not be parsed.
112
-     */
113
-    public function isSupported($features)
114
-    {
115
-
116
-        if (is_string($features)) {
117
-            $features = array($features);
118
-        }
119
-
120
-        if ( ! is_array($features)) {
121
-            throw new InvalidArgumentException(sprintf(
122
-                'Wrong type of argument passed in to is_supported(): "%1$s".',
123
-                gettype($features)
124
-            ));
125
-        }
126
-
127
-        $isSupported = true;
128
-
129
-        while ($isSupported && count($features) > 0) {
130
-            $feature = array_pop($features);
131
-            $isSupported &= (bool)$this->checkSupport($feature);
132
-        }
133
-
134
-        return (bool)$isSupported;
135
-    }
136
-
137
-    /**
138
-     * Get the minimum required version that supports all of the requested features.
139
-     *
140
-     * Accepts either a string or an array of strings. Returns a SemanticVersion object for the version number that is
141
-     * known to support all the passed-in features, or false if at least one of them is not supported by any known
142
-     * version.
143
-     *
144
-     * @since 0.2.0
145
-     *
146
-     * @param string|array $features What features to check the support of.
147
-     *
148
-     * @return SemanticVersion|false SemanticVersion object for the version number that is known to support all the
149
-     *                               passed-in features, false if none.
150
-     * @throws InvalidArgumentException If the wrong type of argument is passed in.
151
-     * @throws RuntimeException         If a requirement could not be parsed.
152
-     */
153
-    public function getMinimumRequired($features)
154
-    {
155
-
156
-        if (is_string($features)) {
157
-            $features = array($features);
158
-        }
159
-
160
-        if ( ! is_array($features)) {
161
-            throw new InvalidArgumentException(sprintf(
162
-                'Wrong type of argument passed in to get_minimum_required(): "%1$s".',
163
-                gettype($features)
164
-            ));
165
-        }
166
-
167
-        $minimumRequired = '0.0.0';
168
-        $isSupported     = true;
169
-
170
-        while (count($features) > 0) {
171
-            $feature = array_pop($features);
172
-            $isSupported &= (bool)$this->checkSupport($feature, $minimumRequired);
173
-        }
174
-
175
-        return $minimumRequired !== '0.0.0' ? new SemanticVersion($minimumRequired, true) : false;
176
-    }
177
-
178
-    /**
179
-     * Check whether a single feature is supported.
180
-     *
181
-     * @since 0.1.0
182
-     *
183
-     * @param string      $feature         The feature to check.
184
-     * @param string|null $minimumRequired Optional. Minimum required version that supports all features.
185
-     *
186
-     * @return bool Whether the requested feature is supported.
187
-     * @throws RuntimeException If the requirement could not be parsed.
188
-     */
189
-    protected function checkSupport($feature, &$minimumRequired = null)
190
-    {
191
-
192
-        if ( ! $this->config->hasKey($feature)) {
193
-            return false;
194
-        }
195
-
196
-        $requirements = (array)$this->config->getKey($feature);
197
-
198
-        $isSupported = true;
199
-
200
-        while (($isSupported || null !== $minimumRequired) && count($requirements) > 0) {
201
-            $requirement = array_pop($requirements);
202
-            $isSupported &= (bool)$this->checkRequirement($requirement, $minimumRequired);
203
-        }
204
-
205
-        return (bool)$isSupported;
206
-    }
207
-
208
-    /**
209
-     * Check whether a single requirement is met.
210
-     *
211
-     * @since 0.1.0
212
-     *
213
-     * @param string      $requirement     A requirement that is composed of an operator and a version milestone.
214
-     * @param string|null $minimumRequired Optional. Minimum required version that supports all features.
215
-     *
216
-     * @return bool Whether the requirement is met.
217
-     * @throws RuntimeException If the requirement could not be parsed.
218
-     */
219
-    protected function checkRequirement($requirement, &$minimumRequired = null)
220
-    {
221
-
222
-        $requirement = trim($requirement);
223
-        $pattern     = self::COMPARISON_PATTERN;
224
-
225
-        $arguments = array();
226
-        $result    = preg_match($pattern, $requirement, $arguments);
227
-
228
-        if ( ! $result || ! isset($arguments[1]) || ! isset($arguments[2])) {
229
-            throw new RuntimeException(sprintf(
230
-                'Could not parse the requirement "%1$s".',
231
-                (string)$requirement
232
-            ));
233
-        }
234
-
235
-        $operator  = isset($arguments[1]) ? (string)$arguments[1] : '>=';
236
-        $milestone = isset($arguments[2]) ? (string)$arguments[2] : '0.0.0';
237
-
238
-        $isSupported = (bool)version_compare($this->version->getVersion(), $milestone, $operator);
239
-
240
-        if (null !== $minimumRequired) {
241
-            $requiredVersion = $this->getRequiredVersion($milestone, $operator);
242
-            if (version_compare($requiredVersion, $minimumRequired, '>')) {
243
-                $minimumRequired = $requiredVersion;
244
-            }
245
-        }
246
-
247
-        return $isSupported;
248
-    }
249
-
250
-    /**
251
-     * Get the required version for a single requirement.
252
-     *
253
-     * @todo  The entire algorithm is only an approximation. A 5.2 SemVer library is needed.
254
-     *
255
-     * @since 0.2.0
256
-     *
257
-     * @param string $milestone A version milestone that is used to define the requirement.
258
-     * @param string $operator  An operator that gets applied to the milestone.
259
-     *                          Possible values: '<=', 'lt', '<', 'le', '>=', 'gt', '>', 'ge', '=', '==', 'eq', '!=',
260
-     *                          '<>', 'ne'
261
-     *
262
-     * @return string Version string that meets a single requirement.
263
-     * @throws RuntimeException If the requirement could not be satisfied.
264
-     * @throws RuntimeException If the NotEqual is used.
265
-     */
266
-    protected function getRequiredVersion($milestone, $operator)
267
-    {
268
-        if (null === $this->releases) {
269
-            $this->releases = new PHPReleases();
270
-        }
271
-
272
-        switch ($operator) {
273
-            case '>':
274
-            case 'gt':
275
-                return $this->getGreaterThanVersion($milestone);
276
-            case '<':
277
-            case 'lt':
278
-                return $this->getLesserThanVersion($milestone);
279
-            case '>=':
280
-            case 'ge':
281
-                return $this->getGreaterEqualVersion($milestone);
282
-            case '<=':
283
-            case 'le':
284
-                return $this->getLesserEqualVersion($milestone);
285
-            case '!=':
286
-            case '<>':
287
-            case 'ne':
288
-                throw new RuntimeException('NotEqual operator is not implemented.');
289
-        }
290
-
291
-        return $milestone;
292
-    }
293
-
294
-    /**
295
-     * Get a version greater than the milestone.
296
-     *
297
-     * @since 0.2.4
298
-     *
299
-     * @param string $milestone A version milestone that is used to define the requirement.
300
-     *
301
-     * @return string Version number that meets the requirement.
302
-     * @throws RuntimeException If the requirement could not be satisfied.
303
-     */
304
-    protected function getGreaterThanVersion($milestone)
305
-    {
306
-        $data = $this->releases->getAll();
307
-        foreach ($data as $version => $date) {
308
-            if (version_compare($version, $milestone, '>')) {
309
-                return $version;
310
-            }
311
-        }
312
-
313
-        throw new RuntimeException('Could not satisfy version requirements.');
314
-    }
315
-
316
-    /**
317
-     * Get a version lesser than the milestone.
318
-     *
319
-     * @since 0.2.4
320
-     *
321
-     * @param string $milestone A version milestone that is used to define the requirement.
322
-     *
323
-     * @return string Version number that meets the requirement.
324
-     * @throws RuntimeException If the requirement could not be satisfied.
325
-     */
326
-    protected function getLesserThanVersion($milestone)
327
-    {
328
-        if (version_compare($this->version->getVersion(), $milestone, '<')) {
329
-            return $this->version->getVersion();
330
-        }
331
-        $data = array_reverse($this->releases->getAll());
332
-        foreach ($data as $version => $date) {
333
-            if (version_compare($version, $milestone, '<')) {
334
-                return $version;
335
-            }
336
-        }
337
-
338
-        throw new RuntimeException('Could not satisfy version requirements.');
339
-    }
340
-
341
-    /**
342
-     * Get a version greater or equal than the milestone.
343
-     *
344
-     * @since 0.2.4
345
-     *
346
-     * @param string $milestone A version milestone that is used to define the requirement.
347
-     *
348
-     * @return string Version number that meets the requirement.
349
-     */
350
-    protected function getGreaterEqualVersion($milestone)
351
-    {
352
-        if ($this->releases->exists($milestone)) {
353
-            return $milestone;
354
-        }
355
-
356
-        $data = $this->releases->getAll();
357
-        foreach ($data as $version => $date) {
358
-            if (version_compare($version, $milestone, '>=')) {
359
-                return $version;
360
-            }
361
-        }
362
-
363
-        throw new RuntimeException('Could not satisfy version requirements.');
364
-    }
365
-
366
-    /**
367
-     * Get a version lesser or equal than the milestone.
368
-     *
369
-     * @since 0.2.4
370
-     *
371
-     * @param string $milestone A version milestone that is used to define the requirement.
372
-     *
373
-     * @return string Version number that meets the requirement.
374
-     */
375
-    protected function getLesserEqualVersion($milestone)
376
-    {
377
-        if (version_compare($this->version->getVersion(), $milestone, '<=')) {
378
-            return $this->version->getVersion();
379
-        }
380
-
381
-        $data = array_reverse($this->releases->getAll());
382
-        foreach ($data as $version => $date) {
383
-            if (version_compare($version, $milestone, '<=')) {
384
-                return $version;
385
-            }
386
-        }
387
-
388
-        throw new RuntimeException('Could not satisfy version requirements.');
389
-    }
28
+	/**
29
+	 * RegEx pattern that matches the comparison string.
30
+	 *
31
+	 * @since 0.1.0
32
+	 *
33
+	 * @var string
34
+	 */
35
+	const COMPARISON_PATTERN = '/^(?:(<=|lt|<|le|>=|gt|>|ge|=|==|eq|!=|<>|ne))([0-9].*)$/';
36
+
37
+	/**
38
+	 * Reference to the Configuration object.
39
+	 *
40
+	 * @since 0.1.0
41
+	 *
42
+	 * @var ConfigInterface
43
+	 */
44
+	protected $config;
45
+
46
+	/**
47
+	 * Reference to the Version object.
48
+	 *
49
+	 * @since 0.1.0
50
+	 *
51
+	 * @var SemanticVersion
52
+	 */
53
+	protected $version;
54
+
55
+	/**
56
+	 * Reference to the PHP releases.
57
+	 *
58
+	 * @since 0.2.4
59
+	 *
60
+	 * @var PHPReleases
61
+	 */
62
+	protected $releases;
63
+
64
+	/**
65
+	 * Instantiate a PHPFeature object.
66
+	 *
67
+	 * @since 0.1.0
68
+	 *
69
+	 * @param SemanticVersion|string|int|null $phpVersion Version of PHP to check the features for.
70
+	 * @param ConfigInterface|null            $config     Configuration that contains the known features.
71
+	 *
72
+	 * @throws RuntimeException If the PHP version could not be validated.
73
+	 */
74
+	public function __construct($phpVersion = null, ConfigInterface $config = null)
75
+	{
76
+
77
+		// TODO: Better way to bootstrap this while still allowing DI?
78
+		if ( ! $config) {
79
+			$config = new Config(include(dirname(__FILE__) . '/../config/known_features.php'));
80
+		}
81
+
82
+		$this->config = $config;
83
+
84
+		if (null === $phpVersion) {
85
+			$phpVersion = phpversion();
86
+		}
87
+
88
+		if (is_int($phpVersion)) {
89
+			$phpVersion = (string)$phpVersion;
90
+		}
91
+
92
+		if (is_string($phpVersion)) {
93
+			$phpVersion = new SemanticVersion($phpVersion, true);
94
+		}
95
+
96
+		$this->version = $phpVersion;
97
+	}
98
+
99
+	/**
100
+	 * Check whether a feature or a collection of features is supported.
101
+	 *
102
+	 * Accepts either a string or an array of strings. Returns true if all the passed-in features are supported, or
103
+	 * false if at least one of them is not.
104
+	 *
105
+	 * @since 0.1.0
106
+	 *
107
+	 * @param string|array $features What features to check the support of.
108
+	 *
109
+	 * @return bool Whether the set of features as a whole is supported.
110
+	 * @throws InvalidArgumentException If the wrong type of argument is passed in.
111
+	 * @throws RuntimeException         If a requirement could not be parsed.
112
+	 */
113
+	public function isSupported($features)
114
+	{
115
+
116
+		if (is_string($features)) {
117
+			$features = array($features);
118
+		}
119
+
120
+		if ( ! is_array($features)) {
121
+			throw new InvalidArgumentException(sprintf(
122
+				'Wrong type of argument passed in to is_supported(): "%1$s".',
123
+				gettype($features)
124
+			));
125
+		}
126
+
127
+		$isSupported = true;
128
+
129
+		while ($isSupported && count($features) > 0) {
130
+			$feature = array_pop($features);
131
+			$isSupported &= (bool)$this->checkSupport($feature);
132
+		}
133
+
134
+		return (bool)$isSupported;
135
+	}
136
+
137
+	/**
138
+	 * Get the minimum required version that supports all of the requested features.
139
+	 *
140
+	 * Accepts either a string or an array of strings. Returns a SemanticVersion object for the version number that is
141
+	 * known to support all the passed-in features, or false if at least one of them is not supported by any known
142
+	 * version.
143
+	 *
144
+	 * @since 0.2.0
145
+	 *
146
+	 * @param string|array $features What features to check the support of.
147
+	 *
148
+	 * @return SemanticVersion|false SemanticVersion object for the version number that is known to support all the
149
+	 *                               passed-in features, false if none.
150
+	 * @throws InvalidArgumentException If the wrong type of argument is passed in.
151
+	 * @throws RuntimeException         If a requirement could not be parsed.
152
+	 */
153
+	public function getMinimumRequired($features)
154
+	{
155
+
156
+		if (is_string($features)) {
157
+			$features = array($features);
158
+		}
159
+
160
+		if ( ! is_array($features)) {
161
+			throw new InvalidArgumentException(sprintf(
162
+				'Wrong type of argument passed in to get_minimum_required(): "%1$s".',
163
+				gettype($features)
164
+			));
165
+		}
166
+
167
+		$minimumRequired = '0.0.0';
168
+		$isSupported     = true;
169
+
170
+		while (count($features) > 0) {
171
+			$feature = array_pop($features);
172
+			$isSupported &= (bool)$this->checkSupport($feature, $minimumRequired);
173
+		}
174
+
175
+		return $minimumRequired !== '0.0.0' ? new SemanticVersion($minimumRequired, true) : false;
176
+	}
177
+
178
+	/**
179
+	 * Check whether a single feature is supported.
180
+	 *
181
+	 * @since 0.1.0
182
+	 *
183
+	 * @param string      $feature         The feature to check.
184
+	 * @param string|null $minimumRequired Optional. Minimum required version that supports all features.
185
+	 *
186
+	 * @return bool Whether the requested feature is supported.
187
+	 * @throws RuntimeException If the requirement could not be parsed.
188
+	 */
189
+	protected function checkSupport($feature, &$minimumRequired = null)
190
+	{
191
+
192
+		if ( ! $this->config->hasKey($feature)) {
193
+			return false;
194
+		}
195
+
196
+		$requirements = (array)$this->config->getKey($feature);
197
+
198
+		$isSupported = true;
199
+
200
+		while (($isSupported || null !== $minimumRequired) && count($requirements) > 0) {
201
+			$requirement = array_pop($requirements);
202
+			$isSupported &= (bool)$this->checkRequirement($requirement, $minimumRequired);
203
+		}
204
+
205
+		return (bool)$isSupported;
206
+	}
207
+
208
+	/**
209
+	 * Check whether a single requirement is met.
210
+	 *
211
+	 * @since 0.1.0
212
+	 *
213
+	 * @param string      $requirement     A requirement that is composed of an operator and a version milestone.
214
+	 * @param string|null $minimumRequired Optional. Minimum required version that supports all features.
215
+	 *
216
+	 * @return bool Whether the requirement is met.
217
+	 * @throws RuntimeException If the requirement could not be parsed.
218
+	 */
219
+	protected function checkRequirement($requirement, &$minimumRequired = null)
220
+	{
221
+
222
+		$requirement = trim($requirement);
223
+		$pattern     = self::COMPARISON_PATTERN;
224
+
225
+		$arguments = array();
226
+		$result    = preg_match($pattern, $requirement, $arguments);
227
+
228
+		if ( ! $result || ! isset($arguments[1]) || ! isset($arguments[2])) {
229
+			throw new RuntimeException(sprintf(
230
+				'Could not parse the requirement "%1$s".',
231
+				(string)$requirement
232
+			));
233
+		}
234
+
235
+		$operator  = isset($arguments[1]) ? (string)$arguments[1] : '>=';
236
+		$milestone = isset($arguments[2]) ? (string)$arguments[2] : '0.0.0';
237
+
238
+		$isSupported = (bool)version_compare($this->version->getVersion(), $milestone, $operator);
239
+
240
+		if (null !== $minimumRequired) {
241
+			$requiredVersion = $this->getRequiredVersion($milestone, $operator);
242
+			if (version_compare($requiredVersion, $minimumRequired, '>')) {
243
+				$minimumRequired = $requiredVersion;
244
+			}
245
+		}
246
+
247
+		return $isSupported;
248
+	}
249
+
250
+	/**
251
+	 * Get the required version for a single requirement.
252
+	 *
253
+	 * @todo  The entire algorithm is only an approximation. A 5.2 SemVer library is needed.
254
+	 *
255
+	 * @since 0.2.0
256
+	 *
257
+	 * @param string $milestone A version milestone that is used to define the requirement.
258
+	 * @param string $operator  An operator that gets applied to the milestone.
259
+	 *                          Possible values: '<=', 'lt', '<', 'le', '>=', 'gt', '>', 'ge', '=', '==', 'eq', '!=',
260
+	 *                          '<>', 'ne'
261
+	 *
262
+	 * @return string Version string that meets a single requirement.
263
+	 * @throws RuntimeException If the requirement could not be satisfied.
264
+	 * @throws RuntimeException If the NotEqual is used.
265
+	 */
266
+	protected function getRequiredVersion($milestone, $operator)
267
+	{
268
+		if (null === $this->releases) {
269
+			$this->releases = new PHPReleases();
270
+		}
271
+
272
+		switch ($operator) {
273
+			case '>':
274
+			case 'gt':
275
+				return $this->getGreaterThanVersion($milestone);
276
+			case '<':
277
+			case 'lt':
278
+				return $this->getLesserThanVersion($milestone);
279
+			case '>=':
280
+			case 'ge':
281
+				return $this->getGreaterEqualVersion($milestone);
282
+			case '<=':
283
+			case 'le':
284
+				return $this->getLesserEqualVersion($milestone);
285
+			case '!=':
286
+			case '<>':
287
+			case 'ne':
288
+				throw new RuntimeException('NotEqual operator is not implemented.');
289
+		}
290
+
291
+		return $milestone;
292
+	}
293
+
294
+	/**
295
+	 * Get a version greater than the milestone.
296
+	 *
297
+	 * @since 0.2.4
298
+	 *
299
+	 * @param string $milestone A version milestone that is used to define the requirement.
300
+	 *
301
+	 * @return string Version number that meets the requirement.
302
+	 * @throws RuntimeException If the requirement could not be satisfied.
303
+	 */
304
+	protected function getGreaterThanVersion($milestone)
305
+	{
306
+		$data = $this->releases->getAll();
307
+		foreach ($data as $version => $date) {
308
+			if (version_compare($version, $milestone, '>')) {
309
+				return $version;
310
+			}
311
+		}
312
+
313
+		throw new RuntimeException('Could not satisfy version requirements.');
314
+	}
315
+
316
+	/**
317
+	 * Get a version lesser than the milestone.
318
+	 *
319
+	 * @since 0.2.4
320
+	 *
321
+	 * @param string $milestone A version milestone that is used to define the requirement.
322
+	 *
323
+	 * @return string Version number that meets the requirement.
324
+	 * @throws RuntimeException If the requirement could not be satisfied.
325
+	 */
326
+	protected function getLesserThanVersion($milestone)
327
+	{
328
+		if (version_compare($this->version->getVersion(), $milestone, '<')) {
329
+			return $this->version->getVersion();
330
+		}
331
+		$data = array_reverse($this->releases->getAll());
332
+		foreach ($data as $version => $date) {
333
+			if (version_compare($version, $milestone, '<')) {
334
+				return $version;
335
+			}
336
+		}
337
+
338
+		throw new RuntimeException('Could not satisfy version requirements.');
339
+	}
340
+
341
+	/**
342
+	 * Get a version greater or equal than the milestone.
343
+	 *
344
+	 * @since 0.2.4
345
+	 *
346
+	 * @param string $milestone A version milestone that is used to define the requirement.
347
+	 *
348
+	 * @return string Version number that meets the requirement.
349
+	 */
350
+	protected function getGreaterEqualVersion($milestone)
351
+	{
352
+		if ($this->releases->exists($milestone)) {
353
+			return $milestone;
354
+		}
355
+
356
+		$data = $this->releases->getAll();
357
+		foreach ($data as $version => $date) {
358
+			if (version_compare($version, $milestone, '>=')) {
359
+				return $version;
360
+			}
361
+		}
362
+
363
+		throw new RuntimeException('Could not satisfy version requirements.');
364
+	}
365
+
366
+	/**
367
+	 * Get a version lesser or equal than the milestone.
368
+	 *
369
+	 * @since 0.2.4
370
+	 *
371
+	 * @param string $milestone A version milestone that is used to define the requirement.
372
+	 *
373
+	 * @return string Version number that meets the requirement.
374
+	 */
375
+	protected function getLesserEqualVersion($milestone)
376
+	{
377
+		if (version_compare($this->version->getVersion(), $milestone, '<=')) {
378
+			return $this->version->getVersion();
379
+		}
380
+
381
+		$data = array_reverse($this->releases->getAll());
382
+		foreach ($data as $version => $date) {
383
+			if (version_compare($version, $milestone, '<=')) {
384
+				return $version;
385
+			}
386
+		}
387
+
388
+		throw new RuntimeException('Could not satisfy version requirements.');
389
+	}
390 390
 }
Please login to merge, or discard this patch.