FeatureSet.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. <?php
  2. /**
  3. * This file is part of the ramsey/uuid library
  4. *
  5. * For the full copyright and license information, please view the LICENSE
  6. * file that was distributed with this source code.
  7. *
  8. * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
  9. * @license http://opensource.org/licenses/MIT MIT
  10. * @link https://benramsey.com/projects/ramsey-uuid/ Documentation
  11. * @link https://packagist.org/packages/ramsey/uuid Packagist
  12. * @link https://github.com/ramsey/uuid GitHub
  13. */
  14. namespace Ramsey\Uuid;
  15. use Ramsey\Uuid\Converter\TimeConverterInterface;
  16. use Ramsey\Uuid\Generator\PeclUuidTimeGenerator;
  17. use Ramsey\Uuid\Provider\Node\FallbackNodeProvider;
  18. use Ramsey\Uuid\Provider\Node\RandomNodeProvider;
  19. use Ramsey\Uuid\Provider\Node\SystemNodeProvider;
  20. use Ramsey\Uuid\Converter\NumberConverterInterface;
  21. use Ramsey\Uuid\Converter\Number\BigNumberConverter;
  22. use Ramsey\Uuid\Converter\Number\DegradedNumberConverter;
  23. use Ramsey\Uuid\Converter\Time\BigNumberTimeConverter;
  24. use Ramsey\Uuid\Converter\Time\DegradedTimeConverter;
  25. use Ramsey\Uuid\Converter\Time\PhpTimeConverter;
  26. use Ramsey\Uuid\Provider\Time\SystemTimeProvider;
  27. use Ramsey\Uuid\Builder\UuidBuilderInterface;
  28. use Ramsey\Uuid\Builder\DefaultUuidBuilder;
  29. use Ramsey\Uuid\Codec\CodecInterface;
  30. use Ramsey\Uuid\Codec\StringCodec;
  31. use Ramsey\Uuid\Codec\GuidStringCodec;
  32. use Ramsey\Uuid\Builder\DegradedUuidBuilder;
  33. use Ramsey\Uuid\Generator\RandomGeneratorFactory;
  34. use Ramsey\Uuid\Generator\RandomGeneratorInterface;
  35. use Ramsey\Uuid\Generator\TimeGeneratorFactory;
  36. use Ramsey\Uuid\Generator\TimeGeneratorInterface;
  37. use Ramsey\Uuid\Provider\TimeProviderInterface;
  38. use Ramsey\Uuid\Provider\NodeProviderInterface;
  39. /**
  40. * FeatureSet detects and exposes available features in the current environment
  41. * (32- or 64-bit, available dependencies, etc.)
  42. */
  43. class FeatureSet
  44. {
  45. /**
  46. * @var bool
  47. */
  48. private $disableBigNumber = false;
  49. /**
  50. * @var bool
  51. */
  52. private $disable64Bit = false;
  53. /**
  54. * @var bool
  55. */
  56. private $ignoreSystemNode = false;
  57. /**
  58. * @var bool
  59. */
  60. private $enablePecl = false;
  61. /**
  62. * @var UuidBuilderInterface
  63. */
  64. private $builder;
  65. /**
  66. * @var CodecInterface
  67. */
  68. private $codec;
  69. /**
  70. * @var NodeProviderInterface
  71. */
  72. private $nodeProvider;
  73. /**
  74. * @var NumberConverterInterface
  75. */
  76. private $numberConverter;
  77. /**
  78. * @var RandomGeneratorInterface
  79. */
  80. private $randomGenerator;
  81. /**
  82. * @var TimeGeneratorInterface
  83. */
  84. private $timeGenerator;
  85. /**
  86. * Constructs a `FeatureSet` for use by a `UuidFactory` to determine or set
  87. * features available to the environment
  88. *
  89. * @param bool $useGuids Whether to build UUIDs using the `GuidStringCodec`
  90. * @param bool $force32Bit Whether to force the use of 32-bit functionality
  91. * (primarily for testing purposes)
  92. * @param bool $forceNoBigNumber Whether to disable the use of moontoast/math
  93. * `BigNumber` (primarily for testing purposes)
  94. * @param bool $ignoreSystemNode Whether to disable attempts to check for
  95. * the system host ID (primarily for testing purposes)
  96. * @param bool $enablePecl Whether to enable the use of the `PeclUuidTimeGenerator`
  97. * to generate version 1 UUIDs
  98. */
  99. public function __construct(
  100. $useGuids = false,
  101. $force32Bit = false,
  102. $forceNoBigNumber = false,
  103. $ignoreSystemNode = false,
  104. $enablePecl = false
  105. ) {
  106. $this->disableBigNumber = $forceNoBigNumber;
  107. $this->disable64Bit = $force32Bit;
  108. $this->ignoreSystemNode = $ignoreSystemNode;
  109. $this->enablePecl = $enablePecl;
  110. $this->numberConverter = $this->buildNumberConverter();
  111. $this->builder = $this->buildUuidBuilder();
  112. $this->codec = $this->buildCodec($useGuids);
  113. $this->nodeProvider = $this->buildNodeProvider();
  114. $this->randomGenerator = $this->buildRandomGenerator();
  115. $this->setTimeProvider(new SystemTimeProvider());
  116. }
  117. /**
  118. * Returns the builder configured for this environment
  119. *
  120. * @return UuidBuilderInterface
  121. */
  122. public function getBuilder()
  123. {
  124. return $this->builder;
  125. }
  126. /**
  127. * Returns the UUID UUID coder-decoder configured for this environment
  128. *
  129. * @return CodecInterface
  130. */
  131. public function getCodec()
  132. {
  133. return $this->codec;
  134. }
  135. /**
  136. * Returns the system node ID provider configured for this environment
  137. *
  138. * @return NodeProviderInterface
  139. */
  140. public function getNodeProvider()
  141. {
  142. return $this->nodeProvider;
  143. }
  144. /**
  145. * Returns the number converter configured for this environment
  146. *
  147. * @return NumberConverterInterface
  148. */
  149. public function getNumberConverter()
  150. {
  151. return $this->numberConverter;
  152. }
  153. /**
  154. * Returns the random UUID generator configured for this environment
  155. *
  156. * @return RandomGeneratorInterface
  157. */
  158. public function getRandomGenerator()
  159. {
  160. return $this->randomGenerator;
  161. }
  162. /**
  163. * Returns the time-based UUID generator configured for this environment
  164. *
  165. * @return TimeGeneratorInterface
  166. */
  167. public function getTimeGenerator()
  168. {
  169. return $this->timeGenerator;
  170. }
  171. /**
  172. * Sets the time provider for use in this environment
  173. *
  174. * @param TimeProviderInterface $timeProvider
  175. */
  176. public function setTimeProvider(TimeProviderInterface $timeProvider)
  177. {
  178. $this->timeGenerator = $this->buildTimeGenerator($timeProvider);
  179. }
  180. /**
  181. * Determines which UUID coder-decoder to use and returns the configured
  182. * codec for this environment
  183. *
  184. * @param bool $useGuids Whether to build UUIDs using the `GuidStringCodec`
  185. * @return CodecInterface
  186. */
  187. protected function buildCodec($useGuids = false)
  188. {
  189. if ($useGuids) {
  190. return new GuidStringCodec($this->builder);
  191. }
  192. return new StringCodec($this->builder);
  193. }
  194. /**
  195. * Determines which system node ID provider to use and returns the configured
  196. * system node ID provider for this environment
  197. *
  198. * @return NodeProviderInterface
  199. */
  200. protected function buildNodeProvider()
  201. {
  202. if ($this->ignoreSystemNode) {
  203. return new RandomNodeProvider();
  204. }
  205. return new FallbackNodeProvider([
  206. new SystemNodeProvider(),
  207. new RandomNodeProvider()
  208. ]);
  209. }
  210. /**
  211. * Determines which number converter to use and returns the configured
  212. * number converter for this environment
  213. *
  214. * @return NumberConverterInterface
  215. */
  216. protected function buildNumberConverter()
  217. {
  218. if ($this->hasBigNumber()) {
  219. return new BigNumberConverter();
  220. }
  221. return new DegradedNumberConverter();
  222. }
  223. /**
  224. * Determines which random UUID generator to use and returns the configured
  225. * random UUID generator for this environment
  226. *
  227. * @return RandomGeneratorInterface
  228. */
  229. protected function buildRandomGenerator()
  230. {
  231. return (new RandomGeneratorFactory())->getGenerator();
  232. }
  233. /**
  234. * Determines which time-based UUID generator to use and returns the configured
  235. * time-based UUID generator for this environment
  236. *
  237. * @param TimeProviderInterface $timeProvider
  238. * @return TimeGeneratorInterface
  239. */
  240. protected function buildTimeGenerator(TimeProviderInterface $timeProvider)
  241. {
  242. if ($this->enablePecl) {
  243. return new PeclUuidTimeGenerator();
  244. }
  245. return (new TimeGeneratorFactory(
  246. $this->nodeProvider,
  247. $this->buildTimeConverter(),
  248. $timeProvider
  249. ))->getGenerator();
  250. }
  251. /**
  252. * Determines which time converter to use and returns the configured
  253. * time converter for this environment
  254. *
  255. * @return TimeConverterInterface
  256. */
  257. protected function buildTimeConverter()
  258. {
  259. if ($this->is64BitSystem()) {
  260. return new PhpTimeConverter();
  261. }
  262. if ($this->hasBigNumber()) {
  263. return new BigNumberTimeConverter();
  264. }
  265. return new DegradedTimeConverter();
  266. }
  267. /**
  268. * Determines which UUID builder to use and returns the configured UUID
  269. * builder for this environment
  270. *
  271. * @return UuidBuilderInterface
  272. */
  273. protected function buildUuidBuilder()
  274. {
  275. if ($this->is64BitSystem()) {
  276. return new DefaultUuidBuilder($this->numberConverter);
  277. }
  278. return new DegradedUuidBuilder($this->numberConverter);
  279. }
  280. /**
  281. * Returns true if the system has `Moontoast\Math\BigNumber`
  282. *
  283. * @return bool
  284. */
  285. protected function hasBigNumber()
  286. {
  287. return class_exists('Moontoast\Math\BigNumber') && !$this->disableBigNumber;
  288. }
  289. /**
  290. * Returns true if the system is 64-bit, false otherwise
  291. *
  292. * @return bool
  293. */
  294. protected function is64BitSystem()
  295. {
  296. return PHP_INT_SIZE == 8 && !$this->disable64Bit;
  297. }
  298. }