Completed
Push — master ( 0e67a8...9e7a35 )
by Marcel
02:07
created

Uuid::nil()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace UMA\Uuid;
6
7
/**
8
 * Value object that encapsulates the 128 bits of an UUID.
9
 */
10
class Uuid
11
{
12
    /**
13
     * The 'Nil' UUID described in section 4.1.7 of RFC 4122.
14
     */
15
    const NIL = '00000000-0000-0000-0000-000000000000';
16
17
    /**
18
     * The regular expression of what the value object considers to be a valid UUID in textual form.
19
     *
20
     * It does not try to enforce any particular version.
21
     */
22
    const TEXTUAL_FORMAT = '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i';
23
24
    /**
25
     * Ordered sequence of 16 bytes.
26
     *
27
     * @example 0x96aaab697b764461b008cbb9cfcb6fdf
28
     *
29
     * @var string
30
     */
31
    private $raw;
32
33
    /**
34
     * Textual UUID representation of the $raw byte sequence.
35
     *
36
     * @example '96aaab69-7b76-4461-b008-cbb9cfcb6fdf'
37
     *
38
     * @var string
39
     */
40
    private $textual;
41
42
    /**
43
     * Direct usage of the constructor is only allowed inside the class.
44
     */
45 9
    private function __construct(string $raw, string $textual)
46
    {
47 9
        $this->raw = $raw;
48 9
        $this->textual = strtolower($textual);
49 9
    }
50
51
    /**
52
     * Alias of asString().
53
     */
54 1
    public function __toString(): string
55
    {
56 1
        return $this->asString();
57
    }
58
59
    /**
60
     * Returns the raw 16-byte sequence of the UUID.
61
     */
62 3
    public function asBytes(): string
63
    {
64 3
        return $this->raw;
65
    }
66
67
    /**
68
     * Returns the textual representation of the UUID.
69
     */
70 7
    public function asString(): string
71
    {
72 7
        return $this->textual;
73
    }
74
75
    /**
76
     * Factory to create a new Uuid instance from a raw byte sequence.
77
     *
78
     * Most of the time this method should be used by UuidGenerator
79
     * implementations, not the end user of the library.
80
     *
81
     * @throws \InvalidArgumentException If $bytes is not exactly 16 bytes long.
82
     */
83 7
    public static function fromBytes(string $bytes): Uuid
84
    {
85 7
        if (16 !== strlen($bytes)) {
86 1
            throw new \InvalidArgumentException('Length of $bytes for new Uuid is not 16. Got: 0x' . bin2hex($bytes));
87
        }
88
89 6
        return new self($bytes, self::bin2str($bytes));
90
    }
91
92
    /**
93
     * Factory to create a new Uuid instance from a valid Uuid in string form.
94
     *
95
     * As opposed to the fromBytes() method, this one is meant to
96
     * be used by the end user of the library.
97
     *
98
     * @throws \InvalidArgumentException If $text is not actually a valid Uuid.
99
     */
100 6
    public static function fromString(string $text): Uuid
101
    {
102 6
        if (false === self::isUuid($text)) {
103 1
            throw new \InvalidArgumentException('$text is not a valid Uuid. Got: ' . $text);
104
        }
105
106 5
        return new self(self::str2bin($text), $text);
107
    }
108
109
    /**
110
     * Factory to create a new 'Nil' Uuid instance.
111
     */
112 1
    public static function nil(): Uuid
113
    {
114 1
        return self::fromString(self::NIL);
115
    }
116
117
    /**
118
     * Helper method to validate if a given string can be considered a valid UUID.
119
     */
120 9
    public static function isUuid(string $candidate): bool
121
    {
122 9
        return 1 === preg_match(self::TEXTUAL_FORMAT, $candidate);
123
    }
124
125
    /**
126
     * Turns the textual form of an UUID to its equivalent raw bytes.
127
     *
128
     * Precondition: $uuid is a valid Uuid.
129
     *
130
     * @example '96aaab69-7b76-4461-b008-cbb9cfcb6fdf' => 0x96aaab697b764461b008cbb9cfcb6fdf
131
     */
132 5
    private static function str2bin(string $uuid): string
133
    {
134 5
        return pack('H32', str_replace('-', '', $uuid));
135
    }
136
137
    /**
138
     * Turns the 16 raw bytes of an UUID to its textual form.
139
     *
140
     * Precondition: $bytes is exactly 16 bytes long.
141
     *
142
     * @example 0x96aaab697b764461b008cbb9cfcb6fdf => '96aaab69-7b76-4461-b008-cbb9cfcb6fdf'
143
     */
144 6
    private static function bin2str(string $bytes): string
145
    {
146 6
        return implode('-', unpack('H8a/H4b/H4c/H4d/H12e', $bytes));
147
    }
148
}
149