Skip to content

Instantly share code, notes, and snippets.

@greabock
Created September 19, 2016 17:38
Show Gist options
  • Save greabock/ed4663d9c78a82ec92cfe8b218f70028 to your computer and use it in GitHub Desktop.
Save greabock/ed4663d9c78a82ec92cfe8b218f70028 to your computer and use it in GitHub Desktop.
datatables
<?php
namespace App\Backend\Http\Datatables;
use Datatables;
abstract class AbstractTable
{
/**
* @var Builder
*/
protected $html;
/**
* @var bool
*/
protected $isBuilt;
/**
* @var \Illuminate\Database\Query\Builder
*/
protected $query;
/**
* AbstractTable конструктор.
*
* @param Builder $html
*
*/
public function __construct(Builder $html)
{
$this->html = $html;
$this->html->parameters([
'language' => trans('datatables'),
]);
}
/**
* Возвращает html-код таблицы.
*
* @param array $attributes
* @return string
*/
public function show(array $attributes = [])
{
$this->buildIfNotBuilt();
return $this->html->table($attributes);
}
public function clientSide()
{
$this->html->parameters([
'serverSide' => false,
]);
return $this;
}
/**
* Устанавливает url источника данных для таблицы.
* (по умолчанию, это текущий url).
* @param string $attr
* @return $this
*/
public function ajax($attr)
{
$this->html->ajax($attr);
return $this;
}
/**
* Возвращет javascript-код инициализации таблицы.
*
* @param null $id
*
* @return string
*/
public function script($id = null)
{
$this->buildIfNotBuilt();
return $this->html->scripts(null, ['type' => 'text/javascript'], $id);
}
/**
* Строит таблицу, если она еще не построена.
*
* @return void
*/
public function buildIfNotBuilt()
{
if (!$this->isBuilt()) {
$this->build();
}
}
/**
* Проверяет построена ли данная таблица.
*
* @return bool
*/
private function isBuilt()
{
return $this->isBuilt;
}
/**
* Устанавливет флаг "построен" в истинное значение.
*
*/
private function setBuilt()
{
$this->isBuilt = true;
}
/**
* Строит таблицу.
*
* @return void
*/
private function build()
{
foreach ($this->getTableColumns() as $column) {
$this->html->addColumn($column);
}
$this->setBuilt();
}
/**
* Возвращает данные для наполнения таблицы.
*
* @return \Illuminate\Http\JsonResponse
*/
public function data()
{
return $this->addColumns(
$this->morphColumns(
Datatables::of(
$this->prepareQuery()
)))->make(true);
}
/**
* Запускает все модификаторы колонок.
*
* @param object $table
* @return object
*/
private function morphColumns($table)
{
foreach ($this->getColumnMutators() as $column => $editor) {
$table->editColumn($column, $editor);
}
return $table;
}
/**
* Добавляет дополнительные колнки.
*
* @param object $table
* @return object
*/
private function addColumns($table)
{
foreach ($this->getColumnCreators() as $title => $creator) {
$table->addColumn($title, $creator);
}
return $table;
}
/**
* Устанавливает поля таблицы бд для выборки.
*
* @return \Illuminate\Database\Query\Builder
*/
protected function prepareQuery()
{
$query = $this->query()->select($this->getDatabaseFields());
foreach ($this->getJoins() as $join) {
call_user_func_array([$query, array_shift($join)], $join);
}
return $query;
}
/**
* Возвращает массив модификаторов join.
*
* ['join'|'leftJoin'|'rightJoin', 'table_name', 'первый.операнд', 'оператор сопоставления', 'второй.операнд']
* и/или
* ['join'|'leftJoin'|'rightJoin', 'table_name', $замыкание($join)]
*
* @see https://laravel.com/docs/5.2/queries#joins
*/
protected function getJoins()
{
return [];
}
/**
* @return \Illuminate\Database\Query\Builder
*/
public function query()
{
return $this->query ?: $this->query = $this->getQuery();
}
/**
* Возвращает список полей для получения из бд.
* ['поле_1', 'поле_2', DB::raw('выражение поля 3'), 'поле_4']
*
* @return array
*/
protected function getDatabaseFields()
{
return ['*'];
}
/**
* Возвращает список создатедей (замыканий) дополнительных колонок.
*
* @return array | callable[];
*
*
*/
protected function getColumnCreators()
{
return [];
}
public function attributes($data)
{
$this->html->attributes($data);
return $this;
}
/**
* Возвращает список замыканий конфигурирующих поля.
* ['название_поля' => $замыкание]
*
* @return array|callable[]
*/
protected function getColumnMutators()
{
return [];
}
/**
* Возвращает сконфигурированный список колонок таблицы.
*
* @return array
*/
abstract protected function getTableColumns();
/**
* Возвращает новый объект запроса в бд, для конфигурации.
*
* @return \Illuminate\Database\Query\Builder
*/
abstract protected function getQuery();
}
<?php
namespace App\Backend\Http\Datatables;
use Yajra\Datatables\Html\Builder as BaseBuilder;
class Builder extends BaseBuilder
{
public function scripts($script = null, array $attributes = ['type' => 'text/javascript'], $id = null)
{
if( ! is_null($id))
{
$this->tableAttributes['id'] = $id;
}
$script = $script ?: $this->generateScripts();
return '<script' . $this->html->attributes($attributes) . '>' . $script . '</script>' . PHP_EOL;
}
public function attributes(array $attributes = [])
{
$this->attributes = array_merge($this->attributes,$attributes);
return $this;
}
}
@greabock
Copy link
Author

Пример использования

  public function index(Request $request, UsersTable $table)
    {
        if ($request->ajax()) {

            return $table->data();
        }

        $this->setTitle(trans('system.users'));
        return view('larfang/backend::users', compact('table'));
    }

@greabock
Copy link
Author

greabock commented Sep 19, 2016

Пример реализации

<?php

namespace App\Backend\Http\Datatables;

use App\User\Models\User;

class UsersTable extends AbstractTable
{
    /**
     * Возвращает сконфигурированный список колонок таблицы.
     *
     * @return array
     */
    protected function getTableColumns()
    {
        return [
            [
                'data' => 'id',
                'name' => 'id',
                'title' => 'Id',
            ],
            [
                'data' => 'email',
                'name' => 'email',
                'title' => 'Email',
            ],
            [
                'data' => 'name',
                'name' => 'name',
                'title' => trans('system.name'),
            ],
            [
                'data' => 'phone',
                'name' => 'phone',
                'title' => 'Phone',
            ],
            [
                'data' => 'created_at',
                'name' => 'created_at',
                'title' => 'Created At',
                'searchable' => false
            ],
            [
                'data' => 'status',
                'name' => 'status',
                'title' => 'Status',
            ],
        ];
    }

    /**
     * Возвращает новый объект запроса в бд, для конфигурации.
     *
     * @return \Illuminate\Database\Query\Builder
     */
    protected function getQuery()
    {
        return User::query();
    }

    protected function getDatabaseFields()
    {
        return ['id', 'email', 'name','phone', 'created_at', 'banned_at', 'confirmed', 'frozen_to'];
    }

    protected function getColumnCreators()
    {
        return [
            'status' => function (User $user) {
                if ($user->isActive()) {
                    return '<i class="fa fa-circle text-success"> Активен </i>';
                }
                if ($user->isBanned()) {
                    return '<i class="fa fa-circle text-danger"> Забанен </i>';
                }
                if ($user->isFrozen()) {
                    return '<i class="fa fa-circle text-warning"> Приостановлен </i>';
                }
                if (!$user->isConfirmed()) {
                    return '<i class="fa fa-circle text-muted"> Не подтверждён </i>';
                }

                return '<i class="fa fa-circle text-danger"> Что-то не так... </i>';
            },
        ];
    }

    protected function getColumnMutators()
    {
        return [
            'created_at' => '<span ="pull-left">{{ $created_at->format("d.m.y") }}</span><span class="pull-right">{{ $created_at->diffForHumans() }}</span>',
            'name' => function(User $user) {
                return link_to_route('larfang/user::panel.user', $user->name ,[$user->id]).'';
            }
        ];
    }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment