bummzack/sortablefile

为 SilverStripe 添加对 UploadField 排序功能的扩展。

安装数: 455,533

依赖者: 69

建议者: 2

安全性: 0

星标: 66

关注者: 13

分支: 29

公开问题: 4

类型:silverstripe-vendormodule

2.2.0 2023-05-23 07:30 UTC

This package is auto-updated.

Last update: 2024-09-23 10:05:42 UTC


README

Scrutinizer Code Quality Code Coverage Build Status Latest Stable Version Latest Unstable Version Monthly Downloads

为 SilverStripe 4.1+ 提供的扩展,允许通过 UploadField 排序附加的文件。

此模块装饰现有的 UploadField 并为其添加排序功能。这主要用于与文件或图像的 many_many 关系一起使用。

screen-capture

安装

此模块仅适用于 SilverStripe 4.1+。

对于与 SilverStripe 3 兼容的版本,请使用 1.x 版本。

最简单的方法是使用 composer

composer require bummzack/sortablefile ^2.0

之后运行 dev/build

用法

用法非常简单。只需将 SortableUploadField 代替 UploadField 来管理您的 many_many 关系。为了持久化排序顺序,需要向 many_many 关系添加一个额外的字段来存储排序顺序。您可以通过指定 many_many_extraFields 中的排序列来实现(见下面示例)。

默认情况下,SortableUploadField 假设排序列的名称为 SortOrder。如果您想使用另一个字段名(例如 Sort),则必须显式设置它

SortableUploadField::create('Files')->setSortColumn('Sort');

多对多示例设置

假设我们有一个 PortfolioPage,该页面附加了多个 Images

PortfolioPage 看起来像这样

use SilverStripe\Assets\Image;
use SilverStripe\Forms\FieldList;
use Bummzack\SortableFile\Forms\SortableUploadField;

class PortfolioPage extends Page
{
    // This page can have many images
    private static $many_many = [
        'Images' => Image::class
    ];

    // this adds the SortOrder field to the relation table.
    // Please note that the key (in this case 'Images')
    // has to be the same key as in the $many_many definition!
    private static $many_many_extraFields = [
        'Images' => ['SortOrder' => 'Int']
    ];

    public function getCMSFields()
    {
        $this->beforeUpdateCMSFields(function (FieldList $fields) {
            $fields->addFieldToTab('Root.Main', SortableUploadField::create(
                'Images', $this->fieldLabel('Images')
            ));
        });

        return parent::getCMSFields();
    }
}

一旦设置如上所述,那么您应该能够在 CMS 中添加图像并拖动它们进行排序(使用左侧的句柄)。

模板

通过关系表排序文件不容易通过 DataExtension 实现。这就是为什么目前需要用户实现一个获取器,该获取器将返回排序后的文件,类似于以下内容

// Use this in your templates to get the correctly sorted images

public function Images()
{
    return $this->getManyManyComponents('Images')->sort('SortOrder');
}

// and/or
public function SortedImages()
{
    return $this->Images()->Sort('SortOrder');
}

然后,在您的模板中使用

<% loop $SortedImages %>
  $ScaleWidth(500)
<% end_loop %>

或者,您可以直接在模板中使用排序语句,这将消除在页面类中需要特殊获取器方法的需求。

<% loop $Images.Sort('SortOrder') %>
  $ScaleWidth(500)
<% end_loop %>

多对多通过

该模块也支持编辑多对多通过列表。使用 many_many through 的优点是,您的关联可以正确地进行版本控制。

示例设置

这是一个使用与上面相同的 PortfolioPage 的示例设置,但现在使用 many_many through。如果这还不清楚,请参阅 官方文档

首先,PortfolioPage

<?php

use Bummzack\SortableFile\Forms\SortableUploadField;
use SilverStripe\Forms\FieldList;

class PortfolioPage extends Page
{
    private static $many_many = [
        'Images' => [
            'through' => PortfolioImage::class,
            'from' => 'PortfolioPage',
            'to' => 'Image',
        ]
    ];

    // This is required to automatically publish your images
    // whenever you publish your page
    private static $owns = [
        'Images'
    ];

    // This is required to publish deletions as well,
    // as this will not happen by default!
    private static $cascade_deletes = [
        'Images'
    ];

    public function getCMSFields()
    {
        $this->beforeUpdateCMSFields(function (FieldList $fields) {
            $fields->addFieldToTab('Root.Main', SortableUploadField::create(
                'Images', $this->fieldLabel('Images')
            ));
        });

        return parent::getCMSFields();
    }

    // This is a helper method, that is needed to display the items in the
    // correct order. Is required for proper CMS functionality and can be
    // used in templates as $getImages
    public function getImages()
    {
        return $this->Images()->sort('SortOrder');
    }
}

many_many through 关系的思路是,您有一个中间 DataObject,它连接您的对象。因此,我们添加一个名为 PortfolioImage 的 DataObject

<?php

use SilverStripe\Assets\Image;
use SilverStripe\ORM\DataObject;
use SilverStripe\Versioned\Versioned;

class PortfolioImage extends DataObject
{
    private static $db = [
        'SortOrder' => 'Int'
    ];

    private static $has_one = [
        'Image' => Image::class,
        'PortfolioPage' => PortfolioPage::class
    ];

    private static $default_sort = 'SortOrder';

    // It's important that you add the Versioned extension to this!
    private static $extensions = [
        Versioned::class
    ];
}

我们还应该向 Image 类添加 belongs_many_many 关系。这通过配置很容易实现。因此,在您的 mysite/_config/config.yml 中添加

SilverStripe\Assets\Image:
  belongs_many_many:
    PortfolioPages: PortfolioPage.Images

那么 has_many 支持发生了什么?

由于如果文件只能添加到单个页面,则可能导致非常差的用户体验,因此已删除对 has_many 关系的支持。想象一下,用户将图像添加到 Page A,然后通过 从文件添加 将相同的图像添加到 Page B。文件将被从 Page A 中删除,没有任何警告或解释,这是糟糕的用户体验。