1
|
|
|
<?php |
|
|
|
|
2
|
|
|
/* |
3
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
4
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
5
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
6
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
7
|
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
8
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
9
|
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
10
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
11
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
12
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
13
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
14
|
|
|
*/ |
15
|
|
|
|
16
|
|
|
if (class_exists('MongoId', false)) { |
17
|
|
|
return; |
18
|
|
|
} |
19
|
|
|
|
20
|
|
|
use Alcaeus\MongoDbAdapter\TypeInterface; |
21
|
|
|
use MongoDB\BSON\ObjectID; |
22
|
|
|
|
23
|
|
|
class MongoId implements Serializable, TypeInterface, JsonSerializable |
24
|
|
|
{ |
25
|
|
|
/* |
26
|
|
|
* @var ObjectID |
27
|
|
|
*/ |
28
|
|
|
private $objectID; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Creates a new id |
32
|
|
|
* |
33
|
|
|
* |
34
|
|
|
* @link http://www.php.net/manual/en/mongoid.construct.php |
35
|
|
|
* @param string $id [optional] A string to use as the id. Must be 24 hexidecimal characters. If an invalid string is passed to this constructor, the constructor will ignore it and create a new id value. |
36
|
|
|
* |
37
|
|
|
* @throws MongoException |
38
|
|
|
*/ |
39
|
|
|
public function __construct($id = null) |
40
|
|
|
{ |
41
|
|
|
$this->createObjectID($id); |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* Check if a value is a valid ObjectId |
46
|
|
|
* |
47
|
|
|
* @link http://php.net/manual/en/mongoid.isvalid.php |
48
|
|
|
* @param mixed $value The value to check for validity. |
49
|
|
|
* @return bool |
50
|
|
|
*/ |
51
|
|
|
public static function isValid($value) |
52
|
|
|
{ |
53
|
|
|
if ($value instanceof ObjectID || $value instanceof MongoId) { |
54
|
|
|
return true; |
55
|
|
|
} elseif (! is_string($value)) { |
56
|
|
|
return false; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
return (bool) preg_match('#^[a-f0-9]{24}$#i', $value); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Returns a hexidecimal representation of this id |
64
|
|
|
* @link http://www.php.net/manual/en/mongoid.tostring.php |
65
|
|
|
* @return string |
66
|
|
|
*/ |
67
|
|
|
public function __toString() |
68
|
|
|
{ |
69
|
|
|
return (string) $this->objectID; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Converts this MongoId to the new BSON ObjectID type |
74
|
|
|
* |
75
|
|
|
* @return ObjectID |
76
|
|
|
* @internal This method is not part of the ext-mongo API |
77
|
|
|
*/ |
78
|
|
|
public function toBSONType() |
79
|
|
|
{ |
80
|
|
|
return $this->objectID; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* @param string $name |
85
|
|
|
* |
86
|
|
|
* @return null|string |
87
|
|
|
*/ |
88
|
|
|
public function __get($name) |
89
|
|
|
{ |
90
|
|
|
if ($name === '$id') { |
91
|
|
|
return (string) $this->objectID; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
return null; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* @param string $name |
99
|
|
|
* @param mixed $value |
100
|
|
|
*/ |
101
|
|
|
public function __set($name, $value) |
102
|
|
|
{ |
103
|
|
|
if ($name === 'id') { |
104
|
|
|
trigger_error("The '\$id' property is read-only", E_DEPRECATED); |
105
|
|
|
return; |
106
|
|
|
} |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* @param string $name |
111
|
|
|
* @return bool |
112
|
|
|
*/ |
113
|
|
|
public function __isset($name) |
114
|
|
|
{ |
115
|
|
|
return $name === 'id'; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @param string $name |
120
|
|
|
*/ |
121
|
|
|
public function __unset($name) |
122
|
|
|
{ |
123
|
|
|
if ($name === 'id') { |
124
|
|
|
trigger_error("The '\$id' property is read-only", E_DEPRECATED); |
125
|
|
|
return; |
126
|
|
|
} |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* @return string |
131
|
|
|
*/ |
132
|
|
|
public function serialize() |
133
|
|
|
{ |
134
|
|
|
return (string) $this->objectID; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* @param string $serialized |
139
|
|
|
*/ |
140
|
|
|
public function unserialize($serialized) |
141
|
|
|
{ |
142
|
|
|
$this->createObjectID($serialized); |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* Gets the incremented value to create this id |
147
|
|
|
* @link http://php.net/manual/en/mongoid.getinc.php |
148
|
|
|
* @return int Returns the incremented value used to create this MongoId. |
149
|
|
|
*/ |
150
|
|
|
public function getInc() |
151
|
|
|
{ |
152
|
|
|
return hexdec(substr((string) $this->objectID, -6)); |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* (PECL mongo >= 1.0.11) |
157
|
|
|
* Gets the process ID |
158
|
|
|
* @link http://php.net/manual/en/mongoid.getpid.php |
159
|
|
|
* @return int Returns the PID of the MongoId. |
160
|
|
|
*/ |
161
|
|
|
public function getPID() |
162
|
|
|
{ |
163
|
|
|
$id = (string) $this->objectID; |
164
|
|
|
|
165
|
|
|
// PID is stored as little-endian, flip it around |
166
|
|
|
$pid = substr($id, 16, 2) . substr($id, 14, 2); |
167
|
|
|
return hexdec($pid); |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* (PECL mongo >= 1.0.1) |
172
|
|
|
* Gets the number of seconds since the epoch that this id was created |
173
|
|
|
* @link http://www.php.net/manual/en/mongoid.gettimestamp.php |
174
|
|
|
* @return int |
175
|
|
|
*/ |
176
|
|
|
public function getTimestamp() |
177
|
|
|
{ |
178
|
|
|
return hexdec(substr((string) $this->objectID, 0, 8)); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* Gets the hostname being used for this machine's ids |
183
|
|
|
* @link http://www.php.net/manual/en/mongoid.gethostname.php |
184
|
|
|
* @return string |
185
|
|
|
*/ |
186
|
|
|
public static function getHostname() |
187
|
|
|
{ |
188
|
|
|
return gethostname(); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* (PECL mongo >= 1.0.8) |
193
|
|
|
* Create a dummy MongoId |
194
|
|
|
* @link http://php.net/manual/en/mongoid.set-state.php |
195
|
|
|
* @param array $props <p>Theoretically, an array of properties used to create the new id. However, as MongoId instances have no properties, this is not used.</p> |
196
|
|
|
* @return MongoId A new id with the value "000000000000000000000000". |
197
|
|
|
*/ |
198
|
|
|
public static function __set_state(array $props) |
199
|
|
|
{ |
200
|
|
|
|
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* @return stdClass |
205
|
|
|
*/ |
206
|
|
|
public function jsonSerialize() |
207
|
|
|
{ |
208
|
|
|
$object = new stdClass(); |
209
|
|
|
$object->{'$id'} = (string) $this->objectID; |
210
|
|
|
return $object; |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
/** |
214
|
|
|
* @param $id |
215
|
|
|
* @throws MongoException |
216
|
|
|
*/ |
217
|
|
|
private function createObjectID($id) |
218
|
|
|
{ |
219
|
|
|
try { |
220
|
|
|
if (is_string($id)) { |
221
|
|
|
$this->objectID = new ObjectID($id); |
222
|
|
|
} elseif ($id instanceof self || $id instanceof ObjectID) { |
223
|
|
|
$this->objectID = new ObjectID((string) $id); |
224
|
|
|
} else { |
225
|
|
|
$this->objectID = new ObjectID(); |
226
|
|
|
} |
227
|
|
|
} catch (\Exception $e) { |
228
|
|
|
throw new MongoException('Invalid object ID', 19); |
229
|
|
|
} |
230
|
|
|
} |
231
|
|
|
} |
232
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.