I am trying to create an email that messages all users that are tied to a specific company. If I take the recipients array and add it to my email and test with a single email, I can see all of the user emails print out in the test email. When I try and pass that same recipients array into setTo instead of using a single to email address I get a message "Warning: Illegal offset type"
$company = $this->getDoctrine()->getRepository('Bundle:Customer')->findOneBy(array('accountId' => $compare->getCustomerAccount()));
$recipients = [];
foreach($company->getUsers() as $user){
array_push($recipients, $user);
}
array_push($recipients, $company->getCsr());
$newComment = new Comment();
$newComment->setDetails($comment);
$newComment->setUser($this->getUser());
$em = $this->getDoctrine()->getManager();
$em->flush();
$message = \Swift_Message::newInstance()
->setSubject($subject)
->setFrom($fromEmail)
->setTo($recipients)
->setBody(
$this->renderView(
'Bundle:Comment:email_users.html.twig', array(
'subject' => $subject,
'comment' => $comment,
'company' => $company,
'proof' => $proof
)
)
)
->setContentType('text/html')
;
$this->get('mailer')->send($message);
Se setTo accept an associative array with email and name (check here in the doc), so you should modify your code with something like:
foreach($company->getUsers() as $user){
array_push($recipients, [$user->getEmail() => $user->getName()]);
}
array_push($recipients, $company->getCsr()->getEmail());
Hope this help
The error occurs, because you're trying to set the recipients with an array of $user objects instead of an associative array of strings. When trying to access the index of an array with an object or an array as the index, you will see that error message.
Your $recipientsarray should look more like array('receiver#domain.org', 'other#domain.org' => 'A name') and you should be fine.
Your code could look like this:
$recipients = [];
foreach($company->getUsers() as $user){
array_push($recipients, $user->getEmail());
}
array_push($recipients, $company->getCsr()->getEmail());
I'm just assuming that your user object has a getter method getEmail() which returns the user email address as a string.
I added the following to my user class which extends BaseUser:
/**
* Sets the email.
*
* #return string
*/
public function getEmail()
{
return parent::getEmail();
}
Then I was able to run getEmail on each user
$recipients = [];
foreach($company->getUsers() as $user){
array_push($recipients, $user->getEmail());
}
array_push($recipients, $company->getCsr()->getEmail());
Email was sent successfully!
Related
I use the instructions https://laravel.com/docs/5.8/mail
to send an email later than expected, but I get an error when I try to send it:
ErrorException (E_ERROR)
Only mailables may be queued. (View: ....
Please for help.
My methods to send:
public static function sent_info_email_later ($data_f, $minuts) {
$data = json_decode($data_f);
$when = now()->addMinutes($minuts);
return Mail::later($when,'emails.message', ['title' => $data->subject, 'body' => $data->body], function ($message) use ($data, $when)
{
$message->from(env('MAIL_USERNAME'), 'NETPlatform24');
if(gettype($data->to) == 'array') {
$dest_to = $data->to;
} else {
$dest_to = explode(', ', $data->to)[0];
}
$message->to($dest_to);
$message->subject($data->subject);
return true;
});
}
and calling index.php
$data = json_encode(array('to' => 'my email', 'subject' => 'This email was send 1 min after run', 'body' => 'time now'.now().'<br> time send: '.now()->addMinutes(1)));
$send_mail = \App\Http\Controllers\Backend\Auth\Mail\MailController::sent_info_email_later($data, 1);
I wrote this code long time ago. I hope this will help to clarify. For each Cargo I send a email using queue.
<?php
public function mails_meeting($meeting, $group, $place, $date, $message, $user)
{
$subject = "meeting " . $group;
$cargos = Cargo::where('comision_id', '=', $meeting->comision_id)->where('active', '=', '1')->get();
foreach ($cargos as $cargo) {
$mail_reciever = $cargo->asambleista->user->email;
Mail::queue('correos.comision_mail', ['group' => $group, 'place' => $place,
'date' => $date, 'message' => $message, 'user' => $user],
function ($mail) use ($subject, $mail_reciever) {
$mail->from('siarcaf#gmail.com', 'Automatic mail system');
$mail->to($mail_reciever);
$mail->subject($subject);
});
}
return 0;
}
In your_app/config/mail.php .
'sendmail' => '/usr/sbin/sendmail -bs',
'stream' => [
'ssl' => [
'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false,
],
],
.env file
MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your_username
MAIL_PASSWORD=your_password
MAIL_ENCRYPTION=your_conf
The error you're getting (and the docs) indicate that the second argument passed to the later method must be an instance of Illuminate\Mail\Mailable.
Where you currently have the string 'emails.message', you will need to replace this with an instance of Mailable that represents the email message that you're trying to send.
For example, create this file in /app/Mail (create the folder if it doesn't exist):
<?php
namespace App\Mail;
use Illuminate\Mail\Mailable;
use Illuminate\Contracts\Queue\ShouldQueue;
class InfoEmail extends Mailable implements ShouldQueue
{
public $subject;
public $body;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($subject, $body)
{
$this->subject = $subject;
$this->body = $body;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from(env('MAIL_USERNAME'), 'NETPlatform24')
->subject($this->subject)
->view('emails.message', ['title' => $this->subject, 'body' => $this->body]);
}
}
This assumes that 'emails.message' is the view file you intend to use for this email, located at /resources/views/emails/message.blade.php relative to your project's root. I'd actually recommend changing this to something a bit more descriptive.
You'll then need to change your sent_info_email_later method to something like this:
public static function sent_info_email_later ($data_f, $minuts) {
$data = json_decode($data_f);
$when = now()->addMinutes($minuts);
$recipients = is_array($data->to) ? $data->to : explode(', ', $data->to);
$recipients = array_filter(array_map('trim', $recipients));
$first_recipient = array_shift($recipients);
return Mail::to($first_recipient)
->cc($recipients)
->later($when, new InfoEmail($data->subject, $data->body));
}
I've taken the liberty of tidying up your recipients by extracting out the first recipient for the to and moving the rest to cc as this may play better with more email service providers.
Hope this helps!
I'm developing a blog under symfony and to send emails I use swiftMailer.
I use this code in my controller to send to all my users to warn them that a new article was added but the problem is that it shows me an error message.
My controller:
/**
* #Route("/admin/ajout")
* #param Request $request
* #return Response
* #throws \Exception
*/
public function add(Request $request, \Swift_Mailer $mailer): Response {
$article = new Articles();
$addArticle = $this->createForm(ArticlesType::class, $article);
$addArticle->handleRequest($request);
$info = $this->getDoctrine()->getRepository(InfoMore::class)->findByInfo(2);
$em = $this->get('doctrine.orm.entity_manager');
$dql = "SELECT email FROM App:user";
$query = $em->createQuery($dql);
if($addArticle->isSubmitted() && $addArticle->isValid()) {
$article = $addArticle->getData();
$manager = $this->getDoctrine()->getManager();
$manager->persist($article);
$manager->flush();
$message = (new \Swift_Message('Un nouvelles articles est publier'))
->setFrom('contact#al-houria.com')
->setTo($query)
->setBody(
$this->renderView(
'email/article_publish.html.twig'
),
'text/html'
)
;
$mailer->send($message);
$this->addFlash('article', 'L\'article a bien étais ajouter');
return $this->redirectToRoute('app_backoffice_admin');
}
return $this->render('backOffice/CRUD/add.html.twig', [
'title' => 'Ajouter un article a votre blog',
'info' => $info,
'addArticle' => $addArticle->createView()
]);
}
and the message error:
Address in mailbox given [Doctrine\ORM\Query_state] does not comply with RFC 2822, 3.6.2
It tells me that the address is not valid and in this case how to add multiple email addresses?
Thank you for your help!
Assuming your User entity is in App\Entity\User, you can select this:
$emails = $em
->createQuery('SELECT u.email FROM App\Entity\User u')
->getResult()
;
This will return an array of email addresses from your users. Then you just pass that to your setTo() method:
$message = (new \Swift_Message('Un nouvelles articles est publier'))
->setFrom('contact#al-houria.com')
->setTo($emails)
// ...
;
See the Doctrine DQL SELECT Examples for further help. If you wanted to be a bit fancier, you could add the user's name to their email addresses and send that out. Let's assume you have a getName() function in your User entity. You could instead generate your email addresses like so:
$emails = [];
$users = $this->getDoctrine()->getRepository(User::class)->findAll();
foreach ($users as $user) {
$emails[$user->getEmail()] = $user->getName();
}
Then when you called ->setTo($emails) it would have both their name and email address.
One last note, I would use $em = $this->getDoctrine()->getManager(); rather than $this->get('doctrine.orm.entity_manager');
I am trying to send two emails at the same time when the user submits contact form. One email to the website owner and other to the user as autoresponse. I have been trying to do this for about last 4 hours and tried different solutions on internet but I am totally lost. Here is my code to send an email
public function contactForm(Request $request)
{
$parameters = Input::get();
$email = Input::get('email');
$inquiryType = Input::get('type_inquiry');
foreach ([
'contactmessage' => 'Message',
'email' => 'Email',
'phone' => 'Phone',
'first_name' => 'Contact Name',
'g-recaptcha-response' => 'Captcha',
] as $key => $label) {
if (!isset($parameters[$key]) || empty($parameters[$key])) {
return response()->json(
[
'success' => false,
'error' => "{$label} cannot be empty",
]
);
}
}
$recipients = 'abc#gmail.com';
// if page set, try to get recipients from the page settings
if (Input::get('page_id')) {
$page = Page::find(Input::get('page_id'));
if ($page && !empty($page->recipients)) {
$recipients = explode(',', $page->recipients);
}
}
try {
$res = Mail::send(
'emails.contact',
$parameters,
function (Message $message) use ($recipients) {
$message->subject('Contact message');
if (is_array($recipients)) {
// email to first address
$message->to(array_shift($recipients));
// cc others
$message->cc($recipients);
} else {
$message->to($recipients);
}
}
);
} catch (\Exception $e) {
return response()->json(
[
'success' => false,
'error' => $e->getMessage(),
]
);
}
if($inquiryType == 'Rental Inquiry'){
Mail::send(
'emails.autoresponse',
'',
function (Message $message) use ($email) {
$message->subject('Thank you for inquiring');
if (is_array($email) {
// email to first address
$message->to(array_shift($email);
// cc others
$message->cc($email);
} else {
$message->to($email);
}
}
);
}
return response()->json(
[
'success' => $res,
]
);
}
I have tried to do the same thing by different methods but none of them are working. Please help me. This is the first time I am sending multiple emails using laravel. I think I am doing a big and silly mistake somewhere.
Thank you.
You have a missing closing parenthesis near is_array($email)
$message->subject('Thank you for inquiring');
if (is_array($email)) {
Also i would you use laravel's validator to check for required input. Another suggestion would be to use queues for mails. Sending two mails in a single request might cause your page load time to increase significantly.
The best way is create one Laravel Jobs
php artisan queue:table
php artisan migrate
php artisan make:job SendEmail
Edit your .env
QUEUE_DRIVER=database
Edit your app /Jobs/SendEmail.php
namespace App\Jobs;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Mail\Mailer;
class SendEmail extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
protected $subject;
protected $view;
protected $data;
protected $email;
/**
* SendEmail constructor.
* #param $subject
* #param $data
* #param $view
* #param $email
*/
public function __construct($subject, $data, $view, $email)
{
$this->subject = $subject;
$this->data = $data;
$this->email = $email;
$this->view = $view;
}
/**
* Execute the job.
* #param $mailer
* #return void
*/
public function handle(Mailer $mailer)
{
$email = $this->email;
$subject = $this->subject;
$view = $this->view;
$mailer->send($view, $this->data,
function ($message) use ($email, $subject) {
$message->to($email)
->subject($subject);
}
);
}
}
And handle in your controller
use App\Jobs\SendEmail;
public function contactForm(Request $request) {
//TODO Configure Subject
$subjectOwner = 'Your Email Subject For Owner';
$subjectUser = 'Your Email Subject For User';
//TODO Configure Email
$ownerEmail = 'ownerEmail#gmail.com';
$userEmail = 'userEmail#gmail.com';
//TODO Configure Data Email send to email blade viewer
$dataEmail = [
'lang' => 'en',
'user_name' => 'User Name'
];
//emails.owner mean emails/owner.blade.php
//emails.admin mean emails/admin.blade.php
$jobOwner = (new SendEmail($subjectOwner, $dataEmail, "emails.owner" , $ownerEmail))->onQueue('emails');
dispatch($jobOwner);
$jobUser = (new SendEmail($subjectUser, $dataEmail, "emails.admin" , $userEmail))->onQueue('emails');
dispatch($jobUser);
}
And try command
//IF You using Laravel 5.2
php artisan queue:listen --queue=emails
//IF You using Laravel >5.3
php artisan queue:work
I am trying to send mails to multiple recipients,But i got an error like
Swift_RfcComplianceException in MailboxHeader.php line 345: Address in
mailbox given [exmple1#gmail.com, example2#gmail.com,
ex3#gmail.com] does not comply with RFC 2822, 3.6.2.
but the code does however work when I only specify one recipient.
Here is my code:
Controller :
$myEmail='exmple1#gmail.com, exmple2#gmail.com';
$dataArray['name'] ='name';
$dataArray['E_id'] = 011;
$dataArray['password'] = '1234';
$dataArray['username'] = 'test';
Mail::to($myEmail)->send(new HeadMail($dataArray));
HeadMail.php(inside app folder)
public function build() {
$address = 'abc#gmail.com';
$name = 'test TEAM';
$subject = 'USER CREDENTIALS';
return $this->view('emails.index')
->from($address, $name)
->cc($address, $name)
->bcc($address, $name)
->replyTo($address, $name)
->subject($subject)
->with([
'name' => $this->dataArray['name'],
'password' => $this->dataArray['password'],
'E_id' => $this->dataArray['E_id'],
'email' => $this->dataArray['username'],
]);
}
How can I send the email to all recipients?Please help me.
Separate emails with a comma and use a simpler solution. At least, this is what I do:
Mail::send(['blade.view.html', 'blade.view.txt'], ['title' => $subject, 'content' => $content], function ($message) {
$message->from('it#example.com', 'IT Serviss');
$message->to(explode(",", $client_email_array));
$message->subject($subject);
});
I have an error trying to use SwiftMailer with Symfony.
I'm following a tutorial from here: http://symblog.site90.net/docs/validators-and-forms.html
The error code is:
FatalErrorException: Error: Call to undefined method Swift_Message::setMessage() in C:\xampp\htdocs\TP\src\TP\MainBundle\Controller\DefaultController.php line 327
My action is:
public function newAction()
{
$contacto = new Contacto();
$form = $this->createForm(new ContactoType(), $contacto);
$request = $this->getRequest();
if ($request->getMethod() == 'POST') {
$form->bind($request);
if ($form->isValid()) {
$message = \Swift_Message::newInstance()
->setFrom('enquiries#myweb.com.ar')
->setTo($this->container->getParameter('tp_main.emails.contact_email'))
//this is the line 327 related with the error
->setMessage($this->renderView('TPMainBundle:Default:contactEmail.txt.twig', array('contacto' => $contacto)));
//
$this->get('mailer')->send($message);
$this->get('session')->setFlash('blogger-notice', 'Your contact enquiry was successfully sent. Thank you!');
return $this->redirect($this->generateUrl('contacto_new'));
}
}
return $this->render('TPMainBundle:Default:contact.html.twig', array(
'form' => $form->createView(),));}
The error says it's undefined but,
my method setMessage() is defined in my class Contacto.php with getter and setter :
/**
* #var string
*
* #ORM\Column(name="message", type="text")
*/
private $message;
/**
* Set message
*
* #param string $message
* #return Contacto
*/
public function setMessage($message)
{
$this->message = $message;
return $this;
}
/**
* Get message
*
* #return string
*/
public function getMessage()
{
return $this->message;
}
According on what I read trying to solve it myself, could the problem be related to the versions of SwiftMailer ?
Thanks
The method "setMessage" refers indeed to your Contacto entity, but to set the content of a message with SwiftMailer, you have to use setBody();
Example :
$mail = \Swift_Message::newInstance();
$mail->setFrom('me#mail.com')
->setTo('you#mail.com')
->setSubject('Email subject')
->setBody('email body, can be swift template')
->setContentType('text/html');
$this->get('mailer')->send($mail);
EDIT : save the email content in database and send it to Twig template
I added a bit of code in your function, to actually save the email content in database. It's not mandatory but I imagine you'll want to retrieve this information later in your application. Anyway, I didn't test this, but it should work : your controller set the SwiftMailer message body as a Twig template. Your template should be able to parse the "contacto" entity.
public function newAction()
{
$contacto = new Contacto();
$form = $this->createForm(new ContactoType(), $contacto);
$request = $this->getRequest();
if ($request->getMethod() == 'POST') {
$form->bind($request);
if ($form->isValid()) {
// set your "contacto" entity
$contacto->setMessage($form->get('message')->getData());
// do the rest of $contact->set{......}
// save the message in database (if you need to but I would do it)
$em = $this->getDoctrine()->getManager();
$em->persist($contacto);
$em->flush();
// SEND THE EMAIL
$message = \Swift_Message::newInstance();
$message->setFrom('enquiries#myweb.com.ar')
->setTo($this->container->getParameter('tp_main.emails.contact_email'))
->setSubject('YOUR SUBJECT')
->setBody($this->renderView('TPMainBundle:Default:contactEmail.txt.twig', array('contacto' => $contacto)))
->setContentType('text/html');
$this->get('mailer')->send($message);
$this->get('session')->setFlash('blogger-notice', 'Your contact enquiry was successfully sent. Thank you!');
return $this->redirect($this->generateUrl('contacto_new'));
}
}
return $this->render('TPMainBundle:Default:contact.html.twig', array('form' => $form->createView()));
}