Я использую формы Symfony (v3.0) без остальной структуры Symfony. Использование Doctrine v2.5.
Я создал форму, вот класс типа формы:
class CreateMyEntityForm extends BaseFormType { public function buildForm(FormBuilderInterface $builder, array $options){ $builder->add('myEntity', EntityType::class); } }
При загрузке страницы появляется следующая ошибка.
Аргумент 1 передан в Symfony \ Bridge \ Doctrine \ Form \ Type \ DoctrineType :: __ construct () должен быть экземпляром Doctrine \ Common \ Persistence \ ManagerRegistry, не указанным, вызываемым в / var / www / dev3 / Vendor / symfony / form /FormRegistry.php в строке 85
Я считаю, что есть некоторая конфигурация, которая нуждается в создании здесь, но я не знаю, как создать класс, который реализует ManagerRegistryInterface – если это правильно.
Любые указатели?
Изменить – вот мой код для создания Доктрины
use Doctrine\ORM\EntityManager; use Doctrine\ORM\Tools\Setup; class Bootstrap { //...some other methods, including getCredentials() which returns DB credentials for Doctrine public function getEntityManager($env){ $isDevMode = $env == 'dev'; $paths = [ROOT_DIR . '/src']; $config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode, null, null, false); $dbParams = $this->getCredentials($env); $em = EntityManager::create($dbParams, $config); return $em; } }
Поверь мне, ты просишь неприятностей!
EntityType::class
работает, когда он интегрирован в рамки Symfony (есть волшебство под капюшонами – через DoctrineBundle). В противном случае вам нужно написать много кода для правильной работы.
Не стоит усилий!
ChoiceType::class
проще создать репозиторий объектов и ввести его в конструктор форм, а затем использовать в поле ChoiceType::class
. Что-то вроде:
<?php # you form class namespace Application\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class InvoiceItemtType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('product', ChoiceType::class, [ 'choices' => $this->loadProducts($options['products']) ]); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(['products' => [],]); # custom form option } private function loadProducts($productsCollection) { # custom logic here (if any) } }
И где-то в приложении:
$repo = $entityManager->getRepository(Product::class); $formOptions = ['products' => $repo->findAll()]; $formFactory = Forms::createFormFactory(); $formFactory->create(InvoiceItemtType::class, new InvoiceItem, $formOptions);
В этом-то и дело!
Расширение ответа на вопрос хаббух.
Я смог реализовать EntityType
в FormBuilder
без лишней дополнительной работы. Однако он не работает с аннотациями, чтобы использовать Constraints
непосредственно внутри объекта, что потребовало бы гораздо большей работы.
Вы можете легко облегчить требование ManagerRegistry
расширения Doctrine ORM Forms Extension, расширив существующий AbstractManagerRegistry
и создав собственное свойство контейнера в настраиваемом ManagerRegistry
.
Тогда это просто вопрос регистрации расширения формы, как и любое другое расширение ( ValidatorExtension
, HttpFoundationExtension
и т. Д.).
МенеджерRegistry
use \Doctrine\Common\Persistence\AbstractManagerRegistry; class ManagerRegistry extends AbstractManagerRegistry { /** * @var array */ protected $container = []; public function __construct($name, array $connections, array $managers, $defaultConnection, $defaultManager, $proxyInterfaceName) { $this->container = $managers; parent::__construct($name, $connections, array_keys($managers), $defaultConnection, $defaultManager, $proxyInterfaceName); } protected function getService($name) { return $this->container[$name]; //alternatively supply the entity manager here instead } protected function resetService($name) { //unset($this->container[$name]); return; //don't want to lose the manager } public function getAliasNamespace($alias) { throw new \BadMethodCallException('Namespace aliases not supported'); } } $managerRegistry = new \ManagerRegistry('default', [], ['default' => $entityManager], null, 'default', 'Doctrine\\ORM\\Proxy\\Proxy');
сuse \Doctrine\Common\Persistence\AbstractManagerRegistry; class ManagerRegistry extends AbstractManagerRegistry { /** * @var array */ protected $container = []; public function __construct($name, array $connections, array $managers, $defaultConnection, $defaultManager, $proxyInterfaceName) { $this->container = $managers; parent::__construct($name, $connections, array_keys($managers), $defaultConnection, $defaultManager, $proxyInterfaceName); } protected function getService($name) { return $this->container[$name]; //alternatively supply the entity manager here instead } protected function resetService($name) { //unset($this->container[$name]); return; //don't want to lose the manager } public function getAliasNamespace($alias) { throw new \BadMethodCallException('Namespace aliases not supported'); } } $managerRegistry = new \ManagerRegistry('default', [], ['default' => $entityManager], null, 'default', 'Doctrine\\ORM\\Proxy\\Proxy');
Настройте формы для использования расширения
$extension = new \Symfony\Bridge\Doctrine\Form\DoctrineOrmExtension($managerRegistry); $formBuilder = \Symfony\Component\Form\FormFactoryBuilder::createFormFactoryBuilder(); $formBuilder->addExtension($extension); $formFactory = $formBuilder->getFormFactory();
Создать форму
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class UserType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('field_name', EntityType::class, [ 'class' => YourEntity::class, 'choice_label' => 'id' ]); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(['data_class' => YourAssociatedEntity::class]); } } $form = $formFactory->create(new \UserType, $data, $options);
Самый простой способ решить вашу проблему – зарегистрировать DoctrineOrmExtension с моста Doctrine, который гарантирует, что тип сущности зарегистрирован с необходимыми зависимостями.
Таким образом, процесс начальной загрузки компонента Form будет выглядеть следующим образом:
// a Doctrine ManagerRegistry instance (you will probably already build this somewhere else) $managerRegistry = ...; $doctrineOrmExtension = new DoctrineOrmExtension($managerRegistry); // the list of form extensions $extensions = array(); // register other extensions // ... // add the DoctrineOrmExtension $extensions[] = $doctrineOrmExtension; // a ResolvedFormTypeFactoryInterface instance $resolvedTypeFactory = ...; $formRegistry = new FormRegistry($extensions, $resolvedTypeFactory);