On my personal Symfony3.2 project I want to use HtmlPurifier into my UserProfile Form in order to to prvent XSS Attacks.
Therefore as described in: https://github.com/Exercise/HTMLPurifierBundle I modified the UserProfileFormType
accorditly:
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();
}
}
And also used these entries in services.yml
entries:
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 }
Also I put these entries in 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'
With these options I get the following error message:
Type error: Argument 1 passed to AppUserBundle\Form\Type\UserProfileFormType::__construct() must be an instance of Symfony\Component\Form\DataTransformerInterface, none given, called in /home/pcmagas/Kwdikas/php/apps/symfonyAdminLTE/vendor/symfony/symfony/src/Symfony/Component/Form/FormRegistry.php on line 85
I also tried to change the following value in src/AppUserBundle/Resources/config.yml
:
fos_user:
#Some configuration
profile:
form:
type: AppUserBundle\Form\Type\UserProfileFormType
With this one:
fos_user #Some configuration profile: form: type: app_user.user_profile_form
That returns the following error:
Could not load type "app_user.user_profile_form"
Do you have any Idea how I will solve this one? As long as I Understand the prob is that the FosUserBundle cannot load the proper service somehow. Do you have any idea how I will tell to load the appropriate service to the configuration?
On UserProfileFormType
method I replaced the:
$builder->add('description',TextareaType::class,['required' => false]);
With:
$builder->add('description',PurifiedTextAreaType::class,['required' => false]);
And I got the following error:
Type error: Argument 1 passed to AppUserBundle\Form\Type\PurifiedTextAreaType::__construct() must implement interface Symfony\Component\Form\DataTransformerInterface, none given, called in /home/pcmagas/Kwdikas/php/apps/symfonyAdminLTE/var/cache/dev/appDevDebugProjectContainer.php on line 389
Please keep in mind that I created the 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';
}
}
I also forgot to mention that I use a different bundle in order to do any sort of user management and handling named AppUserBudnle
all the custom forms are in this bundle.
I think that, the best way to use this extension is as described in the tutorial, with a single Textarea which you can call in your final form as your own TextAreaType:
I see this mistake in your description, there are the namespace but "UserProfileFormType" class name is missing.
services:
app_user.user_profile_form:
class: AppUserBundle\Form\Type
arguments: ["@app_user.html_purifier"]
tags:
- { name: form.type, alias: app_user_profile }
In this configuration
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
You must overwrite profile form type and then call it by name instead of by class name (which may construct you form without argument) :
Have a look there: http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_forms.html#overriding-a-form-type