SerializesAndRestoresModelIdentifiers.php
TLDR
This file provides a trait called SerializesAndRestoresModelIdentifiers
that contains methods for serializing and restoring model identifiers used in the Laravel Queue system.
Methods
getSerializedPropertyValue
This method is used to prepare a property value for serialization. It takes in a value and a boolean flag indicating whether to include relations. If the value is a queueable collection, it creates a new ModelIdentifier
object with the class, IDs, relations, and connection of the collection. If the value is a queueable entity, it creates a new ModelIdentifier
object with the class, ID, relations, and connection of the entity. If the value is neither a queueable collection nor a queueable entity, the value is returned as is.
getRestoredPropertyValue
This method is used to restore a property value after deserialization. It takes in a value and checks if it is an instance of ModelIdentifier
. If it is not, the value is returned as is. If it is, the method checks if the ID is an array. If it is, a collection of models is restored using the restoreCollection
method. If it is not, a single model is restored using the restoreModel
method.
restoreCollection
This method is used to restore a queueable collection instance. It takes in a ModelIdentifier
object and returns a new instance of EloquentCollection
or a custom collection class specified in the ModelIdentifier
. If the class is a pivot table or uses the AsPivot
trait, the collection is returned as is. Otherwise, the collection is keyed by the models' primary keys and filtered to include only models with the specified IDs.
restoreModel
This method is used to restore a model from a ModelIdentifier
instance. It takes in a ModelIdentifier
object and returns the first model that matches the ID and connection, loaded with the specified relations.
getQueryForModelRestoration
This method is used to get the query for model restoration. It takes in a model instance and an ID or array of IDs and returns a new query builder instance for restoration.
<?php
namespace Illuminate\Queue;
use Illuminate\Contracts\Database\ModelIdentifier;
use Illuminate\Contracts\Queue\QueueableCollection;
use Illuminate\Contracts\Queue\QueueableEntity;
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
use Illuminate\Database\Eloquent\Relations\Concerns\AsPivot;
use Illuminate\Database\Eloquent\Relations\Pivot;
trait SerializesAndRestoresModelIdentifiers
{
/**
* Get the property value prepared for serialization.
*
* @param mixed $value
* @param bool $withRelations
* @return mixed
*/
protected function getSerializedPropertyValue($value, $withRelations = true)
{
if ($value instanceof QueueableCollection) {
return (new ModelIdentifier(
$value->getQueueableClass(),
$value->getQueueableIds(),
$withRelations ? $value->getQueueableRelations() : [],
$value->getQueueableConnection()
))->useCollectionClass(
($collectionClass = get_class($value)) !== EloquentCollection::class
? $collectionClass
: null
);
}
if ($value instanceof QueueableEntity) {
return new ModelIdentifier(
get_class($value),
$value->getQueueableId(),
$withRelations ? $value->getQueueableRelations() : [],
$value->getQueueableConnection()
);
}
return $value;
}
/**
* Get the restored property value after deserialization.
*
* @param mixed $value
* @return mixed
*/
protected function getRestoredPropertyValue($value)
{
if (! $value instanceof ModelIdentifier) {
return $value;
}
return is_array($value->id)
? $this->restoreCollection($value)
: $this->restoreModel($value);
}
/**
* Restore a queueable collection instance.
*
* @param \Illuminate\Contracts\Database\ModelIdentifier $value
* @return \Illuminate\Database\Eloquent\Collection
*/
protected function restoreCollection($value)
{
if (! $value->class || count($value->id) === 0) {
return ! is_null($value->collectionClass ?? null)
? new $value->collectionClass
: new EloquentCollection;
}
$collection = $this->getQueryForModelRestoration(
(new $value->class)->setConnection($value->connection), $value->id
)->useWritePdo()->get();
if (is_a($value->class, Pivot::class, true) ||
in_array(AsPivot::class, class_uses($value->class))) {
return $collection;
}
$collection = $collection->keyBy->getKey();
$collectionClass = get_class($collection);
return new $collectionClass(
collect($value->id)->map(function ($id) use ($collection) {
return $collection[$id] ?? null;
})->filter()
);
}
/**
* Restore the model from the model identifier instance.
*
* @param \Illuminate\Contracts\Database\ModelIdentifier $value
* @return \Illuminate\Database\Eloquent\Model
*/
public function restoreModel($value)
{
return $this->getQueryForModelRestoration(
(new $value->class)->setConnection($value->connection), $value->id
)->useWritePdo()->firstOrFail()->load($value->relations ?? []);
}
/**
* Get the query for model restoration.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param array|int $ids
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function getQueryForModelRestoration($model, $ids)
{
return $model->newQueryForRestoration($ids);
}
}