diff options
Diffstat (limited to 'vendor/ramsey')
144 files changed, 11919 insertions, 2357 deletions
diff --git a/vendor/ramsey/collection/CHANGELOG.md b/vendor/ramsey/collection/CHANGELOG.md new file mode 100644 index 000000000..6333f3966 --- /dev/null +++ b/vendor/ramsey/collection/CHANGELOG.md @@ -0,0 +1,120 @@ +# ramsey/collection Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] +### Added +### Changed +### Deprecated +### Removed +### Fixed +### Security + +## [1.1.1] - 2020-09-10 + +### Fixed + +* Fixed broken `AbstractCollection::map()` implementation. + +## [1.1.0] - 2020-08-10 + +### Fixed + +* Fixed `AbstractCollection::diff()`, `AbstractCollection::intersect()` and + `AbstractCollection::merge()` when used with Generic collections. +* Fixed `AbstractCollection::diff()` and `AbstractCollection::intersect()` + returning inconsistent results when used on collections containing objects. +* Removed warning about deprecated dependency when running `composer install` + +## [1.0.1] - 2020-01-04 + +### Fixed + +* Fixed `AbstractCollection::offsetSet()` so that it uses the provided `$offset` + when setting `$value` in the array. + +## [1.0.0] - 2018-12-31 + +### Added + +* Added support for *queue* data structures to represent collections of ordered + entities. Together with *double-ended queues* (a.k.a. *deques*), + first-in-first-out (FIFO), last-in-first-out (LIFO), and other queue and stack + behaviors may be implemented. This functionality includes interfaces + `QueueInterface` and `DoubleEndedQueueInterface` and classes `Queue` and + `DoubleEndedQueue`. +* Added support for *set* data structures, representing collections that cannot + contain any duplicated elements; includes classes `AbstractSet` and `Set`. +* Added support for *typed map* data structures to represent maps of elements + where both keys and values have specified data types; includes + `TypedMapInterface` and the classes `AbstractTypedMap` and `TypedMap`. +* Added new manipulation and analyze methods for collections: `column()`, + `first()`, `last()`, `sort()`, `filter()`, `where()`, `map()`, `diff()`, + `intersect()`, and `merge()`. See [CollectionInterface](https://github.com/ramsey/collection/blob/master/src/CollectionInterface.php) + for more information. +* Added the following new exceptions specific to the ramsey/collection library: + `CollectionMismatchException`, `InvalidArgumentException`, + `InvalidSortOrderException`, `NoSuchElementException`, `OutOfBoundsException`, + `UnsupportedOperationException`, and `ValueExtractionException`. + +### Changed + +* Minimum PHP version supported is 7.2. +* Strict types are enforced throughout. + +### Removed + +* Removed support for HHVM. + +### Security + +* Fixed possible exploit using `AbstractArray::unserialize()` + (see [#47](https://github.com/ramsey/collection/issues/47)). + +## [0.3.0] - 2016-05-23 + +### Added + +* Added `MapInterface::keys()` method to return the keys from a `MapInterface` + object. This was added to the `AbstractMap` class. + +### Removed + +* Removed `getType()` and constructor methods from `AbstractCollection`. Children + of `AbstractCollection` must now implement `getType()`, which should return a + string value that defines the data type of items for the collection. + +### Fixed + +* Improve error messages in exceptions when `Collection` and `NamedParameterMap` + items fail type checks. + +## [0.2.1] - 2016-02-22 + +### Fixed + +* Allow non-strict checking of values in typed collections. + +## [0.2.0] - 2016-02-05 + +### Added + +* Support typed collections. + +## [0.1.0] - 2015-10-27 + +### Added + +* Support generic arrays and maps. + +[Unreleased]: https://github.com/ramsey/collection/compare/1.1.0...HEAD +[1.1.0]: https://github.com/ramsey/collection/compare/1.0.1...1.1.0 +[1.0.1]: https://github.com/ramsey/collection/compare/1.0.0...1.0.1 +[1.0.0]: https://github.com/ramsey/collection/compare/0.3.0...1.0.0 +[0.3.0]: https://github.com/ramsey/collection/compare/0.2.1...0.3.0 +[0.2.1]: https://github.com/ramsey/collection/compare/0.2.0...0.2.1 +[0.2.0]: https://github.com/ramsey/collection/compare/0.1.0...0.2.0 +[0.1.0]: https://github.com/ramsey/collection/commits/0.1.0 diff --git a/vendor/ramsey/collection/LICENSE b/vendor/ramsey/collection/LICENSE new file mode 100644 index 000000000..0efc999bf --- /dev/null +++ b/vendor/ramsey/collection/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-2020 Ben Ramsey <ben@benramsey.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/ramsey/collection/README.md b/vendor/ramsey/collection/README.md new file mode 100644 index 000000000..1b7897eb4 --- /dev/null +++ b/vendor/ramsey/collection/README.md @@ -0,0 +1,170 @@ +# ramsey/collection + +[![Source Code][badge-source]][source] +[![Latest Version][badge-release]][packagist] +[![Software License][badge-license]][license] +[![PHP Version][badge-php]][php] +[![Build Status][badge-build]][build] +[![Coverage Status][badge-coverage]][coverage] +[![Total Downloads][badge-downloads]][downloads] + +ramsey/collection is a PHP 7.2+ library for representing and manipulating collections. + +Much inspiration for this library came from the [Java Collections Framework][java]. + +This project adheres to a [code of conduct](CODE_OF_CONDUCT.md). +By participating in this project and its community, you are expected to +uphold this code. + + +## Installation + +Install this package as a dependency using [Composer](https://getcomposer.org). + +``` bash +composer require ramsey/collection +``` + +## Usage + +The [latest class API documentation][apidocs] is available online. + +Examples of how to use this framework can be found in the +[Wiki pages](https://github.com/ramsey/collection/wiki/Examples). + +## Contributing + +Contributions are welcome! Before contributing to this project, familiarize +yourself with [CONTRIBUTING.md](CONTRIBUTING.md). + +To develop this project, you will need [PHP](https://www.php.net) 7.2 or greater +and [Composer](https://getcomposer.org). + +After cloning this repository locally, execute the following commands: + +``` bash +cd /path/to/repository +composer install +``` + +Now, you are ready to develop! + +### Tooling + +This project uses [CaptainHook](https://github.com/CaptainHookPhp/captainhook) +to validate all staged changes prior to commit. + +#### Composer Commands + +To see all the commands available in the project `br` namespace for +Composer, type: + +``` bash +composer list br +``` + +##### Composer Command Autocompletion + +If you'd like to have Composer command auto-completion, you may use +[bamarni/symfony-console-autocomplete](https://github.com/bamarni/symfony-console-autocomplete). +Install it globally with Composer: + +``` bash +composer global require bamarni/symfony-console-autocomplete +``` + +Then, in your shell configuration file — usually `~/.bash_profile` or `~/.zshrc`, +but it could be different depending on your settings — ensure that your global +Composer `bin` directory is in your `PATH`, and evaluate the +`symfony-autocomplete` command. This will look like this: + +``` bash +export PATH="$(composer config home)/vendor/bin:$PATH" +eval "$(symfony-autocomplete)" +``` + +Now, you can use the `tab` key to auto-complete Composer commands: + +``` bash +composer br:[TAB][TAB] +``` + +#### Coding Standards + +This project follows a superset of [PSR-12](https://www.php-fig.org/psr/psr-12/) +coding standards, enforced by [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer). +The project PHP_CodeSniffer configuration may be found in `phpcs.xml.dist`. + +CaptainHook will run PHP_CodeSniffer before committing. It will attempt to fix +any errors it can, and it will reject the commit if there are any un-fixable +issues. Many issues can be fixed automatically and will be done so pre-commit. + +You may lint the entire codebase using PHP_CodeSniffer with the following +commands: + +``` bash +# Lint +composer br:lint + +# Lint and autofix +composer br:lint:fix +``` + +#### Static Analysis + +This project uses a combination of [PHPStan](https://github.com/phpstan/phpstan) +and [Psalm](https://github.com/vimeo/psalm) to provide static analysis of PHP +code. Configurations for these are in `phpstan.neon.dist` and `psalm.xml`, +respectively. + +CaptainHook will run PHPStan and Psalm before committing. The pre-commit hook +does not attempt to fix any static analysis errors. Instead, the commit will +fail, and you must fix the errors manually. + +You may run static analysis manually across the whole codebase with the +following command: + +``` bash +# Static analysis +composer br:analyze +``` + +### Project Structure + +This project uses [pds/skeleton](https://github.com/php-pds/skeleton) as its +base folder structure and layout. + +| Name | Description | +| ------------------| ---------------------------------------------- | +| **bin/** | Commands and scripts for this project | +| **build/** | Cache, logs, reports, etc. for project builds | +| **docs/** | Project-specific documentation | +| **resources/** | Additional resources for this project | +| **src/** | Project library and application source code | +| **tests/** | Tests for this project | + +## Copyright and License + +The ramsey/collection library is copyright © [Ben Ramsey](https://benramsey.com) +and licensed for use under the terms of the +MIT License (MIT). Please see [LICENSE](LICENSE) for more information. + + +[java]: http://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html +[apidocs]: https://docs.benramsey.com/ramsey-collection/latest/ + +[badge-source]: http://img.shields.io/badge/source-ramsey/collection-blue.svg?style=flat-square +[badge-release]: https://img.shields.io/packagist/v/ramsey/collection.svg?style=flat-square&label=release +[badge-license]: https://img.shields.io/packagist/l/ramsey/collection.svg?style=flat-square +[badge-php]: https://img.shields.io/packagist/php-v/ramsey/collection.svg?style=flat-square +[badge-build]: https://img.shields.io/travis/ramsey/collection/master.svg?style=flat-square +[badge-coverage]: https://img.shields.io/coveralls/github/ramsey/collection/master.svg?style=flat-square +[badge-downloads]: https://img.shields.io/packagist/dt/ramsey/collection.svg?style=flat-square&colorB=mediumvioletred + +[source]: https://github.com/ramsey/collection +[packagist]: https://packagist.org/packages/ramsey/collection +[license]: https://github.com/ramsey/collection/blob/master/LICENSE +[php]: https://php.net +[build]: https://travis-ci.org/ramsey/collection +[coverage]: https://coveralls.io/r/ramsey/collection?branch=master +[downloads]: https://packagist.org/packages/ramsey/collection diff --git a/vendor/ramsey/collection/composer.json b/vendor/ramsey/collection/composer.json new file mode 100644 index 000000000..9e443d93c --- /dev/null +++ b/vendor/ramsey/collection/composer.json @@ -0,0 +1,105 @@ +{ + "name": "ramsey/collection", + "type": "library", + "description": "A PHP 7.2+ library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "license": "MIT", + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "require": { + "php": "^7.2 || ^8" + }, + "require-dev": { + "captainhook/captainhook": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "ergebnis/composer-normalize": "^2.6", + "fzaninotto/faker": "^1.5", + "hamcrest/hamcrest-php": "^2", + "jangregor/phpstan-prophecy": "^0.6", + "mockery/mockery": "^1.3", + "phpstan/extension-installer": "^1", + "phpstan/phpstan": "^0.12.32", + "phpstan/phpstan-mockery": "^0.12.5", + "phpstan/phpstan-phpunit": "^0.12.11", + "phpunit/phpunit": "^8.5", + "psy/psysh": "^0.10.4", + "slevomat/coding-standard": "^6.3", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^3.12.2" + }, + "config": { + "sort-packages": true + }, + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Ramsey\\Console\\": "resources/console/", + "Ramsey\\Collection\\Test\\": "tests/" + }, + "files": [ + "vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest.php" + ] + }, + "scripts": { + "post-autoload-dump": "captainhook install --ansi -f -s", + "br:analyze": [ + "@br:analyze:phpstan", + "@br:analyze:psalm" + ], + "br:analyze:phpstan": "phpstan --memory-limit=1G analyse", + "br:analyze:psalm": "psalm --diff --diff-methods --config=psalm.xml", + "br:build:clean": "git clean -fX build/.", + "br:build:clear-cache": "git clean -fX build/cache/.", + "br:lint": "phpcs --cache=build/cache/phpcs.cache", + "br:lint:fix": "./bin/lint-fix.sh", + "br:repl": [ + "echo ; echo 'Type ./bin/repl to start the REPL.'" + ], + "br:test": "phpunit", + "br:test:all": [ + "@br:lint", + "@br:analyze", + "@br:test" + ], + "br:test:coverage:ci": "phpunit --coverage-clover build/logs/clover.xml", + "br:test:coverage:html": "phpunit --coverage-html build/coverage", + "pre-commit": [ + "@br:lint:fix", + "@br:lint", + "@br:analyze" + ], + "test": "@br:test:all" + }, + "scripts-descriptions": { + "br:analyze": "Performs static analysis on the code base.", + "br:analyze:phpstan": "Runs the PHPStan static analyzer.", + "br:analyze:psalm": "Runs the Psalm static analyzer.", + "br:build:clean": "Removes everything not under version control from the build directory.", + "br:build:clear-cache": "Removes everything not under version control from build/cache/.", + "br:lint": "Checks all source code for coding standards issues.", + "br:lint:fix": "Checks source code for coding standards issues and fixes them, if possible.", + "br:repl": "Note: Use ./bin/repl to run the REPL.", + "br:test": "Runs the full unit test suite.", + "br:test:all": "Runs linting, static analysis, and unit tests.", + "br:test:coverage:ci": "Runs the unit test suite and generates a Clover coverage report.", + "br:test:coverage:html": "Runs the unit tests suite and generates an HTML coverage report.", + "pre-commit": "These commands are run as part of a Git pre-commit hook installed using captainhook/captainhook. Each command should be prepared to accept a list of space-separated staged files.", + "test": "Shortcut to run the full test suite." + } +} diff --git a/vendor/ramsey/collection/src/AbstractArray.php b/vendor/ramsey/collection/src/AbstractArray.php new file mode 100644 index 000000000..f8b4be2ce --- /dev/null +++ b/vendor/ramsey/collection/src/AbstractArray.php @@ -0,0 +1,180 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection; + +use ArrayIterator; +use Traversable; + +use function serialize; +use function unserialize; + +/** + * This class provides a basic implementation of `ArrayInterface`, to minimize + * the effort required to implement this interface. + */ +abstract class AbstractArray implements ArrayInterface +{ + /** + * The items of this array. + * + * @var mixed[] + */ + protected $data = []; + + /** + * Constructs a new array object. + * + * @param mixed[] $data The initial items to add to this array. + */ + public function __construct(array $data = []) + { + // Invoke offsetSet() for each value added; in this way, sub-classes + // may provide additional logic about values added to the array object. + foreach ($data as $key => $value) { + $this[$key] = $value; + } + } + + /** + * Returns an iterator for this array. + * + * @link http://php.net/manual/en/iteratoraggregate.getiterator.php IteratorAggregate::getIterator() + * + * @return ArrayIterator<mixed, mixed> + */ + public function getIterator(): Traversable + { + return new ArrayIterator($this->data); + } + + /** + * Returns `true` if the given offset exists in this array. + * + * @link http://php.net/manual/en/arrayaccess.offsetexists.php ArrayAccess::offsetExists() + * + * @param mixed $offset The offset to check. + */ + public function offsetExists($offset): bool + { + return isset($this->data[$offset]); + } + + /** + * Returns the value at the specified offset. + * + * @link http://php.net/manual/en/arrayaccess.offsetget.php ArrayAccess::offsetGet() + * + * @param mixed $offset The offset for which a value should be returned. + * + * @return mixed|null the value stored at the offset, or null if the offset + * does not exist. + */ + public function offsetGet($offset) + { + return $this->data[$offset] ?? null; + } + + /** + * Sets the given value to the given offset in the array. + * + * @link http://php.net/manual/en/arrayaccess.offsetset.php ArrayAccess::offsetSet() + * + * @param mixed|null $offset The offset to set. If `null`, the value may be + * set at a numerically-indexed offset. + * @param mixed $value The value to set at the given offset. + */ + public function offsetSet($offset, $value): void + { + if ($offset === null) { + $this->data[] = $value; + } else { + $this->data[$offset] = $value; + } + } + + /** + * Removes the given offset and its value from the array. + * + * @link http://php.net/manual/en/arrayaccess.offsetunset.php ArrayAccess::offsetUnset() + * + * @param mixed $offset The offset to remove from the array. + */ + public function offsetUnset($offset): void + { + unset($this->data[$offset]); + } + + /** + * Returns a serialized string representation of this array object. + * + * @link http://php.net/manual/en/serializable.serialize.php Serializable::serialize() + * + * @return string a PHP serialized string. + */ + public function serialize(): string + { + return serialize($this->data); + } + + /** + * Converts a serialized string representation into an instance object. + * + * @link http://php.net/manual/en/serializable.unserialize.php Serializable::unserialize() + * + * @param string $serialized A PHP serialized string to unserialize. + * + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + */ + public function unserialize($serialized): void + { + $this->data = unserialize($serialized, ['allowed_classes' => false]); + } + + /** + * Returns the number of items in this array. + * + * @link http://php.net/manual/en/countable.count.php Countable::count() + */ + public function count(): int + { + return count($this->data); + } + + /** + * Removes all items from this array. + */ + public function clear(): void + { + $this->data = []; + } + + /** + * Returns a native PHP array representation of this array object. + * + * @return mixed[] + */ + public function toArray(): array + { + return $this->data; + } + + /** + * Returns `true` if this array is empty. + */ + public function isEmpty(): bool + { + return count($this->data) === 0; + } +} diff --git a/vendor/ramsey/collection/src/AbstractCollection.php b/vendor/ramsey/collection/src/AbstractCollection.php new file mode 100644 index 000000000..546f1adba --- /dev/null +++ b/vendor/ramsey/collection/src/AbstractCollection.php @@ -0,0 +1,409 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection; + +use Ramsey\Collection\Exception\CollectionMismatchException; +use Ramsey\Collection\Exception\InvalidArgumentException; +use Ramsey\Collection\Exception\InvalidSortOrderException; +use Ramsey\Collection\Exception\OutOfBoundsException; +use Ramsey\Collection\Exception\ValueExtractionException; +use Ramsey\Collection\Tool\TypeTrait; +use Ramsey\Collection\Tool\ValueExtractorTrait; +use Ramsey\Collection\Tool\ValueToStringTrait; + +use function array_filter; +use function array_map; +use function array_merge; +use function array_search; +use function array_udiff; +use function array_uintersect; +use function current; +use function end; +use function in_array; +use function reset; +use function sprintf; +use function unserialize; +use function usort; + +/** + * This class provides a basic implementation of `CollectionInterface`, to + * minimize the effort required to implement this interface + */ +abstract class AbstractCollection extends AbstractArray implements CollectionInterface +{ + use TypeTrait; + use ValueToStringTrait; + use ValueExtractorTrait; + + /** + * Ensures that this collection contains the specified element. + * + * @param mixed $element The element to add to the collection. + * + * @return bool `true` if this collection changed as a result of the call. + * + * @throws InvalidArgumentException when the element does not match the + * specified type for this collection. + */ + public function add($element): bool + { + $this[] = $element; + + return true; + } + + /** + * Returns `true` if this collection contains the specified element. + * + * @param mixed $element The element to check whether the collection contains. + * @param bool $strict Whether to perform a strict type check on the value. + */ + public function contains($element, bool $strict = true): bool + { + return in_array($element, $this->data, $strict); + } + + /** + * Sets the given value to the given offset in the array. + * + * @param mixed|null $offset The position to set the value in the array, or + * `null` to append the value to the array. + * @param mixed $value The value to set at the given offset. + * + * @throws InvalidArgumentException when the value does not match the + * specified type for this collection. + */ + public function offsetSet($offset, $value): void + { + if ($this->checkType($this->getType(), $value) === false) { + throw new InvalidArgumentException( + 'Value must be of type ' . $this->getType() . '; value is ' + . $this->toolValueToString($value) + ); + } + + if ($offset === null) { + $this->data[] = $value; + } else { + $this->data[$offset] = $value; + } + } + + /** + * Removes a single instance of the specified element from this collection, + * if it is present. + * + * @param mixed $element The element to remove from the collection. + * + * @return bool `true` if an element was removed as a result of this call. + */ + public function remove($element): bool + { + if (($position = array_search($element, $this->data, true)) !== false) { + unset($this->data[$position]); + + return true; + } + + return false; + } + + /** + * Returns the values from given property or method. + * + * @param string $propertyOrMethod The property or method name to filter by. + * + * @return mixed[] + * + * @throws ValueExtractionException if property or method is not defined. + */ + public function column(string $propertyOrMethod): array + { + $temp = []; + + foreach ($this->data as $item) { + $temp[] = $this->extractValue($item, $propertyOrMethod); + } + + return $temp; + } + + /** + * Returns the first item of the collection. + * + * @return mixed + * + * @throws OutOfBoundsException when the collection is empty. + */ + public function first() + { + if ($this->isEmpty()) { + throw new OutOfBoundsException('Can\'t determine first item. Collection is empty'); + } + + reset($this->data); + + return current($this->data); + } + + /** + * Returns the last item of the collection. + * + * @return mixed + * + * @throws OutOfBoundsException when the collection is empty. + */ + public function last() + { + if ($this->isEmpty()) { + throw new OutOfBoundsException('Can\'t determine last item. Collection is empty'); + } + + $item = end($this->data); + reset($this->data); + + return $item; + } + + /** + * Returns a sorted collection. + * + * {@inheritdoc} + * + * @param string $propertyOrMethod The property or method to sort by. + * @param string $order The sort order for the resulting collection (one of + * this interface's `SORT_*` constants). + * + * @return CollectionInterface<mixed, mixed> + * + * @throws InvalidSortOrderException if neither "asc" nor "desc" was given + * as the order. + * @throws ValueExtractionException if property or method is not defined. + */ + public function sort(string $propertyOrMethod, string $order = self::SORT_ASC): CollectionInterface + { + if (!in_array($order, [self::SORT_ASC, self::SORT_DESC], true)) { + throw new InvalidSortOrderException('Invalid sort order given: ' . $order); + } + + $collection = clone $this; + + usort($collection->data, function ($a, $b) use ($propertyOrMethod, $order) { + $aValue = $this->extractValue($a, $propertyOrMethod); + $bValue = $this->extractValue($b, $propertyOrMethod); + + return ($aValue <=> $bValue) * ($order === self::SORT_DESC ? -1 : 1); + }); + + return $collection; + } + + /** + * Returns a filtered collection. + * + * {@inheritdoc} + * + * @param callable $callback A callable to use for filtering elements. + * + * @return CollectionInterface<mixed, mixed> + */ + public function filter(callable $callback): CollectionInterface + { + $collection = clone $this; + $collection->data = array_merge([], array_filter($collection->data, $callback)); + + return $collection; + } + + /** + * Returns a collection of matching items. + * + * {@inheritdoc} + * + * @param string $propertyOrMethod The property or method to evaluate. + * @param mixed $value The value to match. + * + * @return CollectionInterface<mixed, mixed> + * + * @throws ValueExtractionException if property or method is not defined. + */ + public function where(string $propertyOrMethod, $value): CollectionInterface + { + return $this->filter(function ($item) use ($propertyOrMethod, $value) { + $accessorValue = $this->extractValue($item, $propertyOrMethod); + + return $accessorValue === $value; + }); + } + + /** + * Applies a callback to each item of the collection. + * + * {@inheritdoc} + * + * @param callable $callback A callable to apply to each item of the + * collection. + * + * @return CollectionInterface<mixed, mixed> + */ + public function map(callable $callback): CollectionInterface + { + $collection = clone $this; + $collection->data = array_map($callback, $collection->data); + + return $collection; + } + + /** + * Create a new collection with divergent items between current and given + * collection. + * + * @param CollectionInterface<mixed, mixed> $other The collection to check for divergent + * items. + * + * @return CollectionInterface<mixed, mixed> + * + * @throws CollectionMismatchException if the given collection is not of the + * same type. + */ + public function diff(CollectionInterface $other): CollectionInterface + { + if (!$other instanceof static) { + throw new CollectionMismatchException('Collection must be of type ' . static::class); + } + + // When using generics (Collection.php, Set.php, etc), + // we also need to make sure that the internal types match each other + if ($other->getType() !== $this->getType()) { + throw new CollectionMismatchException('Collection items must be of type ' . $this->getType()); + } + + $comparator = function ($a, $b): int { + // If the two values are object, we convert them to unique scalars. + // If the collection contains mixed values (unlikely) where some are objects + // and some are not, we leave them as they are. + // The comparator should still work and the result of $a < $b should + // be consistent but unpredictable since not documented. + if (is_object($a) && is_object($b)) { + $a = spl_object_id($a); + $b = spl_object_id($b); + } + + return $a === $b ? 0 : ($a < $b ? 1 : -1); + }; + + $diffAtoB = array_udiff($this->data, $other->data, $comparator); + $diffBtoA = array_udiff($other->data, $this->data, $comparator); + $diff = array_merge($diffAtoB, $diffBtoA); + + $collection = clone $this; + $collection->data = $diff; + + return $collection; + } + + /** + * Create a new collection with intersecting item between current and given + * collection. + * + * @param CollectionInterface<mixed, mixed> $other The collection to check for + * intersecting items. + * + * @return CollectionInterface<mixed, mixed> + * + * @throws CollectionMismatchException if the given collection is not of the + * same type. + */ + public function intersect(CollectionInterface $other): CollectionInterface + { + if (!$other instanceof static) { + throw new CollectionMismatchException('Collection must be of type ' . static::class); + } + + // When using generics (Collection.php, Set.php, etc), + // we also need to make sure that the internal types match each other + if ($other->getType() !== $this->getType()) { + throw new CollectionMismatchException('Collection items must be of type ' . $this->getType()); + } + + $comparator = function ($a, $b): int { + // If the two values are object, we convert them to unique scalars. + // If the collection contains mixed values (unlikely) where some are objects + // and some are not, we leave them as they are. + // The comparator should still work and the result of $a < $b should + // be consistent but unpredictable since not documented. + if (is_object($a) && is_object($b)) { + $a = spl_object_id($a); + $b = spl_object_id($b); + } + + return $a === $b ? 0 : ($a < $b ? 1 : -1); + }; + + $intersect = array_uintersect($this->data, $other->data, $comparator); + + $collection = clone $this; + $collection->data = $intersect; + + return $collection; + } + + /** + * Merge current items and items of given collections into a new one. + * + * @param CollectionInterface<mixed, mixed> ...$collections The collections to merge. + * + * @return CollectionInterface<mixed, mixed> + * + * @throws CollectionMismatchException if any of the given collections are not of the same type. + */ + public function merge(CollectionInterface ...$collections): CollectionInterface + { + $temp = [$this->data]; + + foreach ($collections as $index => $collection) { + if (!$collection instanceof static) { + throw new CollectionMismatchException( + sprintf('Collection with index %d must be of type %s', $index, static::class) + ); + } + + // When using generics (Collection.php, Set.php, etc), + // we also need to make sure that the internal types match each other + if ($collection->getType() !== $this->getType()) { + throw new CollectionMismatchException( + sprintf('Collection items in collection with index %d must be of type %s', $index, $this->getType()) + ); + } + + $temp[] = $collection->toArray(); + } + + $merge = array_merge(...$temp); + + $collection = clone $this; + $collection->data = $merge; + + return $collection; + } + + /** + * @inheritDoc + */ + public function unserialize($serialized): void + { + $this->data = unserialize($serialized, ['allowed_classes' => [$this->getType()]]); + } +} diff --git a/vendor/ramsey/collection/src/AbstractSet.php b/vendor/ramsey/collection/src/AbstractSet.php new file mode 100644 index 000000000..674fda03d --- /dev/null +++ b/vendor/ramsey/collection/src/AbstractSet.php @@ -0,0 +1,64 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection; + +use Ramsey\Collection\Exception\InvalidArgumentException; + +/** + * This class contains the basic implementation of a collection that does not + * allow duplicated values (a set), to minimize the effort required to implement + * this specific type of collection. + */ +abstract class AbstractSet extends AbstractCollection +{ + /** + * Adds the specified element to this set, if it is not already present. + * + * @param mixed $element The element to add to the set. + * + * @return bool `true` if this set did not already contain the specified + * element. + * + * @throws InvalidArgumentException when the element does not match the + * specified type for this set. + */ + public function add($element): bool + { + if ($this->contains($element)) { + return false; + } + + return parent::add($element); + } + + /** + * Sets the given value to the given offset in this set, if it is not + * already present. + * + * @param mixed|null $offset The offset is ignored and is treated as `null`. + * @param mixed $value The value to set at the given offset. + * + * @throws InvalidArgumentException when the value does not match the + * specified type for this set. + */ + public function offsetSet($offset, $value): void + { + if ($this->contains($value)) { + return; + } + + parent::offsetSet($offset, $value); + } +} diff --git a/vendor/ramsey/collection/src/ArrayInterface.php b/vendor/ramsey/collection/src/ArrayInterface.php new file mode 100644 index 000000000..81835cc80 --- /dev/null +++ b/vendor/ramsey/collection/src/ArrayInterface.php @@ -0,0 +1,47 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection; + +use ArrayAccess; +use Countable; +use IteratorAggregate; +use Serializable; + +/** + * `ArrayInterface` provides traversable array functionality to data types. + */ +interface ArrayInterface extends + ArrayAccess, + Countable, + IteratorAggregate, + Serializable +{ + /** + * Removes all items from this array. + */ + public function clear(): void; + + /** + * Returns a native PHP array representation of this array object. + * + * @return mixed[] + */ + public function toArray(): array; + + /** + * Returns `true` if this array is empty. + */ + public function isEmpty(): bool; +} diff --git a/vendor/ramsey/collection/src/Collection.php b/vendor/ramsey/collection/src/Collection.php new file mode 100644 index 000000000..e4db68dfe --- /dev/null +++ b/vendor/ramsey/collection/src/Collection.php @@ -0,0 +1,106 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection; + +/** + * A collection represents a group of objects. + * + * Each object in the collection is of a specific, defined type. + * + * This is a direct implementation of `CollectionInterface`, provided for + * the sake of convenience. + * + * Example usage: + * + * ``` php + * $collection = new \Ramsey\Collection\Collection('My\\Foo'); + * $collection->add(new \My\Foo()); + * $collection->add(new \My\Foo()); + * + * foreach ($collection as $foo) { + * // Do something with $foo + * } + * ``` + * + * It is preferable to subclass `AbstractCollection` to create your own typed + * collections. For example: + * + * ``` php + * namespace My\Foo; + * + * class FooCollection extends \Ramsey\Collection\AbstractCollection + * { + * public function getType() + * { + * return 'My\\Foo'; + * } + * } + * ``` + * + * And then use it similarly to the earlier example: + * + * ``` php + * $fooCollection = new \My\Foo\FooCollection(); + * $fooCollection->add(new \My\Foo()); + * $fooCollection->add(new \My\Foo()); + * + * foreach ($fooCollection as $foo) { + * // Do something with $foo + * } + * ``` + * + * The benefit with this approach is that you may do type-checking on the + * collection object: + * + * ``` php + * if ($collection instanceof \My\Foo\FooCollection) { + * // the collection is a collection of My\Foo objects + * } + * ``` + */ +class Collection extends AbstractCollection +{ + /** + * The type of elements stored in this collection. + * + * A collection's type is immutable once it is set. For this reason, this + * property is set private. + * + * @var string + */ + private $collectionType; + + /** + * Constructs a collection object of the specified type, optionally with the + * specified data. + * + * @param string $collectionType The type (FQCN) associated with this + * collection. + * @param mixed[] $data The initial items to store in the collection. + */ + public function __construct(string $collectionType, array $data = []) + { + $this->collectionType = $collectionType; + parent::__construct($data); + } + + /** + * Returns the type associated with this collection. + */ + public function getType(): string + { + return $this->collectionType; + } +} diff --git a/vendor/ramsey/collection/src/CollectionInterface.php b/vendor/ramsey/collection/src/CollectionInterface.php new file mode 100644 index 000000000..c865fa9f5 --- /dev/null +++ b/vendor/ramsey/collection/src/CollectionInterface.php @@ -0,0 +1,196 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection; + +/** + * A collection represents a group of objects, known as its elements. + * + * Some collections allow duplicate elements and others do not. Some are ordered + * and others unordered. + */ +interface CollectionInterface extends ArrayInterface +{ + /** + * Ascending sort type. + */ + public const SORT_ASC = 'asc'; + + /** + * Descending sort type. + */ + public const SORT_DESC = 'desc'; + + /** + * Ensures that this collection contains the specified element (optional + * operation). + * + * Returns `true` if this collection changed as a result of the call. + * (Returns `false` if this collection does not permit duplicates and + * already contains the specified element.) + * + * Collections that support this operation may place limitations on what + * elements may be added to this collection. In particular, some + * collections will refuse to add `null` elements, and others will impose + * restrictions on the type of elements that may be added. Collection + * classes should clearly specify in their documentation any restrictions + * on what elements may be added. + * + * If a collection refuses to add a particular element for any reason other + * than that it already contains the element, it must throw an exception + * (rather than returning `false`). This preserves the invariant that a + * collection always contains the specified element after this call returns. + * + * @param mixed $element The element to add to the collection. + * + * @return bool `true` if this collection changed as a result of the call. + */ + public function add($element): bool; + + /** + * Returns `true` if this collection contains the specified element. + * + * @param mixed $element The element to check whether the collection contains. + * @param bool $strict Whether to perform a strict type check on the value. + */ + public function contains($element, bool $strict = true): bool; + + /** + * Returns the type associated with this collection. + */ + public function getType(): string; + + /** + * Removes a single instance of the specified element from this collection, + * if it is present. + * + * @param mixed $element The element to remove from the collection. + * + * @return bool `true` if an element was removed as a result of this call. + */ + public function remove($element): bool; + + /** + * Returns the values from the given property or method. + * + * @param string $propertyOrMethod The property or method name to filter by. + * + * @return mixed[] + */ + public function column(string $propertyOrMethod): array; + + /** + * Returns the first item of the collection. + * + * @return mixed + */ + public function first(); + + /** + * Returns the last item of the collection. + * + * @return mixed + */ + public function last(); + + /** + * Sort the collection by a property or method with the given sort order. + * + * This will always leave the original collection untouched and will return + * a new one. + * + * @param string $propertyOrMethod The property or method to sort by. + * @param string $order The sort order for the resulting collection (one of + * this interface's `SORT_*` constants). + * + * @return CollectionInterface<mixed, mixed> + */ + public function sort(string $propertyOrMethod, string $order = self::SORT_ASC): self; + + /** + * Filter out items of the collection which don't match the criteria of + * given callback. + * + * This will always leave the original collection untouched and will return + * a new one. + * + * See the {@link http://php.net/manual/en/function.array-filter.php PHP array_filter() documentation} + * for examples of how the `$callback` parameter works. + * + * @param callable $callback A callable to use for filtering elements. + * + * @return CollectionInterface<mixed, mixed> + */ + public function filter(callable $callback): self; + + /** + * Create a new collection where items match the criteria of given callback. + * + * This will always leave the original collection untouched and will return + * a new one. + * + * @param string $propertyOrMethod The property or method to evaluate. + * @param mixed $value The value to match. + * + * @return CollectionInterface<mixed, mixed> + */ + public function where(string $propertyOrMethod, $value): self; + + /** + * Apply a given callback method on each item of the collection. + * + * This will always leave the original collection untouched and will return + * a new one. + * + * See the {@link http://php.net/manual/en/function.array-map.php PHP array_map() documentation} + * for examples of how the `$callback` parameter works. + * + * @param callable $callback A callable to apply to each item of the + * collection. + * + * @return CollectionInterface<mixed, mixed> + */ + public function map(callable $callback): self; + + /** + * Create a new collection with divergent items between current and given + * collection. + * + * @param CollectionInterface<mixed, mixed> $other The collection to check for divergent + * items. + * + * @return CollectionInterface<mixed, mixed> + */ + public function diff(CollectionInterface $other): self; + + /** + * Create a new collection with intersecting item between current and given + * collection. + * + * @param CollectionInterface<mixed, mixed> $other The collection to check for + * intersecting items. + * + * @return CollectionInterface<mixed, mixed> + */ + public function intersect(CollectionInterface $other): self; + + /** + * Merge current items and items of given collections into a new one. + * + * @param CollectionInterface<mixed, mixed> ...$collections The collections to merge. + * + * @return CollectionInterface<mixed, mixed> + */ + public function merge(CollectionInterface ...$collections): self; +} diff --git a/vendor/ramsey/collection/src/DoubleEndedQueue.php b/vendor/ramsey/collection/src/DoubleEndedQueue.php new file mode 100644 index 000000000..4eb4dbeab --- /dev/null +++ b/vendor/ramsey/collection/src/DoubleEndedQueue.php @@ -0,0 +1,288 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection; + +use Ramsey\Collection\Exception\InvalidArgumentException; +use Ramsey\Collection\Exception\NoSuchElementException; + +/** + * This class provides a basic implementation of `DoubleEndedQueueInterface`, to + * minimize the effort required to implement this interface. + */ +class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface +{ + /** + * Index of the last element in the queue. + * + * @var int + */ + private $tail = -1; + + /** + * Sets the given value to the given offset in the queue. + * + * Since arbitrary offsets may not be manipulated in a queue, this method + * serves only to fulfill the `ArrayAccess` interface requirements. It is + * invoked by other operations when adding values to the queue. + * + * @link http://php.net/manual/en/arrayaccess.offsetset.php ArrayAccess::offsetSet() + * + * @param mixed|null $offset The offset is ignored and is treated as `null`. + * @param mixed $value The value to set at the given offset. + * + * @throws InvalidArgumentException when the value does not match the + * specified type for this queue. + */ + public function offsetSet($offset, $value): void + { + if ($this->checkType($this->getType(), $value) === false) { + throw new InvalidArgumentException( + 'Value must be of type ' . $this->getType() . '; value is ' + . $this->toolValueToString($value) + ); + } + + $this->tail++; + + $this->data[$this->tail] = $value; + } + + /** + * Ensures that the specified element is inserted at the front of this queue. + * + * @see self::offerFirst() + * + * @param mixed $element The element to add to this queue. + * + * @return bool `true` if this queue changed as a result of the call. + * + * @throws InvalidArgumentException when the value does not match the + * specified type for this queue. + */ + public function addFirst($element): bool + { + if ($this->checkType($this->getType(), $element) === false) { + throw new InvalidArgumentException( + 'Value must be of type ' . $this->getType() . '; value is ' + . $this->toolValueToString($element) + ); + } + + $this->index--; + + $this->data[$this->index] = $element; + + return true; + } + + /** + * Ensures that the specified element in inserted at the end of this queue. + * + * @see Queue::add() + * + * @param mixed $element The element to add to this queue. + * + * @return bool `true` if this queue changed as a result of the call. + * + * @throws InvalidArgumentException when the value does not match the + * specified type for this queue. + */ + public function addLast($element): bool + { + return $this->add($element); + } + + /** + * Inserts the specified element at the front this queue. + * + * @see self::addFirst() + * + * @param mixed $element The element to add to this queue. + * + * @return bool `true` if the element was added to this queue, else `false`. + */ + public function offerFirst($element): bool + { + try { + return $this->addFirst($element); + } catch (InvalidArgumentException $e) { + return false; + } + } + + /** + * Inserts the specified element at the end this queue. + * + * @see self::addLast() + * @see Queue::offer() + * + * @param mixed $element The element to add to this queue. + * + * @return bool `true` if the element was added to this queue, else `false`. + */ + public function offerLast($element): bool + { + return $this->offer($element); + } + + /** + * Retrieves and removes the head of this queue. + * + * This method differs from `pollFirst()` only in that it throws an + * exception if this queue is empty. + * + * @see self::pollFirst() + * @see Queue::remove() + * + * @return mixed the head of this queue. + * + * @throws NoSuchElementException if this queue is empty. + */ + public function removeFirst() + { + return $this->remove(); + } + + /** + * Retrieves and removes the tail of this queue. + * + * This method differs from `pollLast()` only in that it throws an exception + * if this queue is empty. + * + * @see self::pollLast() + * + * @return mixed the tail of this queue. + * + * @throws NoSuchElementException if this queue is empty. + */ + public function removeLast() + { + if ($this->count() === 0) { + throw new NoSuchElementException('Can\'t return element from Queue. Queue is empty.'); + } + + $tail = $this[$this->tail]; + + unset($this[$this->tail]); + $this->tail--; + + return $tail; + } + + /** + * Retrieves and removes the head of this queue, or returns `null` if this + * queue is empty. + * + * @see self::removeFirst() + * + * @return mixed|null the head of this queue, or `null` if this queue is empty. + */ + public function pollFirst() + { + return $this->poll(); + } + + /** + * Retrieves and removes the tail of this queue, or returns `null` if this + * queue is empty. + * + * @see self::removeLast() + * + * @return mixed|null the tail of this queue, or `null` if this queue is empty. + */ + public function pollLast() + { + if ($this->count() === 0) { + return null; + } + + $tail = $this[$this->tail]; + + unset($this[$this->tail]); + $this->tail--; + + return $tail; + } + + /** + * Retrieves, but does not remove, the head of this queue. + * + * This method differs from `peekFirst()` only in that it throws an + * exception if this queue is empty. + * + * @see self::peekFirst() + * @see Queue::element() + * + * @return mixed the head of this queue. + * + * @throws NoSuchElementException if this queue is empty. + */ + public function firstElement() + { + return $this->element(); + } + + /** + * Retrieves, but does not remove, the tail of this queue. + * + * This method differs from `peekLast()` only in that it throws an exception + * if this queue is empty. + * + * @see self::peekLast() + * + * @return mixed the tail of this queue. + * + * @throws NoSuchElementException if this queue is empty. + */ + public function lastElement() + { + if ($this->count() === 0) { + throw new NoSuchElementException('Can\'t return element from Queue. Queue is empty.'); + } + + return $this->data[$this->tail]; + } + + /** + * Retrieves, but does not remove, the head of this queue, or returns `null` + * if this queue is empty. + * + * @see self::firstElement() + * @see Queue::peek() + * + * @return mixed|null the head of this queue, or `null` if this queue is empty. + */ + public function peekFirst() + { + return $this->peek(); + } + + /** + * Retrieves, but does not remove, the tail of this queue, or returns `null` + * if this queue is empty. + * + * @see self::lastElement() + * + * @return mixed|null the tail of this queue, or `null` if this queue is empty + */ + public function peekLast() + { + if ($this->count() === 0) { + return null; + } + + return $this->data[$this->tail]; + } +} diff --git a/vendor/ramsey/collection/src/DoubleEndedQueueInterface.php b/vendor/ramsey/collection/src/DoubleEndedQueueInterface.php new file mode 100644 index 000000000..6b23cf553 --- /dev/null +++ b/vendor/ramsey/collection/src/DoubleEndedQueueInterface.php @@ -0,0 +1,309 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection; + +use Ramsey\Collection\Exception\NoSuchElementException; + +/** + * A linear collection that supports element insertion and removal at both ends. + * + * Most `DoubleEndedQueueInterface` implementations place no fixed limits on the + * number of elements they may contain, but this interface supports + * capacity-restricted double-ended queues as well as those with no fixed size + * limit. + * + * This interface defines methods to access the elements at both ends of the + * double-ended queue. Methods are provided to insert, remove, and examine the + * element. Each of these methods exists in two forms: one throws an exception + * if the operation fails, the other returns a special value (either `null` or + * `false`, depending on the operation). The latter form of the insert operation + * is designed specifically for use with capacity-restricted implementations; in + * most implementations, insert operations cannot fail. + * + * The twelve methods described above are summarized in the following table: + * + * <table> + * <caption>Summary of DoubleEndedQueueInterface methods</caption> + * <thead> + * <tr> + * <th></th> + * <th colspan=2>First Element (Head)</th> + * <th colspan=2>Last Element (Tail)</th> + * </tr> + * <tr> + * <td></td> + * <td><em>Throws exception</em></td> + * <td><em>Special value</em></td> + * <td><em>Throws exception</em></td> + * <td><em>Special value</em></td> + * </tr> + * </thead> + * <tbody> + * <tr> + * <th>Insert</th> + * <td><code>addFirst()</code></td> + * <td><code>offerFirst()</code></td> + * <td><code>addLast()</code></td> + * <td><code>offerLast()</code></td> + * </tr> + * <tr> + * <th>Remove</th> + * <td><code>removeFirst()</code></td> + * <td><code>pollFirst()</code></td> + * <td><code>removeLast()</code></td> + * <td><code>pollLast()</code></td> + * </tr> + * <tr> + * <th>Examine</th> + * <td><code>firstElement()</code></td> + * <td><code>peekFirst()</code></td> + * <td><code>lastElement()</code></td> + * <td><code>peekLast()</code></td> + * </tr> + * </tbody> + * </table> + * + * This interface extends the `QueueInterface`. When a double-ended queue is + * used as a queue, FIFO (first-in-first-out) behavior results. Elements are + * added at the end of the double-ended queue and removed from the beginning. + * The methods inherited from the `QueueInterface` are precisely equivalent to + * `DoubleEndedQueueInterface` methods as indicated in the following table: + * + * <table> + * <caption>Comparison of QueueInterface and DoubleEndedQueueInterface methods</caption> + * <thead> + * <tr> + * <th>QueueInterface Method</th> + * <th>DoubleEndedQueueInterface Method</th> + * </tr> + * </thead> + * <tbody> + * <tr> + * <td><code>add()</code></td> + * <td><code>addLast()</code></td> + * </tr> + * <tr> + * <td><code>offer()</code></td> + * <td><code>offerLast()</code></td> + * </tr> + * <tr> + * <td><code>remove()</code></td> + * <td><code>removeFirst()</code></td> + * </tr> + * <tr> + * <td><code>poll()</code></td> + * <td><code>pollFirst()</code></td> + * </tr> + * <tr> + * <td><code>element()</code></td> + * <td><code>firstElement()</code></td> + * </tr> + * <tr> + * <td><code>peek()</code></td> + * <td><code>peekFirst()</code></td> + * </tr> + * </tbody> + * </table> + * + * Double-ended queues can also be used as LIFO (last-in-first-out) stacks. When + * a double-ended queue is used as a stack, elements are pushed and popped from + * the beginning of the double-ended queue. Stack concepts are precisely + * equivalent to `DoubleEndedQueueInterface` methods as indicated in the table + * below: + * + * <table> + * <caption>Comparison of stack concepts and DoubleEndedQueueInterface methods</caption> + * <thead> + * <tr> + * <th>Stack concept</th> + * <th>DoubleEndedQueueInterface Method</th> + * </tr> + * </thead> + * <tbody> + * <tr> + * <td><em>push</em></td> + * <td><code>addFirst()</code></td> + * </tr> + * <tr> + * <td><em>pop</em></td> + * <td><code>removeFirst()</code></td> + * </tr> + * <tr> + * <td><em>peek</em></td> + * <td><code>peekFirst()</code></td> + * </tr> + * </tbody> + * </table> + * + * Note that the `peek()` method works equally well when a double-ended queue is + * used as a queue or a stack; in either case, elements are drawn from the + * beginning of the double-ended queue. + * + * While `DoubleEndedQueueInterface` implementations are not strictly required + * to prohibit the insertion of `null` elements, they are strongly encouraged to + * do so. Users of any `DoubleEndedQueueInterface` implementations that do allow + * `null` elements are strongly encouraged *not* to take advantage of the + * ability to insert nulls. This is so because `null` is used as a special + * return value by various methods to indicated that the double-ended queue is + * empty. + */ +interface DoubleEndedQueueInterface extends QueueInterface +{ + /** + * Inserts the specified element at the front of this queue if it is + * possible to do so immediately without violating capacity restrictions. + * + * When using a capacity-restricted double-ended queue, it is generally + * preferable to use the `offerFirst()` method. + * + * @param mixed $element The element to add to the front of this queue. + * + * @return bool `true` if this queue changed as a result of the call. + * + * @throws \RuntimeException if a queue refuses to add a particular element + * for any reason other than that it already contains the element. + * Implementations should use a more-specific exception that extends + * `\RuntimeException`. + */ + public function addFirst($element): bool; + + /** + * Inserts the specified element at the end of this queue if it is possible + * to do so immediately without violating capacity restrictions. + * + * When using a capacity-restricted double-ended queue, it is generally + * preferable to use the `offerLast()` method. + * + * This method is equivalent to `add()`. + * + * @param mixed $element The element to add to the end of this queue. + * + * @return bool `true` if this queue changed as a result of the call. + * + * @throws \RuntimeException if a queue refuses to add a particular element + * for any reason other than that it already contains the element. + * Implementations should use a more-specific exception that extends + * `\RuntimeException`. + */ + public function addLast($element): bool; + + /** + * Inserts the specified element at the front of this queue if it is + * possible to do so immediately without violating capacity restrictions. + * + * When using a capacity-restricted queue, this method is generally + * preferable to `addFirst()`, which can fail to insert an element only by + * throwing an exception. + * + * @param mixed $element The element to add to the front of this queue. + * + * @return bool `true` if the element was added to this queue, else `false`. + */ + public function offerFirst($element): bool; + + /** + * Inserts the specified element at the end of this queue if it is possible + * to do so immediately without violating capacity restrictions. + * + * When using a capacity-restricted queue, this method is generally + * preferable to `addLast()` which can fail to insert an element only by + * throwing an exception. + * + * @param mixed $element The element to add to the end of this queue. + * + * @return bool `true` if the element was added to this queue, else `false`. + */ + public function offerLast($element): bool; + + /** + * Retrieves and removes the head of this queue. + * + * This method differs from `pollFirst()` only in that it throws an + * exception if this queue is empty. + * + * @return mixed the first element in this queue. + * + * @throws NoSuchElementException if this queue is empty. + */ + public function removeFirst(); + + /** + * Retrieves and removes the tail of this queue. + * + * This method differs from `pollLast()` only in that it throws an exception + * if this queue is empty. + * + * @return mixed the last element in this queue. + * + * @throws NoSuchElementException if this queue is empty. + */ + public function removeLast(); + + /** + * Retrieves and removes the head of this queue, or returns `null` if this + * queue is empty. + * + * @return mixed|null the head of this queue, or `null` if this queue is empty. + */ + public function pollFirst(); + + /** + * Retrieves and removes the tail of this queue, or returns `null` if this + * queue is empty. + * + * @return mixed|null the tail of this queue, or `null` if this queue is empty. + */ + public function pollLast(); + + /** + * Retrieves, but does not remove, the head of this queue. + * + * This method differs from `peekFirst()` only in that it throws an + * exception if this queue is empty. + * + * @return mixed the head of this queue. + * + * @throws NoSuchElementException if this queue is empty. + */ + public function firstElement(); + + /** + * Retrieves, but does not remove, the tail of this queue. + * + * This method differs from `peekLast()` only in that it throws an exception + * if this queue is empty. + * + * @return mixed the tail of this queue. + * + * @throws NoSuchElementException if this queue is empty. + */ + public function lastElement(); + + /** + * Retrieves, but does not remove, the head of this queue, or returns `null` + * if this queue is empty. + * + * @return mixed|null the head of this queue, or `null` if this queue is empty. + */ + public function peekFirst(); + + /** + * Retrieves, but does not remove, the tail of this queue, or returns `null` + * if this queue is empty. + * + * @return mixed|null the tail of this queue, or `null` if this queue is empty. + */ + public function peekLast(); +} diff --git a/vendor/ramsey/collection/src/Exception/CollectionMismatchException.php b/vendor/ramsey/collection/src/Exception/CollectionMismatchException.php new file mode 100644 index 000000000..d4b335f45 --- /dev/null +++ b/vendor/ramsey/collection/src/Exception/CollectionMismatchException.php @@ -0,0 +1,22 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Exception; + +/** + * Thrown when attempting to operate on collections of differing types. + */ +class CollectionMismatchException extends \RuntimeException +{ +} diff --git a/vendor/ramsey/collection/src/Exception/InvalidArgumentException.php b/vendor/ramsey/collection/src/Exception/InvalidArgumentException.php new file mode 100644 index 000000000..dcc3eac60 --- /dev/null +++ b/vendor/ramsey/collection/src/Exception/InvalidArgumentException.php @@ -0,0 +1,22 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Exception; + +/** + * Thrown to indicate an argument is not of the expected type. + */ +class InvalidArgumentException extends \InvalidArgumentException +{ +} diff --git a/vendor/ramsey/collection/src/Exception/InvalidSortOrderException.php b/vendor/ramsey/collection/src/Exception/InvalidSortOrderException.php new file mode 100644 index 000000000..9337ccc66 --- /dev/null +++ b/vendor/ramsey/collection/src/Exception/InvalidSortOrderException.php @@ -0,0 +1,22 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Exception; + +/** + * Thrown when attempting to use a sort order that is not recognized. + */ +class InvalidSortOrderException extends \RuntimeException +{ +} diff --git a/vendor/ramsey/collection/src/Exception/NoSuchElementException.php b/vendor/ramsey/collection/src/Exception/NoSuchElementException.php new file mode 100644 index 000000000..9debe8f66 --- /dev/null +++ b/vendor/ramsey/collection/src/Exception/NoSuchElementException.php @@ -0,0 +1,22 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Exception; + +/** + * Thrown when attempting to access an element that does not exist. + */ +class NoSuchElementException extends \RuntimeException +{ +} diff --git a/vendor/ramsey/collection/src/Exception/OutOfBoundsException.php b/vendor/ramsey/collection/src/Exception/OutOfBoundsException.php new file mode 100644 index 000000000..4e9d16fa3 --- /dev/null +++ b/vendor/ramsey/collection/src/Exception/OutOfBoundsException.php @@ -0,0 +1,22 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Exception; + +/** + * Thrown when attempting to access an element out of the range of the collection. + */ +class OutOfBoundsException extends \OutOfBoundsException +{ +} diff --git a/vendor/ramsey/collection/src/Exception/UnsupportedOperationException.php b/vendor/ramsey/collection/src/Exception/UnsupportedOperationException.php new file mode 100644 index 000000000..8f45e5836 --- /dev/null +++ b/vendor/ramsey/collection/src/Exception/UnsupportedOperationException.php @@ -0,0 +1,22 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Exception; + +/** + * Thrown to indicate that the requested operation is not supported. + */ +class UnsupportedOperationException extends \RuntimeException +{ +} diff --git a/vendor/ramsey/collection/src/Exception/ValueExtractionException.php b/vendor/ramsey/collection/src/Exception/ValueExtractionException.php new file mode 100644 index 000000000..f6c6cb4ec --- /dev/null +++ b/vendor/ramsey/collection/src/Exception/ValueExtractionException.php @@ -0,0 +1,22 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Exception; + +/** + * Thrown when attempting to extract a value for a method or property that does not exist. + */ +class ValueExtractionException extends \RuntimeException +{ +} diff --git a/vendor/ramsey/collection/src/GenericArray.php b/vendor/ramsey/collection/src/GenericArray.php new file mode 100644 index 000000000..2f9ab7677 --- /dev/null +++ b/vendor/ramsey/collection/src/GenericArray.php @@ -0,0 +1,22 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection; + +/** + * `GenericArray` represents a standard array object. + */ +class GenericArray extends AbstractArray +{ +} diff --git a/vendor/ramsey/collection/src/Map/AbstractMap.php b/vendor/ramsey/collection/src/Map/AbstractMap.php new file mode 100644 index 000000000..6b2e97a08 --- /dev/null +++ b/vendor/ramsey/collection/src/Map/AbstractMap.php @@ -0,0 +1,226 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Map; + +use Ramsey\Collection\AbstractArray; +use Ramsey\Collection\Exception\InvalidArgumentException; + +use function array_key_exists; +use function array_keys; +use function in_array; + +/** + * This class provides a basic implementation of `MapInterface`, to minimize the + * effort required to implement this interface. + */ +abstract class AbstractMap extends AbstractArray implements MapInterface +{ + /** + * Sets the given value to the given offset in the map. + * + * @param mixed $offset The offset to set. + * @param mixed $value The value to set at the given offset. + * + * @throws InvalidArgumentException if the offset provided is `null`. + */ + public function offsetSet($offset, $value): void + { + if ($offset === null) { + throw new InvalidArgumentException( + 'Map elements are key/value pairs; a key must be provided for ' + . 'value ' . $value + ); + } + + $this->data[$offset] = $value; + } + + /** + * Returns `true` if this map contains a mapping for the specified key. + * + * @param mixed $key The key to check in the map. + */ + public function containsKey($key): bool + { + return array_key_exists($key, $this->data); + } + + /** + * Returns `true` if this map maps one or more keys to the specified value. + * + * This performs a strict type check on the value. + * + * @param mixed $value The value to check in the map. + */ + public function containsValue($value): bool + { + return in_array($value, $this->data, true); + } + + /** + * Return an array of the keys contained in this map. + * + * @return mixed[] + */ + public function keys(): array + { + return array_keys($this->data); + } + + /** + * Returns the value to which the specified key is mapped, `null` if this + * map contains no mapping for the key, or (optionally) `$defaultValue` if + * this map contains no mapping for the key. + * + * @param mixed $key The key to return from the map. + * @param mixed $defaultValue The default value to use if `$key` is not found. + * + * @return mixed|null the value or `null` if the key could not be found. + */ + public function get($key, $defaultValue = null) + { + if (!$this->containsKey($key)) { + return $defaultValue; + } + + return $this[$key]; + } + + /** + * Associates the specified value with the specified key in this map. + * + * If the map previously contained a mapping for the key, the old value is + * replaced by the specified value. + * + * @param mixed $key The key to put or replace in the map. + * @param mixed $value The value to store at `$key`. + * + * @return mixed|null the previous value associated with key, or `null` if + * there was no mapping for `$key`. + */ + public function put($key, $value) + { + $previousValue = $this->get($key); + $this[$key] = $value; + + return $previousValue; + } + + /** + * Associates the specified value with the specified key in this map only if + * it is not already set. + * + * If there is already a value associated with `$key`, this returns that + * value without replacing it. + * + * @param mixed $key The key to put in the map. + * @param mixed $value The value to store at `$key`. + * + * @return mixed|null the previous value associated with key, or `null` if + * there was no mapping for `$key`. + */ + public function putIfAbsent($key, $value) + { + $currentValue = $this->get($key); + + if ($currentValue === null) { + $this[$key] = $value; + } + + return $currentValue; + } + + /** + * Removes the mapping for a key from this map if it is present. + * + * @param mixed $key The key to remove from the map. + * + * @return mixed|null the previous value associated with key, or `null` if + * there was no mapping for `$key`. + */ + public function remove($key) + { + $previousValue = $this->get($key); + unset($this[$key]); + + return $previousValue; + } + + /** + * Removes the entry for the specified key only if it is currently mapped to + * the specified value. + * + * This performs a strict type check on the value. + * + * @param mixed $key The key to remove from the map. + * @param mixed $value The value to match. + * + * @return bool true if the value was removed. + */ + public function removeIf($key, $value): bool + { + if ($this->get($key) === $value) { + unset($this[$key]); + + return true; + } + + return false; + } + + /** + * Replaces the entry for the specified key only if it is currently mapped + * to some value. + * + * @param mixed $key The key to replace. + * @param mixed $value The value to set at `$key`. + * + * @return mixed|null the previous value associated with key, or `null` if + * there was no mapping for `$key`. + */ + public function replace($key, $value) + { + $currentValue = $this->get($key); + + if ($this->containsKey($key)) { + $this[$key] = $value; + } + + return $currentValue; + } + + /** + * Replaces the entry for the specified key only if currently mapped to the + * specified value. + * + * This performs a strict type check on the value. + * + * @param mixed $key The key to remove from the map. + * @param mixed $oldValue The value to match. + * @param mixed $newValue The value to use as a replacement. + * + * @return bool true if the value was replaced. + */ + public function replaceIf($key, $oldValue, $newValue): bool + { + if ($this->get($key) === $oldValue) { + $this[$key] = $newValue; + + return true; + } + + return false; + } +} diff --git a/vendor/ramsey/collection/src/Map/AbstractTypedMap.php b/vendor/ramsey/collection/src/Map/AbstractTypedMap.php new file mode 100644 index 000000000..80cec2e22 --- /dev/null +++ b/vendor/ramsey/collection/src/Map/AbstractTypedMap.php @@ -0,0 +1,57 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Map; + +use Ramsey\Collection\Exception\InvalidArgumentException; +use Ramsey\Collection\Tool\TypeTrait; +use Ramsey\Collection\Tool\ValueToStringTrait; + +/** + * This class provides a basic implementation of `TypedMapInterface`, to + * minimize the effort required to implement this interface. + */ +abstract class AbstractTypedMap extends AbstractMap implements TypedMapInterface +{ + use TypeTrait; + use ValueToStringTrait; + + /** + * Sets the given value to the given offset in the map. + * + * @param mixed $offset The offset to set. + * @param mixed $value The value to set at the given offset. + * + * @throws InvalidArgumentException if the offset or value do not match the + * expected types. + */ + public function offsetSet($offset, $value): void + { + if ($this->checkType($this->getKeyType(), $offset) === false) { + throw new InvalidArgumentException( + 'Key must be of type ' . $this->getKeyType() . '; key is ' + . $this->toolValueToString($offset) + ); + } + + if ($this->checkType($this->getValueType(), $value) === false) { + throw new InvalidArgumentException( + 'Value must be of type ' . $this->getValueType() . '; value is ' + . $this->toolValueToString($value) + ); + } + + parent::offsetSet($offset, $value); + } +} diff --git a/vendor/ramsey/collection/src/Map/AssociativeArrayMap.php b/vendor/ramsey/collection/src/Map/AssociativeArrayMap.php new file mode 100644 index 000000000..f97e21728 --- /dev/null +++ b/vendor/ramsey/collection/src/Map/AssociativeArrayMap.php @@ -0,0 +1,22 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Map; + +/** + * `AssociativeArrayMap` represents a standard associative array object. + */ +class AssociativeArrayMap extends AbstractMap +{ +} diff --git a/vendor/ramsey/collection/src/Map/MapInterface.php b/vendor/ramsey/collection/src/Map/MapInterface.php new file mode 100644 index 000000000..500bdb2d0 --- /dev/null +++ b/vendor/ramsey/collection/src/Map/MapInterface.php @@ -0,0 +1,138 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Map; + +use Ramsey\Collection\ArrayInterface; + +/** + * An object that maps keys to values. + * + * A map cannot contain duplicate keys; each key can map to at most one value. + */ +interface MapInterface extends ArrayInterface +{ + /** + * Returns `true` if this map contains a mapping for the specified key. + * + * @param mixed $key The key to check in the map. + */ + public function containsKey($key): bool; + + /** + * Returns `true` if this map maps one or more keys to the specified value. + * + * This performs a strict type check on the value. + * + * @param mixed $value The value to check in the map. + */ + public function containsValue($value): bool; + + /** + * Return an array of the keys contained in this map. + * + * @return mixed[] + */ + public function keys(): array; + + /** + * Returns the value to which the specified key is mapped, `null` if this + * map contains no mapping for the key, or (optionally) `$defaultValue` if + * this map contains no mapping for the key. + * + * @param mixed $key The key to return from the map. + * @param mixed $defaultValue The default value to use if `$key` is not found. + * + * @return mixed|null the value or `null` if the key could not be found. + */ + public function get($key, $defaultValue = null); + + /** + * Associates the specified value with the specified key in this map. + * + * If the map previously contained a mapping for the key, the old value is + * replaced by the specified value. + * + * @param mixed $key The key to put or replace in the map. + * @param mixed $value The value to store at `$key`. + * + * @return mixed|null the previous value associated with key, or `null` if + * there was no mapping for `$key`. + */ + public function put($key, $value); + + /** + * Associates the specified value with the specified key in this map only if + * it is not already set. + * + * If there is already a value associated with `$key`, this returns that + * value without replacing it. + * + * @param mixed $key The key to put in the map. + * @param mixed $value The value to store at `$key`. + * + * @return mixed|null the previous value associated with key, or `null` if + * there was no mapping for `$key`. + */ + public function putIfAbsent($key, $value); + + /** + * Removes the mapping for a key from this map if it is present. + * + * @param mixed $key The key to remove from the map. + * + * @return mixed|null the previous value associated with key, or `null` if + * there was no mapping for `$key`. + */ + public function remove($key); + + /** + * Removes the entry for the specified key only if it is currently mapped to + * the specified value. + * + * This performs a strict type check on the value. + * + * @param mixed $key The key to remove from the map. + * @param mixed $value The value to match. + * + * @return bool true if the value was removed. + */ + public function removeIf($key, $value): bool; + + /** + * Replaces the entry for the specified key only if it is currently mapped + * to some value. + * + * @param mixed $key The key to replace. + * @param mixed $value The value to set at `$key`. + * + * @return mixed|null the previous value associated with key, or `null` if + * there was no mapping for `$key`. + */ + public function replace($key, $value); + + /** + * Replaces the entry for the specified key only if currently mapped to the + * specified value. + * + * This performs a strict type check on the value. + * + * @param mixed $key The key to remove from the map. + * @param mixed $oldValue The value to match. + * @param mixed $newValue The value to use as a replacement. + * + * @return bool true if the value was replaced. + */ + public function replaceIf($key, $oldValue, $newValue): bool; +} diff --git a/vendor/ramsey/collection/src/Map/NamedParameterMap.php b/vendor/ramsey/collection/src/Map/NamedParameterMap.php new file mode 100644 index 000000000..7adfa0afd --- /dev/null +++ b/vendor/ramsey/collection/src/Map/NamedParameterMap.php @@ -0,0 +1,118 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Map; + +use Ramsey\Collection\Exception\InvalidArgumentException; +use Ramsey\Collection\Tool\TypeTrait; +use Ramsey\Collection\Tool\ValueToStringTrait; + +use function array_combine; +use function array_key_exists; +use function is_int; + +/** + * `NamedParameterMap` represents a mapping of values to a set of named keys + * that may optionally be typed + */ +class NamedParameterMap extends AbstractMap +{ + use TypeTrait; + use ValueToStringTrait; + + /** + * Named parameters defined for this map. + * + * @var array<mixed, string> + */ + protected $namedParameters; + + /** + * Constructs a new `NamedParameterMap`. + * + * @param array<mixed, string> $namedParameters The named parameters defined for this map. + * @param mixed[] $data An initial set of data to set on this map. + */ + public function __construct(array $namedParameters, array $data = []) + { + $this->namedParameters = $this->filterNamedParameters($namedParameters); + parent::__construct($data); + } + + /** + * Returns named parameters set for this `NamedParameterMap`. + * + * @return array<mixed, string> + */ + public function getNamedParameters(): array + { + return $this->namedParameters; + } + + /** + * Sets the given value to the given offset in the map. + * + * @param mixed $offset The offset to set. + * @param mixed $value The value to set at the given offset. + * + * @throws InvalidArgumentException if the offset provided is not a + * defined named parameter, or if the value is not of the type defined + * for the given named parameter. + */ + public function offsetSet($offset, $value): void + { + if (!array_key_exists($offset, $this->namedParameters)) { + throw new InvalidArgumentException( + 'Attempting to set value for unconfigured parameter \'' + . $offset . '\'' + ); + } + + if ($this->checkType($this->namedParameters[$offset], $value) === false) { + throw new InvalidArgumentException( + 'Value for \'' . $offset . '\' must be of type ' + . $this->namedParameters[$offset] . '; value is ' + . $this->toolValueToString($value) + ); + } + + $this->data[$offset] = $value; + } + + /** + * Given an array of named parameters, constructs a proper mapping of + * named parameters to types. + * + * @param array<mixed, string> $namedParameters The named parameters to filter. + * + * @return array<mixed, string> + */ + protected function filterNamedParameters(array $namedParameters): array + { + $names = []; + $types = []; + + foreach ($namedParameters as $key => $value) { + if (is_int($key)) { + $names[] = (string) $value; + $types[] = 'mixed'; + } else { + $names[] = $key; + $types[] = (string) $value; + } + } + + return array_combine($names, $types) ?: []; + } +} diff --git a/vendor/ramsey/collection/src/Map/TypedMap.php b/vendor/ramsey/collection/src/Map/TypedMap.php new file mode 100644 index 000000000..84d075f80 --- /dev/null +++ b/vendor/ramsey/collection/src/Map/TypedMap.php @@ -0,0 +1,137 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Map; + +use Ramsey\Collection\Tool\TypeTrait; + +/** + * A `TypedMap` represents a map of elements where key and value are typed. + * + * Each element is identified by a key with defined type and a value of defined + * type. The keys of the map must be unique. The values on the map can be= + * repeated but each with its own different key. + * + * The most common case is to use a string type key, but it's not limited to + * this type of keys. + * + * This is a direct implementation of `TypedMapInterface`, provided for the sake + * of convenience. + * + * Example usage: + * + * ```php + * $map = new TypedMap('string', Foo::class); + * $map['x'] = new Foo(); + * foreach ($map as $key => $value) { + * // do something with $key, it will be a Foo::class + * } + * + * // this will throw an exception since key must be string + * $map[10] = new Foo(); + * + * // this will throw an exception since value must be a Foo + * $map['bar'] = 'bar'; + * + * // initialize map with contents + * $map = new TypedMap('string', Foo::class, [ + * new Foo(), new Foo(), new Foo() + * ]); + * ``` + * + * It is preferable to subclass `AbstractTypedMap` to create your own typed map + * implementation: + * + * ```php + * class FooTypedMap extends AbstractTypedMap + * { + * public function getKeyType() + * { + * return 'int'; + * } + * + * public function getValueType() + * { + * return Foo::class; + * } + * } + * ``` + * + * … but you also may use the `TypedMap` class: + * + * ```php + * class FooTypedMap extends TypedMap + * { + * public function __constructor(array $data = []) + * { + * parent::__construct('int', Foo::class, $data); + * } + * } + * ``` + */ +class TypedMap extends AbstractTypedMap +{ + use TypeTrait; + + /** + * The data type of keys stored in this collection. + * + * A map key's type is immutable once it is set. For this reason, this + * property is set private. + * + * @var string data type of the map key. + */ + private $keyType; + + /** + * The data type of values stored in this collection. + * + * A map values's type is immutable once it is set. For this reason, this + * property is set private. + * + * @var string data type of the map value. + */ + private $valueType; + + /** + * Constructs a map object of the specified key and value types, + * optionally with the specified data. + * + * @param string $keyType The data type of the map's keys. + * @param string $valueType The data type of the map's values. + * @param mixed[] $data The initial data to set for this map. + */ + public function __construct(string $keyType, string $valueType, array $data = []) + { + $this->keyType = $keyType; + $this->valueType = $valueType; + parent::__construct($data); + } + + /** + * Return the type used on the key. + */ + public function getKeyType(): string + { + return $this->keyType; + } + + /** + * Return the type forced on the values. + */ + public function getValueType(): string + { + return $this->valueType; + } +} diff --git a/vendor/ramsey/collection/src/Map/TypedMapInterface.php b/vendor/ramsey/collection/src/Map/TypedMapInterface.php new file mode 100644 index 000000000..54c783695 --- /dev/null +++ b/vendor/ramsey/collection/src/Map/TypedMapInterface.php @@ -0,0 +1,32 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Map; + +/** + * A `TypedMapInterface` represents a map of elements where key and value are + * typed. + */ +interface TypedMapInterface extends MapInterface +{ + /** + * Return the type used on the key. + */ + public function getKeyType(): string; + + /** + * Return the type forced on the values. + */ + public function getValueType(): string; +} diff --git a/vendor/ramsey/collection/src/Queue.php b/vendor/ramsey/collection/src/Queue.php new file mode 100644 index 000000000..4f53ff5e6 --- /dev/null +++ b/vendor/ramsey/collection/src/Queue.php @@ -0,0 +1,226 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection; + +use Ramsey\Collection\Exception\InvalidArgumentException; +use Ramsey\Collection\Exception\NoSuchElementException; +use Ramsey\Collection\Tool\TypeTrait; +use Ramsey\Collection\Tool\ValueToStringTrait; + +/** + * This class provides a basic implementation of `QueueInterface`, to minimize + * the effort required to implement this interface. + */ +class Queue extends AbstractArray implements QueueInterface +{ + use TypeTrait; + use ValueToStringTrait; + + /** + * The type of elements stored in this queue. + * + * A queue's type is immutable once it is set. For this reason, this + * property is set private. + * + * @var string + */ + private $queueType; + + /** + * The index of the head of the queue. + * + * @var int + */ + protected $index = 0; + + /** + * Constructs a queue object of the specified type, optionally with the + * specified data. + * + * @param string $queueType The type (FQCN) associated with this queue. + * @param mixed[] $data The initial items to store in the collection. + */ + public function __construct(string $queueType, array $data = []) + { + $this->queueType = $queueType; + parent::__construct($data); + } + + /** + * Sets the given value to the given offset in the queue. + * + * Since arbitrary offsets may not be manipulated in a queue, this method + * serves only to fulfill the `ArrayAccess` interface requirements. It is + * invoked by other operations when adding values to the queue. + * + * @link http://php.net/manual/en/arrayaccess.offsetset.php ArrayAccess::offsetSet() + * + * @param mixed|null $offset The offset is ignored and is treated as `null`. + * @param mixed $value The value to set at the given offset. + * + * @throws InvalidArgumentException when the value does not match the + * specified type for this queue. + */ + public function offsetSet($offset, $value): void + { + if ($this->checkType($this->getType(), $value) === false) { + throw new InvalidArgumentException( + 'Value must be of type ' . $this->getType() . '; value is ' + . $this->toolValueToString($value) + ); + } + + $this->data[] = $value; + } + + /** + * Ensures that this queue contains the specified element. + * + * This method differs from `offer()` only in that it throws an exception if + * it cannot add the element to the queue. + * + * @see self::offer() + * + * @param mixed $element The element to add to this queue. + * + * @return bool `true` if this queue changed as a result of the call. + * + * @throws InvalidArgumentException when the element does not match the + * specified type for this queue. + */ + public function add($element): bool + { + $this[] = $element; + + return true; + } + + /** + * Retrieves, but does not remove, the head of this queue. + * + * This method differs from `peek()` only in that it throws an exception if + * this queue is empty. + * + * @see self::peek() + * + * @return mixed the head of this queue. + * + * @throws NoSuchElementException if this queue is empty. + */ + public function element() + { + if ($this->count() === 0) { + throw new NoSuchElementException( + 'Can\'t return element from Queue. Queue is empty.' + ); + } + + return $this[$this->index]; + } + + /** + * Inserts the specified element into this queue. + * + * This method differs from `add()` only in that it does not throw an + * exception if it cannot add the element to the queue. + * + * @see self::add() + * + * @param mixed $element The element to add to this queue. + * + * @return bool `true` if the element was added to this queue, else `false`. + */ + public function offer($element): bool + { + try { + return $this->add($element); + } catch (InvalidArgumentException $e) { + return false; + } + } + + /** + * Retrieves, but does not remove, the head of this queue, or returns `null` + * if this queue is empty. + * + * @see self::element() + * + * @return mixed|null the head of this queue, or `null` if this queue is empty. + */ + public function peek() + { + if ($this->count() === 0) { + return null; + } + + return $this[$this->index]; + } + + /** + * Retrieves and removes the head of this queue, or returns `null` + * if this queue is empty. + * + * @see self::remove() + * + * @return mixed|null the head of this queue, or `null` if this queue is empty. + */ + public function poll() + { + if ($this->count() === 0) { + return null; + } + + $head = $this[$this->index]; + + unset($this[$this->index]); + $this->index++; + + return $head; + } + + /** + * Retrieves and removes the head of this queue. + * + * This method differs from `poll()` only in that it throws an exception if + * this queue is empty. + * + * @see self::poll() + * + * @return mixed the head of this queue. + * + * @throws NoSuchElementException if this queue is empty. + */ + public function remove() + { + if ($this->count() === 0) { + throw new NoSuchElementException('Can\'t return element from Queue. Queue is empty.'); + } + + $head = $this[$this->index]; + + unset($this[$this->index]); + $this->index++; + + return $head; + } + + /** + * Returns the type associated with this queue. + */ + public function getType(): string + { + return $this->queueType; + } +} diff --git a/vendor/ramsey/collection/src/QueueInterface.php b/vendor/ramsey/collection/src/QueueInterface.php new file mode 100644 index 000000000..6c7f2ac2c --- /dev/null +++ b/vendor/ramsey/collection/src/QueueInterface.php @@ -0,0 +1,198 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection; + +use Ramsey\Collection\Exception\NoSuchElementException; + +/** + * A queue is a collection in which the entities in the collection are kept in + * order. + * + * The principal operations on the queue are the addition of entities to the end + * (tail), also known as *enqueue*, and removal of entities from the front + * (head), also known as *dequeue*. This makes the queue a first-in-first-out + * (FIFO) data structure. + * + * Besides basic array operations, queues provide additional insertion, + * extraction, and inspection operations. Each of these methods exists in two + * forms: one throws an exception if the operation fails, the other returns a + * special value (either `null` or `false`, depending on the operation). The + * latter form of the insert operation is designed specifically for use with + * capacity-restricted `QueueInterface` implementations; in most + * implementations, insert operations cannot fail. + * + * <table> + * <caption>Summary of QueueInterface methods</caption> + * <thead> + * <tr> + * <td></td> + * <td><em>Throws exception</em></td> + * <td><em>Returns special value</em></td> + * </tr> + * </thead> + * <tbody> + * <tr> + * <th>Insert</th> + * <td><code>add()</code></td> + * <td><code>offer()</code></td> + * </tr> + * <tr> + * <th>Remove</th> + * <td><code>remove()</code></td> + * <td><code>poll()</code></td> + * </tr> + * <tr> + * <th>Examine</th> + * <td><code>element()</code></td> + * <td><code>peek()</code></td> + * </tr> + * </tbody> + * </table> + * + * Queues typically, but do not necessarily, order elements in a FIFO + * (first-in-first-out) manner. Among the exceptions are priority queues, which + * order elements according to a supplied comparator, or the elements' natural + * ordering, and LIFO queues (or stacks) which order the elements LIFO + * (last-in-first-out). Whatever the ordering used, the head of the queue is + * that element which would be removed by a call to remove() or poll(). In a + * FIFO queue, all new elements are inserted at the tail of the queue. Other + * kinds of queues may use different placement rules. Every `QueueInterface` + * implementation must specify its ordering properties. + * + * The `offer()` method inserts an element if possible, otherwise returning + * `false`. This differs from the `add()` method, which can fail to add an + * element only by throwing an unchecked exception. The `offer()` method is + * designed for use when failure is a normal, rather than exceptional + * occurrence, for example, in fixed-capacity (or "bounded") queues. + * + * The `remove()` and `poll()` methods remove and return the head of the queue. + * Exactly which element is removed from the queue is a function of the queue's + * ordering policy, which differs from implementation to implementation. The + * `remove()` and `poll()` methods differ only in their behavior when the queue + * is empty: the `remove()` method throws an exception, while the `poll()` + * method returns `null`. + * + * The `element()` and `peek()` methods return, but do not remove, the head of + * the queue. + * + * `QueueInterface` implementations generally do not allow insertion of `null` + * elements, although some implementations do not prohibit insertion of `null`. + * Even in the implementations that permit it, `null` should not be inserted + * into a queue, as `null` is also used as a special return value by the + * `poll()` method to indicate that the queue contains no elements. + */ +interface QueueInterface extends ArrayInterface +{ + /** + * Ensures that this queue contains the specified element (optional + * operation). + * + * Returns `true` if this queue changed as a result of the call. (Returns + * `false` if this queue does not permit duplicates and already contains the + * specified element.) + * + * Queues that support this operation may place limitations on what elements + * may be added to this queue. In particular, some queues will refuse to add + * `null` elements, and others will impose restrictions on the type of + * elements that may be added. Queue classes should clearly specify in their + * documentation any restrictions on what elements may be added. + * + * If a queue refuses to add a particular element for any reason other than + * that it already contains the element, it must throw an exception (rather + * than returning `false`). This preserves the invariant that a queue always + * contains the specified element after this call returns. + * + * @see self::offer() + * + * @param mixed $element The element to add to this queue. + * + * @return bool `true` if this queue changed as a result of the call. + * + * @throws \RuntimeException if a queue refuses to add a particular element + * for any reason other than that it already contains the element. + * Implementations should use a more-specific exception that extends + * `\RuntimeException`. + */ + public function add($element): bool; + + /** + * Retrieves, but does not remove, the head of this queue. + * + * This method differs from `peek()` only in that it throws an exception if + * this queue is empty. + * + * @see self::peek() + * + * @return mixed the head of this queue. + * + * @throws NoSuchElementException if this queue is empty. + */ + public function element(); + + /** + * Inserts the specified element into this queue if it is possible to do so + * immediately without violating capacity restrictions. + * + * When using a capacity-restricted queue, this method is generally + * preferable to `add()`, which can fail to insert an element only by + * throwing an exception. + * + * @see self::add() + * + * @param mixed $element The element to add to this queue. + * + * @return bool `true` if the element was added to this queue, else `false`. + */ + public function offer($element): bool; + + /** + * Retrieves, but does not remove, the head of this queue, or returns `null` + * if this queue is empty. + * + * @see self::element() + * + * @return mixed|null the head of this queue, or `null` if this queue is empty. + */ + public function peek(); + + /** + * Retrieves and removes the head of this queue, or returns `null` + * if this queue is empty. + * + * @see self::remove() + * + * @return mixed|null the head of this queue, or `null` if this queue is empty. + */ + public function poll(); + + /** + * Retrieves and removes the head of this queue. + * + * This method differs from `poll()` only in that it throws an exception if + * this queue is empty. + * + * @see self::poll() + * + * @return mixed the head of this queue. + * + * @throws NoSuchElementException if this queue is empty. + */ + public function remove(); + + /** + * Returns the type associated with this queue. + */ + public function getType(): string; +} diff --git a/vendor/ramsey/collection/src/Set.php b/vendor/ramsey/collection/src/Set.php new file mode 100644 index 000000000..42fb66c36 --- /dev/null +++ b/vendor/ramsey/collection/src/Set.php @@ -0,0 +1,69 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection; + +/** + * A set is a collection that contains no duplicate elements. + * + * Great care must be exercised if mutable objects are used as set elements. + * The behavior of a set is not specified if the value of an object is changed + * in a manner that affects equals comparisons while the object is an element in + * the set. + * + * Example usage: + * + * ``` php + * $foo = new \My\Foo(); + * $set = new Set(\My\Foo::class); + * + * $set->add($foo); // returns TRUE, the element don't exists + * $set->add($foo); // returns FALSE, the element already exists + * + * $bar = new \My\Foo(); + * $set->add($bar); // returns TRUE, $bar !== $foo + * ``` + */ +class Set extends AbstractSet +{ + /** + * The type of elements stored in this set + * + * A set's type is immutable. For this reason, this property is private. + * + * @var string + */ + private $setType; + + /** + * Constructs a set object of the specified type, optionally with the + * specified data. + * + * @param string $setType The type (FQCN) associated with this set. + * @param mixed[] $data The initial items to store in the set. + */ + public function __construct(string $setType, array $data = []) + { + $this->setType = $setType; + parent::__construct($data); + } + + /** + * Returns the type associated with this set. + */ + public function getType(): string + { + return $this->setType; + } +} diff --git a/vendor/ramsey/collection/src/Tool/TypeTrait.php b/vendor/ramsey/collection/src/Tool/TypeTrait.php new file mode 100644 index 000000000..8214e9654 --- /dev/null +++ b/vendor/ramsey/collection/src/Tool/TypeTrait.php @@ -0,0 +1,73 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Tool; + +use function is_array; +use function is_bool; +use function is_callable; +use function is_float; +use function is_int; +use function is_numeric; +use function is_object; +use function is_resource; +use function is_scalar; +use function is_string; + +/** + * Provides functionality to check values for specific types. + */ +trait TypeTrait +{ + /** + * Returns `true` if value is of the specified type. + * + * @param string $type The type to check the value against. + * @param mixed $value The value to check. + */ + protected function checkType(string $type, $value): bool + { + switch ($type) { + case 'array': + return is_array($value); + case 'bool': + case 'boolean': + return is_bool($value); + case 'callable': + return is_callable($value); + case 'float': + case 'double': + return is_float($value); + case 'int': + case 'integer': + return is_int($value); + case 'null': + return $value === null; + case 'numeric': + return is_numeric($value); + case 'object': + return is_object($value); + case 'resource': + return is_resource($value); + case 'scalar': + return is_scalar($value); + case 'string': + return is_string($value); + case 'mixed': + return true; + default: + return $value instanceof $type; + } + } +} diff --git a/vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php b/vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php new file mode 100644 index 000000000..7bc4878db --- /dev/null +++ b/vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php @@ -0,0 +1,54 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Tool; + +use Ramsey\Collection\Exception\ValueExtractionException; + +use function get_class; +use function method_exists; +use function property_exists; +use function sprintf; + +/** + * Provides functionality to extract the value of a property or method from an object. + */ +trait ValueExtractorTrait +{ + /** + * Extracts the value of the given property or method from the object. + * + * @param object $object The object to extract the value from. + * @param string $propertyOrMethod The property or method for which the + * value should be extracted. + * + * @return mixed the value extracted from the specified property or method. + * + * @throws ValueExtractionException if the method or property is not defined. + */ + protected function extractValue(object $object, string $propertyOrMethod) + { + if (property_exists($object, $propertyOrMethod)) { + return $object->$propertyOrMethod; + } + + if (method_exists($object, $propertyOrMethod)) { + return $object->{$propertyOrMethod}(); + } + + throw new ValueExtractionException( + sprintf('Method or property "%s" not defined in %s', $propertyOrMethod, get_class($object)) + ); + } +} diff --git a/vendor/ramsey/collection/src/Tool/ValueToStringTrait.php b/vendor/ramsey/collection/src/Tool/ValueToStringTrait.php new file mode 100644 index 000000000..34a9a0a68 --- /dev/null +++ b/vendor/ramsey/collection/src/Tool/ValueToStringTrait.php @@ -0,0 +1,89 @@ +<?php + +/** + * This file is part of the ramsey/collection library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Collection\Tool; + +use DateTimeInterface; + +use function get_class; +use function get_resource_type; +use function is_array; +use function is_bool; +use function is_callable; +use function is_resource; +use function is_scalar; + +/** + * Provides functionality to express a value as string + */ +trait ValueToStringTrait +{ + /** + * Returns a string representation of the value. + * + * - null value: `'NULL'` + * - boolean: `'TRUE'`, `'FALSE'` + * - array: `'Array'` + * - scalar: converted-value + * - resource: `'(type resource #number)'` + * - object with `__toString()`: result of `__toString()` + * - object DateTime: ISO 8601 date + * - object: `'(className Object)'` + * - anonymous function: same as object + * + * @param mixed $value the value to return as a string. + */ + protected function toolValueToString($value): string + { + // null + if ($value === null) { + return 'NULL'; + } + + // boolean constants + if (is_bool($value)) { + return $value ? 'TRUE' : 'FALSE'; + } + + // array + if (is_array($value)) { + return 'Array'; + } + + // scalar types (integer, float, string) + if (is_scalar($value)) { + return (string) $value; + } + + // resource + if (is_resource($value)) { + return '(' . get_resource_type($value) . ' resource #' . (int) $value . ')'; + } + + // after this line $value is an object since is not null, scalar, array or resource + + // __toString() is implemented + if (is_callable([$value, '__toString'])) { + return (string) $value->__toString(); + } + + // object of type \DateTime + if ($value instanceof DateTimeInterface) { + return $value->format('c'); + } + + // unknown type + return '(' . get_class($value) . ' Object)'; + } +} diff --git a/vendor/ramsey/uuid/CHANGELOG.md b/vendor/ramsey/uuid/CHANGELOG.md index 57b7f5ea7..e65960558 100644 --- a/vendor/ramsey/uuid/CHANGELOG.md +++ b/vendor/ramsey/uuid/CHANGELOG.md @@ -21,6 +21,597 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Security +## [4.1.1] - 2020-08-18 + +### Fixed + +* Allow use of brick/math version 0.9 + + +## [4.1.0] - 2020-07-28 + +### Changed + +* Improve performance of `Uuid::fromString()`, `Uuid::fromBytes()`, + `UuidInterface#toString()`, and `UuidInterface#getBytes()`. See PR + [#324](https://github.com/ramsey/uuid/pull/324) for more information. + + +## [4.0.1] - 2020-03-29 + +### Fixed + +* Fix collection deserialization errors due to upstream `allowed_classes` being + set to `false`. For details, see [ramsey/uuid#303](https://github.com/ramsey/uuid/issues/303) + and [ramsey/collection#47](https://github.com/ramsey/collection/issues/47). + + +## [4.0.0] - 2020-03-22 + +### Added + +* Add support for version 6 UUIDs, as defined by <http://gh.peabody.io/uuidv6/>, + including the static method `Uuid::uuid6()`, which returns a + `Nonstandard\UuidV6` instance. +* Add ability to generate version 2 (DCE Security) UUIDs, including the static + method `Uuid::uuid2()`, which returns an `Rfc4122\UuidV2` instance. +* Add classes to represent each version of RFC 4122 UUID. When generating new + UUIDs or creating UUIDs from existing strings, bytes, or integers, if the UUID + is an RFC 4122 variant, one of these instances will be returned: + * `Rfc4122\UuidV1` + * `Rfc4122\UuidV2` + * `Rfc4122\UuidV3` + * `Rfc4122\UuidV4` + * `Rfc4122\UuidV5` + * `Rfc4122\NilUuid` +* Add classes to represent version 6 UUIDs, GUIDs, and nonstandard + (non-RFC 4122 variant) UUIDs: + * `Nonstandard\UuidV6` + * `Guid\Guid` + * `Nonstandard\Uuid` +* Add `Uuid::fromDateTime()` to create version 1 UUIDs from instances of + `\DateTimeInterface`. +* The `\DateTimeInterface` instance returned by `UuidInterface::getDateTime()` + (and now `Rfc4122\UuidV1::getDateTime()`) now includes microseconds, as + specified by the version 1 UUID. +* Add `Validator\ValidatorInterface` and `Validator\GenericValidator` to allow + flexibility in validating UUIDs/GUIDs. + * The default validator continues to validate UUID strings using the same + relaxed validation pattern found in the 3.x series of ramsey/uuid. + * Introduce `Rfc4122\Validator` that may be used for strict validation of + RFC 4122 UUID strings. + * Add ability to change the default validator used by `Uuid` through + `FeatureSet::setValidator()`. + * Add `getValidator()` and `setValidator()` to `UuidFactory`. +* Add `Provider\Node\StaticNodeProvider` to assist in setting a custom static + node value with the multicast bit set for version 1 UUIDs. +* Add the following new exceptions: + * `Exception\BuilderNotFoundException` - + Thrown to indicate that no suitable UUID builder could be found. + * `Exception\DateTimeException` - + Thrown to indicate that the PHP DateTime extension encountered an + exception/error. + * `Exception\DceSecurityException` - + Thrown to indicate an exception occurred while dealing with DCE Security + (version 2) UUIDs. + * `Exception\InvalidArgumentException` - + Thrown to indicate that the argument received is not valid. This extends the + built-in PHP `\InvalidArgumentException`, so there should be no BC breaks + with ramsey/uuid throwing this exception, if you are catching the PHP + exception. + * `Exception\InvalidBytesException` - + Thrown to indicate that the bytes being operated on are invalid in some way. + * `Exception\NameException` - + Thrown to indicate that an error occurred while attempting to hash a + namespace and name. + * `Exception\NodeException` - + Throw to indicate that attempting to fetch or create a node ID encountered + an error. + * `Exception\RandomSourceException` - + Thrown to indicate that the source of random data encountered an error. + * `Exception\TimeSourceException` - + Thrown to indicate that the source of time encountered an error. + * `Exception\UnableToBuildUuidException` - + Thrown to indicate a builder is unable to build a UUID. +* Introduce a `Builder\FallbackBuilder`, used by `FeatureSet` to help decide + whether to return a `Uuid` or `Nonstandard\Uuid` when decoding a + UUID string or bytes. +* Add `Rfc4122\UuidInterface` to specifically represent RFC 4122 variant UUIDs. +* Add `Rfc4122\UuidBuilder` to build RFC 4122 variant UUIDs. This replaces the + existing `Builder\DefaultUuidBuilder`, which is now deprecated. +* Introduce `Math\CalculatorInterface` for representing calculators to perform + arithmetic operations on integers. +* Depend on [brick/math](https://github.com/brick/math) for the + `Math\BrickMathCalculator`, which is the default calculator used by this + library when math cannot be performed in native PHP due to integer size + limitations. The calculator is configurable and may be changed, if desired. +* Add `Converter\Number\GenericNumberConverter` and + `Converter\Time\GenericTimeConverter` which will use the calculator provided + to convert numbers and time to values for UUIDs. +* Introduce `Type\Hexadecimal`, `Type\Integer`, `Type\Decimal`, and `Type\Time` + for improved type-safety when dealing with arbitrary string values. +* Add a `Type\TypeInterface` that each of the ramsey/uuid types implements. +* Add `Fields\FieldsInterface` and `Rfc4122\FieldsInterface` to define + field layouts for UUID variants. The implementations `Rfc4122\Fields`, + `Guid\Fields`, and `Nonstandard\Fields` store the 16-byte, + binary string representation of the UUID internally, and these manage + conversion of the binary string into the hexadecimal field values. +* Introduce `Builder\BuilderCollection` and `Provider\Node\NodeProviderCollection`. + These are typed collections for providing builders and node providers to + `Builder\FallbackBuilder` and `Provider\Node\FallbackNodeProvider`, respectively. +* Add `Generator\NameGeneratorInterface` to support alternate methods of + generating bytes for version 3 and version 5 name-based UUID. By default, + ramsey/uuid uses the `Generator\DefaultNameGenerator`, which uses the standard + algorithm this library has used since the beginning. You may choose to use the + new `Generator\PeclUuidNameGenerator` to make use of the new + `uuid_generate_md5()` and `uuid_generate_sha1()` functions in + [ext-uuid version 1.1.0](https://pecl.php.net/package/uuid). + +### Changed + +* Set minimum required PHP version to 7.2. +* This library now works on 32-bit and 64-bit systems, with no degradation in + functionality. +* By default, the following static methods will now return specific instance + types. This should not cause any BC breaks if typehints target `UuidInterface`: + * `Uuid::uuid1` returns `Rfc4122\UuidV1` + * `Uuid::uuid3` returns `Rfc4122\UuidV3` + * `Uuid::uuid4` returns `Rfc4122\UuidV4` + * `Uuid::uuid5` returns `Rfc4122\UuidV5` +* Accept `Type\Hexadecimal` for the `$node` parameter for + `UuidFactoryInterface::uuid1()`. This is in addition to the `int|string` types + already accepted, so there are no BC breaks. `Type\Hexadecimal` is now the + recommended type to pass for `$node`. +* Out of the box, `Uuid::fromString()`, `Uuid::fromBytes()`, and + `Uuid::fromInteger()` will now return either an `Rfc4122\UuidInterface` + instance or an instance of `Nonstandard\Uuid`, depending on whether the input + contains an RFC 4122 variant UUID with a valid version identifier. Both + implement `UuidInterface`, so BC breaks should not occur if typehints use the + interface. +* Change `Uuid::getFields()` to return an instance of `Fields\FieldsInterface`. + Previously, it returned an array of integer values (on 64-bit systems only). +* `Uuid::getDateTime()` now returns an instance of `\DateTimeImmutable` instead + of `\DateTime`. +* Make the following changes to `UuidInterface`: + * `getHex()` now returns a `Type\Hexadecimal` instance. + * `getInteger()` now returns a `Type\Integer` instance. The `Type\Integer` + instance holds a string representation of a 128-bit integer. You may then + use a math library of your choice (bcmath, gmp, etc.) to operate on the + string integer. + * `getDateTime()` now returns `\DateTimeInterface` instead of `\DateTime`. + * Add `__toString()` method. + * Add `getFields()` method. It returns an instance of `Fields\FieldsInterface`. +* Add the following new methods to `UuidFactoryInterface`: + * `uuid2()` + * `uuid6()` + * `fromDateTime()` + * `fromInteger()` + * `getValidator()` +* This library no longer throws generic exceptions. However, this should not + result in BC breaks, since the new exceptions extend from built-in PHP + exceptions that this library previously threw. + * `Exception\UnsupportedOperationException` is now descended from + `\LogicException`. Previously, it descended from `\RuntimeException`. +* Change required constructor parameters for `Uuid`: + * Change the first required constructor parameter for `Uuid` from + `array $fields` to `Rfc4122\FieldsInterface $fields`. + * Add `Converter\TimeConverterInterface $timeConverter` as the fourth + required constructor parameter for `Uuid`. +* Change the second required parameter of `Builder\UuidBuilderInterface::build()` + from `array $fields` to `string $bytes`. Rather than accepting an array of + hexadecimal strings as UUID fields, the `build()` method now expects a byte + string. +* Add `Converter\TimeConverterInterface $timeConverter` as the second required + constructor parameter for `Rfc4122\UuidBuilder`. This also affects the + now-deprecated `Builder\DefaultUuidBuilder`, since this class now inherits + from `Rfc4122\UuidBuilder`. +* Add `convertTime()` method to `Converter\TimeConverterInterface`. +* Add `getTime()` method to `Provider\TimeProviderInterface`. It replaces the + `currentTime()` method. +* `Provider\Node\FallbackNodeProvider` now accepts only a + `Provider\Node\NodeProviderCollection` as its constructor parameter. +* `Provider\Time\FixedTimeProvider` no longer accepts an array but accepts only + `Type\Time` instances. +* `Provider\NodeProviderInterface::getNode()` now returns `Type\Hexadecimal` + instead of `string|false|null`. +* `Converter/TimeConverterInterface::calculateTime()` now returns + `Type\Hexadecimal` instead of `array`. The value is the full UUID timestamp + value (count of 100-nanosecond intervals since the Gregorian calendar epoch) + in hexadecimal format. +* Change methods in `NumberConverterInterface` to accept and return string values + instead of `mixed`; this simplifies the interface and makes it consistent. +* `Generator\DefaultTimeGenerator` no longer adds the variant and version bits + to the bytes it returns. These must be applied to the bytes afterwards. +* When encoding to bytes or decoding from bytes, `OrderedTimeCodec` now checks + whether the UUID is an RFC 4122 variant, version 1 UUID. If not, it will throw + an exception—`InvalidArgumentException` when using + `OrderedTimeCodec::encodeBinary()` and `UnsupportedOperationException` when + using `OrderedTimeCodec::decodeBytes()`. + +### Deprecated + +The following functionality is deprecated and will be removed in ramsey/uuid +5.0.0. + +* The following methods from `UuidInterface` and `Uuid` are deprecated. Use their + counterparts on the `Rfc4122\FieldsInterface` returned by `Uuid::getFields()`. + * `getClockSeqHiAndReservedHex()` + * `getClockSeqLowHex()` + * `getClockSequenceHex()` + * `getFieldsHex()` + * `getNodeHex()` + * `getTimeHiAndVersionHex()` + * `getTimeLowHex()` + * `getTimeMidHex()` + * `getTimestampHex()` + * `getVariant()` + * `getVersion()` +* The following methods from `Uuid` are deprecated. Use the `Rfc4122\FieldsInterface` + instance returned by `Uuid::getFields()` to get the `Type\Hexadecimal` value + for these fields. You may use the new `Math\CalculatorInterface::toIntegerValue()` + method to convert the `Type\Hexadecimal` instances to instances of + `Type\Integer`. This library provides `Math\BrickMathCalculator`, which may be + used for this purpose, or you may use the arbitrary-precision arithemetic + library of your choice. + * `getClockSeqHiAndReserved()` + * `getClockSeqLow()` + * `getClockSequence()` + * `getNode()` + * `getTimeHiAndVersion()` + * `getTimeLow()` + * `getTimeMid()` + * `getTimestamp()` +* `getDateTime()` on `UuidInterface` and `Uuid` is deprecated. Use this method + only on instances of `Rfc4122\UuidV1` or `Nonstandard\UuidV6`. +* `getUrn()` on `UuidInterface` and `Uuid` is deprecated. It is available on + `Rfc4122\UuidInterface` and classes that implement it. +* The following methods are deprecated and have no direct replacements. However, + you may obtain the same information by calling `UuidInterface::getHex()` and + splitting the return value in half. + * `UuidInterface::getLeastSignificantBitsHex()` + * `UuidInterface::getMostSignificantBitsHex()` + * `Uuid::getLeastSignificantBitsHex()` + * `Uuid::getMostSignificantBitsHex()` + * `Uuid::getLeastSignificantBits()` + * `Uuid::getMostSignificantBits()` +* `UuidInterface::getNumberConverter()` and `Uuid::getNumberConverter()` are + deprecated. There is no alternative recommendation, so plan accordingly. +* `Builder\DefaultUuidBuilder` is deprecated; transition to `Rfc4122\UuidBuilder`. +* `Converter\Number\BigNumberConverter` is deprecated; transition to + `Converter\Number\GenericNumberConverter`. +* `Converter\Time\BigNumberTimeConverter` is deprecated; transition to + `Converter\Time\GenericTimeConverter`. +* The classes for representing and generating *degraded* UUIDs are deprecated. + These are no longer necessary; this library now behaves the same on 32-bit and + 64-bit systems. + * `Builder\DegradedUuidBuilder` + * `Converter\Number\DegradedNumberConverter` + * `Converter\Time\DegradedTimeConverter` + * `DegradedUuid` +* The `Uuid::UUID_TYPE_IDENTIFIER` constant is deprecated. Use + `Uuid::UUID_TYPE_DCE_SECURITY` instead. +* The `Uuid::VALID_PATTERN` constant is deprecated. Use + `Validator\GenericValidator::getPattern()` or `Rfc4122\Validator::getPattern()` + instead. + +### Removed + +* Remove the following bytes generators and recommend + `Generator\RandomBytesGenerator` as a suitable replacement: + * `Generator\MtRandGenerator` + * `Generator\OpenSslGenerator` + * `Generator\SodiumRandomGenerator` +* Remove `Exception\UnsatisfiedDependencyException`. This library no longer + throws this exception. +* Remove the method `Provider\TimeProviderInterface::currentTime()`. Use + `Provider\TimeProviderInterface::getTime()` instead. + + +## [4.0.0-beta2] - 2020-03-01 + +## Added + +* Add missing convenience methods for `Rfc4122\UuidV2`. +* Add `Provider\Node\StaticNodeProvider` to assist in setting a custom static + node value with the multicast bit set for version 1 UUIDs. + +## Changed + +* `Provider\NodeProviderInterface::getNode()` now returns `Type\Hexadecimal` + instead of `string|false|null`. + + +## [4.0.0-beta1] - 2020-02-27 + +### Added + +* Add `ValidatorInterface::getPattern()` to return the regular expression + pattern used by the validator. +* Add `v6()` helper function for version 6 UUIDs. + +### Changed + +* Set the pattern constants on validators as `private`. Use the `getPattern()` + method instead. +* Change the `$node` parameter for `UuidFactoryInterface::uuid6()` to accept + `null` or `Type\Hexadecimal`. +* Accept `Type\Hexadecimal` for the `$node` parameter for + `UuidFactoryInterface::uuid1()`. This is in addition to the `int|string` types + already accepted, so there are no BC breaks. `Type\Hexadecimal` is now the + recommended type to pass for `$node`. + +### Removed + +* Remove `currentTime()` method from `Provider\Time\FixedTimeProvider` and + `Provider\Time\SystemTimeProvider`; it had previously been removed from + `Provider\TimeProviderInterface`. + + +## [4.0.0-alpha5] - 2020-02-23 + +### Added + +* Introduce `Builder\BuilderCollection` and `Provider\Node\NodeProviderCollection`. + +### Changed + +* `Builder\FallbackBuilder` now accepts only a `Builder\BuilderCollection` as + its constructor parameter. +* `Provider\Node\FallbackNodeProvider` now accepts only a `Provider\Node\NodeProviderCollection` + as its constructor parameter. +* `Provider\Time\FixedTimeProvider` no longer accepts an array but accepts only + `Type\Time` instances. + + +## [4.0.0-alpha4] - 2020-02-23 + +### Added + +* Add a `Type\TypeInterface` that each of the ramsey/uuid types implements. +* Support version 6 UUIDs; see <http://gh.peabody.io/uuidv6/>. + +### Changed + +* Rename `Type\IntegerValue` to `Type\Integer`. It was originally named + `IntegerValue` because static analysis sees `Integer` in docblock annotations + and treats it as the native `int` type. `Integer` is not a reserved word in + PHP, so it should be named `Integer` for consistency with other types in this + library. When using it, a class alias prevents static analysis from + complaining. +* Mark `Guid\Guid` and `Nonstandard\Uuid` classes as `final`. +* Add `uuid6()` method to `UuidFactoryInterface`. + +### Deprecated + +* `Uuid::UUID_TYPE_IDENTIFIER` is deprecated. Use `Uuid::UUID_TYPE_DCE_SECURITY` + instead. +* `Uuid::VALID_PATTERN` is deprecated. Use `Validator\GenericValidator::VALID_PATTERN` + instead. + + +## [4.0.0-alpha3] - 2020-02-21 + +### Fixed + +* Fix microsecond rounding error on 32-bit systems. + + +## [4.0.0-alpha2] - 2020-02-21 + +### Added + +* Add `Uuid::fromDateTime()` to create version 1 UUIDs from instances of + `\DateTimeInterface`. +* Add `Generator\NameGeneratorInterface` to support alternate methods of + generating bytes for version 3 and version 5 name-based UUID. By default, + ramsey/uuid uses the `Generator\DefaultNameGenerator`, which uses the standard + algorithm this library has used since the beginning. You may choose to use the + new `Generator\PeclUuidNameGenerator` to make use of the new + `uuid_generate_md5()` and `uuid_generate_sha1()` functions in ext-uuid version + 1.1.0. + +### Changed + +* Add `fromDateTime()` method to `UuidFactoryInterface`. +* Change `UuidInterface::getHex()` to return a `Ramsey\Uuid\Type\Hexadecimal` instance. +* Change `UuidInterface::getInteger()` to return a `Ramsey\Uuid\Type\IntegerValue` instance. + +### Fixed + +* Round microseconds to six digits when getting DateTime from v1 UUIDs. This + circumvents a needless exception for an otherwise valid time-based UUID. + + +## [4.0.0-alpha1] - 2020-01-22 + +### Added + +* Add `Validator\ValidatorInterface` and `Validator\GenericValidator` to allow + flexibility in validating UUIDs/GUIDs. + * Add ability to change the default validator used by `Uuid` through + `FeatureSet::setValidator()`. + * Add `getValidator()` and `setValidator()` to `UuidFactory`. +* Add an internal `InvalidArgumentException` that descends from the built-in + PHP `\InvalidArgumentException`. All places that used to throw + `\InvalidArgumentException` now throw `Ramsey\Uuid\Exception\InvalidArgumentException`. + This should not cause any BC breaks, however. +* Add an internal `DateTimeException` that descends from the built-in PHP + `\RuntimeException`. `Uuid::getDateTime()` may throw this exception if + `\DateTimeImmutable` throws an error or exception. +* Add `RandomSourceException` that descends from the built-in PHP + `\RuntimeException`. `DefaultTimeGenerator`, `RandomBytesGenerator`, and + `RandomNodeProvider` may throw this exception if `random_bytes()` or + `random_int()` throw an error or exception. +* Add `Fields\FieldsInterface` and `Rfc4122\FieldsInterface` to define + field layouts for UUID variants. The implementations `Rfc4122\Fields`, + `Guid\Fields`, and `Nonstandard\Fields` store the 16-byte, + binary string representation of the UUID internally, and these manage + conversion of the binary string into the hexadecimal field values. +* Add `Rfc4122\UuidInterface` to specifically represent RFC 4122 variant UUIDs. +* Add classes to represent each version of RFC 4122 UUID. When generating new + UUIDs or creating UUIDs from existing strings, bytes, or integers, if the UUID + is an RFC 4122 variant, one of these instances will be returned: + * `Rfc4122\UuidV1` + * `Rfc4122\UuidV2` + * `Rfc4122\UuidV3` + * `Rfc4122\UuidV4` + * `Rfc4122\UuidV5` + * `Rfc4122\NilUuid` +* Add `Rfc4122\UuidBuilder` to build RFC 4122 variant UUIDs. This replaces the + existing `Builder\DefaultUuidBuilder`, which is now deprecated. +* Add ability to generate version 2 (DCE Security) UUIDs, including the static + method `Uuid::uuid2()`, which returns an `Rfc4122\UuidV2` instance. +* Add classes to represent GUIDs and nonstandard (non-RFC 4122 variant) UUIDs: + * `Guid\Guid` + * `Nonstandard\Uuid`. +* Introduce a `Builder\FallbackBuilder`, used by `FeatureSet` to help decide + whether to return a `Uuid` or `Nonstandard\Uuid` when decoding a + UUID string or bytes. +* Introduce `Type\Hexadecimal`, `Type\IntegerValue`, and `Type\Time` for + improved type-safety when dealing with arbitrary string values. +* Introduce `Math\CalculatorInterface` for representing calculators to perform + arithmetic operations on integers. +* Depend on [brick/math](https://github.com/brick/math) for the + `Math\BrickMathCalculator`, which is the default calculator used by this + library when math cannot be performed in native PHP due to integer size + limitations. The calculator is configurable and may be changed, if desired. +* Add `Converter\Number\GenericNumberConverter` and + `Converter\Time\GenericTimeConverter` which will use the calculator provided + to convert numbers and time to values for UUIDs. +* The `\DateTimeInterface` instance returned by `UuidInterface::getDateTime()` + (and now `Rfc4122\UuidV1::getDateTime()`) now includes microseconds, as + specified by the version 1 UUID. + +### Changed + +* Set minimum required PHP version to 7.2. +* Add `__toString()` method to `UuidInterface`. +* The `UuidInterface::getDateTime()` method now specifies `\DateTimeInterface` + as the return value, rather than `\DateTime`; `Uuid::getDateTime()` now + returns an instance of `\DateTimeImmutable` instead of `\DateTime`. +* Add `getFields()` method to `UuidInterface`. +* Add `getValidator()` method to `UuidFactoryInterface`. +* Add `uuid2()` method to `UuidFactoryInterface`. +* Add `convertTime()` method to `Converter\TimeConverterInterface`. +* Add `getTime()` method to `Provider\TimeProviderInterface`. +* Change `Uuid::getFields()` to return an instance of `Fields\FieldsInterface`. + Previously, it returned an array of integer values (on 64-bit systems only). +* Change the first required constructor parameter for `Uuid` from + `array $fields` to `Rfc4122\FieldsInterface $fields`. +* Introduce `Converter\TimeConverterInterface $timeConverter` as fourth required + constructor parameter for `Uuid` and second required constructor parameter for + `Builder\DefaultUuidBuilder`. +* Change `UuidInterface::getInteger()` to always return a `string` value instead + of `mixed`. This is a string representation of a 128-bit integer. You may then + use a math library of your choice (bcmath, gmp, etc.) to operate on the + string integer. +* Change the second required parameter of `Builder\UuidBuilderInterface::build()` + from `array $fields` to `string $bytes`. Rather than accepting an array of + hexadecimal strings as UUID fields, the `build()` method now expects a byte + string. +* `Generator\DefaultTimeGenerator` no longer adds the variant and version bits + to the bytes it returns. These must be applied to the bytes afterwards. +* `Converter/TimeConverterInterface::calculateTime()` now returns + `Type\Hexadecimal` instead of `array`. The value is the full UUID timestamp + value (count of 100-nanosecond intervals since the Gregorian calendar epoch) + in hexadecimal format. +* Change methods in converter interfaces to accept and return string values + instead of `mixed`; this simplifies the interface and makes it consistent: + * `NumberConverterInterface::fromHex(string $hex): string` + * `NumberConverterInterface::toHex(string $number): string` + * `TimeConverterInterface::calculateTime(string $seconds, string $microseconds): array` +* `UnsupportedOperationException` is now descended from `\LogicException`. + Previously, it descended from `\RuntimeException`. +* When encoding to bytes or decoding from bytes, `OrderedTimeCodec` now checks + whether the UUID is an RFC 4122 variant, version 1 UUID. If not, it will throw + an exception—`InvalidArgumentException` when using + `OrderedTimeCodec::encodeBinary()` and `UnsupportedOperationException` when + using `OrderedTimeCodec::decodeBytes()`. +* Out of the box, `Uuid::fromString()`, `Uuid::fromBytes()`, and + `Uuid::fromInteger()` will now return either an `Rfc4122\UuidInterface` + instance or an instance of `Nonstandard\Uuid`, depending on whether the input + contains an RFC 4122 variant UUID with a valid version identifier. Both + implement `UuidInterface`, so BC breaks should not occur if typehints use the + interface. +* By default, the following static methods will now return the specific instance + types. This should not cause any BC breaks if typehints target `UuidInterface`: + * `Uuid::uuid1` returns `Rfc4122\UuidV1` + * `Uuid::uuid3` returns `Rfc4122\UuidV3` + * `Uuid::uuid4` returns `Rfc4122\UuidV4` + * `Uuid::uuid5` returns `Rfc4122\UuidV5` + +### Deprecated + +The following functionality is deprecated and will be removed in ramsey/uuid +5.0.0. + +* The following methods from `UuidInterface` and `Uuid` are deprecated. Use their + counterparts on the `Rfc4122\FieldsInterface` returned by `Uuid::getFields()`. + * `getClockSeqHiAndReservedHex()` + * `getClockSeqLowHex()` + * `getClockSequenceHex()` + * `getFieldsHex()` + * `getNodeHex()` + * `getTimeHiAndVersionHex()` + * `getTimeLowHex()` + * `getTimeMidHex()` + * `getTimestampHex()` + * `getVariant()` + * `getVersion()` +* The following methods from `Uuid` are deprecated. Use the `Rfc4122\FieldsInterface` + instance returned by `Uuid::getFields()` to get the `Type\Hexadecimal` value + for these fields, and then use the arbitrary-precision arithmetic library of + your choice to convert them to string integers. + * `getClockSeqHiAndReserved()` + * `getClockSeqLow()` + * `getClockSequence()` + * `getNode()` + * `getTimeHiAndVersion()` + * `getTimeLow()` + * `getTimeMid()` + * `getTimestamp()` +* `getDateTime()` on `UuidInterface` and `Uuid` is deprecated. Use this method + only on instances of `Rfc4122\UuidV1`. +* `getUrn()` on `UuidInterface` and `Uuid` is deprecated. It is available on + `Rfc4122\UuidInterface` and classes that implement it. +* The following methods are deprecated and have no direct replacements. However, + you may obtain the same information by calling `UuidInterface::getHex()` and + splitting the return value in half. + * `UuidInterface::getLeastSignificantBitsHex()` + * `UuidInterface::getMostSignificantBitsHex()` + * `Uuid::getLeastSignificantBitsHex()` + * `Uuid::getMostSignificantBitsHex()` + * `Uuid::getLeastSignificantBits()` + * `Uuid::getMostSignificantBits()` +* `UuidInterface::getNumberConverter()` and `Uuid::getNumberConverter()` are + deprecated. There is no alternative recommendation, so plan accordingly. +* `Builder\DefaultUuidBuilder` is deprecated; transition to + `Rfc4122\UuidBuilder`. +* `Converter\Number\BigNumberConverter` is deprecated; transition to + `Converter\Number\GenericNumberConverter`. +* `Converter\Time\BigNumberTimeConverter` is deprecated; transition to + `Converter\Time\GenericTimeConverter`. +* `Provider\TimeProviderInterface::currentTime()` is deprecated; transition to + the `getTimestamp()` method on the same interface. +* The classes for representing and generating *degraded* UUIDs are deprecated. + These are no longer necessary; this library now behaves the same on 32-bit and + 64-bit PHP. + * `Builder\DegradedUuidBuilder` + * `Converter\Number\DegradedNumberConverter` + * `Converter\Time\DegradedTimeConverter` + * `DegradedUuid` + +### Removed + +* Remove the following bytes generators and recommend + `Generator\RandomBytesGenerator` as a suitable replacement: + * `Generator\MtRandGenerator` + * `Generator\OpenSslGenerator` + * `Generator\SodiumRandomGenerator` +* Remove `Exception\UnsatisfiedDependencyException`. This library no longer + throws this exception. + + ## [3.9.3] - 2020-02-20 ### Fixed @@ -441,8 +1032,7 @@ versions leading up to this release.* ### Fixed -* Improve Doctrine conversion to Uuid or string for the ramsey/uuid [Doctrine - field type] +* Improve Doctrine conversion to Uuid or string for the ramsey/uuid [Doctrine field type] ## [2.7.4] - 2014-10-29 @@ -608,7 +1198,18 @@ versions leading up to this release.* [ramsey/uuid-doctrine]: https://github.com/ramsey/uuid-doctrine [ramsey/uuid-console]: https://github.com/ramsey/uuid-console -[unreleased]: https://github.com/ramsey/uuid/compare/3.9.3...HEAD +[unreleased]: https://github.com/ramsey/uuid/compare/4.1.1...HEAD +[4.1.1]: https://github.com/ramsey/uuid/compare/4.1.0...4.1.1 +[4.1.0]: https://github.com/ramsey/uuid/compare/4.0.1...4.1.0 +[4.0.1]: https://github.com/ramsey/uuid/compare/4.0.0...4.0.1 +[4.0.0]: https://github.com/ramsey/uuid/compare/4.0.0-beta2...4.0.0 +[4.0.0-beta2]: https://github.com/ramsey/uuid/compare/4.0.0-beta1...4.0.0-beta2 +[4.0.0-beta1]: https://github.com/ramsey/uuid/compare/4.0.0-alpha5...4.0.0-beta1 +[4.0.0-alpha5]: https://github.com/ramsey/uuid/compare/4.0.0-alpha4...4.0.0-alpha5 +[4.0.0-alpha4]: https://github.com/ramsey/uuid/compare/4.0.0-alpha3...4.0.0-alpha4 +[4.0.0-alpha3]: https://github.com/ramsey/uuid/compare/4.0.0-alpha2...4.0.0-alpha3 +[4.0.0-alpha2]: https://github.com/ramsey/uuid/compare/4.0.0-alpha1...4.0.0-alpha2 +[4.0.0-alpha1]: https://github.com/ramsey/uuid/compare/3.9.3...4.0.0-alpha1 [3.9.3]: https://github.com/ramsey/uuid/compare/3.9.2...3.9.3 [3.9.2]: https://github.com/ramsey/uuid/compare/3.9.1...3.9.2 [3.9.1]: https://github.com/ramsey/uuid/compare/3.9.0...3.9.1 diff --git a/vendor/ramsey/uuid/README.md b/vendor/ramsey/uuid/README.md index 95d4c21c0..0e539e6b8 100644 --- a/vendor/ramsey/uuid/README.md +++ b/vendor/ramsey/uuid/README.md @@ -1,8 +1,5 @@ # ramsey/uuid -*NOTICE: Formerly known as `rhumsaa/uuid`, The package and namespace names have -changed to `ramsey/uuid` and `Ramsey\Uuid`, respectively.* - [![Source Code][badge-source]][source] [![Latest Version][badge-release]][release] [![Software License][badge-license]][license] @@ -11,28 +8,13 @@ changed to `ramsey/uuid` and `Ramsey\Uuid`, respectively.* [![Coverage Status][badge-coverage]][coverage] [![Total Downloads][badge-downloads]][downloads] -ramsey/uuid is a PHP 5.4+ library for generating and working with -[RFC 4122][rfc4122] version 1, 3, 4, and 5 universally unique identifiers -(UUID). +ramsey/uuid is a PHP library for generating and working with universally unique +identifiers (UUIDs). This project adheres to a [Contributor Code of Conduct][conduct]. By participating in this project and its community, you are expected to uphold this code. -From [Wikipedia](http://en.wikipedia.org/wiki/Universally_unique_identifier): - -> The intent of UUIDs is to enable distributed systems to uniquely identify -> information without significant central coordination. In this context the word -> unique should be taken to mean "practically unique" rather than "guaranteed -> unique". Since the identifiers have a finite size, it is possible for two -> differing items to share the same identifier. The identifier size and -> generation process need to be selected so as to make this sufficiently -> improbable in practice. Anyone can create a UUID and use it to identify -> something with reasonable confidence that the same identifier will never be -> unintentionally created by anyone to identify something else. Information -> labeled with UUIDs can therefore be later combined into a single database -> without needing to resolve identifier (ID) conflicts. - Much inspiration for this library came from the [Java][javauuid] and [Python][pyuuid] UUID libraries. @@ -48,103 +30,17 @@ composer require ramsey/uuid ``` -## Upgrading from 2.x to 3.x - -While we have made significant internal changes to the library, we have made -every effort to ensure a seamless upgrade path from the 2.x series of this -library to 3.x. - -One major breaking change is the transition from the `Rhumsaa` root namespace to -`Ramsey`. In most cases, all you will need is to change the namespace to -`Ramsey` in your code, and everything will "just work." - -Here are full details on the breaking changes to the public API of this library: - -1. All namespace references of `Rhumsaa` have changed to `Ramsey`. Simply change - the namespace to `Ramsey` in your code and everything should work. -2. The console application has moved to - [ramsey/uuid-console](https://packagist.org/packages/ramsey/uuid-console). - If using the console functionality, use Composer to require - `ramsey/uuid-console`. -3. The Doctrine field type mapping has moved to - [ramsey/uuid-doctrine](https://packagist.org/packages/ramsey/uuid-doctrine). - If using the Doctrine functionality, use Composer to require - `ramsey/uuid-doctrine`. - - -## What to do if you see a "rhumsaa/uuid is abandoned" message - -When installing your project's dependencies using Composer, you might see the -following message: - -``` -Package rhumsaa/uuid is abandoned, you should avoid using it. Use -ramsey/uuid instead. -``` - -Don't panic. Simply execute the following commands with Composer: - -``` bash -composer remove rhumsaa/uuid -composer require ramsey/uuid=^2.9 -``` - -After doing so, you will have the latest ramsey/uuid package in the 2.x series, -and there will be no need to modify any code; the namespace in the 2.x series is -still `Rhumsaa`. - - -## Requirements - -Some methods in this library have requirements due to integer size restrictions -on 32-bit and 64-bit builds of PHP. A 64-bit build of PHP and the -[Moontoast\Math][] library are recommended. However, this library is designed to -work on 32-bit builds of PHP without Moontoast\Math, with some degraded -functionality. Please check the API documentation for more information. - -If a particular requirement is not present, then an -`UnsatisfiedDependencyException` is thrown, allowing one to catch a bad call in -an environment where the call is not supported and gracefully degrade. - - -## Examples +## Upgrading to Version 4 -See the [cookbook on the wiki][wiki-cookbook] for more examples and approaches -to specific use-cases. +See the documentation for a thorough upgrade guide: -```php -<?php -require 'vendor/autoload.php'; +* [Upgrading ramsey/uuid Version 3 to 4](https://uuid.ramsey.dev/en/latest/upgrading/3-to-4.html) -use Ramsey\Uuid\Uuid; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; -try { +## Documentation - // Generate a version 1 (time-based) UUID object - $uuid1 = Uuid::uuid1(); - echo $uuid1->toString() . "\n"; // i.e. e4eaaaf2-d142-11e1-b3e4-080027620cdd - - // Generate a version 3 (name-based and hashed with MD5) UUID object - $uuid3 = Uuid::uuid3(Uuid::NAMESPACE_DNS, 'php.net'); - echo $uuid3->toString() . "\n"; // i.e. 11a38b9a-b3da-360f-9353-a5a725514269 - - // Generate a version 4 (random) UUID object - $uuid4 = Uuid::uuid4(); - echo $uuid4->toString() . "\n"; // i.e. 25769c6c-d34d-4bfe-ba98-e0ee856f3e7a - - // Generate a version 5 (name-based and hashed with SHA1) UUID object - $uuid5 = Uuid::uuid5(Uuid::NAMESPACE_DNS, 'php.net'); - echo $uuid5->toString() . "\n"; // i.e. c4a760a8-dbcf-5254-a0d9-6a4474bd1b62 - -} catch (UnsatisfiedDependencyException $e) { - - // Some dependency was not met. Either the method cannot be called on a - // 32-bit system, or it can, but it relies on Moontoast\Math to be present. - echo 'Caught exception: ' . $e->getMessage() . "\n"; - -} -``` +Please see <https://uuid.ramsey.dev> for documentation, tips, examples, and +frequently asked questions. ## Contributing @@ -164,8 +60,6 @@ information. [javauuid]: http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html [pyuuid]: http://docs.python.org/3/library/uuid.html [composer]: http://getcomposer.org/ -[moontoast\math]: https://packagist.org/packages/moontoast/math -[wiki-cookbook]: https://github.com/ramsey/uuid/wiki/Ramsey%5CUuid-Cookbook [contributing.md]: https://github.com/ramsey/uuid/blob/master/.github/CONTRIBUTING.md [badge-source]: https://img.shields.io/badge/source-ramsey/uuid-blue.svg?style=flat-square diff --git a/vendor/ramsey/uuid/composer.json b/vendor/ramsey/uuid/composer.json index 81da625ca..41d500b20 100644 --- a/vendor/ramsey/uuid/composer.json +++ b/vendor/ramsey/uuid/composer.json @@ -1,50 +1,48 @@ { "name": "ramsey/uuid", "type": "library", - "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", - "keywords": ["uuid", "identifier", "guid"], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "uuid", + "identifier", + "guid" + ], "homepage": "https://github.com/ramsey/uuid", "license": "MIT", - "authors": [ - { - "name": "Ben Ramsey", - "email": "ben@benramsey.com", - "homepage": "https://benramsey.com" - }, - { - "name": "Marijn Huizendveld", - "email": "marijn.huizendveld@gmail.com" - }, - { - "name": "Thibaud Fabre", - "email": "thibaud@aztech.io" - } - ], "require": { - "php": "^5.4 | ^7 | ^8", + "php": "^7.2 || ^8", "ext-json": "*", - "paragonie/random_compat": "^1 | ^2 | 9.99.99", + "brick/math": "^0.8 || ^0.9", + "ramsey/collection": "^1.0", "symfony/polyfill-ctype": "^1.8" }, "require-dev": { - "codeception/aspect-mock": "^1 | ^2", - "doctrine/annotations": "^1.2", - "goaop/framework": "1.0.0-alpha.2 | ^1 | ^2.1", - "jakub-onderka/php-parallel-lint": "^1", - "mockery/mockery": "^0.9.11 | ^1", + "codeception/aspect-mock": "^3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7.0", + "doctrine/annotations": "^1.8", + "goaop/framework": "^2", + "mockery/mockery": "^1.3", "moontoast/math": "^1.1", "paragonie/random-lib": "^2", - "php-mock/php-mock-phpunit": "^0.3 | ^1.1", - "phpunit/phpunit": "^4.8 | ^5.4 | ^6.5", - "squizlabs/php_codesniffer": "^3.5" + "php-mock/php-mock-mockery": "^1.3", + "php-mock/php-mock-phpunit": "^2.5", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^0.17.1", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-mockery": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^8.5", + "psy/psysh": "^0.10.0", + "slevomat/coding-standard": "^6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "3.9.4" }, "suggest": { - "ext-ctype": "Provides support for PHP Ctype functions", - "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", - "ext-openssl": "Provides the OpenSSL extension for use with the OpenSslGenerator", - "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", - "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", - "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-ctype": "Enables faster processing of character classification using ctype functions.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter" }, @@ -53,7 +51,7 @@ }, "extra": { "branch-alias": { - "dev-master": "3.x-dev" + "dev-master": "4.x-dev" } }, "replace": { @@ -69,24 +67,35 @@ }, "autoload-dev": { "psr-4": { + "Ramsey\\Uuid\\Benchmark\\": "tests/benchmark/", + "Ramsey\\Uuid\\StaticAnalysis\\": "tests/static-analysis/", "Ramsey\\Uuid\\Test\\": "tests/" } }, "scripts": { "lint": "parallel-lint src tests", - "phpcs": "phpcs src tests --standard=psr2 -sp --colors", + "phpbench": "phpbench run", + "phpcbf": "phpcbf -vpw --cache=build/cache/phpcs.cache", + "phpcs": "phpcs --cache=build/cache/phpcs.cache", + "phpstan": [ + "phpstan analyse -c tests/phpstan.neon --no-progress", + "phpstan analyse -c tests/phpstan-tests.neon --no-progress" + ], + "psalm": "psalm --show-info=false --config=tests/psalm.xml", "phpunit": "phpunit --verbose --colors=always", "phpunit-coverage": "phpunit --verbose --colors=always --coverage-html build/coverage", "test": [ "@lint", + "@phpbench", "@phpcs", + "@phpstan", + "@psalm", "@phpunit" ] }, "support": { "issues": "https://github.com/ramsey/uuid/issues", "rss": "https://github.com/ramsey/uuid/releases.atom", - "source": "https://github.com/ramsey/uuid", - "wiki": "https://github.com/ramsey/uuid/wiki" + "source": "https://github.com/ramsey/uuid" } } diff --git a/vendor/ramsey/uuid/src/BinaryUtils.php b/vendor/ramsey/uuid/src/BinaryUtils.php index 18ea467d9..fb8ba9adc 100644 --- a/vendor/ramsey/uuid/src/BinaryUtils.php +++ b/vendor/ramsey/uuid/src/BinaryUtils.php @@ -1,5 +1,17 @@ <?php +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + namespace Ramsey\Uuid; /** @@ -8,32 +20,42 @@ namespace Ramsey\Uuid; class BinaryUtils { /** - * Applies the RFC 4122 variant field to the `clock_seq_hi_and_reserved` field + * Applies the RFC 4122 variant field to the 16-bit clock sequence + * + * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant * - * @param $clockSeqHi - * @return int The high field of the clock sequence multiplexed with the variant - * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 + * @param int $clockSeq The 16-bit clock sequence value before the RFC 4122 + * variant is applied + * + * @return int The 16-bit clock sequence multiplexed with the UUID variant + * + * @psalm-pure */ - public static function applyVariant($clockSeqHi) + public static function applyVariant(int $clockSeq): int { - // Set the variant to RFC 4122 - $clockSeqHi = $clockSeqHi & 0x3f; - $clockSeqHi |= 0x80; + $clockSeq = $clockSeq & 0x3fff; + $clockSeq |= 0x8000; - return $clockSeqHi; + return $clockSeq; } /** - * Applies the RFC 4122 version number to the `time_hi_and_version` field + * Applies the RFC 4122 version number to the 16-bit `time_hi_and_version` field + * + * @link http://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version + * + * @param int $timeHi The value of the 16-bit `time_hi_and_version` field + * before the RFC 4122 version is applied + * @param int $version The RFC 4122 version to apply to the `time_hi` field + * + * @return int The 16-bit time_hi field of the timestamp multiplexed with + * the UUID version number * - * @param string $timeHi - * @param integer $version - * @return int The high field of the timestamp multiplexed with the version number - * @link http://tools.ietf.org/html/rfc4122#section-4.1.3 + * @psalm-pure */ - public static function applyVersion($timeHi, $version) + public static function applyVersion(int $timeHi, int $version): int { - $timeHi = hexdec($timeHi) & 0x0fff; + $timeHi = $timeHi & 0x0fff; $timeHi |= $version << 12; return $timeHi; diff --git a/vendor/ramsey/uuid/src/Builder/BuilderCollection.php b/vendor/ramsey/uuid/src/Builder/BuilderCollection.php new file mode 100644 index 000000000..b3e5f1dc9 --- /dev/null +++ b/vendor/ramsey/uuid/src/Builder/BuilderCollection.php @@ -0,0 +1,73 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Builder; + +use Ramsey\Collection\AbstractCollection; +use Ramsey\Collection\CollectionInterface; +use Ramsey\Uuid\Converter\Number\GenericNumberConverter; +use Ramsey\Uuid\Converter\Time\GenericTimeConverter; +use Ramsey\Uuid\Converter\Time\PhpTimeConverter; +use Ramsey\Uuid\Guid\GuidBuilder; +use Ramsey\Uuid\Math\BrickMathCalculator; +use Ramsey\Uuid\Nonstandard\UuidBuilder as NonstandardUuidBuilder; +use Ramsey\Uuid\Rfc4122\UuidBuilder as Rfc4122UuidBuilder; +use Traversable; + +/** + * A collection of UuidBuilderInterface objects + */ +class BuilderCollection extends AbstractCollection implements CollectionInterface +{ + public function getType(): string + { + return UuidBuilderInterface::class; + } + + /** + * @psalm-mutation-free + * @psalm-suppress ImpureMethodCall + * @psalm-suppress InvalidTemplateParam + */ + public function getIterator(): Traversable + { + return parent::getIterator(); + } + + /** + * Re-constructs the object from its serialized form + * + * @param string $serialized The serialized PHP string to unserialize into + * a UuidInterface instance + * + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + */ + public function unserialize($serialized): void + { + /** @var mixed[] $data */ + $data = unserialize($serialized, [ + 'allowed_classes' => [ + BrickMathCalculator::class, + GenericNumberConverter::class, + GenericTimeConverter::class, + GuidBuilder::class, + NonstandardUuidBuilder::class, + PhpTimeConverter::class, + Rfc4122UuidBuilder::class, + ], + ]); + + $this->data = $data; + } +} diff --git a/vendor/ramsey/uuid/src/Builder/DefaultUuidBuilder.php b/vendor/ramsey/uuid/src/Builder/DefaultUuidBuilder.php index 20656acdf..2af4e867d 100644 --- a/vendor/ramsey/uuid/src/Builder/DefaultUuidBuilder.php +++ b/vendor/ramsey/uuid/src/Builder/DefaultUuidBuilder.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,48 +8,19 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Builder; -use Ramsey\Uuid\Codec\CodecInterface; -use Ramsey\Uuid\Converter\NumberConverterInterface; -use Ramsey\Uuid\Uuid; +use Ramsey\Uuid\Rfc4122\UuidBuilder as Rfc4122UuidBuilder; /** - * DefaultUuidBuilder is the default UUID builder for ramsey/uuid; it builds - * instances of Uuid objects + * @deprecated Transition to {@see Rfc4122UuidBuilder}. + * + * @psalm-immutable */ -class DefaultUuidBuilder implements UuidBuilderInterface +class DefaultUuidBuilder extends Rfc4122UuidBuilder implements UuidBuilderInterface { - /** - * @var NumberConverterInterface - */ - private $converter; - - /** - * Constructs the DefaultUuidBuilder - * - * @param NumberConverterInterface $converter The number converter to use when constructing the Uuid - */ - public function __construct(NumberConverterInterface $converter) - { - $this->converter = $converter; - } - - /** - * Builds a Uuid - * - * @param CodecInterface $codec The codec to use for building this Uuid - * @param array $fields An array of fields from which to construct the Uuid; - * see {@see \Ramsey\Uuid\UuidInterface::getFieldsHex()} for array structure. - * @return Uuid - */ - public function build(CodecInterface $codec, array $fields) - { - return new Uuid($fields, $this->converter, $codec); - } } diff --git a/vendor/ramsey/uuid/src/Builder/DegradedUuidBuilder.php b/vendor/ramsey/uuid/src/Builder/DegradedUuidBuilder.php index 7edb6deb7..23931e416 100644 --- a/vendor/ramsey/uuid/src/Builder/DegradedUuidBuilder.php +++ b/vendor/ramsey/uuid/src/Builder/DegradedUuidBuilder.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,47 +8,69 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Builder; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\Time\DegradedTimeConverter; +use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\DegradedUuid; +use Ramsey\Uuid\Rfc4122\Fields as Rfc4122Fields; +use Ramsey\Uuid\UuidInterface; /** - * DegradedUuidBuilder builds instances of DegradedUuid + * @deprecated DegradedUuid instances are no longer necessary to support 32-bit + * systems. Transition to {@see DefaultUuidBuilder}. + * + * @psalm-immutable */ class DegradedUuidBuilder implements UuidBuilderInterface { /** * @var NumberConverterInterface */ - private $converter; + private $numberConverter; /** - * Constructs the DegradedUuidBuilder - * - * @param NumberConverterInterface $converter The number converter to use when constructing the DegradedUuid + * @var TimeConverterInterface */ - public function __construct(NumberConverterInterface $converter) - { - $this->converter = $converter; + private $timeConverter; + + /** + * @param NumberConverterInterface $numberConverter The number converter to + * use when constructing the DegradedUuid + * @param TimeConverterInterface|null $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to Unix timestamps + */ + public function __construct( + NumberConverterInterface $numberConverter, + ?TimeConverterInterface $timeConverter = null + ) { + $this->numberConverter = $numberConverter; + $this->timeConverter = $timeConverter ?: new DegradedTimeConverter(); } /** - * Builds a DegradedUuid + * Builds and returns a DegradedUuid + * + * @param CodecInterface $codec The codec to use for building this DegradedUuid instance + * @param string $bytes The byte string from which to construct a UUID + * + * @return DegradedUuid The DegradedUuidBuild returns an instance of Ramsey\Uuid\DegradedUuid * - * @param CodecInterface $codec The codec to use for building this DegradedUuid - * @param array $fields An array of fields from which to construct the DegradedUuid; - * see {@see \Ramsey\Uuid\UuidInterface::getFieldsHex()} for array structure. - * @return DegradedUuid + * @psalm-pure */ - public function build(CodecInterface $codec, array $fields) + public function build(CodecInterface $codec, string $bytes): UuidInterface { - return new DegradedUuid($fields, $this->converter, $codec); + return new DegradedUuid( + new Rfc4122Fields($bytes), + $this->numberConverter, + $codec, + $this->timeConverter + ); } } diff --git a/vendor/ramsey/uuid/src/Builder/FallbackBuilder.php b/vendor/ramsey/uuid/src/Builder/FallbackBuilder.php new file mode 100644 index 000000000..cfd4665ac --- /dev/null +++ b/vendor/ramsey/uuid/src/Builder/FallbackBuilder.php @@ -0,0 +1,75 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Builder; + +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Exception\BuilderNotFoundException; +use Ramsey\Uuid\Exception\UnableToBuildUuidException; +use Ramsey\Uuid\UuidInterface; + +/** + * FallbackBuilder builds a UUID by stepping through a list of UUID builders + * until a UUID can be constructed without exceptions + * + * @psalm-immutable + */ +class FallbackBuilder implements UuidBuilderInterface +{ + /** + * @var BuilderCollection + */ + private $builders; + + /** + * @param BuilderCollection $builders An array of UUID builders + */ + public function __construct(BuilderCollection $builders) + { + $this->builders = $builders; + } + + /** + * Builds and returns a UuidInterface instance using the first builder that + * succeeds + * + * @param CodecInterface $codec The codec to use for building this instance + * @param string $bytes The byte string from which to construct a UUID + * + * @return UuidInterface an instance of a UUID object + * + * @psalm-pure + */ + public function build(CodecInterface $codec, string $bytes): UuidInterface + { + $lastBuilderException = null; + + /** @var UuidBuilderInterface $builder */ + foreach ($this->builders as $builder) { + try { + return $builder->build($codec, $bytes); + } catch (UnableToBuildUuidException $exception) { + $lastBuilderException = $exception; + + continue; + } + } + + throw new BuilderNotFoundException( + 'Could not find a suitable builder for the provided codec and fields', + 0, + $lastBuilderException + ); + } +} diff --git a/vendor/ramsey/uuid/src/Builder/UuidBuilderInterface.php b/vendor/ramsey/uuid/src/Builder/UuidBuilderInterface.php index e4e990109..8e58b2b43 100644 --- a/vendor/ramsey/uuid/src/Builder/UuidBuilderInterface.php +++ b/vendor/ramsey/uuid/src/Builder/UuidBuilderInterface.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,28 +8,32 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Builder; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\UuidInterface; /** - * UuidBuilderInterface builds instances UuidInterface + * A UUID builder builds instances of UuidInterface + * + * @psalm-immutable */ interface UuidBuilderInterface { /** - * Builds an instance of a UuidInterface + * Builds and returns a UuidInterface * * @param CodecInterface $codec The codec to use for building this UuidInterface instance - * @param array $fields An array of fields from which to construct a UuidInterface instance; - * see {@see \Ramsey\Uuid\UuidInterface::getFieldsHex()} for array structure. - * @return UuidInterface + * @param string $bytes The byte string from which to construct a UUID + * + * @return UuidInterface Implementations may choose to return more specific + * instances of UUIDs that implement UuidInterface + * + * @psalm-pure */ - public function build(CodecInterface $codec, array $fields); + public function build(CodecInterface $codec, string $bytes): UuidInterface; } diff --git a/vendor/ramsey/uuid/src/Codec/CodecInterface.php b/vendor/ramsey/uuid/src/Codec/CodecInterface.php index c6c54c78a..85f8a7e99 100644 --- a/vendor/ramsey/uuid/src/Codec/CodecInterface.php +++ b/vendor/ramsey/uuid/src/Codec/CodecInterface.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,54 +8,64 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Codec; -use InvalidArgumentException; -use Ramsey\Uuid\Exception\InvalidUuidStringException; use Ramsey\Uuid\UuidInterface; /** - * CodecInterface represents a UUID coder-decoder + * A codec encodes and decodes a UUID according to defined rules + * + * @psalm-immutable */ interface CodecInterface { /** - * Encodes a UuidInterface as a string representation of a UUID + * Returns a hexadecimal string representation of a UuidInterface + * + * @param UuidInterface $uuid The UUID for which to create a hexadecimal + * string representation * - * @param UuidInterface $uuid * @return string Hexadecimal string representation of a UUID + * + * @psalm-return non-empty-string */ - public function encode(UuidInterface $uuid); + public function encode(UuidInterface $uuid): string; /** - * Encodes a UuidInterface as a binary representation of a UUID + * Returns a binary string representation of a UuidInterface + * + * @param UuidInterface $uuid The UUID for which to create a binary string + * representation * - * @param UuidInterface $uuid * @return string Binary string representation of a UUID + * + * @psalm-return non-empty-string */ - public function encodeBinary(UuidInterface $uuid); + public function encodeBinary(UuidInterface $uuid): string; /** - * Decodes a string representation of a UUID into a UuidInterface object instance + * Returns a UuidInterface derived from a hexadecimal string representation * - * @param string $encodedUuid - * @return UuidInterface - * @throws InvalidUuidStringException + * @param string $encodedUuid The hexadecimal string representation to + * convert into a UuidInterface instance + * + * @return UuidInterface An instance of a UUID decoded from a hexadecimal + * string representation */ - public function decode($encodedUuid); + public function decode(string $encodedUuid): UuidInterface; /** - * Decodes a binary representation of a UUID into a UuidInterface object instance + * Returns a UuidInterface derived from a binary string representation + * + * @param string $bytes The binary string representation to convert into a + * UuidInterface instance * - * @param string $bytes - * @return UuidInterface - * @throws InvalidUuidStringException - * @throws InvalidArgumentException if string has not 16 characters + * @return UuidInterface An instance of a UUID decoded from a binary string + * representation */ - public function decodeBytes($bytes); + public function decodeBytes(string $bytes): UuidInterface; } diff --git a/vendor/ramsey/uuid/src/Codec/GuidStringCodec.php b/vendor/ramsey/uuid/src/Codec/GuidStringCodec.php index 367548070..f11e9d50a 100644 --- a/vendor/ramsey/uuid/src/Codec/GuidStringCodec.php +++ b/vendor/ramsey/uuid/src/Codec/GuidStringCodec.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,97 +8,48 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Codec; -use Ramsey\Uuid\Exception\InvalidUuidStringException; +use Ramsey\Uuid\Guid\Guid; use Ramsey\Uuid\UuidInterface; +use function bin2hex; +use function substr; + /** * GuidStringCodec encodes and decodes globally unique identifiers (GUID) * - * @link https://en.wikipedia.org/wiki/Globally_unique_identifier + * @see Guid + * + * @psalm-immutable */ class GuidStringCodec extends StringCodec { - /** - * Encodes a UuidInterface as a string representation of a GUID - * - * @param UuidInterface $uuid - * @return string Hexadecimal string representation of a GUID - */ - public function encode(UuidInterface $uuid) - { - $components = array_values($uuid->getFieldsHex()); - - // Swap byte-order on the first three fields - $this->swapFields($components); - - return vsprintf( - '%08s-%04s-%04s-%02s%02s-%012s', - $components - ); - } - - /** - * Encodes a UuidInterface as a binary representation of a GUID - * - * @param UuidInterface $uuid - * @return string Binary string representation of a GUID - */ - public function encodeBinary(UuidInterface $uuid) + public function decode(string $encodedUuid): UuidInterface { - $components = array_values($uuid->getFieldsHex()); + $bytes = $this->getBytes($encodedUuid); - return hex2bin(implode('', $components)); + return $this->getBuilder()->build($this, $this->swapBytes($bytes)); } - /** - * Decodes a string representation of a GUID into a UuidInterface object instance - * - * @param string $encodedUuid - * @return UuidInterface - * @throws InvalidUuidStringException - */ - public function decode($encodedUuid) - { - $components = $this->extractComponents($encodedUuid); - - $this->swapFields($components); - - return $this->getBuilder()->build($this, $this->getFields($components)); - } - - /** - * Decodes a binary representation of a GUID into a UuidInterface object instance - * - * @param string $bytes - * @return UuidInterface - * @throws InvalidUuidStringException - */ - public function decodeBytes($bytes) + public function decodeBytes(string $bytes): UuidInterface { // Specifically call parent::decode to preserve correct byte order return parent::decode(bin2hex($bytes)); } /** - * Swaps fields to support GUID byte order - * - * @param array $components An array of UUID components (the UUID exploded on its dashes) - * @return void + * Swaps bytes according to the GUID rules */ - protected function swapFields(array &$components) + private function swapBytes(string $bytes): string { - $hex = unpack('H*', pack('L', hexdec($components[0]))); - $components[0] = $hex[1]; - $hex = unpack('H*', pack('S', hexdec($components[1]))); - $components[1] = $hex[1]; - $hex = unpack('H*', pack('S', hexdec($components[2]))); - $components[2] = $hex[1]; + return $bytes[3] . $bytes[2] . $bytes[1] . $bytes[0] + . $bytes[5] . $bytes[4] + . $bytes[7] . $bytes[6] + . substr($bytes, 8); } } diff --git a/vendor/ramsey/uuid/src/Codec/OrderedTimeCodec.php b/vendor/ramsey/uuid/src/Codec/OrderedTimeCodec.php index de91aab8d..fe9f57c76 100644 --- a/vendor/ramsey/uuid/src/Codec/OrderedTimeCodec.php +++ b/vendor/ramsey/uuid/src/Codec/OrderedTimeCodec.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,62 +8,105 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ + +declare(strict_types=1); + namespace Ramsey\Uuid\Codec; -use InvalidArgumentException; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Exception\UnsupportedOperationException; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; +use function strlen; +use function substr; + /** - * OrderedTimeCodec optimizes the bytes to increment UUIDs when time goes by, to improve database INSERTs. - * The string value will be unchanged from StringCodec. Only works for UUID type 1. + * OrderedTimeCodec encodes and decodes a UUID, optimizing the byte order for + * more efficient storage + * + * For binary representations of version 1 UUID, this codec may be used to + * reorganize the time fields, making the UUID closer to sequential when storing + * the bytes. According to Percona, this optimization can improve database + * INSERTs and SELECTs using the UUID column as a key. + * + * The string representation of the UUID will remain unchanged. Only the binary + * representation is reordered. + * + * **PLEASE NOTE:** Binary representations of UUIDs encoded with this codec must + * be decoded with this codec. Decoding using another codec can result in + * malformed UUIDs. + * + * @link https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/ Storing UUID Values in MySQL + * + * @psalm-immutable */ class OrderedTimeCodec extends StringCodec { - /** - * Encodes a UuidInterface as an optimized binary representation of a UUID + * Returns a binary string representation of a UUID, with the timestamp + * fields rearranged for optimized storage * - * @param UuidInterface $uuid - * @return string Binary string representation of a UUID + * @inheritDoc + * @psalm-return non-empty-string + * @psalm-suppress MoreSpecificReturnType we know that the retrieved `string` is never empty + * @psalm-suppress LessSpecificReturnStatement we know that the retrieved `string` is never empty */ - public function encodeBinary(UuidInterface $uuid) + public function encodeBinary(UuidInterface $uuid): string { - $fields = $uuid->getFieldsHex(); + if ( + !($uuid->getFields() instanceof Rfc4122FieldsInterface) + || $uuid->getFields()->getVersion() !== Uuid::UUID_TYPE_TIME + ) { + throw new InvalidArgumentException( + 'Expected RFC 4122 version 1 (time-based) UUID' + ); + } - $optimized = [ - $fields['time_hi_and_version'], - $fields['time_mid'], - $fields['time_low'], - $fields['clock_seq_hi_and_reserved'], - $fields['clock_seq_low'], - $fields['node'], - ]; + $bytes = $uuid->getFields()->getBytes(); - return hex2bin(implode('', $optimized)); + return $bytes[6] . $bytes[7] + . $bytes[4] . $bytes[5] + . $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3] + . substr($bytes, 8); } /** - * Decodes an optimized binary representation of a UUID into a UuidInterface object instance + * Returns a UuidInterface derived from an ordered-time binary string + * representation * - * @param string $bytes - * @return UuidInterface - * @throws InvalidArgumentException if string has not 16 characters + * @throws InvalidArgumentException if $bytes is an invalid length + * + * @inheritDoc */ - public function decodeBytes($bytes) + public function decodeBytes(string $bytes): UuidInterface { if (strlen($bytes) !== 16) { - throw new InvalidArgumentException('$bytes string should contain 16 characters.'); + throw new InvalidArgumentException( + '$bytes string should contain 16 characters.' + ); } - $hex = unpack('H*', $bytes)[1]; + // Rearrange the bytes to their original order. + $rearrangedBytes = $bytes[4] . $bytes[5] . $bytes[6] . $bytes[7] + . $bytes[2] . $bytes[3] + . $bytes[0] . $bytes[1] + . substr($bytes, 8); + + $uuid = parent::decodeBytes($rearrangedBytes); - // Rearrange the fields to their original order - $hex = substr($hex, 8, 4) . substr($hex, 12, 4) . substr($hex, 4, 4) . substr($hex, 0, 4) . substr($hex, 16); + if ( + !($uuid->getFields() instanceof Rfc4122FieldsInterface) + || $uuid->getFields()->getVersion() !== Uuid::UUID_TYPE_TIME + ) { + throw new UnsupportedOperationException( + 'Attempting to decode a non-time-based UUID using ' + . 'OrderedTimeCodec' + ); + } - return $this->decode($hex); + return $uuid; } } diff --git a/vendor/ramsey/uuid/src/Codec/StringCodec.php b/vendor/ramsey/uuid/src/Codec/StringCodec.php index f1bc0249a..fff13bd81 100644 --- a/vendor/ramsey/uuid/src/Codec/StringCodec.php +++ b/vendor/ramsey/uuid/src/Codec/StringCodec.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,23 +8,31 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Codec; -use InvalidArgumentException; use Ramsey\Uuid\Builder\UuidBuilderInterface; +use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Exception\InvalidUuidStringException; +use Ramsey\Uuid\Rfc4122\FieldsInterface; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; +use function hex2bin; +use function implode; +use function str_replace; +use function strlen; +use function substr; + /** * StringCodec encodes and decodes RFC 4122 UUIDs * * @link http://tools.ietf.org/html/rfc4122 + * + * @psalm-immutable */ class StringCodec implements CodecInterface { @@ -33,138 +42,96 @@ class StringCodec implements CodecInterface private $builder; /** - * Constructs a StringCodec for use encoding and decoding UUIDs + * Constructs a StringCodec * - * @param UuidBuilderInterface $builder The UUID builder to use when encoding UUIDs + * @param UuidBuilderInterface $builder The builder to use when encoding UUIDs */ public function __construct(UuidBuilderInterface $builder) { $this->builder = $builder; } - /** - * Encodes a UuidInterface as a string representation of a UUID - * - * @param UuidInterface $uuid - * @return string Hexadecimal string representation of a UUID - */ - public function encode(UuidInterface $uuid) + public function encode(UuidInterface $uuid): string { - $fields = array_values($uuid->getFieldsHex()); - - return vsprintf( - '%08s-%04s-%04s-%02s%02s-%012s', - $fields - ); + /** @var FieldsInterface $fields */ + $fields = $uuid->getFields(); + + return $fields->getTimeLow()->toString() + . '-' + . $fields->getTimeMid()->toString() + . '-' + . $fields->getTimeHiAndVersion()->toString() + . '-' + . $fields->getClockSeqHiAndReserved()->toString() + . $fields->getClockSeqLow()->toString() + . '-' + . $fields->getNode()->toString(); } /** - * Encodes a UuidInterface as a binary representation of a UUID - * - * @param UuidInterface $uuid - * @return string Binary string representation of a UUID + * @psalm-return non-empty-string + * @psalm-suppress MoreSpecificReturnType we know that the retrieved `string` is never empty + * @psalm-suppress LessSpecificReturnStatement we know that the retrieved `string` is never empty */ - public function encodeBinary(UuidInterface $uuid) + public function encodeBinary(UuidInterface $uuid): string { - return hex2bin($uuid->getHex()); + return $uuid->getFields()->getBytes(); } /** - * Decodes a string representation of a UUID into a UuidInterface object instance - * - * @param string $encodedUuid - * @return UuidInterface * @throws InvalidUuidStringException + * + * @inheritDoc */ - public function decode($encodedUuid) + public function decode(string $encodedUuid): UuidInterface { - $components = $this->extractComponents($encodedUuid); - $fields = $this->getFields($components); - - return $this->builder->build($this, $fields); + return $this->builder->build($this, $this->getBytes($encodedUuid)); } - /** - * Decodes a binary representation of a UUID into a UuidInterface object instance - * - * @param string $bytes - * @return UuidInterface - * @throws InvalidArgumentException if string has not 16 characters - */ - public function decodeBytes($bytes) + public function decodeBytes(string $bytes): UuidInterface { if (strlen($bytes) !== 16) { - throw new InvalidArgumentException('$bytes string should contain 16 characters.'); + throw new InvalidArgumentException( + '$bytes string should contain 16 characters.' + ); } - $hexUuid = unpack('H*', $bytes); - - return $this->decode($hexUuid[1]); + return $this->builder->build($this, $bytes); } /** * Returns the UUID builder - * - * @return UuidBuilderInterface */ - protected function getBuilder() + protected function getBuilder(): UuidBuilderInterface { return $this->builder; } /** - * Returns an array of UUID components (the UUID exploded on its dashes) - * - * @param string $encodedUuid - * @return array - * @throws InvalidUuidStringException + * Returns a byte string of the UUID */ - protected function extractComponents($encodedUuid) + protected function getBytes(string $encodedUuid): string { - $nameParsed = str_replace([ - 'urn:', - 'uuid:', - '{', - '}', - '-' - ], '', $encodedUuid); - - // We have stripped out the dashes and are breaking up the string using - // substr(). In this way, we can accept a full hex value that doesn't - // contain dashes. + $parsedUuid = str_replace( + ['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}', '-'], + '', + $encodedUuid + ); + $components = [ - substr($nameParsed, 0, 8), - substr($nameParsed, 8, 4), - substr($nameParsed, 12, 4), - substr($nameParsed, 16, 4), - substr($nameParsed, 20) + substr($parsedUuid, 0, 8), + substr($parsedUuid, 8, 4), + substr($parsedUuid, 12, 4), + substr($parsedUuid, 16, 4), + substr($parsedUuid, 20), ]; - $nameParsed = implode('-', $components); - - if (!Uuid::isValid($nameParsed)) { - throw new InvalidUuidStringException('Invalid UUID string: ' . $encodedUuid); + if (!Uuid::isValid(implode('-', $components))) { + throw new InvalidUuidStringException( + 'Invalid UUID string: ' . $encodedUuid + ); } - return $components; - } - - /** - * Returns the fields that make up this UUID - * - * @see \Ramsey\Uuid\UuidInterface::getFieldsHex() - * @param array $components - * @return array - */ - protected function getFields(array $components) - { - return [ - 'time_low' => str_pad($components[0], 8, '0', STR_PAD_LEFT), - 'time_mid' => str_pad($components[1], 4, '0', STR_PAD_LEFT), - 'time_hi_and_version' => str_pad($components[2], 4, '0', STR_PAD_LEFT), - 'clock_seq_hi_and_reserved' => str_pad(substr($components[3], 0, 2), 2, '0', STR_PAD_LEFT), - 'clock_seq_low' => str_pad(substr($components[3], 2), 2, '0', STR_PAD_LEFT), - 'node' => str_pad($components[4], 12, '0', STR_PAD_LEFT) - ]; + return (string) hex2bin($parsedUuid); } } diff --git a/vendor/ramsey/uuid/src/Codec/TimestampFirstCombCodec.php b/vendor/ramsey/uuid/src/Codec/TimestampFirstCombCodec.php index 9d13af70c..06ce38fbb 100644 --- a/vendor/ramsey/uuid/src/Codec/TimestampFirstCombCodec.php +++ b/vendor/ramsey/uuid/src/Codec/TimestampFirstCombCodec.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,102 +8,105 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ + +declare(strict_types=1); + namespace Ramsey\Uuid\Codec; use Ramsey\Uuid\Exception\InvalidUuidStringException; use Ramsey\Uuid\UuidInterface; +use function bin2hex; +use function sprintf; +use function substr; +use function substr_replace; + /** - * TimestampFirstCombCodec encodes and decodes COMB UUIDs which have the timestamp as the first 48 bits. - * To be used with MySQL, PostgreSQL, Oracle. + * TimestampFirstCombCodec encodes and decodes COMBs, with the timestamp as the + * first 48 bits + * + * In contrast with the TimestampLastCombCodec, the TimestampFirstCombCodec + * adds the timestamp to the first 48 bits of the COMB. To generate a + * timestamp-first COMB, set the TimestampFirstCombCodec as the codec, along + * with the CombGenerator as the random generator. + * + * ``` php + * $factory = new UuidFactory(); + * + * $factory->setCodec(new TimestampFirstCombCodec($factory->getUuidBuilder())); + * + * $factory->setRandomGenerator(new CombGenerator( + * $factory->getRandomGenerator(), + * $factory->getNumberConverter() + * )); + * + * $timestampFirstComb = $factory->uuid4(); + * ``` + * + * @link https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys + * + * @psalm-immutable */ class TimestampFirstCombCodec extends StringCodec { /** - * Encodes a UuidInterface as a string representation of a timestamp first COMB UUID - * - * @param UuidInterface $uuid - * - * @return string Hexadecimal string representation of a GUID + * @psalm-return non-empty-string + * @psalm-suppress MoreSpecificReturnType we know that the retrieved `string` is never empty + * @psalm-suppress LessSpecificReturnStatement we know that the retrieved `string` is never empty */ - public function encode(UuidInterface $uuid) + public function encode(UuidInterface $uuid): string { - $sixPieceComponents = array_values($uuid->getFieldsHex()); - - $this->swapTimestampAndRandomBits($sixPieceComponents); + $bytes = $this->swapBytes($uuid->getFields()->getBytes()); - return vsprintf( - '%08s-%04s-%04s-%02s%02s-%012s', - $sixPieceComponents + return sprintf( + '%08s-%04s-%04s-%04s-%012s', + bin2hex(substr($bytes, 0, 4)), + bin2hex(substr($bytes, 4, 2)), + bin2hex(substr($bytes, 6, 2)), + bin2hex(substr($bytes, 8, 2)), + bin2hex(substr($bytes, 10)) ); } /** - * Encodes a UuidInterface as a binary representation of timestamp first COMB UUID - * - * @param UuidInterface $uuid - * - * @return string Binary string representation of timestamp first COMB UUID + * @psalm-return non-empty-string + * @psalm-suppress MoreSpecificReturnType we know that the retrieved `string` is never empty + * @psalm-suppress LessSpecificReturnStatement we know that the retrieved `string` is never empty */ - public function encodeBinary(UuidInterface $uuid) + public function encodeBinary(UuidInterface $uuid): string { - $stringEncoding = $this->encode($uuid); - - return hex2bin(str_replace('-', '', $stringEncoding)); + return $this->swapBytes($uuid->getFields()->getBytes()); } /** - * Decodes a string representation of timestamp first COMB UUID into a UuidInterface object instance - * - * @param string $encodedUuid - * - * @return UuidInterface * @throws InvalidUuidStringException + * + * @inheritDoc */ - public function decode($encodedUuid) + public function decode(string $encodedUuid): UuidInterface { - $fivePieceComponents = $this->extractComponents($encodedUuid); - - $this->swapTimestampAndRandomBits($fivePieceComponents); + $bytes = $this->getBytes($encodedUuid); - return $this->getBuilder()->build($this, $this->getFields($fivePieceComponents)); + return $this->getBuilder()->build($this, $this->swapBytes($bytes)); } - /** - * Decodes a binary representation of timestamp first COMB UUID into a UuidInterface object instance - * - * @param string $bytes - * - * @return UuidInterface - * @throws InvalidUuidStringException - */ - public function decodeBytes($bytes) + public function decodeBytes(string $bytes): UuidInterface { - return $this->decode(bin2hex($bytes)); + return $this->getBuilder()->build($this, $this->swapBytes($bytes)); } /** - * Swaps the first 48 bits with the last 48 bits - * - * @param array $components An array of UUID components (the UUID exploded on its dashes) - * - * @return void + * Swaps bytes according to the timestamp-first COMB rules */ - protected function swapTimestampAndRandomBits(array &$components) + private function swapBytes(string $bytes): string { - $last48Bits = $components[4]; - if (count($components) == 6) { - $last48Bits = $components[5]; - $components[5] = $components[0] . $components[1]; - } else { - $components[4] = $components[0] . $components[1]; - } + $first48Bits = substr($bytes, 0, 6); + $last48Bits = substr($bytes, -6); + + $bytes = substr_replace($bytes, $last48Bits, 0, 6); + $bytes = substr_replace($bytes, $first48Bits, -6); - $components[0] = substr($last48Bits, 0, 8); - $components[1] = substr($last48Bits, 8, 4); + return $bytes; } } diff --git a/vendor/ramsey/uuid/src/Codec/TimestampLastCombCodec.php b/vendor/ramsey/uuid/src/Codec/TimestampLastCombCodec.php index 240f613e2..4856deaed 100644 --- a/vendor/ramsey/uuid/src/Codec/TimestampLastCombCodec.php +++ b/vendor/ramsey/uuid/src/Codec/TimestampLastCombCodec.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,15 +8,43 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ + +declare(strict_types=1); + namespace Ramsey\Uuid\Codec; /** - * TimestampLastCombCodec encodes and decodes COMB UUIDs which have the timestamp as the last 48 bits. - * To be used with MSSQL. + * TimestampLastCombCodec encodes and decodes COMBs, with the timestamp as the + * last 48 bits + * + * The CombGenerator when used with the StringCodec (and, by proxy, the + * TimestampLastCombCodec) adds the timestamp to the last 48 bits of the COMB. + * The TimestampLastCombCodec is provided for the sake of consistency. In + * practice, it is identical to the standard StringCodec but, it may be used + * with the CombGenerator for additional context when reading code. + * + * Consider the following code. By default, the codec used by UuidFactory is the + * StringCodec, but here, we explicitly set the TimestampLastCombCodec. It is + * redundant, but it is clear that we intend this COMB to be generated with the + * timestamp appearing at the end. + * + * ``` php + * $factory = new UuidFactory(); + * + * $factory->setCodec(new TimestampLastCombCodec($factory->getUuidBuilder())); + * + * $factory->setRandomGenerator(new CombGenerator( + * $factory->getRandomGenerator(), + * $factory->getNumberConverter() + * )); + * + * $timestampLastComb = $factory->uuid4(); + * ``` + * + * @link https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys + * + * @psalm-immutable */ class TimestampLastCombCodec extends StringCodec { diff --git a/vendor/ramsey/uuid/src/Converter/Number/BigNumberConverter.php b/vendor/ramsey/uuid/src/Converter/Number/BigNumberConverter.php index d23512256..fef63fd00 100644 --- a/vendor/ramsey/uuid/src/Converter/Number/BigNumberConverter.php +++ b/vendor/ramsey/uuid/src/Converter/Number/BigNumberConverter.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,48 +8,50 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Converter\Number; -use Moontoast\Math\BigNumber; use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Math\BrickMathCalculator; /** - * BigNumberConverter converts UUIDs from hexadecimal characters into - * moontoast/math `BigNumber` representations of integers and vice versa + * Previously used to integrate moontoast/math as a bignum arithmetic library, + * BigNumberConverter is deprecated in favor of GenericNumberConverter + * + * @deprecated Transition to {@see GenericNumberConverter}. + * + * @psalm-immutable */ class BigNumberConverter implements NumberConverterInterface { /** - * Converts a hexadecimal number into a `Moontoast\Math\BigNumber` representation - * - * @param string $hex The hexadecimal string representation to convert - * @return BigNumber + * @var NumberConverterInterface */ - public function fromHex($hex) - { - $number = BigNumber::convertToBase10($hex, 16); + private $converter; - return new BigNumber($number); + public function __construct() + { + $this->converter = new GenericNumberConverter(new BrickMathCalculator()); } /** - * Converts an integer or `Moontoast\Math\BigNumber` integer representation - * into a hexadecimal string representation - * - * @param int|string|BigNumber $integer An integer or `Moontoast\Math\BigNumber` - * @return string Hexadecimal string + * @inheritDoc + * @psalm-pure */ - public function toHex($integer) + public function fromHex(string $hex): string { - if (!$integer instanceof BigNumber) { - $integer = new BigNumber($integer); - } + return $this->converter->fromHex($hex); + } - return BigNumber::convertFromBase10($integer, 16); + /** + * @inheritDoc + * @psalm-pure + */ + public function toHex(string $number): string + { + return $this->converter->toHex($number); } } diff --git a/vendor/ramsey/uuid/src/Converter/Number/DegradedNumberConverter.php b/vendor/ramsey/uuid/src/Converter/Number/DegradedNumberConverter.php index 96a011c65..c9cfa6864 100644 --- a/vendor/ramsey/uuid/src/Converter/Number/DegradedNumberConverter.php +++ b/vendor/ramsey/uuid/src/Converter/Number/DegradedNumberConverter.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,52 +8,18 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ -namespace Ramsey\Uuid\Converter\Number; +declare(strict_types=1); -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; -use Ramsey\Uuid\Converter\NumberConverterInterface; +namespace Ramsey\Uuid\Converter\Number; /** - * DegradedNumberConverter throws `UnsatisfiedDependencyException` exceptions - * if attempting to use number conversion functionality in an environment that - * does not support large integers (i.e. when moontoast/math is not available) + * @deprecated DegradedNumberConverter is no longer necessary for converting + * numbers on 32-bit systems. Transition to {@see GenericNumberConverter}. + * + * @psalm-immutable */ -class DegradedNumberConverter implements NumberConverterInterface +class DegradedNumberConverter extends BigNumberConverter { - /** - * Throws an `UnsatisfiedDependencyException` - * - * @param string $hex The hexadecimal string representation to convert - * @return void - * @throws UnsatisfiedDependencyException - */ - public function fromHex($hex) - { - throw new UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' without support for large ' - . 'integers, since integer is an unsigned ' - . '128-bit integer; Moontoast\Math\BigNumber is required.' - ); - } - - /** - * Throws an `UnsatisfiedDependencyException` - * - * @param mixed $integer An integer representation to convert - * @return void - * @throws UnsatisfiedDependencyException - */ - public function toHex($integer) - { - throw new UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' without support for large ' - . 'integers, since integer is an unsigned ' - . '128-bit integer; Moontoast\Math\BigNumber is required. ' - ); - } } diff --git a/vendor/ramsey/uuid/src/Converter/Number/GenericNumberConverter.php b/vendor/ramsey/uuid/src/Converter/Number/GenericNumberConverter.php new file mode 100644 index 000000000..c85bc3a71 --- /dev/null +++ b/vendor/ramsey/uuid/src/Converter/Number/GenericNumberConverter.php @@ -0,0 +1,62 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Converter\Number; + +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Math\CalculatorInterface; +use Ramsey\Uuid\Type\Integer as IntegerObject; + +/** + * GenericNumberConverter uses the provided calculate to convert decimal + * numbers to and from hexadecimal values + * + * @psalm-immutable + */ +class GenericNumberConverter implements NumberConverterInterface +{ + /** + * @var CalculatorInterface + */ + private $calculator; + + public function __construct(CalculatorInterface $calculator) + { + $this->calculator = $calculator; + } + + /** + * @inheritDoc + * @psalm-pure + * @psalm-return numeric-string + * @psalm-suppress MoreSpecificReturnType we know that the retrieved `string` is never empty + * @psalm-suppress LessSpecificReturnStatement we know that the retrieved `string` is never empty + */ + public function fromHex(string $hex): string + { + return $this->calculator->fromBase($hex, 16)->toString(); + } + + /** + * @inheritDoc + * @psalm-pure + * @psalm-return non-empty-string + * @psalm-suppress MoreSpecificReturnType we know that the retrieved `string` is never empty + * @psalm-suppress LessSpecificReturnStatement we know that the retrieved `string` is never empty + */ + public function toHex(string $number): string + { + return $this->calculator->toBase(new IntegerObject($number), 16); + } +} diff --git a/vendor/ramsey/uuid/src/Converter/NumberConverterInterface.php b/vendor/ramsey/uuid/src/Converter/NumberConverterInterface.php index b978e2e7b..b33ec31f9 100644 --- a/vendor/ramsey/uuid/src/Converter/NumberConverterInterface.php +++ b/vendor/ramsey/uuid/src/Converter/NumberConverterInterface.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,42 +8,50 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ -namespace Ramsey\Uuid\Converter; +declare(strict_types=1); -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; +namespace Ramsey\Uuid\Converter; /** - * NumberConverterInterface converts UUIDs from hexadecimal characters into + * A number converter converts UUIDs from hexadecimal characters into * representations of integers and vice versa + * + * @psalm-immutable */ interface NumberConverterInterface { /** - * Converts a hexadecimal number into an integer representation of the number + * Converts a hexadecimal number into an string integer representation of + * the number * - * The integer representation returned may be an object or a string - * representation of the integer, depending on the implementation. + * The integer representation returned is a string representation of the + * integer, to accommodate unsigned integers greater than PHP_INT_MAX. * * @param string $hex The hexadecimal string representation to convert - * @return mixed - * @throws UnsatisfiedDependencyException if `Moontoast\Math\BigNumber` is not present + * + * @return string String representation of an integer + * + * @psalm-return numeric-string + * + * @psalm-pure */ - public function fromHex($hex); + public function fromHex(string $hex): string; /** - * Converts an integer representation into a hexadecimal string representation - * of the number + * Converts a string integer representation into a hexadecimal string + * representation of the number + * + * @param string $number A string integer representation to convert; this + * must be a numeric string to accommodate unsigned integers greater + * than PHP_INT_MAX. * - * @param mixed $integer An integer representation to convert; this may be - * a true integer, a string integer, or a object representation that - * this converter can understand * @return string Hexadecimal string - * @throws UnsatisfiedDependencyException if `Moontoast\Math\BigNumber` is not present + * + * @psalm-return non-empty-string + * + * @psalm-pure */ - public function toHex($integer); + public function toHex(string $number): string; } diff --git a/vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php b/vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php index 112f72272..7390dad83 100644 --- a/vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php +++ b/vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,53 +8,44 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Converter\Time; -use Moontoast\Math\BigNumber; use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Math\BrickMathCalculator; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Time; /** - * BigNumberTimeConverter uses the moontoast/math library's `BigNumber` to - * provide facilities for converting parts of time into representations that may - * be used in UUIDs + * Previously used to integrate moontoast/math as a bignum arithmetic library, + * BigNumberTimeConverter is deprecated in favor of GenericTimeConverter + * + * @deprecated Transition to {@see GenericTimeConverter}. + * + * @psalm-immutable */ class BigNumberTimeConverter implements TimeConverterInterface { /** - * Uses the provided seconds and micro-seconds to calculate the time_low, - * time_mid, and time_high fields used by RFC 4122 version 1 UUIDs - * - * @param string $seconds - * @param string $microSeconds - * @return string[] An array containing `low`, `mid`, and `high` keys - * @link http://tools.ietf.org/html/rfc4122#section-4.2.2 + * @var TimeConverterInterface */ - public function calculateTime($seconds, $microSeconds) - { - $uuidTime = new BigNumber('0'); - - $sec = new BigNumber($seconds); - $sec->multiply('10000000'); + private $converter; - $usec = new BigNumber($microSeconds); - $usec->multiply('10'); - - $uuidTime - ->add($sec) - ->add($usec) - ->add('122192928000000000'); + public function __construct() + { + $this->converter = new GenericTimeConverter(new BrickMathCalculator()); + } - $uuidTimeHex = sprintf('%016s', $uuidTime->convertToBase(16)); + public function calculateTime(string $seconds, string $microseconds): Hexadecimal + { + return $this->converter->calculateTime($seconds, $microseconds); + } - return [ - 'low' => substr($uuidTimeHex, 8), - 'mid' => substr($uuidTimeHex, 4, 4), - 'hi' => substr($uuidTimeHex, 0, 4), - ]; + public function convertTime(Hexadecimal $uuidTimestamp): Time + { + return $this->converter->convertTime($uuidTimestamp); } } diff --git a/vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php b/vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php index b94589cd3..cdc28752d 100644 --- a/vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php +++ b/vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,36 +8,18 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ -namespace Ramsey\Uuid\Converter\Time; +declare(strict_types=1); -use Ramsey\Uuid\Converter\TimeConverterInterface; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; +namespace Ramsey\Uuid\Converter\Time; /** - * DegradedTimeConverter throws `UnsatisfiedDependencyException` exceptions - * if attempting to use time conversion functionality in an environment that - * does not support large integers (i.e. when moontoast/math is not available) + * @deprecated DegradedTimeConverter is no longer necessary for converting + * time on 32-bit systems. Transition to {@see GenericTimeConverter}. + * + * @psalm-immutable */ -class DegradedTimeConverter implements TimeConverterInterface +class DegradedTimeConverter extends BigNumberTimeConverter { - /** - * Throws an `UnsatisfiedDependencyException` - * - * @param string $seconds - * @param string $microSeconds - * @return void - * @throws UnsatisfiedDependencyException if called on a 32-bit system and `Moontoast\Math\BigNumber` is not present - */ - public function calculateTime($seconds, $microSeconds) - { - throw new UnsatisfiedDependencyException( - 'When calling ' . __METHOD__ . ' on a 32-bit system, ' - . 'Moontoast\Math\BigNumber must be present.' - ); - } } diff --git a/vendor/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php b/vendor/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php new file mode 100644 index 000000000..a8aa64b73 --- /dev/null +++ b/vendor/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php @@ -0,0 +1,124 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Converter\Time; + +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Math\CalculatorInterface; +use Ramsey\Uuid\Math\RoundingMode; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\Type\Time; + +use function explode; +use function str_pad; + +use const STR_PAD_LEFT; + +/** + * GenericTimeConverter uses the provided calculator to calculate and convert + * time values + * + * @psalm-immutable + */ +class GenericTimeConverter implements TimeConverterInterface +{ + /** + * The number of 100-nanosecond intervals from the Gregorian calendar epoch + * to the Unix epoch. + */ + private const GREGORIAN_TO_UNIX_INTERVALS = '122192928000000000'; + + /** + * The number of 100-nanosecond intervals in one second. + */ + private const SECOND_INTERVALS = '10000000'; + + /** + * The number of 100-nanosecond intervals in one microsecond. + */ + private const MICROSECOND_INTERVALS = '10'; + + /** + * @var CalculatorInterface + */ + private $calculator; + + public function __construct(CalculatorInterface $calculator) + { + $this->calculator = $calculator; + } + + public function calculateTime(string $seconds, string $microseconds): Hexadecimal + { + $timestamp = new Time($seconds, $microseconds); + + // Convert the seconds into a count of 100-nanosecond intervals. + $sec = $this->calculator->multiply( + $timestamp->getSeconds(), + new IntegerObject(self::SECOND_INTERVALS) + ); + + // Convert the microseconds into a count of 100-nanosecond intervals. + $usec = $this->calculator->multiply( + $timestamp->getMicroseconds(), + new IntegerObject(self::MICROSECOND_INTERVALS) + ); + + // Combine the seconds and microseconds intervals and add the count of + // 100-nanosecond intervals from the Gregorian calendar epoch to the + // Unix epoch. This gives us the correct count of 100-nanosecond + // intervals since the Gregorian calendar epoch for the given seconds + // and microseconds. + /** @var IntegerObject $uuidTime */ + $uuidTime = $this->calculator->add( + $sec, + $usec, + new IntegerObject(self::GREGORIAN_TO_UNIX_INTERVALS) + ); + + $uuidTimeHex = str_pad( + $this->calculator->toHexadecimal($uuidTime)->toString(), + 16, + '0', + STR_PAD_LEFT + ); + + return new Hexadecimal($uuidTimeHex); + } + + public function convertTime(Hexadecimal $uuidTimestamp): Time + { + // From the total, subtract the number of 100-nanosecond intervals from + // the Gregorian calendar epoch to the Unix epoch. This gives us the + // number of 100-nanosecond intervals from the Unix epoch, which also + // includes the microtime. + $epochNanoseconds = $this->calculator->subtract( + $this->calculator->toInteger($uuidTimestamp), + new IntegerObject(self::GREGORIAN_TO_UNIX_INTERVALS) + ); + + // Convert the 100-nanosecond intervals into seconds and microseconds. + $unixTimestamp = $this->calculator->divide( + RoundingMode::HALF_UP, + 6, + $epochNanoseconds, + new IntegerObject(self::SECOND_INTERVALS) + ); + + $split = explode('.', (string) $unixTimestamp, 2); + + return new Time($split[0], $split[1] ?? 0); + } +} diff --git a/vendor/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php b/vendor/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php index 57c882dbb..52963fed6 100644 --- a/vendor/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php +++ b/vendor/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,41 +8,176 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Converter\Time; use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Math\BrickMathCalculator; +use Ramsey\Uuid\Math\CalculatorInterface; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\Type\Time; + +use function count; +use function dechex; +use function explode; +use function is_float; +use function is_int; +use function str_pad; +use function strlen; +use function substr; + +use const STR_PAD_LEFT; +use const STR_PAD_RIGHT; /** * PhpTimeConverter uses built-in PHP functions and standard math operations * available to the PHP programming language to provide facilities for * converting parts of time into representations that may be used in UUIDs + * + * @psalm-immutable */ class PhpTimeConverter implements TimeConverterInterface { /** - * Uses the provided seconds and micro-seconds to calculate the time_low, - * time_mid, and time_high fields used by RFC 4122 version 1 UUIDs + * The number of 100-nanosecond intervals from the Gregorian calendar epoch + * to the Unix epoch. + */ + private const GREGORIAN_TO_UNIX_INTERVALS = 0x01b21dd213814000; + + /** + * The number of 100-nanosecond intervals in one second. + */ + private const SECOND_INTERVALS = 10000000; + + /** + * The number of 100-nanosecond intervals in one microsecond. + */ + private const MICROSECOND_INTERVALS = 10; + + /** + * @var CalculatorInterface + */ + private $calculator; + + /** + * @var TimeConverterInterface + */ + private $fallbackConverter; + + /** + * @var int + */ + private $phpPrecision; + + public function __construct( + ?CalculatorInterface $calculator = null, + ?TimeConverterInterface $fallbackConverter = null + ) { + if ($calculator === null) { + $calculator = new BrickMathCalculator(); + } + + if ($fallbackConverter === null) { + $fallbackConverter = new GenericTimeConverter($calculator); + } + + $this->calculator = $calculator; + $this->fallbackConverter = $fallbackConverter; + $this->phpPrecision = (int) ini_get('precision'); + } + + public function calculateTime(string $seconds, string $microseconds): Hexadecimal + { + $seconds = new IntegerObject($seconds); + $microseconds = new IntegerObject($microseconds); + + // Calculate the count of 100-nanosecond intervals since the Gregorian + // calendar epoch for the given seconds and microseconds. + $uuidTime = ((int) $seconds->toString() * self::SECOND_INTERVALS) + + ((int) $microseconds->toString() * self::MICROSECOND_INTERVALS) + + self::GREGORIAN_TO_UNIX_INTERVALS; + + // Check to see whether we've overflowed the max/min integer size. + // If so, we will default to a different time converter. + /** @psalm-suppress RedundantCondition */ + if (!is_int($uuidTime)) { + return $this->fallbackConverter->calculateTime( + $seconds->toString(), + $microseconds->toString() + ); + } + + return new Hexadecimal(str_pad(dechex((int) $uuidTime), 16, '0', STR_PAD_LEFT)); + } + + public function convertTime(Hexadecimal $uuidTimestamp): Time + { + $timestamp = $this->calculator->toInteger($uuidTimestamp); + + // Convert the 100-nanosecond intervals into seconds and microseconds. + $splitTime = $this->splitTime( + ((int) $timestamp->toString() - self::GREGORIAN_TO_UNIX_INTERVALS) + / self::SECOND_INTERVALS + ); + + if (count($splitTime) === 0) { + return $this->fallbackConverter->convertTime($uuidTimestamp); + } + + return new Time($splitTime['sec'], $splitTime['usec']); + } + + /** + * @param int|float $time The time to split into seconds and microseconds * - * @param string $seconds - * @param string $microSeconds - * @return string[] An array containing `low`, `mid`, and `high` keys - * @link http://tools.ietf.org/html/rfc4122#section-4.2.2 + * @return string[] */ - public function calculateTime($seconds, $microSeconds) + private function splitTime($time): array { - // 0x01b21dd213814000 is the number of 100-ns intervals between the - // UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00. - $uuidTime = ($seconds * 10000000) + ($microSeconds * 10) + 0x01b21dd213814000; + $split = explode('.', (string) $time, 2); + + // If the $time value is a float but $split only has 1 element, then the + // float math was rounded up to the next second, so we want to return + // an empty array to allow use of the fallback converter. + if (is_float($time) && count($split) === 1) { + return []; + } + + if (count($split) === 1) { + return [ + 'sec' => $split[0], + 'usec' => '0', + ]; + } + + // If the microseconds are less than six characters AND the length of + // the number is greater than or equal to the PHP precision, then it's + // possible that we lost some precision for the microseconds. Return an + // empty array, so that we can choose to use the fallback converter. + if (strlen($split[1]) < 6 && strlen((string) $time) >= $this->phpPrecision) { + return []; + } + + $microseconds = $split[1]; + + // Ensure the microseconds are no longer than 6 digits. If they are, + // truncate the number to the first 6 digits and round up, if needed. + if (strlen($microseconds) > 6) { + $roundingDigit = (int) substr($microseconds, 6, 1); + $microseconds = (int) substr($microseconds, 0, 6); + + if ($roundingDigit >= 5) { + $microseconds++; + } + } return [ - 'low' => sprintf('%08x', $uuidTime & 0xffffffff), - 'mid' => sprintf('%04x', ($uuidTime >> 32) & 0xffff), - 'hi' => sprintf('%04x', ($uuidTime >> 48) & 0x0fff), + 'sec' => $split[0], + 'usec' => str_pad((string) $microseconds, 6, '0', STR_PAD_RIGHT), ]; } } diff --git a/vendor/ramsey/uuid/src/Converter/TimeConverterInterface.php b/vendor/ramsey/uuid/src/Converter/TimeConverterInterface.php index 23cf1640b..1e8480701 100644 --- a/vendor/ramsey/uuid/src/Converter/TimeConverterInterface.php +++ b/vendor/ramsey/uuid/src/Converter/TimeConverterInterface.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,31 +8,51 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Converter; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Time; /** - * TimeConverterInterface provides facilities for converting parts of time into - * representations that may be used in UUIDs + * A time converter converts timestamps into representations that may be used + * in UUIDs + * + * @psalm-immutable */ interface TimeConverterInterface { /** - * Uses the provided seconds and micro-seconds to calculate the time_low, - * time_mid, and time_high fields used by RFC 4122 version 1 UUIDs + * Uses the provided seconds and micro-seconds to calculate the count of + * 100-nanosecond intervals since UTC 00:00:00.00, 15 October 1582, for + * RFC 4122 variant UUIDs + * + * @link http://tools.ietf.org/html/rfc4122#section-4.2.2 RFC 4122, § 4.2.2: Generation Details + * + * @param string $seconds A string representation of the number of seconds + * since the Unix epoch for the time to calculate + * @param string $microseconds A string representation of the micro-seconds + * associated with the time to calculate + * + * @return Hexadecimal The full UUID timestamp as a Hexadecimal value + * + * @psalm-pure + */ + public function calculateTime(string $seconds, string $microseconds): Hexadecimal; + + /** + * Converts a timestamp extracted from a UUID to a Unix timestamp + * + * @param Hexadecimal $uuidTimestamp A hexadecimal representation of a UUID + * timestamp; a UUID timestamp is a count of 100-nanosecond intervals + * since UTC 00:00:00.00, 15 October 1582. + * + * @return Time An instance of {@see Time} * - * @param string $seconds - * @param string $microSeconds - * @return string[] An array guaranteed to contain `low`, `mid`, and `hi` keys - * @throws UnsatisfiedDependencyException if called on a 32-bit system and - * `Moontoast\Math\BigNumber` is not present - * @link http://tools.ietf.org/html/rfc4122#section-4.2.2 + * @psalm-pure */ - public function calculateTime($seconds, $microSeconds); + public function convertTime(Hexadecimal $uuidTimestamp): Time; } diff --git a/vendor/ramsey/uuid/src/DegradedUuid.php b/vendor/ramsey/uuid/src/DegradedUuid.php index 4e11272d0..9166042cc 100644 --- a/vendor/ramsey/uuid/src/DegradedUuid.php +++ b/vendor/ramsey/uuid/src/DegradedUuid.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,110 +8,18 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ -namespace Ramsey\Uuid; +declare(strict_types=1); -use DateTime; -use Moontoast\Math\BigNumber; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; -use Ramsey\Uuid\Exception\UnsupportedOperationException; +namespace Ramsey\Uuid; /** - * DegradedUuid represents an RFC 4122 UUID on 32-bit systems + * @deprecated DegradedUuid is no longer necessary to represent UUIDs on 32-bit + * systems. Transition typehints to {@see UuidInterface}. * - * @see Uuid + * @psalm-immutable */ class DegradedUuid extends Uuid { - /** - * @inheritdoc - */ - public function getDateTime() - { - if ($this->getVersion() != 1) { - throw new UnsupportedOperationException('Not a time-based UUID'); - } - - $time = $this->converter->fromHex($this->getTimestampHex()); - - $ts = new BigNumber($time, 20); - $ts->subtract('122192928000000000'); - $ts->divide('10000000.0'); - $ts->floor(); - $unixTime = $ts->getValue(); - - return new DateTime("@{$unixTime}"); - } - - /** - * For degraded UUIDs, throws an `UnsatisfiedDependencyException` when - * called on a 32-bit system - * - * @throws UnsatisfiedDependencyException if called on a 32-bit system - */ - public function getFields() - { - throw new UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since some ' - . 'values overflow the system max integer value' - . '; consider calling getFieldsHex instead' - ); - } - - /** - * For degraded UUIDs, throws an `UnsatisfiedDependencyException` when - * called on a 32-bit system - * - * @throws UnsatisfiedDependencyException if called on a 32-bit system - */ - public function getNode() - { - throw new UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since node ' - . 'is an unsigned 48-bit integer and can overflow the system ' - . 'max integer value' - . '; consider calling getNodeHex instead' - ); - } - - /** - * For degraded UUIDs, throws an `UnsatisfiedDependencyException` when - * called on a 32-bit system - * - * @throws UnsatisfiedDependencyException if called on a 32-bit system - */ - public function getTimeLow() - { - throw new UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since time_low ' - . 'is an unsigned 32-bit integer and can overflow the system ' - . 'max integer value' - . '; consider calling getTimeLowHex instead' - ); - } - - /** - * For degraded UUIDs, throws an `UnsatisfiedDependencyException` when - * called on a 32-bit system - * - * @throws UnsatisfiedDependencyException if called on a 32-bit system - * @throws UnsupportedOperationException If this UUID is not a version 1 UUID - */ - public function getTimestamp() - { - if ($this->getVersion() != 1) { - throw new UnsupportedOperationException('Not a time-based UUID'); - } - - throw new UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since timestamp ' - . 'is an unsigned 60-bit integer and can overflow the system ' - . 'max integer value' - . '; consider calling getTimestampHex instead' - ); - } } diff --git a/vendor/ramsey/uuid/src/DeprecatedUuidInterface.php b/vendor/ramsey/uuid/src/DeprecatedUuidInterface.php new file mode 100644 index 000000000..ed6d9dec8 --- /dev/null +++ b/vendor/ramsey/uuid/src/DeprecatedUuidInterface.php @@ -0,0 +1,147 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid; + +use DateTimeInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; + +/** + * This interface encapsulates deprecated methods for ramsey/uuid; this + * interface and its methods will be removed in ramsey/uuid 5.0.0. + * + * @psalm-immutable + */ +interface DeprecatedUuidInterface +{ + /** + * @deprecated This method will be removed in 5.0.0. There is no alternative + * recommendation, so plan accordingly. + */ + public function getNumberConverter(): NumberConverterInterface; + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. + * + * @return string[] + */ + public function getFieldsHex(): array; + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqHiAndReserved()}. + */ + public function getClockSeqHiAndReservedHex(): string; + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqLow()}. + */ + public function getClockSeqLowHex(): string; + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeq()}. + */ + public function getClockSequenceHex(): string; + + /** + * @deprecated In ramsey/uuid version 5.0.0, this will be removed from the + * interface. It is available at {@see UuidV1::getDateTime()}. + */ + public function getDateTime(): DateTimeInterface; + + /** + * @deprecated This method will be removed in 5.0.0. There is no direct + * alternative, but the same information may be obtained by splitting + * in half the value returned by {@see UuidInterface::getHex()}. + */ + public function getLeastSignificantBitsHex(): string; + + /** + * @deprecated This method will be removed in 5.0.0. There is no direct + * alternative, but the same information may be obtained by splitting + * in half the value returned by {@see UuidInterface::getHex()}. + */ + public function getMostSignificantBitsHex(): string; + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getNode()}. + */ + public function getNodeHex(): string; + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeHiAndVersion()}. + */ + public function getTimeHiAndVersionHex(): string; + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeLow()}. + */ + public function getTimeLowHex(): string; + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeMid()}. + */ + public function getTimeMidHex(): string; + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimestamp()}. + */ + public function getTimestampHex(): string; + + /** + * @deprecated In ramsey/uuid version 5.0.0, this will be removed from this + * interface. It has moved to {@see \Ramsey\Uuid\Rfc4122\UuidInterface::getUrn()}. + */ + public function getUrn(): string; + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getVariant()}. + */ + public function getVariant(): ?int; + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getVersion()}. + */ + public function getVersion(): ?int; +} diff --git a/vendor/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php b/vendor/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php new file mode 100644 index 000000000..342829523 --- /dev/null +++ b/vendor/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php @@ -0,0 +1,370 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid; + +use DateTimeImmutable; +use DateTimeInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\DateTimeException; +use Ramsey\Uuid\Exception\UnsupportedOperationException; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Throwable; + +use function str_pad; +use function substr; + +use const STR_PAD_LEFT; + +/** + * This trait encapsulates deprecated methods for ramsey/uuid; this trait and + * its methods will be removed in ramsey/uuid 5.0.0. + * + * @psalm-immutable + */ +trait DeprecatedUuidMethodsTrait +{ + /** + * @var Rfc4122FieldsInterface + */ + protected $fields; + + /** + * @var NumberConverterInterface + */ + protected $numberConverter; + + /** + * @var TimeConverterInterface + */ + protected $timeConverter; + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqHiAndReserved()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getClockSeqHiAndReserved(): string + { + return $this->numberConverter->fromHex($this->fields->getClockSeqHiAndReserved()->toString()); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqHiAndReserved()}. + */ + public function getClockSeqHiAndReservedHex(): string + { + return $this->fields->getClockSeqHiAndReserved()->toString(); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqLow()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getClockSeqLow(): string + { + return $this->numberConverter->fromHex($this->fields->getClockSeqLow()->toString()); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqLow()}. + */ + public function getClockSeqLowHex(): string + { + return $this->fields->getClockSeqLow()->toString(); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getClockSeq()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getClockSequence(): string + { + return $this->numberConverter->fromHex($this->fields->getClockSeq()->toString()); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getClockSeq()}. + */ + public function getClockSequenceHex(): string + { + return $this->fields->getClockSeq()->toString(); + } + + /** + * @deprecated This method will be removed in 5.0.0. There is no alternative + * recommendation, so plan accordingly. + */ + public function getNumberConverter(): NumberConverterInterface + { + return $this->numberConverter; + } + + /** + * @deprecated In ramsey/uuid version 5.0.0, this will be removed. + * It is available at {@see UuidV1::getDateTime()}. + * + * @return DateTimeImmutable An immutable instance of DateTimeInterface + * + * @throws UnsupportedOperationException if UUID is not time-based + * @throws DateTimeException if DateTime throws an exception/error + */ + public function getDateTime(): DateTimeInterface + { + if ($this->fields->getVersion() !== 1) { + throw new UnsupportedOperationException('Not a time-based UUID'); + } + + $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); + + try { + return new DateTimeImmutable( + '@' + . $time->getSeconds()->toString() + . '.' + . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) + ); + } catch (Throwable $e) { + throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); + } + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. + * + * @return string[] + */ + public function getFieldsHex(): array + { + return [ + 'time_low' => $this->fields->getTimeLow()->toString(), + 'time_mid' => $this->fields->getTimeMid()->toString(), + 'time_hi_and_version' => $this->fields->getTimeHiAndVersion()->toString(), + 'clock_seq_hi_and_reserved' => $this->fields->getClockSeqHiAndReserved()->toString(), + 'clock_seq_low' => $this->fields->getClockSeqLow()->toString(), + 'node' => $this->fields->getNode()->toString(), + ]; + } + + /** + * @deprecated This method will be removed in 5.0.0. There is no direct + * alternative, but the same information may be obtained by splitting + * in half the value returned by {@see UuidInterface::getHex()}. + */ + public function getLeastSignificantBits(): string + { + $leastSignificantHex = substr($this->getHex()->toString(), 16); + + return $this->numberConverter->fromHex($leastSignificantHex); + } + + /** + * @deprecated This method will be removed in 5.0.0. There is no direct + * alternative, but the same information may be obtained by splitting + * in half the value returned by {@see UuidInterface::getHex()}. + */ + public function getLeastSignificantBitsHex(): string + { + return substr($this->getHex()->toString(), 16); + } + + /** + * @deprecated This method will be removed in 5.0.0. There is no direct + * alternative, but the same information may be obtained by splitting + * in half the value returned by {@see UuidInterface::getHex()}. + */ + public function getMostSignificantBits(): string + { + $mostSignificantHex = substr($this->getHex()->toString(), 0, 16); + + return $this->numberConverter->fromHex($mostSignificantHex); + } + + /** + * @deprecated This method will be removed in 5.0.0. There is no direct + * alternative, but the same information may be obtained by splitting + * in half the value returned by {@see UuidInterface::getHex()}. + */ + public function getMostSignificantBitsHex(): string + { + return substr($this->getHex()->toString(), 0, 16); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getNode()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getNode(): string + { + return $this->numberConverter->fromHex($this->fields->getNode()->toString()); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getNode()}. + */ + public function getNodeHex(): string + { + return $this->fields->getNode()->toString(); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimeHiAndVersion()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getTimeHiAndVersion(): string + { + return $this->numberConverter->fromHex($this->fields->getTimeHiAndVersion()->toString()); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimeHiAndVersion()}. + */ + public function getTimeHiAndVersionHex(): string + { + return $this->fields->getTimeHiAndVersion()->toString(); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimeLow()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getTimeLow(): string + { + return $this->numberConverter->fromHex($this->fields->getTimeLow()->toString()); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimeLow()}. + */ + public function getTimeLowHex(): string + { + return $this->fields->getTimeLow()->toString(); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimeMid()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getTimeMid(): string + { + return $this->numberConverter->fromHex($this->fields->getTimeMid()->toString()); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimeMid()}. + */ + public function getTimeMidHex(): string + { + return $this->fields->getTimeMid()->toString(); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimestamp()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getTimestamp(): string + { + if ($this->fields->getVersion() !== 1) { + throw new UnsupportedOperationException('Not a time-based UUID'); + } + + return $this->numberConverter->fromHex($this->fields->getTimestamp()->toString()); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimestamp()}. + */ + public function getTimestampHex(): string + { + if ($this->fields->getVersion() !== 1) { + throw new UnsupportedOperationException('Not a time-based UUID'); + } + + return $this->fields->getTimestamp()->toString(); + } + + /** + * @deprecated This has moved to {@see Rfc4122FieldsInterface::getUrn()} and + * is available on {@see \Ramsey\Uuid\Rfc4122\UuidV1}, + * {@see \Ramsey\Uuid\Rfc4122\UuidV3}, {@see \Ramsey\Uuid\Rfc4122\UuidV4}, + * and {@see \Ramsey\Uuid\Rfc4122\UuidV5}. + */ + public function getUrn(): string + { + return 'urn:uuid:' . $this->toString(); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getVariant()}. + */ + public function getVariant(): ?int + { + return $this->fields->getVariant(); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call + * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getVersion()}. + */ + public function getVersion(): ?int + { + return $this->fields->getVersion(); + } +} diff --git a/vendor/ramsey/uuid/src/Exception/BuilderNotFoundException.php b/vendor/ramsey/uuid/src/Exception/BuilderNotFoundException.php new file mode 100644 index 000000000..c0854d256 --- /dev/null +++ b/vendor/ramsey/uuid/src/Exception/BuilderNotFoundException.php @@ -0,0 +1,24 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Exception; + +use RuntimeException as PhpRuntimeException; + +/** + * Thrown to indicate that no suitable builder could be found + */ +class BuilderNotFoundException extends PhpRuntimeException +{ +} diff --git a/vendor/ramsey/uuid/src/Exception/DateTimeException.php b/vendor/ramsey/uuid/src/Exception/DateTimeException.php new file mode 100644 index 000000000..dbc484045 --- /dev/null +++ b/vendor/ramsey/uuid/src/Exception/DateTimeException.php @@ -0,0 +1,24 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Exception; + +use RuntimeException as PhpRuntimeException; + +/** + * Thrown to indicate that the PHP DateTime extension encountered an exception/error + */ +class DateTimeException extends PhpRuntimeException +{ +} diff --git a/vendor/ramsey/uuid/src/Exception/DceSecurityException.php b/vendor/ramsey/uuid/src/Exception/DceSecurityException.php new file mode 100644 index 000000000..a65f80cd4 --- /dev/null +++ b/vendor/ramsey/uuid/src/Exception/DceSecurityException.php @@ -0,0 +1,25 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Exception; + +use RuntimeException as PhpRuntimeException; + +/** + * Thrown to indicate an exception occurred while dealing with DCE Security + * (version 2) UUIDs + */ +class DceSecurityException extends PhpRuntimeException +{ +} diff --git a/vendor/ramsey/uuid/src/Exception/InvalidArgumentException.php b/vendor/ramsey/uuid/src/Exception/InvalidArgumentException.php new file mode 100644 index 000000000..08bbb8029 --- /dev/null +++ b/vendor/ramsey/uuid/src/Exception/InvalidArgumentException.php @@ -0,0 +1,24 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Exception; + +use InvalidArgumentException as PhpInvalidArgumentException; + +/** + * Thrown to indicate that the argument received is not valid + */ +class InvalidArgumentException extends PhpInvalidArgumentException +{ +} diff --git a/vendor/ramsey/uuid/src/Exception/InvalidBytesException.php b/vendor/ramsey/uuid/src/Exception/InvalidBytesException.php new file mode 100644 index 000000000..b20be3de0 --- /dev/null +++ b/vendor/ramsey/uuid/src/Exception/InvalidBytesException.php @@ -0,0 +1,24 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Exception; + +use RuntimeException as PhpRuntimeException; + +/** + * Thrown to indicate that the bytes being operated on are invalid in some way + */ +class InvalidBytesException extends PhpRuntimeException +{ +} diff --git a/vendor/ramsey/uuid/src/Exception/InvalidUuidStringException.php b/vendor/ramsey/uuid/src/Exception/InvalidUuidStringException.php index 7df0e8cce..24f42c643 100644 --- a/vendor/ramsey/uuid/src/Exception/InvalidUuidStringException.php +++ b/vendor/ramsey/uuid/src/Exception/InvalidUuidStringException.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,17 +8,17 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ -namespace Ramsey\Uuid\Exception; +declare(strict_types=1); -use InvalidArgumentException; +namespace Ramsey\Uuid\Exception; /** - * Thrown to indicate that the parsed UUID string is invalid. + * Thrown to indicate that the string received is not a valid UUID + * + * The InvalidArgumentException that this extends is the ramsey/uuid version + * of this exception. It exists in the same namespace as this class. */ class InvalidUuidStringException extends InvalidArgumentException { diff --git a/vendor/ramsey/uuid/src/Exception/NameException.php b/vendor/ramsey/uuid/src/Exception/NameException.php new file mode 100644 index 000000000..54d32ec38 --- /dev/null +++ b/vendor/ramsey/uuid/src/Exception/NameException.php @@ -0,0 +1,25 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Exception; + +use RuntimeException as PhpRuntimeException; + +/** + * Thrown to indicate that an error occurred while attempting to hash a + * namespace and name + */ +class NameException extends PhpRuntimeException +{ +} diff --git a/vendor/ramsey/uuid/src/Exception/NodeException.php b/vendor/ramsey/uuid/src/Exception/NodeException.php new file mode 100644 index 000000000..21b6d1804 --- /dev/null +++ b/vendor/ramsey/uuid/src/Exception/NodeException.php @@ -0,0 +1,24 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Exception; + +use RuntimeException as PhpRuntimeException; + +/** + * Thrown to indicate that attempting to fetch or create a node ID encountered an error + */ +class NodeException extends PhpRuntimeException +{ +} diff --git a/vendor/ramsey/uuid/src/Exception/RandomSourceException.php b/vendor/ramsey/uuid/src/Exception/RandomSourceException.php new file mode 100644 index 000000000..0c3e4f523 --- /dev/null +++ b/vendor/ramsey/uuid/src/Exception/RandomSourceException.php @@ -0,0 +1,27 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Exception; + +use RuntimeException as PhpRuntimeException; + +/** + * Thrown to indicate that the source of random data encountered an error + * + * This exception is used mostly to indicate that random_bytes() or random_int() + * threw an exception. However, it may be used for other sources of random data. + */ +class RandomSourceException extends PhpRuntimeException +{ +} diff --git a/vendor/ramsey/uuid/src/Exception/TimeSourceException.php b/vendor/ramsey/uuid/src/Exception/TimeSourceException.php new file mode 100644 index 000000000..accd37f87 --- /dev/null +++ b/vendor/ramsey/uuid/src/Exception/TimeSourceException.php @@ -0,0 +1,24 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Exception; + +use RuntimeException as PhpRuntimeException; + +/** + * Thrown to indicate that the source of time encountered an error + */ +class TimeSourceException extends PhpRuntimeException +{ +} diff --git a/vendor/ramsey/uuid/src/Exception/UnableToBuildUuidException.php b/vendor/ramsey/uuid/src/Exception/UnableToBuildUuidException.php new file mode 100644 index 000000000..da9649035 --- /dev/null +++ b/vendor/ramsey/uuid/src/Exception/UnableToBuildUuidException.php @@ -0,0 +1,24 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Exception; + +use RuntimeException as PhpRuntimeException; + +/** + * Thrown to indicate a builder is unable to build a UUID + */ +class UnableToBuildUuidException extends PhpRuntimeException +{ +} diff --git a/vendor/ramsey/uuid/src/Exception/UnsatisfiedDependencyException.php b/vendor/ramsey/uuid/src/Exception/UnsatisfiedDependencyException.php deleted file mode 100644 index 89c739658..000000000 --- a/vendor/ramsey/uuid/src/Exception/UnsatisfiedDependencyException.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/** - * This file is part of the ramsey/uuid library - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> - * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub - */ - -namespace Ramsey\Uuid\Exception; - -use RuntimeException; - -/** - * Thrown to indicate that the requested operation has dependencies that have not - * been satisfied. - */ -class UnsatisfiedDependencyException extends RuntimeException -{ -} diff --git a/vendor/ramsey/uuid/src/Exception/UnsupportedOperationException.php b/vendor/ramsey/uuid/src/Exception/UnsupportedOperationException.php index 43409470d..e6391b03d 100644 --- a/vendor/ramsey/uuid/src/Exception/UnsupportedOperationException.php +++ b/vendor/ramsey/uuid/src/Exception/UnsupportedOperationException.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,18 +8,17 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Exception; -use RuntimeException; +use LogicException as PhpLogicException; /** - * Thrown to indicate that the requested operation is not supported. + * Thrown to indicate that the requested operation is not supported */ -class UnsupportedOperationException extends RuntimeException +class UnsupportedOperationException extends PhpLogicException { } diff --git a/vendor/ramsey/uuid/src/FeatureSet.php b/vendor/ramsey/uuid/src/FeatureSet.php index 2027b9e02..4531a6d7f 100644 --- a/vendor/ramsey/uuid/src/FeatureSet.php +++ b/vendor/ramsey/uuid/src/FeatureSet.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,41 +8,58 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid; -use Ramsey\Uuid\Converter\TimeConverterInterface; -use Ramsey\Uuid\Generator\PeclUuidTimeGenerator; -use Ramsey\Uuid\Provider\Node\FallbackNodeProvider; -use Ramsey\Uuid\Provider\Node\RandomNodeProvider; -use Ramsey\Uuid\Provider\Node\SystemNodeProvider; -use Ramsey\Uuid\Converter\NumberConverterInterface; -use Ramsey\Uuid\Converter\Number\BigNumberConverter; -use Ramsey\Uuid\Converter\Number\DegradedNumberConverter; -use Ramsey\Uuid\Converter\Time\BigNumberTimeConverter; -use Ramsey\Uuid\Converter\Time\DegradedTimeConverter; -use Ramsey\Uuid\Converter\Time\PhpTimeConverter; -use Ramsey\Uuid\Provider\Time\SystemTimeProvider; +use Ramsey\Uuid\Builder\BuilderCollection; +use Ramsey\Uuid\Builder\FallbackBuilder; use Ramsey\Uuid\Builder\UuidBuilderInterface; -use Ramsey\Uuid\Builder\DefaultUuidBuilder; use Ramsey\Uuid\Codec\CodecInterface; -use Ramsey\Uuid\Codec\StringCodec; use Ramsey\Uuid\Codec\GuidStringCodec; -use Ramsey\Uuid\Builder\DegradedUuidBuilder; +use Ramsey\Uuid\Codec\StringCodec; +use Ramsey\Uuid\Converter\Number\GenericNumberConverter; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\Time\GenericTimeConverter; +use Ramsey\Uuid\Converter\Time\PhpTimeConverter; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Generator\DceSecurityGenerator; +use Ramsey\Uuid\Generator\DceSecurityGeneratorInterface; +use Ramsey\Uuid\Generator\NameGeneratorFactory; +use Ramsey\Uuid\Generator\NameGeneratorInterface; +use Ramsey\Uuid\Generator\PeclUuidNameGenerator; +use Ramsey\Uuid\Generator\PeclUuidRandomGenerator; +use Ramsey\Uuid\Generator\PeclUuidTimeGenerator; use Ramsey\Uuid\Generator\RandomGeneratorFactory; use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Generator\TimeGeneratorFactory; use Ramsey\Uuid\Generator\TimeGeneratorInterface; -use Ramsey\Uuid\Provider\TimeProviderInterface; +use Ramsey\Uuid\Guid\GuidBuilder; +use Ramsey\Uuid\Math\BrickMathCalculator; +use Ramsey\Uuid\Math\CalculatorInterface; +use Ramsey\Uuid\Nonstandard\UuidBuilder as NonstandardUuidBuilder; +use Ramsey\Uuid\Provider\Dce\SystemDceSecurityProvider; +use Ramsey\Uuid\Provider\DceSecurityProviderInterface; +use Ramsey\Uuid\Provider\Node\FallbackNodeProvider; +use Ramsey\Uuid\Provider\Node\NodeProviderCollection; +use Ramsey\Uuid\Provider\Node\RandomNodeProvider; +use Ramsey\Uuid\Provider\Node\SystemNodeProvider; use Ramsey\Uuid\Provider\NodeProviderInterface; +use Ramsey\Uuid\Provider\Time\SystemTimeProvider; +use Ramsey\Uuid\Provider\TimeProviderInterface; +use Ramsey\Uuid\Rfc4122\UuidBuilder as Rfc4122UuidBuilder; +use Ramsey\Uuid\Validator\GenericValidator; +use Ramsey\Uuid\Validator\ValidatorInterface; + +use const PHP_INT_SIZE; /** * FeatureSet detects and exposes available features in the current environment - * (32- or 64-bit, available dependencies, etc.) + * + * A feature set is used by UuidFactory to determine the available features and + * capabilities of the environment. */ class FeatureSet { @@ -76,6 +94,16 @@ class FeatureSet private $codec; /** + * @var DceSecurityGeneratorInterface + */ + private $dceSecurityGenerator; + + /** + * @var NameGeneratorInterface + */ + private $nameGenerator; + + /** * @var NodeProviderInterface */ private $nodeProvider; @@ -86,6 +114,11 @@ class FeatureSet private $numberConverter; /** + * @var TimeConverterInterface + */ + private $timeConverter; + + /** * @var RandomGeneratorInterface */ private $randomGenerator; @@ -96,117 +129,196 @@ class FeatureSet private $timeGenerator; /** - * Constructs a `FeatureSet` for use by a `UuidFactory` to determine or set - * features available to the environment - * - * @param bool $useGuids Whether to build UUIDs using the `GuidStringCodec` - * @param bool $force32Bit Whether to force the use of 32-bit functionality + * @var TimeProviderInterface + */ + private $timeProvider; + + /** + * @var ValidatorInterface + */ + private $validator; + + /** + * @var CalculatorInterface + */ + private $calculator; + + /** + * @param bool $useGuids True build UUIDs using the GuidStringCodec + * @param bool $force32Bit True to force the use of 32-bit functionality * (primarily for testing purposes) - * @param bool $forceNoBigNumber Whether to disable the use of moontoast/math - * `BigNumber` (primarily for testing purposes) - * @param bool $ignoreSystemNode Whether to disable attempts to check for - * the system host ID (primarily for testing purposes) - * @param bool $enablePecl Whether to enable the use of the `PeclUuidTimeGenerator` + * @param bool $forceNoBigNumber True to disable the use of moontoast/math + * (primarily for testing purposes) + * @param bool $ignoreSystemNode True to disable attempts to check for the + * system node ID (primarily for testing purposes) + * @param bool $enablePecl True to enable the use of the PeclUuidTimeGenerator * to generate version 1 UUIDs */ public function __construct( - $useGuids = false, - $force32Bit = false, - $forceNoBigNumber = false, - $ignoreSystemNode = false, - $enablePecl = false + bool $useGuids = false, + bool $force32Bit = false, + bool $forceNoBigNumber = false, + bool $ignoreSystemNode = false, + bool $enablePecl = false ) { $this->disableBigNumber = $forceNoBigNumber; $this->disable64Bit = $force32Bit; $this->ignoreSystemNode = $ignoreSystemNode; $this->enablePecl = $enablePecl; - $this->numberConverter = $this->buildNumberConverter(); - $this->builder = $this->buildUuidBuilder(); + $this->setCalculator(new BrickMathCalculator()); + $this->builder = $this->buildUuidBuilder($useGuids); $this->codec = $this->buildCodec($useGuids); $this->nodeProvider = $this->buildNodeProvider(); + $this->nameGenerator = $this->buildNameGenerator(); $this->randomGenerator = $this->buildRandomGenerator(); $this->setTimeProvider(new SystemTimeProvider()); + $this->setDceSecurityProvider(new SystemDceSecurityProvider()); + $this->validator = new GenericValidator(); } /** * Returns the builder configured for this environment - * - * @return UuidBuilderInterface */ - public function getBuilder() + public function getBuilder(): UuidBuilderInterface { return $this->builder; } /** - * Returns the UUID UUID coder-decoder configured for this environment - * - * @return CodecInterface + * Returns the calculator configured for this environment */ - public function getCodec() + public function getCalculator(): CalculatorInterface + { + return $this->calculator; + } + + /** + * Returns the codec configured for this environment + */ + public function getCodec(): CodecInterface { return $this->codec; } /** - * Returns the system node ID provider configured for this environment - * - * @return NodeProviderInterface + * Returns the DCE Security generator configured for this environment */ - public function getNodeProvider() + public function getDceSecurityGenerator(): DceSecurityGeneratorInterface + { + return $this->dceSecurityGenerator; + } + + /** + * Returns the name generator configured for this environment + */ + public function getNameGenerator(): NameGeneratorInterface + { + return $this->nameGenerator; + } + + /** + * Returns the node provider configured for this environment + */ + public function getNodeProvider(): NodeProviderInterface { return $this->nodeProvider; } /** * Returns the number converter configured for this environment - * - * @return NumberConverterInterface */ - public function getNumberConverter() + public function getNumberConverter(): NumberConverterInterface { return $this->numberConverter; } /** - * Returns the random UUID generator configured for this environment - * - * @return RandomGeneratorInterface + * Returns the random generator configured for this environment */ - public function getRandomGenerator() + public function getRandomGenerator(): RandomGeneratorInterface { return $this->randomGenerator; } /** - * Returns the time-based UUID generator configured for this environment - * - * @return TimeGeneratorInterface + * Returns the time converter configured for this environment */ - public function getTimeGenerator() + public function getTimeConverter(): TimeConverterInterface + { + return $this->timeConverter; + } + + /** + * Returns the time generator configured for this environment + */ + public function getTimeGenerator(): TimeGeneratorInterface { return $this->timeGenerator; } /** - * Sets the time provider for use in this environment - * - * @param TimeProviderInterface $timeProvider + * Returns the validator configured for this environment + */ + public function getValidator(): ValidatorInterface + { + return $this->validator; + } + + /** + * Sets the calculator to use in this environment + */ + public function setCalculator(CalculatorInterface $calculator): void + { + $this->calculator = $calculator; + $this->numberConverter = $this->buildNumberConverter($calculator); + $this->timeConverter = $this->buildTimeConverter($calculator); + + if (isset($this->timeProvider)) { + $this->timeGenerator = $this->buildTimeGenerator($this->timeProvider); + } + } + + /** + * Sets the DCE Security provider to use in this environment + */ + public function setDceSecurityProvider(DceSecurityProviderInterface $dceSecurityProvider): void + { + $this->dceSecurityGenerator = $this->buildDceSecurityGenerator($dceSecurityProvider); + } + + /** + * Sets the node provider to use in this environment + */ + public function setNodeProvider(NodeProviderInterface $nodeProvider): void + { + $this->nodeProvider = $nodeProvider; + $this->timeGenerator = $this->buildTimeGenerator($this->timeProvider); + } + + /** + * Sets the time provider to use in this environment */ - public function setTimeProvider(TimeProviderInterface $timeProvider) + public function setTimeProvider(TimeProviderInterface $timeProvider): void { + $this->timeProvider = $timeProvider; $this->timeGenerator = $this->buildTimeGenerator($timeProvider); } /** - * Determines which UUID coder-decoder to use and returns the configured - * codec for this environment + * Set the validator to use in this environment + */ + public function setValidator(ValidatorInterface $validator): void + { + $this->validator = $validator; + } + + /** + * Returns a codec configured for this environment * - * @param bool $useGuids Whether to build UUIDs using the `GuidStringCodec` - * @return CodecInterface + * @param bool $useGuids Whether to build UUIDs using the GuidStringCodec */ - protected function buildCodec($useGuids = false) + private function buildCodec(bool $useGuids = false): CodecInterface { if ($useGuids) { return new GuidStringCodec($this->builder); @@ -216,57 +328,60 @@ class FeatureSet } /** - * Determines which system node ID provider to use and returns the configured - * system node ID provider for this environment - * - * @return NodeProviderInterface + * Returns a DCE Security generator configured for this environment */ - protected function buildNodeProvider() + private function buildDceSecurityGenerator( + DceSecurityProviderInterface $dceSecurityProvider + ): DceSecurityGeneratorInterface { + return new DceSecurityGenerator( + $this->numberConverter, + $this->timeGenerator, + $dceSecurityProvider + ); + } + + /** + * Returns a node provider configured for this environment + */ + private function buildNodeProvider(): NodeProviderInterface { if ($this->ignoreSystemNode) { return new RandomNodeProvider(); } - return new FallbackNodeProvider([ + return new FallbackNodeProvider(new NodeProviderCollection([ new SystemNodeProvider(), - new RandomNodeProvider() - ]); + new RandomNodeProvider(), + ])); } /** - * Determines which number converter to use and returns the configured - * number converter for this environment - * - * @return NumberConverterInterface + * Returns a number converter configured for this environment */ - protected function buildNumberConverter() + private function buildNumberConverter(CalculatorInterface $calculator): NumberConverterInterface { - if ($this->hasBigNumber()) { - return new BigNumberConverter(); - } - - return new DegradedNumberConverter(); + return new GenericNumberConverter($calculator); } /** - * Determines which random UUID generator to use and returns the configured - * random UUID generator for this environment - * - * @return RandomGeneratorInterface + * Returns a random generator configured for this environment */ - protected function buildRandomGenerator() + private function buildRandomGenerator(): RandomGeneratorInterface { + if ($this->enablePecl) { + return new PeclUuidRandomGenerator(); + } + return (new RandomGeneratorFactory())->getGenerator(); } /** - * Determines which time-based UUID generator to use and returns the configured - * time-based UUID generator for this environment + * Returns a time generator configured for this environment * - * @param TimeProviderInterface $timeProvider - * @return TimeGeneratorInterface + * @param TimeProviderInterface $timeProvider The time provider to use with + * the time generator */ - protected function buildTimeGenerator(TimeProviderInterface $timeProvider) + private function buildTimeGenerator(TimeProviderInterface $timeProvider): TimeGeneratorInterface { if ($this->enablePecl) { return new PeclUuidTimeGenerator(); @@ -274,62 +389,60 @@ class FeatureSet return (new TimeGeneratorFactory( $this->nodeProvider, - $this->buildTimeConverter(), + $this->timeConverter, $timeProvider ))->getGenerator(); } /** - * Determines which time converter to use and returns the configured - * time converter for this environment - * - * @return TimeConverterInterface + * Returns a name generator configured for this environment */ - protected function buildTimeConverter() + private function buildNameGenerator(): NameGeneratorInterface { - if ($this->is64BitSystem()) { - return new PhpTimeConverter(); - } - - if ($this->hasBigNumber()) { - return new BigNumberTimeConverter(); + if ($this->enablePecl) { + return new PeclUuidNameGenerator(); } - return new DegradedTimeConverter(); + return (new NameGeneratorFactory())->getGenerator(); } /** - * Determines which UUID builder to use and returns the configured UUID - * builder for this environment - * - * @return UuidBuilderInterface + * Returns a time converter configured for this environment */ - protected function buildUuidBuilder() + private function buildTimeConverter(CalculatorInterface $calculator): TimeConverterInterface { + $genericConverter = new GenericTimeConverter($calculator); + if ($this->is64BitSystem()) { - return new DefaultUuidBuilder($this->numberConverter); + return new PhpTimeConverter($calculator, $genericConverter); } - return new DegradedUuidBuilder($this->numberConverter); + return $genericConverter; } /** - * Returns true if the system has `Moontoast\Math\BigNumber` + * Returns a UUID builder configured for this environment * - * @return bool + * @param bool $useGuids Whether to build UUIDs using the GuidStringCodec */ - protected function hasBigNumber() + private function buildUuidBuilder(bool $useGuids = false): UuidBuilderInterface { - return class_exists('Moontoast\Math\BigNumber') && !$this->disableBigNumber; + if ($useGuids) { + return new GuidBuilder($this->numberConverter, $this->timeConverter); + } + + /** @psalm-suppress ImpureArgument */ + return new FallbackBuilder(new BuilderCollection([ + new Rfc4122UuidBuilder($this->numberConverter, $this->timeConverter), + new NonstandardUuidBuilder($this->numberConverter, $this->timeConverter), + ])); } /** - * Returns true if the system is 64-bit, false otherwise - * - * @return bool + * Returns true if the PHP build is 64-bit */ - protected function is64BitSystem() + private function is64BitSystem(): bool { - return PHP_INT_SIZE == 8 && !$this->disable64Bit; + return PHP_INT_SIZE === 8 && !$this->disable64Bit; } } diff --git a/vendor/ramsey/uuid/src/Fields/FieldsInterface.php b/vendor/ramsey/uuid/src/Fields/FieldsInterface.php new file mode 100644 index 000000000..f1b7a290d --- /dev/null +++ b/vendor/ramsey/uuid/src/Fields/FieldsInterface.php @@ -0,0 +1,32 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Fields; + +use Serializable; + +/** + * UUIDs are comprised of unsigned integers, the bytes of which are separated + * into fields and arranged in a particular layout defined by the specification + * for the variant + * + * @psalm-immutable + */ +interface FieldsInterface extends Serializable +{ + /** + * Returns the bytes that comprise the fields + */ + public function getBytes(): string; +} diff --git a/vendor/ramsey/uuid/src/Fields/SerializableFieldsTrait.php b/vendor/ramsey/uuid/src/Fields/SerializableFieldsTrait.php new file mode 100644 index 000000000..4ae90be2c --- /dev/null +++ b/vendor/ramsey/uuid/src/Fields/SerializableFieldsTrait.php @@ -0,0 +1,60 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Fields; + +use function base64_decode; +use function strlen; + +/** + * Provides common serialization functionality to fields + * + * @psalm-immutable + */ +trait SerializableFieldsTrait +{ + /** + * @param string $bytes The bytes that comprise the fields + */ + abstract public function __construct(string $bytes); + + /** + * Returns the bytes that comprise the fields + */ + abstract public function getBytes(): string; + + /** + * Returns a string representation of object + */ + public function serialize(): string + { + return $this->getBytes(); + } + + /** + * Constructs the object from a serialized string representation + * + * @param string $serialized The serialized string representation of the object + * + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + */ + public function unserialize($serialized): void + { + if (strlen($serialized) === 16) { + $this->__construct($serialized); + } else { + $this->__construct(base64_decode($serialized)); + } + } +} diff --git a/vendor/ramsey/uuid/src/Generator/CombGenerator.php b/vendor/ramsey/uuid/src/Generator/CombGenerator.php index 1d4a5f604..88ae6ea23 100644 --- a/vendor/ramsey/uuid/src/Generator/CombGenerator.php +++ b/vendor/ramsey/uuid/src/Generator/CombGenerator.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,27 +8,58 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Generator; -use Exception; -use InvalidArgumentException; use Ramsey\Uuid\Converter\NumberConverterInterface; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; +use Ramsey\Uuid\Exception\InvalidArgumentException; + +use function bin2hex; +use function explode; +use function hex2bin; +use function microtime; +use function str_pad; +use function substr; + +use const STR_PAD_LEFT; /** - * CombGenerator provides functionality to generate COMB (combined GUID/timestamp) - * sequential UUIDs + * CombGenerator generates COMBs (combined UUID/timestamp) + * + * The CombGenerator, when used with the StringCodec (and, by proxy, the + * TimestampLastCombCodec) or the TimestampFirstCombCodec, combines the current + * timestamp with a UUID (hence the name "COMB"). The timestamp either appears + * as the first or last 48 bits of the COMB, depending on the codec used. + * + * By default, COMBs will have the timestamp set as the last 48 bits of the + * identifier. + * + * ``` php + * $factory = new UuidFactory(); + * + * $factory->setRandomGenerator(new CombGenerator( + * $factory->getRandomGenerator(), + * $factory->getNumberConverter() + * )); + * + * $comb = $factory->uuid4(); + * ``` * - * @link https://en.wikipedia.org/wiki/Globally_unique_identifier#Sequential_algorithms + * To generate a COMB with the timestamp as the first 48 bits, set the + * TimestampFirstCombCodec as the codec. + * + * ``` php + * $factory->setCodec(new TimestampFirstCombCodec($factory->getUuidBuilder())); + * ``` + * + * @link https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys */ class CombGenerator implements RandomGeneratorInterface { - const TIMESTAMP_BYTES = 6; + public const TIMESTAMP_BYTES = 6; /** * @var RandomGeneratorInterface @@ -39,50 +71,54 @@ class CombGenerator implements RandomGeneratorInterface */ private $converter; - /** - * Constructs a `CombGenerator` using a random-number generator and a number converter - * - * @param RandomGeneratorInterface $generator Random-number generator for the non-time part. - * @param NumberConverterInterface $numberConverter Instance of number converter. - */ - public function __construct(RandomGeneratorInterface $generator, NumberConverterInterface $numberConverter) - { + public function __construct( + RandomGeneratorInterface $generator, + NumberConverterInterface $numberConverter + ) { $this->converter = $numberConverter; $this->randomGenerator = $generator; } /** - * Generates a string of binary data of the specified length + * @throws InvalidArgumentException if $length is not a positive integer + * greater than or equal to CombGenerator::TIMESTAMP_BYTES * - * @param integer $length The number of bytes of random binary data to generate - * @return string A binary string - * @throws UnsatisfiedDependencyException if `Moontoast\Math\BigNumber` is not present - * @throws InvalidArgumentException if length is not a positive integer - * @throws Exception + * @inheritDoc */ - public function generate($length) + public function generate(int $length): string { if ($length < self::TIMESTAMP_BYTES || $length < 0) { - throw new InvalidArgumentException('Length must be a positive integer.'); + throw new InvalidArgumentException( + 'Length must be a positive integer greater than or equal to ' . self::TIMESTAMP_BYTES + ); } $hash = ''; - if (self::TIMESTAMP_BYTES > 0 && $length > self::TIMESTAMP_BYTES) { $hash = $this->randomGenerator->generate($length - self::TIMESTAMP_BYTES); } - $lsbTime = str_pad($this->converter->toHex($this->timestamp()), self::TIMESTAMP_BYTES * 2, '0', STR_PAD_LEFT); + $lsbTime = str_pad( + $this->converter->toHex($this->timestamp()), + self::TIMESTAMP_BYTES * 2, + '0', + STR_PAD_LEFT + ); - return hex2bin(str_pad(bin2hex($hash), $length - self::TIMESTAMP_BYTES, '0') . $lsbTime); + return (string) hex2bin( + str_pad( + bin2hex((string) $hash), + $length - self::TIMESTAMP_BYTES, + '0' + ) + . $lsbTime + ); } /** - * Returns current timestamp as integer, precise to 0.00001 seconds - * - * @return string + * Returns current timestamp a string integer, precise to 0.00001 seconds */ - private function timestamp() + private function timestamp(): string { $time = explode(' ', microtime(false)); diff --git a/vendor/ramsey/uuid/src/Generator/DceSecurityGenerator.php b/vendor/ramsey/uuid/src/Generator/DceSecurityGenerator.php new file mode 100644 index 000000000..a3f07f2ff --- /dev/null +++ b/vendor/ramsey/uuid/src/Generator/DceSecurityGenerator.php @@ -0,0 +1,161 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Generator; + +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Exception\DceSecurityException; +use Ramsey\Uuid\Provider\DceSecurityProviderInterface; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\Uuid; + +use function hex2bin; +use function in_array; +use function pack; +use function str_pad; +use function strlen; +use function substr_replace; + +use const STR_PAD_LEFT; + +/** + * DceSecurityGenerator generates strings of binary data based on a local + * domain, local identifier, node ID, clock sequence, and the current time + */ +class DceSecurityGenerator implements DceSecurityGeneratorInterface +{ + private const DOMAINS = [ + Uuid::DCE_DOMAIN_PERSON, + Uuid::DCE_DOMAIN_GROUP, + Uuid::DCE_DOMAIN_ORG, + ]; + + /** + * Upper bounds for the clock sequence in DCE Security UUIDs. + */ + private const CLOCK_SEQ_HIGH = 63; + + /** + * Lower bounds for the clock sequence in DCE Security UUIDs. + */ + private const CLOCK_SEQ_LOW = 0; + + /** + * @var NumberConverterInterface + */ + private $numberConverter; + + /** + * @var TimeGeneratorInterface + */ + private $timeGenerator; + + /** + * @var DceSecurityProviderInterface + */ + private $dceSecurityProvider; + + public function __construct( + NumberConverterInterface $numberConverter, + TimeGeneratorInterface $timeGenerator, + DceSecurityProviderInterface $dceSecurityProvider + ) { + $this->numberConverter = $numberConverter; + $this->timeGenerator = $timeGenerator; + $this->dceSecurityProvider = $dceSecurityProvider; + } + + public function generate( + int $localDomain, + ?IntegerObject $localIdentifier = null, + ?Hexadecimal $node = null, + ?int $clockSeq = null + ): string { + if (!in_array($localDomain, self::DOMAINS)) { + throw new DceSecurityException( + 'Local domain must be a valid DCE Security domain' + ); + } + + if ($localIdentifier && $localIdentifier->isNegative()) { + throw new DceSecurityException( + 'Local identifier out of bounds; it must be a value between 0 and 4294967295' + ); + } + + if ($clockSeq > self::CLOCK_SEQ_HIGH || $clockSeq < self::CLOCK_SEQ_LOW) { + throw new DceSecurityException( + 'Clock sequence out of bounds; it must be a value between 0 and 63' + ); + } + + switch ($localDomain) { + case Uuid::DCE_DOMAIN_ORG: + if ($localIdentifier === null) { + throw new DceSecurityException( + 'A local identifier must be provided for the org domain' + ); + } + + break; + case Uuid::DCE_DOMAIN_PERSON: + if ($localIdentifier === null) { + $localIdentifier = $this->dceSecurityProvider->getUid(); + } + + break; + case Uuid::DCE_DOMAIN_GROUP: + default: + if ($localIdentifier === null) { + $localIdentifier = $this->dceSecurityProvider->getGid(); + } + + break; + } + + $identifierHex = $this->numberConverter->toHex($localIdentifier->toString()); + + // The maximum value for the local identifier is 0xffffffff, or + // 4294967295. This is 8 hexadecimal digits, so if the length of + // hexadecimal digits is greater than 8, we know the value is greater + // than 0xffffffff. + if (strlen($identifierHex) > 8) { + throw new DceSecurityException( + 'Local identifier out of bounds; it must be a value between 0 and 4294967295' + ); + } + + $domainByte = pack('n', $localDomain)[1]; + $identifierBytes = hex2bin(str_pad($identifierHex, 8, '0', STR_PAD_LEFT)); + + if ($node instanceof Hexadecimal) { + $node = $node->toString(); + } + + // Shift the clock sequence 8 bits to the left, so it matches 0x3f00. + if ($clockSeq !== null) { + $clockSeq = $clockSeq << 8; + } + + /** @var string $bytes */ + $bytes = $this->timeGenerator->generate($node, $clockSeq); + + // Replace bytes in the time-based UUID with DCE Security values. + $bytes = substr_replace($bytes, $identifierBytes, 0, 4); + $bytes = substr_replace($bytes, $domainByte, 9, 1); + + return $bytes; + } +} diff --git a/vendor/ramsey/uuid/src/Generator/DceSecurityGeneratorInterface.php b/vendor/ramsey/uuid/src/Generator/DceSecurityGeneratorInterface.php new file mode 100644 index 000000000..faa29a53d --- /dev/null +++ b/vendor/ramsey/uuid/src/Generator/DceSecurityGeneratorInterface.php @@ -0,0 +1,53 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Generator; + +use Ramsey\Uuid\Rfc4122\UuidV2; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; + +/** + * A DCE Security generator generates strings of binary data based on a local + * domain, local identifier, node ID, clock sequence, and the current time + * + * @see UuidV2 + */ +interface DceSecurityGeneratorInterface +{ + /** + * Generate a binary string from a local domain, local identifier, node ID, + * clock sequence, and current time + * + * @param int $localDomain The local domain to use when generating bytes, + * according to DCE Security + * @param IntegerObject|null $localIdentifier The local identifier for the + * given domain; this may be a UID or GID on POSIX systems, if the local + * domain is person or group, or it may be a site-defined identifier + * if the local domain is org + * @param Hexadecimal|null $node A 48-bit number representing the hardware + * address + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates + * that could arise when the clock is set backwards in time or if the + * node ID changes + * + * @return string A binary string + */ + public function generate( + int $localDomain, + ?IntegerObject $localIdentifier = null, + ?Hexadecimal $node = null, + ?int $clockSeq = null + ): string; +} diff --git a/vendor/ramsey/uuid/src/Generator/DefaultNameGenerator.php b/vendor/ramsey/uuid/src/Generator/DefaultNameGenerator.php new file mode 100644 index 000000000..270e8fbe1 --- /dev/null +++ b/vendor/ramsey/uuid/src/Generator/DefaultNameGenerator.php @@ -0,0 +1,43 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Generator; + +use Ramsey\Uuid\Exception\NameException; +use Ramsey\Uuid\UuidInterface; + +use function hash; + +/** + * DefaultNameGenerator generates strings of binary data based on a namespace, + * name, and hashing algorithm + */ +class DefaultNameGenerator implements NameGeneratorInterface +{ + /** @psalm-pure */ + public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string + { + /** @var string|bool $bytes */ + $bytes = @hash($hashAlgorithm, $ns->getBytes() . $name, true); + + if ($bytes === false) { + throw new NameException(sprintf( + 'Unable to hash namespace and name with algorithm \'%s\'', + $hashAlgorithm + )); + } + + return (string) $bytes; + } +} diff --git a/vendor/ramsey/uuid/src/Generator/DefaultTimeGenerator.php b/vendor/ramsey/uuid/src/Generator/DefaultTimeGenerator.php index 5c5ccb294..d245c7bcc 100644 --- a/vendor/ramsey/uuid/src/Generator/DefaultTimeGenerator.php +++ b/vendor/ramsey/uuid/src/Generator/DefaultTimeGenerator.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,25 +8,35 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Generator; -use Exception; -use InvalidArgumentException; -use Ramsey\Uuid\BinaryUtils; use Ramsey\Uuid\Converter\TimeConverterInterface; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Exception\RandomSourceException; +use Ramsey\Uuid\Exception\TimeSourceException; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Provider\TimeProviderInterface; +use Ramsey\Uuid\Type\Hexadecimal; +use Throwable; + +use function ctype_xdigit; +use function dechex; +use function hex2bin; +use function is_int; +use function pack; +use function sprintf; +use function str_pad; +use function strlen; + +use const STR_PAD_LEFT; /** - * DefaultTimeGenerator provides functionality to generate strings of binary - * data for version 1 UUIDs based on a host ID, sequence number, and the current - * time + * DefaultTimeGenerator generates strings of binary data based on a node ID, + * clock sequence, and the current time */ class DefaultTimeGenerator implements TimeGeneratorInterface { @@ -44,14 +55,6 @@ class DefaultTimeGenerator implements TimeGeneratorInterface */ private $timeProvider; - /** - * Constructs a `DefaultTimeGenerator` using a node provider, time converter, - * and time provider - * - * @param NodeProviderInterface $nodeProvider - * @param TimeConverterInterface $timeConverter - * @param TimeProviderInterface $timeProvider - */ public function __construct( NodeProviderInterface $nodeProvider, TimeConverterInterface $timeConverter, @@ -63,79 +66,82 @@ class DefaultTimeGenerator implements TimeGeneratorInterface } /** - * Generate a version 1 UUID from a host ID, sequence number, and the current time + * @throws InvalidArgumentException if the parameters contain invalid values + * @throws RandomSourceException if random_int() throws an exception/error * - * If $node is not given, we will attempt to obtain the local hardware - * address. If $clockSeq is given, it is used as the sequence number; - * otherwise a random 14-bit sequence number is chosen. - * - * @param int|string $node A 48-bit number representing the hardware address - * This number may be represented as an integer or a hexadecimal string. - * @param int $clockSeq A 14-bit number used to help avoid duplicates that - * could arise when the clock is set backwards in time or if the node ID - * changes. - * @return string A binary string - * @throws UnsatisfiedDependencyException if called on a 32-bit system and - * `Moontoast\Math\BigNumber` is not present - * @throws InvalidArgumentException - * @throws Exception if it was not possible to gather sufficient entropy + * @inheritDoc */ - public function generate($node = null, $clockSeq = null) + public function generate($node = null, ?int $clockSeq = null): string { + if ($node instanceof Hexadecimal) { + $node = $node->toString(); + } + $node = $this->getValidNode($node); if ($clockSeq === null) { - // Not using "stable storage"; see RFC 4122, Section 4.2.1.1 - $clockSeq = random_int(0, 0x3fff); + try { + // This does not use "stable storage"; see RFC 4122, Section 4.2.1.1. + $clockSeq = random_int(0, 0x3fff); + } catch (Throwable $exception) { + throw new RandomSourceException( + $exception->getMessage(), + (int) $exception->getCode(), + $exception + ); + } } - // Create a 60-bit time value as a count of 100-nanosecond intervals - // since 00:00:00.00, 15 October 1582 - $timeOfDay = $this->timeProvider->currentTime(); - $uuidTime = $this->timeConverter->calculateTime($timeOfDay['sec'], $timeOfDay['usec']); - - $timeHi = BinaryUtils::applyVersion($uuidTime['hi'], 1); - $clockSeqHi = BinaryUtils::applyVariant($clockSeq >> 8); - - $hex = vsprintf( - '%08s%04s%04s%02s%02s%012s', - [ - $uuidTime['low'], - $uuidTime['mid'], - sprintf('%04x', $timeHi), - sprintf('%02x', $clockSeqHi), - sprintf('%02x', $clockSeq & 0xff), - $node, - ] + $time = $this->timeProvider->getTime(); + + $uuidTime = $this->timeConverter->calculateTime( + $time->getSeconds()->toString(), + $time->getMicroseconds()->toString() ); - return hex2bin($hex); + $timeHex = str_pad($uuidTime->toString(), 16, '0', STR_PAD_LEFT); + + if (strlen($timeHex) !== 16) { + throw new TimeSourceException(sprintf( + 'The generated time of \'%s\' is larger than expected', + $timeHex + )); + } + + $timeBytes = (string) hex2bin($timeHex); + + return $timeBytes[4] . $timeBytes[5] . $timeBytes[6] . $timeBytes[7] + . $timeBytes[2] . $timeBytes[3] + . $timeBytes[0] . $timeBytes[1] + . pack('n*', $clockSeq) + . $node; } /** * Uses the node provider given when constructing this instance to get * the node ID (usually a MAC address) * - * @param string|int $node A node value that may be used to override the node provider - * @return string Hexadecimal representation of the node ID + * @param string|int|null $node A node value that may be used to override the node provider + * + * @return string 6-byte binary string representation of the node + * * @throws InvalidArgumentException - * @throws Exception */ - protected function getValidNode($node) + private function getValidNode($node): string { if ($node === null) { $node = $this->nodeProvider->getNode(); } - // Convert the node to hex, if it is still an integer + // Convert the node to hex, if it is still an integer. if (is_int($node)) { - $node = sprintf('%012x', $node); + $node = dechex($node); } - if (!ctype_xdigit($node) || strlen($node) > 12) { + if (!ctype_xdigit((string) $node) || strlen((string) $node) > 12) { throw new InvalidArgumentException('Invalid node value'); } - return strtolower(sprintf('%012s', $node)); + return (string) hex2bin(str_pad((string) $node, 12, '0', STR_PAD_LEFT)); } } diff --git a/vendor/ramsey/uuid/src/Generator/MtRandGenerator.php b/vendor/ramsey/uuid/src/Generator/MtRandGenerator.php deleted file mode 100644 index 8d4b5f9b9..000000000 --- a/vendor/ramsey/uuid/src/Generator/MtRandGenerator.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/** - * This file is part of the ramsey/uuid library - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> - * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub - */ - -namespace Ramsey\Uuid\Generator; - -/** - * MtRandRandomGenerator provides functionality to generate strings of random - * binary data using the `mt_rand()` PHP function - * - * @deprecated The mt_rand() function is not a reliable source of randomness. - * The default RandomBytesGenerator, which uses the random_bytes() function, - * is recommended as the safest and most reliable source of randomness. - * <em>This generator will be removed in ramsey/uuid 4.0.0.</em> - * @link http://php.net/mt_rand - */ -class MtRandGenerator implements RandomGeneratorInterface -{ - /** - * Generates a string of random binary data of the specified length - * - * @param integer $length The number of bytes of random binary data to generate - * @return string A binary string - */ - public function generate($length) - { - $bytes = ''; - - for ($i = 1; $i <= $length; $i++) { - $bytes = chr(mt_rand(0, 255)) . $bytes; - } - - return $bytes; - } -} diff --git a/vendor/ramsey/uuid/src/Generator/NameGeneratorFactory.php b/vendor/ramsey/uuid/src/Generator/NameGeneratorFactory.php new file mode 100644 index 000000000..6f08e2910 --- /dev/null +++ b/vendor/ramsey/uuid/src/Generator/NameGeneratorFactory.php @@ -0,0 +1,30 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Generator; + +/** + * NameGeneratorFactory retrieves a default name generator, based on the + * environment + */ +class NameGeneratorFactory +{ + /** + * Returns a default name generator, based on the current environment + */ + public function getGenerator(): NameGeneratorInterface + { + return new DefaultNameGenerator(); + } +} diff --git a/vendor/ramsey/uuid/src/Generator/NameGeneratorInterface.php b/vendor/ramsey/uuid/src/Generator/NameGeneratorInterface.php new file mode 100644 index 000000000..cc43dd029 --- /dev/null +++ b/vendor/ramsey/uuid/src/Generator/NameGeneratorInterface.php @@ -0,0 +1,38 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Generator; + +use Ramsey\Uuid\UuidInterface; + +/** + * A name generator generates strings of binary data created by hashing together + * a namespace with a name, according to a hashing algorithm + */ +interface NameGeneratorInterface +{ + /** + * Generate a binary string from a namespace and name hashed together with + * the specified hashing algorithm + * + * @param UuidInterface $ns The namespace + * @param string $name The name to use for creating a UUID + * @param string $hashAlgorithm The hashing algorithm to use + * + * @return string A binary string + * + * @psalm-pure + */ + public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string; +} diff --git a/vendor/ramsey/uuid/src/Generator/OpenSslGenerator.php b/vendor/ramsey/uuid/src/Generator/OpenSslGenerator.php deleted file mode 100644 index 47abf9bb5..000000000 --- a/vendor/ramsey/uuid/src/Generator/OpenSslGenerator.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -/** - * This file is part of the ramsey/uuid library - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> - * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub - */ - -namespace Ramsey\Uuid\Generator; - -/** - * OpenSslRandomGenerator provides functionality to generate strings of random - * binary data using the `openssl_random_pseudo_bytes()` PHP function - * - * The use of this generator requires PHP to be compiled using the - * `--with-openssl` option. - * - * @deprecated The openssl_random_pseudo_bytes() function is not a reliable - * source of randomness. The default RandomBytesGenerator, which uses the - * random_bytes() function, is recommended as the safest and most reliable - * source of randomness. - * <em>This generator will be removed in ramsey/uuid 4.0.0.</em> - * @link http://php.net/openssl_random_pseudo_bytes - */ -class OpenSslGenerator implements RandomGeneratorInterface -{ - /** - * Generates a string of random binary data of the specified length - * - * @param integer $length The number of bytes of random binary data to generate - * @return string A binary string - */ - public function generate($length) - { - return openssl_random_pseudo_bytes($length); - } -} diff --git a/vendor/ramsey/uuid/src/Generator/PeclUuidNameGenerator.php b/vendor/ramsey/uuid/src/Generator/PeclUuidNameGenerator.php new file mode 100644 index 000000000..93b786878 --- /dev/null +++ b/vendor/ramsey/uuid/src/Generator/PeclUuidNameGenerator.php @@ -0,0 +1,54 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Generator; + +use Ramsey\Uuid\Exception\NameException; +use Ramsey\Uuid\UuidInterface; + +use function sprintf; +use function uuid_generate_md5; +use function uuid_generate_sha1; +use function uuid_parse; + +/** + * PeclUuidNameGenerator generates strings of binary data from a namespace and a + * name, using ext-uuid + * + * @link https://pecl.php.net/package/uuid ext-uuid + */ +class PeclUuidNameGenerator implements NameGeneratorInterface +{ + /** @psalm-pure */ + public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string + { + switch ($hashAlgorithm) { + case 'md5': + $uuid = (string) uuid_generate_md5($ns->toString(), $name); + + break; + case 'sha1': + $uuid = (string) uuid_generate_sha1($ns->toString(), $name); + + break; + default: + throw new NameException(sprintf( + 'Unable to hash namespace and name with algorithm \'%s\'', + $hashAlgorithm + )); + } + + return (string) uuid_parse($uuid); + } +} diff --git a/vendor/ramsey/uuid/src/Generator/PeclUuidRandomGenerator.php b/vendor/ramsey/uuid/src/Generator/PeclUuidRandomGenerator.php index fc2ef7e4d..df750f6a5 100644 --- a/vendor/ramsey/uuid/src/Generator/PeclUuidRandomGenerator.php +++ b/vendor/ramsey/uuid/src/Generator/PeclUuidRandomGenerator.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,28 +8,22 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Generator; +use const UUID_TYPE_RANDOM; + /** - * PeclUuidRandomGenerator provides functionality to generate strings of random - * binary data using the PECL UUID PHP extension + * PeclUuidRandomGenerator generates strings of random binary data using ext-uuid * - * @link https://pecl.php.net/package/uuid + * @link https://pecl.php.net/package/uuid ext-uuid */ class PeclUuidRandomGenerator implements RandomGeneratorInterface { - /** - * Generates a string of random binary data of the specified length - * - * @param integer $length The number of bytes of random binary data to generate - * @return string A binary string - */ - public function generate($length) + public function generate(int $length): string { $uuid = uuid_create(UUID_TYPE_RANDOM); diff --git a/vendor/ramsey/uuid/src/Generator/PeclUuidTimeGenerator.php b/vendor/ramsey/uuid/src/Generator/PeclUuidTimeGenerator.php index 7ccf16fd9..903798dd3 100644 --- a/vendor/ramsey/uuid/src/Generator/PeclUuidTimeGenerator.php +++ b/vendor/ramsey/uuid/src/Generator/PeclUuidTimeGenerator.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,29 +8,26 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Generator; +use const UUID_TYPE_TIME; + /** - * PeclUuidTimeGenerator provides functionality to generate strings of binary - * data for version 1 UUIDs using the PECL UUID PHP extension + * PeclUuidTimeGenerator generates strings of binary data for time-base UUIDs, + * using ext-uuid * - * @link https://pecl.php.net/package/uuid + * @link https://pecl.php.net/package/uuid ext-uuid */ class PeclUuidTimeGenerator implements TimeGeneratorInterface { /** - * Generate a version 1 UUID using the PECL UUID extension - * - * @param int|string $node Not used in this context - * @param int $clockSeq Not used in this context - * @return string A binary string + * @inheritDoc */ - public function generate($node = null, $clockSeq = null) + public function generate($node = null, ?int $clockSeq = null): string { $uuid = uuid_create(UUID_TYPE_TIME); diff --git a/vendor/ramsey/uuid/src/Generator/RandomBytesGenerator.php b/vendor/ramsey/uuid/src/Generator/RandomBytesGenerator.php index cc3d37989..e6e9a199b 100644 --- a/vendor/ramsey/uuid/src/Generator/RandomBytesGenerator.php +++ b/vendor/ramsey/uuid/src/Generator/RandomBytesGenerator.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,33 +8,37 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Generator; -use Exception; +use Ramsey\Uuid\Exception\RandomSourceException; /** - * RandomBytesGenerator provides functionality to generate strings of random - * binary data using `random_bytes()` function in PHP 7+ or paragonie/random_compat + * RandomBytesGenerator generates strings of random binary data using the + * built-in `random_bytes()` PHP function * - * @link http://php.net/random_bytes - * @link https://github.com/paragonie/random_compat + * @link http://php.net/random_bytes random_bytes() */ class RandomBytesGenerator implements RandomGeneratorInterface { /** - * Generates a string of random binary data of the specified length + * @throws RandomSourceException if random_bytes() throws an exception/error * - * @param integer $length The number of bytes of random binary data to generate - * @return string A binary string - * @throws Exception if it was not possible to gather sufficient entropy + * @inheritDoc */ - public function generate($length) + public function generate(int $length): string { - return random_bytes($length); + try { + return random_bytes($length); + } catch (\Throwable $exception) { + throw new RandomSourceException( + $exception->getMessage(), + (int) $exception->getCode(), + $exception + ); + } } } diff --git a/vendor/ramsey/uuid/src/Generator/RandomGeneratorFactory.php b/vendor/ramsey/uuid/src/Generator/RandomGeneratorFactory.php index 39110622f..b723ac29e 100644 --- a/vendor/ramsey/uuid/src/Generator/RandomGeneratorFactory.php +++ b/vendor/ramsey/uuid/src/Generator/RandomGeneratorFactory.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,24 +8,22 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Generator; /** - * A factory for retrieving a random generator, based on the environment + * RandomGeneratorFactory retrieves a default random generator, based on the + * environment */ class RandomGeneratorFactory { /** * Returns a default random generator, based on the current environment - * - * @return RandomGeneratorInterface */ - public static function getGenerator() + public function getGenerator(): RandomGeneratorInterface { return new RandomBytesGenerator(); } diff --git a/vendor/ramsey/uuid/src/Generator/RandomGeneratorInterface.php b/vendor/ramsey/uuid/src/Generator/RandomGeneratorInterface.php index b791d60d4..5c83cb4d8 100644 --- a/vendor/ramsey/uuid/src/Generator/RandomGeneratorInterface.php +++ b/vendor/ramsey/uuid/src/Generator/RandomGeneratorInterface.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,31 +8,23 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ -namespace Ramsey\Uuid\Generator; +declare(strict_types=1); -use Exception; -use InvalidArgumentException; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; +namespace Ramsey\Uuid\Generator; /** - * RandomGeneratorInterface provides functionality to generate strings of random - * binary data + * A random generator generates strings of random binary data */ interface RandomGeneratorInterface { /** - * Generates a string of random binary data of the specified length + * Generates a string of randomized binary data + * + * @param int $length The number of bytes of random binary data to generate * - * @param integer $length The number of bytes of random binary data to generate * @return string A binary string - * @throws UnsatisfiedDependencyException if `Moontoast\Math\BigNumber` is not present - * @throws InvalidArgumentException - * @throws Exception if it was not possible to gather sufficient entropy */ - public function generate($length); + public function generate(int $length): string; } diff --git a/vendor/ramsey/uuid/src/Generator/RandomLibAdapter.php b/vendor/ramsey/uuid/src/Generator/RandomLibAdapter.php index 5aa0e8865..24ed56920 100644 --- a/vendor/ramsey/uuid/src/Generator/RandomLibAdapter.php +++ b/vendor/ramsey/uuid/src/Generator/RandomLibAdapter.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,21 +8,20 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Generator; -use RandomLib\Generator; use RandomLib\Factory; +use RandomLib\Generator; /** - * RandomLibAdapter provides functionality to generate strings of random - * binary data using the paragonie/random-lib library + * RandomLibAdapter generates strings of random binary data using the + * paragonie/random-lib library * - * @link https://packagist.org/packages/paragonie/random-lib + * @link https://packagist.org/packages/paragonie/random-lib paragonie/random-lib */ class RandomLibAdapter implements RandomGeneratorInterface { @@ -31,31 +31,24 @@ class RandomLibAdapter implements RandomGeneratorInterface private $generator; /** - * Constructs a `RandomLibAdapter` using a `RandomLib\Generator` + * Constructs a RandomLibAdapter * - * By default, if no `Generator` is passed in, this creates a high-strength + * By default, if no Generator is passed in, this creates a high-strength * generator to use when generating random binary data. * - * @param Generator $generator An paragonie/random-lib `Generator` + * @param Generator|null $generator The generator to use when generating binary data */ - public function __construct(Generator $generator = null) + public function __construct(?Generator $generator = null) { - $this->generator = $generator; - - if ($this->generator === null) { + if ($generator === null) { $factory = new Factory(); - - $this->generator = $factory->getHighStrengthGenerator(); + $generator = $factory->getHighStrengthGenerator(); } + + $this->generator = $generator; } - /** - * Generates a string of random binary data of the specified length - * - * @param integer $length The number of bytes of random binary data to generate - * @return string A binary string - */ - public function generate($length) + public function generate(int $length): string { return $this->generator->generate($length); } diff --git a/vendor/ramsey/uuid/src/Generator/SodiumRandomGenerator.php b/vendor/ramsey/uuid/src/Generator/SodiumRandomGenerator.php deleted file mode 100644 index f4ccf8593..000000000 --- a/vendor/ramsey/uuid/src/Generator/SodiumRandomGenerator.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -/** - * This file is part of the ramsey/uuid library - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> - * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub - */ - -namespace Ramsey\Uuid\Generator; - -/** - * SodiumRandomGenerator provides functionality to generate strings of random - * binary data using the PECL libsodium extension - * - * @deprecated As of PHP 7.2.0, the libsodium extension is bundled with PHP, and - * the random_bytes() PHP function is now the recommended method for - * generating random byes. The default RandomBytesGenerator uses the - * random_bytes() function. - * <em>This generator will be removed in ramsey/uuid 4.0.0.</em> - * @link http://pecl.php.net/package/libsodium - * @link https://paragonie.com/book/pecl-libsodium - */ -class SodiumRandomGenerator implements RandomGeneratorInterface -{ - /** - * Generates a string of random binary data of the specified length - * - * @param integer $length The number of bytes of random binary data to generate - * @return string A binary string - */ - public function generate($length) - { - return \Sodium\randombytes_buf($length); - } -} diff --git a/vendor/ramsey/uuid/src/Generator/TimeGeneratorFactory.php b/vendor/ramsey/uuid/src/Generator/TimeGeneratorFactory.php index 24d501bbf..3d55fc4d6 100644 --- a/vendor/ramsey/uuid/src/Generator/TimeGeneratorFactory.php +++ b/vendor/ramsey/uuid/src/Generator/TimeGeneratorFactory.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,11 +8,10 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\Converter\TimeConverterInterface; @@ -19,7 +19,8 @@ use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Provider\TimeProviderInterface; /** - * A factory for retrieving a time generator, based on the environment + * TimeGeneratorFactory retrieves a default time generator, based on the + * environment */ class TimeGeneratorFactory { @@ -38,14 +39,6 @@ class TimeGeneratorFactory */ private $timeProvider; - /** - * Constructs a `TimeGeneratorFactory` using a node provider, time converter, - * and time provider - * - * @param NodeProviderInterface $nodeProvider - * @param TimeConverterInterface $timeConverter - * @param TimeProviderInterface $timeProvider - */ public function __construct( NodeProviderInterface $nodeProvider, TimeConverterInterface $timeConverter, @@ -58,10 +51,8 @@ class TimeGeneratorFactory /** * Returns a default time generator, based on the current environment - * - * @return TimeGeneratorInterface */ - public function getGenerator() + public function getGenerator(): TimeGeneratorInterface { return new DefaultTimeGenerator( $this->nodeProvider, diff --git a/vendor/ramsey/uuid/src/Generator/TimeGeneratorInterface.php b/vendor/ramsey/uuid/src/Generator/TimeGeneratorInterface.php index 27c74590f..18f21c4b6 100644 --- a/vendor/ramsey/uuid/src/Generator/TimeGeneratorInterface.php +++ b/vendor/ramsey/uuid/src/Generator/TimeGeneratorInterface.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,37 +8,31 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Generator; -use Exception; -use InvalidArgumentException; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; +use Ramsey\Uuid\Type\Hexadecimal; /** - * TimeGeneratorInterface provides functionality to generate strings of binary - * data for version 1 UUIDs based on a host ID, sequence number, and the current - * time + * A time generator generates strings of binary data based on a node ID, + * clock sequence, and the current time */ interface TimeGeneratorInterface { /** - * Generate a version 1 UUID from a host ID, sequence number, and the current time + * Generate a binary string from a node ID, clock sequence, and current time + * + * @param Hexadecimal|int|string|null $node A 48-bit number representing the + * hardware address; this number may be represented as an integer or a + * hexadecimal string + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates + * that could arise when the clock is set backwards in time or if the + * node ID changes * - * @param int|string $node A 48-bit number representing the hardware address - * This number may be represented as an integer or a hexadecimal string. - * @param int $clockSeq A 14-bit number used to help avoid duplicates that - * could arise when the clock is set backwards in time or if the node ID - * changes. * @return string A binary string - * @throws UnsatisfiedDependencyException if called on a 32-bit system and - * `Moontoast\Math\BigNumber` is not present - * @throws InvalidArgumentException - * @throws Exception if it was not possible to gather sufficient entropy */ - public function generate($node = null, $clockSeq = null); + public function generate($node = null, ?int $clockSeq = null): string; } diff --git a/vendor/ramsey/uuid/src/Guid/Fields.php b/vendor/ramsey/uuid/src/Guid/Fields.php new file mode 100644 index 000000000..49db4ed2f --- /dev/null +++ b/vendor/ramsey/uuid/src/Guid/Fields.php @@ -0,0 +1,190 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Guid; + +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Fields\SerializableFieldsTrait; +use Ramsey\Uuid\Rfc4122\FieldsInterface; +use Ramsey\Uuid\Rfc4122\NilTrait; +use Ramsey\Uuid\Rfc4122\VariantTrait; +use Ramsey\Uuid\Rfc4122\VersionTrait; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Uuid; + +use function bin2hex; +use function dechex; +use function hexdec; +use function pack; +use function sprintf; +use function str_pad; +use function strlen; +use function substr; +use function unpack; + +use const STR_PAD_LEFT; + +/** + * GUIDs are comprised of a set of named fields, according to RFC 4122 + * + * @see Guid + * + * @psalm-immutable + */ +final class Fields implements FieldsInterface +{ + use NilTrait; + use SerializableFieldsTrait; + use VariantTrait; + use VersionTrait; + + /** + * @var string + */ + private $bytes; + + /** + * @param string $bytes A 16-byte binary string representation of a UUID + * + * @throws InvalidArgumentException if the byte string is not exactly 16 bytes + * @throws InvalidArgumentException if the byte string does not represent a GUID + * @throws InvalidArgumentException if the byte string does not contain a valid version + */ + public function __construct(string $bytes) + { + if (strlen($bytes) !== 16) { + throw new InvalidArgumentException( + 'The byte string must be 16 bytes long; ' + . 'received ' . strlen($bytes) . ' bytes' + ); + } + + $this->bytes = $bytes; + + if (!$this->isCorrectVariant()) { + throw new InvalidArgumentException( + 'The byte string received does not conform to the RFC ' + . '4122 or Microsoft Corporation variants' + ); + } + + if (!$this->isCorrectVersion()) { + throw new InvalidArgumentException( + 'The byte string received does not contain a valid version' + ); + } + } + + public function getBytes(): string + { + return $this->bytes; + } + + public function getTimeLow(): Hexadecimal + { + // Swap the bytes from little endian to network byte order. + $hex = unpack( + 'H*', + pack( + 'v*', + hexdec(bin2hex(substr($this->bytes, 2, 2))), + hexdec(bin2hex(substr($this->bytes, 0, 2))) + ) + ); + + return new Hexadecimal((string) ($hex[1] ?? '')); + } + + public function getTimeMid(): Hexadecimal + { + // Swap the bytes from little endian to network byte order. + $hex = unpack( + 'H*', + pack( + 'v', + hexdec(bin2hex(substr($this->bytes, 4, 2))) + ) + ); + + return new Hexadecimal((string) ($hex[1] ?? '')); + } + + public function getTimeHiAndVersion(): Hexadecimal + { + // Swap the bytes from little endian to network byte order. + $hex = unpack( + 'H*', + pack( + 'v', + hexdec(bin2hex(substr($this->bytes, 6, 2))) + ) + ); + + return new Hexadecimal((string) ($hex[1] ?? '')); + } + + public function getTimestamp(): Hexadecimal + { + return new Hexadecimal(sprintf( + '%03x%04s%08s', + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, + $this->getTimeMid()->toString(), + $this->getTimeLow()->toString() + )); + } + + public function getClockSeq(): Hexadecimal + { + $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + + return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); + } + + public function getClockSeqHiAndReserved(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 8, 1))); + } + + public function getClockSeqLow(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 9, 1))); + } + + public function getNode(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 10))); + } + + public function getVersion(): ?int + { + if ($this->isNil()) { + return null; + } + + $parts = unpack('n*', $this->bytes); + + return ((int) $parts[4] >> 4) & 0x00f; + } + + private function isCorrectVariant(): bool + { + if ($this->isNil()) { + return true; + } + + $variant = $this->getVariant(); + + return $variant === Uuid::RFC_4122 || $variant === Uuid::RESERVED_MICROSOFT; + } +} diff --git a/vendor/ramsey/uuid/src/Guid/Guid.php b/vendor/ramsey/uuid/src/Guid/Guid.php new file mode 100644 index 000000000..08a00695a --- /dev/null +++ b/vendor/ramsey/uuid/src/Guid/Guid.php @@ -0,0 +1,62 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Guid; + +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Uuid; +use Ramsey\Uuid\UuidInterface; + +/** + * Guid represents a UUID with "native" (little-endian) byte order + * + * From Wikipedia: + * + * > The first three fields are unsigned 32- and 16-bit integers and are subject + * > to swapping, while the last two fields consist of uninterpreted bytes, not + * > subject to swapping. This byte swapping applies even for versions 3, 4, and + * > 5, where the canonical fields do not correspond to the content of the UUID. + * + * The first three fields of a GUID are encoded in little-endian byte order, + * while the last three fields are in network (big-endian) byte order. This is + * according to the history of the Microsoft definition of a GUID. + * + * According to the .NET Guid.ToByteArray method documentation: + * + * > Note that the order of bytes in the returned byte array is different from + * > the string representation of a Guid value. The order of the beginning + * > four-byte group and the next two two-byte groups is reversed, whereas the + * > order of the last two-byte group and the closing six-byte group is the + * > same. + * + * @link https://en.wikipedia.org/wiki/Universally_unique_identifier#Variants UUID Variants on Wikipedia + * @link https://docs.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid Windows GUID structure + * @link https://docs.microsoft.com/en-us/dotnet/api/system.guid .NET Guid Struct + * @link https://docs.microsoft.com/en-us/dotnet/api/system.guid.tobytearray .NET Guid.ToByteArray Method + * + * @psalm-immutable + */ +final class Guid extends Uuid implements UuidInterface +{ + public function __construct( + Fields $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter + ) { + parent::__construct($fields, $numberConverter, $codec, $timeConverter); + } +} diff --git a/vendor/ramsey/uuid/src/Guid/GuidBuilder.php b/vendor/ramsey/uuid/src/Guid/GuidBuilder.php new file mode 100644 index 000000000..758dd6b7f --- /dev/null +++ b/vendor/ramsey/uuid/src/Guid/GuidBuilder.php @@ -0,0 +1,89 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Guid; + +use Ramsey\Uuid\Builder\UuidBuilderInterface; +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\UnableToBuildUuidException; +use Ramsey\Uuid\UuidInterface; +use Throwable; + +/** + * GuidBuilder builds instances of Guid + * + * @see Guid + * + * @psalm-immutable + */ +class GuidBuilder implements UuidBuilderInterface +{ + /** + * @var NumberConverterInterface + */ + private $numberConverter; + + /** + * @var TimeConverterInterface + */ + private $timeConverter; + + /** + * @param NumberConverterInterface $numberConverter The number converter to + * use when constructing the Guid + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to Unix timestamps + */ + public function __construct( + NumberConverterInterface $numberConverter, + TimeConverterInterface $timeConverter + ) { + $this->numberConverter = $numberConverter; + $this->timeConverter = $timeConverter; + } + + /** + * Builds and returns a Guid + * + * @param CodecInterface $codec The codec to use for building this Guid instance + * @param string $bytes The byte string from which to construct a UUID + * + * @return Guid The GuidBuilder returns an instance of Ramsey\Uuid\Guid\Guid + * + * @psalm-pure + */ + public function build(CodecInterface $codec, string $bytes): UuidInterface + { + try { + return new Guid( + $this->buildFields($bytes), + $this->numberConverter, + $codec, + $this->timeConverter + ); + } catch (Throwable $e) { + throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e); + } + } + + /** + * Proxy method to allow injecting a mock, for testing + */ + protected function buildFields(string $bytes): Fields + { + return new Fields($bytes); + } +} diff --git a/vendor/ramsey/uuid/src/Lazy/LazyUuidFromString.php b/vendor/ramsey/uuid/src/Lazy/LazyUuidFromString.php new file mode 100644 index 000000000..3d4ddcb21 --- /dev/null +++ b/vendor/ramsey/uuid/src/Lazy/LazyUuidFromString.php @@ -0,0 +1,546 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Lazy; + +use DateTimeInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Exception\UnsupportedOperationException; +use Ramsey\Uuid\Fields\FieldsInterface; +use Ramsey\Uuid\Nonstandard\UuidV6; +use Ramsey\Uuid\Rfc4122\UuidV1; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\UuidFactory; +use Ramsey\Uuid\UuidInterface; + +use function assert; +use function bin2hex; +use function hex2bin; +use function str_replace; +use function substr; + +/** + * Lazy version of a UUID: its format has not been determined yet, so it is mostly only usable for string/bytes + * conversion. This object optimizes instantiation, serialization and string conversion time, at the cost of + * increased overhead for more advanced UUID operations. + * + * @internal this type is used internally for performance reasons, and is not supposed to be directly referenced + * in consumer libraries. + * + * @psalm-immutable + * + * Note: the {@see FieldsInterface} does not declare methods that deprecated API + * relies upon: the API has been ported from the {@see \Ramsey\Uuid\Uuid} definition, + * and is deprecated anyway. + * Note: the deprecated API from {@see \Ramsey\Uuid\Uuid} is in use here (on purpose): it will be removed + * once the deprecated API is gone from this class too. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + */ +final class LazyUuidFromString implements UuidInterface +{ + public const VALID_REGEX = '/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/ms'; + /** + * @var string + * @psalm-var non-empty-string + */ + private $uuid; + /** @var UuidInterface|null */ + private $unwrapped; + + /** @psalm-param non-empty-string $uuid */ + public function __construct(string $uuid) + { + $this->uuid = $uuid; + } + + /** @psalm-pure */ + public static function fromBytes(string $bytes): self + { + $base16Uuid = bin2hex($bytes); + + return new self( + substr($base16Uuid, 0, 8) + . '-' + . substr($base16Uuid, 8, 4) + . '-' + . substr($base16Uuid, 12, 4) + . '-' + . substr($base16Uuid, 16, 4) + . '-' + . substr($base16Uuid, 20, 12) + ); + } + + public function serialize(): string + { + return $this->uuid; + } + + /** + * {@inheritDoc} + * + * @param string $serialized + * + * @psalm-param non-empty-string $serialized + */ + public function unserialize($serialized): void + { + $this->uuid = $serialized; + } + + /** @psalm-suppress DeprecatedMethod */ + public function getNumberConverter(): NumberConverterInterface + { + return ($this->unwrapped ?? $this->unwrap()) + ->getNumberConverter(); + } + + /** + * {@inheritDoc} + * + * @psalm-suppress DeprecatedMethod + */ + public function getFieldsHex(): array + { + return ($this->unwrapped ?? $this->unwrap()) + ->getFieldsHex(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getClockSeqHiAndReservedHex(): string + { + return ($this->unwrapped ?? $this->unwrap()) + ->getClockSeqHiAndReservedHex(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getClockSeqLowHex(): string + { + return ($this->unwrapped ?? $this->unwrap()) + ->getClockSeqLowHex(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getClockSequenceHex(): string + { + return ($this->unwrapped ?? $this->unwrap()) + ->getClockSequenceHex(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getDateTime(): DateTimeInterface + { + return ($this->unwrapped ?? $this->unwrap()) + ->getDateTime(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getLeastSignificantBitsHex(): string + { + return ($this->unwrapped ?? $this->unwrap()) + ->getLeastSignificantBitsHex(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getMostSignificantBitsHex(): string + { + return ($this->unwrapped ?? $this->unwrap()) + ->getMostSignificantBitsHex(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getNodeHex(): string + { + return ($this->unwrapped ?? $this->unwrap()) + ->getNodeHex(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getTimeHiAndVersionHex(): string + { + return ($this->unwrapped ?? $this->unwrap()) + ->getTimeHiAndVersionHex(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getTimeLowHex(): string + { + return ($this->unwrapped ?? $this->unwrap()) + ->getTimeLowHex(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getTimeMidHex(): string + { + return ($this->unwrapped ?? $this->unwrap()) + ->getTimeMidHex(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getTimestampHex(): string + { + return ($this->unwrapped ?? $this->unwrap()) + ->getTimestampHex(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getUrn(): string + { + return ($this->unwrapped ?? $this->unwrap()) + ->getUrn(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getVariant(): ?int + { + return ($this->unwrapped ?? $this->unwrap()) + ->getVariant(); + } + + /** @psalm-suppress DeprecatedMethod */ + public function getVersion(): ?int + { + return ($this->unwrapped ?? $this->unwrap()) + ->getVersion(); + } + + public function compareTo(UuidInterface $other): int + { + return ($this->unwrapped ?? $this->unwrap()) + ->compareTo($other); + } + + public function equals(?object $other): bool + { + if (! $other instanceof UuidInterface) { + return false; + } + + return $this->uuid === $other->toString(); + } + + /** + * {@inheritDoc} + * + * @psalm-suppress MoreSpecificReturnType + * @psalm-suppress LessSpecificReturnStatement we know that {@see self::$uuid} is a non-empty string, so + * we know that {@see hex2bin} will retrieve a non-empty string too. + */ + public function getBytes(): string + { + return (string) hex2bin(str_replace('-', '', $this->uuid)); + } + + public function getFields(): FieldsInterface + { + return ($this->unwrapped ?? $this->unwrap()) + ->getFields(); + } + + public function getHex(): Hexadecimal + { + return ($this->unwrapped ?? $this->unwrap()) + ->getHex(); + } + + public function getInteger(): IntegerObject + { + return ($this->unwrapped ?? $this->unwrap()) + ->getInteger(); + } + + public function toString(): string + { + return $this->uuid; + } + + public function __toString(): string + { + return $this->uuid; + } + + public function jsonSerialize(): string + { + return $this->uuid; + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqHiAndReserved()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall + */ + public function getClockSeqHiAndReserved(): string + { + $instance = ($this->unwrapped ?? $this->unwrap()); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getClockSeqHiAndReserved() + ->toString() + ); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqLow()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall + */ + public function getClockSeqLow(): string + { + $instance = ($this->unwrapped ?? $this->unwrap()); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getClockSeqLow() + ->toString() + ); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getClockSeq()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall + */ + public function getClockSequence(): string + { + $instance = ($this->unwrapped ?? $this->unwrap()); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getClockSeq() + ->toString() + ); + } + + /** + * @deprecated This method will be removed in 5.0.0. There is no direct + * alternative, but the same information may be obtained by splitting + * in half the value returned by {@see UuidInterface::getHex()}. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall + */ + public function getLeastSignificantBits(): string + { + $instance = ($this->unwrapped ?? $this->unwrap()); + + return $instance->getNumberConverter() + ->fromHex(substr($instance->getHex()->toString(), 16)); + } + + /** + * @deprecated This method will be removed in 5.0.0. There is no direct + * alternative, but the same information may be obtained by splitting + * in half the value returned by {@see UuidInterface::getHex()}. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall + */ + public function getMostSignificantBits(): string + { + $instance = ($this->unwrapped ?? $this->unwrap()); + + return $instance->getNumberConverter() + ->fromHex(substr($instance->getHex()->toString(), 0, 16)); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getNode()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall + */ + public function getNode(): string + { + $instance = ($this->unwrapped ?? $this->unwrap()); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getNode() + ->toString() + ); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimeHiAndVersion()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall + */ + public function getTimeHiAndVersion(): string + { + $instance = ($this->unwrapped ?? $this->unwrap()); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getTimeHiAndVersion() + ->toString() + ); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimeLow()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall + */ + public function getTimeLow(): string + { + $instance = ($this->unwrapped ?? $this->unwrap()); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getTimeLow() + ->toString() + ); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimeMid()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall + */ + public function getTimeMid(): string + { + $instance = ($this->unwrapped ?? $this->unwrap()); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getTimeMid() + ->toString() + ); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimestamp()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall + */ + public function getTimestamp(): string + { + $instance = ($this->unwrapped ?? $this->unwrap()); + $fields = $instance->getFields(); + + if ($fields->getVersion() !== 1) { + throw new UnsupportedOperationException('Not a time-based UUID'); + } + + return $instance->getNumberConverter() + ->fromHex($fields->getTimestamp()->toString()); + } + + public function toUuidV1(): UuidV1 + { + $instance = ($this->unwrapped ?? $this->unwrap()); + + if ($instance instanceof UuidV1) { + return $instance; + } + + assert($instance instanceof UuidV6); + + return $instance->toUuidV1(); + } + + public function toUuidV6(): UuidV6 + { + $instance = ($this->unwrapped ?? $this->unwrap()); + + assert($instance instanceof UuidV6); + + return $instance; + } + + /** + * @psalm-suppress ImpureMethodCall the retrieval of the factory is a clear violation of purity here: this is a + * known pitfall of the design of this library, where a value object contains + * a mutable reference to a factory. We use a fixed factory here, so the violation + * will not have real-world effects, as this object is only instantiated with the + * default factory settings/features. + * @psalm-suppress InaccessibleProperty property {@see $unwrapped} is used as a cache: we don't expose it to the + * outside world, so we should be fine here. + */ + private function unwrap(): UuidInterface + { + return $this->unwrapped = (new UuidFactory()) + ->fromString($this->uuid); + } +} diff --git a/vendor/ramsey/uuid/src/Math/BrickMathCalculator.php b/vendor/ramsey/uuid/src/Math/BrickMathCalculator.php new file mode 100644 index 000000000..f2d86788c --- /dev/null +++ b/vendor/ramsey/uuid/src/Math/BrickMathCalculator.php @@ -0,0 +1,144 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Math; + +use Brick\Math\BigDecimal; +use Brick\Math\BigInteger; +use Brick\Math\Exception\MathException; +use Brick\Math\RoundingMode as BrickMathRounding; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Type\Decimal; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\Type\NumberInterface; + +/** + * A calculator using the brick/math library for arbitrary-precision arithmetic + * + * @psalm-immutable + */ +final class BrickMathCalculator implements CalculatorInterface +{ + private const ROUNDING_MODE_MAP = [ + RoundingMode::UNNECESSARY => BrickMathRounding::UNNECESSARY, + RoundingMode::UP => BrickMathRounding::UP, + RoundingMode::DOWN => BrickMathRounding::DOWN, + RoundingMode::CEILING => BrickMathRounding::CEILING, + RoundingMode::FLOOR => BrickMathRounding::FLOOR, + RoundingMode::HALF_UP => BrickMathRounding::HALF_UP, + RoundingMode::HALF_DOWN => BrickMathRounding::HALF_DOWN, + RoundingMode::HALF_CEILING => BrickMathRounding::HALF_CEILING, + RoundingMode::HALF_FLOOR => BrickMathRounding::HALF_FLOOR, + RoundingMode::HALF_EVEN => BrickMathRounding::HALF_EVEN, + ]; + + public function add(NumberInterface $augend, NumberInterface ...$addends): NumberInterface + { + $sum = BigInteger::of($augend->toString()); + + foreach ($addends as $addend) { + $sum = $sum->plus($addend->toString()); + } + + return new IntegerObject((string) $sum); + } + + public function subtract(NumberInterface $minuend, NumberInterface ...$subtrahends): NumberInterface + { + $difference = BigInteger::of($minuend->toString()); + + foreach ($subtrahends as $subtrahend) { + $difference = $difference->minus($subtrahend->toString()); + } + + return new IntegerObject((string) $difference); + } + + public function multiply(NumberInterface $multiplicand, NumberInterface ...$multipliers): NumberInterface + { + $product = BigInteger::of($multiplicand->toString()); + + foreach ($multipliers as $multiplier) { + $product = $product->multipliedBy($multiplier->toString()); + } + + return new IntegerObject((string) $product); + } + + public function divide( + int $roundingMode, + int $scale, + NumberInterface $dividend, + NumberInterface ...$divisors + ): NumberInterface { + $brickRounding = $this->getBrickRoundingMode($roundingMode); + + $quotient = BigDecimal::of($dividend->toString()); + + foreach ($divisors as $divisor) { + $quotient = $quotient->dividedBy($divisor->toString(), $scale, $brickRounding); + } + + if ($scale === 0) { + return new IntegerObject((string) $quotient->toBigInteger()); + } + + return new Decimal((string) $quotient); + } + + public function fromBase(string $value, int $base): IntegerObject + { + try { + return new IntegerObject((string) BigInteger::fromBase($value, $base)); + } catch (MathException | \InvalidArgumentException $exception) { + throw new InvalidArgumentException( + $exception->getMessage(), + (int) $exception->getCode(), + $exception + ); + } + } + + public function toBase(IntegerObject $value, int $base): string + { + try { + return BigInteger::of($value->toString())->toBase($base); + } catch (MathException | \InvalidArgumentException $exception) { + throw new InvalidArgumentException( + $exception->getMessage(), + (int) $exception->getCode(), + $exception + ); + } + } + + public function toHexadecimal(IntegerObject $value): Hexadecimal + { + return new Hexadecimal($this->toBase($value, 16)); + } + + public function toInteger(Hexadecimal $value): IntegerObject + { + return $this->fromBase($value->toString(), 16); + } + + /** + * Maps ramsey/uuid rounding modes to those used by brick/math + */ + private function getBrickRoundingMode(int $roundingMode): int + { + return self::ROUNDING_MODE_MAP[$roundingMode] ?? 0; + } +} diff --git a/vendor/ramsey/uuid/src/Math/CalculatorInterface.php b/vendor/ramsey/uuid/src/Math/CalculatorInterface.php new file mode 100644 index 000000000..f03645d0f --- /dev/null +++ b/vendor/ramsey/uuid/src/Math/CalculatorInterface.php @@ -0,0 +1,106 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Math; + +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\Type\NumberInterface; + +/** + * A calculator performs arithmetic operations on numbers + * + * @psalm-immutable + */ +interface CalculatorInterface +{ + /** + * Returns the sum of all the provided parameters + * + * @param NumberInterface $augend The first addend (the integer being added to) + * @param NumberInterface ...$addends The additional integers to a add to the augend + * + * @return NumberInterface The sum of all the parameters + */ + public function add(NumberInterface $augend, NumberInterface ...$addends): NumberInterface; + + /** + * Returns the difference of all the provided parameters + * + * @param NumberInterface $minuend The integer being subtracted from + * @param NumberInterface ...$subtrahends The integers to subtract from the minuend + * + * @return NumberInterface The difference after subtracting all parameters + */ + public function subtract(NumberInterface $minuend, NumberInterface ...$subtrahends): NumberInterface; + + /** + * Returns the product of all the provided parameters + * + * @param NumberInterface $multiplicand The integer to be multiplied + * @param NumberInterface ...$multipliers The factors by which to multiply the multiplicand + * + * @return NumberInterface The product of multiplying all the provided parameters + */ + public function multiply(NumberInterface $multiplicand, NumberInterface ...$multipliers): NumberInterface; + + /** + * Returns the quotient of the provided parameters divided left-to-right + * + * @param int $roundingMode The RoundingMode constant to use for this operation + * @param int $scale The scale to use for this operation + * @param NumberInterface $dividend The integer to be divided + * @param NumberInterface ...$divisors The integers to divide $dividend by, in + * the order in which the division operations should take place + * (left-to-right) + * + * @return NumberInterface The quotient of dividing the provided parameters left-to-right + */ + public function divide( + int $roundingMode, + int $scale, + NumberInterface $dividend, + NumberInterface ...$divisors + ): NumberInterface; + + /** + * Converts a value from an arbitrary base to a base-10 integer value + * + * @param string $value The value to convert + * @param int $base The base to convert from (i.e., 2, 16, 32, etc.) + * + * @return IntegerObject The base-10 integer value of the converted value + */ + public function fromBase(string $value, int $base): IntegerObject; + + /** + * Converts a base-10 integer value to an arbitrary base + * + * @param IntegerObject $value The integer value to convert + * @param int $base The base to convert to (i.e., 2, 16, 32, etc.) + * + * @return string The value represented in the specified base + */ + public function toBase(IntegerObject $value, int $base): string; + + /** + * Converts an Integer instance to a Hexadecimal instance + */ + public function toHexadecimal(IntegerObject $value): Hexadecimal; + + /** + * Converts a Hexadecimal instance to an Integer instance + */ + public function toInteger(Hexadecimal $value): IntegerObject; +} diff --git a/vendor/ramsey/uuid/src/Math/RoundingMode.php b/vendor/ramsey/uuid/src/Math/RoundingMode.php new file mode 100644 index 000000000..e710270d0 --- /dev/null +++ b/vendor/ramsey/uuid/src/Math/RoundingMode.php @@ -0,0 +1,146 @@ +<?php + +/** + * This file was originally part of brick/math + * + * Copyright (c) 2013-present Benjamin Morel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @link https://github.com/brick/math brick/math at GitHub + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Math; + +/** + * Specifies a rounding behavior for numerical operations capable of discarding + * precision. + * + * Each rounding mode indicates how the least significant returned digit of a + * rounded result is to be calculated. If fewer digits are returned than the + * digits needed to represent the exact numerical result, the discarded digits + * will be referred to as the discarded fraction regardless the digits' + * contribution to the value of the number. In other words, considered as a + * numerical value, the discarded fraction could have an absolute value greater + * than one. + */ +final class RoundingMode +{ + /** + * Private constructor. This class is not instantiable. + * + * @codeCoverageIgnore + */ + private function __construct() + { + } + + /** + * Asserts that the requested operation has an exact result, hence no + * rounding is necessary. + */ + public const UNNECESSARY = 0; + + /** + * Rounds away from zero. + * + * Always increments the digit prior to a nonzero discarded fraction. + * Note that this rounding mode never decreases the magnitude of the + * calculated value. + */ + public const UP = 1; + + /** + * Rounds towards zero. + * + * Never increments the digit prior to a discarded fraction (i.e., + * truncates). Note that this rounding mode never increases the magnitude of + * the calculated value. + */ + public const DOWN = 2; + + /** + * Rounds towards positive infinity. + * + * If the result is positive, behaves as for UP; if negative, behaves as for + * DOWN. Note that this rounding mode never decreases the calculated value. + */ + public const CEILING = 3; + + /** + * Rounds towards negative infinity. + * + * If the result is positive, behave as for DOWN; if negative, behave as for + * UP. Note that this rounding mode never increases the calculated value. + */ + public const FLOOR = 4; + + /** + * Rounds towards "nearest neighbor" unless both neighbors are equidistant, + * in which case round up. + * + * Behaves as for UP if the discarded fraction is >= 0.5; otherwise, behaves + * as for DOWN. Note that this is the rounding mode commonly taught at + * school. + */ + public const HALF_UP = 5; + + /** + * Rounds towards "nearest neighbor" unless both neighbors are equidistant, + * in which case round down. + * + * Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves + * as for DOWN. + */ + public const HALF_DOWN = 6; + + /** + * Rounds towards "nearest neighbor" unless both neighbors are equidistant, + * in which case round towards positive infinity. + * + * If the result is positive, behaves as for HALF_UP; if negative, behaves + * as for HALF_DOWN. + */ + public const HALF_CEILING = 7; + + /** + * Rounds towards "nearest neighbor" unless both neighbors are equidistant, + * in which case round towards negative infinity. + * + * If the result is positive, behaves as for HALF_DOWN; if negative, behaves + * as for HALF_UP. + */ + public const HALF_FLOOR = 8; + + /** + * Rounds towards the "nearest neighbor" unless both neighbors are + * equidistant, in which case rounds towards the even neighbor. + * + * Behaves as for HALF_UP if the digit to the left of the discarded fraction + * is odd; behaves as for HALF_DOWN if it's even. + * + * Note that this is the rounding mode that statistically minimizes + * cumulative error when applied repeatedly over a sequence of calculations. + * It is sometimes known as "Banker's rounding", and is chiefly used in the + * USA. + */ + public const HALF_EVEN = 9; +} diff --git a/vendor/ramsey/uuid/src/Nonstandard/Fields.php b/vendor/ramsey/uuid/src/Nonstandard/Fields.php new file mode 100644 index 000000000..927bc6a26 --- /dev/null +++ b/vendor/ramsey/uuid/src/Nonstandard/Fields.php @@ -0,0 +1,133 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Nonstandard; + +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Fields\SerializableFieldsTrait; +use Ramsey\Uuid\Rfc4122\FieldsInterface; +use Ramsey\Uuid\Rfc4122\VariantTrait; +use Ramsey\Uuid\Type\Hexadecimal; + +use function bin2hex; +use function dechex; +use function hexdec; +use function sprintf; +use function str_pad; +use function strlen; +use function substr; + +use const STR_PAD_LEFT; + +/** + * Nonstandard UUID fields do not conform to the RFC 4122 standard + * + * Since some systems may create nonstandard UUIDs, this implements the + * Rfc4122\FieldsInterface, so that functionality of a nonstandard UUID is not + * degraded, in the event these UUIDs are expected to contain RFC 4122 fields. + * + * Internally, this class represents the fields together as a 16-byte binary + * string. + * + * @psalm-immutable + */ +final class Fields implements FieldsInterface +{ + use SerializableFieldsTrait; + use VariantTrait; + + /** + * @var string + */ + private $bytes; + + /** + * @param string $bytes A 16-byte binary string representation of a UUID + * + * @throws InvalidArgumentException if the byte string is not exactly 16 bytes + */ + public function __construct(string $bytes) + { + if (strlen($bytes) !== 16) { + throw new InvalidArgumentException( + 'The byte string must be 16 bytes long; ' + . 'received ' . strlen($bytes) . ' bytes' + ); + } + + $this->bytes = $bytes; + } + + public function getBytes(): string + { + return $this->bytes; + } + + public function getClockSeq(): Hexadecimal + { + $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + + return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); + } + + public function getClockSeqHiAndReserved(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 8, 1))); + } + + public function getClockSeqLow(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 9, 1))); + } + + public function getNode(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 10))); + } + + public function getTimeHiAndVersion(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 6, 2))); + } + + public function getTimeLow(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 0, 4))); + } + + public function getTimeMid(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 4, 2))); + } + + public function getTimestamp(): Hexadecimal + { + return new Hexadecimal(sprintf( + '%03x%04s%08s', + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, + $this->getTimeMid()->toString(), + $this->getTimeLow()->toString() + )); + } + + public function getVersion(): ?int + { + return null; + } + + public function isNil(): bool + { + return false; + } +} diff --git a/vendor/ramsey/uuid/src/Nonstandard/Uuid.php b/vendor/ramsey/uuid/src/Nonstandard/Uuid.php new file mode 100644 index 000000000..5a7a33347 --- /dev/null +++ b/vendor/ramsey/uuid/src/Nonstandard/Uuid.php @@ -0,0 +1,38 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Nonstandard; + +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Uuid as BaseUuid; +use Ramsey\Uuid\UuidInterface; + +/** + * Nonstandard\Uuid is a UUID that doesn't conform to RFC 4122 + * + * @psalm-immutable + */ +final class Uuid extends BaseUuid implements UuidInterface +{ + public function __construct( + Fields $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter + ) { + parent::__construct($fields, $numberConverter, $codec, $timeConverter); + } +} diff --git a/vendor/ramsey/uuid/src/Nonstandard/UuidBuilder.php b/vendor/ramsey/uuid/src/Nonstandard/UuidBuilder.php new file mode 100644 index 000000000..0c8927738 --- /dev/null +++ b/vendor/ramsey/uuid/src/Nonstandard/UuidBuilder.php @@ -0,0 +1,88 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Nonstandard; + +use Ramsey\Uuid\Builder\UuidBuilderInterface; +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\UnableToBuildUuidException; +use Ramsey\Uuid\UuidInterface; +use Throwable; + +/** + * Nonstandard\UuidBuilder builds instances of Nonstandard\Uuid + * + * @psalm-immutable + */ +class UuidBuilder implements UuidBuilderInterface +{ + /** + * @var NumberConverterInterface + */ + private $numberConverter; + + /** + * @var TimeConverterInterface + */ + private $timeConverter; + + /** + * @param NumberConverterInterface $numberConverter The number converter to + * use when constructing the Nonstandard\Uuid + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to Unix timestamps + */ + public function __construct( + NumberConverterInterface $numberConverter, + TimeConverterInterface $timeConverter + ) { + $this->numberConverter = $numberConverter; + $this->timeConverter = $timeConverter; + } + + /** + * Builds and returns a Nonstandard\Uuid + * + * @param CodecInterface $codec The codec to use for building this instance + * @param string $bytes The byte string from which to construct a UUID + * + * @return Uuid The Nonstandard\UuidBuilder returns an instance of + * Nonstandard\Uuid + * + * @psalm-pure + */ + public function build(CodecInterface $codec, string $bytes): UuidInterface + { + try { + return new Uuid( + $this->buildFields($bytes), + $this->numberConverter, + $codec, + $this->timeConverter + ); + } catch (Throwable $e) { + throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e); + } + } + + /** + * Proxy method to allow injecting a mock, for testing + */ + protected function buildFields(string $bytes): Fields + { + return new Fields($bytes); + } +} diff --git a/vendor/ramsey/uuid/src/Nonstandard/UuidV6.php b/vendor/ramsey/uuid/src/Nonstandard/UuidV6.php new file mode 100644 index 000000000..05586b3eb --- /dev/null +++ b/vendor/ramsey/uuid/src/Nonstandard/UuidV6.php @@ -0,0 +1,133 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Nonstandard; + +use DateTimeImmutable; +use DateTimeInterface; +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\DateTimeException; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Lazy\LazyUuidFromString; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Rfc4122\UuidInterface; +use Ramsey\Uuid\Rfc4122\UuidV1; +use Ramsey\Uuid\Uuid; +use Throwable; + +use function hex2bin; +use function str_pad; +use function substr; + +use const STR_PAD_LEFT; + +/** + * Ordered-time, or version 6, UUIDs include timestamp, clock sequence, and node + * values that are combined into a 128-bit unsigned integer + * + * @link https://github.com/uuid6/uuid6-ietf-draft UUID version 6 IETF draft + * @link http://gh.peabody.io/uuidv6/ "Version 6" UUIDs + * + * @psalm-immutable + */ +final class UuidV6 extends Uuid implements UuidInterface +{ + /** + * Creates a version 6 (time-based) UUID + * + * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID + * @param NumberConverterInterface $numberConverter The number converter to use + * for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding + * UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to unix timestamps + */ + public function __construct( + Rfc4122FieldsInterface $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter + ) { + if ($fields->getVersion() !== Uuid::UUID_TYPE_PEABODY) { + throw new InvalidArgumentException( + 'Fields used to create a UuidV6 must represent a ' + . 'version 6 (ordered-time) UUID' + ); + } + + parent::__construct($fields, $numberConverter, $codec, $timeConverter); + } + + /** + * Returns a DateTimeInterface object representing the timestamp associated + * with the UUID + * + * @return DateTimeImmutable A PHP DateTimeImmutable instance representing + * the timestamp of a version 6 UUID + */ + public function getDateTime(): DateTimeInterface + { + $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); + + try { + return new DateTimeImmutable( + '@' + . $time->getSeconds()->toString() + . '.' + . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) + ); + } catch (Throwable $e) { + throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); + } + } + + /** + * Converts this UUID into an instance of a version 1 UUID + */ + public function toUuidV1(): UuidV1 + { + $hex = $this->getHex()->toString(); + $hex = substr($hex, 7, 5) + . substr($hex, 13, 3) + . substr($hex, 3, 4) + . '1' . substr($hex, 0, 3) + . substr($hex, 16); + + /** @var LazyUuidFromString $uuid */ + $uuid = Uuid::fromBytes((string) hex2bin($hex)); + + return $uuid->toUuidV1(); + } + + /** + * Converts a version 1 UUID into an instance of a version 6 UUID + */ + public static function fromUuidV1(UuidV1 $uuidV1): UuidV6 + { + $hex = $uuidV1->getHex()->toString(); + $hex = substr($hex, 13, 3) + . substr($hex, 8, 4) + . substr($hex, 0, 5) + . '6' . substr($hex, 5, 3) + . substr($hex, 16); + + /** @var LazyUuidFromString $uuid */ + $uuid = Uuid::fromBytes((string) hex2bin($hex)); + + return $uuid->toUuidV6(); + } +} diff --git a/vendor/ramsey/uuid/src/Provider/Dce/SystemDceSecurityProvider.php b/vendor/ramsey/uuid/src/Provider/Dce/SystemDceSecurityProvider.php new file mode 100644 index 000000000..1a1f4cf2e --- /dev/null +++ b/vendor/ramsey/uuid/src/Provider/Dce/SystemDceSecurityProvider.php @@ -0,0 +1,235 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Provider\Dce; + +use Ramsey\Uuid\Exception\DceSecurityException; +use Ramsey\Uuid\Provider\DceSecurityProviderInterface; +use Ramsey\Uuid\Type\Integer as IntegerObject; + +use function escapeshellarg; +use function preg_split; +use function str_getcsv; +use function strpos; +use function strrpos; +use function strtolower; +use function strtoupper; +use function substr; +use function trim; + +use const PREG_SPLIT_NO_EMPTY; + +/** + * SystemDceSecurityProvider retrieves the user or group identifiers from the system + */ +class SystemDceSecurityProvider implements DceSecurityProviderInterface +{ + /** + * @throws DceSecurityException if unable to get a user identifier + * + * @inheritDoc + */ + public function getUid(): IntegerObject + { + static $uid = null; + + if ($uid instanceof IntegerObject) { + return $uid; + } + + if ($uid === null) { + $uid = $this->getSystemUid(); + } + + if ($uid === '') { + throw new DceSecurityException( + 'Unable to get a user identifier using the system DCE ' + . 'Security provider; please provide a custom identifier or ' + . 'use a different provider' + ); + } + + $uid = new IntegerObject($uid); + + return $uid; + } + + /** + * @throws DceSecurityException if unable to get a group identifier + * + * @inheritDoc + */ + public function getGid(): IntegerObject + { + static $gid = null; + + if ($gid instanceof IntegerObject) { + return $gid; + } + + if ($gid === null) { + $gid = $this->getSystemGid(); + } + + if ($gid === '') { + throw new DceSecurityException( + 'Unable to get a group identifier using the system DCE ' + . 'Security provider; please provide a custom identifier or ' + . 'use a different provider' + ); + } + + $gid = new IntegerObject($gid); + + return $gid; + } + + /** + * Returns the UID from the system + */ + private function getSystemUid(): string + { + if (!$this->hasShellExec()) { + return ''; + } + + switch ($this->getOs()) { + case 'WIN': + return $this->getWindowsUid(); + case 'DAR': + case 'FRE': + case 'LIN': + default: + return trim((string) shell_exec('id -u')); + } + } + + /** + * Returns the GID from the system + */ + private function getSystemGid(): string + { + if (!$this->hasShellExec()) { + return ''; + } + + switch ($this->getOs()) { + case 'WIN': + return $this->getWindowsGid(); + case 'DAR': + case 'FRE': + case 'LIN': + default: + return trim((string) shell_exec('id -g')); + } + } + + /** + * Returns true if shell_exec() is available for use + */ + private function hasShellExec(): bool + { + $disabledFunctions = strtolower((string) ini_get('disable_functions')); + + return strpos($disabledFunctions, 'shell_exec') === false; + } + + /** + * Returns the PHP_OS string + */ + private function getOs(): string + { + return strtoupper(substr(constant('PHP_OS'), 0, 3)); + } + + /** + * Returns the user identifier for a user on a Windows system + * + * Windows does not have the same concept as an effective POSIX UID for the + * running script. Instead, each user is uniquely identified by an SID + * (security identifier). The SID includes three 32-bit unsigned integers + * that make up a unique domain identifier, followed by an RID (relative + * identifier) that we will use as the UID. The primary caveat is that this + * UID may not be unique to the system, since it is, instead, unique to the + * domain. + * + * @link https://www.lifewire.com/what-is-an-sid-number-2626005 What Is an SID Number? + * @link https://bit.ly/30vE7NM Well-known SID Structures + * @link https://bit.ly/2FWcYKJ Well-known security identifiers in Windows operating systems + * @link https://www.windows-commandline.com/get-sid-of-user/ Get SID of user + */ + private function getWindowsUid(): string + { + $response = shell_exec('whoami /user /fo csv /nh'); + + if ($response === null) { + return ''; + } + + /** @var string $sid */ + $sid = str_getcsv(trim($response))[1] ?? ''; + + if (($lastHyphen = strrpos($sid, '-')) === false) { + return ''; + } + + return trim(substr($sid, $lastHyphen + 1)); + } + + /** + * Returns a group identifier for a user on a Windows system + * + * Since Windows does not have the same concept as an effective POSIX GID + * for the running script, we will get the local group memberships for the + * user running the script. Then, we will get the SID (security identifier) + * for the first group that appears in that list. Finally, we will return + * the RID (relative identifier) for the group and use that as the GID. + * + * @link https://www.windows-commandline.com/list-of-user-groups-command-line/ List of user groups command line + */ + private function getWindowsGid(): string + { + $response = shell_exec('net user %username% | findstr /b /i "Local Group Memberships"'); + + if ($response === null) { + return ''; + } + + /** @var string[] $userGroups */ + $userGroups = preg_split('/\s{2,}/', $response, -1, PREG_SPLIT_NO_EMPTY); + + $firstGroup = trim($userGroups[1] ?? '', "* \t\n\r\0\x0B"); + + if ($firstGroup === '') { + return ''; + } + + $response = shell_exec('wmic group get name,sid | findstr /b /i ' . escapeshellarg($firstGroup)); + + if ($response === null) { + return ''; + } + + /** @var string[] $userGroup */ + $userGroup = preg_split('/\s{2,}/', $response, -1, PREG_SPLIT_NO_EMPTY); + + $sid = $userGroup[1] ?? ''; + + if (($lastHyphen = strrpos($sid, '-')) === false) { + return ''; + } + + return trim((string) substr($sid, $lastHyphen + 1)); + } +} diff --git a/vendor/ramsey/uuid/src/Provider/DceSecurityProviderInterface.php b/vendor/ramsey/uuid/src/Provider/DceSecurityProviderInterface.php new file mode 100644 index 000000000..8325da696 --- /dev/null +++ b/vendor/ramsey/uuid/src/Provider/DceSecurityProviderInterface.php @@ -0,0 +1,41 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Provider; + +use Ramsey\Uuid\Rfc4122\UuidV2; +use Ramsey\Uuid\Type\Integer as IntegerObject; + +/** + * A DCE provider provides access to local domain identifiers for version 2, + * DCE Security, UUIDs + * + * @see UuidV2 + */ +interface DceSecurityProviderInterface +{ + /** + * Returns a user identifier for the system + * + * @link https://en.wikipedia.org/wiki/User_identifier User identifier + */ + public function getUid(): IntegerObject; + + /** + * Returns a group identifier for the system + * + * @link https://en.wikipedia.org/wiki/Group_identifier Group identifier + */ + public function getGid(): IntegerObject; +} diff --git a/vendor/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php b/vendor/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php index 83488ab96..f6e5e406d 100644 --- a/vendor/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php +++ b/vendor/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,53 +8,54 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Provider\Node; -use Exception; +use Ramsey\Uuid\Exception\NodeException; use Ramsey\Uuid\Provider\NodeProviderInterface; +use Ramsey\Uuid\Type\Hexadecimal; /** - * FallbackNodeProvider attempts to gain the system host ID from an array of - * providers, falling back to the next in line in the event a host ID can not be - * obtained + * FallbackNodeProvider retrieves the system node ID by stepping through a list + * of providers until a node ID can be obtained */ class FallbackNodeProvider implements NodeProviderInterface { /** - * @var NodeProviderInterface[] + * @var NodeProviderCollection */ private $nodeProviders; /** - * Constructs a `FallbackNodeProvider` using an array of node providers - * - * @param NodeProviderInterface[] $providers Array of node providers + * @param NodeProviderCollection $providers Array of node providers */ - public function __construct(array $providers) + public function __construct(NodeProviderCollection $providers) { $this->nodeProviders = $providers; } - /** - * Returns the system node ID by iterating over an array of node providers - * and returning the first non-empty value found - * - * @return string System node ID as a hexadecimal string - * @throws Exception - */ - public function getNode() + public function getNode(): Hexadecimal { + $lastProviderException = null; + + /** @var NodeProviderInterface $provider */ foreach ($this->nodeProviders as $provider) { - if ($node = $provider->getNode()) { - return $node; + try { + return $provider->getNode(); + } catch (NodeException $exception) { + $lastProviderException = $exception; + + continue; } } - return null; + throw new NodeException( + 'Unable to find a suitable node provider', + 0, + $lastProviderException + ); } } diff --git a/vendor/ramsey/uuid/src/Provider/Node/NodeProviderCollection.php b/vendor/ramsey/uuid/src/Provider/Node/NodeProviderCollection.php new file mode 100644 index 000000000..89d09178d --- /dev/null +++ b/vendor/ramsey/uuid/src/Provider/Node/NodeProviderCollection.php @@ -0,0 +1,54 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Provider\Node; + +use Ramsey\Collection\AbstractCollection; +use Ramsey\Collection\CollectionInterface; +use Ramsey\Uuid\Provider\NodeProviderInterface; +use Ramsey\Uuid\Type\Hexadecimal; + +/** + * A collection of NodeProviderInterface objects + */ +class NodeProviderCollection extends AbstractCollection implements CollectionInterface +{ + public function getType(): string + { + return NodeProviderInterface::class; + } + + /** + * Re-constructs the object from its serialized form + * + * @param string $serialized The serialized PHP string to unserialize into + * a UuidInterface instance + * + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + */ + public function unserialize($serialized): void + { + /** @var mixed[] $data */ + $data = unserialize($serialized, [ + 'allowed_classes' => [ + Hexadecimal::class, + RandomNodeProvider::class, + StaticNodeProvider::class, + SystemNodeProvider::class, + ], + ]); + + $this->data = $data; + } +} diff --git a/vendor/ramsey/uuid/src/Provider/Node/RandomNodeProvider.php b/vendor/ramsey/uuid/src/Provider/Node/RandomNodeProvider.php index 79ec63cb8..266c0b738 100644 --- a/vendor/ramsey/uuid/src/Provider/Node/RandomNodeProvider.php +++ b/vendor/ramsey/uuid/src/Provider/Node/RandomNodeProvider.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,33 +8,43 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Provider\Node; -use Exception; +use Ramsey\Uuid\Exception\RandomSourceException; use Ramsey\Uuid\Provider\NodeProviderInterface; +use Ramsey\Uuid\Type\Hexadecimal; + +use function bin2hex; +use function dechex; +use function hex2bin; +use function hexdec; +use function str_pad; +use function substr; + +use const STR_PAD_LEFT; /** - * RandomNodeProvider provides functionality to generate a random node ID, in - * the event that the node ID could not be obtained from the host system + * RandomNodeProvider generates a random node ID * - * @link http://tools.ietf.org/html/rfc4122#section-4.5 + * @link http://tools.ietf.org/html/rfc4122#section-4.5 RFC 4122, § 4.5: Node IDs that Do Not Identify the Host */ class RandomNodeProvider implements NodeProviderInterface { - /** - * Returns the system node ID - * - * @return string System node ID as a hexadecimal string - * @throws Exception if it was not possible to gather sufficient entropy - */ - public function getNode() + public function getNode(): Hexadecimal { - $nodeBytes = random_bytes(6); + try { + $nodeBytes = random_bytes(6); + } catch (\Throwable $exception) { + throw new RandomSourceException( + $exception->getMessage(), + (int) $exception->getCode(), + $exception + ); + } // Split the node bytes for math on 32-bit systems. $nodeMsb = substr($nodeBytes, 0, 3); @@ -52,6 +63,6 @@ class RandomNodeProvider implements NodeProviderInterface // Recombine the node bytes. $node = $nodeMsb . $nodeLsb; - return str_pad(bin2hex($node), 12, '0', STR_PAD_LEFT); + return new Hexadecimal(str_pad(bin2hex($node), 12, '0', STR_PAD_LEFT)); } } diff --git a/vendor/ramsey/uuid/src/Provider/Node/StaticNodeProvider.php b/vendor/ramsey/uuid/src/Provider/Node/StaticNodeProvider.php new file mode 100644 index 000000000..51f1b02ea --- /dev/null +++ b/vendor/ramsey/uuid/src/Provider/Node/StaticNodeProvider.php @@ -0,0 +1,76 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Provider\Node; + +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Provider\NodeProviderInterface; +use Ramsey\Uuid\Type\Hexadecimal; + +use function dechex; +use function hexdec; +use function str_pad; +use function substr; + +use const STR_PAD_LEFT; + +/** + * StaticNodeProvider provides a static node value with the multicast bit set + * + * @link http://tools.ietf.org/html/rfc4122#section-4.5 RFC 4122, § 4.5: Node IDs that Do Not Identify the Host + */ +class StaticNodeProvider implements NodeProviderInterface +{ + /** + * @var Hexadecimal + */ + private $node; + + /** + * @param Hexadecimal $node The static node value to use + */ + public function __construct(Hexadecimal $node) + { + if (strlen($node->toString()) > 12) { + throw new InvalidArgumentException( + 'Static node value cannot be greater than 12 hexadecimal characters' + ); + } + + $this->node = $this->setMulticastBit($node); + } + + public function getNode(): Hexadecimal + { + return $this->node; + } + + /** + * Set the multicast bit for the static node value + */ + private function setMulticastBit(Hexadecimal $node): Hexadecimal + { + $nodeHex = str_pad($node->toString(), 12, '0', STR_PAD_LEFT); + $firstOctet = substr($nodeHex, 0, 2); + + $firstOctet = str_pad( + dechex(hexdec($firstOctet) | 0x01), + 2, + '0', + STR_PAD_LEFT + ); + + return new Hexadecimal($firstOctet . substr($nodeHex, 2)); + } +} diff --git a/vendor/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php b/vendor/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php index 57015133a..8234abaee 100644 --- a/vendor/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php +++ b/vendor/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,50 +8,86 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Provider\Node; +use Ramsey\Uuid\Exception\NodeException; use Ramsey\Uuid\Provider\NodeProviderInterface; +use Ramsey\Uuid\Type\Hexadecimal; + +use function array_filter; +use function array_map; +use function array_walk; +use function count; +use function ob_get_clean; +use function ob_start; +use function preg_match; +use function preg_match_all; +use function reset; +use function str_replace; +use function strpos; +use function strtolower; +use function strtoupper; +use function substr; + +use const GLOB_NOSORT; +use const PREG_PATTERN_ORDER; /** - * SystemNodeProvider provides functionality to get the system node ID (MAC - * address) using external system calls + * SystemNodeProvider retrieves the system node ID, if possible + * + * The system node ID, or host ID, is often the same as the MAC address for a + * network interface on the host. */ class SystemNodeProvider implements NodeProviderInterface { /** - * Returns the system node ID - * - * @return string|false System node ID as a hexadecimal string, or false if it is not found + * Pattern to match nodes in ifconfig and ipconfig output. + */ + private const IFCONFIG_PATTERN = '/[^:]([0-9a-f]{2}([:-])[0-9a-f]{2}(\2[0-9a-f]{2}){4})[^:]/i'; + + /** + * Pattern to match nodes in sysfs stream output. + */ + private const SYSFS_PATTERN = '/^([0-9a-f]{2}:){5}[0-9a-f]{2}$/i'; + + public function getNode(): Hexadecimal + { + $node = $this->getNodeFromSystem(); + + if ($node === '') { + throw new NodeException( + 'Unable to fetch a node for this system' + ); + } + + return new Hexadecimal($node); + } + + /** + * Returns the system node, if it can find it */ - public function getNode() + protected function getNodeFromSystem(): string { static $node = null; if ($node !== null) { - return $node; + return (string) $node; } - $pattern = '/[^:]([0-9A-Fa-f]{2}([:-])[0-9A-Fa-f]{2}(\2[0-9A-Fa-f]{2}){4})[^:]/'; - $matches = []; - - // first try a linux specific way + // First, try a Linux-specific approach. $node = $this->getSysfs(); - // Search the ifconfig output for all MAC addresses and return - // the first one found - if ($node === false) { - if (preg_match_all($pattern, $this->getIfconfig(), $matches, PREG_PATTERN_ORDER)) { - $node = $matches[1][0]; - } - } - if ($node !== false) { - $node = str_replace([':', '-'], '', $node); + if ($node === '') { + // Search ifconfig output for MAC addresses & return the first one. + $node = $this->getIfconfig(); } + + $node = str_replace([':', '-'], '', $node); + return $node; } @@ -58,11 +95,12 @@ class SystemNodeProvider implements NodeProviderInterface * Returns the network interface configuration for the system * * @codeCoverageIgnore - * @return string */ - protected function getIfconfig() + protected function getIfconfig(): string { - if (strpos(strtolower(ini_get('disable_functions')), 'passthru') !== false) { + $disabledFunctions = strtolower((string) ini_get('disable_functions')); + + if (strpos($disabledFunctions, 'passthru') !== false) { return ''; } @@ -70,40 +108,50 @@ class SystemNodeProvider implements NodeProviderInterface switch (strtoupper(substr(constant('PHP_OS'), 0, 3))) { case 'WIN': passthru('ipconfig /all 2>&1'); + break; case 'DAR': passthru('ifconfig 2>&1'); + break; case 'FRE': passthru('netstat -i -f link 2>&1'); + break; case 'LIN': default: passthru('netstat -ie 2>&1'); + break; } - return ob_get_clean(); + $ifconfig = (string) ob_get_clean(); + + $node = ''; + if (preg_match_all(self::IFCONFIG_PATTERN, $ifconfig, $matches, PREG_PATTERN_ORDER)) { + $node = $matches[1][0] ?? ''; + } + + return (string) $node; } /** - * Returns mac address from the first system interface via the sysfs interface - * - * @return string|bool + * Returns MAC address from the first system interface via the sysfs interface */ - protected function getSysfs() + protected function getSysfs(): string { - $mac = false; + $mac = ''; if (strtoupper(constant('PHP_OS')) === 'LINUX') { $addressPaths = glob('/sys/class/net/*/address', GLOB_NOSORT); - if (empty($addressPaths)) { - return false; + if ($addressPaths === false || count($addressPaths) === 0) { + return ''; } $macs = []; - array_walk($addressPaths, function ($addressPath) use (&$macs) { + + array_walk($addressPaths, function (string $addressPath) use (&$macs): void { if (is_readable($addressPath)) { $macs[] = file_get_contents($addressPath); } @@ -111,18 +159,15 @@ class SystemNodeProvider implements NodeProviderInterface $macs = array_map('trim', $macs); - // remove invalid entries - $macs = array_filter($macs, function ($mac) { - return - // localhost adapter - $mac !== '00:00:00:00:00:00' && - // must match mac adress - preg_match('/^([0-9a-f]{2}:){5}[0-9a-f]{2}$/i', $mac); + // Remove invalid entries. + $macs = array_filter($macs, function (string $address) { + return $address !== '00:00:00:00:00:00' + && preg_match(self::SYSFS_PATTERN, $address); }); $mac = reset($macs); } - return $mac; + return (string) $mac; } } diff --git a/vendor/ramsey/uuid/src/Provider/NodeProviderInterface.php b/vendor/ramsey/uuid/src/Provider/NodeProviderInterface.php index b6f721feb..d536b4558 100644 --- a/vendor/ramsey/uuid/src/Provider/NodeProviderInterface.php +++ b/vendor/ramsey/uuid/src/Provider/NodeProviderInterface.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,26 +8,23 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Provider; -use Exception; +use Ramsey\Uuid\Type\Hexadecimal; /** - * NodeProviderInterface provides functionality to get the node ID (or host ID - * in the form of the system's MAC address) from a specific type of node provider + * A node provider retrieves or generates a node ID */ interface NodeProviderInterface { /** - * Returns the system node ID + * Returns a node ID * - * @return string System node ID as a hexadecimal string - * @throws Exception if it was not possible to gather sufficient entropy + * @return Hexadecimal The node ID as a hexadecimal string */ - public function getNode(); + public function getNode(): Hexadecimal; } diff --git a/vendor/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php b/vendor/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php index 79a9d04e0..b8bfd7215 100644 --- a/vendor/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php +++ b/vendor/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,70 +8,55 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Provider\Time; -use InvalidArgumentException; use Ramsey\Uuid\Provider\TimeProviderInterface; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\Type\Time; /** - * FixedTimeProvider uses an previously-generated timestamp to provide the time + * FixedTimeProvider uses an known time to provide the time * - * This provider allows the use of a previously-generated timestamp, such as one - * stored in a database, when creating version 1 UUIDs. + * This provider allows the use of a previously-generated, or known, time + * when generating time-based UUIDs. */ class FixedTimeProvider implements TimeProviderInterface { /** - * @var int[] Array containing `sec` and `usec` components of a timestamp + * @var Time */ private $fixedTime; - /** - * Constructs a `FixedTimeProvider` using the provided `$timestamp` - * - * @param int[] Array containing `sec` and `usec` components of a timestamp - * @throws InvalidArgumentException if the `$timestamp` does not contain `sec` or `usec` components - */ - public function __construct(array $timestamp) + public function __construct(Time $time) { - if (!array_key_exists('sec', $timestamp) || !array_key_exists('usec', $timestamp)) { - throw new InvalidArgumentException('Array must contain sec and usec keys.'); - } - - $this->fixedTime = $timestamp; + $this->fixedTime = $time; } /** - * Sets the `usec` component of the timestamp + * Sets the `usec` component of the time * - * @param int $value The `usec` value to set + * @param int|string|IntegerObject $value The `usec` value to set */ - public function setUsec($value) + public function setUsec($value): void { - $this->fixedTime['usec'] = $value; + $this->fixedTime = new Time($this->fixedTime->getSeconds(), $value); } /** - * Sets the `sec` component of the timestamp + * Sets the `sec` component of the time * - * @param int $value The `sec` value to set + * @param int|string|IntegerObject $value The `sec` value to set */ - public function setSec($value) + public function setSec($value): void { - $this->fixedTime['sec'] = $value; + $this->fixedTime = new Time($value, $this->fixedTime->getMicroseconds()); } - /** - * Returns a timestamp array - * - * @return int[] Array containing `sec` and `usec` components of a timestamp - */ - public function currentTime() + public function getTime(): Time { return $this->fixedTime; } diff --git a/vendor/ramsey/uuid/src/Provider/Time/SystemTimeProvider.php b/vendor/ramsey/uuid/src/Provider/Time/SystemTimeProvider.php index 6442985fa..3a1e09cb4 100644 --- a/vendor/ramsey/uuid/src/Provider/Time/SystemTimeProvider.php +++ b/vendor/ramsey/uuid/src/Provider/Time/SystemTimeProvider.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,27 +8,26 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Provider\Time; use Ramsey\Uuid\Provider\TimeProviderInterface; +use Ramsey\Uuid\Type\Time; + +use function gettimeofday; /** - * SystemTimeProvider uses built-in PHP functions to provide the time + * SystemTimeProvider retrieves the current time using built-in PHP functions */ class SystemTimeProvider implements TimeProviderInterface { - /** - * Returns a timestamp array - * - * @return int[] Array containing `sec` and `usec` components of a timestamp - */ - public function currentTime() + public function getTime(): Time { - return gettimeofday(); + $time = gettimeofday(); + + return new Time($time['sec'], $time['usec']); } } diff --git a/vendor/ramsey/uuid/src/Provider/TimeProviderInterface.php b/vendor/ramsey/uuid/src/Provider/TimeProviderInterface.php index ef8099dd1..43588e0bd 100644 --- a/vendor/ramsey/uuid/src/Provider/TimeProviderInterface.php +++ b/vendor/ramsey/uuid/src/Provider/TimeProviderInterface.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,23 +8,21 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid\Provider; +use Ramsey\Uuid\Type\Time; + /** - * TimeProviderInterface provides functionality to get the time from a specific - * type of time provider + * A time provider retrieves the current time */ interface TimeProviderInterface { /** - * Returns a timestamp array - * - * @return int[] Array guaranteed to contain `sec` and `usec` components of a timestamp + * Returns a time object */ - public function currentTime(); + public function getTime(): Time; } diff --git a/vendor/ramsey/uuid/src/Rfc4122/Fields.php b/vendor/ramsey/uuid/src/Rfc4122/Fields.php new file mode 100644 index 000000000..0989d842a --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/Fields.php @@ -0,0 +1,193 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Fields\SerializableFieldsTrait; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Uuid; + +use function bin2hex; +use function dechex; +use function hexdec; +use function sprintf; +use function str_pad; +use function strlen; +use function substr; +use function unpack; + +use const STR_PAD_LEFT; + +/** + * RFC 4122 variant UUIDs are comprised of a set of named fields + * + * Internally, this class represents the fields together as a 16-byte binary + * string. + * + * @psalm-immutable + */ +final class Fields implements FieldsInterface +{ + use NilTrait; + use SerializableFieldsTrait; + use VariantTrait; + use VersionTrait; + + /** + * @var string + */ + private $bytes; + + /** + * @param string $bytes A 16-byte binary string representation of a UUID + * + * @throws InvalidArgumentException if the byte string is not exactly 16 bytes + * @throws InvalidArgumentException if the byte string does not represent an RFC 4122 UUID + * @throws InvalidArgumentException if the byte string does not contain a valid version + */ + public function __construct(string $bytes) + { + if (strlen($bytes) !== 16) { + throw new InvalidArgumentException( + 'The byte string must be 16 bytes long; ' + . 'received ' . strlen($bytes) . ' bytes' + ); + } + + $this->bytes = $bytes; + + if (!$this->isCorrectVariant()) { + throw new InvalidArgumentException( + 'The byte string received does not conform to the RFC 4122 variant' + ); + } + + if (!$this->isCorrectVersion()) { + throw new InvalidArgumentException( + 'The byte string received does not contain a valid RFC 4122 version' + ); + } + } + + public function getBytes(): string + { + return $this->bytes; + } + + public function getClockSeq(): Hexadecimal + { + $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + + return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); + } + + public function getClockSeqHiAndReserved(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 8, 1))); + } + + public function getClockSeqLow(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 9, 1))); + } + + public function getNode(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 10))); + } + + public function getTimeHiAndVersion(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 6, 2))); + } + + public function getTimeLow(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 0, 4))); + } + + public function getTimeMid(): Hexadecimal + { + return new Hexadecimal(bin2hex(substr($this->bytes, 4, 2))); + } + + /** + * Returns the full 60-bit timestamp, without the version + * + * For version 2 UUIDs, the time_low field is the local identifier and + * should not be returned as part of the time. For this reason, we set the + * bottom 32 bits of the timestamp to 0's. As a result, there is some loss + * of fidelity of the timestamp, for version 2 UUIDs. The timestamp can be + * off by a range of 0 to 429.4967295 seconds (or 7 minutes, 9 seconds, and + * 496730 microseconds). + * + * For version 6 UUIDs, the timestamp order is reversed from the typical RFC + * 4122 order (the time bits are in the correct bit order, so that it is + * monotonically increasing). In returning the timestamp value, we put the + * bits in the order: time_low + time_mid + time_hi. + */ + public function getTimestamp(): Hexadecimal + { + switch ($this->getVersion()) { + case Uuid::UUID_TYPE_DCE_SECURITY: + $timestamp = sprintf( + '%03x%04s%08s', + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, + $this->getTimeMid()->toString(), + '' + ); + + break; + case Uuid::UUID_TYPE_PEABODY: + $timestamp = sprintf( + '%08s%04s%03x', + $this->getTimeLow()->toString(), + $this->getTimeMid()->toString(), + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff + ); + + break; + default: + $timestamp = sprintf( + '%03x%04s%08s', + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, + $this->getTimeMid()->toString(), + $this->getTimeLow()->toString() + ); + } + + return new Hexadecimal($timestamp); + } + + public function getVersion(): ?int + { + if ($this->isNil()) { + return null; + } + + $parts = unpack('n*', $this->bytes); + + return (int) $parts[4] >> 12; + } + + private function isCorrectVariant(): bool + { + if ($this->isNil()) { + return true; + } + + return $this->getVariant() === Uuid::RFC_4122; + } +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/FieldsInterface.php b/vendor/ramsey/uuid/src/Rfc4122/FieldsInterface.php new file mode 100644 index 000000000..a303525d6 --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/FieldsInterface.php @@ -0,0 +1,126 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Fields\FieldsInterface as BaseFieldsInterface; +use Ramsey\Uuid\Type\Hexadecimal; + +/** + * RFC 4122 defines fields for a specific variant of UUID + * + * The fields of an RFC 4122 variant UUID are: + * + * * **time_low**: The low field of the timestamp, an unsigned 32-bit integer + * * **time_mid**: The middle field of the timestamp, an unsigned 16-bit integer + * * **time_hi_and_version**: The high field of the timestamp multiplexed with + * the version number, an unsigned 16-bit integer + * * **clock_seq_hi_and_reserved**: The high field of the clock sequence + * multiplexed with the variant, an unsigned 8-bit integer + * * **clock_seq_low**: The low field of the clock sequence, an unsigned + * 8-bit integer + * * **node**: The spatially unique node identifier, an unsigned 48-bit + * integer + * + * @link http://tools.ietf.org/html/rfc4122#section-4.1 RFC 4122, § 4.1: Format + * + * @psalm-immutable + */ +interface FieldsInterface extends BaseFieldsInterface +{ + /** + * Returns the full 16-bit clock sequence, with the variant bits (two most + * significant bits) masked out + */ + public function getClockSeq(): Hexadecimal; + + /** + * Returns the high field of the clock sequence multiplexed with the variant + */ + public function getClockSeqHiAndReserved(): Hexadecimal; + + /** + * Returns the low field of the clock sequence + */ + public function getClockSeqLow(): Hexadecimal; + + /** + * Returns the node field + */ + public function getNode(): Hexadecimal; + + /** + * Returns the high field of the timestamp multiplexed with the version + */ + public function getTimeHiAndVersion(): Hexadecimal; + + /** + * Returns the low field of the timestamp + */ + public function getTimeLow(): Hexadecimal; + + /** + * Returns the middle field of the timestamp + */ + public function getTimeMid(): Hexadecimal; + + /** + * Returns the full 60-bit timestamp, without the version + */ + public function getTimestamp(): Hexadecimal; + + /** + * Returns the variant + * + * The variant number describes the layout of the UUID. The variant + * number has the following meaning: + * + * - 0 - Reserved for NCS backward compatibility + * - 2 - The RFC 4122 variant + * - 6 - Reserved, Microsoft Corporation backward compatibility + * - 7 - Reserved for future definition + * + * For RFC 4122 variant UUIDs, this value should always be the integer `2`. + * + * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant + */ + public function getVariant(): int; + + /** + * Returns the version + * + * The version number describes how the UUID was generated and has the + * following meaning: + * + * 1. Time-based UUID + * 2. DCE security UUID + * 3. Name-based UUID hashed with MD5 + * 4. Randomly generated UUID + * 5. Name-based UUID hashed with SHA-1 + * + * This returns `null` if the UUID is not an RFC 4122 variant, since version + * is only meaningful for this variant. + * + * @link http://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version + */ + public function getVersion(): ?int; + + /** + * Returns true if these fields represent a nil UUID + * + * The nil UUID is special form of UUID that is specified to have all 128 + * bits set to zero. + */ + public function isNil(): bool; +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/NilTrait.php b/vendor/ramsey/uuid/src/Rfc4122/NilTrait.php new file mode 100644 index 000000000..9a9774d89 --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/NilTrait.php @@ -0,0 +1,41 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +/** + * Provides common functionality for nil UUIDs + * + * The nil UUID is special form of UUID that is specified to have all 128 bits + * set to zero. + * + * @link https://tools.ietf.org/html/rfc4122#section-4.1.7 RFC 4122, § 4.1.7: Nil UUID + * + * @psalm-immutable + */ +trait NilTrait +{ + /** + * Returns the bytes that comprise the fields + */ + abstract public function getBytes(): string; + + /** + * Returns true if the byte string represents a nil UUID + */ + public function isNil(): bool + { + return $this->getBytes() === "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + } +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/NilUuid.php b/vendor/ramsey/uuid/src/Rfc4122/NilUuid.php new file mode 100644 index 000000000..c49b9945d --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/NilUuid.php @@ -0,0 +1,27 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Uuid; + +/** + * The nil UUID is special form of UUID that is specified to have all 128 bits + * set to zero + * + * @psalm-immutable + */ +final class NilUuid extends Uuid implements UuidInterface +{ +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/UuidBuilder.php b/vendor/ramsey/uuid/src/Rfc4122/UuidBuilder.php new file mode 100644 index 000000000..736931af2 --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/UuidBuilder.php @@ -0,0 +1,111 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Builder\UuidBuilderInterface; +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\UnableToBuildUuidException; +use Ramsey\Uuid\Exception\UnsupportedOperationException; +use Ramsey\Uuid\Nonstandard\UuidV6; +use Ramsey\Uuid\Rfc4122\UuidInterface as Rfc4122UuidInterface; +use Ramsey\Uuid\UuidInterface; +use Throwable; + +/** + * UuidBuilder builds instances of RFC 4122 UUIDs + * + * @psalm-immutable + */ +class UuidBuilder implements UuidBuilderInterface +{ + /** + * @var NumberConverterInterface + */ + private $numberConverter; + + /** + * @var TimeConverterInterface + */ + private $timeConverter; + + /** + * Constructs the DefaultUuidBuilder + * + * @param NumberConverterInterface $numberConverter The number converter to + * use when constructing the Uuid + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to Unix timestamps + */ + public function __construct( + NumberConverterInterface $numberConverter, + TimeConverterInterface $timeConverter + ) { + $this->numberConverter = $numberConverter; + $this->timeConverter = $timeConverter; + } + + /** + * Builds and returns a Uuid + * + * @param CodecInterface $codec The codec to use for building this Uuid instance + * @param string $bytes The byte string from which to construct a UUID + * + * @return Rfc4122UuidInterface UuidBuilder returns instances of Rfc4122UuidInterface + * + * @psalm-pure + */ + public function build(CodecInterface $codec, string $bytes): UuidInterface + { + try { + $fields = $this->buildFields($bytes); + + if ($fields->isNil()) { + return new NilUuid($fields, $this->numberConverter, $codec, $this->timeConverter); + } + + switch ($fields->getVersion()) { + case 1: + return new UuidV1($fields, $this->numberConverter, $codec, $this->timeConverter); + case 2: + return new UuidV2($fields, $this->numberConverter, $codec, $this->timeConverter); + case 3: + return new UuidV3($fields, $this->numberConverter, $codec, $this->timeConverter); + case 4: + return new UuidV4($fields, $this->numberConverter, $codec, $this->timeConverter); + case 5: + return new UuidV5($fields, $this->numberConverter, $codec, $this->timeConverter); + case 6: + return new UuidV6($fields, $this->numberConverter, $codec, $this->timeConverter); + } + + throw new UnsupportedOperationException( + 'The UUID version in the given fields is not supported ' + . 'by this UUID builder' + ); + } catch (Throwable $e) { + throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e); + } + } + + /** + * Proxy method to allow injecting a mock, for testing + */ + protected function buildFields(string $bytes): FieldsInterface + { + return new Fields($bytes); + } +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/UuidInterface.php b/vendor/ramsey/uuid/src/Rfc4122/UuidInterface.php new file mode 100644 index 000000000..3e4d9faee --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/UuidInterface.php @@ -0,0 +1,36 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\UuidInterface as BaseUuidInterface; + +/** + * Also known as a Leach-Salz variant UUID, an RFC 4122 variant UUID is a + * universally unique identifier defined by RFC 4122 + * + * @link https://tools.ietf.org/html/rfc4122 RFC 4122 + * + * @psalm-immutable + */ +interface UuidInterface extends BaseUuidInterface +{ + /** + * Returns the string standard representation of the UUID as a URN + * + * @link http://en.wikipedia.org/wiki/Uniform_Resource_Name Uniform Resource Name + * @link https://tools.ietf.org/html/rfc4122#section-3 RFC 4122, § 3: Namespace Registration Template + */ + public function getUrn(): string; +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/UuidV1.php b/vendor/ramsey/uuid/src/Rfc4122/UuidV1.php new file mode 100644 index 000000000..764e42f84 --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/UuidV1.php @@ -0,0 +1,92 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use DateTimeImmutable; +use DateTimeInterface; +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\DateTimeException; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Uuid; +use Throwable; + +use function str_pad; + +use const STR_PAD_LEFT; + +/** + * Time-based, or version 1, UUIDs include timestamp, clock sequence, and node + * values that are combined into a 128-bit unsigned integer + * + * @psalm-immutable + */ +final class UuidV1 extends Uuid implements UuidInterface +{ + /** + * Creates a version 1 (time-based) UUID + * + * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID + * @param NumberConverterInterface $numberConverter The number converter to use + * for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding + * UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to unix timestamps + */ + public function __construct( + Rfc4122FieldsInterface $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter + ) { + if ($fields->getVersion() !== Uuid::UUID_TYPE_TIME) { + throw new InvalidArgumentException( + 'Fields used to create a UuidV1 must represent a ' + . 'version 1 (time-based) UUID' + ); + } + + parent::__construct($fields, $numberConverter, $codec, $timeConverter); + } + + /** + * Returns a DateTimeInterface object representing the timestamp associated + * with the UUID + * + * The timestamp value is only meaningful in a time-based UUID, which + * has version type 1. + * + * @return DateTimeImmutable A PHP DateTimeImmutable instance representing + * the timestamp of a version 1 UUID + */ + public function getDateTime(): DateTimeInterface + { + $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); + + try { + return new DateTimeImmutable( + '@' + . $time->getSeconds()->toString() + . '.' + . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) + ); + } catch (Throwable $e) { + throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); + } + } +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/UuidV2.php b/vendor/ramsey/uuid/src/Rfc4122/UuidV2.php new file mode 100644 index 000000000..74906f050 --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/UuidV2.php @@ -0,0 +1,143 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use DateTimeImmutable; +use DateTimeInterface; +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\DateTimeException; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\Uuid; +use Throwable; + +use function hexdec; +use function str_pad; + +use const STR_PAD_LEFT; + +/** + * DCE Security version, or version 2, UUIDs include local domain identifier, + * local ID for the specified domain, and node values that are combined into a + * 128-bit unsigned integer + * + * @link https://publications.opengroup.org/c311 DCE 1.1: Authentication and Security Services + * @link https://publications.opengroup.org/c706 DCE 1.1: Remote Procedure Call + * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01 DCE 1.1: Auth & Sec, §5.2.1.1 + * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1: Auth & Sec, §11.5.1.1 + * @link https://pubs.opengroup.org/onlinepubs/9629399/apdxa.htm DCE 1.1: RPC, Appendix A + * @link https://github.com/google/uuid Go package for UUIDs (includes DCE implementation) + * + * @psalm-immutable + */ +final class UuidV2 extends Uuid implements UuidInterface +{ + /** + * Creates a version 2 (DCE Security) UUID + * + * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID + * @param NumberConverterInterface $numberConverter The number converter to use + * for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding + * UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to unix timestamps + */ + public function __construct( + Rfc4122FieldsInterface $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter + ) { + if ($fields->getVersion() !== Uuid::UUID_TYPE_DCE_SECURITY) { + throw new InvalidArgumentException( + 'Fields used to create a UuidV2 must represent a ' + . 'version 2 (DCE Security) UUID' + ); + } + + parent::__construct($fields, $numberConverter, $codec, $timeConverter); + } + + /** + * Returns a DateTimeInterface object representing the timestamp associated + * with the UUID + * + * It is important to note that a version 2 UUID suffers from some loss of + * fidelity of the timestamp, due to replacing the time_low field with the + * local identifier. When constructing the timestamp value for date + * purposes, we replace the local identifier bits with zeros. As a result, + * the timestamp can be off by a range of 0 to 429.4967295 seconds (or 7 + * minutes, 9 seconds, and 496730 microseconds). + * + * Astute observers might note this value directly corresponds to 2^32 - 1, + * or 0xffffffff. The local identifier is 32-bits, and we have set each of + * these bits to 0, so the maximum range of timestamp drift is 0x00000000 + * to 0xffffffff (counted in 100-nanosecond intervals). + * + * @return DateTimeImmutable A PHP DateTimeImmutable instance representing + * the timestamp of a version 2 UUID + */ + public function getDateTime(): DateTimeInterface + { + $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); + + try { + return new DateTimeImmutable( + '@' + . $time->getSeconds()->toString() + . '.' + . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) + ); + } catch (Throwable $e) { + throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); + } + } + + /** + * Returns the local domain used to create this version 2 UUID + */ + public function getLocalDomain(): int + { + /** @var Rfc4122FieldsInterface $fields */ + $fields = $this->getFields(); + + return (int) hexdec($fields->getClockSeqLow()->toString()); + } + + /** + * Returns the string name of the local domain + */ + public function getLocalDomainName(): string + { + return Uuid::DCE_DOMAIN_NAMES[$this->getLocalDomain()]; + } + + /** + * Returns the local identifier for the domain used to create this version 2 UUID + */ + public function getLocalIdentifier(): IntegerObject + { + /** @var Rfc4122FieldsInterface $fields */ + $fields = $this->getFields(); + + return new IntegerObject( + $this->numberConverter->fromHex($fields->getTimeLow()->toString()) + ); + } +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/UuidV3.php b/vendor/ramsey/uuid/src/Rfc4122/UuidV3.php new file mode 100644 index 000000000..deaa54eb0 --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/UuidV3.php @@ -0,0 +1,58 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Uuid; + +/** + * Version 3 UUIDs are named-based, using combination of a namespace and name + * that are hashed into a 128-bit unsigned integer using MD5 + * + * @psalm-immutable + */ +final class UuidV3 extends Uuid implements UuidInterface +{ + /** + * Creates a version 3 (name-based, MD5-hashed) UUID + * + * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID + * @param NumberConverterInterface $numberConverter The number converter to use + * for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding + * UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to unix timestamps + */ + public function __construct( + Rfc4122FieldsInterface $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter + ) { + if ($fields->getVersion() !== Uuid::UUID_TYPE_HASH_MD5) { + throw new InvalidArgumentException( + 'Fields used to create a UuidV3 must represent a ' + . 'version 3 (name-based, MD5-hashed) UUID' + ); + } + + parent::__construct($fields, $numberConverter, $codec, $timeConverter); + } +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/UuidV4.php b/vendor/ramsey/uuid/src/Rfc4122/UuidV4.php new file mode 100644 index 000000000..2e5724620 --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/UuidV4.php @@ -0,0 +1,58 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Uuid; + +/** + * Random, or version 4, UUIDs are randomly or pseudo-randomly generated 128-bit + * integers + * + * @psalm-immutable + */ +final class UuidV4 extends Uuid implements UuidInterface +{ + /** + * Creates a version 4 (random) UUID + * + * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID + * @param NumberConverterInterface $numberConverter The number converter to use + * for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding + * UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to unix timestamps + */ + public function __construct( + Rfc4122FieldsInterface $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter + ) { + if ($fields->getVersion() !== Uuid::UUID_TYPE_RANDOM) { + throw new InvalidArgumentException( + 'Fields used to create a UuidV4 must represent a ' + . 'version 4 (random) UUID' + ); + } + + parent::__construct($fields, $numberConverter, $codec, $timeConverter); + } +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/UuidV5.php b/vendor/ramsey/uuid/src/Rfc4122/UuidV5.php new file mode 100644 index 000000000..2ef6ab3f1 --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/UuidV5.php @@ -0,0 +1,58 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Codec\CodecInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Uuid; + +/** + * Version 5 UUIDs are named-based, using combination of a namespace and name + * that are hashed into a 128-bit unsigned integer using SHA1 + * + * @psalm-immutable + */ +final class UuidV5 extends Uuid implements UuidInterface +{ + /** + * Creates a version 5 (name-based, SHA1-hashed) UUID + * + * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID + * @param NumberConverterInterface $numberConverter The number converter to use + * for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding + * UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to unix timestamps + */ + public function __construct( + Rfc4122FieldsInterface $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter + ) { + if ($fields->getVersion() !== Uuid::UUID_TYPE_HASH_SHA1) { + throw new InvalidArgumentException( + 'Fields used to create a UuidV5 must represent a ' + . 'version 5 (named-based, SHA1-hashed) UUID' + ); + } + + parent::__construct($fields, $numberConverter, $codec, $timeConverter); + } +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/Validator.php b/vendor/ramsey/uuid/src/Rfc4122/Validator.php new file mode 100644 index 000000000..ed43c982f --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/Validator.php @@ -0,0 +1,49 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Uuid; +use Ramsey\Uuid\Validator\ValidatorInterface; + +use function preg_match; +use function str_replace; + +/** + * Rfc4122\Validator validates strings as UUIDs of the RFC 4122 variant + * + * @psalm-immutable + */ +final class Validator implements ValidatorInterface +{ + private const VALID_PATTERN = '\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-' + . '[1-5]{1}[0-9A-Fa-f]{3}-[ABab89]{1}[0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\z'; + + /** + * @psalm-return non-empty-string + * @psalm-suppress MoreSpecificReturnType we know that the retrieved `string` is never empty + * @psalm-suppress LessSpecificReturnStatement we know that the retrieved `string` is never empty + */ + public function getPattern(): string + { + return self::VALID_PATTERN; + } + + public function validate(string $uuid): bool + { + $uuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid); + + return $uuid === Uuid::NIL || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); + } +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/VariantTrait.php b/vendor/ramsey/uuid/src/Rfc4122/VariantTrait.php new file mode 100644 index 000000000..c32a8ce80 --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/VariantTrait.php @@ -0,0 +1,89 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +use Ramsey\Uuid\Exception\InvalidBytesException; +use Ramsey\Uuid\Uuid; + +use function decbin; +use function str_pad; +use function strlen; +use function strpos; +use function substr; +use function unpack; + +use const STR_PAD_LEFT; + +/** + * Provides common functionality for handling the variant, as defined by RFC 4122 + * + * @psalm-immutable + */ +trait VariantTrait +{ + /** + * Returns the bytes that comprise the fields + */ + abstract public function getBytes(): string; + + /** + * Returns the variant identifier, according to RFC 4122, for the given bytes + * + * The following values may be returned: + * + * - `0` -- Reserved, NCS backward compatibility. + * - `2` -- The variant specified in RFC 4122. + * - `6` -- Reserved, Microsoft Corporation backward compatibility. + * - `7` -- Reserved for future definition. + * + * @link https://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant + * + * @return int The variant identifier, according to RFC 4122 + */ + public function getVariant(): int + { + if (strlen($this->getBytes()) !== 16) { + throw new InvalidBytesException('Invalid number of bytes'); + } + + $parts = unpack('n*', $this->getBytes()); + + // $parts[5] is a 16-bit, unsigned integer containing the variant bits + // of the UUID. We convert this integer into a string containing a + // binary representation, padded to 16 characters. We analyze the first + // three characters (three most-significant bits) to determine the + // variant. + $binary = str_pad( + decbin((int) $parts[5]), + 16, + '0', + STR_PAD_LEFT + ); + + $msb = substr($binary, 0, 3); + + if ($msb === '111') { + $variant = Uuid::RESERVED_FUTURE; + } elseif ($msb === '110') { + $variant = Uuid::RESERVED_MICROSOFT; + } elseif (strpos($msb, '10') === 0) { + $variant = Uuid::RFC_4122; + } else { + $variant = Uuid::RESERVED_NCS; + } + + return $variant; + } +} diff --git a/vendor/ramsey/uuid/src/Rfc4122/VersionTrait.php b/vendor/ramsey/uuid/src/Rfc4122/VersionTrait.php new file mode 100644 index 000000000..cee55fbef --- /dev/null +++ b/vendor/ramsey/uuid/src/Rfc4122/VersionTrait.php @@ -0,0 +1,57 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Rfc4122; + +/** + * Provides common functionality for handling the version, as defined by RFC 4122 + * + * @psalm-immutable + */ +trait VersionTrait +{ + /** + * Returns the version + */ + abstract public function getVersion(): ?int; + + /** + * Returns true if these fields represent a nil UUID + */ + abstract public function isNil(): bool; + + /** + * Returns true if the version matches one of those defined by RFC 4122 + * + * @return bool True if the UUID version is valid, false otherwise + */ + private function isCorrectVersion(): bool + { + if ($this->isNil()) { + return true; + } + + switch ($this->getVersion()) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + return true; + } + + return false; + } +} diff --git a/vendor/ramsey/uuid/src/Type/Decimal.php b/vendor/ramsey/uuid/src/Type/Decimal.php new file mode 100644 index 000000000..5ba886535 --- /dev/null +++ b/vendor/ramsey/uuid/src/Type/Decimal.php @@ -0,0 +1,112 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Type; + +use Ramsey\Uuid\Exception\InvalidArgumentException; + +use function is_numeric; + +/** + * A value object representing a decimal + * + * This class exists for type-safety purposes, to ensure that decimals + * returned from ramsey/uuid methods as strings are truly decimals and not some + * other kind of string. + * + * To support values as true decimals and not as floats or doubles, we store the + * decimals as strings. + * + * @psalm-immutable + */ +final class Decimal implements NumberInterface +{ + /** + * @var string + */ + private $value; + + /** + * @var bool + */ + private $isNegative = false; + + /** + * @param mixed $value The decimal value to store + */ + public function __construct($value) + { + $value = (string) $value; + + if (!is_numeric($value)) { + throw new InvalidArgumentException( + 'Value must be a signed decimal or a string containing only ' + . 'digits 0-9 and, optionally, a decimal point or sign (+ or -)' + ); + } + + // Remove the leading +-symbol. + if (strpos($value, '+') === 0) { + $value = substr($value, 1); + } + + // For cases like `-0` or `-0.0000`, convert the value to `0`. + if (abs((float) $value) === 0.0) { + $value = '0'; + } + + if (strpos($value, '-') === 0) { + $this->isNegative = true; + } + + $this->value = $value; + } + + public function isNegative(): bool + { + return $this->isNegative; + } + + public function toString(): string + { + return $this->value; + } + + public function __toString(): string + { + return $this->toString(); + } + + public function jsonSerialize(): string + { + return $this->toString(); + } + + public function serialize(): string + { + return $this->toString(); + } + + /** + * Constructs the object from a serialized string representation + * + * @param string $serialized The serialized string representation of the object + * + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + */ + public function unserialize($serialized): void + { + $this->__construct($serialized); + } +} diff --git a/vendor/ramsey/uuid/src/Type/Hexadecimal.php b/vendor/ramsey/uuid/src/Type/Hexadecimal.php new file mode 100644 index 000000000..11450186e --- /dev/null +++ b/vendor/ramsey/uuid/src/Type/Hexadecimal.php @@ -0,0 +1,91 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Type; + +use Ramsey\Uuid\Exception\InvalidArgumentException; + +use function ctype_xdigit; +use function strpos; +use function strtolower; +use function substr; + +/** + * A value object representing a hexadecimal number + * + * This class exists for type-safety purposes, to ensure that hexadecimal numbers + * returned from ramsey/uuid methods as strings are truly hexadecimal and not some + * other kind of string. + * + * @psalm-immutable + */ +final class Hexadecimal implements TypeInterface +{ + /** + * @var string + */ + private $value; + + /** + * @param string $value The hexadecimal value to store + */ + public function __construct(string $value) + { + $value = strtolower($value); + + if (strpos($value, '0x') === 0) { + $value = substr($value, 2); + } + + if (!ctype_xdigit($value)) { + throw new InvalidArgumentException( + 'Value must be a hexadecimal number' + ); + } + + $this->value = $value; + } + + public function toString(): string + { + return $this->value; + } + + public function __toString(): string + { + return $this->toString(); + } + + public function jsonSerialize(): string + { + return $this->toString(); + } + + public function serialize(): string + { + return $this->toString(); + } + + /** + * Constructs the object from a serialized string representation + * + * @param string $serialized The serialized string representation of the object + * + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + */ + public function unserialize($serialized): void + { + $this->__construct($serialized); + } +} diff --git a/vendor/ramsey/uuid/src/Type/Integer.php b/vendor/ramsey/uuid/src/Type/Integer.php new file mode 100644 index 000000000..05d420a85 --- /dev/null +++ b/vendor/ramsey/uuid/src/Type/Integer.php @@ -0,0 +1,122 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Type; + +use Ramsey\Uuid\Exception\InvalidArgumentException; + +use function ctype_digit; +use function ltrim; +use function strpos; +use function substr; + +/** + * A value object representing an integer + * + * This class exists for type-safety purposes, to ensure that integers + * returned from ramsey/uuid methods as strings are truly integers and not some + * other kind of string. + * + * To support large integers beyond PHP_INT_MAX and PHP_INT_MIN on both 64-bit + * and 32-bit systems, we store the integers as strings. + * + * @psalm-immutable + */ +final class Integer implements NumberInterface +{ + /** + * @var string + */ + private $value; + + /** + * @var bool + */ + private $isNegative = false; + + /** + * @param mixed $value The integer value to store + */ + public function __construct($value) + { + $value = (string) $value; + $sign = '+'; + + // If the value contains a sign, remove it for ctype_digit() check. + if (strpos($value, '-') === 0 || strpos($value, '+') === 0) { + $sign = substr($value, 0, 1); + $value = substr($value, 1); + } + + if (!ctype_digit($value)) { + throw new InvalidArgumentException( + 'Value must be a signed integer or a string containing only ' + . 'digits 0-9 and, optionally, a sign (+ or -)' + ); + } + + // Trim any leading zeros. + $value = ltrim($value, '0'); + + // Set to zero if the string is empty after trimming zeros. + if ($value === '') { + $value = '0'; + } + + // Add the negative sign back to the value. + if ($sign === '-' && $value !== '0') { + $value = $sign . $value; + $this->isNegative = true; + } + + $this->value = $value; + } + + public function isNegative(): bool + { + return $this->isNegative; + } + + public function toString(): string + { + return $this->value; + } + + public function __toString(): string + { + return $this->toString(); + } + + public function jsonSerialize(): string + { + return $this->toString(); + } + + public function serialize(): string + { + return $this->toString(); + } + + /** + * Constructs the object from a serialized string representation + * + * @param string $serialized The serialized string representation of the object + * + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + */ + public function unserialize($serialized): void + { + $this->__construct($serialized); + } +} diff --git a/vendor/ramsey/uuid/src/Type/NumberInterface.php b/vendor/ramsey/uuid/src/Type/NumberInterface.php new file mode 100644 index 000000000..bf4ae9db8 --- /dev/null +++ b/vendor/ramsey/uuid/src/Type/NumberInterface.php @@ -0,0 +1,28 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Type; + +/** + * NumberInterface ensures consistency in numeric values returned by ramsey/uuid + * + * @psalm-immutable + */ +interface NumberInterface extends TypeInterface +{ + /** + * Returns true if this number is less than zero + */ + public function isNegative(): bool; +} diff --git a/vendor/ramsey/uuid/src/Type/Time.php b/vendor/ramsey/uuid/src/Type/Time.php new file mode 100644 index 000000000..f6a140f05 --- /dev/null +++ b/vendor/ramsey/uuid/src/Type/Time.php @@ -0,0 +1,111 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Type; + +use Ramsey\Uuid\Exception\UnsupportedOperationException; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use stdClass; + +use function json_decode; +use function json_encode; + +/** + * A value object representing a timestamp + * + * This class exists for type-safety purposes, to ensure that timestamps used + * by ramsey/uuid are truly timestamp integers and not some other kind of string + * or integer. + * + * @psalm-immutable + */ +final class Time implements TypeInterface +{ + /** + * @var IntegerObject + */ + private $seconds; + + /** + * @var IntegerObject + */ + private $microseconds; + + /** + * @param mixed $seconds + * @param mixed $microseconds + */ + public function __construct($seconds, $microseconds = 0) + { + $this->seconds = new IntegerObject($seconds); + $this->microseconds = new IntegerObject($microseconds); + } + + public function getSeconds(): IntegerObject + { + return $this->seconds; + } + + public function getMicroseconds(): IntegerObject + { + return $this->microseconds; + } + + public function toString(): string + { + return $this->seconds->toString() . '.' . $this->microseconds->toString(); + } + + public function __toString(): string + { + return $this->toString(); + } + + /** + * @return string[] + */ + public function jsonSerialize(): array + { + return [ + 'seconds' => $this->getSeconds()->toString(), + 'microseconds' => $this->getMicroseconds()->toString(), + ]; + } + + public function serialize(): string + { + return (string) json_encode($this); + } + + /** + * Constructs the object from a serialized string representation + * + * @param string $serialized The serialized string representation of the object + * + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint + */ + public function unserialize($serialized): void + { + /** @var stdClass $time */ + $time = json_decode($serialized); + + if (!isset($time->seconds) || !isset($time->microseconds)) { + throw new UnsupportedOperationException( + 'Attempted to unserialize an invalid value' + ); + } + + $this->__construct($time->seconds, $time->microseconds); + } +} diff --git a/vendor/ramsey/uuid/src/Type/TypeInterface.php b/vendor/ramsey/uuid/src/Type/TypeInterface.php new file mode 100644 index 000000000..da2d8b203 --- /dev/null +++ b/vendor/ramsey/uuid/src/Type/TypeInterface.php @@ -0,0 +1,30 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Type; + +use JsonSerializable; +use Serializable; + +/** + * TypeInterface ensures consistency in typed values returned by ramsey/uuid + * + * @psalm-immutable + */ +interface TypeInterface extends JsonSerializable, Serializable +{ + public function toString(): string; + + public function __toString(): string; +} diff --git a/vendor/ramsey/uuid/src/Uuid.php b/vendor/ramsey/uuid/src/Uuid.php index f2912b48a..762dfdbae 100644 --- a/vendor/ramsey/uuid/src/Uuid.php +++ b/vendor/ramsey/uuid/src/Uuid.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,161 +8,228 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid; -use DateTime; -use Exception; -use InvalidArgumentException; -use Ramsey\Uuid\Converter\NumberConverterInterface; +use DateTimeInterface; use Ramsey\Uuid\Codec\CodecInterface; -use Ramsey\Uuid\Exception\InvalidUuidStringException; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; -use Ramsey\Uuid\Exception\UnsupportedOperationException; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Fields\FieldsInterface; +use Ramsey\Uuid\Lazy\LazyUuidFromString; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; + +use function bin2hex; +use function preg_match; +use function str_replace; +use function strcmp; +use function strlen; +use function strtolower; +use function substr; /** - * Represents a universally unique identifier (UUID), according to RFC 4122. + * Uuid provides constants and static methods for working with and generating UUIDs * - * This class provides immutable UUID objects (the Uuid class) and the static - * methods `uuid1()`, `uuid3()`, `uuid4()`, and `uuid5()` for generating version - * 1, 3, 4, and 5 UUIDs as specified in RFC 4122. - * - * If all you want is a unique ID, you should probably call `uuid1()` or `uuid4()`. - * Note that `uuid1()` may compromise privacy since it creates a UUID containing - * the computer’s network address. `uuid4()` creates a random UUID. - * - * @link http://tools.ietf.org/html/rfc4122 - * @link http://en.wikipedia.org/wiki/Universally_unique_identifier - * @link http://docs.python.org/3/library/uuid.html - * @link http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html + * @psalm-immutable */ class Uuid implements UuidInterface { + use DeprecatedUuidMethodsTrait; + /** - * When this namespace is specified, the name string is a fully-qualified domain name. - * @link http://tools.ietf.org/html/rfc4122#appendix-C + * When this namespace is specified, the name string is a fully-qualified + * domain name + * + * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs */ - const NAMESPACE_DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; + public const NAMESPACE_DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; /** - * When this namespace is specified, the name string is a URL. - * @link http://tools.ietf.org/html/rfc4122#appendix-C + * When this namespace is specified, the name string is a URL + * + * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs */ - const NAMESPACE_URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; + public const NAMESPACE_URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; /** - * When this namespace is specified, the name string is an ISO OID. - * @link http://tools.ietf.org/html/rfc4122#appendix-C + * When this namespace is specified, the name string is an ISO OID + * + * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs */ - const NAMESPACE_OID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8'; + public const NAMESPACE_OID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8'; /** - * When this namespace is specified, the name string is an X.500 DN in DER or a text output format. - * @link http://tools.ietf.org/html/rfc4122#appendix-C + * When this namespace is specified, the name string is an X.500 DN in DER + * or a text output format + * + * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs */ - const NAMESPACE_X500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8'; + public const NAMESPACE_X500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8'; /** - * The nil UUID is special form of UUID that is specified to have all 128 bits set to zero. - * @link http://tools.ietf.org/html/rfc4122#section-4.1.7 + * The nil UUID is a special form of UUID that is specified to have all 128 + * bits set to zero + * + * @link http://tools.ietf.org/html/rfc4122#section-4.1.7 RFC 4122, § 4.1.7: Nil UUID */ - const NIL = '00000000-0000-0000-0000-000000000000'; + public const NIL = '00000000-0000-0000-0000-000000000000'; /** - * Reserved for NCS compatibility. - * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 + * Variant: reserved, NCS backward compatibility + * + * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant */ - const RESERVED_NCS = 0; + public const RESERVED_NCS = 0; /** - * Specifies the UUID layout given in RFC 4122. - * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 + * Variant: the UUID layout specified in RFC 4122 + * + * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant */ - const RFC_4122 = 2; + public const RFC_4122 = 2; /** - * Reserved for Microsoft compatibility. - * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 + * Variant: reserved, Microsoft Corporation backward compatibility + * + * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant */ - const RESERVED_MICROSOFT = 6; + public const RESERVED_MICROSOFT = 6; /** - * Reserved for future definition. - * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 + * Variant: reserved for future definition + * + * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant */ - const RESERVED_FUTURE = 7; + public const RESERVED_FUTURE = 7; /** - * Regular expression pattern for matching a valid UUID of any variant. + * @deprecated Use {@see ValidatorInterface::getPattern()} instead. */ - 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}$'; + 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}$'; /** - * Version 1 (time-based) UUID object constant identifier + * Version 1 (time-based) UUID + * + * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version */ - const UUID_TYPE_TIME = 1; + public const UUID_TYPE_TIME = 1; /** - * Version 2 (identifier-based) UUID object constant identifier + * Version 2 (DCE Security) UUID + * + * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version */ - const UUID_TYPE_IDENTIFIER = 2; + public const UUID_TYPE_DCE_SECURITY = 2; /** - * Version 3 (name-based and hashed with MD5) UUID object constant identifier + * @deprecated Use {@see Uuid::UUID_TYPE_DCE_SECURITY} instead. + */ + public const UUID_TYPE_IDENTIFIER = 2; + + /** + * Version 3 (name-based and hashed with MD5) UUID + * + * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version */ - const UUID_TYPE_HASH_MD5 = 3; + public const UUID_TYPE_HASH_MD5 = 3; /** - * Version 4 (random) UUID object constant identifier + * Version 4 (random) UUID + * + * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version */ - const UUID_TYPE_RANDOM = 4; + public const UUID_TYPE_RANDOM = 4; /** - * Version 5 (name-based and hashed with SHA1) UUID object constant identifier + * Version 5 (name-based and hashed with SHA1) UUID + * + * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version */ - const UUID_TYPE_HASH_SHA1 = 5; + public const UUID_TYPE_HASH_SHA1 = 5; /** - * The factory to use when creating UUIDs. - * @var UuidFactoryInterface + * Version 6 (ordered-time) UUID + * + * This is named `UUID_TYPE_PEABODY`, since the specification is still in + * draft form, and the primary author/editor's name is Brad Peabody. + * + * @link https://github.com/uuid6/uuid6-ietf-draft UUID version 6 IETF draft + * @link http://gh.peabody.io/uuidv6/ "Version 6" UUIDs + */ + public const UUID_TYPE_PEABODY = 6; + + /** + * DCE Security principal domain + * + * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1 + */ + public const DCE_DOMAIN_PERSON = 0; + + /** + * DCE Security group domain + * + * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1 + */ + public const DCE_DOMAIN_GROUP = 1; + + /** + * DCE Security organization domain + * + * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1 + */ + public const DCE_DOMAIN_ORG = 2; + + /** + * DCE Security domain string names + * + * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1 + */ + public const DCE_DOMAIN_NAMES = [ + self::DCE_DOMAIN_PERSON => 'person', + self::DCE_DOMAIN_GROUP => 'group', + self::DCE_DOMAIN_ORG => 'org', + ]; + + /** + * @var UuidFactoryInterface|null */ private static $factory = null; /** - * The codec to use when encoding or decoding UUID strings. + * @var bool flag to detect if the UUID factory was replaced internally, which disables all optimizations + * for the default/happy path internal scenarios + */ + private static $factoryReplaced = false; + + /** * @var CodecInterface */ protected $codec; /** - * The fields that make up this UUID. - * - * This is initialized to the nil value. + * The fields that make up this UUID * - * @var array - * @see UuidInterface::getFieldsHex() + * @var Rfc4122FieldsInterface */ - protected $fields = [ - 'time_low' => '00000000', - 'time_mid' => '0000', - 'time_hi_and_version' => '0000', - 'clock_seq_hi_and_reserved' => '00', - 'clock_seq_low' => '00', - 'node' => '000000000000', - ]; + protected $fields; /** - * The number converter to use for converting hex values to/from integers. * @var NumberConverterInterface */ - protected $converter; + protected $numberConverter; + + /** + * @var TimeConverterInterface + */ + protected $timeConverter; /** - * Creates a universally unique identifier (UUID) from an array of fields. + * Creates a universally unique identifier (UUID) from an array of fields * * Unless you're making advanced use of this library to generate identifiers * that deviate from RFC 4122, you probably do not want to instantiate a @@ -176,576 +244,394 @@ class Uuid implements UuidInterface * $namespaceSha1Uuid = Uuid::uuid5(Uuid::NAMESPACE_URL, 'http://php.net/'); * ``` * - * @param array $fields An array of fields from which to construct a UUID; - * see {@see \Ramsey\Uuid\UuidInterface::getFieldsHex()} for array structure. - * @param NumberConverterInterface $converter The number converter to use - * for converting hex values to/from integers. + * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID + * @param NumberConverterInterface $numberConverter The number converter to use + * for converting hex values to/from integers * @param CodecInterface $codec The codec to use when encoding or decoding - * UUID strings. + * UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use + * for converting timestamps extracted from a UUID to unix timestamps */ public function __construct( - array $fields, - NumberConverterInterface $converter, - CodecInterface $codec + Rfc4122FieldsInterface $fields, + NumberConverterInterface $numberConverter, + CodecInterface $codec, + TimeConverterInterface $timeConverter ) { $this->fields = $fields; $this->codec = $codec; - $this->converter = $converter; + $this->numberConverter = $numberConverter; + $this->timeConverter = $timeConverter; } /** - * Converts this UUID object to a string when the object is used in any - * string context. - * - * @return string - * @link http://www.php.net/manual/en/language.oop5.magic.php#object.tostring + * @psalm-return non-empty-string */ - public function __toString() + public function __toString(): string { return $this->toString(); } /** - * Converts this UUID object to a string when the object is serialized - * with `json_encode()` - * - * @return string - * @link http://php.net/manual/en/class.jsonserializable.php + * Converts the UUID to a string for JSON serialization */ - public function jsonSerialize() + public function jsonSerialize(): string { return $this->toString(); } /** - * Converts this UUID object to a string when the object is serialized - * with `serialize()` - * - * @return string - * @link http://php.net/manual/en/class.serializable.php + * Converts the UUID to a string for PHP serialization */ - public function serialize() + public function serialize(): string { - return $this->toString(); + return $this->getBytes(); } /** - * Re-constructs the object from its serialized form. + * Re-constructs the object from its serialized form + * + * @param string $serialized The serialized PHP string to unserialize into + * a UuidInterface instance * - * @param string $serialized - * @link http://php.net/manual/en/class.serializable.php - * @throws InvalidUuidStringException + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint */ - public function unserialize($serialized) + public function unserialize($serialized): void { - $uuid = self::fromString($serialized); + if (strlen($serialized) === 16) { + /** @var Uuid $uuid */ + $uuid = self::getFactory()->fromBytes($serialized); + } else { + /** @var Uuid $uuid */ + $uuid = self::getFactory()->fromString($serialized); + } + $this->codec = $uuid->codec; - $this->converter = $uuid->converter; + $this->numberConverter = $uuid->numberConverter; $this->fields = $uuid->fields; + $this->timeConverter = $uuid->timeConverter; } - public function compareTo(UuidInterface $other) + public function compareTo(UuidInterface $other): int { - if ($this->getMostSignificantBitsHex() < $other->getMostSignificantBitsHex()) { - return -1; - } - - if ($this->getMostSignificantBitsHex() > $other->getMostSignificantBitsHex()) { - return 1; - } + $compare = strcmp($this->toString(), $other->toString()); - if ($this->getLeastSignificantBitsHex() < $other->getLeastSignificantBitsHex()) { + if ($compare < 0) { return -1; } - if ($this->getLeastSignificantBitsHex() > $other->getLeastSignificantBitsHex()) { + if ($compare > 0) { return 1; } return 0; } - public function equals($other) + public function equals(?object $other): bool { if (!$other instanceof UuidInterface) { return false; } - return $this->compareTo($other) == 0; - } - - public function getBytes() - { - return $this->codec->encodeBinary($this); + return $this->compareTo($other) === 0; } /** - * Returns the high field of the clock sequence multiplexed with the variant - * (bits 65-72 of the UUID). - * - * @return int Unsigned 8-bit integer value of clock_seq_hi_and_reserved + * @psalm-return non-empty-string */ - public function getClockSeqHiAndReserved() + public function getBytes(): string { - return hexdec($this->getClockSeqHiAndReservedHex()); + return $this->codec->encodeBinary($this); } - public function getClockSeqHiAndReservedHex() + public function getFields(): FieldsInterface { - return $this->fields['clock_seq_hi_and_reserved']; + return $this->fields; } - /** - * Returns the low field of the clock sequence (bits 73-80 of the UUID). - * - * @return int Unsigned 8-bit integer value of clock_seq_low - */ - public function getClockSeqLow() + public function getHex(): Hexadecimal { - return hexdec($this->getClockSeqLowHex()); + return new Hexadecimal(str_replace('-', '', $this->toString())); } - public function getClockSeqLowHex() + public function getInteger(): IntegerObject { - return $this->fields['clock_seq_low']; + return new IntegerObject($this->numberConverter->fromHex($this->getHex()->toString())); } /** - * Returns the clock sequence value associated with this UUID. - * - * For UUID version 1, the clock sequence is used to help avoid - * duplicates that could arise when the clock is set backwards in time - * or if the node ID changes. - * - * For UUID version 3 or 5, the clock sequence is a 14-bit value - * constructed from a name as described in RFC 4122, Section 4.3. - * - * For UUID version 4, clock sequence is a randomly or pseudo-randomly - * generated 14-bit value as described in RFC 4122, Section 4.4. - * - * @return int Unsigned 14-bit integer value of clock sequence - * @link http://tools.ietf.org/html/rfc4122#section-4.1.5 + * @psalm-return non-empty-string */ - public function getClockSequence() - { - return ($this->getClockSeqHiAndReserved() & 0x3f) << 8 | $this->getClockSeqLow(); - } - - public function getClockSequenceHex() - { - return sprintf('%04x', $this->getClockSequence()); - } - - public function getNumberConverter() + public function toString(): string { - return $this->converter; + return $this->codec->encode($this); } /** - * @inheritdoc + * Returns the factory used to create UUIDs */ - public function getDateTime() + public static function getFactory(): UuidFactoryInterface { - if ($this->getVersion() != 1) { - throw new UnsupportedOperationException('Not a time-based UUID'); + if (self::$factory === null) { + self::$factory = new UuidFactory(); } - $unixTimeNanoseconds = $this->getTimestamp() - 0x01b21dd213814000; - $unixTime = ($unixTimeNanoseconds - $unixTimeNanoseconds % 1e7) / 1e7; - - return new DateTime("@{$unixTime}"); + return self::$factory; } /** - * Returns an array of the fields of this UUID, with keys named according - * to the RFC 4122 names for the fields. - * - * * **time_low**: The low field of the timestamp, an unsigned 32-bit integer - * * **time_mid**: The middle field of the timestamp, an unsigned 16-bit integer - * * **time_hi_and_version**: The high field of the timestamp multiplexed with - * the version number, an unsigned 16-bit integer - * * **clock_seq_hi_and_reserved**: The high field of the clock sequence - * multiplexed with the variant, an unsigned 8-bit integer - * * **clock_seq_low**: The low field of the clock sequence, an unsigned - * 8-bit integer - * * **node**: The spatially unique node identifier, an unsigned 48-bit - * integer + * Sets the factory used to create UUIDs * - * @return array The UUID fields represented as integer values - * @link http://tools.ietf.org/html/rfc4122#section-4.1.2 + * @param UuidFactoryInterface $factory A factory that will be used by this + * class to create UUIDs */ - public function getFields() - { - return [ - 'time_low' => $this->getTimeLow(), - 'time_mid' => $this->getTimeMid(), - 'time_hi_and_version' => $this->getTimeHiAndVersion(), - 'clock_seq_hi_and_reserved' => $this->getClockSeqHiAndReserved(), - 'clock_seq_low' => $this->getClockSeqLow(), - 'node' => $this->getNode(), - ]; - } - - public function getFieldsHex() + public static function setFactory(UuidFactoryInterface $factory): void { - return $this->fields; - } - - public function getHex() - { - return str_replace('-', '', $this->toString()); - } + // Note: non-strict equality is intentional here. If the factory is configured differently, every assumption + // around purity is broken, and we have to internally decide everything differently. + // phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedNotEqualOperator + self::$factoryReplaced = ($factory != new UuidFactory()); - /** - * @inheritdoc - */ - public function getInteger() - { - return $this->converter->fromHex($this->getHex()); + self::$factory = $factory; } /** - * Returns the least significant 64 bits of this UUID's 128 bit value. + * Creates a UUID from a byte string * - * @return mixed Converted representation of the unsigned 64-bit integer value - * @throws UnsatisfiedDependencyException if `Moontoast\Math\BigNumber` is not present - */ - public function getLeastSignificantBits() - { - return $this->converter->fromHex($this->getLeastSignificantBitsHex()); - } - - public function getLeastSignificantBitsHex() - { - return sprintf( - '%02s%02s%012s', - $this->fields['clock_seq_hi_and_reserved'], - $this->fields['clock_seq_low'], - $this->fields['node'] - ); - } - - /** - * Returns the most significant 64 bits of this UUID's 128 bit value. + * @param string $bytes A binary string + * + * @return UuidInterface A UuidInterface instance created from a binary + * string representation + * + * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, + * but under constant factory setups, this method operates in functionally pure manners * - * @return mixed Converted representation of the unsigned 64-bit integer value - * @throws UnsatisfiedDependencyException if `Moontoast\Math\BigNumber` is not present + * @psalm-suppress ImpureStaticProperty we know that the factory being replaced can lead to massive + * havoc across all consumers: that should never happen, and + * is generally to be discouraged. Until the factory is kept + * un-replaced, this method is effectively pure. */ - public function getMostSignificantBits() + public static function fromBytes(string $bytes): UuidInterface { - return $this->converter->fromHex($this->getMostSignificantBitsHex()); - } + if (! self::$factoryReplaced && strlen($bytes) === 16) { + $base16Uuid = bin2hex($bytes); - public function getMostSignificantBitsHex() - { - return sprintf( - '%08s%04s%04s', - $this->fields['time_low'], - $this->fields['time_mid'], - $this->fields['time_hi_and_version'] - ); + // Note: we are calling `fromString` internally because we don't know if the given `$bytes` is a valid UUID + return self::fromString( + substr($base16Uuid, 0, 8) + . '-' + . substr($base16Uuid, 8, 4) + . '-' + . substr($base16Uuid, 12, 4) + . '-' + . substr($base16Uuid, 16, 4) + . '-' + . substr($base16Uuid, 20, 12) + ); + } + + return self::getFactory()->fromBytes($bytes); } /** - * Returns the node value associated with this UUID - * - * For UUID version 1, the node field consists of an IEEE 802 MAC - * address, usually the host address. For systems with multiple IEEE - * 802 addresses, any available one can be used. The lowest addressed - * octet (octet number 10) contains the global/local bit and the - * unicast/multicast bit, and is the first octet of the address - * transmitted on an 802.3 LAN. + * Creates a UUID from the string standard representation * - * For systems with no IEEE address, a randomly or pseudo-randomly - * generated value may be used; see RFC 4122, Section 4.5. The - * multicast bit must be set in such addresses, in order that they - * will never conflict with addresses obtained from network cards. + * @param string $uuid A hexadecimal string * - * For UUID version 3 or 5, the node field is a 48-bit value constructed - * from a name as described in RFC 4122, Section 4.3. + * @return UuidInterface A UuidInterface instance created from a hexadecimal + * string representation * - * For UUID version 4, the node field is a randomly or pseudo-randomly - * generated 48-bit value as described in RFC 4122, Section 4.4. + * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, + * but under constant factory setups, this method operates in functionally pure manners * - * @return int Unsigned 48-bit integer value of node - * @link http://tools.ietf.org/html/rfc4122#section-4.1.6 + * @psalm-suppress ImpureStaticProperty we know that the factory being replaced can lead to massive + * havoc across all consumers: that should never happen, and + * is generally to be discouraged. Until the factory is kept + * un-replaced, this method is effectively pure. */ - public function getNode() + public static function fromString(string $uuid): UuidInterface { - return hexdec($this->getNodeHex()); - } + if (! self::$factoryReplaced && preg_match(LazyUuidFromString::VALID_REGEX, $uuid) === 1) { + return new LazyUuidFromString(strtolower($uuid)); + } - public function getNodeHex() - { - return $this->fields['node']; + return self::getFactory()->fromString($uuid); } /** - * Returns the high field of the timestamp multiplexed with the version - * number (bits 49-64 of the UUID). + * Creates a UUID from a DateTimeInterface instance * - * @return int Unsigned 16-bit integer value of time_hi_and_version - */ - public function getTimeHiAndVersion() - { - return hexdec($this->getTimeHiAndVersionHex()); - } - - public function getTimeHiAndVersionHex() - { - return $this->fields['time_hi_and_version']; - } - - /** - * Returns the low field of the timestamp (the first 32 bits of the UUID). + * @param DateTimeInterface $dateTime The date and time + * @param Hexadecimal|null $node A 48-bit number representing the hardware + * address + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates + * that could arise when the clock is set backwards in time or if the + * node ID changes * - * @return int Unsigned 32-bit integer value of time_low + * @return UuidInterface A UuidInterface instance that represents a + * version 1 UUID created from a DateTimeInterface instance */ - public function getTimeLow() - { - return hexdec($this->getTimeLowHex()); - } - - public function getTimeLowHex() - { - return $this->fields['time_low']; + public static function fromDateTime( + DateTimeInterface $dateTime, + ?Hexadecimal $node = null, + ?int $clockSeq = null + ): UuidInterface { + return self::getFactory()->fromDateTime($dateTime, $node, $clockSeq); } /** - * Returns the middle field of the timestamp (bits 33-48 of the UUID). + * Creates a UUID from a 128-bit integer string + * + * @param string $integer String representation of 128-bit integer + * + * @return UuidInterface A UuidInterface instance created from the string + * representation of a 128-bit integer * - * @return int Unsigned 16-bit integer value of time_mid + * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, + * but under constant factory setups, this method operates in functionally pure manners */ - public function getTimeMid() + public static function fromInteger(string $integer): UuidInterface { - return hexdec($this->getTimeMidHex()); - } - - public function getTimeMidHex() - { - return $this->fields['time_mid']; + return self::getFactory()->fromInteger($integer); } /** - * Returns the timestamp value associated with this UUID. + * Returns true if the provided string is a valid UUID * - * The 60 bit timestamp value is constructed from the time_low, - * time_mid, and time_hi fields of this UUID. The resulting - * timestamp is measured in 100-nanosecond units since midnight, - * October 15, 1582 UTC. + * @param string $uuid A string to validate as a UUID * - * The timestamp value is only meaningful in a time-based UUID, which - * has version type 1. If this UUID is not a time-based UUID then - * this method throws UnsupportedOperationException. + * @return bool True if the string is a valid UUID, false otherwise * - * @return int Unsigned 60-bit integer value of the timestamp - * @throws UnsupportedOperationException If this UUID is not a version 1 UUID - * @link http://tools.ietf.org/html/rfc4122#section-4.1.4 + * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, + * but under constant factory setups, this method operates in functionally pure manners */ - public function getTimestamp() + public static function isValid(string $uuid): bool { - if ($this->getVersion() != 1) { - throw new UnsupportedOperationException('Not a time-based UUID'); - } - - return hexdec($this->getTimestampHex()); + return self::getFactory()->getValidator()->validate($uuid); } /** - * @inheritdoc - */ - public function getTimestampHex() - { - if ($this->getVersion() != 1) { - throw new UnsupportedOperationException('Not a time-based UUID'); - } - - return sprintf( - '%03x%04s%08s', - ($this->getTimeHiAndVersion() & 0x0fff), - $this->fields['time_mid'], - $this->fields['time_low'] - ); - } - - public function getUrn() - { - return 'urn:uuid:' . $this->toString(); - } - - public function getVariant() - { - $clockSeq = $this->getClockSeqHiAndReserved(); - - if (0 === ($clockSeq & 0x80)) { - return self::RESERVED_NCS; - } - - if (0 === ($clockSeq & 0x40)) { - return self::RFC_4122; - } - - if (0 === ($clockSeq & 0x20)) { - return self::RESERVED_MICROSOFT; - } - - return self::RESERVED_FUTURE; - } - - public function getVersion() - { - if ($this->getVariant() == self::RFC_4122) { - return (int) (($this->getTimeHiAndVersion() >> 12) & 0x0f); - } - - return null; - } - - public function toString() - { - return $this->codec->encode($this); - } - - /** - * Returns the currently set factory used to create UUIDs. + * Returns a version 1 (time-based) UUID from a host ID, sequence number, + * and the current time * - * @return UuidFactoryInterface - */ - public static function getFactory() - { - if (!self::$factory) { - self::$factory = new UuidFactory(); - } - - return self::$factory; - } - - /** - * Sets the factory used to create UUIDs. + * @param Hexadecimal|int|string|null $node A 48-bit number representing the + * hardware address; this number may be represented as an integer or a + * hexadecimal string + * @param int $clockSeq A 14-bit number used to help avoid duplicates that + * could arise when the clock is set backwards in time or if the node ID + * changes * - * @param UuidFactoryInterface $factory + * @return UuidInterface A UuidInterface instance that represents a + * version 1 UUID */ - public static function setFactory(UuidFactoryInterface $factory) + public static function uuid1($node = null, ?int $clockSeq = null): UuidInterface { - self::$factory = $factory; + return self::getFactory()->uuid1($node, $clockSeq); } /** - * Creates a UUID from a byte string. + * Returns a version 2 (DCE Security) UUID from a local domain, local + * identifier, host ID, clock sequence, and the current time * - * @param string $bytes - * @return UuidInterface - * @throws InvalidUuidStringException - * @throws InvalidArgumentException - */ - public static function fromBytes($bytes) - { - return self::getFactory()->fromBytes($bytes); - } - - /** - * Creates a UUID from the string standard representation. + * @param int $localDomain The local domain to use when generating bytes, + * according to DCE Security + * @param IntegerObject|null $localIdentifier The local identifier for the + * given domain; this may be a UID or GID on POSIX systems, if the local + * domain is person or group, or it may be a site-defined identifier + * if the local domain is org + * @param Hexadecimal|null $node A 48-bit number representing the hardware + * address + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates + * that could arise when the clock is set backwards in time or if the + * node ID changes (in a version 2 UUID, the lower 8 bits of this number + * are replaced with the domain). * - * @param string $name A string that specifies a UUID - * @return UuidInterface - * @throws InvalidUuidStringException + * @return UuidInterface A UuidInterface instance that represents a + * version 2 UUID */ - public static function fromString($name) - { - return self::getFactory()->fromString($name); + public static function uuid2( + int $localDomain, + ?IntegerObject $localIdentifier = null, + ?Hexadecimal $node = null, + ?int $clockSeq = null + ): UuidInterface { + return self::getFactory()->uuid2($localDomain, $localIdentifier, $node, $clockSeq); } /** - * Creates a UUID from a 128-bit integer string. + * Returns a version 3 (name-based) UUID based on the MD5 hash of a + * namespace ID and a name * - * @param string $integer String representation of 128-bit integer - * @return UuidInterface - * @throws UnsatisfiedDependencyException if `Moontoast\Math\BigNumber` is not present - * @throws InvalidUuidStringException + * @param string|UuidInterface $ns The namespace (must be a valid UUID) + * @param string $name The name to use for creating a UUID + * + * @return UuidInterface A UuidInterface instance that represents a + * version 3 UUID + * + * @psalm-suppress ImpureMethodCall we know that the factory being replaced can lead to massive + * havoc across all consumers: that should never happen, and + * is generally to be discouraged. Until the factory is kept + * un-replaced, this method is effectively pure. + * + * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, + * but under constant factory setups, this method operates in functionally pure manners */ - public static function fromInteger($integer) + public static function uuid3($ns, string $name): UuidInterface { - return self::getFactory()->fromInteger($integer); + return self::getFactory()->uuid3($ns, $name); } /** - * Check if a string is a valid UUID. + * Returns a version 4 (random) UUID * - * @param string $uuid The string UUID to test - * @return boolean + * @return UuidInterface A UuidInterface instance that represents a + * version 4 UUID */ - public static function isValid($uuid) + public static function uuid4(): UuidInterface { - $uuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid); - - if ($uuid == self::NIL) { - return true; - } - - if (!preg_match('/' . self::VALID_PATTERN . '/D', $uuid)) { - return false; - } - - return true; + return self::getFactory()->uuid4(); } /** - * Generate a version 1 UUID from a host ID, sequence number, and the current time. + * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a + * namespace ID and a name * - * @param int|string $node A 48-bit number representing the hardware address - * This number may be represented as an integer or a hexadecimal string. - * @param int $clockSeq A 14-bit number used to help avoid duplicates that - * could arise when the clock is set backwards in time or if the node ID - * changes. - * @return UuidInterface - * @throws UnsatisfiedDependencyException if called on a 32-bit system and - * `Moontoast\Math\BigNumber` is not present - * @throws InvalidArgumentException - * @throws Exception if it was not possible to gather sufficient entropy - */ - public static function uuid1($node = null, $clockSeq = null) - { - return self::getFactory()->uuid1($node, $clockSeq); - } - - /** - * Generate a version 3 UUID based on the MD5 hash of a namespace identifier - * (which is a UUID) and a name (which is a string). + * @param string|UuidInterface $ns The namespace (must be a valid UUID) + * @param string $name The name to use for creating a UUID * - * @param string|UuidInterface $ns The UUID namespace in which to create the named UUID - * @param string $name The name to create a UUID for - * @return UuidInterface - * @throws InvalidUuidStringException - */ - public static function uuid3($ns, $name) - { - return self::getFactory()->uuid3($ns, $name); - } - - /** - * Generate a version 4 (random) UUID. + * @return UuidInterface A UuidInterface instance that represents a + * version 5 UUID + * + * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, + * but under constant factory setups, this method operates in functionally pure manners * - * @return UuidInterface - * @throws UnsatisfiedDependencyException if `Moontoast\Math\BigNumber` is not present - * @throws InvalidArgumentException - * @throws Exception + * @psalm-suppress ImpureMethodCall we know that the factory being replaced can lead to massive + * havoc across all consumers: that should never happen, and + * is generally to be discouraged. Until the factory is kept + * un-replaced, this method is effectively pure. */ - public static function uuid4() + public static function uuid5($ns, string $name): UuidInterface { - return self::getFactory()->uuid4(); + return self::getFactory()->uuid5($ns, $name); } /** - * Generate a version 5 UUID based on the SHA-1 hash of a namespace - * identifier (which is a UUID) and a name (which is a string). + * Returns a version 6 (ordered-time) UUID from a host ID, sequence number, + * and the current time * - * @param string|UuidInterface $ns The UUID namespace in which to create the named UUID - * @param string $name The name to create a UUID for - * @return UuidInterface - * @throws InvalidUuidStringException + * @param Hexadecimal|null $node A 48-bit number representing the hardware + * address + * @param int $clockSeq A 14-bit number used to help avoid duplicates that + * could arise when the clock is set backwards in time or if the node ID + * changes + * + * @return UuidInterface A UuidInterface instance that represents a + * version 6 UUID */ - public static function uuid5($ns, $name) - { - return self::getFactory()->uuid5($ns, $name); + public static function uuid6( + ?Hexadecimal $node = null, + ?int $clockSeq = null + ): UuidInterface { + return self::getFactory()->uuid6($node, $clockSeq); } } diff --git a/vendor/ramsey/uuid/src/UuidFactory.php b/vendor/ramsey/uuid/src/UuidFactory.php index 5a57b09b2..feddef88d 100644 --- a/vendor/ramsey/uuid/src/UuidFactory.php +++ b/vendor/ramsey/uuid/src/UuidFactory.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,201 +8,314 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid; +use DateTimeInterface; +use Ramsey\Uuid\Builder\UuidBuilderInterface; +use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; -use Ramsey\Uuid\Exception\InvalidUuidStringException; -use Ramsey\Uuid\Provider\NodeProviderInterface; +use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Generator\DceSecurityGeneratorInterface; +use Ramsey\Uuid\Generator\DefaultTimeGenerator; +use Ramsey\Uuid\Generator\NameGeneratorInterface; use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Generator\TimeGeneratorInterface; -use Ramsey\Uuid\Codec\CodecInterface; -use Ramsey\Uuid\Builder\UuidBuilderInterface; +use Ramsey\Uuid\Lazy\LazyUuidFromString; +use Ramsey\Uuid\Provider\NodeProviderInterface; +use Ramsey\Uuid\Provider\Time\FixedTimeProvider; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\Type\Time; +use Ramsey\Uuid\Validator\ValidatorInterface; + +use function bin2hex; +use function hex2bin; +use function pack; +use function str_pad; +use function strtolower; +use function substr; +use function substr_replace; +use function unpack; + +use const STR_PAD_LEFT; class UuidFactory implements UuidFactoryInterface { /** * @var CodecInterface */ - private $codec = null; + private $codec; + + /** + * @var DceSecurityGeneratorInterface + */ + private $dceSecurityGenerator; + + /** + * @var NameGeneratorInterface + */ + private $nameGenerator; /** * @var NodeProviderInterface */ - private $nodeProvider = null; + private $nodeProvider; /** * @var NumberConverterInterface */ - private $numberConverter = null; + private $numberConverter; /** * @var RandomGeneratorInterface */ - private $randomGenerator = null; + private $randomGenerator; + + /** + * @var TimeConverterInterface + */ + private $timeConverter; /** * @var TimeGeneratorInterface */ - private $timeGenerator = null; + private $timeGenerator; /** * @var UuidBuilderInterface */ - private $uuidBuilder = null; + private $uuidBuilder; /** - * Constructs a `UuidFactory` for creating `Ramsey\Uuid\UuidInterface` instances - * - * @param FeatureSet $features A set of features for use when creating UUIDs + * @var ValidatorInterface + */ + private $validator; + + /** @var bool whether the feature set was provided from outside, or we can operate under "default" assumptions */ + private $isDefaultFeatureSet; + + /** + * @param FeatureSet $features A set of available features in the current environment */ - public function __construct(FeatureSet $features = null) + public function __construct(?FeatureSet $features = null) { + $this->isDefaultFeatureSet = $features === null; + $features = $features ?: new FeatureSet(); $this->codec = $features->getCodec(); + $this->dceSecurityGenerator = $features->getDceSecurityGenerator(); + $this->nameGenerator = $features->getNameGenerator(); $this->nodeProvider = $features->getNodeProvider(); $this->numberConverter = $features->getNumberConverter(); $this->randomGenerator = $features->getRandomGenerator(); + $this->timeConverter = $features->getTimeConverter(); $this->timeGenerator = $features->getTimeGenerator(); $this->uuidBuilder = $features->getBuilder(); + $this->validator = $features->getValidator(); } /** - * Returns the UUID coder-decoder used by this factory - * - * @return CodecInterface + * Returns the codec used by this factory */ - public function getCodec() + public function getCodec(): CodecInterface { return $this->codec; } /** - * Sets the UUID coder-decoder used by this factory + * Sets the codec to use for this factory * - * @param CodecInterface $codec + * @param CodecInterface $codec A UUID encoder-decoder */ - public function setCodec(CodecInterface $codec) + public function setCodec(CodecInterface $codec): void { + $this->isDefaultFeatureSet = false; + $this->codec = $codec; } /** - * Returns the system node ID provider used by this factory + * Returns the name generator used by this factory + */ + public function getNameGenerator(): NameGeneratorInterface + { + return $this->nameGenerator; + } + + /** + * Sets the name generator to use for this factory * - * @return NodeProviderInterface + * @param NameGeneratorInterface $nameGenerator A generator to generate + * binary data, based on a namespace and name + */ + public function setNameGenerator(NameGeneratorInterface $nameGenerator): void + { + $this->isDefaultFeatureSet = false; + + $this->nameGenerator = $nameGenerator; + } + + /** + * Returns the node provider used by this factory */ - public function getNodeProvider() + public function getNodeProvider(): NodeProviderInterface { return $this->nodeProvider; } /** - * Returns the random UUID generator used by this factory - * - * @return RandomGeneratorInterface + * Returns the random generator used by this factory */ - public function getRandomGenerator() + public function getRandomGenerator(): RandomGeneratorInterface { return $this->randomGenerator; } /** - * Returns the time-based UUID generator used by this factory - * - * @return TimeGeneratorInterface + * Returns the time generator used by this factory */ - public function getTimeGenerator() + public function getTimeGenerator(): TimeGeneratorInterface { return $this->timeGenerator; } /** - * Sets the time-based UUID generator this factory will use to generate version 1 UUIDs + * Sets the time generator to use for this factory * - * @param TimeGeneratorInterface $generator + * @param TimeGeneratorInterface $generator A generator to generate binary + * data, based on the time */ - public function setTimeGenerator(TimeGeneratorInterface $generator) + public function setTimeGenerator(TimeGeneratorInterface $generator): void { + $this->isDefaultFeatureSet = false; + $this->timeGenerator = $generator; } /** - * Returns the number converter used by this factory + * Returns the DCE Security generator used by this factory + */ + public function getDceSecurityGenerator(): DceSecurityGeneratorInterface + { + return $this->dceSecurityGenerator; + } + + /** + * Sets the DCE Security generator to use for this factory * - * @return NumberConverterInterface + * @param DceSecurityGeneratorInterface $generator A generator to generate + * binary data, based on a local domain and local identifier */ - public function getNumberConverter() + public function setDceSecurityGenerator(DceSecurityGeneratorInterface $generator): void + { + $this->isDefaultFeatureSet = false; + + $this->dceSecurityGenerator = $generator; + } + + /** + * Returns the number converter used by this factory + */ + public function getNumberConverter(): NumberConverterInterface { return $this->numberConverter; } /** - * Sets the random UUID generator this factory will use to generate version 4 UUIDs + * Sets the random generator to use for this factory * - * @param RandomGeneratorInterface $generator + * @param RandomGeneratorInterface $generator A generator to generate binary + * data, based on some random input */ - public function setRandomGenerator(RandomGeneratorInterface $generator) + public function setRandomGenerator(RandomGeneratorInterface $generator): void { + $this->isDefaultFeatureSet = false; + $this->randomGenerator = $generator; } /** - * Sets the number converter this factory will use + * Sets the number converter to use for this factory * - * @param NumberConverterInterface $converter + * @param NumberConverterInterface $converter A converter to use for working + * with large integers (i.e. integers greater than PHP_INT_MAX) */ - public function setNumberConverter(NumberConverterInterface $converter) + public function setNumberConverter(NumberConverterInterface $converter): void { + $this->isDefaultFeatureSet = false; + $this->numberConverter = $converter; } /** - * Returns the UUID builder this factory uses when creating `Uuid` instances - * - * @return UuidBuilderInterface $builder + * Returns the UUID builder used by this factory */ - public function getUuidBuilder() + public function getUuidBuilder(): UuidBuilderInterface { return $this->uuidBuilder; } /** - * Sets the UUID builder this factory will use when creating `Uuid` instances + * Sets the UUID builder to use for this factory * - * @param UuidBuilderInterface $builder + * @param UuidBuilderInterface $builder A builder for constructing instances + * of UuidInterface */ - public function setUuidBuilder(UuidBuilderInterface $builder) + public function setUuidBuilder(UuidBuilderInterface $builder): void { + $this->isDefaultFeatureSet = false; + $this->uuidBuilder = $builder; } /** - * @inheritdoc + * @psalm-mutation-free + */ + public function getValidator(): ValidatorInterface + { + return $this->validator; + } + + /** + * Sets the validator to use for this factory + * + * @param ValidatorInterface $validator A validator to use for validating + * whether a string is a valid UUID + */ + public function setValidator(ValidatorInterface $validator): void + { + $this->isDefaultFeatureSet = false; + + $this->validator = $validator; + } + + /** + * @psalm-pure */ - public function fromBytes($bytes) + public function fromBytes(string $bytes): UuidInterface { return $this->codec->decodeBytes($bytes); } /** - * @inheritdoc + * @psalm-pure */ - public function fromString($uuid) + public function fromString(string $uuid): UuidInterface { $uuid = strtolower($uuid); + return $this->codec->decode($uuid); } /** - * @inheritdoc + * @psalm-pure */ - public function fromInteger($integer) + public function fromInteger(string $integer): UuidInterface { $hex = $this->numberConverter->toHex($integer); $hex = str_pad($hex, 32, '0', STR_PAD_LEFT); @@ -209,107 +323,167 @@ class UuidFactory implements UuidFactoryInterface return $this->fromString($hex); } + public function fromDateTime( + DateTimeInterface $dateTime, + ?Hexadecimal $node = null, + ?int $clockSeq = null + ): UuidInterface { + $timeProvider = new FixedTimeProvider( + new Time($dateTime->format('U'), $dateTime->format('u')) + ); + + $timeGenerator = new DefaultTimeGenerator( + $this->nodeProvider, + $this->timeConverter, + $timeProvider + ); + + $nodeHex = $node ? $node->toString() : null; + + $bytes = $timeGenerator->generate($nodeHex, $clockSeq); + + return $this->uuidFromBytesAndVersion($bytes, 1); + } + /** - * @inheritdoc + * @inheritDoc */ - public function uuid1($node = null, $clockSeq = null) + public function uuid1($node = null, ?int $clockSeq = null): UuidInterface { $bytes = $this->timeGenerator->generate($node, $clockSeq); - $hex = bin2hex($bytes); - return $this->uuidFromHashedName($hex, 1); + return $this->uuidFromBytesAndVersion($bytes, 1); + } + + public function uuid2( + int $localDomain, + ?IntegerObject $localIdentifier = null, + ?Hexadecimal $node = null, + ?int $clockSeq = null + ): UuidInterface { + $bytes = $this->dceSecurityGenerator->generate( + $localDomain, + $localIdentifier, + $node, + $clockSeq + ); + + return $this->uuidFromBytesAndVersion($bytes, 2); } /** - * @inheritdoc + * @inheritDoc + * @psalm-pure */ - public function uuid3($ns, $name) + public function uuid3($ns, string $name): UuidInterface { return $this->uuidFromNsAndName($ns, $name, 3, 'md5'); } - /** - * @inheritdoc - */ - public function uuid4() + public function uuid4(): UuidInterface { $bytes = $this->randomGenerator->generate(16); - // When converting the bytes to hex, it turns into a 32-character - // hexadecimal string that looks a lot like an MD5 hash, so at this - // point, we can just pass it to uuidFromHashedName. - $hex = bin2hex($bytes); - - return $this->uuidFromHashedName($hex, 4); + return $this->uuidFromBytesAndVersion($bytes, 4); } /** - * @inheritdoc + * @inheritDoc + * @psalm-pure */ - public function uuid5($ns, $name) + public function uuid5($ns, string $name): UuidInterface { return $this->uuidFromNsAndName($ns, $name, 5, 'sha1'); } + public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface + { + $nodeHex = $node ? $node->toString() : null; + $bytes = $this->timeGenerator->generate($nodeHex, $clockSeq); + + // Rearrange the bytes, according to the UUID version 6 specification. + $v6 = $bytes[6] . $bytes[7] . $bytes[4] . $bytes[5] + . $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3]; + $v6 = bin2hex($v6); + + // Drop the first four bits, while adding an empty four bits for the + // version field. This allows us to reconstruct the correct time from + // the bytes of this UUID. + $v6Bytes = hex2bin(substr($v6, 1, 12) . '0' . substr($v6, -3)); + $v6Bytes .= substr($bytes, 8); + + return $this->uuidFromBytesAndVersion($v6Bytes, 6); + } + /** - * Returns a `Uuid` + * Returns a Uuid created from the provided byte string + * + * Uses the configured builder and codec and the provided byte string to + * construct a Uuid object. + * + * @param string $bytes The byte string from which to construct a UUID * - * Uses the configured builder and codec and the provided array of hexadecimal - * value UUID fields to construct a `Uuid` object. + * @return UuidInterface An instance of UuidInterface, created from the + * provided bytes * - * @param array $fields An array of fields from which to construct a UUID; - * see {@see \Ramsey\Uuid\UuidInterface::getFieldsHex()} for array structure. - * @return UuidInterface + * @psalm-pure */ - public function uuid(array $fields) + public function uuid(string $bytes): UuidInterface { - return $this->uuidBuilder->build($this->codec, $fields); + return $this->uuidBuilder->build($this->codec, $bytes); } /** - * Returns a version 3 or 5 namespaced `Uuid` + * Returns a version 3 or 5 namespaced Uuid * - * @param string|UuidInterface $ns The UUID namespace to use - * @param string $name The string to hash together with the namespace + * @param string|UuidInterface $ns The namespace (must be a valid UUID) + * @param string $name The name to hash together with the namespace * @param int $version The version of UUID to create (3 or 5) - * @param string $hashFunction The hash function to use when hashing together - * the namespace and name - * @return UuidInterface - * @throws InvalidUuidStringException + * @param string $hashAlgorithm The hashing algorithm to use when hashing + * together the namespace and name + * + * @return UuidInterface An instance of UuidInterface, created by hashing + * together the provided namespace and name + * + * @psalm-pure */ - protected function uuidFromNsAndName($ns, $name, $version, $hashFunction) + private function uuidFromNsAndName($ns, string $name, int $version, string $hashAlgorithm): UuidInterface { if (!($ns instanceof UuidInterface)) { - $ns = $this->codec->decode($ns); + $ns = $this->fromString($ns); } - $hash = call_user_func($hashFunction, ($ns->getBytes() . $name)); + $bytes = $this->nameGenerator->generate($ns, $name, $hashAlgorithm); - return $this->uuidFromHashedName($hash, $version); + return $this->uuidFromBytesAndVersion(substr($bytes, 0, 16), $version); } /** - * Returns a `Uuid` created from `$hash` with the version field set to `$version` - * and the variant field set for RFC 4122 + * Returns an RFC 4122 variant Uuid, created from the provided bytes and version + * + * @param string $bytes The byte string to convert to a UUID + * @param int $version The RFC 4122 version to apply to the UUID * - * @param string $hash The hash to use when creating the UUID - * @param int $version The UUID version to set for this hash (1, 3, 4, or 5) - * @return UuidInterface + * @return UuidInterface An instance of UuidInterface, created from the + * byte string and version + * + * @psalm-pure */ - protected function uuidFromHashedName($hash, $version) + private function uuidFromBytesAndVersion(string $bytes, int $version): UuidInterface { - $timeHi = BinaryUtils::applyVersion(substr($hash, 12, 4), $version); - $clockSeqHi = BinaryUtils::applyVariant(hexdec(substr($hash, 16, 2))); - - $fields = [ - 'time_low' => substr($hash, 0, 8), - 'time_mid' => substr($hash, 8, 4), - 'time_hi_and_version' => str_pad(dechex($timeHi), 4, '0', STR_PAD_LEFT), - 'clock_seq_hi_and_reserved' => str_pad(dechex($clockSeqHi), 2, '0', STR_PAD_LEFT), - 'clock_seq_low' => substr($hash, 18, 2), - 'node' => substr($hash, 20, 12), - ]; - - return $this->uuid($fields); + $timeHi = (int) unpack('n*', substr($bytes, 6, 2))[1]; + $timeHiAndVersion = pack('n*', BinaryUtils::applyVersion($timeHi, $version)); + + $clockSeqHi = (int) unpack('n*', substr($bytes, 8, 2))[1]; + $clockSeqHiAndReserved = pack('n*', BinaryUtils::applyVariant($clockSeqHi)); + + $bytes = substr_replace($bytes, $timeHiAndVersion, 6, 2); + $bytes = substr_replace($bytes, $clockSeqHiAndReserved, 8, 2); + + if ($this->isDefaultFeatureSet) { + return LazyUuidFromString::fromBytes($bytes); + } + + return $this->uuid($bytes); } } diff --git a/vendor/ramsey/uuid/src/UuidFactoryInterface.php b/vendor/ramsey/uuid/src/UuidFactoryInterface.php index 1c1651d64..468cc6377 100644 --- a/vendor/ramsey/uuid/src/UuidFactoryInterface.php +++ b/vendor/ramsey/uuid/src/UuidFactoryInterface.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,17 +8,16 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid; -use Exception; -use InvalidArgumentException; -use Ramsey\Uuid\Exception\InvalidUuidStringException; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; +use DateTimeInterface; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\Validator\ValidatorInterface; /** * UuidFactoryInterface defines common functionality all `UuidFactory` instances @@ -26,83 +26,157 @@ use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; interface UuidFactoryInterface { /** - * Generate a version 1 UUID from a host ID, sequence number, and the current time. - * - * @param int|string|null $node A 48-bit number representing the hardware address - * This number may be represented as an integer or a hexadecimal string. - * @param int|null $clockSeq A 14-bit number used to help avoid duplicates that - * could arise when the clock is set backwards in time or if the node ID - * changes. - * @return UuidInterface - * @throws UnsatisfiedDependencyException if called on a 32-bit system and - * `Moontoast\Math\BigNumber` is not present - * @throws InvalidArgumentException - * @throws Exception if it was not possible to gather sufficient entropy + * Returns the validator to use for the factory + * + * @psalm-mutation-free + */ + public function getValidator(): ValidatorInterface; + + /** + * Returns a version 1 (time-based) UUID from a host ID, sequence number, + * and the current time + * + * @param Hexadecimal|int|string|null $node A 48-bit number representing the + * hardware address; this number may be represented as an integer or a + * hexadecimal string + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates + * that could arise when the clock is set backwards in time or if the + * node ID changes + * + * @return UuidInterface A UuidInterface instance that represents a + * version 1 UUID + */ + public function uuid1($node = null, ?int $clockSeq = null): UuidInterface; + + /** + * Returns a version 2 (DCE Security) UUID from a local domain, local + * identifier, host ID, clock sequence, and the current time + * + * @param int $localDomain The local domain to use when generating bytes, + * according to DCE Security + * @param IntegerObject|null $localIdentifier The local identifier for the + * given domain; this may be a UID or GID on POSIX systems, if the local + * domain is person or group, or it may be a site-defined identifier + * if the local domain is org + * @param Hexadecimal|null $node A 48-bit number representing the hardware + * address + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates + * that could arise when the clock is set backwards in time or if the + * node ID changes + * + * @return UuidInterface A UuidInterface instance that represents a + * version 2 UUID + */ + public function uuid2( + int $localDomain, + ?IntegerObject $localIdentifier = null, + ?Hexadecimal $node = null, + ?int $clockSeq = null + ): UuidInterface; + + /** + * Returns a version 3 (name-based) UUID based on the MD5 hash of a + * namespace ID and a name + * + * @param string|UuidInterface $ns The namespace (must be a valid UUID) + * @param string $name The name to use for creating a UUID + * + * @return UuidInterface A UuidInterface instance that represents a + * version 3 UUID + * + * @psalm-pure */ - public function uuid1($node = null, $clockSeq = null); + public function uuid3($ns, string $name): UuidInterface; /** - * Generate a version 3 UUID based on the MD5 hash of a namespace identifier - * (which is a UUID) and a name (which is a string). + * Returns a version 4 (random) UUID * - * @param string|UuidInterface $ns The UUID namespace in which to create the named UUID - * @param string $name The name to create a UUID for - * @return UuidInterface - * @throws InvalidUuidStringException + * @return UuidInterface A UuidInterface instance that represents a + * version 4 UUID */ - public function uuid3($ns, $name); + public function uuid4(): UuidInterface; /** - * Generate a version 4 (random) UUID. + * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a + * namespace ID and a name + * + * @param string|UuidInterface $ns The namespace (must be a valid UUID) + * @param string $name The name to use for creating a UUID * - * @return UuidInterface - * @throws UnsatisfiedDependencyException if `Moontoast\Math\BigNumber` is not present - * @throws InvalidArgumentException - * @throws Exception + * @return UuidInterface A UuidInterface instance that represents a + * version 5 UUID + * + * @psalm-pure */ - public function uuid4(); + public function uuid5($ns, string $name): UuidInterface; /** - * Generate a version 5 UUID based on the SHA-1 hash of a namespace - * identifier (which is a UUID) and a name (which is a string). + * Returns a version 6 (ordered-time) UUID from a host ID, sequence number, + * and the current time + * + * @param Hexadecimal|null $node A 48-bit number representing the hardware + * address + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates + * that could arise when the clock is set backwards in time or if the + * node ID changes * - * @param string|UuidInterface $ns The UUID namespace in which to create the named UUID - * @param string $name The name to create a UUID for - * @return UuidInterface - * @throws InvalidUuidStringException + * @return UuidInterface A UuidInterface instance that represents a + * version 6 UUID */ - public function uuid5($ns, $name); + public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface; /** - * Creates a UUID from a byte string. + * Creates a UUID from a byte string + * + * @param string $bytes A binary string + * + * @return UuidInterface A UuidInterface instance created from a binary + * string representation * - * @param string $bytes A 16-byte string representation of a UUID - * @return UuidInterface - * @throws InvalidUuidStringException - * @throws InvalidArgumentException if string has not 16 characters + * @psalm-pure */ - public function fromBytes($bytes); + public function fromBytes(string $bytes): UuidInterface; /** * Creates a UUID from the string standard representation * - * @param string $uuid A string representation of a UUID - * @return UuidInterface - * @throws InvalidUuidStringException + * @param string $uuid A hexadecimal string + * + * @return UuidInterface A UuidInterface instance created from a hexadecimal + * string representation + * + * @psalm-pure + */ + public function fromString(string $uuid): UuidInterface; + + /** + * Creates a UUID from a 128-bit integer string + * + * @param string $integer String representation of 128-bit integer + * + * @return UuidInterface A UuidInterface instance created from the string + * representation of a 128-bit integer + * + * @psalm-pure */ - public function fromString($uuid); + public function fromInteger(string $integer): UuidInterface; /** - * Creates a `Uuid` from an integer representation + * Creates a UUID from a DateTimeInterface instance * - * The integer representation may be a real integer, a string integer, or - * an integer representation supported by a configured number converter. + * @param DateTimeInterface $dateTime The date and time + * @param Hexadecimal|null $node A 48-bit number representing the hardware + * address + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates + * that could arise when the clock is set backwards in time or if the + * node ID changes * - * @param mixed $integer The integer to use when creating a `Uuid` from an - * integer; may be of any type understood by the configured number converter - * @return UuidInterface - * @throws UnsatisfiedDependencyException if `Moontoast\Math\BigNumber` is not present - * @throws InvalidUuidStringException + * @return UuidInterface A UuidInterface instance that represents a + * version 1 UUID created from a DateTimeInterface instance */ - public function fromInteger($integer); + public function fromDateTime( + DateTimeInterface $dateTime, + ?Hexadecimal $node = null, + ?int $clockSeq = null + ): UuidInterface; } diff --git a/vendor/ramsey/uuid/src/UuidInterface.php b/vendor/ramsey/uuid/src/UuidInterface.php index 42a3ad7ff..f22eb0f99 100644 --- a/vendor/ramsey/uuid/src/UuidInterface.php +++ b/vendor/ramsey/uuid/src/UuidInterface.php @@ -1,4 +1,5 @@ <?php + /** * This file is part of the ramsey/uuid library * @@ -7,28 +8,32 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT - * @link https://benramsey.com/projects/ramsey-uuid/ Documentation - * @link https://packagist.org/packages/ramsey/uuid Packagist - * @link https://github.com/ramsey/uuid GitHub */ +declare(strict_types=1); + namespace Ramsey\Uuid; -use DateTime; use JsonSerializable; -use Ramsey\Uuid\Converter\NumberConverterInterface; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; -use Ramsey\Uuid\Exception\UnsupportedOperationException; +use Ramsey\Uuid\Fields\FieldsInterface; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; use Serializable; /** - * UuidInterface defines common functionality for all universally unique - * identifiers (UUIDs) + * A UUID is a universally unique identifier adhering to an agreed-upon + * representation format and standard for generation + * + * @psalm-immutable */ -interface UuidInterface extends JsonSerializable, Serializable +interface UuidInterface extends + DeprecatedUuidInterface, + JsonSerializable, + Serializable { /** - * Compares this UUID to the specified UUID. + * Returns -1, 0, or 1 if the UUID is less than, equal to, or greater than + * the other UUID * * The first of two UUIDs is greater than the second if the most * significant field in which the UUIDs differ is greater for the first @@ -37,238 +42,58 @@ interface UuidInterface extends JsonSerializable, Serializable * * Q. What's the value of being able to sort UUIDs? * * A. Use them as keys in a B-Tree or similar mapping. * - * @param UuidInterface $other UUID to which this UUID is compared - * @return int -1, 0 or 1 as this UUID is less than, equal to, or greater than `$uuid` + * @param UuidInterface $other The UUID to compare + * + * @return int -1, 0, or 1 if the UUID is less than, equal to, or greater than $other */ - public function compareTo(UuidInterface $other); + public function compareTo(UuidInterface $other): int; /** - * Compares this object to the specified object. + * Returns true if the UUID is equal to the provided object * * The result is true if and only if the argument is not null, is a UUID * object, has the same variant, and contains the same value, bit for bit, - * as this UUID. - * - * @param object $other - * @return bool True if `$other` is equal to this UUID - */ - public function equals($other); - - /** - * Returns the UUID as a 16-byte string (containing the six integer fields - * in big-endian byte order). - * - * @return string - */ - public function getBytes(); - - /** - * Returns the number converter to use for converting hex values to/from integers. - * - * @return NumberConverterInterface - */ - public function getNumberConverter(); - - /** - * Returns the hexadecimal value of the UUID. - * - * @return string - */ - public function getHex(); - - /** - * Returns an array of the fields of this UUID, with keys named according - * to the RFC 4122 names for the fields. - * - * * **time_low**: The low field of the timestamp, an unsigned 32-bit integer - * * **time_mid**: The middle field of the timestamp, an unsigned 16-bit integer - * * **time_hi_and_version**: The high field of the timestamp multiplexed with - * the version number, an unsigned 16-bit integer - * * **clock_seq_hi_and_reserved**: The high field of the clock sequence - * multiplexed with the variant, an unsigned 8-bit integer - * * **clock_seq_low**: The low field of the clock sequence, an unsigned - * 8-bit integer - * * **node**: The spatially unique node identifier, an unsigned 48-bit - * integer + * as the UUID. * - * @return array The UUID fields represented as hexadecimal values - */ - public function getFieldsHex(); - - /** - * Returns the high field of the clock sequence multiplexed with the variant - * (bits 65-72 of the UUID). + * @param object|null $other An object to test for equality with this UUID * - * @return string Hexadecimal value of clock_seq_hi_and_reserved + * @return bool True if the other object is equal to this UUID */ - public function getClockSeqHiAndReservedHex(); + public function equals(?object $other): bool; /** - * Returns the low field of the clock sequence (bits 73-80 of the UUID). + * Returns the binary string representation of the UUID * - * @return string Hexadecimal value of clock_seq_low + * @psalm-return non-empty-string */ - public function getClockSeqLowHex(); + public function getBytes(): string; /** - * Returns the clock sequence value associated with this UUID. - * - * @return string Hexadecimal value of clock sequence + * Returns the fields that comprise this UUID */ - public function getClockSequenceHex(); + public function getFields(): FieldsInterface; /** - * Returns a PHP `DateTime` object representing the timestamp associated - * with this UUID. - * - * The timestamp value is only meaningful in a time-based UUID, which - * has version type 1. If this UUID is not a time-based UUID then - * this method throws `UnsupportedOperationException`. - * - * @return DateTime A PHP DateTime representation of the date - * @throws UnsupportedOperationException If this UUID is not a version 1 UUID - * @throws UnsatisfiedDependencyException if called in a 32-bit system and - * `Moontoast\Math\BigNumber` is not present + * Returns the hexadecimal representation of the UUID */ - public function getDateTime(); + public function getHex(): Hexadecimal; /** - * Returns the integer value of the UUID, converted to an appropriate number - * representation. - * - * @return mixed Converted representation of the unsigned 128-bit integer value - * @throws UnsatisfiedDependencyException if `Moontoast\Math\BigNumber` is not present + * Returns the integer representation of the UUID */ - public function getInteger(); + public function getInteger(): IntegerObject; /** - * Returns the least significant 64 bits of this UUID's 128 bit value. - * - * @return string Hexadecimal value of least significant bits - */ - public function getLeastSignificantBitsHex(); - - /** - * Returns the most significant 64 bits of this UUID's 128 bit value. - * - * @return string Hexadecimal value of most significant bits - */ - public function getMostSignificantBitsHex(); - - /** - * Returns the node value associated with this UUID - * - * For UUID version 1, the node field consists of an IEEE 802 MAC - * address, usually the host address. For systems with multiple IEEE - * 802 addresses, any available one can be used. The lowest addressed - * octet (octet number 10) contains the global/local bit and the - * unicast/multicast bit, and is the first octet of the address - * transmitted on an 802.3 LAN. - * - * For systems with no IEEE address, a randomly or pseudo-randomly - * generated value may be used; see RFC 4122, Section 4.5. The - * multicast bit must be set in such addresses, in order that they - * will never conflict with addresses obtained from network cards. - * - * For UUID version 3 or 5, the node field is a 48-bit value constructed - * from a name as described in RFC 4122, Section 4.3. - * - * For UUID version 4, the node field is a randomly or pseudo-randomly - * generated 48-bit value as described in RFC 4122, Section 4.4. - * - * @return string Hexadecimal value of node - * @link http://tools.ietf.org/html/rfc4122#section-4.1.6 - */ - public function getNodeHex(); - - /** - * Returns the high field of the timestamp multiplexed with the version - * number (bits 49-64 of the UUID). - * - * @return string Hexadecimal value of time_hi_and_version - */ - public function getTimeHiAndVersionHex(); - - /** - * Returns the low field of the timestamp (the first 32 bits of the UUID). - * - * @return string Hexadecimal value of time_low - */ - public function getTimeLowHex(); - - /** - * Returns the middle field of the timestamp (bits 33-48 of the UUID). - * - * @return string Hexadecimal value of time_mid - */ - public function getTimeMidHex(); - - /** - * Returns the timestamp value associated with this UUID. - * - * The 60 bit timestamp value is constructed from the time_low, - * time_mid, and time_hi fields of this UUID. The resulting - * timestamp is measured in 100-nanosecond units since midnight, - * October 15, 1582 UTC. - * - * The timestamp value is only meaningful in a time-based UUID, which - * has version type 1. If this UUID is not a time-based UUID then - * this method throws UnsupportedOperationException. - * - * @return string Hexadecimal value of the timestamp - * @throws UnsupportedOperationException If this UUID is not a version 1 UUID - * @link http://tools.ietf.org/html/rfc4122#section-4.1.4 - */ - public function getTimestampHex(); - - /** - * Returns the string representation of the UUID as a URN. - * - * @return string - * @link http://en.wikipedia.org/wiki/Uniform_Resource_Name - */ - public function getUrn(); - - /** - * Returns the variant number associated with this UUID. - * - * The variant number describes the layout of the UUID. The variant - * number has the following meaning: - * - * * 0 - Reserved for NCS backward compatibility - * * 2 - The RFC 4122 variant (used by this class) - * * 6 - Reserved, Microsoft Corporation backward compatibility - * * 7 - Reserved for future definition - * - * @return int - * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 - */ - public function getVariant(); - - /** - * Returns the version number associated with this UUID. - * - * The version number describes how this UUID was generated and has the - * following meaning: - * - * * 1 - Time-based UUID - * * 2 - DCE security UUID - * * 3 - Name-based UUID hashed with MD5 - * * 4 - Randomly generated UUID - * * 5 - Name-based UUID hashed with SHA-1 - * - * Returns null if this UUID is not an RFC 4122 variant, since version - * is only meaningful for this variant. + * Returns the string standard representation of the UUID * - * @return int|null - * @link http://tools.ietf.org/html/rfc4122#section-4.1.3 + * @psalm-return non-empty-string */ - public function getVersion(); + public function toString(): string; /** - * Converts this UUID into a string representation. + * Casts the UUID to the string standard representation * - * @return string + * @psalm-return non-empty-string */ - public function toString(); + public function __toString(): string; } diff --git a/vendor/ramsey/uuid/src/Validator/GenericValidator.php b/vendor/ramsey/uuid/src/Validator/GenericValidator.php new file mode 100644 index 000000000..fd6095511 --- /dev/null +++ b/vendor/ramsey/uuid/src/Validator/GenericValidator.php @@ -0,0 +1,50 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Validator; + +use Ramsey\Uuid\Uuid; + +use function preg_match; +use function str_replace; + +/** + * GenericValidator validates strings as UUIDs of any variant + * + * @psalm-immutable + */ +final class GenericValidator implements ValidatorInterface +{ + /** + * Regular expression pattern for matching a UUID of any variant. + */ + private const VALID_PATTERN = '\A[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}\z'; + + /** + * @psalm-return non-empty-string + * @psalm-suppress MoreSpecificReturnType we know that the retrieved `string` is never empty + * @psalm-suppress LessSpecificReturnStatement we know that the retrieved `string` is never empty + */ + public function getPattern(): string + { + return self::VALID_PATTERN; + } + + public function validate(string $uuid): bool + { + $uuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid); + + return $uuid === Uuid::NIL || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); + } +} diff --git a/vendor/ramsey/uuid/src/Validator/ValidatorInterface.php b/vendor/ramsey/uuid/src/Validator/ValidatorInterface.php new file mode 100644 index 000000000..3d4bd6f28 --- /dev/null +++ b/vendor/ramsey/uuid/src/Validator/ValidatorInterface.php @@ -0,0 +1,41 @@ +<?php + +/** + * This file is part of the ramsey/uuid library + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Validator; + +/** + * A validator validates a string as a proper UUID + * + * @psalm-immutable + */ +interface ValidatorInterface +{ + /** + * Returns the regular expression pattern used by this validator + * + * @return string The regular expression pattern this validator uses + * + * @psalm-return non-empty-string + */ + public function getPattern(): string; + + /** + * Returns true if the provided string represents a UUID + * + * @param string $uuid The string to validate as a UUID + * + * @return bool True if the string is a valid UUID, false otherwise + */ + public function validate(string $uuid): bool; +} diff --git a/vendor/ramsey/uuid/src/functions.php b/vendor/ramsey/uuid/src/functions.php index b5db34183..7b29ec4b1 100644 --- a/vendor/ramsey/uuid/src/functions.php +++ b/vendor/ramsey/uuid/src/functions.php @@ -8,71 +8,110 @@ * * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com> * @license http://opensource.org/licenses/MIT MIT + * phpcs:disable Squiz.Functions.GlobalFunction */ +declare(strict_types=1); + namespace Ramsey\Uuid; -use Exception; -use InvalidArgumentException; -use Ramsey\Uuid\Exception\InvalidUuidStringException; -use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; /** - * Generate a version 1 UUID from a host ID, sequence number, and the current time. + * Returns a version 1 (time-based) UUID from a host ID, sequence number, + * and the current time * - * @param int|string|null $node A 48-bit number representing the hardware address - * This number may be represented as an integer or a hexadecimal string. - * @param int|null $clockSeq A 14-bit number used to help avoid duplicates that + * @param Hexadecimal|int|string|null $node A 48-bit number representing the + * hardware address; this number may be represented as an integer or a + * hexadecimal string + * @param int $clockSeq A 14-bit number used to help avoid duplicates that * could arise when the clock is set backwards in time or if the node ID - * changes. - * @return string - * @throws UnsatisfiedDependencyException if called on a 32-bit system and - * `Moontoast\Math\BigNumber` is not present - * @throws InvalidArgumentException - * @throws Exception if it was not possible to gather sufficient entropy + * changes + * + * @return string Version 1 UUID as a string */ -function v1($node = null, $clockSeq = null) +function v1($node = null, ?int $clockSeq = null): string { return Uuid::uuid1($node, $clockSeq)->toString(); } /** - * Generate a version 3 UUID based on the MD5 hash of a namespace identifier - * (which is a UUID) and a name (which is a string). + * Returns a version 2 (DCE Security) UUID from a local domain, local + * identifier, host ID, clock sequence, and the current time + * + * @param int $localDomain The local domain to use when generating bytes, + * according to DCE Security + * @param IntegerObject|null $localIdentifier The local identifier for the + * given domain; this may be a UID or GID on POSIX systems, if the local + * domain is person or group, or it may be a site-defined identifier + * if the local domain is org + * @param Hexadecimal|null $node A 48-bit number representing the hardware + * address + * @param int|null $clockSeq A 14-bit number used to help avoid duplicates + * that could arise when the clock is set backwards in time or if the + * node ID changes + * + * @return string Version 2 UUID as a string + */ +function v2( + int $localDomain, + ?IntegerObject $localIdentifier = null, + ?Hexadecimal $node = null, + ?int $clockSeq = null +): string { + return Uuid::uuid2($localDomain, $localIdentifier, $node, $clockSeq)->toString(); +} + +/** + * Returns a version 3 (name-based) UUID based on the MD5 hash of a + * namespace ID and a name + * + * @param string|UuidInterface $ns The namespace (must be a valid UUID) * - * @param string|UuidInterface $ns The UUID namespace in which to create the named UUID - * @param string $name The name to create a UUID for - * @return string - * @throws InvalidUuidStringException + * @return string Version 3 UUID as a string */ -function v3($ns, $name) +function v3($ns, string $name): string { return Uuid::uuid3($ns, $name)->toString(); } /** - * Generate a version 4 (random) UUID. + * Returns a version 4 (random) UUID * - * @return string - * @throws UnsatisfiedDependencyException if `Moontoast\Math\BigNumber` is not present - * @throws InvalidArgumentException - * @throws Exception + * @return string Version 4 UUID as a string */ -function v4() +function v4(): string { return Uuid::uuid4()->toString(); } /** - * Generate a version 5 UUID based on the SHA-1 hash of a namespace - * identifier (which is a UUID) and a name (which is a string). + * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a + * namespace ID and a name * - * @param string|UuidInterface $ns The UUID namespace in which to create the named UUID - * @param string $name The name to create a UUID for - * @return string - * @throws InvalidUuidStringException + * @param string|UuidInterface $ns The namespace (must be a valid UUID) + * + * @return string Version 5 UUID as a string */ -function v5($ns, $name) +function v5($ns, string $name): string { return Uuid::uuid5($ns, $name)->toString(); } + +/** + * Returns a version 6 (ordered-time) UUID from a host ID, sequence number, + * and the current time + * + * @param Hexadecimal|null $node A 48-bit number representing the hardware + * address + * @param int $clockSeq A 14-bit number used to help avoid duplicates that + * could arise when the clock is set backwards in time or if the node ID + * changes + * + * @return string Version 6 UUID as a string + */ +function v6(?Hexadecimal $node = null, ?int $clockSeq = null): string +{ + return Uuid::uuid6($node, $clockSeq)->toString(); +} |