在研究this question时,我想出了以下解决方案,该解决方案从canDelete()
的{{1}}扩展名调用{/ 1}}:
File
虽然有一个我无法解决的边缘情况。例如,如果在博客文章中更改了特色图像,那么如果只有一个其他使用相同的图像,那么使用这种方法它仍然允许它被删除。这是因为在保存页面之前,当前的更改并不计入图像的使用。
在CMS页面和媒体管理器中以不同方式设置阈值,以允许从正在使用它的页面中删除图像。
有没有办法可以在我的文件扩展程序中访问包含页面(或其他元素 - 我们正在使用Elemental)来查看其相关图像是否已更改?
答案 0 :(得分:2)
这是我最终提出的解决方案。我不必完全不必检查请求,但看不到任何其他解决方案:
public function canDelete($member = null)
{
return !$this->isFileInUse();
}
/**
* Check if the file is in use anywhere on the site
* @return bool True if the file is in use
*/
protected function isFileInUse()
{
$owner = $this->getOwner();
$dataObjectSubClasses = ClassInfo::subclassesFor('DataObject');
$classesWithFileHasOne = [];
foreach ($dataObjectSubClasses as $subClass) {
$hasOnes = array_flip($subClass::create()->hasOne());
if (array_key_exists($owner->class, $hasOnes)) {
$classesWithFileHasOne[$subClass] = $hasOnes[$owner->class];
}
}
$threshold = ($this->isAssetAdmin() || ($this->isFileAttach($classesWithFileHasOne))) ? 1 : 2;
$uses = 0;
foreach ($classesWithFileHasOne as $class => $relation) {
$uses += count($class::get()->filter("{$relation}ID", $this->owner->ID));
if ($uses >= $threshold) {
return true;
}
}
return false;
}
/**
* Are we in the asset manager rather than editing a Page or Element?
* @return bool
*/
protected function isAssetAdmin()
{
return 'AssetAdmin' === Director::get_current_page()->class;
}
/**
* Is the current action attaching a file to a field that we're interested in?
* @param array $classesWithFileHasOne Classes with a relationship we're interested in and the name of the
* relevant field
* @return bool
*/
protected function isFileAttach($classesWithFileHasOne)
{
$controller = Controller::curr();
$field = $controller->request->allParams()['FieldName'];
return (preg_match('/attach$/', $controller->requestParams['url']) &&
($controller->action == 'EditForm')
&& (in_array($field, array_values($classesWithFileHasOne))));
}