首页 > 解决方案 > Symfony 表单元素 ID

问题描述

我继承了一些使用 Symfony (v3.3) 生成表单的代码。正在创建的一些元素在元素类型和自动生成的 ID 之间没有空格。这意味着该元素不显示:

<selectid="someID">
...
</selectid="someID">

这发生在 select 元素和 textarea 元素上。

我不熟悉 Symfony,所以不知道如何解决这个问题......非常感谢任何帮助!

编辑:按要求添加代码。问题是我不知道问题出在哪里,而且课程很多。

树枝模板

<form action="" method="post" name="callback" id="request-callback" class="contact-form">
    <input type="hidden" name="form-type" value="callback">
    {#<input type="hidden" name="mc4wp-subscribe" value="1">#}
    <div{% if form.name.vars.errors | length > 0 %} class="form-error"{% endif %}>
        {{ form_label(form.name) }} {{ form_errors(form.name) }}
        {{ form_widget(form.name) }}
    </div>
    <div{% if form.phone_number.vars.errors | length > 0 %} class="form-error"{% endif %}>
        {{ form_label(form.phone_number) }} {{ form_errors(form.phone_number) }}
        {{ form_widget(form.phone_number) }}
    </div>
    <div{% if form.email.vars.errors | length > 0 %} class="form-error"{% endif %}>
        {{ form_label(form.email) }} {{ form_errors(form.email) }}
        {{ form_widget(form.email) }}
    </div>
    <div{% if form.treatment.vars.errors | length > 0 %} class="form-error"{% endif %}>
        {{ form_label(form.treatment) }} {{ form_errors(form.treatment) }}
        {{ form_widget(form.treatment) }}
    </div>
    <div class="text-center">
        <button class="button bg-darkblue" type="submit" id="contact_send" name="contact[send]">Send My Request</button>
    </div>
</form>

表单类

<?php

namespace REDACTED;

use DrewM\MailChimp\MailChimp;
use GuzzleHttp\Exception\ConnectException;
use Symfony\Component\Form\Forms;
use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationExtension;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Translation\Translator;
use Symfony\Bridge\Twig\Extension\FormExtension;
use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Bridge\Twig\Form\TwigRendererEngine;
use Symfony\Bridge\Twig\Form\TwigRenderer;
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
use Symfony\Component\Validator\Validation;
use GuzzleHttp\Client;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormFactoryInterface;

abstract class Form
{
    /**
     * Recaptcha endpoint
     */
    const RECAPTCHA_VERIFY = 'https://www.google.com/recaptcha/api/siteverify';

    /**
     * Default from name
     */
    const EMAIL_FROMNAME = '';

    /**
     * @var \Twig_Environment
     */
    protected $twig;

    /**
     * @var \Symfony\Component\Form\FormInterface
     */
    protected $form;

    /**
     * @var \Symfony\Component\HttpFoundation\Request
     */
    private $request;

    /**
     * Capture failed
     *
     * @var bool
     */
    protected $captchaFailed = false;

    /**
     * @var string
     */
    protected $template;

    /**
     * @var string
     */
    protected $messageTemplate;

    /**
     * @var string
     */
    protected $subject;

    /**
     * @var string
     */
    protected $emailTo;

    /**
     * @var string
     */
    protected $emailFromName;

    /**
     * @var array
     */
    protected $params = [];

    protected $mailchimpList;

    private $mailchimpApiKey = '6542760048f1c73d69df8f552d4a2b87-us18';

    public $mailerError;

    public $redirectTo;

    /**
     * SunstoneForm constructor
     *
     * @param Request $request
     * @param $emailTo
     * @param $emailFromName
     * @param array $params
     */
    private function __construct(
        Request $request = null,
        $emailTo = null,
        $emailFromName = null,
        array $params = []
    ) {
        $this->request = $request;
        $this->emailTo = $emailTo;
        $this->emailFromName = $emailFromName;
        $this->params = $params;
    }

    /**
     * Make the contact form
     *
     * @param Request $request
     * @param string $emailTo
     * @param string $emailFromName
     * @param array $params
     * @return static
     */
    public static function make(
        Request $request = null,
        $emailTo = null,
        $emailFromName = self::EMAIL_FROMNAME,
        array $params = []
    ) {
        return (new static($request, $emailTo, $emailFromName, $params))
            ->twig()
            ->form();
    }

    /**
     * Render the form
     *
     * @return string
     */
    public function renderForm()
    {
        return $this->twig->render($this->template, [
            'form' => $this->form->createView(),
            'captchaFailed' => $this->captchaFailed,
        ]);
    }

    /**
     * Handle a form submission and check form is valid
     *
     * @return bool
     */
    public function handleRequest()
    {
        $this->form->handleRequest($this->request);
        if ($this->form->isSubmitted() && $this->form->isValid()) {
            // send the message
            return $this->process();
        }

        return false;
    }

    /**
     * Instantiate Twig
     *
     * @return $this
     */
    protected function twig()
    {
        // instantiate twig
        $translator = new Translator('en');
        $loader = new \Twig_Loader_Filesystem([
            TWIG_TEMPLATE_DIR,
            ABSPATH.'vendor/symfony/twig-bridge/Resources/views/Form',
        ]);
        $twig = new \Twig_Environment($loader, [
            'debug' => WP_DEBUG,
        ]);
        $twig->addExtension(new FormExtension());
        $twig->addExtension(new TranslationExtension($translator));
        if (WP_DEBUG) {
            $twig->addExtension(new \Twig_Extension_Debug);
        }

        // get form engine
        $formEngine = new TwigRendererEngine(['form_div_layout.html.twig'], $twig);
        $twig->addRuntimeLoader(new \Twig_FactoryRuntimeLoader([
            TwigRenderer::class => function() use ($formEngine) {
                return new TwigRenderer($formEngine);
            },
        ]));

        $this->twig = $twig;

        return $this;
    }

    public function getForm()
    {
        return $this->form;
    }

    public function getSubmissionComplete()
    {
        return sprintf('<div class="form-sent">%s</div>',
            get_field('form_submitted_content', 'options')
        );
    }

    /**
     * Generate the form
     *
     * @return $this
     */
    protected function form()
    {
        $this->form = $this->formFields(
            Forms::createFormFactoryBuilder()
                ->addExtension(new HttpFoundationExtension)
                ->addExtension(new ValidatorExtension(Validation::createValidator()))
                ->getFormFactory()
            )
            ->getForm();

        return $this;
    }

    /**
     * @param array $additionalData
     * @return bool
     */
    protected function process(array $additionalData = [])
    {
        $data = $this->form->getData();

        $mailer = new \PHPMailer(true);
        $mailer->addAddress($this->emailTo);
        if (WP_DEBUG && defined('DEBUG_BCC')) {
            $mailer->addBCC(DEBUG_BCC);
        }
        $mailer->From = $this->emailTo;
        $mailer->FromName = 'drpuneetgupta.co.uk';
        $mailer->Subject = $this->subject;
        $mailer->Body = $this->twig->render($this->messageTemplate, [
            'data' => $data + $additionalData,
        ]);
        $mailer->isHTML(true);
        
        if ($this->mailchimpList) {
            try {
                $mailchimp = new MailChimp($this->mailchimpApiKey);
                $mailchimp->post("lists/{$this->mailchimpList}/members", [
                    'email_address' => $data['email'],
                    'status' => 'subscribed',
                ]);
            } catch (\Exception $e) {}
        }

        try {
            return $mailer->send();
        } catch (\phpmailerException $e) {
            $this->mailerError = $e->getMessage();
        }
        return false;
    }

    /**
     * Define form fields
     *
     * @param FormFactoryInterface $formFactory
     * @return mixed
     */
    abstract protected function formFields(FormFactoryInterface $formFactory);
}

RequestCallback 扩展 Form 类

<?php

namespace REDACTED;

use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Email;
use DrewM\MailChimp\MailChimp;

class RequestCallback extends Form
{
    protected $template = 'request-callback.twig';

    protected $messageTemplate = 'email-callback.twig';

    protected $mailchimpList = 'REDACTED';

    protected $subject = 'Callback request';

    /**
     * @param FormFactoryInterface $formFactory
     * @return FormBuilderInterface
     */
    protected function formFields(FormFactoryInterface $formFactory)
    {
        return $formFactory->createNamedBuilder('request_callback', FormType::class, null, [
                'allow_extra_fields' => true,
            ])
            ->add('mc4wp-subscribe', HiddenType::class, [
                'data' => 1,
            ])
            ->add('name', TextType::class, [
                'required' => true,
                'label' => 'Your Name',
                'attr' => [
                    'placeholder' => 'Your Name',
                ],
                'label_attr' => [
                    'class' => 'sr-only',
                ],
                'constraints' => [
                    new NotBlank(['message' => 'Please enter your name']),
                ],
            ])
            ->add('phone_number', TextType::class, [
                'required' => true,
                'label' => 'Phone Number',
                'attr' => [
                    'placeholder' => 'Phone Number',
                ],
                'label_attr' => [
                    'class' => 'sr-only',
                ],
                'constraints' => [
                    new NotBlank(['message' => 'Please enter your phone number']),
                ],
            ])
            ->add('email', EmailType::class, [
                'required' => true,
                'label' => 'Your email address',
                'attr' => [
                    'placeholder' => 'Email address',
                ],
                'label_attr' => [
                    'class' => 'sr-only',
                ],
                'constraints' => [
                    new NotBlank(['message' => 'Please enter your email address']),
                    new Email(['message' => 'Please enter a valid email address']),
                ],
            ])
            ->add('treatment', ChoiceType::class, [
                'required' => true,
                'label' => 'Which treatment would you like to discuss?',
                'label_attr' => [
                    'class' => 'sr-only',
                ],
                'constraints' => [
                    new NotBlank(['message' => 'Please select a treatment']),
                ],
                'choices' => [
                    'Which treatment would you like to discuss?' => '',
                    'Liposuction' => 'Liposuction',
                    'Lipoedema' => 'Lipoedema',
                    'Breast reduction' => 'Breast reduction',
                    'Male chest reduction' => 'Male chest reduction',
                ],
            ]);
    }
}

标签: symfonytwig

解决方案


我想我会为此创建一个答案,因为在评论中找到正确的答案并不简单。

正如@DarkBee 在其中一个问题评论中提到的那样,对问题PHP 7.4 trimming whitespace between string variables的修复解决了这个问题。

Twig 中有一个修复程序可以防止空白被修剪,因此更新到最近的 Twig 版本可以解决该问题: composer require "twig/twig:^2.0"


推荐阅读