diff --git a/composer.json b/composer.json index 082e1dee54a6..dfbdf5d129a2 100644 --- a/composer.json +++ b/composer.json @@ -94,7 +94,8 @@ "phpstan/phpstan": "^1.4.7", "phpunit/phpunit": "^9.5.8", "predis/predis": "^1.1.9|^2.0", - "symfony/cache": "^6.0" + "symfony/cache": "^6.0", + "symfony/uid": "^6.0" }, "provide": { "psr/container-implementation": "1.1|2.0", @@ -163,7 +164,8 @@ "symfony/http-client": "Required to enable support for the Symfony API mail transports (^6.0).", "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.0).", "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0).", - "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0).", + "symfony/uid": "Required to generate ULIDs for Eloquent (^6.0)." }, "config": { "sort-packages": true, diff --git a/src/Illuminate/Database/Eloquent/Concerns/HasUlids.php b/src/Illuminate/Database/Eloquent/Concerns/HasUlids.php new file mode 100644 index 000000000000..7456ee98b238 --- /dev/null +++ b/src/Illuminate/Database/Eloquent/Concerns/HasUlids.php @@ -0,0 +1,64 @@ +uniqueIds() as $column) { + if (empty($model->{$column})) { + $model->{$column} = $model->newUniqueId(); + } + } + }); + } + + /** + * Generate a new ULID for the model. + * + * @return string + */ + public function newUniqueId() + { + return strtolower((string) Str::ulid()); + } + + /** + * Get the columns that should receive a unique identifier. + * + * @return array + */ + public function uniqueIds() + { + return [$this->getKeyName()]; + } + + /** + * Get the auto-incrementing key type. + * + * @return string + */ + public function getKeyType() + { + return 'string'; + } + + /** + * Get the value indicating whether the IDs are incrementing. + * + * @return bool + */ + public function getIncrementing() + { + return false; + } +} diff --git a/src/Illuminate/Database/Eloquent/Concerns/HasUuids.php b/src/Illuminate/Database/Eloquent/Concerns/HasUuids.php new file mode 100644 index 000000000000..2bed18a97d2b --- /dev/null +++ b/src/Illuminate/Database/Eloquent/Concerns/HasUuids.php @@ -0,0 +1,64 @@ +uniqueIds() as $column) { + if (empty($model->{$column})) { + $model->{$column} = $model->newUniqueId(); + } + } + }); + } + + /** + * Generate a new UUID for the model. + * + * @return string + */ + public function newUniqueId() + { + return (string) Str::orderedUuid(); + } + + /** + * Get the columns that should receive a unique identifier. + * + * @return array + */ + public function uniqueIds() + { + return [$this->getKeyName()]; + } + + /** + * Get the auto-incrementing key type. + * + * @return string + */ + public function getKeyType() + { + return 'string'; + } + + /** + * Get the value indicating whether the IDs are incrementing. + * + * @return bool + */ + public function getIncrementing() + { + return false; + } +} diff --git a/src/Illuminate/Support/Str.php b/src/Illuminate/Support/Str.php index 3ca9821f25eb..58ee38525f28 100644 --- a/src/Illuminate/Support/Str.php +++ b/src/Illuminate/Support/Str.php @@ -14,6 +14,7 @@ use Ramsey\Uuid\Generator\CombGenerator; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidFactory; +use Symfony\Component\Uid\Ulid; use Traversable; use voku\helper\ASCII; @@ -424,6 +425,21 @@ public static function isUuid($value) return preg_match('/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iD', $value) > 0; } + /** + * Determine if a given string is a valid ULID. + * + * @param string $value + * @return bool + */ + public static function isUlid($value) + { + if (! is_string($value)) { + return false; + } + + return Ulid::isValid($value); + } + /** * Convert a string to kebab case. * @@ -1306,6 +1322,16 @@ public static function createUuidsNormally() static::$uuidFactory = null; } + /** + * Generate a ULID. + * + * @return \Symfony\Component\Uid\Ulid + */ + public static function ulid() + { + return new Ulid(); + } + /** * Remove all strings from the casing caches. * diff --git a/src/Illuminate/Support/composer.json b/src/Illuminate/Support/composer.json index 1e1681cee1e7..b8bdef9ffa1d 100644 --- a/src/Illuminate/Support/composer.json +++ b/src/Illuminate/Support/composer.json @@ -46,6 +46,7 @@ "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.0.2).", "ramsey/uuid": "Required to use Str::uuid() (^4.2.2).", "symfony/process": "Required to use the composer class (^6.0).", + "symfony/uid": "Required to generate ULIDs for Eloquent (^6.0).", "symfony/var-dumper": "Required to use the dd function (^6.0).", "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)." }, diff --git a/tests/Integration/Database/EloquentUlidPrimaryKeyTest.php b/tests/Integration/Database/EloquentUlidPrimaryKeyTest.php new file mode 100644 index 000000000000..0fc2a23c2788 --- /dev/null +++ b/tests/Integration/Database/EloquentUlidPrimaryKeyTest.php @@ -0,0 +1,36 @@ +char('id', 26)->primary(); + $table->timestamps(); + }); + } + + public function testUserWithUlidPrimaryKeyCanBeCreated() + { + $user = UserWithUlidPrimaryKey::create(); + + $this->assertTrue(Str::isUlid($user->id)); + } +} + +class UserWithUlidPrimaryKey extends Eloquent +{ + use HasUlids; + + protected $table = 'users'; + + protected $guarded = []; +} diff --git a/tests/Integration/Database/EloquentUuidPrimaryKeyTest.php b/tests/Integration/Database/EloquentUuidPrimaryKeyTest.php new file mode 100644 index 000000000000..06e81fef5151 --- /dev/null +++ b/tests/Integration/Database/EloquentUuidPrimaryKeyTest.php @@ -0,0 +1,36 @@ +uuid('id')->primary(); + $table->timestamps(); + }); + } + + public function testUserWithUuidPrimaryKeyCanBeCreated() + { + $user = UserWithUuidPrimaryKey::create(); + + $this->assertTrue(Str::isUuid($user->id)); + } +} + +class UserWithUuidPrimaryKey extends Eloquent +{ + use HasUuids; + + protected $table = 'users'; + + protected $guarded = []; +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy