2016-09-15 15 views
1

Я ищу способ расширить Symfony 2 EntityTypeПродлить Doctrine2 формы EntityType

Symfony\Bridge\Doctrine\Form\Type\EntityType 

как в новом типе расширения этот, не создавая FormTypeExtension - и я не могу понять это. Кто-нибудь знает какой-либо правильный способ сделать это?

Я пытался просто расширяя его таким образом:

class NestedEntityType extends EntityType { 

    public function getName() { 
     return $this->getBlockPrefix(); 
    } 

    public function getBlockPrefix() { 
     return 'nested_entity'; 
    } 
} 

, а затем в сонатной классе админ у меня есть:

protected function configureFormFields(FormMapper $formMapper) 
{ 
    $formMapper->add('types', NestedEntityType::class, [ 
     'label' => false, 
     'multiple' => true, 
     'expanded' => true, 
     'by_reference' => false 
    ]); 
} 

, но, к сожалению, это приводит к фатальной ошибке:

Catchable Fatal Error: Argument 1 passed to Symfony\Bridge\Doctrine\Form\Type\DoctrineType::__construct() must implement interface Doctrine\Common\Persistence\ManagerRegistry, none given, called in

Мне нужно сохранить всю функциональность EntityType, за одним исключением - способом, которым он является подарил. Вот почему мне нужно расширить этот тип (я использую его в других полях, поэтому я не могу просто изменить шаблон для него!).

Я использую Symfony 2.8 (только для справки).

ответ

1

Итак, если вам нужно создать многоразовое решение для разных объектов, в этом случае вам не потребуется configureOptions.

Вы должны создать ElementType в вас код как

$this->createForm(NestedEntityType::class, null, ['class' => YourEntity::class]);

И в этом случае вам нужно будет пройти как вариант имени класса Entity, который вложен.

+0

Ни в коем случае Sonata/Symfony не может сделать это автоматически, как это делается для EntityType? Ну, я думаю, что смогу жить с этим, если нет другого пути :) – user1970395

+0

Я думаю, что это возможно. Это Symfony в конце концов. Но вам нужно глубоко вникать в код и сначала понять, как он работает с EntityType –

+0

Вот что я предположил, ну, на данный момент я могу жить с опцией 'class'. Спасибо за Вашу поддержку! – user1970395

1

Если бы в EntityType, вы увидите, что это расширение DoctrineType и нуждается в зависимости в конструкторе -

public function __construct(ManagerRegistry $registry, PropertyAccessorInterface $propertyAccessor = null) 
{ 
    $this->registry = $registry; 
    $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor(); 
} 

Итак, ваш класс NestedEntityType использует тот же конструктор и нуждается в те же зависимости.

На самом деле, то, что вам нужно, это

class NestedEntityType extends AbstractType { 

    public function getParent() { 
     return EntityType::class; 
    } 

    public function getName() { 
     return $this->getBlockPrefix(); 
    } 

    public function getBlockPrefix() { 
     return 'nested_entity'; 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults([ 
      'class' => YourEntity::class 
     ]); 
    } 
} 

UPD: Конечно, вам нужно настроить параметры, в соответствии с EntityType doc. См. Метод, который я добавил в код.

+0

У вас есть опечатка в 'AbstractType'! Также спасибо, это меня толкает вперед, к сожалению, я сейчас получаю: 'Отсутствует обязательный параметр класса.', поэтому это не расширение 1: 1 EntityType, потому что мне все еще нужен какой-то дополнительный материал, чтобы он работал;> Я принял подход передачи аргументов конструктору, но, к сожалению, я не могу найти какие-либо соответствующие службы для передачи в качестве аргументов , любой шанс, что вы знаете, что я должен включить в определение службы, чтобы он работал? – user1970395

+0

Конечно, вам нужна опция 'class'. См. Обновленный ответ. –

+0

Ah, right:> И я считаю, что это автоматически передается Sonata EntityType? – user1970395

5

Вы не должны расширить его напрямую, но использовать parent вариант

/** 
* {@inheritdoc} 
*/ 
public function getParent() 
{ 
    return EntityType::class; 
} 

Так что-то вроде

class NestedEntityType extends AbstractType 
{ 

    public function getName() 
    { 
     return $this->getBlockPrefix(); 
    } 

    public function getBlockPrefix() 
    { 
     return 'nested_entity'; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function getParent() 
    { 
     return EntityType::class; 
    } 
} 

Таким образом, если вы FormType простирающийся от есть что-то в впрыскивается (или выставиться) в конструктор , вам не нужно заботиться о том, как symfony сделает это за вас.

+0

'Необходимый параметр" class "отсутствует. '- Я могу только предположить, что это имеет какое-то отношение к Sonata, а не к Symfony2? – user1970395

+1

@ user1970395 это как-то связано с формой, в которой вы используете 'NestedEntityType'. Разрешение: вам необходимо передать в качестве опции класс объекта, в котором вы используете этот тип формы. – DonCallisto

+0

Благодарим за помощь! Я хотел бы отметить оба ответа, как принято, но Дмитрий более глубоко затрагивает вопрос, поэтому я буду отмечать его ответ! :) Надеюсь, ты не против. – user1970395