Symfony how could I add fields to my FOSUser? - symfony

I'm trying to add a field 'name' to my user and this is how I proceeded
namespace User\UserBundle\Controller;
use FOS\UserBundle\Controller\RegistrationController as BaseController;
class DefaultController extends BaseController
{
public function indexAction()
{
$response = parent::registerAction();
// ... do custom stuff
return $response;
}
And this is My userType
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder
->add('nom')
->add('prenom')
;
}
When I try to add,
{{ form_widget(form.name) }}
I get this error
Method "nom" for object "Symfony\Component\Form\FormView" does not exist in FOSUserBundle:Registration:register.html.twig at line
This is my user class
namespace User\UserBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
// your own logic
}
/**
* #var string
*
* #ORM\Column(name="nom", type="string", length=255, nullable=true )
*/
private $nom;
/**
* #var string
*
* #ORM\Column(name="prenom", type="string", length=255, nullable=true )
*/
private $prenom;
/**
* Set nom
*
* #param string $nom
* #return User
*/
public function setNom($nom)
{
$this->nom = $nom;
return $this;
}
/**
* Get nom
*
* #return string
*/
public function getNom()
{
return $this->nom;
}
/**
* Set prenom
*
* #param string $prenom
* #return User
*/
public function setPrenom($prenom)
{
$this->prenom = $prenom;
return $this;
}
/**
* Get prenom
*
* #return string
*/
public function getPrenom()
{
return $this->prenom;
}
}
This is what I have under app/config
enter image description here
What should I do more? Any suggestions please? i'm newly starter with FOSUserBundle. THanks

It looks like you're trying to add the nom and prenom fields to the registration form. So you need to override the FOSUserBundle registration form. Follow the guide at Overriding Default FOSUserBundle Forms which shows how to override any form.

Maybe this link will help you http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_forms.html

This is my config.yml
Do you write it all in config.yml ?
you need to write this code in config.yml:
fos_user:
db_driver: orm
firewall_name: main
user_class: User\UserBundle\Entity\User
registration:
form:
type: user_userbundle_user
and the remaining write in ./config/services.yml
services:
fos_user.doctrine_registry:
alias: doctrine
app.form.registration:
class: UserUserBundle\Form\UserType
tags:
- { name: form.type, alias: user_userbundle_user }

So I finally got it ! I added construct to my userType
public function __construct($class)
{
parent::__construct($class);
}
And this is my new services.yml
parameters:
user_user.registration.class: User\UserBundle\Entity\User
services:
user.form.user:
class: User\UserBundle\Form\UserType
arguments: [%user_user.registration.class%]
tags:
- { name: form.type, alias: user_userbundle_user }
And that's it I hope it helps someOne. Thanks everyone

Related

Translate custom validator message

I'm trying to translate a custom constraint message:
<?php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Translation\TranslatorInterface;
/**
* #Annotation
*/
class YoutubeLink extends Constraint
{
public $message = '"{{ string }}" is not a valid Youtube link';
/**
* #var TranslatorInterface
*/
private $translator;
public function __construct($translator)
{
$this->translator = $translator;
}
}
I'm injecting the translator:
services:
App\Validator\Constraints\YoutubeLink:
arguments: [ "#translator" ]
tags:
- { name: validator.constraint_validator, alias: validator.youtube_link }
But how to translate the message now with the argument?
Just put the translation key in the entity since $message is public:
/**
* #var string
*
* #ORM\Column(type="string")
* #AppAssert\YoutubeLink(
* message = "link.invalid_youtube"
* )
*/
protected $url;

Upload image using VichUploaderBundle

