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

问题描述 投票:1回答:2

例如,我有这个代码

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如何自动从文件系统中删除文件?

forms orm silverstripe
2个回答
1
投票

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

**更新**

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


0
投票

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

<?php
use SilverStripe\ORM\DataExtension;
use SilverStripe\Assets\File;

 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

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

解决方案并不完美:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.