如何从SilverStripe管理员中的DataObject分离文件系统时删除文件(图像)?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从SilverStripe管理员中的DataObject分离文件系统时删除文件(图像)?相关的知识,希望对你有一定的参考价值。

例如,我有这个代码

class MyDataObject extends DataObject {
    private static $has_one = [
        "MyImage" => Image::class,
    ];
    public function getCMSFields(){ 
        $fields = parent::getCMSFields();
        $fields->addFieldsToTab('Root.Main', [
            UploadField::create('MyImage');
        ]);
        return $fields;
    }
}

用户从admin中的MyDataObject中删除文件时

[screen]

此文件仍保留在cms,数据库和文件系统的“文件”部分,因此用户需要转到“文件”并手动删除。

在实践中,他经常忘记在从某些数据对象中分离文件后删除文件,并且所有这些文件都占有很多位置。

当用户点击屏幕截图时,SilverStripe如何自动从文件系统中删除文件?

答案

你的数据对象需要一个onAfterDelete()。在那里你可以删除该文件。 (别忘了在你的方法中调用Parent::onAfterDelete()

**更新**

或者,如果仅在用户编辑而不是删除您的对象时,则onAfterWrite()是您的朋友。在那里,您可以比较图像的新旧ID,如果不同,请删除具有旧ID的图像。

另一答案

为了解决这个问题,我创建了这个扩展

<?php
use SilverStripeORMDataExtension;
use SilverStripeAssetsFile;

 class DataObjectRemoveImagesExt extends DataExtension {

     private function killFile($fileId) {
         $fileToRemove = File::get()->byId($fileId);
         if ($fileToRemove) $fileToRemove->delete();
     }

     public function onAfterWrite() {
         $changedFieldsArr = $this->owner->getChangedFields();

         if (!$this->owner->config()->get('kill_on_detach')) return;

         $detachList = $this->owner->config()->get('kill_on_detach');

         foreach ($detachList as $fileFieldName) {
             if (!isset($changedFieldsArr["{$fileFieldName}ID"])) continue;

             $changedFieldValues = $changedFieldsArr["{$fileFieldName}ID"];

             if (
                 (
                     $changedFieldValues['before'] != $changedFieldValues['after']
                     &&
                     $changedFieldValues['before'] != 0
                     &&
                     $changedFieldValues['after'] != 0
                 )
                 ||
                 (
                     $changedFieldValues['after'] == 0
                     &&
                     $changedFieldValues['before'] != 0
                 )
             ){
                 $this->killFile($changedFieldValues['before']);
             }
         }
     }
 }

用法: 1.附加到DataObject

SilverStripeORMDataObject:
  extensions:
    - DataObjectRemoveImagesExt
  1. 在自定义DataObject子项中,使用此属性设置要删除的文件/图像 private static $ kill_on_detach = ['Image','Thumb',];

解决方案并不完美:

  • 即使它附加到另一个DataObject实例,它也会杀死文件
  • 如果用户从admin-panel分离文件并忘记保存DataObject,它不会杀死文件

如果有人想提出更好的决定 - 欢迎。

以上是关于如何从SilverStripe管理员中的DataObject分离文件系统时删除文件(图像)?的主要内容,如果未能解决你的问题,请参考以下文章

如何将原始 SQL 查询转换为 Silverstripe SQLQuery 抽象层

Silverstripe 4.6 从 url 创建/保存图像对象

Silverstripe类GridFieldConfig_RelationEditor

Silverstripe 3:如何按标题,日期等对CMS网站树中的页面进行排序

Silverstripe - 在模板中循环非关联数组

如何在 SilverStripe 4 CMS 中添加自定义样式