Repository Pattern Laravel
<?php namespace App\Repositories;
use Fhferreira\Repositories\Contracts\RepositoryInterface;
use Fhferreira\Repositories\Eloquent\Repository;
class ActorRepository extends Repository {
/**
* Specify Model class name
*
* @return mixed
*/
function model()
{
return 'Fhferreira\Models\Actor';
}
}
<?php namespace App\Http\Controllers;
use App\Repositories\ActorRepository as Actor;
class ActorsController extends Controller {
/**
* @var Actor
*/
private $actor;
public function __construct(Actor $actor) {
$this->actor = $actor;
}
public function index() {
return \Response::json($this->actor->all());
}
}
<?php namespace Fhferreira\Repositories\Criteria;
use Bosnadev\Repositories\Contracts\RepositoryInterface as Repository;
use Bosnadev\Repositories\Contracts\RepositoryInterface;
abstract class Criteria {
/**
* @param $model
* @param RepositoryInterface $repository
* @return mixed
*/
public abstract function apply($model, Repository $repository);
}
<?php namespace Fhferreira\Repositories\Contracts;
use Fhferreira\Repositories\Criteria\Criteria;
/**
* Interface CriteriaInterface
* @package Fhferreira\Repositories\Contracts
*/
interface CriteriaInterface {
/**
* @param bool $status
* @return $this
*/
public function skipCriteria($status = true);
/**
* @return mixed
*/
public function getCriteria();
/**
* @param Criteria $criteria
* @return $this
*/
public function getByCriteria(Criteria $criteria);
/**
* @param Criteria $criteria
* @return $this
*/
public function pushCriteria(Criteria $criteria);
/**
* @return $this
*/
public function applyCriteria();
}
<?php namespace App\Http\Controllers;
use App\Repositories\Criteria\Films\LengthOverTwoHours;
use App\Repositories\FilmRepository as Film;
class FilmsController extends Controller {
/**
* @var Film
*/
private $film;
public function __construct(Film $film) {
$this->film = $film;
}
public function index() {
//$this->film->pushCriteria(new LengthOverTwoHours());
//return \Response::json($this->film->all()); or
$criteria = new LengthOverTwoHours();
return \Response::json($this->film->getByCriteria($criteria)->all());
}
}
<?php namespace App\Repositories\Criteria\Films;
use Fhferreira\Repositories\Contracts\CriteriaInterface;
use Fhferreira\Repositories\Contracts\RepositoryInterface as Repository;
use Fhferreira\Repositories\Contracts\RepositoryInterface;
class LengthOverTwoHours implements CriteriaInterface {
/**
* @param $model
* @param RepositoryInterface $repository
* @return mixed
*/
public function apply($model, Repository $repository)
{
$query = $model->where('length', '>', 120);
return $query;
}
}
<?php namespace Fhferreira\Repositories\Eloquent;
use Fhferreira\Repositories\Contracts\RepositoryInterface;
use Fhferreira\Repositories\Exceptions\RepositoryException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Container\Container as App;
/**
* Class Repository
* @package Fhferreira\Repositories\Eloquent
*/
abstract class Repository implements RepositoryInterface {
/**
* @var App
*/
private $app;
/**
* @var
*/
protected $model;
/**
* @param App $app
* @throws \Fhferreira\Repositories\Exceptions\RepositoryException
*/
public function __construct(App $app) {
$this->app = $app;
$this->makeModel();
}
/**
* Specify Model class name
*
* @return mixed
*/
abstract function model();
/**
* @param array $columns
* @return mixed
*/
public function all($columns = array('*')) {
return $this->model->get($columns);
}
/**
* @param int $perPage
* @param array $columns
* @return mixed
*/
public function paginate($perPage = 15, $columns = array('*')) {
return $this->model->paginate($perPage, $columns);
}
/**
* @param array $data
* @return mixed
*/
public function create(array $data) {
return $this->model->create($data);
}
/**
* @param array $data
* @param $id
* @param string $attribute
* @return mixed
*/
public function update(array $data, $id, $attribute="id") {
return $this->model->where($attribute, '=', $id)->update($data);
}
/**
* @param $id
* @return mixed
*/
public function delete($id) {
return $this->model->destroy($id);
}
/**
* @param $id
* @param array $columns
* @return mixed
*/
public function find($id, $columns = array('*')) {
return $this->model->find($id, $columns);
}
/**
* @param $attribute
* @param $value
* @param array $columns
* @return mixed
*/
public function findBy($attribute, $value, $columns = array('*')) {
return $this->model->where($attribute, '=', $value)->first($columns);
}
/**
* @return \Illuminate\Database\Eloquent\Builder
* @throws RepositoryException
*/
public function makeModel() {
$model = $this->app->make($this->model());
if (!$model instanceof Model)
throw new RepositoryException("Class {$this->model()} must be an instance of Illuminate\\Database\\Eloquent\\Model");
return $this->model = $model->newQuery();
}
}
<?php namespace Fhferreira\Repositories\Contracts;
interface RepositoryInterface {
public function all($columns = array('*'));
public function paginate($perPage = 15, $columns = array('*'));
public function create(array $data);
public function update(array $data, $id);
public function delete($id);
public function find($id, $columns = array('*'));
public function findBy($field, $value, $columns = array('*'));
}