Skip to content

Instantly share code, notes, and snippets.

@DarkGhostHunter
Last active March 17, 2023 09:29
Show Gist options
  • Save DarkGhostHunter/91dae1ecd966a0e3d47648653efaf9fa to your computer and use it in GitHub Desktop.
Save DarkGhostHunter/91dae1ecd966a0e3d47648653efaf9fa to your computer and use it in GitHub Desktop.
An Eloquent Scope that extends the builder with private/protected methods.
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Support\Collection;
use ReflectionClass
use SplFixedArray;
class ExtendableScope implements Scope
{
/**
* List of (fixed) methods for the current scope.
*
* @var \SplFixedArray(int, \ReflectionMethod)
*/
protected static SplFixedArray $methods;
/**
* 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): void
{
// ...
}
/**
* Extend the Eloquent Query Builder instance with macros.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
public function extend(Builder $builder): void
{
static::$methods ??= SplFixedArray::fromArray(
Collection::make((new ReflectionClass($this))->getMethods())
->filter(fn($method) => !$method->isPublic() && !$method->isStatic())
->toArray()
);
foreach (static::$methods) as $method) {
$builder->macro($method, $method->getClosure());
}
}
/**
* This is an example method that will be added to query builder.
*
* @example Model::where('adult', true)->age(28);
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param int $age
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function age(Builder $query, int $age): Builder
{
return $query->where('age', $age);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment