Salut à tous !
J'ai un souci lorque j'enregistre un nouvel utilisateur (User).
Je m'explique, j'ai une entité User, celui-ci à plusieurs propriétés dont ses langues parlées ( ex : anglais, allemand, italien, etc).
j'ai une entité Language à un id et code (code de la langue, ex = EN pour anglais)
j'ai une entité UserLanguage , une classe d'association pour faire la relation entre User et Language avec un attribut $level
Les langues de l'utilisateur et leur niveau (de 0 à 3 pour native, débutant, bon, expert) peuvent se décomposer comme ça =>
1) Langue native ( exemple FR) (niveau max par défaut = 0)
2) EN avec un niveau à (bon = 2 par exemple)
3)Eo avec niveau à (débutant = 1 )
4) etc..
A l'inscription, l'utilisateur doit seulement enregistrer sa langue native (maternelle) avec un menu déroulant (hydrater via intl de symfony)
Le problème est quand mon registerType (formulaire d'inscription) est généré par symfony, il se base sur User, et à l'enregistrement apres submit du Form, dans mon controleur, je n'arrive pas à faire tout simplement que la langue soit enregistrer dans la classe Language et lié à l'User...
J'ai plusieurs type d'erreur au fur et à mesure de tout mes essais...
Voici le code de tout ça ........
USER
<?php
/**
* @Class User
*/
namespace App\Entity;
use App\Entity\Language;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @ORM\Table(name="user")
* @UniqueEntity(fields="username")
*/
class User implements UserInterface, \Serializable
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* username is email for login/register
*
* @ORM\Column(type="string", length=255, unique=true)
* @Assert\Email
* @var $username
*/
private $username;
/**
* @ORM\Column(name="password", type="string", length=255)
* @var $password
*/
private $password;
/**
* @ORM\Column(name="nickname", type="string", length=255)
* @Assert\Length(min=3)
* @var $nickname
*/
private $nickname;
/**
* @ORM\OneToMany(targetEntity="App\Entity\UserLanguage", mappedBy="user")
*
*/
private $language;
//.............//
/**
* @method array __construct
*/
public function __construct()
{
$this->isActive = true;
$this->roles = array("ROLE_USER");
$this->interest = new ArrayCollection();
$this->language = new ArrayCollection();
}
public function addLanguage(Language $language)
{
$this->language[] = $language;
// On lie l'user à la language
$language->setUser($this);
return $this;
}
public function removeLanguage(Language $language)
{
$this->language->removeElement($language);
// Et si notre relation était facultative (nullable=true, ce qui n'est pas notre cas ici attention) :
// $languages->setUser(null);
}
//.......................////
/**
* Get the value of languages
*/
public function getLanguage()
{
return $this->language;
}
/**
* Set the value of languages
*
* @return self
*/
public function setLanguage($language)
{
$this->language[] = $language;
return $this;
}
LANGUAGE
<?php
namespace App\Entity;
use App\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Table(name="language")
* @ORM\Entity(repositoryClass="App\Repository\LanguageRepository")
*/
class Language {
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="code", type="string", length=10)
*/
private $code;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\UserLanguage", inversedBy="language")
*
*/
private $user;
/**
* Get the value of id
*/
public function getId()
{
return $this->id;
}
/**
* Get the value of code
*/
public function getCode()
{
return $this->code;
}
/**
* Set the value of code
*
* @return self
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get the value of user
*/
public function getUser()
{
return $this->user;
}
/**
* Set the value of user
*
* @return self
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
}
USERLANGUAGE
<?php
namespace App\Entity;
use App\Entity\User;
use App\Entity\Language;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="user_language")
* @ORM\Entity(repositoryClass="App\Repository\UserLanguageRepository")
*/
class UserLanguage
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="App\Entity\User")
*/
protected $user;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="App\Entity\Language")
*/
protected $language;
/**
* @var int
* @ORM\Column(name="level",type="integer")
*/
private $level;
/**
* Get the value of level
*/
public function getLevel()
{
return $this->level;
}
/**
* Set the value of level
*
* @return self
*/
public function setLevel(int $level)
{
$this->level = $level;
return $this;
}
/**
* Get the value of user
*/
public function getUser()
{
return $this->user;
}
/**
* Set the value of user
*
* @return self
*/
public function setUser(User $user)
{
$this->user = $user;
return $this;
}
/**
* Get the value of language
*/
public function getLanguage()
{
return $this->language;
}
/**
* Set the value of language
*
* @return self
*/
public function setLanguage(Language $language)
{
$this->language = $language;
return $this;
}
}
registerType
<?php
namespace App\Form;
use App\Entity\User;
use App\Entity\Language;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\RadioType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\LanguageType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\CountryType;
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username', EmailType::class, array(
'label' => 'register.label.email', 'required'=> true
))
->add('password', PasswordType::class, array(
'label' => 'register.label.password', 'required'=> true
))
->add('nickname', TextType::class, array(
'label' => 'register.label.nickname', 'required'=> true
))
->add('language', LanguageType::class, array(
'label' => 'register.label.language', 'required'=> true
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => User::class,
));
}
}
Et le controller RegisterController, qui pour l'instant , est un grand n'importe quoi :-D ...
<?php
namespace App\Controller;
use App\Form\RegistrationType;
use App\Entity\User;
use App\Entity\Language;
use App\Entity\UserLanguage;
use App\Service\EmailProvider;
use App\Service\LanguagesProvider;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Validator\Constraints\DateTime;
use Symfony\Component\Intl\Intl;
class RegistrationController extends Controller
{
public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder, EmailProvider $emailProvider, LanguagesProvider $languagesProvider)
{
// Entities User
$user = new User();
// build the form
$form = $this->createForm(RegistrationType::class, $user);
// handle the submit (will only happen on POST)
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
// Encode the password (you could also do this via Doctrine listener)
$password = $passwordEncoder->encodePassword($user, $user->getPassword());
// Save _locale of user
$locale = $request->getLocale();
// Create tokenRegister
$tokenRegister = base64_encode(random_bytes(64));
// Language
$codeLanguage = $form->get('language')->getData();
$language = $this->getDoctrine()->getRepository(Language::class)->findByCode($codeLanguage);
// Inject parameters for user
$user->setTokenRegister($tokenRegister);
$user->setLocale($locale);
$user->setPassword($password);
$user->setFirstConnection(new \DateTime('NOW'));
$user->setLastConnection(new \DateTime('NOW'));
$user->setLanguage($language);
$entityManager->persist($user);
//$entityManager->flush();
// Create new relation user language
$userLanguage = new UserLanguage();
// linking language
$userLanguage->setLanguage($language);
// linking user
$userLanguage->setUser($user);
// Setting level, for native language, this is 0 (else 1=beginner, 2=good, 3=expert)
$userLanguage->setLevel(0);
// Persist
$entityManager->persist($userLanguage);
// Save
$entityManager->flush();
// Send confirmation mail with EmailProvider
$emailRegister = $emailProvider->emailRegister($user);
$this->addFlash('success',$this->get('translator')->trans('register.message.success'));
//return $this->redirectToRoute('index');
}
// Render all languages
$langs = $languagesProvider->getAllLanguages($request);
// Render twig
return $this->render(
'registration/register.html.twig',
array('form' => $form->createView(), 'languages' => $langs)
);
}
}
Voilà si des courageux sont arrivés jusque là, c'est cool, merci pour votre aide !