diff --git a/src/Eloquent/Casts/BinaryUuid.php b/src/Eloquent/Casts/BinaryUuid.php new file mode 100644 index 000000000..1ca9d407a --- /dev/null +++ b/src/Eloquent/Casts/BinaryUuid.php @@ -0,0 +1,63 @@ +getType() !== Binary::TYPE_UUID) { + return $value; + } + + $base16Uuid = bin2hex($value->getData()); + + return sprintf( + '%s-%s-%s-%s-%s', + substr($base16Uuid, 0, 8), + substr($base16Uuid, 8, 4), + substr($base16Uuid, 12, 4), + substr($base16Uuid, 16, 4), + substr($base16Uuid, 20, 12), + ); + } + + /** + * Prepare the given value for storage. + * + * @param Model $model + * @param string $key + * @param mixed $value + * @param array $attributes + * @return mixed + */ + public function set($model, string $key, $value, array $attributes) + { + if ($value instanceof Binary) { + return $value; + } + + if (is_string($value) && strlen($value) === 16) { + return new Binary($value, Binary::TYPE_UUID); + } + + return new Binary(hex2bin(str_replace('-', '', $value)), Binary::TYPE_UUID); + } +} diff --git a/src/Eloquent/Casts/ObjectId.php b/src/Eloquent/Casts/ObjectId.php new file mode 100644 index 000000000..bf34bea2f --- /dev/null +++ b/src/Eloquent/Casts/ObjectId.php @@ -0,0 +1,46 @@ + $saveUuid]); + + $model = CastBinaryUuid::firstWhere('uuid', $queryUuid); + $this->assertNotNull($model); + $this->assertSame($expectedUuid, $model->uuid); + } + + public static function provideBinaryUuidCast(): Generator + { + $uuid = '0c103357-3806-48c9-a84b-867dcb625cfb'; + $binaryUuid = new Binary(hex2bin('0c103357380648c9a84b867dcb625cfb'), Binary::TYPE_UUID); + + yield 'Save Binary, Query Binary' => [$uuid, $binaryUuid, $binaryUuid]; + yield 'Save string, Query Binary' => [$uuid, $uuid, $binaryUuid]; + } + + public function testQueryByStringDoesNotCast(): void + { + $uuid = '0c103357-3806-48c9-a84b-867dcb625cfb'; + + CastBinaryUuid::create(['uuid' => $uuid]); + + $model = CastBinaryUuid::firstWhere('uuid', $uuid); + $this->assertNull($model); + } +} diff --git a/tests/Casts/ObjectIdTest.php b/tests/Casts/ObjectIdTest.php new file mode 100644 index 000000000..d9f385543 --- /dev/null +++ b/tests/Casts/ObjectIdTest.php @@ -0,0 +1,50 @@ + $saveObjectId]); + + $model = CastObjectId::firstWhere('oid', $queryObjectId); + $this->assertNotNull($model); + $this->assertSame($stringObjectId, $model->oid); + } + + public static function provideObjectIdCast(): Generator + { + $objectId = new ObjectId(); + $stringObjectId = (string) $objectId; + + yield 'Save ObjectId, Query ObjectId' => [$objectId, $objectId]; + yield 'Save string, Query ObjectId' => [$stringObjectId, $objectId]; + } + + public function testQueryByStringDoesNotCast(): void + { + $objectId = new ObjectId(); + $stringObjectId = (string) $objectId; + + CastObjectId::create(['oid' => $objectId]); + + $model = CastObjectId::firstWhere('oid', $stringObjectId); + $this->assertNull($model); + } +} diff --git a/tests/Models/CastBinaryUuid.php b/tests/Models/CastBinaryUuid.php new file mode 100644 index 000000000..cb8aa5537 --- /dev/null +++ b/tests/Models/CastBinaryUuid.php @@ -0,0 +1,17 @@ + BinaryUuid::class, + ]; +} diff --git a/tests/Models/CastObjectId.php b/tests/Models/CastObjectId.php new file mode 100644 index 000000000..0c82cb9f8 --- /dev/null +++ b/tests/Models/CastObjectId.php @@ -0,0 +1,17 @@ + ObjectId::class, + ]; +}