s-damian/ larasort
Laravel 列表排序
Requires
- php: ^8.0
Requires (Dev)
- laravel/framework: ^8.0 || ^9.0 || ^10.0 || ^11.0
- laravel/pint: ^1.0
- orchestra/testbench: ^6
- phpstan/phpstan: ^1.11
- phpunit/phpunit: 9.5.*
README
Laravel 列表排序 - 可排序 - 按排序
Larasort : Laravel 列表排序 - 轻松排序
简介 - Larasort 包
此包允许您自动化 SQL 查询的 ORDER BY
,同时还能自动化生成可排序链接。
此开源库允许您使用 Laravel 自动化方式制作 可排序列。
您有一个包,但有两个功能:Larasort(用于与 Eloquent ORM 进行排序)和 LarasortManual(用于不使用 Eloquent ORM 进行排序)。
自动化的方式轻松排序 🚀
使用 Larasort 的简单示例
- 模型示例
private array $sortables = [ // The attributes that are sortable. 'email', 'first_name', 'created_at', ];
- 控制器示例
$customers = Customer::whereNotNull('confirmed_at') ->autosort() // Automate ORDER BY and its direction. ->paginate();
- 视图示例(blade 模板中)
@sortableLink('email', 'Email')
表格中链接的示例渲染
作者
此包由 Stephen Damian 开发
要求
- PHP 8.0 || 8.1 || 8.2 || 8.3
- Laravel 8 || 9 || 10 || 11
摘要
安装
通过 Composer 安装
composer require s-damian/larasort
使用 "vendor:publish" 进行自定义
自定义配置和语言以及 CSS
安装包后,您必须运行 vendor:publish
命令
php artisan vendor:publish --provider="SDamian\Larasort\LarasortServiceProvider"
vendor:publish
命令将生成以下文件
-
config/larasort.php
-
public/vendor/larasort/css/larasort.css
(您必须在网站中包含此 CSS) -
public/vendor/larasort/images/order.webp
您当然可以自定义这些文件。
使用 "--tag" 参数的 "vendor:publish"
仅发布 config
文件
php artisan vendor:publish --provider="SDamian\Larasort\LarasortServiceProvider" --tag=config
仅发布 CSS
文件
php artisan vendor:publish --provider="SDamian\Larasort\LarasortServiceProvider" --tag=css
仅发布 images
文件
php artisan vendor:publish --provider="SDamian\Larasort\LarasortServiceProvider" --tag=images
Larasort - 用于 Eloquent ORM
Larasort 在使用 Eloquent ORM 时非常有用。
基本用法
首先,您的模型必须使用 AutoSortable
特性。
然后,在您的模型中声明 $sortables
。此属性用于定义允许在 ORDER BY
中排序的列(数据库表中的列)。
PS:数组 $sortables
的第一列将用作 SQL ORDER BY
的默认列。
示例
<?php use SDamian\Larasort\AutoSortable; class Customer extends Model { use AutoSortable; /** * The attributes that are sortable. */ private array $sortables = [ 'id', // "id" column will be the default column for the ORDER BY. 'first_name', 'email', 'created_at', ]; }
您可以使用此静态方法覆盖用于 ORDER BY
的默认列
PS:使用 setDefaultSortable
方法的优点是,即使 URL 中没有 ?orderby={column}&order={direction}
,默认列的链接中也会出现相同的图标。
<?php use SDamian\Larasort\Larasort; Larasort::setDefaultSortable('email') // "email" column will be the default column for the ORDER BY.
如果默认情况下(当 URL 中没有 ?orderby={column}
时),您不希望在 SQL 查询中添加 ORDER BY
<?php use SDamian\Larasort\AutoSortable; class Customer extends Model { use AutoSortable; /** * The attributes that are sortable. */ private array $sortables = [ null, // Will be null by default (by default there will be no ORDER BY). 'id', 'first_name', 'email', 'created_at', ]; }
然后,您可以使用 Eloquent 的 ->autosort()
魔法方法
<?php use App\Models\Customer; class CustomerController extends Controller { public function index() { $customers = Customer::whereNotNull('confirmed_at') ->autosort() // Automate ORDER BY and its direction. ->paginate(); return view('customer.index', [ 'customers' => $customers, ]); } }
在视图中,您可以在table
的thead
部分执行此操作,例如。
PS:您必须在包含blade指令的HTML标签(例如table
或thead
标签)上放置CSS类with-larasort
。
<thead class="with-larasort"> <tr> <th> @sortableLink('first_name', 'First name') </th> <th> @sortableLink('email', 'Email') </th> <th> @sortableLink('created_at', 'Register on') </th> </tr> </thead>
PS:第一个参数是数据库中的column
,第二个参数是title
(label
)。第二个参数是可选的。如果您没有指定,将自动根据列名生成标签。
如果您需要在th
内部保持更多控制,作为等效方案,可以将@sortableLink
替换为@sortableHref
和@sortableIcon
。示例
<th> <a @sortableHref('email')> Email @sortableIcon('email') </a> </th>
别名
对于某些列,如果您不想指定以表前缀,则必须使用$sortablesAs
属性。
在具体情况下,别名在执行带有连接的SQL查询时特别有用。
使用 ->join() 的示例
- 在客户模型中的示例
<?php use SDamian\Larasort\AutoSortable; class Customer extends Model { use AutoSortable; /** * The attributes that are sortable. */ private array $sortables = [ 'id', 'first_name', 'email', 'created_at', ]; /** * The attributes that are sortable without table in prefix. */ private array $sortablesAs = [ 'article_title', // Here. ]; }
- 在客户控制器中的示例
<?php class CustomerController extends Controller { public function index() { $customers = Customer::select([ 'customers.*', 'articles.title AS article_title', // Here. ]) ->join( 'articles', 'customers.id', '=', 'articles.customer_id' ) ->autosort() // Automate ORDER BY and its direction. ->paginate(); return view('customer.index', [ 'customers' => $customers, ]); } }
- 视图示例(blade 模板中)
@sortableLink('article_title', 'Article Title')
关系
使用Larasort
,您可以自动为您的关系One To One和One To Many设置ORDER BY
。
为此,您可以使用autosortWith
方法。
一对一
在这个例子中,一个user
创建了一个article
,一个article
由一个user
创建。
这因此建立了users
和articles
之间的One To One
关系。
- 在用户模型中的示例
<?php /** * The attributes of its sortable relations. */ private array $sortablesRelated = [ // Convention: {relationship name}{separator}{column in this relationship table}. 'article.title', ]; public function article() { return $this->hasOne(Article::class, 'user_id_created_at', 'id'); }
- 在用户控制器中的示例
<?php $users = User::autosortWith('article', [ 'join_type' => 'join', // Optional - "leftJoin" by default. 'columns' => ['id', 'username', 'email', 'role'], // Optional - "*" by default. 'related_columns' => ['title AS article_title', 'h1'], // Optional - "*" by default. ]) ->paginate();
- 视图示例(blade 模板中)
@sortableLink('article.title', 'Article Title')
PS:对于@sortableLink
的第一个参数,使用与模型$sortablesRelated
属性中的相同约定。
一对多
在这个例子中,一个user
创建了许多articles
,一个article
由一个user
创建。
这因此建立了users
和articles
之间的One To Many
关系(每个用户有多个文章,每个文章只有一个用户)。
- 在用户模型中的示例
<?php /** * The attributes of its sortable relations. */ private array $sortablesRelated = [ // Convention: {relationship name}{separator}{column in this relationship table}. 'articles.title', ]; public function articles() { return $this->hasMany(Article::class, 'user_id_created_at', 'id'); }
- 在用户控制器中的示例
<?php $users = User::autosortWith('articles', [ 'join_type' => 'join', // Optional - "leftJoin" by default. 'columns' => ['id', 'username', 'email', 'role'], // Optional - "*" by default. 'related_columns' => ['title AS article_title', 'h1'], // Optional - "*" by default. ]) ->paginate();
- 视图示例(blade 模板中)
@sortableLink('articles.title', 'Article Title')
PS:对于@sortableLink
的第一个参数,使用与模型$sortablesRelated
属性中的相同约定。
属于
对于One To One
或One To Many
关系,您必须在文章模型中放置belongsTo
方法。
- 在文章模型中的示例
<?php private array $sortablesRelated = [ // Convention: {relationship name}{separator}{column in this relationship table}. 'user.email', ]; public function user() { return $this->belongsTo(User::class, 'user_id_created_at', 'id'); }
- 在文章控制器中的示例
<?php $articles = Article::autosortWith('user', [ 'join_type' => 'join', // Optional - "leftJoin" by default. 'columns' => ['id', 'slug', 'h1', 'updated_at'], // Optional - "*" by default. 'related_columns' => ['email AS user_email', 'first_name'], // Optional - "*" by default. ]) ->paginate();
- 视图示例(blade 模板中)
@sortableLink('user.email', 'User Email')
PS:对于@sortableLink
的第一个参数,使用与模型$sortablesRelated
属性中的相同约定。
关系 - 规范
模型$sortablesRelated属性
对于放置在$sortablesRelated
属性中的列,约定是:{关系名称}{分隔符}{此关系表中的列}
Larasort将使用{关系名称}
对其表进行ORDER BY
。
默认情况下,分隔符是点。如果您愿意,可以在配置中将其更改为relation_column_separator
。
->autosortWith()方法选项
要执行连接,您必须在->autosortWith()
的第一个参数中指定关系的名称。
内部,您必须传递您的关系名称(您在模型中放置的关系方法名称)。Larasort将使用此名称进行join
。
选项
PS:如果将->autosortWith()
的第一个参数放置在不同于属性$sortablesRelated
中{关系名称}
的关系名称中,则关系上不会发生ORDER BY
。
- "
join_type
"(可选)
要执行除了默认连接(配置中指定的)之外的其他连接,可以指定join_type
选项。
- "
columns
"(可选)
如果您想指定要为您的模型SELECT
的列,可以指定columns
选项。
您可以使用数组或字符串。数组示例:['id', 'email', 'username']
字符串示例:'id, email, username'
默认情况下,将选择所有列。
- "
related_columns
"(可选)
如果您想指定为您的模型的关系SELECT
哪些列,可以指定related_columns
选项。
您可以使用数组或字符串。数组示例:['title AS article_title', 'content']
字符串示例:'title AS article_title, content'
默认情况下,将选择所有列。
对于一列,指定其表
使用Larasort
,您可以针对列指定它们的表(这在执行带有连接的SQL查询时很有用)。
默认情况下,Larasort将会在包含AutoSortable
特质的表上执行ORDER BY
。
让我们举一个例子,在一个SQL查询中,你想要检索文章(来自articles
表)和分类(来自categories
表),并且对于这两个表,你想要检索id
列。但你想要在categories
表上而不是在articles
表上执行ORDER BY id
。
你可以通过以下两种解决方案来解决这个问题
解决方案 1 - 使用$sortablesToTables属性
你可以选择在模型中设置$sortablesToTables
属性
<?php use SDamian\Larasort\AutoSortable; class Article extends Model { use AutoSortable; /** * The attributes that are sortable. */ private array $sortables = [ 'id', 'title', 'updated_at', ]; /** * The sortable attributes to which their table is specified. */ private array $sortablesToTables = [ 'id' => 'categories.id', // Here. ]; }
解决方案 2 - 使用Larasort::setSortablesToTables(array $sortablesToTables)
可以在使用->autosort()
的SQL查询之前(例如在控制器或模型中)选择性地设置Larasort::setSortablesToTables(array $sortablesToTables)
方法。
在ArticleController中的示例
<?php use SDamian\Larasort\Larasort; class ArticleController extends Controller { public function index() { Larasort::setSortablesToTables(['id' => 'categories.id']); // Here. // Here your SQL query with ->autosort() // Then the rest of the code... } }
如果同时使用$sortablesToTables
属性和Larasort::setSortablesToTables(array $sortablesToTables)
方法对同一列进行操作,则Larasort::setSortablesToTables(array $sortablesToTables)
方法将覆盖$sortablesToTables
属性。
使用这两种解决方案,SQL查询的结果将是:ORDER BY `categories`.`id` ASC
而不是ORDER BY `articles`.`id` ASC
对于某些列,默认使用 "desc" 或 "asc"
对于某些列,可能希望默认顺序(或在其链接的第一次点击上)为desc
而不是asc
。
可以在使用->autosort()
的SQL查询之前选择性地进行设置(例如在控制器或模型中)。
在InvoiceController中的示例
<?php use SDamian\Larasort\Larasort; class InvoiceController extends Controller { public function index() { Larasort::setSortablesDefaultOrder([ 'desc' => ['id', 'created_at', 'price_with_vat'], // Here. ]); // Here your SQL query with ->autosort() // Then the rest of the code... } }
如果你更改“default_order”在“config/larasort.php”文件中 - 为某些列设置默认的“asc”
在config/larasort.php
配置文件中,你可以更改default_order
的值(默认为asc
)。
如果你这样做,则某些列的顺序可能希望为asc
而不是desc
。
在InvoiceController中的示例
<?php use SDamian\Larasort\Larasort; class InvoiceController extends Controller { public function index() { Larasort::setSortablesDefaultOrder([ 'asc' => ['customer_email', 'customer_first_name'], // Here. ]); // Here your SQL query with ->autosort() // Then the rest of the code... } }
清除 Larasort 静态方法
如果需要,你可以清除(重置)Larasort的静态方法
<?php Larasort::clearDefaultSortable(); Larasort::clearSortablesToTables(); Larasort::clearSortablesDefaultOrder();
Larasort - API 文档
模型属性
Larasort 类
对于SDamian\Larasort\Larasort
类
AutoSortable 特性
对于SDamian\Larasort\AutoSortable
特质
Blade 指令
LarasortManual - 用于不使用 Eloquent ORM
Larasort在未使用Eloquent ORM时非常有用。
如果你想要进行手动SQL查询(或如果你想要进行文件列表),存在一个替代方案:LarasortManual
LarasortManual - 基本用法
使用LarasortManual
,setSortables(array $sortables)
方法可以用来定义允许在ORDER BY
中排序的列。简单示例
<?php use SDamian\Larasort\Manual\LarasortManual; class CustomerController extends Controller { public function index() { $larasortMan = new LarasortManual(); $larasortMan->setSortables(['id', 'first_name', 'email', 'created_at']); // Here. $resultLarasortMan = $larasortMan->get(); $customers = DB::select(' SELECT * FROM customers ORDER BY '.$resultLarasortMan['order_by'].' '.$resultLarasortMan['order'].' '); return view('customer.index', [ 'customers' => $customers, 'larasortManAttrs' => $resultLarasortMan['attrs'], ]); } }
在视图中的thead
的table
中可以这样做,例如
<thead class="with-larasort"> <tr> <th> <a {!! $larasortManAttrs['first_name']['href'] !!}> First name {!! $larasortManAttrs['first_name']['icon'] !!} </a> </th> <th> <a {!! $larasortManAttrs['email']['href'] !!}> Email {!! $larasortManAttrs['email']['icon'] !!} </a> </th> <th> <a {!! $larasortManAttrs['created_at']['href'] !!}> Register on {!! $larasortManAttrs['created_at']['icon'] !!} </a> </th> <th>Actions</th> </tr> </thead>
PS:如果你希望,你也可以访问$larasortManAttrs['column_name']['url']
LarasortManual - 对于一列,指定其表
使用LarasortManual
也可以为列指定它们的表(这在执行带有join的SQL查询时很有用)。
与默认情况下在包含AutoSortable
特质的表上执行SQL查询的Larasort
不同,LarasortManual
默认将执行不指定前缀表的ORDER BY column
。
因此,当你连接多个表时,如果你在多个表上SELECT
相同的列名,你可能会遇到类似“完整性约束违反:1052 列 '{colomn}' 在顺序子句中是模糊的”的错误。
让我们举一个例子,在一个SQL查询中,你想要检索文章(来自articles
表)和分类(来自categories
表),并且对于这两个表,你想要检索id
列。并且你想要在categories
表上执行ORDER BY id
。
你可以使用$larasortMan->setSortablesToTables(array $sortablesToTables)
方法来做这件事。示例
<?php use SDamian\Larasort\Manual\LarasortManual; class ArticleController extends Controller { public function index() { $larasortMan = new LarasortManual(); $larasortMan->setSortables(['id', 'title', 'created_at']); $larasortMan->setSortablesToTables(['id' => 'categories.id']); // Here. $resultLarasortMan = $larasortMan->get(); // Here your SQL query with $resultLarasortMan['order_by'] and $resultLarasortMan['order'] // Then the rest of the code... } }
$resultLarasortMan['order_by']
将生成SQL查询ORDER BY `categories`.`id` ASC
而不是ORDER BY `id` ASC
LarasortManual - 对于某些列,默认使用 "desc" 或 "asc"
使用 LarasortManual,您也可以对某些列进行排序(即 ORDER BY 的方向),默认(或在首次点击其链接时)为 desc
而不是 asc
。
您可以通过 $larasortMan->setSortablesDefaultOrder(array $sortablesDefaultOrder)
方法来实现这一点。示例
<?php use SDamian\Larasort\Manual\LarasortManual; class InvoiceController extends Controller { public function index() { $larasortMan = new LarasortManual(); $larasortMan->setSortables(['id', 'ref', 'customer_email', 'created_at', 'price_with_vat']); $larasortMan->setSortablesDefaultOrder([ 'desc' => ['id', 'created_at', 'price_with_vat'], // Here. ]); $resultLarasortMan = $larasortMan->get(); // Here your SQL query with $resultLarasortMan['order_by'] and $resultLarasortMan['order'] // Then the rest of the code... } }
如果你更改“default_order”在“config/larasort.php”文件中 - 为某些列设置默认的“asc”
您可以通过与 Larasort 完全相同的方式进行操作。例如这样做
<?php $larasortMan->setSortablesDefaultOrder([ 'asc' => ['customer_email', 'customer_first_name'], // Here. ]);
LarasortManual - API 文档
LarasortManual 类
对于 SDamian\Larasort\Manual\LarasortManual
类
支持
错误和安全漏洞
如果您发现错误或安全漏洞,请给 Stephen 发送消息。谢谢。
所有错误和所有安全漏洞都将得到及时解决。
许可证
此项目是一个 MIT 许可下的开源软件包。有关详细信息,请参阅 LICENSE 文件。