问题
I am using SonataUserBundle and I am trying to override the edit profile form, but I am not sure about the services.yml and the config.yml. Here is the code.
ProfileType.php
namespace Application\Sonata\UserBundle\Form\Type;
use Symfony\Component\Form\FormBuilderInterface;
use Sonata\UserBundle\Form\Type\ProfileType as BaseType;
class ProfileType extends BaseType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('ciudad', null, array('label' => 'Ciudad'));
$builder->add('file', 'file', array('required' => false, 'label' => 'Subir Foto'));
}
public function getName()
{
return 'sonata_user_profile';
}
}
ProfileFormHandler.php
<?php
namespace Application\Sonata\UserBundle\Form\Handler;
use Sonata\UserBundle\Model\UserInterface;
use Sonata\UserBundle\Form\Handler\ProfileFormHandler as BaseHandler;
class ProfileFormHandler extends BaseHandler
{
public function process(UserInterface $user)
{
$this->form->setData($user);
if ('POST' == $this->request->getMethod()) {
$this->form->bindRequest($this->request);
if ($this->form->isValid()) {
$nombreArchivoFoto = uniqid().$user->getId() . '-' . $user->getUsername() . '-foto-perfil.jpg';
$user->upload($nombreArchivoFoto);
$this->onSuccess($user);
return true;
}
$this->userManager->reloadUser($user);
}
return false;
}
}
services.yml
services:
sonata_user.registration.form.type:
class: Application\Sonata\UserBundle\Form\Type\RegistrationFormType
arguments: [%fos_user.model.user.class%]
tags:
- { name: form.type, alias: sonata_user_registration }
sonata_user.profile.form.type:
class: Application\Sonata\UserBundle\Form\Type\ProfileType
arguments: [%fos_user.model.user.class%]
tags:
- { name: form.type, alias: sonata_user_profile }
sonata_user.form.handler.profile:
class: Application\Sonata\UserBundle\Form\Handler\ProfileFormHandler
arguments: ["@fos_user.profile.form", "@request", "@fos_user.user_manager"]
scope: request
public: false
Config.yml
fos_user:
db_driver: orm
firewall_name: main
user_class: Application\Sonata\UserBundle\Entity\User
registration:
form:
type: application_sonata_user_registration
profile:
form:
type: fos_user_profile
handler: fos_user.profile.form.handler.default
name: fos_user_profile_form
validation_groups: [Authentication]
sonata_user:
security_acl: false
class:
user: Application\Sonata\UserBundle\Entity\User
group: Application\Sonata\UserBundle\Entity\Group
profile:
form:
type: sonata_user_profile
handler: sonata_user.form.handler.profile
name: sonata_user_profile_form
validation_groups: [Profile]
If I use the above settings I get the next exception
ErrorException: Runtime Notice: Declaration of Application\Sonata\UserBundle\Form\Handler\ProfileFormHandler::process() should be compatible with Sonata\UserBundle\Form\Handler\ProfileFormHandler::process(FOS\UserBundle\Model\UserInterface $user) in D:\xampp\htdocs\misplanes.dev\src\Application\Sonata\UserBundle\Form\Handler\ProfileFormHandler.php line 8
And if I change the services.yml
arguments: ["@sonata_user.profile.form", "@request", "@fos_user.user_manager"]
instead of
arguments: ["@fos_user.profile.form", "@request", "@fos_user.user_manager"]
I get the next exception
ServiceNotFoundException: The service "sonata.user.profile.form.handler" has a dependency on a non-existent service "sonata_user.profile.form".
I don't really know where the mistake is, I have tried a lot of configurations and I have read different forums and blogs but I have not found the solution. I will really appreciate your help. Thanks
回答1:
I finally have found the solution. In the code above I had various mistakes.
The ProfileType.php is ok, but I change the return parameter in the GetName() just to avoid conflicts, so, the code is here
namespace Application\Sonata\UserBundle\Form\Type; use Symfony\Component\Form\FormBuilderInterface; use Sonata\UserBundle\Form\Type\ProfileType as BaseType; use Symfony\Component\OptionsResolver\OptionsResolverInterface; class ProfileType extends BaseType { private $class; /** * @param string $class The User class name */ public function __construct($class) { $this->class = $class; } public function buildForm(FormBuilderInterface $builder, array $options) { parent::buildForm($builder, $options); $builder->add('ciudad', null, array('label' => 'Ciudad')); $builder->add('file', 'file', array('required' => false, 'label' => 'Subir Foto')); } /** * {@inheritdoc} */ public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => $this->class )); } public function getName() { return 'application_sonata_user_profile'; } }
ProfileFormHandler.php: I found a mistake here in the uses statement, so, the correct code is...
use FOS\UserBundle\Model\UserInterface; use Sonata\UserBundle\Form\Handler\ProfileFormHandler as BaseHandler; class ProfileFormHandler extends BaseHandler { public function process(UserInterface $user) { $this->form->setData($user); if ('POST' == $this->request->getMethod()) { $this->form->bindRequest($this->request); if ($this->form->isValid()) { $nombreArchivoFoto = uniqid().$user->getId() . '-' . $user->getUsername() . '-foto-perfil.jpg'; $user->upload($nombreArchivoFoto); $this->onSuccess($user); return true; } $this->userManager->reloadUser($user); } return false; } protected function onSuccess(UserInterface $user) { $this->userManager->updateUser($user); } }
Services.yml:
services: sonata_user.registration.form.type: class: Application\Sonata\UserBundle\Form\Type\RegistrationFormType arguments: [%fos_user.model.user.class%] tags: - { name: form.type, alias: sonata_user_registration } sonata_user.profile.form.type: class: Application\Sonata\UserBundle\Form\Type\ProfileType arguments: [%fos_user.model.user.class%] tags: - { name: form.type, alias: application_sonata_user_profile } sonata_user.form.handler.profile: class: Application\Sonata\UserBundle\Form\Handler\ProfileFormHandler arguments: ["@sonata.user.profile.form", "@request", "@fos_user.user_manager"] scope: request public: false
Config.yml:
fos_user: db_driver: orm firewall_name: main user_class: Application\Sonata\UserBundle\Entity\User registration: form: type: application_sonata_user_registration profile: form: type: fos_user_profile handler: fos_user.profile.form.handler.default name: fos_user_profile_form validation_groups: [Authentication] sonata_user: security_acl: false class: user: Application\Sonata\UserBundle\Entity\User group: Application\Sonata\UserBundle\Entity\Group profile: # Profile Form (firstname, lastname, etc ...) form: type: application_sonata_user_profile handler: sonata_user.form.handler.profile name: sonata_user_profile_form validation_groups: [Profile]
Finally, Another mistake was related with the template, I was using the {{ form_rest(form) }}
to see the new fields, but I don't know why this didn't work, so I had to put the fields with:
{{ form_label(form.ciudad, 'CIUDAD') }}
{{ form_errors(form.ciudad) }}
{{ form_widget(form.ciudad) }}
PS. Sorry for my english level xD..
来源:https://stackoverflow.com/questions/17279497/sonatauserbundle-override-form-profile