SoftDeletingScope.php
TLDR
This file, SoftDeletingScope.php
, contains the implementation of the SoftDeletingScope
class. This class is used in the Laravel framework for applying a soft delete mechanism to Eloquent models.
Methods
apply
This method applies the soft deleting scope to a given Eloquent query builder. It adds a where clause to the builder to filter out records where the deleted_at
column is not null.
extend
This method extends the query builder with several functions related to soft deleting. It adds the necessary extensions to the builder, such as restore
, restoreOrCreate
, createOrRestore
, withTrashed
, withoutTrashed
, and onlyTrashed
. Additionally, it defines the behavior of the onDelete
event, where the deleted_at
column is updated with the current timestamp.
getDeletedAtColumn
This protected method retrieves the name of the "deleted at" column for a given builder. If the builder has joins, it returns the qualified name of the column. Otherwise, it returns the column name defined for the model.
addRestore
This protected method adds the restore
extension to the builder. It configures the builder to include trashed records and sets the deleted_at
column to null for the selected records.
addRestoreOrCreate
This protected method adds the restoreOrCreate
extension to the builder. It configures the builder to include trashed records and performs a firstOrCreate
operation. If a new record is created, it is then restored.
addCreateOrRestore
This protected method adds the createOrRestore
extension to the builder. Similar to addRestoreOrCreate
, it configures the builder to include trashed records and performs a createOrFirst
operation. If a new record is created, it is then restored.
addWithTrashed
This protected method adds the withTrashed
extension to the builder. It allows including the trashed records when querying. If the parameter $withTrashed
is false
, it instead calls withoutTrashed
.
addWithoutTrashed
This protected method adds the withoutTrashed
extension to the builder. It excludes the trashed records from the query by adding a where clause.
addOnlyTrashed
This protected method adds the onlyTrashed
extension to the builder. It includes only the trashed records by adding a where clause.
END
<?php
namespace Illuminate\Database\Eloquent;
class SoftDeletingScope implements Scope
{
/**
* All of the extensions to be added to the builder.
*
* @var string[]
*/
protected $extensions = ['Restore', 'RestoreOrCreate', 'CreateOrRestore', 'WithTrashed', 'WithoutTrashed', 'OnlyTrashed'];
/**
* Apply the scope to a given Eloquent query builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
$builder->whereNull($model->getQualifiedDeletedAtColumn());
}
/**
* Extend the query builder with the needed functions.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
public function extend(Builder $builder)
{
foreach ($this->extensions as $extension) {
$this->{"add{$extension}"}($builder);
}
$builder->onDelete(function (Builder $builder) {
$column = $this->getDeletedAtColumn($builder);
return $builder->update([
$column => $builder->getModel()->freshTimestampString(),
]);
});
}
/**
* Get the "deleted at" column for the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return string
*/
protected function getDeletedAtColumn(Builder $builder)
{
if (count((array) $builder->getQuery()->joins) > 0) {
return $builder->getModel()->getQualifiedDeletedAtColumn();
}
return $builder->getModel()->getDeletedAtColumn();
}
/**
* Add the restore extension to the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
protected function addRestore(Builder $builder)
{
$builder->macro('restore', function (Builder $builder) {
$builder->withTrashed();
return $builder->update([$builder->getModel()->getDeletedAtColumn() => null]);
});
}
/**
* Add the restore-or-create extension to the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
protected function addRestoreOrCreate(Builder $builder)
{
$builder->macro('restoreOrCreate', function (Builder $builder, array $attributes = [], array $values = []) {
$builder->withTrashed();
return tap($builder->firstOrCreate($attributes, $values), function ($instance) {
$instance->restore();
});
});
}
/**
* Add the create-or-restore extension to the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
protected function addCreateOrRestore(Builder $builder)
{
$builder->macro('createOrRestore', function (Builder $builder, array $attributes = [], array $values = []) {
$builder->withTrashed();
return tap($builder->createOrFirst($attributes, $values), function ($instance) {
$instance->restore();
});
});
}
/**
* Add the with-trashed extension to the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
protected function addWithTrashed(Builder $builder)
{
$builder->macro('withTrashed', function (Builder $builder, $withTrashed = true) {
if (! $withTrashed) {
return $builder->withoutTrashed();
}
return $builder->withoutGlobalScope($this);
});
}
/**
* Add the without-trashed extension to the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
protected function addWithoutTrashed(Builder $builder)
{
$builder->macro('withoutTrashed', function (Builder $builder) {
$model = $builder->getModel();
$builder->withoutGlobalScope($this)->whereNull(
$model->getQualifiedDeletedAtColumn()
);
return $builder;
});
}
/**
* Add the only-trashed extension to the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
protected function addOnlyTrashed(Builder $builder)
{
$builder->macro('onlyTrashed', function (Builder $builder) {
$model = $builder->getModel();
$builder->withoutGlobalScope($this)->whereNotNull(
$model->getQualifiedDeletedAtColumn()
);
return $builder;
});
}
}