I have a problem with VichUploaderBundle, I followed all the instructions but I dont know how my Controller should handle this after finished form becouse image failed to uploaded and database did not write.
my Entity class:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* #ORM\Entity
* #Vich\Uploadable
*/
class Product
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// ..... other fields
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* #Vich\UploadableField(mapping="product_image", fileNameProperty="imageName", size="imageSize")
*
* #var File
*/
private $imageFile;
/**
* #ORM\Column(type="string", length=255)
*
* #var string
*/
private $imageName;
/**
* #ORM\Column(type="integer")
*
* #var integer
*/
private $imageSize;
/**
* #ORM\Column(type="datetime")
*
* #var \DateTime
*/
private $updatedAt;
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* #param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*
* #return Product
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
var_dump($image);
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTimeImmutable();
}
return $this;
}
/**
* #return File|null
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* #param string $imageName
*
* #return Product
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
return $this;
}
/**
* #return string|null
*/
public function getImageName()
{
return $this->imageName;
}
/**
* #param integer $imageSize
*
* #return Product
*/
public function setImageSize($imageSize)
{
$this->imagesize = $imageSize;
return $this;
}
/**
* #return integer|null
*/
public function getImageSize()
{
return $this->imageSize;
}
}
my FormType class:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;
class AvatarType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('imageFile', FileType::class, array('label' => 'Brochure (PDF file)'))
;
}
public function getName()
{
return 'avatar_form';
}
}
config:
vich_uploader:
db_driver: orm # or mongodb or propel or phpcr
mappings:
product_image:
uri_prefix: /image/avatar
upload_destination: '%kernel.root_dir%/../web/image/avatar'
Twig template:
<div>
{{ form_start(form) }}
{{ form_label(form) }}
{{ form_errors(form) }}
{{ form_widget(form.imageFile) }}
<button type="submit" class="btn btn-default">Submit</button>
{{ form_end(form) }}
</div>
and finally Controller:
namespace AppBundle\Controller\User;
use AppBundle\Entity\Product;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use AppBundle\Controller\InitController;
use AppBundle\Form\AvatarType;
class UserController extends Controller implements InitController
{
/**
* #Route("/user/avatar", name="AvatarAction")
*/
public function AvatarAction(Request $request)
{
$form = $this->createForm('AppBundle\Form\AvatarType',null,array(
// To set the action use $this->generateUrl('route_identifier')
'action' => $this->generateUrl('AvatarAction'),
'method' => 'POST'
));
$form->handleRequest($request);
if ($request->isMethod('POST')) {
if($form->isValid()){
//$track = new Product();
//$em = $this->getDoctrine()->getManager();
//$em->persist($track);
//$em->flush();
}
return $this->render('default/avatar.html.twig',array(
'form' => $form->createView()
));
}
}
Thanks for all your advice!
Maybe this is not the solution, but your line :
->add('imageFile', FileType::class, array('label' => 'Brochure (PDF file)')):
Should be :
->add('imageFile', VichFileType::class, array('label' => 'Brochure (PDF file)'))
More info : https://github.com/dustin10/VichUploaderBundle/blob/master/Resources/doc/form/vich_file_type.md
What Symfony tells you as error ?
Have a nice day

Symfony: use DataTransformer in formType via Dependency injection

I want to use my DataTransformer to convert base64 strings to fileSystem images.
my code:
services:
lion_visionomie_media_bundle_base64_data_transformer:
class: Lion\Visionomie\MediaBundle\Transformer\Base64DataTransformer
arguments: ['#sonata.media.generator.default', '#sonata.media.manager.media', '#sonata.media.pool', '#doctrine.orm.entity_manager']
lion_visionomie_media_bundle_slide_type:
class: Lion\Visionomie\MediaBundle\Form\SlideType
arguments: ['#lion_visionomie_media_bundle_base64_data_transformer']
tags:
- {name: form.type}
class Base64DataTransformer implements DataTransformerInterface
{
/**
* #var GeneratorInterface
*/
private $pathGenerator;
/**
* #var MediaManager
*/
private $mediaManager;
/**
* #var Pool
*/
private $pool;
/**
* #var EntityManagerInterface
*/
private $entityManager;
public function __construct(GeneratorInterface $generator, MediaManager $mediaManager, Pool $pool, EntityManagerInterface $entityManager)
{
$this->pathGenerator = $generator;
$this->mediaManager = $mediaManager;
$this->pool = $pool;
$this->entityManager = $entityManager;
}
/**
* #param mixed $value
* #return mixed
*/
public function transform($value)
{
// [...]
return $media;
}
/**
* #param mixed $value
* #return mixed
*/
public function reverseTransform($value)
{
/** #var Media $media */
$media = $value;
return base64_encode(file_get_contents($media->getPreviousProviderReference()));
}
}
class SlideType extends AbstractType
{
/**
* #var Base64DataTransformer
*/
private $base64DataTransformer;
public function __construct(Base64DataTransformer $base64DataTransformer)
{
dump($base64DataTransformer);
die;
$this->base64DataTransformer = $base64DataTransformer;
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('active')
->add('background')
->addModelTransformer($this->base64DataTransformer)
->add('thumbnail')
;
}
My current problem is, that the base64DataTransformer variable in SlideType is null.
Can you tell me why is this null?
Maybe I can use the ContainerAwareInterface in my SlideType. But I don't want to put my dependencies manually to my DataTransformer Class.
If you want to register your form in the DIC with Symfony < 2.8, you should add the alias: <result of getName()> parameter to the form.type tag of the type. In your case, if SlideType::getName() returns slide, set the tag to { name: form.type, alias: slide } and make sure that the form is instantiated by passing the name, not the type instance:
// good
$form = $this->createForm('slide', ...);
// bad
$form = $this->createForm(new SlideType(), ...);

FOSUserBundle: Unrecognized field: usernameCanonical

First of all, I know SO is full of questions like this but I tried to combine different config values according to those responses with no luck.
I'm using FOSUserBundle with my own User class and when submiting login form I get this error:
Unrecognized field: usernameCanonical
Here are some bits of my code:
doctrine:
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
# mappings:
# FOSUserBundle: ~
fos_user:
service:
mailer: fos_user.mailer.twig_swift
db_driver: orm
firewall_name: main
user_class: AppBundle\Entity\User
Some variations tested include setting auto_mapping: false and/or uncommenting mappings.FOSUserBundle: ~
This is my user class:
<?php
namespace AppBundle\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* AppBundle\Entity\User
*
* #ORM\Entity
* #ORM\Table(name="user")
*/
class User extends BaseUser implements UserInterface
{
const ROLE_DEFAULT = 'ROLE_ADMIN';
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=100)
*/
protected $name;
/**
* #ORM\Column(type="string", length=40)
* #Assert\Email()
*/
protected $login;
/**
* #ORM\Column(type="string", length=255)
*/
protected $password;
/**
* #ORM\Column(type="string", length=255)
*/
protected $salt;
/**
* #ORM\Column(type="array", length=255)
*/
protected $roles;
/**
* Método requerido por la interfaz UserInterface
*/
public function equals(\Symfony\Component\Security\Core\User\UserInterface $user)
{
return $this->getLogin() == $user->getLogin();
}
/**
* Método requerido por la interfaz UserInterface
*/
public function eraseCredentials()
{
}
/**
* Método requerido por la interfaz UserInterface
*/
public function getUsername()
{
return $this->getLogin();
}
public function __toString()
{
return $this->getName();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set login
*
* #param string $login
*/
public function setLogin($login)
{
$this->login = $login;
}
/**
* Get login
*
* #return string
*/
public function getLogin()
{
return $this->login;
}
/**
* Set password
*
* #param string $password
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* Get salt
*
* #return string
*/
public function getSalt()
{
return $this->salt;
}
/**
* Set salt
*
* #param string $salt
*/
public function setSalt($salt)
{
$this->salt = $salt;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Adds a role to the user.
*
* #param string $role
*/
public function addRole($role)
{
$role = strtoupper($role);
if ($role === static::ROLE_DEFAULT) {
return;
}
if (!in_array($role, $this->roles, true)) {
$this->roles[] = $role;
}
}
/**
* Returns the user roles
*
* Implements SecurityUserInterface
*
* #return array The roles
*/
public function getRoles()
{
$roles = $this->roles;
foreach ($this->getGroups() as $group) {
$roles = array_merge($roles, $group->getRoles());
}
// we need to make sure to have at least one role
$roles[] = static::ROLE_DEFAULT;
return array_unique($roles);
}
/**
* Set roles
*
* #param string $roles
*/
public function setRoles(array $roles)
{
$this->roles = $roles;
}
/**
* Never use this to check if this user has access to anything!
*
* Use the SecurityContext, or an implementation of AccessDecisionManager
* instead, e.g.
*
* $securityContext->isGranted('ROLE_USER');
*
* #param string $role
* #return Boolean
*/
public function hasRole($role)
{
return in_array(strtoupper($role), $this->getRoles(), true);
}
}
Login (layout.html.twig actually) template has been overriden and apparently renders properly, my versions are:
Symonfy: Symfony version 2.8.2 - app/dev/debug
"friendsofsymfony/user-bundle": "^1.3"
console doctrine:schema:updatehas been executed and it doesn't detect any more changes, although usernameCanonical or email do not exist in the DB table.
Thanks
With FOSUserBundle 1.3.x you have to extend FOS\UserBundle\Entity\User instead of FOS\UserBundle\Model\User (see http://symfony.com/doc/1.3.x/bundles/FOSUserBundle/index.html#a-doctrine-orm-user-class).

Could not load type "acme_user_registration"

I know this problem is highly common, I surf the solution of this problem but i don't fined. I try override the form type in FOSUserBundle (add name field), and i follow this documentation:
https://github.com/FriendsOfSymfony/FOSUserBundle/blob/1.3.x/Resources/doc/overriding_forms.md, I get an error : "Could not load type "acme_user_registration".
My Entity User:
//src/MyBlogBundle/UserBundle/Entity/User.php
namespace MyBlogBundle\UserBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=50)
* #Assert\NotBlank(message="Please enter your name.", groups= {"Registration", "Profile"})
* #Assert\Length(min=3,max=50, minMessage="The name is too short.",
* maxMessage = "Your first name cannot be longer than {{ limit }} characters long",
* groups={"Registration", "Profile"})
*/
protected $name;
public function __construct()
{
parent::__construct();
}
}
My FormType:
// src/MyBlogBundle/UserBundle/Form/Type/RegistrationFormType.php
namespace MyBlogBundle\UserBundle\Form\Type;
use Symfony\Component\Form\FormBuilderInterface;
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
class RegistrationFormType extends BaseType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('name');
}
public function getName()
{
return 'acme_user_registration';
}
}
Configuring form type:
# src/MyBlogBundle/UserBundle/Resources/config/services.yml
services:
acme_user.registration.form.type:
class: MyBlogBundle\UserBundle\Form\Type\RegistrationFormType
arguments: [%fos_user.model.user.class%]
tags:
- { name: form.type, alias: acme_user_registration }
And app/config/config.yml:
fos_user:
db_driver: orm
firewall_name: main
user_class: MyBlogBundle\UserBundle\Entity\User
registration:
form:
type: acme_user_registration
Can any give me a tip what i do wrong?
transfered configuring from src/MyBlogBundle/UserBundle/Resources/config/services.yml to src/MyBlogBundle//Resources/config/services.yml and add Set and Get method to User Entity - it's solve my problem.

Resources