【问题标题】:Find whether an Image is used anywhere查找图像是否在任何地方使用
【发布时间】:2016-06-29 20:48:04
【问题描述】:

在我的 SilverStripe 3.4 环境中,我有一堆带有附加图片的不同模型,例如:

  • BlogPosthas_oneImage(来自 silverstripe/blog)
  • Widgethas_oneImage(通过 silverstripe/widgets)
  • MyWidgethas_oneImage(自定义模块)

我想阻止图像,例如如果 ID 123 用于上述任何一项,则不会在 CMS 管理员中被删除(作为示例 - 这应该是系统范围的)。

有没有一种方法可以一次检查所有具有相关图像的模型,可能是通过Image belongs_many_many 查找或其他方式?

【问题讨论】:

    标签: php silverstripe


    【解决方案1】:

    您可能需要通过DataExtension 子类装饰Image,并使用自定义onBeforeDelete()validate() 声明一个$belongs_to 静态数组。

    无论如何,您都可以在其中调用一个例程来检查您的数据库的必要条件。您选择使用哪种方法 由可能在您的系统中删除 Image 记录的场景决定(例如,您可能有一些自动化的非人工任务,您希望避免的场景被播放 - 所以您会避免 validate() 和使用onBeforeDelete())

    类似的东西(完全未经测试!)

    class MyImageExtension extends DatExtension
    {
    
        public function onBeforeDelete()
        {
            if (!$this->imagesExistThatShouldNotBeDeleted()) {
                parent::onBeforeDelete();
            }
        }
    
        /**
         * @return boolean True if images exist that shouldn't be deleted, false otherwise.
         */
        private function imagesExistThatShouldNotBeDeleted()
        {
            $owner = $this->getOwner();
            $dataObjectSubClasses = ClassInfo::getValidSubClasses('DataObject');
            $classesWithImageHasOne = [];
            foreach ($dataObjectSubClasses as $subClass) {
                if ($classHasOneImage = $subClass::create()->hasOneComponent('Image')) {
                    $classesWithImageHasOne[] = $classHasOneImage;
                }
            }
    
            if (in_array($owner->class, $classesWithImageHasOne)) {
                return true;
            }
    
            return false;
        }
    
    }
    

    【讨论】:

    • 谢谢拉塞尔。假设我不知道有多少模型与图像相关,我可以使用与您描述的相同的概念来实现这一点,还是我需要了解所有关系才能使这种方法起作用?
    • 我已根据您的问题更新了“解决方案”。注意:上面的解决方案假定所有有一个类的Image has_one 被称为Image。如果您已将 Image 子类化,那么您需要修改对 DataObject::hasOneComponent() 的调用,例如使用 in_array()
    • 你不能通过不调用parent::onBeforeDelete();来阻止删除。在DataExtension 中执行此操作没有任何效果。即使在课堂上这样做也会很糟糕,因为它会引发“broken onBeforeDelete”错误。我认为改写canDelete 权限会更好吗?或者如果你想硬核的话,在onBeforeDelete 中抛出一个错误。
    • 是的,刚刚重新看了一遍,你是绝对正确的。无论是抛出错误(肯定是异常?)还是使用 canDelete(),两者都会分别导致 500 或 403 HTTP 状态码,因此无论如何都需要处理,
    猜你喜欢
    • 2011-01-23
    • 2010-10-29
    • 1970-01-01
    • 2014-09-27
    • 2022-12-01
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    相关资源
    最近更新 更多