Class 'Swift_Mime_Headers_UnstructuredHeader' not found in Laravel 5.4 - php

I am sending e-mails from Laravel app, the e-mail is working fine in localhost, but not working in production server.
Note: Hosted the application in Shared Hosting (as its for personal use)
My Controller
public function createapplication(Request $request)
{
$leaves = Application::create([
'emp_id' => auth()->user()->id,
'from_date' => request('from_date'),
'to_date' => request('to_date'),
'days' => request('days'),
'reason' => request('reason')
]);
$fromdate = $request->from_date;
$to_date = $request->to_date;
$days = $request->days;
$reason = $request->reason;
$data = array(
'name' => auth()->user()->name,
'From_date' => $fromdate,
'To_date' => $to_date,
'Days' => $days,
'Reason' => $reason
);
Mail::send('mail.leavesmail', $data, function($message) use ($fromdate, $to_date, $days, $reason)
{
$message->to('example.com', 'example')->subject('Leave Application');
$message->from('example.com', "example");
$message->cc(auth()->user()->email);
});
return redirect()->back()->with('status', 'Leave Application Submitted Successfully!');
}

For personal use or not, using your own host to send mail is generally a bad idea. There are many problems that you may come across from not being able to send mail (Host disables mail sending to stop spam). Mail going into spam (Mail comes from a known spam IP) among other issues. For this reason I would suggest Mailgun, it's free tier will keep you going forever.
Onto the problem itself, have you run composer install it looks as if a class is just missing due to that?

Related

Sending email with sendgrid on Azure using PHP returning status code 0

my PHP application is hosted on Azure and I'm using SendGrid PHP client to send emails to the application users. Everything was working fine till yesterday evening and suddenly after that emails have stopped working. On further debugging I found that the following piece of code
$response = $sg->client->mail()->send()->post($mail);
echo $response->statusCode();
is returning statusCode as zero. 0 as I understood is not returned by the server. To cross check I sent test mails through my local XAMPP PHP server and it worked well. So I assume that Azure is not able to reach sendgrid servers.
Please note that the same code was working till yesterday evening and neither code changes nor setting changes were done to trigger any issue.
To reproduce the issue, I have created a simple procedure
public function test_sendgrid_email(){
$api_key = '***************************'; //Hidden for security reasons
$request_body = [
'personalizations' => [
[
'to' => [
[
'email' => 'test#example.com',
'name' => 'Test'
]
],
'subject' => "Sending with SendGrid is Fun"
]
],
'from' => [
'email' => 'example#test.com',
'name' => 'Example'
],
'content' => [
[
'type' => 'text/html',
'value' => "and easy to do anywhere, even with PHP"
]
]
];
$request_body_formatted = json_decode(json_encode(($request_body)));
$sg = new \SendGrid($api_key);
try{
$response = $sg->client->mail()->send()->post($request_body_formatted);
return ['status' => 'success', 'message' => 'status code : ' . $response->statusCode()];
} catch (Exception $ex) {
return ['status' => 'failure', 'message' => 'Failure'];
}
}
Output: {"status":"success","message":"status code : 0"}
Is there any thing that has to be changed in Azure settings to get it back working? Any recent updates to Azure environments that forced this issue ?

Sending large amounts of emails using PHP Mailer with CodeIgniter 3

