Completed
Push — master ( a18a85...88c1b8 )
by Morris
134:26 queued 114:58
created

CompareVersion::compareMajorMinorPatch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 3
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @copyright 2018 Christoph Wurst <[email protected]>
5
 *
6
 * @author 2018 Christoph Wurst <[email protected]>
7
 *
8
 * @license GNU AGPL version 3 or any later version
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License as
12
 * published by the Free Software Foundation, either version 3 of the
13
 * License, or (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 */
24
25
namespace OC\App;
26
27
use InvalidArgumentException;
28
29
class CompareVersion {
30
31
	const REGEX_MAJOR = '/^\d+$/';
32
	const REGEX_MAJOR_MINOR = '/^\d+.\d+$/';
33
	const REGEX_MAJOR_MINOR_PATCH = '/^\d+.\d+.\d+$/';
34
	const REGEX_SERVER = '/^\d+.\d+.\d+(.\d+)?$/';
35
36
	/**
37
	 * Checks if the given server version fulfills the given (app) version requirements.
38
	 *
39
	 * Version requirements can be 'major.minor.patch', 'major.minor' or just 'major',
40
	 * so '13.0.1', '13.0' and '13' are valid.
41
	 *
42
	 * @param string $actual version as major.minor.patch notation
43
	 * @param string $required version where major is requried and minor and patch are optional
44
	 * @param string $comparator passed to `version_compare`
45
	 * @return bool whether the requirement is fulfilled
46
	 * @throws InvalidArgumentException if versions specified in an invalid format
47
	 */
48
	public function isCompatible(string $actual, string $required,
49
		string $comparator = '>='): bool {
50
51
		if (!preg_match(self::REGEX_SERVER, $actual)) {
52
			throw new InvalidArgumentException('server version is invalid');
53
		}
54
55
		if (preg_match(self::REGEX_MAJOR, $required) === 1) {
56
			return $this->compareMajor($actual, $required, $comparator);
57
		} else if (preg_match(self::REGEX_MAJOR_MINOR, $required) === 1) {
58
			return $this->compareMajorMinor($actual, $required, $comparator);
59
		} else if (preg_match(self::REGEX_MAJOR_MINOR_PATCH, $required) === 1) {
60
			return $this->compareMajorMinorPatch($actual, $required, $comparator);
61
		} else {
62
			throw new InvalidArgumentException('required version is invalid');
63
		}
64
	}
65
66
	private function compareMajor(string $actual, string $required,
67
		string $comparator) {
68
		$actualMajor = explode('.', $actual)[0];
69
		$requiredMajor = explode('.', $required)[0];
70
71
		return version_compare($actualMajor, $requiredMajor, $comparator);
72
	}
73
74
	private function compareMajorMinor(string $actual, string $required,
75
		string $comparator) {
76
		$actualMajor = explode('.', $actual)[0];
77
		$actualMinor = explode('.', $actual)[1];
78
		$requiredMajor = explode('.', $required)[0];
79
		$requiredMinor = explode('.', $required)[1];
80
81
		return version_compare("$actualMajor.$actualMinor",
82
			"$requiredMajor.$requiredMinor", $comparator);
83
	}
84
85
	private function compareMajorMinorPatch($actual, $required, $comparator) {
86
		$actualMajor = explode('.', $actual)[0];
87
		$actualMinor = explode('.', $actual)[1];
88
		$actualPatch = explode('.', $actual)[2];
89
		$requiredMajor = explode('.', $required)[0];
90
		$requiredMinor = explode('.', $required)[1];
91
		$requiredPatch = explode('.', $required)[2];
92
93
		return version_compare("$actualMajor.$actualMinor.$actualPatch",
94
			"$requiredMajor.$requiredMinor.$requiredPatch", $comparator);
95
	}
96
97
}
98