首页 文章

Symfony FosUserBundle和HTMLPurifierBundle

提问于
浏览
0

在我个人的Symfony3.2项目中,我想在我的UserProfile表单中使用HtmlPurifier来防止XSS攻击 .

因此如下所述:https://github.com/Exercise/HTMLPurifierBundle我按照以下方式修改了 UserProfileFormType

namespace AppUserBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;

class UserProfileFormType extends AbstractType
{
    private $purifierTransformer;

    public function __construct(DataTransformerInterface $purifierTransformer)
    {
        $this->purifierTransformer = $purifierTransformer;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);        

        $builder->addViewTransformer($this->purifierTransformer);
        $builder->add('name',TextType::class,array('label'=>'profile.first_name','required' => false));
        $builder->add('surname',TextType::class,array('label'=>'profile.surnname','required' => false));
        $builder->remove('username');
        $builder->add('username',TextType::class,['required' => false]);
        $builder->add('email',TextType::class,['required' => false]);
        $builder->add('description',TextareaType::class,['required' => false]);
        $builder->remove('current_password');
    }

    public function getParent()
    {
        return 'FOS\UserBundle\Form\Type\ProfileFormType';
    }

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

    // For Symfony 2.x
    public function getName()
    {
        return $this->getBlockPrefix();
    }
}

并且还在 services.yml 条目中使用了这些条目:

services:
  app_user.html_purifier:
    class: Exercise\HTMLPurifierBundle\Form\HTMLPurifierTransformer
    arguments: ["@exercise_html_purifier.default"]

  app_user.user_profile_form:
    class: AppUserBundle\Form\Type\UserProfileFormType
    arguments: ["@app_user.html_purifier"]
    tags:
      - { name: form.type, alias: app_user_profile }

我也将这些条目放在 config.yml 中:

fos_user:
  db_driver: orm # other valid values are 'mongodb' and 'couchdb'
  firewall_name: main
  user_class: '%user_class%'
  from_email:
    address: "somemail@example.com"
    sender_name: "App Mailer"
  registration:
    confirmation:
      enabled: false
  profile:
    form:
      type: AppUserBundle\Form\Type\UserProfileFormType

exercise_html_purifier:
  default:
    Cache.SerializerPath: '%kernel.cache_dir%/htmlpurifier'

使用这些选项,我收到以下错误消息:

类型错误:传递给AppUserBundle的参数1 \ Form \ Type \ UserProfileFormType :: __ construct()必须是Symfony \ Component \ Form \ DataTransformerInterface的实例,没有给出,在/ home / pcmagas / Kwdikas / php / apps / symfonyAdminLTE中调用第85行/vendor/symfony/symfony/src/Symfony/Component/Form/FormRegistry.php

我还尝试在_2385782中更改以下值:

fos_user:
   #Some configuration
  profile:
    form:
      type: AppUserBundle\Form\Type\UserProfileFormType

有了这个:

fos_user #Some配置文件:form:type:app_user.user_profile_form

这会返回以下错误:

无法加载类型“app_user.user_profile_form”

你知道我将如何解决这个问题吗?只要我了解问题就是FosUserBundle无法以某种方式加载正确的服务 . 您是否知道如何将相应的服务加载到配置中?

编辑1:

UserProfileFormType 方法我替换了:

$builder->add('description',TextareaType::class,['required' => false]);

附:

$builder->add('description',PurifiedTextAreaType::class,['required' => false]);

我收到以下错误:

类型错误:参数1传递给AppUserBundle \ Form \ Type \ PurifiedTextAreaType :: __ construct()必须实现接口Symfony \ Component \ Form \ DataTransformerInterface,没有给出,在/ home / pcmagas / Kwdikas / php / apps / symfonyAdminLTE / var中调用第389行的/cache/dev/appDevDebugProjectContainer.php

请记住,我创建了 AppUserBundle/Form/Type/PurifiedTextAreaType.php

namespace AppUserBundle\Form\Type;


use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class PurifiedTextAreaType extends AbstractType
{
    private $purifierTransformer;

    public function __construct(DataTransformerInterface $purifierTransformer)
    {
        $this->purifierTransformer = $purifierTransformer;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->addViewTransformer($this->purifierTransformer);
    }

    public function getParent()
    {
        return 'textarea';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
                'compound' => false,
        ));
    }

    public function getName()
    {
        return 'purified_textarea';
    }
}

我也忘了提到我使用不同的bundle来进行任何类型的用户管理和处理命名 AppUserBudnle 所有自定义表单都在这个包中 .

2 回答

  • 0

    我认为,使用此扩展的最佳方式是如教程中所述,使用单个Textarea,您可以在最终形式中将其作为自己的TextAreaType调用:

    我在你的描述中看到了这个错误,有命名空间但缺少“UserProfileFormType”类名 .

    services:
      app_user.user_profile_form:
        class: AppUserBundle\Form\Type
        arguments: ["@app_user.html_purifier"]
        tags:
          - { name: form.type, alias: app_user_profile }
    

    在这种配置中

    fos_user:
      db_driver: orm # other valid values are 'mongodb' and 'couchdb'
      firewall_name: main
      user_class: '%user_class%'
      from_email:
        address: "somemail@example.com"
        sender_name: "App Mailer"
      registration:
        confirmation:
          enabled: false
      profile:
        form:
          type: AppUserBundle\Form\Type\UserProfileFormType
    

    您必须覆盖配置文件表单类型,然后按名称而不是按类名称调用它(可以构造不带参数的表单):

    看看那里:http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_forms.html#overriding-a-form-type

  • 1

    正如 Manuel DUVERNON 最后说的,我创建了一个表示HtmlPurified TextArea的FormType:

    namespace AppUserBundle\Form\Type;
    
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\DataTransformerInterface;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    use Exercise\HTMLPurifierBundle\Form\HTMLPurifierTransformer;
    use HTMLPurifier;
    
    class PurifiedTextAreaType extends AbstractType
    {
        private $purifierTransformer;
    
        /**
         * I Do not Dependency Inject the HtmlPurifier because I want to Use it as
         * FormType in FosUserBundle's extended forms in the wat that is described in: 
         * https://symfony.com/doc/master/bundles/FOSUserBundle/overriding_forms.html
         * 
         * And the method described above does not favour Dependency Injection.
         */
        public function __construct()
        {
            $this->purifierTransformer = new HTMLPurifierTransformer(new \HTMLPurifier());
        }
    
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->addViewTransformer($this->purifierTransformer);
        }
    
        public function getParent()
        {
            return 'Symfony\Component\Form\Extension\Core\Type\TextareaType';
        }
    
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                    'compound' => false,
            ));
        }
    
        public function getName()
        {
            return 'purified_textarea';
        }
    }
    

    请记住,不要通过依赖注入加载 HTMLPurifierTransformer ,因为FosUserBundle的FormBuilder无法通过依赖注入加载扩展表单 . 还要记住使用您正在扩展的FormType的命名空间(在我的例子中是 Symfony\Component\Form\Extension\Core\Type\TextareaType ),因为FormBuilder也对特定接口有限制 .

相关问题