PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.20
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.20
1.10.20 1.10.19 1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 All 164 releases
woocommerce-pos / vendor / ramsey / uuid / src / Uuid.php

Uuid.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.20, at vendor/ramsey/uuid/src/Uuid.php

665 lines 21.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * This file is part of the ramsey/uuid library
5 *
6 * For the full copyright and license information, please view the LICENSE
7 * file that was distributed with this source code.
8 *
9 * @copyright Copyright (c) Ben Ramsey <[email protected]>
10 * @license http://opensource.org/licenses/MIT MIT
11 */
12
13 declare(strict_types=1);
14
15 namespace Ramsey\Uuid;
16
17 use DateTimeInterface;
18 use Ramsey\Uuid\Codec\CodecInterface;
19 use Ramsey\Uuid\Converter\NumberConverterInterface;
20 use Ramsey\Uuid\Converter\TimeConverterInterface;
21 use Ramsey\Uuid\Fields\FieldsInterface;
22 use Ramsey\Uuid\Lazy\LazyUuidFromString;
23 use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface;
24 use Ramsey\Uuid\Type\Hexadecimal;
25 use Ramsey\Uuid\Type\Integer as IntegerObject;
26 use ValueError;
27
28 use function assert;
29 use function bin2hex;
30 use function preg_match;
31 use function sprintf;
32 use function str_replace;
33 use function strcmp;
34 use function strlen;
35 use function strtolower;
36 use function substr;
37
38 /**
39 * Uuid provides constants and static methods for working with and generating UUIDs
40 *
41 * @psalm-immutable
42 */
43 class Uuid implements UuidInterface
44 {
45 use DeprecatedUuidMethodsTrait;
46
47 /**
48 * When this namespace is specified, the name string is a fully-qualified
49 * domain name
50 *
51 * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs
52 */
53 public const NAMESPACE_DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
54
55 /**
56 * When this namespace is specified, the name string is a URL
57 *
58 * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs
59 */
60 public const NAMESPACE_URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
61
62 /**
63 * When this namespace is specified, the name string is an ISO OID
64 *
65 * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs
66 */
67 public const NAMESPACE_OID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8';
68
69 /**
70 * When this namespace is specified, the name string is an X.500 DN in DER
71 * or a text output format
72 *
73 * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs
74 */
75 public const NAMESPACE_X500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8';
76
77 /**
78 * The nil UUID is a special form of UUID that is specified to have all 128
79 * bits set to zero
80 *
81 * @link http://tools.ietf.org/html/rfc4122#section-4.1.7 RFC 4122, § 4.1.7: Nil UUID
82 */
83 public const NIL = '00000000-0000-0000-0000-000000000000';
84
85 /**
86 * Variant: reserved, NCS backward compatibility
87 *
88 * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant
89 */
90 public const RESERVED_NCS = 0;
91
92 /**
93 * Variant: the UUID layout specified in RFC 4122
94 *
95 * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant
96 */
97 public const RFC_4122 = 2;
98
99 /**
100 * Variant: reserved, Microsoft Corporation backward compatibility
101 *
102 * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant
103 */
104 public const RESERVED_MICROSOFT = 6;
105
106 /**
107 * Variant: reserved for future definition
108 *
109 * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant
110 */
111 public const RESERVED_FUTURE = 7;
112
113 /**
114 * @deprecated Use {@see ValidatorInterface::getPattern()} instead.
115 */
116 public const VALID_PATTERN = '^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$';
117
118 /**
119 * Version 1 (time-based) UUID
120 *
121 * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version
122 */
123 public const UUID_TYPE_TIME = 1;
124
125 /**
126 * Version 2 (DCE Security) UUID
127 *
128 * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version
129 */
130 public const UUID_TYPE_DCE_SECURITY = 2;
131
132 /**
133 * @deprecated Use {@see Uuid::UUID_TYPE_DCE_SECURITY} instead.
134 */
135 public const UUID_TYPE_IDENTIFIER = 2;
136
137 /**
138 * Version 3 (name-based and hashed with MD5) UUID
139 *
140 * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version
141 */
142 public const UUID_TYPE_HASH_MD5 = 3;
143
144 /**
145 * Version 4 (random) UUID
146 *
147 * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version
148 */
149 public const UUID_TYPE_RANDOM = 4;
150
151 /**
152 * Version 5 (name-based and hashed with SHA1) UUID
153 *
154 * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version
155 */
156 public const UUID_TYPE_HASH_SHA1 = 5;
157
158 /**
159 * Version 6 (ordered-time) UUID
160 *
161 * This is named `UUID_TYPE_PEABODY`, since the specification is still in
162 * draft form, and the primary author/editor's name is Brad Peabody.
163 *
164 * @link https://github.com/uuid6/uuid6-ietf-draft UUID version 6 IETF draft
165 * @link http://gh.peabody.io/uuidv6/ "Version 6" UUIDs
166 */
167 public const UUID_TYPE_PEABODY = 6;
168
169 /**
170 * DCE Security principal domain
171 *
172 * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1
173 */
174 public const DCE_DOMAIN_PERSON = 0;
175
176 /**
177 * DCE Security group domain
178 *
179 * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1
180 */
181 public const DCE_DOMAIN_GROUP = 1;
182
183 /**
184 * DCE Security organization domain
185 *
186 * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1
187 */
188 public const DCE_DOMAIN_ORG = 2;
189
190 /**
191 * DCE Security domain string names
192 *
193 * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1
194 */
195 public const DCE_DOMAIN_NAMES = [
196 self::DCE_DOMAIN_PERSON => 'person',
197 self::DCE_DOMAIN_GROUP => 'group',
198 self::DCE_DOMAIN_ORG => 'org',
199 ];
200
201 /**
202 * @var UuidFactoryInterface|null
203 */
204 private static $factory = null;
205
206 /**
207 * @var bool flag to detect if the UUID factory was replaced internally, which disables all optimizations
208 * for the default/happy path internal scenarios
209 */
210 private static $factoryReplaced = false;
211
212 /**
213 * @var CodecInterface
214 */
215 protected $codec;
216
217 /**
218 * The fields that make up this UUID
219 *
220 * @var Rfc4122FieldsInterface
221 */
222 protected $fields;
223
224 /**
225 * @var NumberConverterInterface
226 */
227 protected $numberConverter;
228
229 /**
230 * @var TimeConverterInterface
231 */
232 protected $timeConverter;
233
234 /**
235 * Creates a universally unique identifier (UUID) from an array of fields
236 *
237 * Unless you're making advanced use of this library to generate identifiers
238 * that deviate from RFC 4122, you probably do not want to instantiate a
239 * UUID directly. Use the static methods, instead:
240 *
241 * ```
242 * use Ramsey\Uuid\Uuid;
243 *
244 * $timeBasedUuid = Uuid::uuid1();
245 * $namespaceMd5Uuid = Uuid::uuid3(Uuid::NAMESPACE_URL, 'http://php.net/');
246 * $randomUuid = Uuid::uuid4();
247 * $namespaceSha1Uuid = Uuid::uuid5(Uuid::NAMESPACE_URL, 'http://php.net/');
248 * ```
249 *
250 * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID
251 * @param NumberConverterInterface $numberConverter The number converter to use
252 * for converting hex values to/from integers
253 * @param CodecInterface $codec The codec to use when encoding or decoding
254 * UUID strings
255 * @param TimeConverterInterface $timeConverter The time converter to use
256 * for converting timestamps extracted from a UUID to unix timestamps
257 */
258 public function __construct(
259 Rfc4122FieldsInterface $fields,
260 NumberConverterInterface $numberConverter,
261 CodecInterface $codec,
262 TimeConverterInterface $timeConverter
263 ) {
264 $this->fields = $fields;
265 $this->codec = $codec;
266 $this->numberConverter = $numberConverter;
267 $this->timeConverter = $timeConverter;
268 }
269
270 /**
271 * @psalm-return non-empty-string
272 */
273 public function __toString(): string
274 {
275 return $this->toString();
276 }
277
278 /**
279 * Converts the UUID to a string for JSON serialization
280 */
281 public function jsonSerialize(): string
282 {
283 return $this->toString();
284 }
285
286 /**
287 * Converts the UUID to a string for PHP serialization
288 */
289 public function serialize(): string
290 {
291 return $this->getFields()->getBytes();
292 }
293
294 /**
295 * @return array{bytes: string}
296 */
297 public function __serialize(): array
298 {
299 return ['bytes' => $this->serialize()];
300 }
301
302 /**
303 * Re-constructs the object from its serialized form
304 *
305 * @param string $serialized The serialized PHP string to unserialize into
306 * a UuidInterface instance
307 *
308 * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
309 */
310 public function unserialize($serialized): void
311 {
312 if (strlen($serialized) === 16) {
313 /** @var Uuid $uuid */
314 $uuid = self::getFactory()->fromBytes($serialized);
315 } else {
316 /** @var Uuid $uuid */
317 $uuid = self::getFactory()->fromString($serialized);
318 }
319
320 $this->codec = $uuid->codec;
321 $this->numberConverter = $uuid->numberConverter;
322 $this->fields = $uuid->fields;
323 $this->timeConverter = $uuid->timeConverter;
324 }
325
326 /**
327 * @param array{bytes: string} $data
328 */
329 public function __unserialize(array $data): void
330 {
331 // @codeCoverageIgnoreStart
332 if (!isset($data['bytes'])) {
333 throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__));
334 }
335 // @codeCoverageIgnoreEnd
336
337 $this->unserialize($data['bytes']);
338 }
339
340 public function compareTo(UuidInterface $other): int
341 {
342 $compare = strcmp($this->toString(), $other->toString());
343
344 if ($compare < 0) {
345 return -1;
346 }
347
348 if ($compare > 0) {
349 return 1;
350 }
351
352 return 0;
353 }
354
355 public function equals(?object $other): bool
356 {
357 if (!$other instanceof UuidInterface) {
358 return false;
359 }
360
361 return $this->compareTo($other) === 0;
362 }
363
364 /**
365 * @psalm-return non-empty-string
366 */
367 public function getBytes(): string
368 {
369 return $this->codec->encodeBinary($this);
370 }
371
372 public function getFields(): FieldsInterface
373 {
374 return $this->fields;
375 }
376
377 public function getHex(): Hexadecimal
378 {
379 return new Hexadecimal(str_replace('-', '', $this->toString()));
380 }
381
382 public function getInteger(): IntegerObject
383 {
384 return new IntegerObject($this->numberConverter->fromHex($this->getHex()->toString()));
385 }
386
387 /**
388 * @psalm-return non-empty-string
389 */
390 public function toString(): string
391 {
392 return $this->codec->encode($this);
393 }
394
395 /**
396 * Returns the factory used to create UUIDs
397 */
398 public static function getFactory(): UuidFactoryInterface
399 {
400 if (self::$factory === null) {
401 self::$factory = new UuidFactory();
402 }
403
404 return self::$factory;
405 }
406
407 /**
408 * Sets the factory used to create UUIDs
409 *
410 * @param UuidFactoryInterface $factory A factory that will be used by this
411 * class to create UUIDs
412 */
413 public static function setFactory(UuidFactoryInterface $factory): void
414 {
415 // Note: non-strict equality is intentional here. If the factory is configured differently, every assumption
416 // around purity is broken, and we have to internally decide everything differently.
417 // phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedNotEqualOperator
418 self::$factoryReplaced = ($factory != new UuidFactory());
419
420 self::$factory = $factory;
421 }
422
423 /**
424 * Creates a UUID from a byte string
425 *
426 * @param string $bytes A binary string
427 *
428 * @return UuidInterface A UuidInterface instance created from a binary
429 * string representation
430 *
431 * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
432 * but under constant factory setups, this method operates in functionally pure manners
433 *
434 * @psalm-suppress ImpureStaticProperty we know that the factory being replaced can lead to massive
435 * havoc across all consumers: that should never happen, and
436 * is generally to be discouraged. Until the factory is kept
437 * un-replaced, this method is effectively pure.
438 */
439 public static function fromBytes(string $bytes): UuidInterface
440 {
441 if (! self::$factoryReplaced && strlen($bytes) === 16) {
442 $base16Uuid = bin2hex($bytes);
443
444 // Note: we are calling `fromString` internally because we don't know if the given `$bytes` is a valid UUID
445 return self::fromString(
446 substr($base16Uuid, 0, 8)
447 . '-'
448 . substr($base16Uuid, 8, 4)
449 . '-'
450 . substr($base16Uuid, 12, 4)
451 . '-'
452 . substr($base16Uuid, 16, 4)
453 . '-'
454 . substr($base16Uuid, 20, 12)
455 );
456 }
457
458 return self::getFactory()->fromBytes($bytes);
459 }
460
461 /**
462 * Creates a UUID from the string standard representation
463 *
464 * @param string $uuid A hexadecimal string
465 *
466 * @return UuidInterface A UuidInterface instance created from a hexadecimal
467 * string representation
468 *
469 * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
470 * but under constant factory setups, this method operates in functionally pure manners
471 *
472 * @psalm-suppress ImpureStaticProperty we know that the factory being replaced can lead to massive
473 * havoc across all consumers: that should never happen, and
474 * is generally to be discouraged. Until the factory is kept
475 * un-replaced, this method is effectively pure.
476 */
477 public static function fromString(string $uuid): UuidInterface
478 {
479 if (! self::$factoryReplaced && preg_match(LazyUuidFromString::VALID_REGEX, $uuid) === 1) {
480 assert($uuid !== '');
481
482 return new LazyUuidFromString(strtolower($uuid));
483 }
484
485 return self::getFactory()->fromString($uuid);
486 }
487
488 /**
489 * Creates a UUID from a DateTimeInterface instance
490 *
491 * @param DateTimeInterface $dateTime The date and time
492 * @param Hexadecimal|null $node A 48-bit number representing the hardware
493 * address
494 * @param int|null $clockSeq A 14-bit number used to help avoid duplicates
495 * that could arise when the clock is set backwards in time or if the
496 * node ID changes
497 *
498 * @return UuidInterface A UuidInterface instance that represents a
499 * version 1 UUID created from a DateTimeInterface instance
500 */
501 public static function fromDateTime(
502 DateTimeInterface $dateTime,
503 ?Hexadecimal $node = null,
504 ?int $clockSeq = null
505 ): UuidInterface {
506 return self::getFactory()->fromDateTime($dateTime, $node, $clockSeq);
507 }
508
509 /**
510 * Creates a UUID from a 128-bit integer string
511 *
512 * @param string $integer String representation of 128-bit integer
513 *
514 * @return UuidInterface A UuidInterface instance created from the string
515 * representation of a 128-bit integer
516 *
517 * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
518 * but under constant factory setups, this method operates in functionally pure manners
519 */
520 public static function fromInteger(string $integer): UuidInterface
521 {
522 return self::getFactory()->fromInteger($integer);
523 }
524
525 /**
526 * Returns true if the provided string is a valid UUID
527 *
528 * @param string $uuid A string to validate as a UUID
529 *
530 * @return bool True if the string is a valid UUID, false otherwise
531 *
532 * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
533 * but under constant factory setups, this method operates in functionally pure manners
534 */
535 public static function isValid(string $uuid): bool
536 {
537 return self::getFactory()->getValidator()->validate($uuid);
538 }
539
540 /**
541 * Returns a version 1 (time-based) UUID from a host ID, sequence number,
542 * and the current time
543 *
544 * @param Hexadecimal|int|string|null $node A 48-bit number representing the
545 * hardware address; this number may be represented as an integer or a
546 * hexadecimal string
547 * @param int $clockSeq A 14-bit number used to help avoid duplicates that
548 * could arise when the clock is set backwards in time or if the node ID
549 * changes
550 *
551 * @return UuidInterface A UuidInterface instance that represents a
552 * version 1 UUID
553 */
554 public static function uuid1($node = null, ?int $clockSeq = null): UuidInterface
555 {
556 return self::getFactory()->uuid1($node, $clockSeq);
557 }
558
559 /**
560 * Returns a version 2 (DCE Security) UUID from a local domain, local
561 * identifier, host ID, clock sequence, and the current time
562 *
563 * @param int $localDomain The local domain to use when generating bytes,
564 * according to DCE Security
565 * @param IntegerObject|null $localIdentifier The local identifier for the
566 * given domain; this may be a UID or GID on POSIX systems, if the local
567 * domain is person or group, or it may be a site-defined identifier
568 * if the local domain is org
569 * @param Hexadecimal|null $node A 48-bit number representing the hardware
570 * address
571 * @param int|null $clockSeq A 14-bit number used to help avoid duplicates
572 * that could arise when the clock is set backwards in time or if the
573 * node ID changes (in a version 2 UUID, the lower 8 bits of this number
574 * are replaced with the domain).
575 *
576 * @return UuidInterface A UuidInterface instance that represents a
577 * version 2 UUID
578 */
579 public static function uuid2(
580 int $localDomain,
581 ?IntegerObject $localIdentifier = null,
582 ?Hexadecimal $node = null,
583 ?int $clockSeq = null
584 ): UuidInterface {
585 return self::getFactory()->uuid2($localDomain, $localIdentifier, $node, $clockSeq);
586 }
587
588 /**
589 * Returns a version 3 (name-based) UUID based on the MD5 hash of a
590 * namespace ID and a name
591 *
592 * @param string|UuidInterface $ns The namespace (must be a valid UUID)
593 * @param string $name The name to use for creating a UUID
594 *
595 * @return UuidInterface A UuidInterface instance that represents a
596 * version 3 UUID
597 *
598 * @psalm-suppress ImpureMethodCall we know that the factory being replaced can lead to massive
599 * havoc across all consumers: that should never happen, and
600 * is generally to be discouraged. Until the factory is kept
601 * un-replaced, this method is effectively pure.
602 *
603 * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
604 * but under constant factory setups, this method operates in functionally pure manners
605 */
606 public static function uuid3($ns, string $name): UuidInterface
607 {
608 return self::getFactory()->uuid3($ns, $name);
609 }
610
611 /**
612 * Returns a version 4 (random) UUID
613 *
614 * @return UuidInterface A UuidInterface instance that represents a
615 * version 4 UUID
616 */
617 public static function uuid4(): UuidInterface
618 {
619 return self::getFactory()->uuid4();
620 }
621
622 /**
623 * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a
624 * namespace ID and a name
625 *
626 * @param string|UuidInterface $ns The namespace (must be a valid UUID)
627 * @param string $name The name to use for creating a UUID
628 *
629 * @return UuidInterface A UuidInterface instance that represents a
630 * version 5 UUID
631 *
632 * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
633 * but under constant factory setups, this method operates in functionally pure manners
634 *
635 * @psalm-suppress ImpureMethodCall we know that the factory being replaced can lead to massive
636 * havoc across all consumers: that should never happen, and
637 * is generally to be discouraged. Until the factory is kept
638 * un-replaced, this method is effectively pure.
639 */
640 public static function uuid5($ns, string $name): UuidInterface
641 {
642 return self::getFactory()->uuid5($ns, $name);
643 }
644
645 /**
646 * Returns a version 6 (ordered-time) UUID from a host ID, sequence number,
647 * and the current time
648 *
649 * @param Hexadecimal|null $node A 48-bit number representing the hardware
650 * address
651 * @param int $clockSeq A 14-bit number used to help avoid duplicates that
652 * could arise when the clock is set backwards in time or if the node ID
653 * changes
654 *
655 * @return UuidInterface A UuidInterface instance that represents a
656 * version 6 UUID
657 */
658 public static function uuid6(
659 ?Hexadecimal $node = null,
660 ?int $clockSeq = null
661 ): UuidInterface {
662 return self::getFactory()->uuid6($node, $clockSeq);
663 }
664 }
665