Я разрабатываю проект с ZF2 и Doctrine. Я пытаюсь использовать Doctrine Hydrator в создании формы, как показано в этот учебник. В этом методе объект ObjectManager создается в контроллере и передается в новую форму при его создании. Передача объекта ObjectManager из контроллера в форму создает проблему, когда я хочу использовать ZF2 FormElementManager, потому что ZF2 требует, чтобы я получил экземпляр класса формы через Zend\Form\FormElementManager вместо прямого его создания. Чтобы обойти это требование, я создал фабрики форм и полей на основе ответа на вопрос Как передать ObjectManager Doctrine в форму через ZF2 FormElementManager. Метод, представленный в ответе на вопрос, работает для типичных элементов fieldset, но мне нужно определить, как включить элемент коллекции. Учебник использует объект ObjectManager в элементе коллекции в родительском наборе полей, и мне нужно выяснить, как добавить коллекцию с помощью factory.
TagFieldset из учебника, которое я пытаюсь подражать:
namespace Application\Form;
use Application\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
)
);
}
}
новый TagFieldsetFactory:
namespace Application\Form;
use Zend\Form\Fieldset;
use Application\Entity\Tag;
class TagFieldsetFactory
{
public function __invoke($formElementManager, $name, $requestedName)
{
$serviceManager = $formElementManager->getServiceLocator();
$hydrator = $serviceManager->get('HydratorManager')->get('DoctrineEntityHydrator');
$fieldset = new Fieldset('tags');
$fieldset->setHydrator($hydrator);
$fieldset->setObject(new Tag);
//... add fieldset elements.
$fieldset->add(['...']);
//...
return $fieldset;
}
}
BlogPostFieldset из учебника, которое я пытаюсь подражать:
namespace Application\Form;
use Application\Entity\BlogPost;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
class BlogPostFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct(ObjectManager $objectManager)
{
parent::__construct('blog-post');
$this->setHydrator(new DoctrineHydrator($objectManager))
->setObject(new BlogPost());
$this->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'title'
));
$tagFieldset = 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(
'title' => array(
'required' => true
),
);
}
}
новый BlogPostFieldsetFactory:
namespace Application\Form;
use Zend\Form\Fieldset;
use Application\Entity\BlogPost;
class BlogPostFieldsetFactory
{
public function __invoke($formElementManager, $name, $requestedName)
{
$serviceManager = $formElementManager->getServiceLocator();
$hydrator = $serviceManager->get('HydratorManager')->get('DoctrineEntityHydrator');
$fieldset = new Fieldset('blog_post');
$fieldset->setHydrator($hydrator);
$fieldset->setObject(new BlogPost);
//... add fieldset elements.
$fieldset->add(['...']);
//...
return $fieldset;
}
}
в module.config.php:
'form_elements' => [
'factories' => [
'UpdateBlogPostForm' => 'Application\Form\UpdateBlogPostFormFactory',
'BlogPostFieldset' => 'Application\Form\BlogPostFieldsetFactory',
'TagFieldset' => 'Application\Form\TagFieldsetFactory',
],
],
Когда я добавляю элементы набора полей В моем новом BlogPostFieldsetFactory я заменяю этот код из исходного набора полей:
$this->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'title'
));
с этим:
$fieldset->add(array(
'type' => 'Zend\Form\Element\Text',
'name' => 'title'
));
Как заменить элемент коллекции из исходного набора полей:
$tagFieldset = new TagFieldset($objectManager);
$this->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'tags',
'options' => array(
'count' => 2,
'target_element' => $tagFieldset
)
));