GithubHelp home page GithubHelp logo

ferpetrelli / scoped-controller Goto Github PK

View Code? Open in Web Editor NEW
1.0 2.0 1.0 12 KB

Very simple controller that automatically execute scopes based on URL parameters

License: MIT License

PHP 100.00%
scopes filter controller laravel parameters

scoped-controller's Introduction

Scoped Controller

Scoped Controller is a very simple Laravel package (<80 LOC) that will allow you to build queries and cleanup your controllers by executing scopes based on request parameters.

Inspired on the Ruby on Rails gem Has Scope.

Install

Just include it in your composer.json file

composer require petrelli/scoped-controller

Or add:

"petrelli/scoped-controller": "0.9.*"

And run composer update.

Basic Usage

Imagine we have a Book model with two filters, by year and by author.

URL parameters might look like the following:

# Get books filtered by year == 2020
/books?byYear=2020

# Get books filtered by author == cortazar
/books?byAuthor=cortazar

# Get books filtered by year and author
/books?byYear=1961&byAuthor=borges

Steps

  1. Create your controller and be sure to inherit from Petrelli\ScopedController\BaseController.

  2. Define which class will hold your collection with the $entity variable. Usually an Eloquent Model, but could be any class that respond to scopes.

protected $entity = Book::class;
  1. Now define the $scopes variable as an Array following the pattern [ URLparameter => scopeName, .... ]
use Petrelli\ScopedController\BaseController;

class EventsController extends BaseController {

// Here as an example we have two scopes: year and author.
// They will be called if we receive the parameters
// byYear and byAuthor respectively.
protected $scopes = [
    'byYear'   => 'year',
    'byAuthor' => 'author',
];

}
  1. Now to get a filtered collection simply call $this->collection(). You can use any available function. If using Eloquent, you could use get(), paginate(...), or anything you need to chain.
$items = $this->collection()->get();
$items = $this->collection()->paginate(static::PER_PAGE);

Customizing the scopes chain

We provide a controller function named beginOfAssociationChain() that you could overload. In there we build the base query over which we will apply all of our scopes.

For example:

protected function beginOfAssociationChain()
{
    return Book::published()->where('library', 'NYC');
}

Here every time we call $this->collection() as previously described we will be executing the published() scope, and also filtering books where 'library' is 'NYC'.

$items = $this->collection()->get();
$items = $this->collection()->paginate(static::PER_PAGE);

Applying scopes manually

We provide the function applyScopes($query) in case you want to manually apply your scopes to a query. As always, which scope will be triggered is a function of the request parameters.

// Controller function
public function index()
{
    $items = $this->applyScopes(Book::query())->get();
}

Extra functionality

Scopes with multi-value parameters

If you need to define a multi-value parameter just pass it as an array and define the scopes as the following:

// Here as an example we have two scopes: year and author.
// They will be called if we receive the parameters
// byYear and byAuthor respectively.
protected $scopes = [
    'byYear'   => 'year',
    'byAuthor' => 'author',
    'sortBy'   => ['sort_by' ['field', 'direction']],
];

Defining the scope as an array will allow you to pass multiple parameters to it coming from the URL as arrays.

Multi-value scopes in action

# Get books filtered by year = 2018 and sorted by author in alphabetical order
/books?byYear=2018&sortBy['field']=author&sortBy['direction']=asc

# Get books filtered by author = borges and sorted by date
/books?byAuthor=borges&sortBy['field']=date&sortBy['direction']=desc

You get the idea. The scope is nothing but a simple two parameter element.

public function scopeSortBy($query, $value, $direction = 'asc')
{
    //...
}

Of course you can generalize to use any number of parameters. Simply add it to the $scopes definition.

Check if any filter is present

Common use case, if you need to check if any scope is present:

// Returns true/false
$this->hasAnyScope()

Use specific scopes for different actions

Because $this->collection() is returning a Query Builder (when using Eloquent for example), you could keep chaining methods and scopes as you would normally do:

public function index()
{
    // Return Books triggering defined scopes
    $items = $this->collection()->get();
}

public function indexBestSellers()
{
    // Return Books triggering defined scopes + bestSeller scope
    $items = $this->collection()->bestSeller()->get();
}

License

The MIT License (MIT). Please see License File for more information.

scoped-controller's People

Contributors

ferpetrelli avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Forkers

mazeeblanke

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.