Chris@18
|
1 <?php
|
Chris@18
|
2
|
Chris@18
|
3 namespace Drupal\Component\Version;
|
Chris@18
|
4
|
Chris@18
|
5 /**
|
Chris@18
|
6 * A value object representing a Drupal version constraint.
|
Chris@18
|
7 */
|
Chris@18
|
8 class Constraint {
|
Chris@18
|
9
|
Chris@18
|
10 /**
|
Chris@18
|
11 * The constraint represented as a string. For example '>=8.x-5.x'.
|
Chris@18
|
12 *
|
Chris@18
|
13 * @var string
|
Chris@18
|
14 */
|
Chris@18
|
15 protected $constraint;
|
Chris@18
|
16
|
Chris@18
|
17 /**
|
Chris@18
|
18 * A list of associative arrays representing the constraint.
|
Chris@18
|
19 *
|
Chris@18
|
20 * Each containing the keys:
|
Chris@18
|
21 * - 'op': can be one of: '=', '==', '!=', '<>', '<', '<=', '>', or '>='.
|
Chris@18
|
22 * - 'version': A complete version, e.g. '4.5-beta3'.
|
Chris@18
|
23 *
|
Chris@18
|
24 * @var array[]
|
Chris@18
|
25 */
|
Chris@18
|
26 protected $constraintArray = [];
|
Chris@18
|
27
|
Chris@18
|
28 /**
|
Chris@18
|
29 * Constraint constructor.
|
Chris@18
|
30 *
|
Chris@18
|
31 * @param string $constraint
|
Chris@18
|
32 * The constraint string to create the object from. For example, '>8.x-1.1'.
|
Chris@18
|
33 * @param string $core_compatibility
|
Chris@18
|
34 * Core compatibility declared for the current version of Drupal core.
|
Chris@18
|
35 * Normally this is set to \Drupal::CORE_COMPATIBILITY by the caller.
|
Chris@18
|
36 */
|
Chris@18
|
37 public function __construct($constraint, $core_compatibility) {
|
Chris@18
|
38 $this->constraint = $constraint;
|
Chris@18
|
39 $this->parseConstraint($constraint, $core_compatibility);
|
Chris@18
|
40 }
|
Chris@18
|
41
|
Chris@18
|
42 /**
|
Chris@18
|
43 * Gets the constraint as a string.
|
Chris@18
|
44 *
|
Chris@18
|
45 * Can be used in the UI for reporting incompatibilities.
|
Chris@18
|
46 *
|
Chris@18
|
47 * @return string
|
Chris@18
|
48 * The constraint as a string.
|
Chris@18
|
49 */
|
Chris@18
|
50 public function __toString() {
|
Chris@18
|
51 return $this->constraint;
|
Chris@18
|
52 }
|
Chris@18
|
53
|
Chris@18
|
54 /**
|
Chris@18
|
55 * A list of associative arrays representing the constraint.
|
Chris@18
|
56 *
|
Chris@18
|
57 * Each containing the keys:
|
Chris@18
|
58 * - 'op': can be one of: '=', '==', '!=', '<>', '<', '<=', '>', or '>='.
|
Chris@18
|
59 * - 'version': A complete version, e.g. '4.5-beta3'.
|
Chris@18
|
60 *
|
Chris@18
|
61 * @return array[]
|
Chris@18
|
62 * The constraint represented as an array.
|
Chris@18
|
63 *
|
Chris@18
|
64 * @deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0.
|
Chris@18
|
65 * Only exists to provide a backwards compatibility layer.
|
Chris@18
|
66 *
|
Chris@18
|
67 * @see https://www.drupal.org/node/2756875
|
Chris@18
|
68 */
|
Chris@18
|
69 public function toArray() {
|
Chris@18
|
70 @trigger_error(sprintf('%s() only exists to provide a backwards compatibility layer. See https://www.drupal.org/node/2756875', __METHOD__), E_USER_DEPRECATED);
|
Chris@18
|
71 return $this->constraintArray;
|
Chris@18
|
72 }
|
Chris@18
|
73
|
Chris@18
|
74 /**
|
Chris@18
|
75 * Determines if the provided version is satisfied by this constraint.
|
Chris@18
|
76 *
|
Chris@18
|
77 * @param string $version
|
Chris@18
|
78 * The version to check, for example '4.2'.
|
Chris@18
|
79 *
|
Chris@18
|
80 * @return bool
|
Chris@18
|
81 * TRUE if the provided version is satisfied by this constraint, FALSE if
|
Chris@18
|
82 * not.
|
Chris@18
|
83 */
|
Chris@18
|
84 public function isCompatible($version) {
|
Chris@18
|
85 foreach ($this->constraintArray as $constraint) {
|
Chris@18
|
86 if (!version_compare($version, $constraint['version'], $constraint['op'])) {
|
Chris@18
|
87 return FALSE;
|
Chris@18
|
88 }
|
Chris@18
|
89 }
|
Chris@18
|
90 return TRUE;
|
Chris@18
|
91 }
|
Chris@18
|
92
|
Chris@18
|
93 /**
|
Chris@18
|
94 * Parses a constraint string.
|
Chris@18
|
95 *
|
Chris@18
|
96 * @param string $constraint_string
|
Chris@18
|
97 * The constraint string to parse.
|
Chris@18
|
98 * @param string $core_compatibility
|
Chris@18
|
99 * Core compatibility declared for the current version of Drupal core.
|
Chris@18
|
100 * Normally this is set to \Drupal::CORE_COMPATIBILITY by the caller.
|
Chris@18
|
101 */
|
Chris@18
|
102 private function parseConstraint($constraint_string, $core_compatibility) {
|
Chris@18
|
103 // We use named subpatterns and support every op that version_compare
|
Chris@18
|
104 // supports. Also, op is optional and defaults to equals.
|
Chris@18
|
105 $p_op = '(?<operation>!=|==|=|<|<=|>|>=|<>)?';
|
Chris@18
|
106 // Core version is always optional: 8.x-2.x and 2.x is treated the same.
|
Chris@18
|
107 $p_core = '(?:' . preg_quote($core_compatibility) . '-)?';
|
Chris@18
|
108 $p_major = '(?<major>\d+)';
|
Chris@18
|
109 // By setting the minor version to x, branches can be matched.
|
Chris@18
|
110 $p_minor = '(?<minor>(?:\d+|x)(?:-[A-Za-z]+\d+)?)';
|
Chris@18
|
111 foreach (explode(',', $constraint_string) as $constraint) {
|
Chris@18
|
112 if (preg_match("/^\s*$p_op\s*$p_core$p_major\.$p_minor/", $constraint, $matches)) {
|
Chris@18
|
113 $op = !empty($matches['operation']) ? $matches['operation'] : '=';
|
Chris@18
|
114 if ($matches['minor'] == 'x') {
|
Chris@18
|
115 // Drupal considers "2.x" to mean any version that begins with
|
Chris@18
|
116 // "2" (e.g. 2.0, 2.9 are all "2.x"). PHP's version_compare(),
|
Chris@18
|
117 // on the other hand, treats "x" as a string; so to
|
Chris@18
|
118 // version_compare(), "2.x" is considered less than 2.0. This
|
Chris@18
|
119 // means that >=2.x and <2.x are handled by version_compare()
|
Chris@18
|
120 // as we need, but > and <= are not.
|
Chris@18
|
121 if ($op == '>' || $op == '<=') {
|
Chris@18
|
122 $matches['major']++;
|
Chris@18
|
123 }
|
Chris@18
|
124 // Equivalence can be checked by adding two restrictions.
|
Chris@18
|
125 if ($op == '=' || $op == '==') {
|
Chris@18
|
126 $this->constraintArray[] = ['op' => '<', 'version' => ($matches['major'] + 1) . '.x'];
|
Chris@18
|
127 $op = '>=';
|
Chris@18
|
128 }
|
Chris@18
|
129 }
|
Chris@18
|
130 $this->constraintArray[] = ['op' => $op, 'version' => $matches['major'] . '.' . $matches['minor']];
|
Chris@18
|
131 }
|
Chris@18
|
132 }
|
Chris@18
|
133 }
|
Chris@18
|
134
|
Chris@18
|
135 }
|