Symfony 5 Mailer undefined method named "htmlTemplate" - php

I'm looking to use Symfony Mailer Inside a personal project. The idea is the user subscribe to a newsletter, then he received a mail that confirm he subscribe.
I've made a function send Mail inside my controller to call this function when the form is submit.
function sendEmail(MailerInterface $mailer, $useremail)
{
$email = (new Email())
->from('mail#mail.exemple')
->to($useremail)
->subject('Great !')
->htmlTemplate('emails/signup.html.twig');
$mailer->send($email);
return $email;
}
/**
* #Route("/", name="homepage")
*/
public function index(Request $request, MailerInterface $mailer)
{
$mailing = new Mailing();
$form = $this->createForm(MailingType::class, $mailing);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$task = $form->getData();
$this->sendEmail($mailer , $request->request->get('mailing')['email']);
return $this->redirectToRoute('homepage');
}
When I submit the form, Everything is okay but when it come inside my sendEmail function the following error appear :
Attempted to call an undefined method named "htmlTemplate" of class
"Symfony\Component\Mime\Email".
Do you have any idea about why this error appear ? I'don't understand what's happening.
THank you.

To use a template, you need to use a TemplatedEmail as described in the docs
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
function sendEmail(MailerInterface $mailer, $useremail)
{
$email = (new TemplatedEmail())
->from('mail#mail.exemple')
->to($useremail)
->subject('Great !')
->htmlTemplate('emails/signup.html.twig');
$mailer->send($email);
return $email;
}

You need to use 'TemplatedEmail' rater than 'Email' class

Related

Why are my Symfony Router are not Working?

I am currently creating a Symfony Project for School and i was just trying some things out with this Security Bundle... I was creating the Registration Controller with this php bin/console make:registration-form Command and it worked out fine. The Files got created and i got no Errors but when i am trying to go to /register they just show me my index.php all the time... if i delete index.php its always # Page not Found from my Symfony Local Server... Im just testing out so im just using this localhost Webserver from Symfony. I tested out the Route with php bin/console router:match /register and it showed green, it works and exists. But when i try going to the Site nothing happens.
namespace App\Controller;
use App\Entity\User;
use App\Form\RegistrationFormType;
use App\Repository\UserRepository;
use App\Security\EmailVerifier;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mime\Address;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;
class RegistrationController extends AbstractController
{
private EmailVerifier $emailVerifier;
public function __construct(EmailVerifier $emailVerifier)
{
$this->emailVerifier = $emailVerifier;
}
#[Route('/register', name: 'app_register')]
public function register(Request $request, UserPasswordHasherInterface $userPasswordHasher, EntityManagerInterface $entityManager): Response
{
$user = new User();
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// encode the plain password
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
)
);
$entityManager->persist($user);
$entityManager->flush();
// generate a signed url and email it to the user
$this->emailVerifier->sendEmailConfirmation('app_verify_email', $user,
(new TemplatedEmail())
->from(new Address('info#julian-schaefers.dev', 'Julian Schaefers'))
->to($user->getUserIdentifier())
->subject('Please Confirm your Email')
->htmlTemplate('registration/confirmation_email.html.twig')
);
// do anything else you need here, like send an email
return $this->redirectToRoute('_profiler_home');
}
return $this->render('registration/register.html.twig', [
'registrationForm' => $form->createView(),
]);
}
#[Route('/verify/email', name: 'app_verify_email')]
public function verifyUserEmail(Request $request, UserRepository $userRepository): Response
{
$id = $request->get('id');
if (null === $id) {
return $this->redirectToRoute('app_register');
}
$user = $userRepository->find($id);
if (null === $user) {
return $this->redirectToRoute('app_register');
}
// validate email confirmation link, sets User::isVerified=true and persists
try {
$this->emailVerifier->handleEmailConfirmation($request, $user);
} catch (VerifyEmailExceptionInterface $exception) {
$this->addFlash('verify_email_error', $exception->getReason());
return $this->redirectToRoute('app_register');
}
// #TODO Change the redirect on success and handle or remove the flash message in your templates
$this->addFlash('success', 'Your email address has been verified.');
return $this->redirectToRoute('app_register');
}
}

How to pass data to mail view using queue?

I have my job class ProductPublish method handle() I am trying to send email.
public function handle()
{
//
Mail::to('i******o#gmail.com')->send(new SendEmail());
}
In the ProductController controller I am calling that job class as like below
ProductPublish::dispatch();
In the SendEmail class which is mailable I am trying to pass data to view as like below
public $message;
public function __construct($message)
{
$this->message = 'This is test message';
}
public function build()
{
return $this->view('email.product.product-publish')->with('message' => $this->message);
}
But it does not works. I also tried with no attaching with() method but still does getting result. In the email view I am calling data as like below
{{ $message }}
Can someone kindly guide me what can be issue that it is not working. Also I want to pass data actually from ProductController but since I am failed to pass from sendEmail that's I didn't tried yet from controller.
Kindly guide me how can I fix it.
In laravel,
The arguments passed to the dispatch method will be given to the job's constructor
So when you are calling dispatch, you can pass message :
ProductPublish::dispatch($message);
Then inside your job you can add a property message and a constructor to get it from dispatch and assign it :
private $message;
public function __construct($message)
{
$this->message = $message;
}
public function handle()
{
// Use the message using $this->messge
Mail::to('i******o#gmail.com')->send(new SendEmail($this->message));
}
Also you can directly queue emails. Check documentation
Try this:
public $message;
public function __construct($message)
{
$this->message= $message;
}
public function build()
{
// Array for passing template
$input = array(
'message' => $this->message
);
return $this->view('email.product.product-publish')
->with([
'inputs' => $input,
]);
}
Check Docs

