简体   繁体   English

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

[英]TYPO3 extbase: Get parent object in model object

I have got two (2) classes: 我有两(2)个课程:

Person model 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;
    }
}

PostalAddress model class 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;
    }
}

In the controller PostalAddressConroller I have got an action which creates the form to edit a single address. 在控制器PostalAddressConroller我有一个操作,该操作创建用于编辑单个地址的表单。

I would like to make some fields editable only if certain conditions are met. 我想使某些字段仅在满足某些条件时才可编辑。 Example: The organization fields on the address are only editable in case the person is of type private person and the address is of type employer. 示例:仅当此人属于私人类型并且该地址属于雇主类型时,地址上的组织字段才可编辑。

To implement such a condition check, I would like to create a method on the PostalAddress model. 为了实现这种条件检查,我想在PostalAddress模型上创建一个方法。 But for this, It would require to have a reference back to the parent object inside the controller. 但是为此,它需要对控制器内部的父对象有一个引用。

I would like to avoid to put all the logic inside the templates to keep the templates clean and easy to understand. 我想避免将所有逻辑放在模板内部,以保持模板整洁和易于理解。

Is there support on extbase level for such back references? extbase级别上是否支持此类反向引用?

In case I have to implement such a back reference myself: How do I prevent circular references in general (for example on object serialization)? 如果我必须自己实现这种反向引用:如何一般地防止循环引用(例如,关于对象序列化)?

I would handle the problem differently. 我会以不同的方式处理这个问题。 This is no controller job imho . 不是管理员的工作 This is definetly a template/view job . 这绝对是模板/视图作业 I'd use if conditions in the template to show the correct layout (field editable or not). 我会使用if模板中的条件来显示正确的布局(是否可编辑字段)。 Afterwards you have to make sure that nobody can just make the fields editable via developer tools for example. 之后,您必须确保没有人可以通过例如开发人员工具使字段可编辑。

That would be achievable by adding conditions in the backend logic, for example: 这可以通过在后端逻辑中添加条件来实现,例如:

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

As I understand the MVC pattern, the model should only carry data, no logic and no dependencies of any kind. 据我了解,MVC模式,该模型应该只携带数据,没有逻辑,也没有任何依赖关系。 So to solve you problem I would use two different model classes, based on the same table, carying only those properites and validation metadata which applies to that particular model. 因此,为解决您的问题,我将基于同一张表使用两个不同的模型类,仅处理适用于该特定模型的那些属性和验证元数据。

Imagine those two models below: 想象下面的两个模型:

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;

    [...]

}

Now you must tell the persistence layer, that those models goes to the same table. 现在,您必须告诉持久层,这些模型将进入同一表。 You do this in typoscript setup for that plugin. 您可以在该插件的排印设置中执行此操作。

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

Now you can transfer the logic into the controller and decide there which model to use. 现在,您可以将逻辑传输到控制器中,并在其中确定要使用的模型。 You can extend this simple case using a common Interface or abstract class, etc. 您可以使用通用接口或抽象类等扩展这种简单情况。

This "choose the right model" logic in the controller may be a little bit tricky at times. 控制器中的这种“选择正确的模型”逻辑有时可能会有些棘手。 In general you will need to place some code dealing with the extbase "property mapper" inside the appropriate "initializeXxxAction" method. 通常,您需要在适当的“ initializeXxxAction”方法中放置一些处理extbase“属性映射器”的代码。 At the begining I was inspired by this article in german (for an older version extbase!): https://jweiland.net/typo3/codebeispiele/extension-programmierung/extbase-dynamische-validierung.html Hope google translate will give you some hints to solve upcomming problems. 一开始,我受到了这篇德语文章的启发(对于较旧版本的extbase!): https ://jweiland.net/typo3/codebeispiele/extension-programmierung/extbase-dynamische-validierung.html希望Google翻译会给您一些帮助解决即将到来的问题的提示。

On top you can assist the server based validation and processing by some frontend work. 最重要的是,您可以通过一些前端工作来协助基于服务器的验证和处理。 Eg JavaScript tricks to enable or disable certain formular fields depending on the private/commercial status chosen. 例如,JavaScript技巧根据所选择的私有/商业状态启用或禁用某些公式字段。 You can as well tune the fluid templates to render/not render certain parts depending of the model variant used in controller. 您还可以根据控制器中使用的模型变量来调整流体模板以渲染/不渲染某些零件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM