Skip to content

Commit

Permalink
[10.x] Add ScopedBy attribute for models (laravel#50034)
Browse files Browse the repository at this point in the history
* [10.x] Introduce ScopedBy attribute for models

* Update HasGlobalScopes.php
  • Loading branch information
emargareten authored Feb 9, 2024
1 parent 6c9cbc9 commit 67a0e47
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/Illuminate/Database/Eloquent/Attributes/ScopedBy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Illuminate\Database\Eloquent\Attributes;

use Attribute;

#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
class ScopedBy
{
/**
* Create a new attribute instance.
*
* @param array|string $classes
* @return void
*/
public function __construct(array|string $classes)
{
}
}
27 changes: 27 additions & 0 deletions src/Illuminate/Database/Eloquent/Concerns/HasGlobalScopes.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,39 @@
namespace Illuminate\Database\Eloquent\Concerns;

use Closure;
use Illuminate\Database\Eloquent\Attributes\ScopedBy;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Support\Arr;
use InvalidArgumentException;
use ReflectionClass;

trait HasGlobalScopes
{
/**
* Boot the has global scopes trait for a model.
*
* @return void
*/
public static function bootHasGlobalScopes()
{
static::addGlobalScopes(static::resolveGlobalScopeAttributes());
}

/**
* Resolve the global scope class names from the attributes.
*
* @return array
*/
public static function resolveGlobalScopeAttributes()
{
$reflectionClass = new ReflectionClass(static::class);

return collect($reflectionClass->getAttributes(ScopedBy::class))
->map(fn ($attribute) => $attribute->getArguments())
->flatten()
->all();
}

/**
* Register a new global scope on the model.
*
Expand Down
15 changes: 15 additions & 0 deletions tests/Database/DatabaseEloquentGlobalScopesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Illuminate\Tests\Database;

use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\Eloquent\Attributes\ScopedBy;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
Expand Down Expand Up @@ -51,6 +52,14 @@ public function testClassNameGlobalScopeIsApplied()
$this->assertEquals([1], $query->getBindings());
}

public function testGlobalScopeInAttributeIsApplied()
{
$model = new EloquentGlobalScopeInAttributeTestModel;
$query = $model->newQuery();
$this->assertSame('select * from "table" where "active" = ?', $query->toSql());
$this->assertEquals([1], $query->getBindings());
}

public function testClosureGlobalScopeIsApplied()
{
$model = new EloquentClosureGlobalScopesTestModel;
Expand Down Expand Up @@ -233,6 +242,12 @@ public static function boot()
}
}

#[ScopedBy(ActiveScope::class)]
class EloquentGlobalScopeInAttributeTestModel extends Model
{
protected $table = 'table';
}

class ActiveScope implements Scope
{
public function apply(Builder $builder, Model $model)
Expand Down

0 comments on commit 67a0e47

Please sign in to comment.