3
\$\begingroup\$

I have several pages in my app that have multiple forms. In this example, the 'account' page has 2 forms:

  1. allowing the user to change their password
  2. allowing the user to contact support

I am new to Symfony and would like to get an understanding if I am following best practices in this situation.

<?php
namespace App\Controller;

use App\Entity\User;
use App\Form\ChangePasswordFormType;
use App\Form\ContactSupportFormType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class AccountController extends AbstractController
{

    public function __construct(EntityManagerInterface $entityManager, UserPasswordEncoderInterface $passwordEncoder, \Swift_Mailer $mailer)
    {
        $this->entityManager = $entityManager;
        $this->passwordEncoder = $passwordEncoder;
        $this->mailer = $mailer;
    }

    /**
    * @Route("/ui/account", name="account")
    */
    public function account(Request $request): Response
    {
        $user = $this->getUser();

        $changePasswordForm = $this->createForm(ChangePasswordFormType::class);
        $contactSupportForm = $this->createForm(ContactSupportFormType::class);

        $changePasswordForm->handleRequest($request);
        $contactSupportForm->handleRequest($request);

        if ($changePasswordForm->isSubmitted() && $changePasswordForm->isValid()) {

            $plainPassword = $changePasswordForm->get('password')->getData();
            $this->updatePassword($user, $plainPassword);
        }

        if ($contactSupportForm->isSubmitted() && $contactSupportForm->isValid()) {

            $subject = $contactSupportForm->get('subject')->getData();
            $message = $contactSupportForm->get('message')->getData();
            $this->contactSupport($user, $subject, $message);
        }

        return $this->render('ui/account.html.twig', [
            'changePasswordForm' => $changePasswordForm->createView(),
            'contactSupportForm' => $contactSupportForm->createView(),
        ]);
    }

    private function updatePassword($user, $plainPassword) 
    {
        $user->setPassword($this->passwordEncoder->encodePassword($user, $plainPassword));
        $this->entityManager->persist($user);
        $this->entityManager->flush();
        $this->addFlash('success', 'Your password has been successfully updated!');
    }

    private function contactSupport($user, $subject, $message) 
    {    
        $email = (new \Swift_Message('Registered User Support Inquiry'))
            ->setFrom('app@mydomain.com')
            ->setTo('support@mydomain.com')
            ->setBody(
                $this->renderView(
                'emails/support.html.twig', [
                    'user' => $user, 
                    'subject' => $subject, 
                    'message' => $message, 
                ]
            ),
            'text/html'
        );

        $this->mailer->send($email);
        $this->addFlash('success', 'Your message was sent successfully!');
    }

}

Some specific concerns I have:

  • Is this the proper use of the constructor? For example, I have often seen the entityManager declared directly within controller methods in documentation examples. Should I declare the vars referenced in the constructor as private properties of the class?
  • Is it considered good practice to have multiple forms handled by a single controller in this way? If not, what is a recommended alternative?
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.