【问题标题】:TYPO3 extbase: Get parent object in model objectTYPO3 extbase:获取模型对象中的父对象
【发布时间】:2017-02-20 11:33:25
【问题描述】:

我有两 (2) 个课程:

人物模型类

<?php

class Person extends BaseDto
{
    /**
     * @var array|PostalAddress
     */
    protected $postalAddresses = array();

    /**
     * @param array|PostalAddress $postalAddresses
     */
    public function setPostalAddresses($postalAddresses)
    {
        $this->postalAddresses = $postalAddresses;
    }

    /**
     * @return array|PostalAddress[]
     */
    public function getPostalAddresses()
    {
        return $this->postalAddresses;
    }
}

PostalAddress 模型类

<?php

class PostalAddress
{
    /**
     * @var string $privatePersonFirstName
     */
    protected $privatePersonFirstName;

    /**
     * @var string $privatePersonName
     */
    protected $privatePersonName;

    /**
     * @return string
     */
    public function getPrivatePersonFirstName()
    {
        return $this->privatePersonFirstName;
    }

    /**
     * @param string $privatePersonFirstName
     */
    public function setPrivatePersonFirstName($privatePersonFirstName)
    {
        $this->privatePersonFirstName = $privatePersonFirstName;
    }

    /**
     * @return string
     */
    public function getPrivatePersonName()
    {
        return $this->privatePersonName;
    }

    /**
     * @param string $privatePersonName
     */
    public function setPrivatePersonName($privatePersonName)
    {
        $this->privatePersonName = $privatePersonName;
    }
}

在控制器 PostalAddressConroller 中,我有一个操作,它创建表单来编辑单个地址。

我想让某些字段仅在满足某些条件时才可编辑。示例:地址上的组织字段仅在人员为私人类型且地址为雇主类型的情况下才可编辑。

为了实现这样的条件检查,我想在PostalAddress 模型上创建一个方法。但为此,它需要有一个对控制器内部父对象的引用。

我想避免将所有逻辑都放在模板中,以保持模板简洁易懂。

extbase 级别是否支持此类反向引用?

如果我必须自己实现这样的反向引用:我如何防止一般的循环引用(例如对象序列化)?

【问题讨论】:

  • 我会以不同的方式处理这个问题。这不是控制器工作恕我直言。这绝对是一个模板的工作。我会使用模板中的 if 条件来显示正确的布局(字段是否可编辑)。之后,您必须确保没有人可以通过例如开发人员工具使字段可编辑。 IE。 if($model-&gt;isAllowedProperty) { AddFieldToResultArrOrSimilar }
  • 我同意 Xatenev 的观点。这属于模板中的区别所在。
  • @Xatenev 你能创建一个答案吗?
  • @AdrianDymorz 做到了。感谢您通知我(很老的问题)。如果您仍然需要任何帮助,请随时评论我的答案。

标签: php typo3 extbase


【解决方案1】:

我会以不同的方式处理问题。这是恕我直言没有控制器工作。这绝对是模板/视图作业。我会使用模板中的 if 条件来显示正确的布局(字段是否可编辑)。之后,您必须确保没有人可以通过例如开发人员工具使字段可编辑。

这可以通过在后端逻辑中添加条件来实现,例如:

if($model->isAllowedProperty) { AddFieldToResultArrOrSimilar() }

【讨论】:

    【解决方案2】:

    据我了解 MVC 模式,模型应该只携带数据,没有逻辑,也没有任何类型的依赖关系。 所以为了解决你的问题,我会使用两个不同的模型类,基于同一张表,只携带适用于该特定模型的属性和验证元数据。

    想象一下下面这两个模型:

    namespace Acme\MyPlugin\Domain\Model;
    class PostalAddressPrivate
    {
        /**
         * @var string $privatePersonFirstName
         */
        protected $privatePersonFirstName;
    
        /**
         * @var string $privatePersonName
         */
        protected $privatePersonName;
    
        [...]
    
    }
    
    namespace Acme\MyPlugin\Domain\Model;
    class PostalAddressCommercial
    {
        /**
         * @var string $privatePersonFirstName
         */
        protected $companyName;
    
        [...]
    
    }
    

    现在您必须告诉持久层,这些模型将进入同一个表。您可以在该插件的打字稿设置中执行此操作。

    plugin.tx_myplugin {
        persistence {
            classes {
                Acme\MyPlugin\Domain\Model\PostalAddressPrivate {
                    mapping {
                        tableName = tx_myplugin_domain_model_postal_address
                    }
                }
                Acme\MyPlugin\Domain\Model\PostalAddressCommercial {
                    mapping {
                        tableName = tx_myplugin_domain_model_postal_address
                    }
                }
        }
    }  
    

    现在您可以将逻辑传输到控制器并在那里决定使用哪个模型。您可以使用通用接口或抽象类等来扩展这个简单的案例。

    控制器中的这种“选择正确的模型”逻辑有时可能有点棘手。一般来说,您需要在适当的“initializeXxxAction”方法中放置一些处理 extbase“属性映射器”的代码。 一开始我受到这篇德语文章的启发(对于旧版本的 extbase!):https://jweiland.net/typo3/codebeispiele/extension-programmierung/extbase-dynamische-validierung.html 希望谷歌翻译能给你一些提示来解决即将出现的问题。

    最重要的是,您可以通过一些前端工作来协助基于服务器的验证和处理。例如。 JavaScript 技巧可根据所选的私人/商业状态启用或禁用某些公式字段。 您还可以根据控制器中使用的模型变体调整流体模板以渲染/不渲染某些部分。

    【讨论】:

    • 那你完全误解了 MVC 模式。模型中的逻辑和依赖都没有错。如果数据,就像在这种情况下,严格绑定到实体的一个实例,它就是域逻辑。该模型是确切的,并且是唯一的地方。胸围不要相信我的话:softwareengineering.stackexchange.com/questions/176639/…
    • OK j4k3,你是对的。也许我不应该使用术语“模型”而是使用“实体”,因为这就是我真正的意思。根据我的经验,将所有应用程序逻辑从实体中取出来更清洁、更安全。实体管理器类 ehich 也将成为模型层的一部分,这可能就是您的意思。在 Symfony 中,例如每次我试图将一些外部依赖项欺骗到实体类中(因为有时它很方便),迟早我会遇到“循环依赖问题”,所以我会坚持我的习惯,只将实体保留为值对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    • 2014-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多