Files
php-uuid/src/FeatureSet.php
T
Ben Ramsey 0d7b8c2b7a Update coding style to include PSR-12, among other options
This also includes heavy use of slevomat/coding-standard to apply
various checks to the code, based on maintainer (me) preference.
2020-01-18 12:13:55 -06:00

356 lines
9.4 KiB
PHP

<?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 Ramsey\Uuid\Builder\DefaultUuidBuilder;
use Ramsey\Uuid\Builder\DegradedUuidBuilder;
use Ramsey\Uuid\Builder\UuidBuilderInterface;
use Ramsey\Uuid\Codec\CodecInterface;
use Ramsey\Uuid\Codec\GuidStringCodec;
use Ramsey\Uuid\Codec\StringCodec;
use Ramsey\Uuid\Converter\Number\BigNumberConverter;
use Ramsey\Uuid\Converter\Number\DegradedNumberConverter;
use Ramsey\Uuid\Converter\Number\GmpConverter;
use Ramsey\Uuid\Converter\NumberConverterInterface;
use Ramsey\Uuid\Converter\Time\BigNumberTimeConverter;
use Ramsey\Uuid\Converter\Time\DegradedTimeConverter;
use Ramsey\Uuid\Converter\Time\GmpTimeConverter;
use Ramsey\Uuid\Converter\Time\PhpTimeConverter;
use Ramsey\Uuid\Converter\TimeConverterInterface;
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\Node\FallbackNodeProvider;
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\Validator\Validator;
use Ramsey\Uuid\Validator\ValidatorInterface;
/**
* FeatureSet detects and exposes available features in the current environment
*
* A feature set is used by UuidFactory to determine the available features and
* capabilities of the environment.
*/
class FeatureSet
{
/**
* @var bool
*/
private $disableBigNumber = false;
/**
* @var bool
*/
private $disableGmp = false;
/**
* @var bool
*/
private $disable64Bit = false;
/**
* @var bool
*/
private $ignoreSystemNode = false;
/**
* @var bool
*/
private $enablePecl = false;
/**
* @var UuidBuilderInterface
*/
private $builder;
/**
* @var CodecInterface
*/
private $codec;
/**
* @var NodeProviderInterface
*/
private $nodeProvider;
/**
* @var NumberConverterInterface
*/
private $numberConverter;
/**
* @var TimeConverterInterface
*/
private $timeConverter;
/**
* @var RandomGeneratorInterface
*/
private $randomGenerator;
/**
* @var TimeGeneratorInterface
*/
private $timeGenerator;
/**
* @var ValidatorInterface
*/
private $validator;
/**
* @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 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
* @param bool $forceNoGmp True to disable the use of ext-gmp (primarily
* for testing purposes)
*/
public function __construct(
bool $useGuids = false,
bool $force32Bit = false,
bool $forceNoBigNumber = false,
bool $ignoreSystemNode = false,
bool $enablePecl = false,
bool $forceNoGmp = false
) {
$this->disableBigNumber = $forceNoBigNumber;
$this->disableGmp = $forceNoGmp;
$this->disable64Bit = $force32Bit;
$this->ignoreSystemNode = $ignoreSystemNode;
$this->enablePecl = $enablePecl;
$this->numberConverter = $this->buildNumberConverter();
$this->timeConverter = $this->buildTimeConverter();
$this->builder = $this->buildUuidBuilder();
$this->codec = $this->buildCodec($useGuids);
$this->nodeProvider = $this->buildNodeProvider();
$this->randomGenerator = $this->buildRandomGenerator();
$this->setTimeProvider(new SystemTimeProvider());
$this->validator = new Validator();
}
/**
* Returns the builder configured for this environment
*/
public function getBuilder(): UuidBuilderInterface
{
return $this->builder;
}
/**
* Returns the codec configured for this environment
*/
public function getCodec(): CodecInterface
{
return $this->codec;
}
/**
* Returns the node provider configured for this environment
*/
public function getNodeProvider(): NodeProviderInterface
{
return $this->nodeProvider;
}
/**
* Returns the number converter configured for this environment
*/
public function getNumberConverter(): NumberConverterInterface
{
return $this->numberConverter;
}
/**
* Returns the random generator configured for this environment
*/
public function getRandomGenerator(): RandomGeneratorInterface
{
return $this->randomGenerator;
}
/**
* Returns the time generator configured for this environment
*/
public function getTimeGenerator(): TimeGeneratorInterface
{
return $this->timeGenerator;
}
/**
* Returns the validator configured for this environment
*/
public function getValidator(): ValidatorInterface
{
return $this->validator;
}
/**
* Sets the time provider to use in this environment
*/
public function setTimeProvider(TimeProviderInterface $timeProvider): void
{
$this->timeGenerator = $this->buildTimeGenerator($timeProvider);
}
/**
* 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
*/
private function buildCodec(bool $useGuids = false): CodecInterface
{
if ($useGuids) {
return new GuidStringCodec($this->builder);
}
return new StringCodec($this->builder);
}
/**
* Returns a node provider configured for this environment
*/
private function buildNodeProvider(): NodeProviderInterface
{
if ($this->ignoreSystemNode) {
return new RandomNodeProvider();
}
return new FallbackNodeProvider([
new SystemNodeProvider(),
new RandomNodeProvider(),
]);
}
/**
* Returns a number converter configured for this environment
*/
private function buildNumberConverter(): NumberConverterInterface
{
if ($this->hasGmp()) {
return new GmpConverter();
}
if ($this->hasBigNumber()) {
return new BigNumberConverter();
}
return new DegradedNumberConverter();
}
/**
* Returns a random generator configured for this environment
*/
private function buildRandomGenerator(): RandomGeneratorInterface
{
return (new RandomGeneratorFactory())->getGenerator();
}
/**
* Returns a time generator configured for this environment
*
* @param TimeProviderInterface $timeProvider The time provider to use with
* the time generator
*/
private function buildTimeGenerator(TimeProviderInterface $timeProvider): TimeGeneratorInterface
{
if ($this->enablePecl) {
return new PeclUuidTimeGenerator();
}
return (new TimeGeneratorFactory(
$this->nodeProvider,
$this->timeConverter,
$timeProvider
))->getGenerator();
}
/**
* Returns a time converter configured for this environment
*/
private function buildTimeConverter(): TimeConverterInterface
{
if ($this->is64BitSystem()) {
return new PhpTimeConverter();
}
if ($this->hasGmp()) {
return new GmpTimeConverter();
}
if ($this->hasBigNumber()) {
return new BigNumberTimeConverter();
}
return new DegradedTimeConverter();
}
/**
* Returns a UUID builder configured for this environment
*/
private function buildUuidBuilder(): UuidBuilderInterface
{
if ($this->is64BitSystem()) {
return new DefaultUuidBuilder($this->numberConverter, $this->timeConverter);
}
return new DegradedUuidBuilder($this->numberConverter, $this->timeConverter);
}
/**
* Returns true if moontoast/math is available
*/
private function hasBigNumber(): bool
{
return class_exists('Moontoast\Math\BigNumber') && !$this->disableBigNumber;
}
/**
* Returns true if ext-gmp is available
*/
private function hasGmp(): bool
{
return extension_loaded('gmp') && !$this->disableGmp;
}
/**
* Returns true if the PHP build is 64-bit
*/
private function is64BitSystem(): bool
{
return PHP_INT_SIZE === 8 && !$this->disable64Bit;
}
}