yii2tech/ar-position

此包已废弃且不再维护。未建议替代包。

为 Yii2 提供 ActiveRecord 自定义排序支持

资助包维护!
klimov-paul
Patreon

安装: 229,476

依赖: 27

建议者: 1

安全: 0

星标: 110

关注者: 9

分支: 11

开放问题: 0

类型:yii2-extension

1.0.1 2017-11-01 10:56 UTC

This package is auto-updated.

Last update: 2022-01-10 10:43:08 UTC


README

12951949

ActiveRecord Position Extension for Yii2


本扩展提供对 ActiveRecord 自定义记录顺序设置的支持。

有关许可信息,请参阅 LICENSE 文件。

Latest Stable Version Total Downloads Build Status

安装

安装此扩展的首选方式是通过 composer

运行以下命令:

php composer.phar require --prefer-dist yii2tech/ar-position

或者添加以下内容到您的 composer.json 的 require 部分:

"yii2tech/ar-position": "*"

使用方法

此扩展通过基于列的位置索引提供对自定义记录顺序设置的支持。

此扩展为在 Yii2 中支持此类解决方案提供了 \yii2tech\ar\position\PositionBehavior ActiveRecord 行为。您可以通过以下方式将其附加到您的模型类中

<?php

use yii\db\ActiveRecord;
use yii2tech\ar\position\PositionBehavior;

class Item extends ActiveRecord
{
    public function behaviors()
    {
        return [
            'positionBehavior' => [
                'class' => PositionBehavior::className(),
                'positionAttribute' => 'position',
            ],
        ];
    }
}

行为使用数据库实体的特定整数字段来设置位置索引。因此,模型所引用的数据库实体必须包含字段 positionAttribute

为了正确显示自定义列表,您应该按 positionAttribute 以升序对其进行排序

<?php

$records = Item::find()->orderBy(['position' => SORT_ASC])->all();
foreach ($records as $record) {
    echo $record->position . ', ';
}
// outputs: 1, 2, 3, 4, 5,...

位置保存

附加行为后,会自动为新记录填充 positionAttribute 值,将其放置在列表末尾

<?php

echo Item::find()->count(); // outputs: 4

$item = new Item();
$item->save();

echo $item->position; // outputs: 5

但是,您可以明确为新记录设置位置

<?php

echo Item::find()->count(); // outputs: 4

$item = new Item();
$item->position = 2; // enforce position '2'
$item->save();

echo $item->position; // outputs: 2 !!!

位置切换

可以使用以下方法将现有记录移动到另一个位置

  • movePrev() - 将记录移动一个位置到列表的开头。
  • moveNext() - 将记录移动一个位置到列表的末尾。
  • moveFirst() - 将记录移动到列表的开头。
  • moveLast() - 将记录移动到列表的末尾。
  • moveToPosition() - 将所有者记录移动到指定位置。

您还可以通过提供给 positionAttribute 的属性来更改记录的位置

<?php

$item = Item::find()->andWhere(['position' => 3])->one();
$item->position = 5; // switch position to '5'
$item->save();

组内位置

有时单个数据库实体包含多个列表,这些列表需要自定义排序,并通过分组属性在逻辑上分离。例如:FAQ 问题可以根据类别分组,而在单个类别内问题应手动排序。为此,可以使用 \yii2tech\ar\position\PositionBehavior::$groupAttributes

<?php

use yii\db\ActiveRecord;
use yii2tech\ar\position\PositionBehavior;

class FaqQuestion extends ActiveRecord
{
    public function behaviors()
    {
        return [
            'positionBehavior' => [
                'class' => PositionBehavior::className(),
                'positionAttribute' => 'position',
                'groupAttributes' => [
                    'categoryId' // multiple lists varying by 'categoryId'
                ],
            ],
        ];
    }
}

在这种情况下,行为将使用 groupAttributes 的所有者值作为位置计算和更改的附加条件

<?php

echo FaqQuestion::find()->andWhere(['categoryId' => 1])->count(); // outputs: '4'
echo FaqQuestion::find()->andWhere(['categoryId' => 2])->count(); // outputs: '7'

$record = new FaqQuestion();
$record->categoryId = 1;
$record->save();
echo $record->position; // outputs: '5'

$record = new FaqQuestion();
$record->categoryId = 2;
$record->save();
echo $record->position; // outputs: '8'

列表导航

应用了自定义位置排序的记录会形成一个链表,如果需要,您可以进行导航。您可以使用 \yii2tech\ar\position\PositionBehavior::getIsFirst()\yii2tech\ar\position\PositionBehavior::getIsLast() 方法来判断特定记录是否为列表中的第一个或最后一个。例如

<?php

echo Item::find()->count(); // outputs: 10

$firstItem = Item::find()->andWhere(['position' => 1])->one();
echo $firstItem->getIsFirst(); // outputs: true
echo $firstItem->getIsLast(); // outputs: false

$lastItem = Item::find()->andWhere(['position' => 10])->one();
echo $lastItem->getIsFirst(); // outputs: false
echo $lastItem->getIsLast(); // outputs: true

对于特定的记录实例,您可以使用 \yii2tech\ar\position\PositionBehavior::getNext()\yii2tech\ar\position\PositionBehavior::getPrev() 方法来找到位于它之后或之前的记录。例如

<?php

$item = Item::find()->andWhere(['position' => 5])->one();

$nextItem = $item->findNext();
echo $nextItem->position; // outputs: 6

$prevItem = $item->findPrev();
echo $prevItem->position; // outputs: 4

您还可以获取列表中的第一个和最后一个记录。例如

<?php

echo Item::find()->count(); // outputs: 10
$item = Item::find()->andWhere(['position' => 5])->one();

$firstItem = $item->findFirst();
echo $firstItem->position; // outputs: 1

$lastItem = $item->findLast();
echo $lastItem->position; // outputs: 10