erikgall / listify
将任何 Eloquent 模型转换为列表!http://erikgall.github.io/listify
Requires
- php: ^7.3|^8.0
- illuminate/console: ^8.0
- illuminate/database: ^8.0
- illuminate/events: ^8.0
- illuminate/support: ^8.0
Requires (Dev)
- php-coveralls/php-coveralls: ^2.1
- phpunit/phpunit: ^9.3.3
README
将任何 Eloquent 模型转换为列表!
描述
该项目最初由 Travis Vignon 创建,但现已停止维护,仅支持 Laravel 5。此项目的分支为 Laravel 7 & 8 应用程序提供支持,并将随着新的 Laravel 版本的发布而更新。请随时提交贡献,帮助保持此包的更新!
Listify 提供了对列表中多个对象的排序和重新排序的功能。具有此指定的类需要在映射的数据库表上定义一个整型的 position
列。Listify 是非常有用的 Ruby 钩子 acts_as_list
(https://github.com/swanandp/acts_as_list)的 Eloquent 端。
要求
- Listify 目前需要 php >= 7.2.5
- Laravel 7 或 Laravel 8
安装
使用 composer 将 Listify 安装到您的 Laravel 8 应用程序中
$ composer require erikgall/listify
可以在以下位置找到 Laravel 7 分支 erikgall/listify:2.x
要使用 composer 将 Listify 安装到您的 Laravel 7 应用程序中
$ composer require erikgall/listify:^2.0
快速入门
首先,您需要添加一个列来存储位置。从命令行,使用迁移生成器
php artisan listify:attach {table_name} {position_column_name} php artisan migrate
{table_name}
是必需的参数。{position_column_name}
是可选的,默认值为 "position"。
然后,在您的模型中
<?php use EGALL\Listify\Listify; class User extends Eloquent { use Listify; ... }
请确保在您的模型中调用
initListify()
方法 在parent::__construct()
之后的parent::__construct()
。
这就是获取 Listify 热度所需的所有内容。
概述
添加到 Eloquent 模型的实例方法
您将为添加到 Eloquent 模型的每个实例添加一些方法。
在 Listify 中,“更高”意味着列表中更靠前的位置(更低的 position
),而“更低”则意味着列表中更靠后的位置(更高的 position
)。这可能会令人困惑,因此添加测试以验证您是否根据您的上下文使用正确的方法可能是有意义的。
更改位置和重新排序列表的方法
eloquentModel.insertAt(int)
eloquentModel.moveLower()
如果项目是最低项,则不会执行任何操作eloquentModel.moveHigher()
如果项目是最高项,则不会执行任何操作eloquentModel.moveToBottom()
eloquentModel.moveToTop()
eloquentModel.removeFromList()
不立即重新排序列表的更改位置的方法
注意:更改的位置在模型保存时仍会触发列表中其他项目的更新
eloquentModel.incrementPosition()
eloquentModel.decrementPosition()
eloquentModel.setListPosition(3)
返回项目列表位置属性的方法
eloquentModel.isFirst()
eloquentModel.isLast()
eloquentModel.isInList()
eloquentModel.isNotInList()
eloquentModel.higherItem()
eloquentModel.higherItems()
将返回列表中位于eloquentModel
之上的所有项目(按位置排序,升序)eloquentModel.lowerItem()
eloquentModel.lowerItems()
将返回列表中位于eloquentModel
之下的所有项目(按位置排序,升序)
配置
有几种配置选项可供选择。您需要在模型的构造函数中将这些作为数组参数传递给 initListify()
。以下是一些选项:
top_of_list
设置列表顶部的整数位置(默认:1
)。column
设置您在安装期间选择的列名(默认:'position'
)。add_new_at
设置您在安装期间选择的列名(默认:'bottom'
,选项:'top'
或'bottom'
)。scope
允许您限定列表中的项。这需要一些详细说明。这里接受三个可能的值:字符串
Illuminate\Database\Eloquent\Relations\BelongsTo
对象Illuminate\Database\Query\Builder
对象
字符串
如果传递了 string
,则将原始字符串作为 whereRaw
传递给范围。这允许您执行类似 'custom_foreign_key = 42'
的操作,并将所有项限定在相应的结果集中。您可以传递任何复杂的 where
子句,并且它将被直接传递到每个数据库操作中。
示例
<?php use EGALL\Listify\Listify; class User extends Eloquent { use Listify; public function __construct(array $attributes = []) { parent::__construct($attributes); $this->listifyConfig->setScope('answer_to_ltuae = 42'); } }
结果为以下范围
WHERE answer_to_ltuae = 42
Illuminate\Database\Eloquent\Relations\BelongsTo
如果传递了 Illuminate\Database\Eloquent\Relations\BelongsTo
,Listify 将匹配范围的外键与模型实例对应的外键值。
示例
<?php use EGALL\Listify\Listify; class ToDoListItem extends Eloquent { use Listify; public function __construct(array $attributes = []) { parent::__construct($attributes); $this->listifyConfig->setScope($this->toDoList()); } public function toDoList() { $this->belongsTo('ToDoList'); } }
结果为以下范围
WHERE to_do_list_id = {{toDoListItem.to_do_list_id的值}}
Illuminate\Database\Query\Builder
最后,如果传递了 Illuminate\Database\Query\Builder
,Listify 将提取构建器的 where
子句并将其用作 Listify 项的范围。这种范围类型是在尝试保持 acts_as_list
版本和 Listify 之间的兼容性时添加的;然而,由于语言和 ActiveRecord 与 Eloquent 之间的差异,这是一个有限的实现,需要改进以更加灵活和安全。这是一个很大的限制,将在未来的版本中首先解决。
这有点复杂,因为为了使其工作,查询对象的 where
数组是在 PDO 之外准备绑定,然后作为原始字符串传递。所以,请注意,如果不小心构建对象,此方法可能会使您的应用程序容易受到滥用。如果您使用直接的用户输入,请在将其用作 Listify 的范围之前对数据进行清理。
示例
<?php class ToDoListItem extends Eloquent { use \EGALL\Listify\Listify; public function __construct(array $attributes = []) { parent::__construct($attributes); $this->listifyConfig->setScope(DB::table($this->getTable())->where('type', '=', 'Not A List of My Favorite Porn Videos')); } }
结果为以下范围
to_do_list_items.type = 'Not A List of My Favorite Porn Videos'
更改配置
您也可以通过使用 Config
类上的任何设置器在运行时更改任何配置值。$this->listifyConfig->('key', 'value');。例如,要更改范围,您可以这样做
$this->listifyConfig->setScope('what_does_the_fox_say = "ring ding ding ding"');
当处理更新时,将使用原始范围从列表中删除记录,并将其插入到新的范围列表中。请小心。在处理过程中更改配置可能会产生不可预测的影响。
您还可以更改其他配置值。设置器是可链的。
$this->listifyConfig->setTopPositionInList(0) ->setPositionColumnName('order') ->setScope($this->menu()) ->setAddNewItemTo(Config::POSITION_BOTTOM);
注释
在特质方法内部的所有 position
查询(选择、更新等)都将在没有默认范围的情况下执行,这将防止默认范围与 Listify 范围不同时的糟糕问题。
position
列在调用验证之后设置,因此您不应在 position
列上放置 presence
验证。
未来计划
- 支持使用闭包作为范围
- 更新
Illuminate\Database\Query\Builder
范围以更加安全和灵活 - 安装命令的附加功能。例如
- 自动更新模型与特质(包括构造函数中的初始化方法)
- 生成(或添加)一个控制器,其中包含为Listify的每个公共方法创建的操作,包括添加必要的路由。这将使得通过AJAX风格的客户端调用类似
https://:8000/foos/1/move_lower
的操作变得容易。
除此之外,我希望在必要时与Ruby gem acts_as_list
(https://github.com/swanandp/acts_as_list) 保持一致。
为 Listify 贡献
- 查看最新主分支以确保功能尚未实现或错误尚未修复。
- 查看问题跟踪器以确保没有人已经请求或贡献了它。
- 分支项目。
- 创建一个功能/错误修复分支。
- 提交并推送,直到你对你的贡献满意为止。
- 确保为它添加测试。这是很重要的,这样我就不会在未来版本中无意中破坏它。
- 请尽量不要修改Composer.json、版本或历史记录。如果你想有自己的版本或这是必需的,那没问题,但请将其隔离到自己的提交中,这样我就可以在它周围选择。
- 我建议在拉取请求之前使用Laravel 8.0及以上版本进行构建测试。
版权
版权(c)2020 Erik Galloway,在MIT许可下发布