I am pretty new to Zend Framework 2 and Doctrine 2, so I am not even sure how to search or debug my problem.
I have 3 database tables
1. advert
id
adverttitle
...
2. category
id
categoryname
...
3. advert_category
advert_id
category_id
I have created 2 Entities, Advert and Category. I have now got a Form where I show the Categories to choose from. I use jQuery to display the categories as a list instead of a dropdown, together with a selectable function. So when you click on a category, the value of this listelement gets entered into a hidden input field called categories.
Everything works fine, besides that when I display the form, the hidden categories input field got a value of Doctrine\Common\Collections\ArrayCollection@000000000..... instead of being empty. What am I doing wrong here? I have tried to find a solution, but unsuccessfully.
I have chosen a ManyToMany Relationship because I want to be able to save more then 1 category in the end. Currently it is only working with 1, but this way I should be able to change this at a later time.
Here my Advert entity:
namespace Advert\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use DateTime;
/** Advert
*
* @ORM\Table(name="advert")
* @ORM\Entity(repositoryClass="Advert\Repository\AdvertRepository")
*/
class Advert
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="advert_title", type="string", length=255, nullable=true)
*/
private $advertTitle;
/**
* @ORM\ManyToMany(targetEntity="Category", inversedBy="adverts", cascade={"persist"})
* @ORM\JoinTable(name="advert2category")
*/
private $categories;
public function __construct()
{
$this->categories = new ArrayCollection();
}
/**
* Set categories
*
* @param ArrayCollection $category
* @return Advert
*/
public function setCategories($categories)
{
$this->categories = $categories;
return $this;
}
/**
* Get categories
*
* @return ArrayCollection
*/
public function getCategories()
{
return $this->categories;
}
/**
* @param Collection $categories
*/
public function addCategories($categories)
{
foreach ($categories as $category) {
$this->categories->add($category);
}
}
/**
* @param Collection $categories
*/
public function removeCategories($categories)
{
foreach($categories as $category){
$this->categories->removeElement($category);
}
}
Is there an Error in the Advert Entity which causes this? I hope someone can help. I have this problems since weeks and can not get it to work correctly.
UPDATE -- added my Form and part in controller to call form
The below Form displays 2 Dropdown Elements and 2 Hidden Input Fields. The 2 Dropdown Fields get turned into a selectable List via jQuery. When you click on a List Element from the Maincategory, the Subcategories show up for that chosen Maincategory again as a selectable list. The MaincategoryID gets then entered into the hidden categoryID Field. As soon you choose the Subcategory from the List, the id of that category gets written in the hidden categories field. A click on the "next" button saves the value of $_POST['categories'] together with the advertID in my linking table.
use Zend\Form\Form;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;
class CategoryForm extends Form implements ObjectManagerAwareInterface
{
protected $objectManager;
public function __construct()
{
$this->setInputFilter(new AdvertFilter());
parent::__construct('category');
}
public function init()
{
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'categories',
'attributes' => array(
'type' => 'hidden',
'id' => 'categories',
),
'options'=> array(
'label'=> 'categories',
),
));
$this->add(
array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'categoriesList',
'options' => array(
'object_manager' => $this->getObjectManager(),
'label' => 'Main Category',
'target_class' => 'Advert\Entity\Category',
'property' => 'name',
'is_method' => true,
'find_method' => array(
'name' => 'getMainCategories',
),
),
'allow_empty' => true,
'required' => false,
'attributes' => array(
'id' => 'categoryList',
'multiple' => true,
)
)
);
$this->add(
array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'subcategoryList',
'options' => array(
'object_manager' => $this->getObjectManager(),
'label' => 'Sub Category',
'target_class' => 'Advert\Entity\Category',
'property' => 'name',
'is_method' => true,
'find_method' => array(
'name' => 'getSubCategories',
),
),
'allow_empty' => true,
'required' => false,
'attributes' => array(
'id' => 'subcategoryList',
'multiple' => true,
)
)
);
$this->add(array(
'type' => 'hidden',
'name' => 'categoryID',
'options'=> array(
'label'=> 'categoryID'),
'attributes' => array(
'id' => 'categoryID',
'value' => '1',
)
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Next',
'id' => 'submitbutton',
),
));
}
public function setObjectManager(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
}
public function getObjectManager()
{
return $this->objectManager;
}
}
In my Controller I call my form the following way:
$sl = $this->getServiceLocator();
$form = $sl->get('FormElementManager')->get('\Advert\Form\CreateForm');
# create a new, empty entity
$advert = new Advert();
# set the hydrator to connect form and entity
$form->setHydrator(new DoctrineHydrator($this->getEntityManager(),'Advert\Entity\Advert'));
# connect form and entity
$form->bind($advert);