2013-07-21 304 views
2

我有以下表格:電影,類別,films_categories和實體:Zend框架2學說2多對多實體關係問題

Film.php

<?php 

namespace Admin\Entity; 

use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\Common\Collections\Collection; 
use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\Table(name="films") 
*/ 
class Film{ 

    /** 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * @ORM\Column(type="integer") 
    * @ORM\Column(length=11) 
    */ 
    private $id; 

    /** 
    * @ORM\Column(type="string") 
    */ 
    private $name; 

    /* .... */ 

    /** 
    * @ORM\ManyToMany(targetEntity="Category") 
    * @ORM\JoinTable(name="films_categories", 
    *    joinColumns={@ORM\JoinColumn(name="film_id", referencedColumnName = "id")}, 
    *    inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")}) 
    */ 
    private $categories; 

    public function __construct(){ 
     $this->categories = new ArrayCollection(); 
    } 

    public function getCategoriesNames(){ 
     $names = array(); 
     foreach($this->categories as $category){ 
      $names[] = $category->getName(); 
     } 
     return $names; 
    } 

    public function getId(){ 
     return $this->id; 
    } 

    public function setId($id){ 
     $this->id = $id; 
    } 

    /* ... */ 

    /** 
    * @return Collection 
    */ 
    public function getCategories(){ 
     return $this->categories; 
    } 

    public function addCategories(Collection $categories){ 
     foreach($categories as $category){ 
      $this->categories->add($category); 
     } 
    } 

    public function removeCategories(Collection $categories){ 
     foreach($categories as $category){ 
      $this->categories->removeElement($category); 
     } 
    } 
} 

Category.php

<?php 

namespace Admin\Entity; 

use Doctrine\ORM\Mapping as ORM; 


/** 
* @ORM\Table(name="categories") 
*/ 
class Category { 

    /** 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * @ORM\Column(type="integer") 
    */ 
    private $id; 

    /* ... */ 

    public function getId(){ 
     return $this->id; 
    } 

    public function setId($id){ 
     $this->id = $id; 
    } 

    /* ... */ 
} 

我想要做的是創建一個表單和添加一個新電影併爲其分配類別的操作。下面是我用的形式:

FilmFieldset.php

<?php 
namespace Admin\Form; 

use Zend\Form\Fieldset; 
use Zend\InputFilter\InputFilterProviderInterface; 
use DoctrineORMModule\Stdlib\Hydrator\DoctrineEntity; 
use Admin\Entity\Film; 

class FilmFieldset extends Fieldset implements InputFilterProviderInterface{ 

    protected $entityManager; 

    public function __construct($em){ 

     parent::__construct('film'); 


     $this->entityManager= $em; 
     $this->setHydrator(new DoctrineEntity($em,'Admin\Entity\Film')) 
      ->setObject(new Film()); 

     #$this->setAttribute('method','post'); 
     #$this->setAttribute('class','standardForm'); 

     $this->add(array(
      'name' => 'id', 
      'type' => 'hidden' 
     ));  

     /* ... */ 

     $this->add(
      array(
       'type' => 'DoctrineModule\Form\Element\ObjectSelect', 
       'name' => 'categories', 
       'attributes' => array(
        'multiple' => 'multiple', 
       ),     
       'options' => array(
        'object_manager' => $em, 
        'target_class' => 'Admin\Entity\Category', 
        'property'  => 'name', 
        'label'   => 'Categories: ', 
        'disable_inarray_validator' => true    
       ), 
      ) 
     );      

    } 

    public function getInputFilterSpecification(){ 
     return array(
        /* .... */ 
      'categories' => array(
       'required' => true,     
      ),     
     ); 
    } 

} 

的FilmForm.php

<?php 
namespace Admin\Form; 

use Zend\Form\Form; 
use Zend\Stdlib\Hydrator\ClassMethods; 
use Admin\Entity\Film; 
use Zend\InputFilter\InputFilter; 
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator; 

class FilmForm extends Form{ 

    public function __construct($em){ 
     parent::__construct('filmForm'); 

     $this->setAttribute('method','post') 
      ->setAttribute('class','standardForm') 
      ->setHydrator(new DoctrineHydrator($em,'\Admin\Entity\Film')) 
      ->setInputFilter(new InputFilter()); 

      /* I register the fieldset through a service and not directly here */ 
     // $this->add(array(
      // 'type' => new FilmFieldset($em), 
      // 'options' => array(
       // 'user_as_base_fieldset' => true 
      //) 
     //)); 

     $this->add(array(
      'name' => 'security', 
      'type' => 'Zend\Form\Element\Csrf' 
     )); 

     $this->add(array(
      'name' => 'submit', 
      'type' => 'submit', 
     )); 

     $this->setValidationGroup(array(
      'security', 
      'film' => array(
       'categories', 
      ) 
     )); 
    } 


} 

的的addAction:

public function addAction() { 
    $em = $this->getEntityManager(); 
    $form = $this->getForm(); 
    $film = new Film(); 
     $form->bind($film); 

    if($request->isPost()){ 
     $post = array_merge_recursive(
        $request->getPost()->toArray(), 
        $request->getFiles()->toArray() 
       );  
     $form->setData($post); 
     if($form->isValid()){ 
      $categories = array(); 
      foreach($post['film']['categories'] as $categoryId){ 
       $categories[] = $em->getRepository('Admin\Entity\Category')->find($categoryId); 
      } 

      $film->addCategories($categories); 

      $em->persist($film); 
      $em->flush(); 
     }else{ 
      // the form is not valid 
     } 
    } 

結果是各種錯誤和與ORMExcption與消息「找到關聯Admin \ Entity \ Film#類別類型的實體,但期望Admin \ Entity \類別「

請幫助我,我真的嚇壞了這個!謝謝:)

+0

從我發現的錯誤是Admin \ Entity \ Film#類別意味着您正在傳遞一些值到您的實體,因爲它期望類型爲「Admin \ Entity \ Category」類型的對象。 –

回答

1

從我從這個發現是一些像這樣的事情,你的實體接收聯繫\實體\電影#類別和這部分類別是一些什麼值。當您的實體期待Admin \ Entity \ Film#類別的對象

爲了克服這一點,你必須創建一個

public function SetCategory(Admin\Entity\Category Category) 
{ 
$this->categories(or category or w/e your variable name is)= Category; 
} 
public function getCategory() 
{ 
return $this->categories(or category or w/e your variable name is); 
} 

然後在你的行動,你必須通過類別的對象電影實體在一些這樣的事

$Film->SetCategory($categoryObj); 

當然你必須根據你的部分來設置你的業務邏輯,但是這個錯誤應該被這個apporach去掉。

+0

一些修改它實際上工作,雖然我有之前嘗試過類似的東西謝謝:) – Systemfreak

+0

歡迎您,如果您不介意,您是否也可以發佈修改,以便其他人也可以獲得幫助 –

0

您需要爲targetEntity定義FQCN。

變化:

* @ORM\ManyToMany(targetEntity="Category") 

到:

* @ORM\ManyToMany(targetEntity="Admin\Entity\Category") 
+0

我改變了它,即時通訊仍然得到相同的錯誤:/ – Systemfreak

+1

只要實體在同一個命名空間,他們不**需要完全合格;) – Sam

0

這與水合和延遲加載有關。我不是這方面的專家,但#categories是一個代理對象,當您要保存它時,它會抱怨,因爲它需要是實際的集合,而不是集合的代理對象。

如果您使用noobie-php的方法,您將在主對象上重新添加新的類別對象,因此它們不再是代理服務器。

這是令人沮喪的,因爲教條本應該爲此節省很多麻煩,但實際上並沒有達到你在許多情況下自然期待的。我在前段時間發現了一個錯誤票,但現在找不到它 - 如果我能找到它,它將添加到此。