Skip to content

Instantly share code, notes, and snippets.

@jhaoda
Created April 18, 2015 14:33
Show Gist options
  • Save jhaoda/5a8ed894413f2567c77b to your computer and use it in GitHub Desktop.
Save jhaoda/5a8ed894413f2567c77b to your computer and use it in GitHub Desktop.
Repository pattern
<?php
namespace App\Repositories;
use App\Model;
use App\Repositories\Contracts\Repository as RepositoryContract;
use InvalidArgumentException;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder as QBuilder;
use Illuminate\Database\Eloquent\Builder as EBuilder;
use Illuminate\Contracts\Pagination\Paginator as PaginatorContract;
abstract class AbstractRepository implements RepositoryContract
{
/**
* @type SoftDeletes|Model
*/
protected $model;
/**
* @type array
*/
private $relations = [];
/**
* Specify the entity class name.
*
* @return object|string
*/
abstract protected function getModelClass();
public function __construct()
{
$model = app()->make($this->getModelClass());
if (!$model instanceof Model) {
throw new InvalidArgumentException(
sprintf('Class "%s" must be an instance of "%s"', $this->getModelClass(), Model::class)
);
}
$this->model = $model;
}
/**
* Добавить связи для жадной загрузки.
*
* @param mixed $relations
*
* @return $this
*/
public function addRelations($relations)
{
if (is_string($relations)) {
$relations = func_get_args();
}
$this->relations = $relations;
return $this;
}
/**
* Загрузить связи.
*
* @param mixed $relations
*
* @return EBuilder|QBuilder|Model|SoftDeletes
*/
protected function with($relations = null)
{
if (is_string($relations)) {
$relations = func_get_args();
}
$relations = array_merge($this->relations, $relations);
return $this->model->with($relations);
}
/**
* {@inheritdoc}
*/
public function all($columns = ['*'], $orderBy = 'created_at', $sort = 'DESC')
{
return $this->model->orderBy($orderBy, $sort)->get($columns);
}
/**
* {@inheritdoc}
*/
public function find($id, $columns = ['*'], $withTrashed = false)
{
if ($withTrashed) {
$query = $this->model->withTrashed();
} else {
$query = $this->model->newQuery();
}
return $query->find($id, $columns);
}
/**
* {@inheritdoc}
*/
public function getFirstBy($key, $operator = null, $value = null)
{
return $this->model->where($key, $operator, $value)->first();
}
/**
* {@inheritdoc}
*/
public function getManyBy($key, $operator = null, $value = null)
{
return $this->model->where($key, $operator, $value)->get();
}
/**
* {@inheritdoc}
*/
public function save($model)
{
if ($model->getDirty()) {
return $model->save();
}
return $model->touch();
}
public function update($model, $attrs)
{
if (is_numeric($model)) {
$model = $this->find($model);
}
if ($attrs instanceof FormRequest) {
$attrs = $attrs->all();
}
/** @type Model $model */
return $model->fill($attrs)->save();
}
public function delete($model)
{
return $model->delete();
}
}
<?php
namespace App\Repositories;
use App\Post;
use Illuminate\Database\Eloquent\Builder;
class PostsRepository extends AbstractRepository
{
/**
* @type Post
*/
protected $model;
protected function getModelClass()
{
return Post::class;
}
/**
* Выбрать статьи указанного типа.
*
* @param string $state тип статьи ('*' для статей всех типов)
*
* @return PrettyPaginator
*/
public function allByStatePaginated($state = Post::STATE_PUBLISHED)
{
/** @type Post|Builder $query */
$query = $this->with('author');
if ('*' != $state) {
$query->state($state);
}
return $this->paginate($query);
}
/**
* Найти пост по slug.
*
* @param string $slug
*
* @return \Illuminate\Database\Eloquent\Model|null|static
*/
public function findBySlug($slug)
{
return $this->getFirstBy('slug', '=', $slug);
}
/**
* Получить все посты по автору.
*
* @param int $id
*
* @return \Illuminate\Contracts\Pagination\Paginator|\Vr\Services\PrettyPaginator
*/
public function getByAuthor($id)
{
$query = $this->with('author')->where('author_id', '=', $id);
return $this->paginate($query);
}
}
<?php
namespace App\Repositories\Contracts;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
interface Repository
{
/**
* Get all items.
*
* @param array $columns columns to select
* @param string $orderBy column to sort by
* @param string $sort sort direction
*
* @return Collection
*/
public function all($columns = ['*'], $orderBy = 'created_at', $sort = 'DECS');
/**
* Find a entity by id.
*
* @param int $id
* @param array $columns
* @param bool $withTrashed
*
* @return Model
*/
public function find($id, $columns = ['*'], $withTrashed = false);
/**
* Find a single entity by key value
*
* @param string $key
* @param mixed $operator
* @param mixed $value
*
* @return Model
*/
public function getFirstBy($key, $operator = null, $value = null);
/**
* Find many entities by key value.
*
* @param string $key
* @param mixed $operator
* @param mixed $value
*
* @return Collection
*/
public function getManyBy($key, $operator = null, $value = null);
/**
* Save the new entity or touch existing.
*
* @param Model $model
*
* @return Model
*/
public function save($model);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment