anik/laravel-backpack-extension

Laravel backpack/crud 的基于类的命令式方法

v1.0 2022-06-07 04:13 UTC

This package is auto-updated.

Last update: 2024-09-08 22:47:46 UTC


README

anik/laravel-backpack-extension codecov PHP 版本要求 最新稳定版本

backpack/crud 的表格视图中的列表操作,如果列存在于数据库表中,默认情况下是可搜索和可排序的,除非有其他指示。此外,要向操作中添加一个 字段,需要传递一个数组。在 PHP 中,数组键是区分大小写的,这使添加字段或列变得繁琐。此软件包允许通过基于类的命令式方法传递数组。因此,无需再进行繁琐的重复键入游戏来匹配确切的数组键。有时 忘记 了? 🤷

文档

安装

要安装此软件包,请运行

composer require anik/laravel-backpack-extension

用法

扩展控制器

在控制器中,使用 \Anik\LaravelBackpack\Extension\Controllers\CrudController 而不是 \Backpack\CRUD\app\Http\Controllers\CrudController

添加列

创建一个

  • new \Anik\LaravelBackpack\Extension\Columns\Column(string $name, [?string $label = null])
  • \Anik\LaravelBackpack\Extension\Columns\Column::create(string $name, [?string $label = null])
  • \Anik\LaravelBackpack\Extension\Columns\Column::ID([?string $label = null], [?string $name = null]) - 创建一个 ID 类型列

从控制器中添加列

  • 对于单个列,使用 $this->registerColumn($column)
  • 对于多个列,使用 $this->registerColumns($columns)

默认情况下,所有 Column 实例都是 不可排序不可搜索 的。

示例

use Anik\LaravelBackpack\Extension\Columns\Column;
use Anik\LaravelBackpack\Extension\Controllers\CrudController;

class AccountCrudController extends CrudController 
{
    public function setupListOperation () {
        $columns = [
            Column::ID()->orderable(), // Only this column will be orderable
            Column::create('email')->searchable(), // Makes this field searchable
            Column::create('name')->searchable(
                fn ($q, $column, $term) => strlen($term = trim($term)) >= 3 ? $q->where('name', 'LIKE', sprintf('%%%s%%', $term)) : null)
            ), // Also makes this field searchable with custom logic
        ];
        
        $this->registerColumns($columns);
        $this->registerColumn((new Column('is_verified', 'Verified'))->setType('boolean'));
    }
}

可用方法

  • orderable() - 使列可排序
  • setOrderable(bool $orderable)
  • searchable() - 使列可搜索
  • setSearchLogic(bool|Closure $logic) - 使用逻辑或不可搜索使列可搜索
  • setKey(string $key)
  • setType(string $type) - 设置列类型
  • setEntity(bool|string $entity)
  • setAttribute(string $attribute)
  • setModel(string $model)
  • setPriority(int $priority)
  • shouldNotEscape() - 在视图中不转义值 {!! $value !!}
  • setEscaped(bool $escape)
  • setValue(mixed $value)
  • setLimit(int $limit)
  • setDefault(mixed $default)
  • setPrefix(mixed $prefix)
  • setSuffix(mixed $suffix)
  • setWrapper(mixed $wrapper, bool $mergeRecursive = false)
  • setOptions(mixed $options, bool $mergeRecursive = false)
  • isExportOnlyField()
  • isNotExportOnlyField()
  • shouldBeVisibleInTable()
  • shouldNotBeVisibleInTable()
  • shouldBeVisibleInModal()
  • shouldNotBeVisibleInModal()
  • isTableColumn()
  • isNotTableColumn()
  • setTableColumn(bool $tableColumn)
  • related(Relation $relation, bool $mergeRecursive = false) - 检查 关系 部分

注意

列类使用 \Anik\LaravelBackpack\Extension\Extensions\Attributable 特性。检查 可属性 部分。

添加字段

实例化一个 字段

  • new \Anik\LaravelBackpack\Extension\Fields\Field(string $name, [?string $label = null])
  • \Anik\LaravelBackpack\Extension\Fields\Field::create(string $name, [?string $label = null])

或者创建一个 可选字段

  • new \Anik\LaravelBackpack\Extension\Fields\OptionalField(string $name, [?string $label = null])
  • \Anik\LaravelBackpack\Extension\Fields\OptionalField::create(string $name, [?string $label = null])

从控制器添加字段

  • 对于单个字段, $this->registerField($field)
  • 对于多个字段, $this->registerFields($fields)

默认情况下,所有 字段 实例都是 必填的

示例

use Anik\LaravelBackpack\Extension\Controllers\CrudController;
use Anik\LaravelBackpack\Extension\Fields\Field;

class AccountCrudController extends CrudController 
{
    public function setupCreateOperation () {
        $fields = [
            Field::create('email')->setType('email'),
            Field::create('is_admin')->checkbox(),
        ];
        
        $this->registerFields($fields);
        $this->registerField((new Field('csrf_token'))->hidden());
    }
}

