PluginProbe ʕ •ᴥ•ʔ
Kubio AI Page Builder / 2.8.6
Kubio AI Page Builder v2.8.6
2.8.6 2.8.5 2.8.4 2.8.3 2.8.2 2.8.1 trunk 1.0.0 1.0.1 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.9.0 2.0.0 2.1.1 2.1.2 2.1.3 2.2.0 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.5 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1 2.6.2 2.6.3 2.6.5 2.6.6 2.6.7 2.7.0 2.7.1 2.7.2 2.7.3 2.8.0
kubio / vendor / sebastian / recursion-context / src / Context.php
kubio / vendor / sebastian / recursion-context / src Last commit date
Context.php 1 year ago Exception.php 1 year ago InvalidArgumentException.php 1 year ago
Context.php
192 lines
1 <?php declare(strict_types=1);
2 /*
3 * This file is part of sebastian/recursion-context.
4 *
5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10 namespace SebastianBergmann\RecursionContext;
11
12 use const PHP_INT_MAX;
13 use const PHP_INT_MIN;
14 use function array_key_exists;
15 use function array_pop;
16 use function array_slice;
17 use function count;
18 use function is_array;
19 use function is_object;
20 use function random_int;
21 use function spl_object_hash;
22 use SplObjectStorage;
23
24 /**
25 * A context containing previously processed arrays and objects
26 * when recursively processing a value.
27 */
28 final class Context
29 {
30 /**
31 * @var array[]
32 */
33 private $arrays;
34
35 /**
36 * @var SplObjectStorage
37 */
38 private $objects;
39
40 /**
41 * Initialises the context.
42 */
43 public function __construct()
44 {
45 $this->arrays = [];
46 $this->objects = new SplObjectStorage;
47 }
48
49 /**
50 * @codeCoverageIgnore
51 */
52 public function __destruct()
53 {
54 foreach ($this->arrays as &$array) {
55 if (is_array($array)) {
56 array_pop($array);
57 array_pop($array);
58 }
59 }
60 }
61
62 /**
63 * Adds a value to the context.
64 *
65 * @param array|object $value the value to add
66 *
67 * @throws InvalidArgumentException Thrown if $value is not an array or object
68 *
69 * @return bool|int|string the ID of the stored value, either as a string or integer
70 *
71 * @psalm-template T
72 * @psalm-param T $value
73 * @param-out T $value
74 */
75 public function add(&$value)
76 {
77 if (is_array($value)) {
78 return $this->addArray($value);
79 }
80
81 if (is_object($value)) {
82 return $this->addObject($value);
83 }
84
85 throw new InvalidArgumentException(
86 'Only arrays and objects are supported'
87 );
88 }
89
90 /**
91 * Checks if the given value exists within the context.
92 *
93 * @param array|object $value the value to check
94 *
95 * @throws InvalidArgumentException Thrown if $value is not an array or object
96 *
97 * @return false|int|string the string or integer ID of the stored value if it has already been seen, or false if the value is not stored
98 *
99 * @psalm-template T
100 * @psalm-param T $value
101 * @param-out T $value
102 */
103 public function contains(&$value)
104 {
105 if (is_array($value)) {
106 return $this->containsArray($value);
107 }
108
109 if (is_object($value)) {
110 return $this->containsObject($value);
111 }
112
113 throw new InvalidArgumentException(
114 'Only arrays and objects are supported'
115 );
116 }
117
118 /**
119 * @return bool|int
120 */
121 private function addArray(array &$array)
122 {
123 $key = $this->containsArray($array);
124
125 if ($key !== false) {
126 return $key;
127 }
128
129 $key = count($this->arrays);
130 $this->arrays[] = &$array;
131
132 if (!array_key_exists(PHP_INT_MAX, $array) && !array_key_exists(PHP_INT_MAX - 1, $array)) {
133 $array[] = $key;
134 $array[] = $this->objects;
135 } else { /* cover the improbable case too */
136 /* Note that array_slice (used in containsArray) will return the
137 * last two values added *not necessarily* the highest integer
138 * keys in the array, so the order of these writes to $array
139 * is important, but the actual keys used is not. */
140 do {
141 $key = random_int(PHP_INT_MIN, PHP_INT_MAX);
142 } while (array_key_exists($key, $array));
143
144 $array[$key] = $key;
145
146 do {
147 $key = random_int(PHP_INT_MIN, PHP_INT_MAX);
148 } while (array_key_exists($key, $array));
149
150 $array[$key] = $this->objects;
151 }
152
153 return $key;
154 }
155
156 /**
157 * @param object $object
158 */
159 private function addObject($object): string
160 {
161 if (!$this->objects->contains($object)) {
162 $this->objects->attach($object);
163 }
164
165 return spl_object_hash($object);
166 }
167
168 /**
169 * @return false|int
170 */
171 private function containsArray(array &$array)
172 {
173 $end = array_slice($array, -2);
174
175 return isset($end[1]) && $end[1] === $this->objects ? $end[0] : false;
176 }
177
178 /**
179 * @param object $value
180 *
181 * @return false|string
182 */
183 private function containsObject($value)
184 {
185 if ($this->objects->contains($value)) {
186 return spl_object_hash($value);
187 }
188
189 return false;
190 }
191 }
192