首页 > 解决方案 > 如何在提交时将表单数据传递给事件订阅者

问题描述

我需要为 MetaSubscribergetUrl回调获取所选品牌。/brand-model该函数根据传递给函数的品牌和baseFieldName在元订阅者中选择的品牌(在本例中为模型)生成一个 URL 。

null目前,这为我提供了关于更新和创建新条目的先前品牌。

我的问题

有什么方法可以将提交的品牌传递给getUrl函数以生成我的 URL?

我的代码

这是我的 Formbuilder 中的 MetaSubscriber,它调用该getUrl函数为添加的条目生成 URL。

$builder->addEventSubscriber(
            new AddMetaSubscriber(
                'Glasses',
                'GlassesDetail',
                GlassesRepository::class,
                'getUrl',
                [
                    'getData.getId',
                    'getData.getBrand' //Need to get the submitted brand here

                    //I've tried with `brand` like it works for the model but I get an "Undefined method" error

                ],
                'model'
            )
        );

它从以下函数获取 URL:

public function getUrl(string $url, int $id = null, string $brand = null): string
    {
        $query = $this
            ->createQueryBuilder('i')
            ->select('COUNT(i)')
            ->innerJoin('i.meta', 'm')
            ->where('m.url = :url')
            ->setParameter('url', $url);

        if ($id !== null) {
            $query
                ->andWhere('i.id != :id')
                ->setParameter('id', $id);
        }
        $url = strtolower($brand)."-".$url;

        if ((int)$query->getQuery()->getSingleScalarResult() === 0) {
            return $url;
        }

        return $this->getUrl(Model::addNumber($url), $id, $brand);
    }

AddMetaSubscriber 类

<?php

namespace Backend\Form\EventListener;

use Backend\Core\Engine\Model;
use Backend\Form\Type\MetaType;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Use this class to add meta url generating to your symfony form.
 *
 * Example: $builder->addEventSubscriber(new AddMetaSubscriber(...));
 */
class AddMetaSubscriber implements EventSubscriberInterface
{
    /**
     * @var string - The URL shown in the backend will need this "action" to be generated.
     */
    private $actionForUrl;

    /**
     * @var string - The field in the form where the URL should be generated for.
     */
    private $baseFieldName;

    /**
     * @var string - Name of the class or the container service id, f.e.: 'moduleForUrl.repository.item',
     */
    private $generateUrlCallbackClass;

    /**
     * @var string - Name of the public method which returns you the URL, f.e.: "getUrl"
     */
    private $generateUrlCallbackMethod;

    /**
     * @var array - Extra parameters you want to include in the AJAX call to get the URL, f.e.: ["getData.getLocale", "getForm.getParent.getParent.getData.getMenuEntityId"]
     */
    private $generateUrlCallbackParameterMethods;

    /**
     * @var string - The URL shown in the backend will need this "module" to be generated.
     */
    private $moduleForUrl;

    public function __construct(
        string $moduleForUrl,
        string $actionForUrl,
        string $generateUrlCallbackClass,
        string $generateUrlCallbackMethod,
        array $generateUrlCallbackParameterMethods,
        string $baseFieldName = 'title'
    ) {
        $this->moduleForUrl = $moduleForUrl;
        $this->actionForUrl = $actionForUrl;
        $this->generateUrlCallbackClass = $generateUrlCallbackClass;
        $this->generateUrlCallbackMethod = $generateUrlCallbackMethod;
        $this->generateUrlCallbackParameterMethods = $generateUrlCallbackParameterMethods;
        $this->baseFieldName = $baseFieldName;
    }

    public static function getSubscribedEvents(): array
    {
        // Tells the dispatcher that you want to listen on the form.pre_set_data
        // event and that the preSetData method should be called.
        return array(FormEvents::PRE_SET_DATA => 'preSetData');
    }

    public function preSetData(FormEvent $event)
    {
        $event->getForm()->add(
            'meta',
            MetaType::class,
            [
                'base_field_name' => $this->baseFieldName,
                'detail_url' => Model::getUrlForBlock($this->moduleForUrl, $this->actionForUrl),
                'generate_url_callback_class' => $this->generateUrlCallbackClass,
                'generate_url_callback_method' => $this->generateUrlCallbackMethod,
                'generate_url_callback_parameters' => $this->buildCallbackParameters($event),
            ]
        );
    }

    private function buildCallbackParameters(FormEvent $event): array
    {
        $parameters = [];

        foreach ($this->generateUrlCallbackParameterMethods as $generateUrlCallbackParameterMethod) {
            $parameter = $event;
            $methods = explode('.', $generateUrlCallbackParameterMethod);

            foreach ($methods as $method) {
                $parameter = $parameter->{$method}();
            }

            $parameters[] = $parameter;
        }

        return $parameters;
    }
}

标签: phpsymfonydoctrine

解决方案


推荐阅读