Forms 在SilverStripe admin中,当文件系统与DataObject分离时,如何从文件系统中删除文件(映像)?
例如,我有这个代码Forms 在SilverStripe admin中,当文件系统与DataObject分离时,如何从文件系统中删除文件(映像)?,forms,orm,silverstripe,Forms,Orm,Silverstripe,例如,我有这个代码 class MyDataObject extends DataObject { private static $has_one = [ "MyImage" => Image::class, ]; public function getCMSFields(){ $fields = parent::getCMSFields(); $fields->addFieldsToTab('Root.Mai
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中删除文件时
该文件仍然保留在cms的“文件”部分、数据库和文件系统中,所以用户需要转到“文件”并手动删除
在实践中,他经常忘记在将文件从某个数据对象中分离出来后将其删除,而所有这些文件占据了很多位置
当用户单击屏幕截图上的十字时,SilverStripe如何自动从文件系统中删除文件?您的数据对象上需要一个
onAfterDelete()
。您可以在那里删除该文件。
(不要忘记在方法中调用Parent::onAfterDelete()
)
**更新**
或者,如果只有当用户正在编辑而不是删除您的对象时,
onAfterWrite()
才是您的朋友。在那里,您可以比较图像的旧ID和新ID,如果不同,请删除具有旧ID的图像。要解决我创建此扩展的问题,请
<?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']);
}
}
}
}
- 即使文件附加到另一个DataObject实例,它也会终止该文件
- 若用户将文件从管理面板中分离并忘记,它不会终止文件 保存数据对象的步骤
如果有人想提出更好的决策-欢迎。如果文件在其他地方使用,不要忘记检查;e、 g.如果是
,则对您自己的数据对象有许多。@Ben您是否正确理解了这个问题?我不确定。您谈论的是级联删除,但问题是MyDataObject实例需要保留。仅从MyDataObject实例中删除图像。现在我正在深入研究onAfterWrite()
和$this->getChangedFields()
@FlamyTwista这不是级联删除,而只是一个钩子,当用户删除数据对象时,可以删除(或执行任何操作)相关对象。“有问题的MyDataObject实例需要保留”=>这不是您在问题中所说的。“当用户在admin中从MyDataObject中删除文件时。此文件仍保留在cms的“文件”部分、数据库中和文件系统中,因此用户需要转到“文件”并手动删除。当用户单击屏幕截图上的“十字”时,SilverStripe如何从文件系统中自动删除文件?”听起来这正是您所要求的。@FlamyTwist更新了对编辑数据对象的响应
SilverStripe\ORM\DataObject:
extensions:
- DataObjectRemoveImagesExt