Вероятно, вам нужно расширение типа формы, оно позволит вам изменить любой существующие типы форм во всей системе. Там вы можете добавить слушателей событий/подписчиков или то, что вы хотите, к любому конкретному или общему типу формы.
Однако эта задача может стать утомительной, если это очень частый случай. Таким образом, выполнение чего-то подобного может обеспечить вам идеальную посадку:
class FoobarFormSubscriber implements EventSubscriberInterface, FormEventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(FormEvents::PRE_SET_DATA => 'preSetData');
}
public static function getFormClass()
{
return FoobarType::class;
}
public function preSetData(FormEvent $event)
{
$form = $event->getForm();
$form->add('custom', null, array('mapped' => false));
}
}
Но очевидно, что это не функция, реализованная Symfony. Здесь я оставляю вам рецепт, чтобы достичь этого:
Во-первых, создайте новое расширение типа формы для добавления подписчика в конструктор форм в соответствии с конфигурацией:
class FormEventTypeExtension extends AbstractTypeExtension
{
private $subscribers;
public function __construct(array $subscribers = array())
{
$this->subscribers = $subscribers;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$formClass = get_class($builder->getType()->getInnerType());
if (isset($this->subscribers[$formClass])) {
foreach ($this->subscribers[$formClass] as $subscriber) {
$builder->addEventSubscriber($subscriber);
}
}
}
public function getExtendedType()
{
return FormType::class;
}
}
Создайте новый интерфейс, чтобы настроить класс формы для прослушивания:
interface FormEventSubscriberInterface
{
public static function getFormClass();
}
Наконец, в новый проход компилятора вводит в службу расширения все зарегистрированные kernel.event_subscriber
которые реализуют предыдущий интерфейс:
public function process(ContainerBuilder $container)
{
$subscribers = array();
foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $serviceId => $tags) {
$subscriberClass = $container->getDefinition($serviceId)->getClass();
if (is_subclass_of($subscriberClass, FormEventSubscriberInterface::class, true)) {
$subscribers[$subscriberClass::getFormClass()][] = new Reference($serviceId);
}
}
$extensionDef = $container->getDefinition(FormEventTypeExtension::class);
$extensionDef->setArgument(0, $subscribers);
}
Затем ваши пользовательские подписчики отделены и готовы к работе как есть, просто убедитесь, что реализованы оба интерфейса (EventSubscriberInterface, FormEventSubscriberInterface
) и зарегистрирован подписчик событий как служба.
person
yceruto
schedule
08.01.2018