I need help sending large amounts of emails through my newly designed automated email platform.
I am using PHP Mailer Library to send emails to my contacts
I built my script in CodeIgniter 3
I am using VPS level 3 from Godaddy
My email system freezes after 5 or more emails in mail queue manager
I am assuming that my script is designed for large volumes of emails.
Mail queue manager in Godaddy WHM panel shows all my emails as FROZEN
Part of my script:
$options = [
'user_id' => $this->me->id,
'limit' => 200000,
'type' => $exploded[1]
];
$this->data['contacts'] = $this->crm_model->get_portal_contacts($options);
$emails = array();
foreach ($this->data['contacts'] as $contact) {
$this->data['fullname'] = get_user($contact)->full_name(false);
$emaildata = [
'from' => ['name' => 'Domain', 'email' => '<no-reply#domai.org>\r\n'],
'to' => strip_tags(get_user($contact)->email),
'subject' => $this->data['email']['email_subject'],
'message' => $this->load->view('np_sh/email/email-template', $this->data, TRUE)
];
$status = _send_mail($emaildata);
}
_send_mail() function is merging $emaildata variable with the default parameters and preparing to send email using PHPMailer and returning boolean status.

Override CakeEmail destination globally

Is there an easy way to "override" the destination of an email using CakeEmail?
I have a model method that send an email using this piece of code:
$Email = new CakeEmail();
$Email->config('default');
$sent = $Email->template('new-notification')
->subject('A new notification for you')
->viewVars([
'name' => $foo['User']['name'],
'text' => $foo['Notification']['text'],
)
->emailFormat('html')
->to($foo['User']['email'])
->send();
And this configuration:
class EmailConfig
{
public $default = array(
'host' => 'smtp.server.com',
'port' => 587,
'username' => 'user#domain.com',
'password' => 'pwdAsYouKnow',
'from' => array('noreply#domain.com' => 'Company'),
'transport' => 'Smtp'
);
}
As you can see, I send the email for a dynamically defined user's email.
My objective is when I'm developing locally on my machine, to force every call to ->send() to force a destination like developer#domain.com.
I can easily detect if I'm on development, but I don't know how to force in a "master" way to CakeEmail only send to a defined account overriding the one set on the call.
I already tried to set an
'to' => array('developer#domain.com' => 'Dev'),
inside $default but, no success.
I appreciate any help, thanks!
i'm assuming when you are on local machine you run in debug mode, so you can check if debug mode is on then use that to send to different email
if(Configure::read('debug')){
$emailTo = 'developer#domain.com'
}
else{
$emailTo = $foo['User']['email'];
}
then you just use variable for email address:
$sent = $Email->template('new-notification')
->subject('A new notification for you')
->viewVars([
'name' => $foo['User']['name'],
'text' => $foo['Notification']['text'],
)
->emailFormat('html')
->to($emailTo)
->send();

send email by Mandrill

I need to send an email for mandrill. This Mandrill API implemented in my project, and send a test mail by apikey provided by the client. I have two options for sending mail, one is by my account of Mandrill and the other is that the user can login by MailChimp. Then insert the API KEY mandrill your account.
I have a default variable in conf file like this:
public $default = array(
'transport' => 'Smtp',
'from' => array('noreply#example.com' => 'Example'),
'host' => 'smtp.mandrillapp.com',
'port' => 587,
'timeout' => 30,
'username' => 'example#example.com',
'password' => '12345678',
'client' => null,
'log' => false
//'charset' => 'utf-8',
//'headerCharset' => 'utf-8',
);
To send mail through my account mandrill I do this:
$email = new FrameworkEmail();
$email->config('default');
$email->emailFormat('html');
And I give my account Mandrill data. But if the user chooses to identify with MailChimp and also add your API KEY Mandrill mails should be sent from your account transactional emails and not mine. Any idea if this is possible?
I do not believe this is possible to authenticate with MailChimp and then send through Mandrill. The Mandrill API uses a different set of keys than the MailChimp API, so you won't have access to a user's Mandrill API keys if they're logged in through MailChimp.
EDIT: If you have a user's Mandrill API key, you should be able to feed it directly into the Mandrill send function from the Mandrill SDK:
<?php
$mandrill = new Mandrill('USER_PROVIDED_API_KEY_GOES_HERE');
$message = array(
'html' => '<p>html content here</p>',
// other details here
)
$async = False;
$ip_pool = null;
$send_at = null;
$result = $mandrill->messages->send($message, $async, $ip_pool, $send_at);
?>
More details on the Message function in the SDK can be found here.
EDIT #2: Same approach can be achieved using CakeEmail - you just need to instantiate the $email class at the time that you receive the user's API key, rather than before.
CakeEmail recommends in a standard setup that you do this in your initial configuration:
class EmailConfig {
public $mandrill = array(
'transport' => 'Mandrill.Mandrill',
'from' => 'from#example.com',
'fromName' => 'FromName',
'timeout' => 30,
'api_key' => 'YOUR_API_KEY',
'emailFormat' => 'both',
);
}
But we can't set this up with default values and then change it per user, using their API key. We need to instantiate this at the time that we receive the user's email, like so:
App::uses('CakeEmail', 'Network/Email');
// PHP code that takes in user email
$user_api_key = // this would come from a form, or from a user's record in the database
$email = new CakeEmail(array(
'transport' => 'Mandrill.Mandrill',
'from' => 'from#example.com',
'fromName' => 'FromName',
'timeout' => 30,
'api_key' => $user_api_key,
'emailFormat' => 'both',
));
// add CakeEmail details like $email->template, $email->subject(), etc.
$email->send();
So the principles are the same regardless of what framework is used. Rather than instantiating Mandrill configuration details in a global setting (like most email frameworks recommend), you will need to instantiate them at the time the user wants to send an email, using user-specific details.

Laravel: How to Queue mails to send later

Im trying to use the Mail::queue to send and email, but when I call this function it simple sends the mail, and the response is delayed ... I thought that the point of using Mail::queue was to queue ....
I want the response to came instantly, not having to wait for the email to be sent
for eg
Mail::queue('emails.template', $data, function($message) {
$message->to('somemail#gmail.com');
$message->subject('Notificacion');
});
return Response::json(array('error' => 0, 'message' => 'Ok'));
I want to receive the response without waiting for the mail to be sent.
How can I do that???
What queue driver (app/config/queue.php - 'default' param) are you using? If you're using sync, and haven't set up one of the others, then you're using the synchronous driver, which does exactly what the name says: Runs your queued task as soon as the task is created.
You need to configure an MQ server for Laravel to talk to. You can get a free iron.io account for this, and then you need to configure it, for instance:
'iron' => array(
'driver' => 'iron',
'project' => 'iron-io-project-id',
'token' => 'iron-io-queue-token',
'queue' => 'queue-name',
),
Then when you use Mail::queue() it will push the instruction to iron.io. You'll then have to have another thread listening on the queue - just run php artisan queue:listen and leave it running while messages are pushed to the queue.
/**
* Get all email recipients and include their user details for Mailgun's
* template tags - %recipient.userToken%
*/
private function getRecipients()
{
foreach (User::get() as $user)
{
$this->recipients[$user->email] = [
'id' => $user->id,
'userToken' => $user->user_token,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'email' => $user->email
];
}
}
private function sendEmail()
{
$subject = 'Demo Subject';
/**
* Data for the Blade template
*/
$data = [
'foo' => 'bar'
];
// Inline the CSS for the email
$inliner = new InlineEmail('emails.some-email', $data);
$content = $inliner->convert();
// Create Emails table entry for this email. Used for Mailgun webhooks
$email = Email::create(['user_id' => $this->userId, 'subject' => $subject, 'email_id' => str_random()]);
// Prepare the email addresses
$emailAddresses = array_column($this->recipients, 'email');
$this->mailgun->sendMessage('demo.org', [
"from" => 'support#demo.org',
"to" => implode(',', $emailAddresses), // Comma separated list of email addresses
"subject" => $subject,
"html" => $content, // Inlined CSS HTML from Blade
"text" => "Plain text message here",
"recipient-variables" => json_encode($this->recipients), // Required for batch sending, matches to recipient details
"v:messageId" => $email->id, // Custom variable used for webhooks
]);
}

Categories