can you help me figure out a way to use the email class of CI4 to send an email with an HTML as the message?
in Codeigniter 3 it is simple and goes like this:
$email->message($this->load->view('html_page_to_send_from_view_folder',$data,true));
but in Codeigniter 4 I tried doing this:
$email->setMessage(echo view('html_page_to_send_from_view_folder',$data,true));
It gives out an error:
syntax error, unexpected echo(T_ECHO), expecting ')'
I also tried putting the view in a variable like so:
$echo_page = echo view('html_page_to_send_from_view_folder',$data,true);
$email->setMessage($echo_page);
but it just throws the same error, I was searching all over the internet and the documentation but couldn't find a way to do this. Help please.
I tried this but got no error, and also got no email :'(
$echo_page = view('html_page_to_send_from_view_folder',$data,true);
$email->setMessage($echo_page);
According to this, if you want to use some template as your message body, you should do something like this:
// Using a custom template
$template = view("email-template", []);
$email->setMessage($template);
CodeIgniter 4 documentation states:
setMessage($body)
Parameters: $body (string) – E-mail message body
Returns: CodeIgniter\Email\Email instance (method chaining)
Return type: CodeIgniter\Email\Email
Sets the e-mail message body:
$email->setMessage('This is my message');
Okay I got it now I made it work by adding this code $email->setNewLine("\r\n"); at the end just after the setMessage:
$email->setMessage($my_message);
$email->setNewLine("\r\n");
and also I set the SMTP port 587 instead of 465:
$config['SMTPPort']= 587;
ALSO, for the setMessage, I did it like this:
$my_message = view('html_page_to_send_from_view_folder',["id" => $data['id']]);
$email->setMessage($my_message);
really weird man....
A. Firstly,
Instead of:❌
$echo_page = echo view('html_page_to_send_from_view_folder',$data,true);
Use this:✅
$echo_page = view('html_page_to_send_from_view_folder',$data);
Notice the luck of an echo statement and not passing true as the third argument of the view(...) hepler function.
B. Secondly, to submit HTML-based emails, ensure that you've set the mailType property to html. This can be achieved by using the setMailType() method on the Email instance. I.e:
$email->setMailType('html');
Alternatively, you could set the "mail type" by passing an array of preference values to the email initialize() method. I.e:
public function sendMail(): bool
{
$email = \Config\Services::email();
$email->initialize([
'SMTPHost' => 'smtp.mailtrap.io',
'SMTPPort' => 2525,
'SMTPUser' => '479d7c109ae335',
'SMTPPass' => '0u6f9d18ef3256',
'SMTPCrypto' => 'tls',
'protocol' => 'smtp',
'mailType' => 'html',
'mailPath' => '/usr/sbin/sendmail',
'SMTPAuth' => true,
'fromEmail' => 'from#example.com',
'fromName' => 'DEMO Company Name',
'subject' => 'First Email Test',
]);
$email->setTo('to#example.com');
$email->setMessage(view('blog_view'));
$response = $email->send();
$response ? log_message("error", "Email has been sent") : log_message("error", $email->printDebugger());
return $response;
}
Related
I'm using the AWS SDK for PHP (version 3.52.33, PHP version 7.2.19) and trying to send emails using the Simple Email Service (SES). I have SES configured, and can run the example code successfully. To make my life easier, I wrote a function to send emails (send_email.php):
<?php
// Path to autoloader for AWS SDK
define('REQUIRED_FILE', "/path/to/vendor/autoload.php");
// Region:
define('REGION','us-west-2');
// Charset
define('CHARSET','UTF-8');
// Specify Sender
define('SENDER', 'sender#xxxx.com');
require REQUIRED_FILE;
use Aws\Ses\SesClient;
use Aws\Ses\Exception\SesException;
function send_email($htmlBody,$textBody,$subject,$recipient) {
$access_key = 'accessKey';
$secret_key = 'secretKey';
$ret_array = array('success' => false,
'message' => 'No Email Sent'
);
$client = SesClient::factory(array(
'version' => 'latest',
'region' => REGION,
'credentials' => array(
'key' => $access_key,
'secret' => $secret_key
)
));
try {
$result = $client->sendEmail([
'Destination' => [
'ToAddresses' => [
$recipient,
],
],
'Message' => [
'Body' => [
'Html' => [
'Charset' => CHARSET,
'Data' => $htmlBody,
],
'Text' => [
'Charset' => CHARSET,
'Data' => $textBody,
],
],
'Subject' => [
'Charset' => CHARSET,
'Data' => $subject,
],
],
'Source' => SENDER,
]);
$messageId = $result->get('MessageId');
$ret_array['success'] = true;
$ret_array['message'] = $messageId;
echo("Email sent! Message ID: $messageId" . "\n");
} catch (SesException $error) {
echo("The email was not sent. Error message: " . $error->getAwsErrorMessage() . "\n");
$ret_array['message'] = $error->getAwsErrorMessage();
}
return $ret_array;
}
This works when called from a simple testing script (test.php) in a terminal:
<?php
ini_set('display_errors','On');
error_reporting(E_ALL | E_STRICT);
require_once './send_email.php';
$email = 'test#email.com';
$htmlbody = 'test';
$txtbody = 'test';
$subject = 'test email';
$success = send_email($htmlbody,$txtbody,$subject,$email);
I get output like:
[~]$ php test.php
Email sent! Message ID: 0101016c8d665369-027be596-f8da-4410-8f09-ff8d7f87181b-000000
which is great. However, I'm doing this to send automated emails from a website (new user registration, password resets, ...) and when I try to use send_email from within a larger script I get a ~%50 success rate (when using a constant email address). Either it works and everything is fine, or it fails without an error message:
The email was not sent. Error message:
I know that an exception is being thrown, as I'm ending up in the catch statement, but I don't know how to get more information about what went wrong since there isn't a message associated with the exception. I've tried expanding what I look for in the catch block:
<snip>
catch (SesException $error) {
echo("The email was not sent. Error message: " . $error->getAwsErrorMessage() . "\n");
$ret_array['message'] = $error->getAwsErrorMessage();
$ret_array['errorCode'] = $error->getAwsErrorCode();
$ret_array['type'] = $error->getAwsErrorType();
$ret_array['response'] = $error->getResponse();
$ret_array['statusCode'] = $error->getStatusCode();
$ret_array['isConnectionError'] = $error->isConnectionError();
}
but when it fails everything is NULL except isConnectionError = false. Anecdotally, it is totally random -- I haven't been able to discern a pattern at all as to when it works and when it fails.
One other potentially relevant note: if I loop the email sending so a new user gets 10 emails, either they all succeed or they all fail.
So, does anyone have any suggestions as to what might be going wrong, or other steps I could take to help diagnose why this is happening?
For anyone running in to a similar issue in the future, I eventually came up with two solutions:
Initially, I gave up hope on the AWS SDK and switched to using PHPMailer which avoided the issue (though I believe at the cost of a loss in performance).
The real issue (I'm fairly certain now) was a mismatch in the versions of PHP between my CLI and what the webserver was providing. This question got me thinking about how that might be the issue. By updating the version of cURL and PHP that the webserver was using, I resolved the issue.
I'm having an issue.
I try to send an activation link when the user signs up but the mail class keeps giving me this error:
{"error":{"type":"ErrorException","message":"json_encode(): Invalid UTF-8 sequence in argument","file":"C:\\BitNami\\wampstack-5.4.25-0\\apache2\\htdocs\\zplus\\vendor\\filp\\whoops\\src\\Whoops\\Handler\\JsonResponseHandler.php","line":106}}
I changed the variables $message, $subject, and even the email $email.Nothing works and I cannot solve the problem.
If I remove the mail function, then there are no problems.
Controller code
$email = Input::get('email');
Mail::queue('emails.auth.activate', array('activation_code' => $activation_code), function($message) use ($email)
{
$message->to($email, "ZL")->subject(trans("global.user_activation"));
});
Auth::loginUsingId($this->user->id);
$data = array('status' => 'success', 'redirect' => URL::to('/'));
return Response::json($data);
Could please someone help me out?
In my case problem was caused by 'driver' => 'sendmail' in app/config/mail.php. Try to use other driver or smpt.
I was wondering if someone could help me with a problem I have been having some trouble researching related to Laravel and inbound email processing through Mandrill.
Basically I wish to be able to receive emails through Mandrill and store them within my Laravel database. Now i'm not sure if i'm reading through the documentation with the wrong kind of eyes, but Mandrill says it deals with inbound email as well as outbound, however i'm starting to think that Mandrill deals with inbound email details as opposed to the actual inbound email, such as if the message is sent etc.
I've created a new Mandrill account, created an API key, created an inbound domain and corresponding subdomain of my site (e.g. inboundmail.myproject.co.uk), set the MX record and the MX record is showing as valid. From there i have set up a route (e.g. queries#inboundmail.myproject.co.uk), and a corresponding webhook (myproject.co.uk/inboundmail.php) and within this webhook tried a variety of the examples given in the API (https://mandrillapp.com/api/docs/inbound.php.html), such as adding a new route, checking the route and attempting to add a new domain. All of them worked and produced the correct results, so my authentication with Mandrill is not in question, but my real question is is there a specific webhook for dealing with accepting incoming mail messages?
I cant help but feel like an absolute idiot asking this question as i'm sure the answer is either staring me in the face or just not possible through Mandrill.
Thanks in advance.
Thanks to duellsy and debest for their help, in the end i found a script and expanded on it to add the mail to my own database and style / display it accordingly. Hope this helps someone who may have the same trouble:
<?php
require 'mandrill.php';
define('API_KEY', 'Your API Key');
define('TO_EMAIL', 'user#example.com');
define('TO_NAME', 'Foo Bar');
if(!isset($_POST['mandrill_events'])) {
echo 'A mandrill error occurred: Invalid mandrill_events';
exit;
}
$mail = array_pop(json_decode($_POST['mandrill_events']));
$attachments = array();
foreach ($mail->msg->attachments as $attachment) {
$attachments[] = array(
'type' => $attachment->type,
'name' => $attachment->name,
'content' => $attachment->content,
);
}
$headers = array();
// Support only Reply-to header
if(isset($mail->msg->headers->{'Reply-to'})) {
$headers[] = array('Reply-to' => $mail->msg->headers->{'Reply-to'});
}
try {
$mandrill = new Mandrill(API_KEY);
$message = array(
'html' => $mail->msg->html,
'text' => $mail->msg->text,
'subject' => $mail->msg->subject,
'from_email' => $mail->msg->from_email,
'from_name' => $mail->msg->from_name,
'to' => array(
array(
'email' => TO_EMAIL,
'name' => TO_NAME,
)
),
'attachments' => $attachments,
'headers' => $headers,
);
$async = false;
$result = $mandrill->messages->send($message, $async);
print_r($result);
} catch(Mandrill_Error $e) {
// Mandrill errors are thrown as exceptions
echo 'A mandrill error occurred: ' . get_class($e) . ' - ' . $e->getMessage();
// A mandrill error occurred: Mandrill_PaymentRequired - This feature is only available for accounts with a positive balance.
throw $e;
}
?>
Like using webhooks from other mail parsing services, you'll need to make use of
file_get_contents("php://input")
This will give you the raw data from the webhook, which you can then json_decode and work with the results.
I've this mail function in my custom module
function mymodule_mail($key, &$message, $params) {
switch ($key) {
case 'notification':
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';
$message['subject'] = $params['subject'];
$message['body'] = t('<table style="border:2px solid black;"><tr><td>MESSAGE BODY </td><td><b>'.$params['msg'].'</b></td></tr></table>');
break;
}
}
Here you can clearly see that for message body i'm using some html tags.
Below code invoke the mail function, which is written in my block.
$params = array(
'subject' => 'email subject',
'msg' => 'message body',
);
drupal_mail('mymodule', 'notification', 'email address', language_default(), $params);
I want to know, is there any easy way to apply a template (.tpl.php) file for my message body so that i can put my all css styling within that tpl file.
Any suggestion would be greatly appreciated.
You'll need to set up a theme call for it
function mymodule_theme() {
$path = drupal_get_path('module', 'mymodule') . '/templates';
return array(
'mymodule_mail_template' => array(
'template' => 'your-template-file', //note that there isn't an extension on here, it assumes .tpl.php
'arguments' => array('message' => ''), //the '' is a default value
'path' => $path,
),
);
}
Now that you have that, you can change the way you're assigning the body
$message['body'] = theme('mymodule_mail_template', array('message' => $params['msg']);
The key message needs to match the argument you supplied in mymodule_theme(), which it does.
Now you can just create your-template-file.tpl.php in the module's templates/ folder (you'll have to make that) and you can use the variable $message in your template to do whatever you'd like. The variable name matches your theme argument name.
After your module is set up properly, make sure to flush the cache. I can't tell you how long it took me to realize that the first time I started working with Drupal, and how much time I wasted trying to fix non-existent bugs.
The HTML Mail module does just that :-)
I am using php/Mail_mime to send styled html content using the code below.
$headers = array ('From' => $sender,
'To' => implode(',',$to),
'Subject' => $subject,
'Reply-To'=>'myemail#mydomain.com',
'MIME-Version'=>'1.0',
'Content-Type'=>'text/html'
);
/*end header*/
$this->mime = new Mail_mime();
$tt=$this->mime;
$tt->addBcc(implode(',',$bcc));
$tt->addCc(implode(',',$cc));
$tt->setTXTBody($text);
$tt->setHTMLBody($body);
$tt->addHTMLImage('../images/delete.gif');
// $tt->addAttachment('../images/delete.gif','image/gif');
$mime_body = $tt->get();
$mime_hdrs = $tt->headers($headers);
$smtp = Mail::factory('smtp',
array ('host' => $this->host,
'port' => $this->port,
'auth' => false,
'username' => $this->username,
'password' => $this->password));
$recipients=array_merge($to,$cc,$bcc);
$mail = $smtp->send($recipients, $mime_hdrs, $mime_body);
This is all a class code, so initialization is done on the constructor, which is not posted here.
Now my question is, while the above code works fine, i didnt see the correct style on the email sent.
for example if i have this as a message body of my email:
<div style="background-color:silver;">
<h1>MY Header</h1>
</div>
On my email, I can only see the My Header. The background didnt showup as silver.
What did i miss on my code above. Any help ?
Its quite possible that the email provider you are using doesn't allow HTML code in the emails, or it restricts CSS styling in the allowed HTML code. Which email provider are you using?
You might want to test this by sending an email to a gmail.com email address, which does allow html code, and see if it makes any difference.
Another thing to test would be to do a view source, or inspect element if you're using google chrome or firebug in firefox, and see if the html code is being placed where it should be.