Path: blob/1.0-develop/app/Models/Traits/HasRealtimeIdentifier.php
14042 views
<?php12namespace Pterodactyl\Models\Traits;34use Ramsey\Uuid\Uuid;5use Illuminate\Support\Str;6use Webmozart\Assert\Assert;7use ParagonIE\ConstantTime\Base32;8use Illuminate\Database\Eloquent\Builder;9use Pterodactyl\Models\Attributes\Identifiable;10use Illuminate\Database\Eloquent\Casts\Attribute;1112/**13* Support realtime identifiers on models that do not track an "identifier" column in14* the database. This allows us to make use of the existing data reliant on UUID columns15* while still allowing for output and querying against a more human readable identifier16* value.17*18* @property-read string $identifier19*20* @method static Builder whereIdentifier(string $identifier)21*22* @mixin \Illuminate\Database\Eloquent\Model23*/24trait HasRealtimeIdentifier25{26private static string $identifierPrefix;2728private static string $identifierDataColumn;2930protected function identifier(): Attribute31{32return Attribute::get(function () {33$bytes = Uuid::fromString($this->getRawOriginal(static::$identifierDataColumn))->getBytes();3435return sprintf('%s_%s', static::$identifierPrefix, Base32::encodeUnpadded($bytes));36});37}3839public function scopeWhereIdentifier(Builder $builder, string $identifier): void40{41if (!str_starts_with($identifier, $prefix = self::$identifierPrefix . '_')) {42$builder->whereRaw('0 = 1');4344return;45}4647$bytes = rescue(fn () => Base32::decode(Str::replaceFirst($prefix, '', $identifier)), report: false);48if (empty($bytes)) {49$builder->whereRaw('0 = 1');5051return;52}5354$builder->where(self::$identifierDataColumn, Uuid::fromBytes($bytes)->toString());55}5657protected static function bootHasRealtimeIdentifier(): void58{59$attrs = (new \ReflectionClass(static::class))->getAttributes(Identifiable::class);6061Assert::count(62$attrs,631,64'The #[' . Identifiable::class . '] attribute must be set on ' . static::class . ' to use realtime identifiers.'65);6667$instance = $attrs[0]->newInstance();6869self::$identifierPrefix = $instance->prefix;70self::$identifierDataColumn = $instance->column;71}72}737475