Is there any way to refresh User session? I have my controller with change locale form, once it submitted i want to refresh that session with new set locale. I already tried to use session migrate() ,but unsuccessfully.
Any ideas?
Part of my controller
/**
* #route("/changeLocale", name="changeLocale")
*/
public function changeLocale(Request $request, Session $session)
{
$form = $this->createFormBuilder(null)
->add('locale', ChoiceType::class, [
'choices' => [
'Français' => 'fr_FR',
'Czech' => 'cs_CZ',
'English(US)' => 'en_US'
]
])
->add('save', SubmitType::class)
->getForm()
;
$form->handleRequest($request);
if ($form->isSubmitted()) {
$em = $this->getDoctrine()->getManager();
$locale = $form->getData()['locale'];
$user = $this->getUser();
$user->setLocale($locale);
$em->persist($user);
$em->flush();
$session->migrate();
}
return $this->render('admin/dashboard/locale.html.twig', [
'form' => $form->createView()
]);
}
That's the wrong way.
When you authenticate, you save the locale of your user entity in the session. Right? If you have a LocaleSubscriber that saves the locale in your session, recreating your session won't work. The locale is only saved in the session at authentication.
If you change the locale, you just need to update the session.
if ($form->isSubmitted()) {
$em = $this->getDoctrine()->getManager();
$locale = $form->getData()['locale'];
$user = $this->getUser();
$user->setLocale($locale);
$em->persist($user);
$em->flush();
// Update the session
$request->getSession()->set('_locale', $locale);
}
Related
I am writing a method to request a password reset in symfony
I get the email of the user from the posted value
$data = $form->getData();
$email = $data['email'];
It seems that I get the good email value and I can verify it by a
dump($email);
that returns
"firstname.name#domain.ext"
Then I try to fetch a user in the database with
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy(["email" => $email]);
but the result is null.
After that I try 2 different ways and both of them work perfectly i.e. give a valid user.
1- I replace
$email = $data['email'];
with
$email = "firstname.name#domain.ext";
2-
I change the line that fetches the user with:
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy(["email" => "firstname.name#domain.ext"]);
Obviously the trouble comes from the way the value is passed to the findOneBy method, not because the user is not in the database.
I would like to know what I should do to use the value I got from the Post ?
Here is my controller
/**
* #Route("/passforgotten", name="app_forgotten_password", methods="GET|POST")
*/
public function askResetPass(
Request $request,
UserPasswordEncoderInterface $encoder,
ManagerRegistry $managerRegistry,
\Swift_Mailer $mailer,
TokenGeneratorInterface $tokenGenerator
): Response {
$defaultData = ['message' => 'Type your message here'];
$form = $this->createFormBuilder($defaultData)
->add('email', EmailType::class)
->add('send', SubmitType::class)
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$email = $data['email'];
//alternative that works of course with a real email
//$email="firstname.name#domain.ext";
dump($email);
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy(["email" => $email]);
dump($email);
dump($user);
if ($user === null) {
$this->addFlash('danger', 'Email Inconnu, recommence !');
return $this->redirectToRoute('app_register');
}
$token = $tokenGenerator->generateToken();
$manager = $managerRegistry->getManager();
try {
$user->setResetPasswordToken($token);
$manager->flush();
} catch (\Exception $e) {
$this->addFlash('warning', $e->getMessage());
return $this->redirectToRoute('home');
}
//this has not been tested yet
$url = $this->generateUrl('security/ask_reset_password', array('token' => $token), UrlGeneratorInterface::ABSOLUTE_URL);
$message = (new \Swift_Message('Rénitialisation du mot de pass'))
->setFrom(array('symfony#domain.ext'))
->setTo($user->getEmail())
->setBody('hello ask for reset pass!'
);
$mailer->send($message);
$this->addFlash('notice', 'Mail correctement envoyé !');
//this is not finished
return $this->redirectToRoute('a_route');
}
return $this->render('security/ask_reset_password.html.twig', [
'form' => $form->createView()
]);
}
Sorry but I was passing a misspelled email a letter l just before a b was missing and I used the form memorization of it each time. In fact it works in every case.
This is my simple code
class LuckyController extends Controller
{
public function taskFormAction(Request $request)
{
$task = new Task();
//$task->setTask('Test task');
//$task->setDueDate(new \DateTime('tomorrow noon'));
$form = $this->createFormBuilder($task)
->add('task', TextType::class)
->add('dueDate', DateType::class)
->add('save', SubmitType::class, array('label' => 'Save'))
->getForm();
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid())
{
$task = $form->getData();
return $this->redirectToRoute('task_ok', array('task' => '123'));
}
return $this->render('pre.html.twig', array('pre' => print_r($task, true), 'form' => $form->createView()));
}
public function taskOKAction(Task $task)
{
return $this->render('ok.html.twig', array('msg' => 'ok', 'task' => print_r($task, true)));
}
}
and this line
return $this->redirectToRoute('task_ok', array('task' => '123'));
makes redirection to taskOKAction, but it lets me just send parameters by URL (?task=123).
I need to send object $task to taskOKAction to print on screen what user typed in form.
How can I do that? I've already red on stackoverflow before asking that the good solution is to store data from form (e.g. in database or file) and just pass in parameter in URL the ID of object. I think it's quite good solution but it adds me responsibility to check if user didn't change ID in URL to show other object.
What is the best way to do that?
Best regards,
L.
Use the parameter converter and annotate the route properly.
Something like (if you use annotation for routes)
/**
* #Route("/task/ok/{id}")
* #ParamConverter("task", class="VendorBundle:Task")
*/
public function taskOKAction(Task $task)
You can also omit the #ParamConverter part if parameter is only one and if is type hinted (as in your case)
From your form action you can do it without actual 302 redirect:
public function taskFormAction(Request $request)
{
$task = new Task();
//$task->setTask('Test task');
//$task->setDueDate(new \DateTime('tomorrow noon'));
$form = $this->createFormBuilder($task)
->add('task', TextType::class)
->add('dueDate', DateType::class)
->add('save', SubmitType::class, array('label' => 'Save'))
->getForm();
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid())
{
$task = $form->getData();
return $this-taskOKAction($task)
}
}
This is perfectly legal, and your frontend colleague will thank you for lack of the redirects.
This is my code. I want to set default value from database in the form. I want to set value in form which i create in this method.
public function updateBlogAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$data = $em->getRepository('AppBundle:Blog\Post')->find($id);
$blogs = new Post();
$form = $this->createFormBuilder($blogs)
->add('title', TextType::class, array('attr'=>array( 'class'=>'form-control','placeholder'=>'Blog title')))
->add('description', TextareaType::class, array('attr'=>array('class'=>'form-control','placeholder'=>'Blog description')))
->add('submit',SubmitType::class, array('label'=>'Add Blog', 'attr'=> array('class'=>'btn btn-primary pull-right')))
->getForm();
$form->handleRequest($request);
if( $form->isSubmitted() && $form->isValid() ){
$data->setTitle($blogs);
$em->flush();
return $this->redirectToRoute('blog');
}
return $this->render('blog/update_blog.html.twig', array(
'form' => $form->createView()
));
}
It is as easy as
$em = $this->getDoctrine()->getManager();
$blogs= $em->getRepository('AppBundle:Blog\Post')->find($id);
$form = $this->createFormBuilder($blogs)
/* ... */
I have an application which only admin can create users and I use FOSUserBundle.
I can create user but I've got some problems when I want to login the created user.
They can't login.
I use the default login from FOSUserBundle and it works with users created from command line.
What I missed to do?
This is my createAction from my UserController:
public function createAction(Request $request)
{
$user = new User();
$form = $this->createForm(new UserType(), $user);
if ($request->getMethod() == 'POST') {
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
}
$this->get('session')->getFlashBag()->add('success', 'The user has been added!');
return $this->redirect($this->generateUrl('crm_users'));
}
return $this->render('LanCrmBundle:User:create.html.twig', array(
'form' => $form->createView(),
));
}
This is my buildForm:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username')
->add('email')
->add('enabled')
->add('password')
->add('roles', 'choice', array('choices' => array('ROLE_USER' => 'User', 'ROLE_ADMIN' => 'Admin'),'multiple' => true));
}
You are not encrypting the password while creating the user.
Change the code inside form valid success to,
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$userManager = $this->container->get('fos_user.user_manager');
$user->setPlainPassword($user->getPassword());
$userManager->updatePassword($user);
$em->persist($user);
$em->flush();
}
Maybe your default enabled value is false.
Try to set it directly :
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$user->setEnabled(true);
$em->persist($user);
$em->flush();
}
Or put it in your default value in entity class.
I want to update the data in two conditions:
When user enters all the fields in form (Name, email, password)
When user does not enter password (I have to update only name & email).
I have the Following formHandler Method.
public function process(UserInterface $user)
{
$this->form->setData($user);
if ('POST' === $this->request->getMethod()) {
$password = trim($this->request->get('fos_user_profile_form')['password']) ;
// Checked where password is empty
// But when I remove the password field, it doesn't update anything.
if(empty($password))
{
$this->form->remove('password');
}
$this->form->bind($this->request);
if ($this->form->isValid()) {
$this->onSuccess($user);
return true;
}
// Reloads the user to reset its username. This is needed when the
// username or password have been changed to avoid issues with the
// security layer.
$this->userManager->reloadUser($user);
}
An easy solution to your problem is to disable the mapping of the password field and copy its value to your model manually unless it is empty. Sample code:
$form = $this->createFormBuilder()
->add('name', 'text')
->add('email', 'repeated', array('type' => 'email'))
->add('password', 'repeated', array('type' => 'password', 'mapped' => false))
// ...
->getForm();
// Symfony 2.3+
$form->handleRequest($request);
// Symfony < 2.3
if ('POST' === $request->getMethod()) {
$form->bind($request);
}
// all versions
if ($form->isValid()) {
$user = $form->getData();
if (null !== $form->get('password')->getData()) {
$user->setPassword($form->get('password')->getData());
}
// persist $user
}
You can also add this logic to your form type if you prefer to keep your controllers clean:
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormInterface $form) {
$form = $event->getForm();
$user = $form->getData();
if (null !== $form->get('password')->getData()) {
$user->setPassword($form->get('password')->getData());
}
});
Easier way:
/my/Entity/User
public function setPassword($password)
{
if ($password) {
$this->password = $password;
}
}
So, any form using User with password will act as expected :)