Я использовал следующий пример для реализации:
У меня есть Entity для страницы и для тэгов к страницам:
MyModule\Entity\Page
MyModule\Entity\Tag
Для одной страницы можно указать N тэгов.
На странице добавления страницы не удается динамически добавлять тэги для страницы. Подскажите что я делаю не так.
Привожу листинг основных файлов:
Модель Страницы:
namespace MyModule\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* Page
*
* @ORM\Table(name="page", indexes={@ORM\Index(name="fk_page_category", columns={"category_id"})})
* @ORM\Entity
*/
class Page
{
/**
* @var integer
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* @var \MyModule\Entity\Category
* @ORM\ManyToOne(targetEntity="MyModule\Entity\Category")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
* })
*/
private $category;
/**
* @ORM\OneToMany(targetEntity="MyModule\Entity\Tag", mappedBy="page", cascade={"persist"})
*/
protected $tags;
/**
* Never forget to initialize all your collections !
*/
public function __construct()
{
$this->tags = new ArrayCollection();
}
/**
* @param Collection $tags
*/
public function addTags(Collection $tags)
{
foreach ($tags as $tag) {
$tag->setPage($this);
$this->tags->add($tag);
}
}
/**
* @param Collection $tags
*/
public function removeTags(Collection $tags)
{
foreach ($tags as $tag) {
$tag->setPage(null);
$this->tags->removeElement($tag);
}
}
/**
* @return Collection
*/
public function getTags()
{
return $this->tasg;
}
/**
* Get category_id.
* @return string
*/
public function getCategory()
{
return $this->category;
}
/**
* Set category_id.
* @param Category $category
* @return Category
*/
public function setCategory($category)
{
$this->category = $category;
return $this;
}
}
Модель Тэга:
namespace MyModule\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Tag
* @ORM\Table(name="tag", indexes={@ORM\Index(name="fk_tag_page", columns={"page_id"})})
* @ORM\Entity
*/
class Tag
{
private $id;
private $name;
/**
* @var \MyModule\Entity\Page
* @ORM\ManyToOne(targetEntity="MyModule\Entity\Page")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="page_id", referencedColumnName="id")
* })
*/
private $page;
/**
* Allow null to remove association
* @param Page $page
*/
public function setPage(Page $page = null)
{
$this->page = $page;
}
/**
* @return Page
*/
public function getPage()
{
return $this->page;
}
}
MyModule\Form\PageFieldset:
namespace MyModule\Form;
use MyModule\Entity\Page;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
class PageFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct(ObjectManager $objectManager)
{
parent::__construct('page');
$this->setHydrator(new DoctrineHydrator($objectManager))
->setObject(new Page());
$this->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'name'
));
$tagsFieldset = new TagFieldset($objectManager);
$this->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'tags',
'options' => array(
'count' => 2,
'target_element' => $tagFieldset
)
));
}
public function getInputFilterSpecification()
{
return array(
'name' => array(
'required' => true
),
);
}
}
MyModule\Form\TagFieldset:
namespace MyModule\Form;
use MyModule\Entity\Tag;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
class TagFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct(ObjectManager $objectManager)
{
parent::__construct('tag');
$this->setHydrator(new DoctrineHydrator($objectManager))
->setObject(new Tag());
$this->add(array(
'type' => 'Zend\Form\Element\Hidden',
'name' => 'id'
));
$this->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'name',
'options' => array(
'label' => 'Tag'
)
));
}
public function getInputFilterSpecification()
{
return array(
'id' => array(
'required' => false
),
'name' => array(
'required' => true
)
);
}
}
MyModule\Form\PageForm:
namespace MyModule\Form;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Form;
class PageForm extends Form
{
protected $objectManager;
/**
* Set the object manager
*
* @param ObjectManager $objectManager
*/
public function setObjectManager(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
}
/**
* Get the object manager
*
* @return ObjectManager
*/
public function getObjectManager()
{
return $this->objectManager;
}
public function __construct(ObjectManager $objectManager)
{
parent::__construct('page-form');
$this->setObjectManager($objectManager);
// The form will hydrate an object of type "Page"
$this->setHydrator(new DoctrineHydrator($objectManager));
// Add the user fieldset, and set it as the base fieldset
$pageFieldset = new PageFieldset($objectManager);
$pageFieldset->setUseAsBaseFieldset(true);
$this->add($pageFieldset);
$this->createElements();
}
public function createElements()
{
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'security',
'type' => 'Zend\Form\Element\Csrf',
));
$this->add(array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'category',
'options' => array(
'label' => 'Category',
'empty_option' => 'Select platform ...',
'object_manager' => $this->getObjectManager(),
'target_class' => 'MyModule\Entity\Category',
'property' => 'name'
),
'attributes' => array(
'required' => 'required'
)
));
$this->add(array(
'name' => 'name',
'type' => 'Text',
'options' => array(
'label' => 'Name'
),
'attributes' => array(
'required' => 'required'
)
));
$this->add(array(
'name' => 'submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Save'
)
));
}
}
Ну и наконец представление add.twig:
{% extends 'layout/layout.twig' %}
{% block content %}
<h1>Add Page</h1>
<div>
{{ form().prepare() }}
{{ form().openTag(form)|raw }}
{% for element in form %}
{% set attributes = element.getAttributes() %}
{% if type != 'hidden' and type != 'submit' %}
<div class="field">
{% endif %}
{% if attributes.type is defined %}
{% set type = attributes.type %}
{% else %}
{% set type = '' %}
{% endif %}
{% if type != 'hidden' and type != 'submit' %}
<label for="{{ element.getName() }}">{{ element.getLabel() }}: </label>
{% if attributes.required is defined %}
<abbr title="Обязательное поле">*</abbr>
{% endif %}
{% endif %}
{% if type == 'text' %}
{{ formInput(form.get( element.name ))|raw }}
{% elseif type == 'textarea' %}
{{ formTextarea(form.get( element.name ))|raw }}
{% elseif type == 'select' %}
{{ formSelect(form.get( element.name ))|raw }}
{% elseif type != 'hidden' and type != 'submit' %}
{{ formRow().setInputErrorClass('error').render(form.get( element.name ))|raw }}
{% endif %}
{% if type != 'hidden' and type != 'submit' %}
</div>
{% endif %}
{% endfor %}
{{ formCollection(form.get( 'page' ).get( 'tags' ))|raw }}
{{ formRow(form.get('submit'))|raw }}
{{ form().closeTag(form)|raw }}
</div>
{% endblock content %}
Подскажите что нужно поправить, чтобы при создании Page можно было динамически добавлять сколько угодно Tag ?