2013-09-16 64 views
1

我已經創建了一個Object to ID Data Transformer。它是自定義ObjectIdType的一部分,它允許我輸入文檔的ID而不是使用「文檔」表單類型。這對於MongoDB非常有用(可能有1億個文檔可供選擇)。Symfony2 - 由於設置器上的類型提示而被迫在DataTransformer內部進行驗證

數據轉換器對該ID執行查詢並返回一個對象。如果找不到對象,則返回null。問題是 - 有時候null是一個可接受的值,有時它不是。

即使我添加NOTNULL驗證,我碰到下面的錯誤 -

捕致命錯誤:傳遞給角色:: setPlayer(參數1)必須是文件\ Player實例中,空給出

因此,無論驗證失敗,它都會調用setter。我通過在變換器中拋出一個TransformationFailedException來解決這個問題 - 但這似乎是一個糟糕的主意。我不應該使用數據轉換器來驗證。

變壓器的代碼如下。我想要的是能夠將驗證器放在正確的位置,並攔截setter,使其不會被調用。一般來說,這似乎有點代碼味,我很想知道其他人是如何解決這個問題的。

class ObjectToIdTransformer implements DataTransformerInterface 
{ 
    private $objectLocator; 
    private $objectName; 
    private $optional; 

    /** 
    * @param ObjectLocator $objectLocator 
    * @param $objectName 
    */ 
    public function __construct(ObjectLocator $objectLocator, $objectName, $optional = false) 
    { 
     $this->objectLocator = $objectLocator; 
     $this->objectName = $objectName; 
     $this->optional  = $optional; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function transform($value) 
    { 
     if (null === $value) { 
      return null; 
     } 

     if (!$value instanceof BaseObject) { 
      throw new TransformationFailedException("transform() expects an instance of BaseObject."); 
     } 

     return $value->getId(); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function reverseTransform($value) 
    { 
     if (null === $value) { 
      return null; 
     } 

     $repo = $this->objectLocator->getRepository($this->objectName); 
     $object = $repo->find($value); 

     if (!$this->optional && !$object) { 
      throw new TransformationFailedException("This is probably a bad place to validate data."); 
     } 

     return $object; 
    } 
} 

回答

3

其實,這是一個PHP怪癖,很直觀 - 特別是對於那些來自其他(邏輯的,直觀的,理智的)像Java語言未來。如果你希望能夠到null參數傳遞給typehinted參數,你必須爲它的默認值設置爲null

public function setPlayer(Player $player = null) 
{ 
    // ... 
} 

是啊,在這裏談論一些一致性...

+0

哦,我沒根本不需要setter中的null值,因爲null不是有效的選項,所以它被有意刪除。你認爲我應該允許null,然後讓驗證器處理它嗎?我沒有考慮過這個問題,因爲我的獲得者和制定者都嚴格地設置,以反映底層資產是否可以爲空。 – james853

+1

是的,你應該允許'null'值並讓驗證器處理它。 –

+0

好的,謝謝。老實說,我認爲這是一種解決方法,但我認爲沒有更好的方法。如果在通過setter將對象提交給對象之前,有人會攔截提交的值,但我認爲這只是Symfony的限制。 – james853