可用方法

  • required() - 使字段必填
  • optional() - 使字段可选
  • setType(string $type) - 设置字段类型
  • related(Relation $relation, bool $mergeRecursive = false) - 检查 关系 部分
  • setRelationType(string $type)
  • setEntity(bool|string $entity)
  • setAttribute(mixed $attribute)
  • setModel(string $model)
  • setBaseModel(string $baseModel)
  • showAsterisk()
  • setShowAsterisk(mixed $value)
  • allowsMultiple()
  • setMultiple(mixed $multiple)
  • setPivot(mixed $pivot)
  • setSubfields(mixed $subfields)
  • setParentFieldName(mixed $value)
  • setPrefix(string $prefix)
  • setSuffix(string $suffix)
  • setDefault(mixed $default)
  • setValue(mixed $value)
  • setHint(string $hint)
  • setInline(mixed $inline)
  • hidden() - 使字段为隐藏类型
  • checkbox() - 使字段为复选框类型
  • radio() - 使字段为单选框类型
  • number() - 使字段为数字类型
  • password() - 使字段为密码类型
  • setPlaceholder(string $placeholder)
  • isReadOnly() - 使字段为只读
  • isDisabled() - 使字段为禁用
  • setClass(string $class) - 设置字段元素的 CSS 类
  • setAttributes(array $attributes, bool $mergeRecursive = true) - 为字段元素添加额外的属性
  • setWrapper(mixed $value, bool $mergeRecursive = true)
  • setFake(bool $fake)
  • setStoresIn(string $storesIn)
  • setOptions(mixed $options, bool $mergeRecursive = true)
  • allowsNull()
  • setAllowsNull(bool $allowNull)
  • setTab(string $tab)

注意

字段类使用 \Anik\LaravelBackpack\Extension\Extensions\Attributable 特性。检查 可属性 部分。

添加过滤器

实例化一个 过滤器

  • new \Anik\LaravelBackpack\Extension\Filters\Filter(string $name, [?string $label = null])
  • \Anik\LaravelBackpack\Extension\Filters\Filter::create(string $name, [?string $label = null])
  • \Anik\LaravelBackpack\Extension\Filters\AjaxFilter::create(string $name, [?string $label = null], [?string $url = null], [?string $method = null])

从控制器添加过滤器

  • 对于单个过滤器, $this->registerFilter($filter)
  • 对于多个过滤器, $this->registerFilters($filters)

示例

use Anik\LaravelBackpack\Extension\Controllers\CrudController;
use Anik\LaravelBackpack\Extension\Filters\Filter;
use Anik\LaravelBackpack\Extension\Filters\AjaxFilter;

class AccountCrudController extends CrudController 
{
    public function setupListOperation () {
        $filters = [
            Filter::create('status')
                ->setValues([1 => 'Draft', 2 => 'Pending', 3 => 'Published',])
                ->setLogic(fn($status) => $this->crud->query->where('status', $status)),
            AjaxFilter::create('user_id'),
        ];
        
        $this->registerFilters($filters);
        $this->registerFilter((new Filter('is_deleted'))->setValues([0, 1]));
    }
}

可用方法

  • setType(string $type) - 设置过滤器类型
  • setViewNamespace(string $namespace)
  • setPlaceholder(string $placeholder)
  • setValues(string|array|callable $values)
  • setLogic(callable $logic)
  • setFallbackLogic(callable $fallbackLogic)

注意

过滤器类使用 \Anik\LaravelBackpack\Extension\Extensions\Attributable 特性。检查 可属性 部分。

添加小部件

实例化一个 小部件

  • new \Anik\LaravelBackpack\Extension\Widgets\Widget([?string $type = null], [?string $name = null], [?string $section = null])
  • \Anik\LaravelBackpack\Extension\Widgets\Script::create(string $src, [?string $name = null])
  • \Anik\LaravelBackpack\Extension\Widgets\Style::create(string $href, [?string $name = null])
  • new \Anik\LaravelBackpack\Extension\Widgets\Hidden([?string $type = null], [?string $name = null], [?string $section = null])

从控制器添加小部件

  • 对于单个小部件, $this->registerWidget($widget)
  • 对于多个小部件, $this->registerWidgets($widgets)

示例

use Anik\LaravelBackpack\Extension\Controllers\CrudController;
use Anik\LaravelBackpack\Extension\Widgets\Script;
use Anik\LaravelBackpack\Extension\Widgets\Style;
use Anik\LaravelBackpack\Extension\Widgets\Widget;

class AccountCrudController extends CrudController 
{
    public function setupListOperation () {
        $widgets = [
            Script::create('assets/js/common.js'),
            Style::create('assets/css/common.css'),
        ];
        
        $this->registerWidgets($widgets);
        $this->registerWidget((new Widget('script'))->setContent('assets/js/another_common.js'));
    }
}

可用方法

  • setSection(string $section)

  • setContent(mixed $content)

  • setViewNamespace(string $namespace)

  • shouldBeHidden()

  • shouldBeFirst()

  • shouldBeLast()

  • Script::setSrc(string $src)

  • Script::setStack(string $stack)

  • Style::setRel(string $rel)

  • Style::setHref(string $href)

  • Style::setStack(string $stack)

注意

Widget 类使用了 \Anik\LaravelBackpack\Extension\Extensions\Attributable 特性。请查看Attributable 部分。

关系

如果列或字段指向一个 Eloquent 关系,则可以使用 Anik\LaravelBackpack\Extension\Relations\Relation

实例化一个 关系

  • new \Anik\LaravelBackpack\Extension\Relations\Relation(string $type, string $method, [?string $attribute = null])
  • new \Anik\LaravelBackpack\Extension\Relations\CustomRelation::create(string $type, string $method, [?string $attribute = null])
  • new \Anik\LaravelBackpack\Extension\Relations\BelongsTo::create(string $method, [?string $attribute = null])
  • new \Anik\LaravelBackpack\Extension\Relations\HasOne::create(string $method, [?string $attribute = null])
  • new \Anik\LaravelBackpack\Extension\Relations\BelongsTo::BelongsToMany(string $method, [?string $attribute = null])
  • new \Anik\LaravelBackpack\Extension\Relations\HasOne::HasMany(string $method, [?string $attribute = null])

参数

  • $method - 在 eloquent 模型 中关系的方法名称。
  • $attribute - 相关 eloquent 模型的 字段/列/属性
  • $type - 由 backpack 使用以选择显示关系计算值的 视图

该软件包提供了 4 个内置关系,这些关系使用 backpack 建议的 类型

  • HasOneBelongsTo - 类型: 选择
  • HasManyBelongsToMany - 类型: 多选

如果您需要自定义关系,可以使用 \Anik\LaravelBackpack\Extension\Relations\CustomRelation

示例

use Anik\LaravelBackpack\Extension\Columns\Column;
use Anik\LaravelBackpack\Extension\Controllers\CrudController;
use Anik\LaravelBackpack\Extension\Fields\Field;
use Anik\LaravelBackpack\Extension\Relations\BelongsTo;
use Anik\LaravelBackpack\Extension\Relations\HasMany;

class AccountCrudController extends CrudController 
{
    public function setupListOperation () {
        $columns = [
            // Other columns
            Column::create('phone')->related(HasMany::create('phones', 'number')),
        ];
        
        $this->registerColumns($columns);
    }
    
    public function setupCreateOperation() {
        $fields = [
            // Other fields
            Field::create('country_id', 'Country')->related(BelongsTo::create('country', 'name')),
        ];
        
        $this->registerFields($fields);
    }
}

可用方法

  • setValueResolver(Closure $resolver) - 设置一个闭包,该闭包将负责计算字段/列的值

注意

只有 CustomRelation 类使用 \Anik\LaravelBackpack\Extension\Extensions\Attributable 特性。请查看Attributable 部分。

Attributable 特性

Attributable 特性允许类以数组格式保存和检索属性。使用该特性的类将能够访问以下方法。

  • addAttribute(string $key, mixed $value, bool $mergeRecursive = false)

  • addAttributes(array $attributes, bool $mergeRecursive = false)

  • unset(string $key)

  • toArray(): array

  • $mergeRecursive 表示是否使用 array_merge 而不是 array_merge_recursive 来合并。

  • addAttributeaddAttributesunset 方法在 添加删除 值时允许使用 点表示法 的键。

示例

use Anik\LaravelBackpack\Extension\Fields\Field;

$field = Field::create('name');

$field->addAttribute('attributes.readonly', 'readonly'); // ['attributes' => ['readonly' => 'readonly']]
// $field->addAttribute('attributes.disabled', 'disabled');  // w/o the parameter [mergeRecursive: true] -> ['attributes' => ['disabled' => 'disabled']]
$field->addAttribute('attributes.disabled', 'disabled', true);  // ['attributes' => ['readonly' => 'readonly', 'disabled' => 'disabled']]
$field->addAttributes(['wrapper.class' => 'col-md-12'], true);

$field->addAttributes(['wrapper' => ['another' => ['key' => 'value']]], true);
// $field->addAttributes(['wrapper.another.key' => 'value'], true); // Alternative implementation of the above line
/**
 * STRUCTURE: $field->toArray();
 * 
 * [
 *      'attributes' => [
 *          'readonly' => 'readonly', 
 *          'disabled' => 'disabled'
 *      ], 
 *      'wrapper' => [
 *          'class' => 'col-md-12',
 *          'another' => [
 *              'key' => 'value'
 *          ]
 *      ]
 * ]
 */

$field->unset('wrapper.another'); 
/**
 * STRUCTURE: $field->toArray();
 * 
 * [
 *      'attributes' => [
 *          'readonly' => 'readonly', 
 *          'disabled' => 'disabled'
 *      ], 
 *      'wrapper' => [
 *          'class' => 'col-md-12'
 *      ]
 * ]
 */