Заполнение данных отношений в формах Zend Framework 2 через Annotation Builder

В настоящее время у меня есть таблицы статей и тегов. Я пытаюсь автоматически заполнить элемент формы «Tag» как поле выбора в форме статьи. Каков наилучший способ настройки параметров значения поля выбора тегов из таблицы базы данных, а затем также, чтобы статья автоматически связывала данные тега во время вызова метода «bind»?

article.php

<?php
// Article class
class Article {
/**
*
* @var \Doctrine\Common\Collections\Collection|Tag[]
*
* @ORM\ManyToMany(targetEntity="Tag", inversedBy="articles")
* @Orm\JoinTable(name="rel_article_tag", joinColumns={@ORM\JoinColumn(name="article_id", referencedColumnName="article_id")}, inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="tag_id")})
*
* @Form\Required(false)
* @Form\Type("Zend\Form\Element\Select")
* @Form\Options({"label":"Tags: ")
* @Form\Attributes({"id":"tags", "data-placeholder":"Choose tags...", "multiple" : "multiple", "class" : "chosen-select"})
*/
private $tags;

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

public function getTags()
{
return $this->tags;
}

public function addTags($tags)
{
$this->tags = $tags;
}

public function removeTags()
{
$this->tags = new ArrayCollection();
}
}

ArticleController.php

class ArticleController{
public function editAction()
{
$builder = new AnnotationBuilder();
$form = $builder->createForm(new TblArticle());

$id = 1;
$article = $em->find('Admin\Entity\TblArticle', $id);
$form->bind($article);
}
}

ЧТО Я СДЕЛАЛ

В ArticleController::editAction()Я динамически добавил параметры значения к элементу тегов в форме.

class ArticleController
{
public function editAction()
{
$builder = new AnnotationBuilder();
$form = $builder->createForm(new TblArticle());

// add tag options to form
$sm = $this->getServiceLocator();
$em = $sm->get('Doctrine\ORM\EntityManager');
$tags = $em->getRepository('Admin\Entity\LuTag')->findAll();
$tagOptions = [null => ''];
foreach ($tags as $tag) {
$tagOptions[$tag->getTagId()] = $tag->getName();
}
$form->get('tags')->setValueOptions($tagOptions);
// end add tag options to form


$id = 1;
$article = $em->find('Admin\Entity\TblArticle', $id);
$form->bind($article);

if ($article->getTags()) {
$tagIds = array();
foreach ($article->getTags() as $tag) {
$tagIds[] = $tag->getTagId();
}
$form->get('tags')->setValue($tagIds);
}
}
}

Это кажется чрезмерным количеством кода в моем контроллере, я знаю, что это неправильно, но я не уверен, как лучше это сделать. Возможно, с помощью FormBuilder, который устанавливает параметры значения для элементов тега?

Благодарю.

13

Решение

Проверьте этот учебник: https://samsonasik.wordpress.com/2014/05/22/zend-framework-2-using-doctrinemoduleformelementobjectselect-and-custom-repository/

По сути, вам нужно указать класс репозитория в вашей аннотации Entity Tag-Entities следующим образом:

@ORM\Entity(repositoryClass="Admin\Entity\LuTag")

Затем вы можете использовать Doctrines DoctrineModule \ Form \ Element \ ObjectSelect Type, который сможет предоставить запрошенную вами функцию:

article.php (Обратите внимание на @Form \ Type Annotation и дополнительные записи @Form \ Options)

...
/**
*
* @var \Doctrine\Common\Collections\Collection|Tag[]
*
* @ORM\ManyToMany(targetEntity="Tag", inversedBy="articles")
* @Orm\JoinTable(name="rel_article_tag", joinColumns={@ORM\JoinColumn(name="article_id", referencedColumnName="article_id")}, inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="tag_id")})
*
* @Form\Required(false)
* @Form\Type("DoctrineModule\Form\Element\ObjectSelect")*
* @Form\Options({"label":"Tags: ", "target_class": "Admin\Entity\LuTag", "property": "name"})
* @Form\Attributes({"id":"tags", "data-placeholder":"Choose tags...", "multiple" : "multiple", "class" : "chosen-select"})
*/
private $tags;

Также проверьте https://github.com/doctrine/DoctrineModule/blob/master/docs/form-element.md
для получения дополнительной информации о ObjectSelect

Наконец вам нужно будет построить форму, используя

DoctrineORMModule\Form\Annotation\AnnotationBuilder

вместо Zends AnnotationBuilder для разрешения зависимостей object_manager.

/* using the service manager like this within a controller method is
bad practice. Inject the EntityManager using a Controller Factory! */
$sm = $this->getServiceLocator();
$em = $sm->get('Doctrine\ORM\EntityManager');

$builder = new DoctrineORMModule\Form\Annotation\AnnotationBuilder($em);
$form = $builder->createForm(TblArticle::class);

Это должно сделать свое дело.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]