2017-02-20 35 views
0

我有两个(2)班:TYPO3 extbase:获取父对象模型对象

Person模型类

<?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级别的反向引用?

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

+0

我将不同的方式处理这个问题。这不是控制器工作恕我直言。这是一个**模板**作业。如果模板中的条件显示正确的布局(字段可编辑或不),我会使用它。之后,您必须确保没有人能够通过开发人员工具让字段可编辑。即'if($ model-> isAllowedProperty){AddFieldToResultArrOrSimilar}' – Xatenev

+0

我同意Xatenev在这里。这属于它在模板中的区别。 – j4k3

+0

@Xatenev你可以创建一个答案吗? –

回答

0

我会以不同的方式处理问题。这是no controller job imho。这仅仅是模板/查看作业。如果模板中的条件显示正确的布局(字段可编辑或不),我会使用它。之后,您必须确保没有人能够通过开发人员工具让字段可编辑。

这将是通过在后端逻辑添加条件,例如可实现的:

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

据我了解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 希望谷歌翻译会给你一些提示,以解决upcomming问题。

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

+0

然后你完全误解了MVC模式。 Theres在模型中没有任何错误的逻辑和依赖关系。如果在这种情况下,数据严格限于实体的实例,那么它就是域逻辑。该模型正是和唯一的地方ist属于。胸围不要拿我的话:http://softwareengineering.stackexchange.com/questions/176639/why-put-the-business-logic-in-the-model-what-happens-when-i-have-multiple-类型 – j4k3

+0

OK j4k3,你是对的。也许我不应该使用术语“模型”,而是使用“实体”,因为这就是我的意思。根据我的经验,将所有应用程序逻辑从实体中提取出来是更清洁和更安全的。一个实体经理类ehich也将成为模型层的一部分,这也许就是你的意思。在Symfony中,例如每次我试图欺骗一些外部依赖到实体类中(因为它有时非常方便),迟早我遇到了“循环依赖问题”,所以我会坚持我的习惯,只将实体保留为值对象。 –