How solve instance problem with Doctrine?

I'm new learner of Symfony 4 and I'm looking for help. I've an Entity named "Player" and I want to generate a random confirmation number.
For now, I'm using a variable $confirmNbr and I save the $confirm in my database with $participant->setConfirmationNumber($confirmNbr);.
What I want it's create a function generateRandomNumber() in my Entity Player.php like this :
public function generateConfirmationNumber() : self
{
$this->confirmationNumber = substr(str_shuffle(str_repeat('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',6)),0,5);
return $this;
}
This is my Controller file
/**
* #Route("/", name="homepage")
*/
public function new(Player $player, EntityManagerInterface $em, Request $request)
{
$participant = $this->playerrepo->findAll();
$form = $this->createForm(PlayerFormType::class);
$randomNbr = $player->generateConfirmationNumber();
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$participant = new Player;
$participant->setName($data['name']);
$participant->setFirstname($data['firstname']);
$participant->setEmail($data['email']);
$participant->setConfirmationNumber($confirmNbr);
$participant->setRegisterAt(new \DateTime);
$em->persist($player);
$em->flush();
$this->addFlash('success', 'Player added!');
return $this->redirectToRoute('homepage');
}
return $this->render('app/subscribe.html.twig', [
'playerForm' => $form->createView(),
'player'=>$player,
]);
}
And this is my error message :
Unable to guess how to get a Doctrine instance from the request
information for parameter "player".
Can you help me please ?
Your method is expecting an instance of the Player object - where should it come from? Doctrine is trying to guess it and get it from the URL, but it cannot. Your method is for creating new players - why do you need an instance of a player? Just remove that parameter from the method signature, i.e. change it to:
public function new(EntityManagerInterface $em, Request $request)
I've found the solution. I've modified my set function and deleted my function that I've added. Everything works!

How to properly call a function with instance in Symfony 4

I'm trying to send an email with SMTP in Symfony 4 and I have the following function as per the docs.
public function send_smtp(\Swift_Mailer $mailer)
{
$message = (new \Swift_Message('Hello Email'))
->setFrom('send#example.com')
->setTo('MyEmail#gmail.com')
->setBody('test email content');
$mailer->send($message);
}
However, I want to call this function from a different one like
$this->send_smtp();
But it complains about 'No parameters are passed' and
$this->send_smtp(\Swift_Mailer);
also gives the error message
Undefined constant 'Swift_Mailer'
What can be the problem and how could it be solved?
There are a few solutions possible. You can add the parameter with typehinting in your action and then use it to call your function:
/**
* #Route("/something")
*/
public function something(\Swift_Mailer $mailer)
{
$this->send_smtp($mailer);
}
or you can retrieve the service from the container in the send_smtp function:
public function send_smtp()
{
$mailer = $this->get('mailer');
$message = (new \Swift_Message('Hello Email'))
->setFrom('send#example.com')
->setTo('MyEmail#gmail.com')
->setBody('test email content');
$mailer->send($message);
}
Create service e.g.
namespace App\Service\Mailer;
class Mailer
{
private $mailer;
public function __construct(\Swift_Mailer $mailer)
{
$this->mailer = $mailer;
}
public function send_smtp()
{
$message = (new \Swift_Message('Hello Email'))
->setFrom('send#example.com')
->setTo('MyEmail#gmail.com')
->setBody('test email content');
$this->mailer->send($message);
}
}
And now you can inject this service wherever you want (e.g. to your Controller action or in another service) via __construct:
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
public function someAction()
{
$this->mailer->send_smtp()
}
Or you can inject it via method or via property. You can read more about injections here: https://symfony.com/doc/current/components/dependency_injection.html
P.S. I don't recommend you use container's method get because this method works only for public services, but in Symfony 4 services are private by default.

What's wrong with my Laravel 5.5 save() method?

I am using Laravel 5.5, I want to do basic form input where is only one field->"email". I am using Eloquent, model to interact with database for these subscriber inputs. When the controller method is called, this error follows:
FatalThrowableError (E_ERROR) Call to a member function save() on
string
The thing is I am using exactly the same solution for other form I've got in my application (contact form). That's the reason why I am pretty sure, that namespacing, models or other stuff I written well.
This is my code:
SubsController.php
class SubsController extends Controller
{
public function store(Request $request)
{
$subscriber = new Subscriber;
$subscriber=$request->input('email');
$subscriber->save();
return redirect()->to(route('homepage'));
}
}
Please check this line, you just assigned a string value to your $subscriber variable
$subscriber =$request->input('email');
The correct way is
public function store(Request $request) {
$subscriber = new Subscriber;
$subscriber->email =$request->input('email');
$subscriber->save();
return redirect()->to(route('homepage'));
}
Here is the solution :
$subscriber = new Subscriber;
$subscriber->email = $request->input('email');
$subscriber->save();
return redirect()->to(route('homepage'));
One more solution is
public function store() {
$data = request()->validate('email');
Subscriber::create($data);
return redirect()->route('homepage');
}

Categories