Skip to content

Commit 546a7b9

Browse files
committed
[String] Added support for UUID
1 parent f632b76 commit 546a7b9

File tree

4 files changed

+255
-1
lines changed

4 files changed

+255
-1
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ before_install:
5757
sudo wget -O - http://packages.couchbase.com/ubuntu/couchbase.key | sudo apt-key add -
5858
echo "deb http://packages.couchbase.com/ubuntu xenial xenial/main" | sudo tee /etc/apt/sources.list.d/couchbase.list
5959
sudo apt update
60-
sudo apt install -y librabbitmq-dev libsodium-dev libcouchbase-dev zlib1g-dev
60+
sudo apt install -y librabbitmq-dev libsodium-dev libcouchbase-dev zlib1g-dev php-uuid
6161
6262
- |
6363
# Start Couchbase

src/Symfony/Component/String/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ CHANGELOG
1111
* added the `s()` helper method to get either an `UnicodeString` or `ByteString` instance,
1212
depending of the input string UTF-8 compliancy
1313
* added `$cut` parameter to `Symfony\Component\String\AbstractString::truncate()`
14+
* added support for `Uuid`
1415

1516
5.0.0
1617
-----
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\String\Tests;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\String\Uuid;
16+
17+
/**
18+
* @requires function uuid_is_valid
19+
*/
20+
class UuidTest extends TestCase
21+
{
22+
private const AN_UUID_V1 = 'd9e7a184-5d5b-11ea-a62a-3499710062d0';
23+
private const AN_UUID_V4 = 'd6b3345b-2905-4048-a83c-b5988e765d98';
24+
25+
public function testConstructorWithInvalidUuid()
26+
{
27+
$this->expectException(\InvalidArgumentException::class);
28+
$this->expectExceptionMessage('The UUID is not valid.');
29+
30+
new Uuid('this is not an uuid');
31+
}
32+
33+
public function testConstructorWithValidUuid()
34+
{
35+
$uuid = new Uuid(self::AN_UUID_V4);
36+
37+
$this->assertSame(self::AN_UUID_V4, (string) $uuid);
38+
$this->assertSame('"'.self::AN_UUID_V4.'"', json_encode($uuid));
39+
}
40+
41+
public function testV1()
42+
{
43+
$uuid = Uuid::v1();
44+
45+
$this->assertSame(Uuid::TYPE_1, $uuid->getType());
46+
}
47+
48+
public function testV3()
49+
{
50+
$uuid = Uuid::v3(new Uuid(self::AN_UUID_V4), 'the name');
51+
52+
$this->assertSame(Uuid::TYPE_3, $uuid->getType());
53+
}
54+
55+
public function testV4()
56+
{
57+
$uuid = Uuid::v4();
58+
59+
$this->assertSame(Uuid::TYPE_4, $uuid->getType());
60+
}
61+
62+
public function testV5()
63+
{
64+
$uuid = Uuid::v5(new Uuid(self::AN_UUID_V4), 'the name');
65+
66+
$this->assertSame(Uuid::TYPE_5, $uuid->getType());
67+
}
68+
69+
public function testBinary()
70+
{
71+
$uuid = new Uuid(self::AN_UUID_V4);
72+
73+
$this->assertSame(self::AN_UUID_V4, (string) Uuid::fromBinary($uuid->toBinary()));
74+
}
75+
76+
public function testIsNull()
77+
{
78+
$uuid = new Uuid(self::AN_UUID_V1);
79+
$this->assertFalse($uuid->isNull());
80+
81+
$uuid = new Uuid('00000000-0000-0000-0000-000000000000');
82+
$this->assertTrue($uuid->isNull());
83+
}
84+
85+
public function testIsEqualsTo()
86+
{
87+
$uuid1 = new Uuid(self::AN_UUID_V1);
88+
$uuid2 = new Uuid(self::AN_UUID_V4);
89+
90+
$this->assertTrue($uuid1->isEqualsTo($uuid1));
91+
$this->assertFalse($uuid1->isEqualsTo($uuid2));
92+
}
93+
94+
public function testCompare()
95+
{
96+
$uuids = [];
97+
98+
$uuids[] = $b = new Uuid('00000000-0000-0000-0000-00000000000b');
99+
$uuids[] = $a = new Uuid('00000000-0000-0000-0000-00000000000a');
100+
$uuids[] = $d = new Uuid('00000000-0000-0000-0000-00000000000d');
101+
$uuids[] = $c = new Uuid('00000000-0000-0000-0000-00000000000c');
102+
103+
$this->assertNotSame([$a, $b, $c, $d], $uuids);
104+
105+
usort($uuids, function (Uuid $a, Uuid $b): int {
106+
return $a->compare($b);
107+
});
108+
109+
$this->assertSame([$a, $b, $c, $d], $uuids);
110+
}
111+
112+
public function testExtraMethods()
113+
{
114+
$uuid = new Uuid(self::AN_UUID_V1);
115+
116+
$this->assertSame(UUID_VARIANT_DCE, $uuid->getVariant());
117+
$this->assertSame(1583245966, $uuid->getTime());
118+
$this->assertSame('3499710062d0', $uuid->getMac());
119+
}
120+
}

