TYPO3 extbase:获取模型对象中的父对象

TYPO3 extbase: Get parent object in model object

我有两 (2) 个 classes:

人物模型class

<?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;
    }
}

邮政地址模型class

<?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 级别是否支持此类反向引用?

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

据我了解 MVC 模式,模型应该只携带数据,没有逻辑,也没有任何类型的依赖关系。 因此,为了解决您的问题,我将使用两个不同的模型 classes,基于相同的 table,仅包含适用于该特定模型的属性和验证元数据。

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

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;

    [...]

}

现在你必须告诉持久层,那些模型都去同一个 table。您可以在该插件的错字设置中执行此操作。

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
                }
            }
    }
}  

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

控制器中的 "choose the right model" 逻辑有时可能有点棘手。通常,您需要在适当的 "initializeXxxAction" 方法中放置一些处理 extbase "property mapper" 的代码。 一开始我受到这篇德语文章的启发(对于旧版本的 extbase!):https://jweiland.net/typo3/codebeispiele/extension-programmierung/extbase-dynamische-validierung.html 希望google翻译能给您一些提示,解决即将出现的问题。

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

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

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

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