PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 10.9.3
WooCommerce v10.9.3
10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / lib / packages / GraphQL / Utils / Utils.php
woocommerce / lib / packages / GraphQL / Utils Last commit date
AST.php 2 months ago ASTDefinitionBuilder.php 2 months ago BreakingChangesFinder.php 2 months ago BuildClientSchema.php 2 months ago BuildSchema.php 2 months ago InterfaceImplementations.php 2 months ago LazyException.php 2 months ago LexicalDistance.php 2 months ago MixedStore.php 2 months ago PairSet.php 2 months ago PhpDoc.php 2 months ago SchemaExtender.php 2 months ago SchemaPrinter.php 2 months ago TypeComparators.php 2 months ago TypeInfo.php 2 months ago Utils.php 2 months ago Value.php 2 months ago
Utils.php
295 lines
1 <?php declare(strict_types=1);
2
3 namespace Automattic\WooCommerce\Vendor\GraphQL\Utils;
4
5 use Automattic\WooCommerce\Vendor\GraphQL\Error\Error;
6 use Automattic\WooCommerce\Vendor\GraphQL\Error\Warning;
7 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\Node;
8
9 class Utils
10 {
11 public static function undefined(): \stdClass
12 {
13 static $undefined;
14
15 return $undefined ??= new \stdClass();
16 }
17
18 /** @param array<string, mixed> $vars */
19 public static function assign(object $obj, array $vars): object
20 {
21 foreach ($vars as $key => $value) {
22 if (! property_exists($obj, $key)) {
23 $cls = get_class($obj);
24 Warning::warn(
25 "Trying to set non-existing property '{$key}' on class '{$cls}'",
26 Warning::WARNING_ASSIGN
27 );
28 }
29
30 $obj->{$key} = $value;
31 }
32
33 return $obj;
34 }
35
36 /**
37 * Print a value that came from JSON for debugging purposes.
38 *
39 * @param mixed $value
40 */
41 public static function printSafeJson($value): string
42 {
43 if ($value instanceof \stdClass) {
44 return static::jsonEncodeOrSerialize($value);
45 }
46
47 return static::printSafeInternal($value);
48 }
49
50 /**
51 * Print a value that came from PHP for debugging purposes.
52 *
53 * @param mixed $value
54 */
55 public static function printSafe($value): string
56 {
57 if (is_object($value)) {
58 if (method_exists($value, '__toString')) {
59 return $value->__toString();
60 }
61
62 return 'instance of ' . get_class($value);
63 }
64
65 return static::printSafeInternal($value);
66 }
67
68 /** @param \stdClass|array<mixed> $value */
69 protected static function jsonEncodeOrSerialize($value): string
70 {
71 try {
72 return json_encode($value, JSON_THROW_ON_ERROR);
73 } catch (\JsonException $jsonException) {
74 return serialize($value);
75 }
76 }
77
78 /** @param mixed $value */
79 protected static function printSafeInternal($value): string
80 {
81 if (is_array($value)) {
82 return static::jsonEncodeOrSerialize($value);
83 }
84
85 if ($value === '') {
86 return '(empty string)';
87 }
88
89 if ($value === null) {
90 return 'null';
91 }
92
93 if ($value === false) {
94 return 'false';
95 }
96
97 if ($value === true) {
98 return 'true';
99 }
100
101 if (is_string($value)) {
102 return "\"{$value}\"";
103 }
104
105 if (is_scalar($value)) {
106 return (string) $value;
107 }
108
109 return gettype($value);
110 }
111
112 /** UTF-8 compatible chr(). */
113 public static function chr(int $ord, string $encoding = 'UTF-8'): string
114 {
115 if ($encoding === 'UCS-4BE') {
116 return pack('N', $ord);
117 }
118
119 return mb_convert_encoding(self::chr($ord, 'UCS-4BE'), $encoding, 'UCS-4BE');
120 }
121
122 /** UTF-8 compatible ord(). */
123 public static function ord(string $char, string $encoding = 'UTF-8'): int
124 {
125 if (! isset($char[1])) {
126 return ord($char);
127 }
128
129 if ($encoding !== 'UCS-4BE') {
130 $char = mb_convert_encoding($char, 'UCS-4BE', $encoding);
131 assert(is_string($char), 'format string is statically known to be correct');
132 }
133
134 $unpacked = unpack('N', $char);
135 assert(is_array($unpacked), 'format string is statically known to be correct');
136
137 return $unpacked[1];
138 }
139
140 /** Returns UTF-8 char code at given $positing of the $string. */
141 public static function charCodeAt(string $string, int $position): int
142 {
143 $char = mb_substr($string, $position, 1, 'UTF-8');
144
145 return self::ord($char);
146 }
147
148 /** @throws \JsonException */
149 public static function printCharCode(?int $code): string
150 {
151 if ($code === null) {
152 return '<EOF>';
153 }
154
155 return $code < 0x007F
156 // Trust JSON for ASCII
157 ? json_encode(self::chr($code), JSON_THROW_ON_ERROR)
158 // Otherwise, print the escaped form
159 : '"\\u' . dechex($code) . '"';
160 }
161
162 /**
163 * Upholds the spec rules about naming.
164 *
165 * @throws Error
166 */
167 public static function assertValidName(string $name): void
168 {
169 $error = self::isValidNameError($name);
170 if ($error !== null) {
171 throw $error;
172 }
173 }
174
175 /** Returns an Error if a name is invalid. */
176 public static function isValidNameError(string $name, ?Node $node = null): ?Error
177 {
178 if (isset($name[1]) && $name[0] === '_' && $name[1] === '_') {
179 return new Error(
180 "Name \"{$name}\" must not begin with \"__\", which is reserved by Automattic\WooCommerce\Vendor\GraphQL introspection.",
181 $node
182 );
183 }
184
185 if (preg_match('/^[_a-zA-Z][_a-zA-Z0-9]*$/', $name) !== 1) {
186 return new Error(
187 "Names must match /^[_a-zA-Z][_a-zA-Z0-9]*\$/ but \"{$name}\" does not.",
188 $node
189 );
190 }
191
192 return null;
193 }
194
195 /** @param array<string> $items */
196 public static function quotedOrList(array $items): string
197 {
198 $quoted = array_map(
199 static fn (string $item): string => "\"{$item}\"",
200 $items
201 );
202
203 return self::orList($quoted);
204 }
205
206 /** @param array<string> $items */
207 public static function orList(array $items): string
208 {
209 if ($items === []) {
210 return '';
211 }
212
213 $selected = array_slice($items, 0, 5);
214 $selectedLength = count($selected);
215 $firstSelected = $selected[0];
216
217 if ($selectedLength === 1) {
218 return $firstSelected;
219 }
220
221 return array_reduce(
222 range(1, $selectedLength - 1),
223 static fn ($list, $index): string => $list
224 . ($selectedLength > 2 ? ', ' : ' ')
225 . ($index === $selectedLength - 1 ? 'or ' : '')
226 . $selected[$index],
227 $firstSelected
228 );
229 }
230
231 /**
232 * Given an invalid input string and a list of valid options, returns a filtered
233 * list of valid options sorted based on their similarity with the input.
234 *
235 * @param array<string> $options
236 *
237 * @return array<int, string>
238 */
239 public static function suggestionList(string $input, array $options): array
240 {
241 /** @var array<string, int> $optionsByDistance */
242 $optionsByDistance = [];
243 $lexicalDistance = new LexicalDistance($input);
244 $threshold = mb_strlen($input) * 0.4 + 1;
245 foreach ($options as $option) {
246 $distance = $lexicalDistance->measure($option, $threshold);
247
248 if ($distance !== null) {
249 $optionsByDistance[$option] = $distance;
250 }
251 }
252
253 uksort($optionsByDistance, static function (string $a, string $b) use ($optionsByDistance) {
254 $distanceDiff = $optionsByDistance[$a] - $optionsByDistance[$b];
255
256 return $distanceDiff !== 0 ? $distanceDiff : strnatcmp($a, $b);
257 });
258
259 return array_map('strval', array_keys($optionsByDistance));
260 }
261
262 /**
263 * Try to extract the value for a key from an object like value.
264 *
265 * @param mixed $objectLikeValue
266 *
267 * @return mixed
268 */
269 public static function extractKey($objectLikeValue, string $key)
270 {
271 if (is_array($objectLikeValue) || $objectLikeValue instanceof \ArrayAccess) {
272 return $objectLikeValue[$key] ?? null;
273 }
274
275 if (is_object($objectLikeValue)) {
276 return $objectLikeValue->{$key} ?? null;
277 }
278
279 return null;
280 }
281
282 /**
283 * Split a string that has either Unix, Windows or Mac style newlines into lines.
284 *
285 * @return list<string>
286 */
287 public static function splitLines(string $value): array
288 {
289 $lines = preg_split("/\r\n|\r|\n/", $value);
290 assert(is_array($lines), 'given the regex is valid');
291
292 return $lines;
293 }
294 }
295