src/Symfony/Component/String/Uuid.php

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\String;
13+
14+
/**
15+
* @author Grégoire Pineau <lyrixx@lyrixx.info>
16+
*/
17+
final class Uuid implements \JsonSerializable
18+
{
19+
public const TYPE_1 = UUID_TYPE_TIME;
20+
public const TYPE_3 = UUID_TYPE_MD5;
21+
public const TYPE_4 = UUID_TYPE_RANDOM;
22+
public const TYPE_5 = UUID_TYPE_SHA1;
23+
24+
public const VARIANT_NCS = UUID_VARIANT_NCS;
25+
public const VARIANT_DCE = UUID_VARIANT_DCE;
26+
public const VARIANT_MICROSOFT = UUID_VARIANT_MICROSOFT;
27+
public const VARIANT_OTHER = UUID_VARIANT_OTHER;
28+
29+
private $uuid;
30+
31+
public function __construct(string $uuid)
32+
{
33+
self::checkIfExtensionIsLoaded();
34+
35+
if (!uuid_is_valid($uuid)) {
36+
throw new \InvalidArgumentException('The UUID is not valid.');
37+
}
38+
39+
$this->uuid = $uuid;
40+
}
41+
42+
public static function v1(): self
43+
{
44+
self::checkIfExtensionIsLoaded();
45+
46+
return new self(uuid_create(\UUID_TYPE_TIME));
47+
}
48+
49+
public static function v3(self $uuidNamespace, string $name): self
50+
{
51+
self::checkIfExtensionIsLoaded();
52+
53+
return new self(uuid_generate_md5($uuidNamespace->uuid, $name));
54+
}
55+
56+
public static function v4(): self
57+
{
58+
self::checkIfExtensionIsLoaded();
59+
60+
return new self(uuid_create(\UUID_TYPE_RANDOM));
61+
}
62+
63+
public static function v5(self $uuidNamespace, string $name): self
64+
{
65+
self::checkIfExtensionIsLoaded();
66+
67+
return new self(uuid_generate_sha1($uuidNamespace->uuid, $name));
68+
}
69+
70+
public static function fromBinary(string $uuidAsBinary): self
71+
{
72+
self::checkIfExtensionIsLoaded();
73+
74+
return new self(uuid_unparse($uuidAsBinary));
75+
}
76+
77+
public function toBinary(): string
78+
{
79+
return uuid_parse($this->uuid);
80+
}
81+
82+
public function isNull(): bool
83+
{
84+
return uuid_is_null($this->uuid);
85+
}
86+
87+
public function isEqualsTo(self $other): bool
88+
{
89+
return $this->uuid === $other->uuid;
90+
}
91+
92+
public function compare(self $other): int
93+
{
94+
return uuid_compare($this->uuid, $other->uuid);
95+
}
96+
97+
public function getType(): int
98+
{
99+
return uuid_type($this->uuid);
100+
}
101+
102+
public function getVariant(): int
103+
{
104+
return uuid_variant($this->uuid);
105+
}
106+
107+
public function getTime(): int
108+
{
109+
return uuid_time($this->uuid);
110+
}
111+
112+
public function getMac(): string
113+
{
114+
return uuid_mac($this->uuid);
115+
}
116+
117+
public function __toString()
118+
{
119+
return $this->uuid;
120+
}
121+
122+
public function jsonSerialize(): string
123+
{
124+
return $this->uuid;
125+
}
126+
127+
private static function checkIfExtensionIsLoaded()
128+
{
129+
if (!\function_exists('uuid_is_valid')) {
130+
throw new \LogicException(sprintf('You cannot use the "%s" class as the UUID extension is not installed. Try running "composer require symfony/polyfill-uuid".', __CLASS__));
131+
}
132+
}
133+
}

0 commit comments

Comments
 (0)