Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • Global filtering - how to use global scope in Laravel Eloquent

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 960
    Comment on it

    I have a situation which will help us to understand the use of Global Filtering.

    Situation:

    I have a published filter that I use for my articles. Guests can only view published articles, logged in users can view and apply filter (?published=0/1):

    To solve this problem we will follow the two step:

    1) Create a class PublishedScope that implements ScopeInterface

    class PublishedScope implements ScopeInterface {
    
    public function apply(Builder $builder)
    {
        $table = $builder->getModel()->getTable();
        $builder->where($table.'.published', '=', 1);
        $this->addWithDrafts($builder);
    }
    
    public function remove(Builder $builder)
    {
        $query = $builder->getQuery();
        $column = $builder->getModel()->getTable().'.published';
        $bindingKey = 0;
        foreach ((array) $query->wheres as $key => $where)
        {
            if ($this->isPublishedConstraint($where, $column))
            {
                unset($query->wheres[$key]);
                $query->wheres = array_values($query->wheres);
                $this->removeBinding($query, $bindingKey);
            }
    
            // Check if where is either NULL or NOT NULL type,
            // if that's the case, don't increment the key
            // since there is no binding for these types
            if ( ! in_array($where['type'], ['Null', 'NotNull'])) $bindingKey++;
        }
    }
    
    protected function removeBinding(Builder $query, $key)
    {
        $bindings = $query->getRawBindings()['where'];
        unset($bindings[$key]);
        $query->setBindings($bindings);
    }
    
    protected function addWithDrafts(Builder $builder)
    {
        $builder->macro('withDrafts', function(Builder $builder)
        {
            $this->remove($builder);
            return $builder;
        });
    }
    

    2 Boot that class in your Eloquent model by calling static::addGlobalScope(new AbcScope)

    // the model
    public static function boot()
    {
        parent::boot();
    
        static::addGlobalScope(new PublishedScope);
    }
    

    If I were you I would use published_at column and check it for null instead of = 1, but that's up to you.

    By this we can solve this issue.

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: