Store email body in table using Laravel 5.3 Mailable - email

I want to store the email body in my communications table. My controller:
Mail::to($user->email)->send(new WelcomeEmail($subscription));
Communication::create([
'to' => $user->email,
'subject' => 'Welcome Email',
'body' => '???'
]);
My email goes out (successfully) and I am able to create a Communication record, but have no idea how to retrieve the email body.
After reading the Mail manual, I thought I could work with an event:
protected $listen = [
'Illuminate\Mail\Events\MessageSending' => [
'App\Listeners\LogSentMessage',
],
];
But here I get only the full plain text email. If I create an instance of the mail, with:
$email = Mail::to($user->email)->send(new WelcomeEmail($subscription));
the outcome of dd($email); is null.
Some extra info, in my WelcomeEmail.php, I am using a view:
public function build()
{
return $this->view('emails.welcome_email');
}

You can directly do this to render Mailable and store it in a variable
$html = (new WelcomeEmail($subscription))->render();

I found a solution, hopefully it can help other people.
$body = View::make('emails.welcome_email')
->with('subscription', $this->subscription)
->with('template', $this->template)
->render();
I rendered the view and saved it in the body variable.

Related

Create new contact to Mailjet and adding to an existing list

After subscription on my website form, I need to create the new contact on Mailjet and then add it to a specific list that already exist.
I have this following code which I execute after insert my user to database.
$firstname = "Michael";
$email = myemail#gmail.com;
$mj = new \Mailjet\Client($MJ_APIKEY_PUBLIC,$MJ_APIKEY_PRIVATE);
// create new contact on Mailjet
$contact_params = [
"Email" => $email
];
$response_add = $mj->post(Resources::$Contact, ['body' => $contact_params]);
// adding the created contact to my list
$list_params = [
'Name' => $firstname,
'Action' => "addnoforce",
'Email' => $email
];
$response_list = $mj->post(Resources::$ContactslistManagecontact, ['id' => 10181436, 'body' => $list_params]);
The contact is correctly created on Mailjet but never add to the list. The $response_list always give me back NULL and I don't really know why. I'm pretty new with Mailjet API, but I've following the official API and the way I want to do it seems correct. (https://dev.mailjet.com/email/reference/contacts/subscriptions#v3_post_contactslist_list_ID_managecontact)
Thanks for help :)
In case you are yet to find a solution.
Try this out, it works for me.
Check the "/contactslist/{list_ID or list_address}/managecontact" section on this documentation; https://dev.mailjet.com/email/reference/contacts/subscriptions#v3_post_listrecipient
Enjoy

Sendgrid change text and style for group unsubscribe links

I'm facing one problem while sending emails with SendGrid. I'm sending normal email with assigning unsubscribe ground id. And when sending email then getting two links Unsubscribe From This List and Manage Email Preferences. Now my requirement is that I want to change these link texts from
Unsubscribe From This List => Unsubscribe
Manage Email Preferences => Update Preferences
And also links are not coming in the bottom of email. I want these after footer texts.
I'm not using marketing emails. Below is the one email screen-shot which I got:-
And below is the code for sending email. I'm using Laravel for sending emails:-
public function sendMail()
{
$status = \Mail::send('emails.demo', ['name' => "testdata"], function($message)
{
$args = [
'asm_group_id' => 3169
];
$message->getHeaders()->addTextHeader('X-SMTPAPI', json_encode($args));
$message->to('test#gmail.com', 'Test User')->subject('This is a demo!');
});
}
Please suggest me if anyone have idea how can I achieve this.
Check this package. https://github.com/s-ichikawa/laravel-sendgrid-driver .
This is the correct format for the above package:
$send = \Mail::send('emails.tests.tests', compact([]),
function (Message $message) use (
$subject, $from_email, $from_name, $to_emails, $to_name ) {
$message->subject($subject)
//->attach($pathToFile)
//->to($to_emails)
->to($to_emails, $to_name)
//->cc($cc_email)
->from($from_email, $from_name)
->embedData([
'asm' => ['group_id' => 123],
],
'sendgrid/x-smtpapi');
});
if you are not using this package then
$status = Mail::send('emails.test', compact('data_var'), function($message)
{
$args = [
'asm_group_id' => 123
];
$message->from('testfrom#gmail.com','from name');
$message->getHeaders()->addTextHeader('X-SMTPAPI', json_encode($args));
$message->to('testto#gmail.com', 'Test User')
->subject('This is a demo!');
});

How to send email with dynamic sender in laravel?

I am creating a simple contact us from in Laravel.
I set up .env with my Gmail account. I can send email from Laravel with my email address, no problem with this.
But, I want to send email from sender address who is sending the message form contact us form.
Here is my code in controller:
public function sendMessage(Request $request)
{
$this->validate($request,[
'email'=>'required|email',
'subject'=>'required',
'body'=>'required|max:150'
]);
$body = $request['body'];
Mail::send('emails.support',['body' => $body], function($message){
$email = Input::get('email');
$subject = Input::get('subject');
$message->sender($email);
$message->to('smartrahat#gmail.com','Mohammed');
$message->subject($subject);
});
return redirect('contactUs');
}
Though, I am getting email address form contact us form, the email always sent form my email account which I configured in .env
I would have done some things different. I guess $body is the email-text? You should put this in a array and add it as a parameter in Mail::send (or directly put $request->all() as a parameter.
Also, inside of the closure of Mail, i don`t thinks its very nice to put logic there (like $email=Input::get). It does not look right if you ask me.
Didn`t test this code, but this should work:
public function sendMessage(Request $request)
{
$this->validate($request,[
'email' => 'required|email',
'subject' => 'required',
'body' => 'required|max:150'
]);
$data = [
'email' => $request->input('email'),
'subject' => $request->input('subject'),
'body' => $request->input('body')
];
Mail::send('emails.support', $data, function($message) use ($data)
{
$message->from($data['email']);
$message->to('smartrahat#gmail.com','Mohammed');
$message->subject($data['subject']);
});
return redirect('contactUs');
}
Because you add $data as as 'use', you can access this data inside the closure. The $data send as a parameter, can be used in the email blade. In this example, you can access the data like this: $email , $subject , $data, in blade these will output the values.
But you can also do it like this:
Mail::send('emails.support', $request->all(), function($message) use ($data)
public function reset_password(Request $request)
{
$user=User::whereEmail($request->email)->first();
if(count($user) == 1)
{
$data = array('name'=>"Virat Gandhi");
$subject=$request->email;
mail::send(['emails'=>'reset_set'],$data,
function($message)use($subject)
{
$message->from('your#gmail.com','kumar');
$message->to($subject);
$message->subject($subject);
});
echo "Basic Email Sent. Check your inbox.";
}
}
foreach ($emails as $value1)
{
$to[]=implode(',',$value1['0']);
}
$subject=$request->input('sub');
$mailsend=Mail::send('email.subscribe',$mail_content,
function($message)use($to,$subject)
{
$message->from('ganarone#ganar.io','Ganar');
$message->to($to);
$message->subject($subject);
});

CakePHP 2.1.0: Capture E-mail Output

I'm building a CakePHP website that sends an e-mail like this:
$email = new CakeEmail('default');
$email->template('test');
$email->emailFormat('html');
$email->to(array('john_doe#example.com' => 'John Doe'));
$email->subject('Test E-mail');
$email->helpers(array('Html', 'Text'));
$email->viewVars(
array(
...
)
);
if ($email->send()) {
$this->Session->setFlash('The e-mail was sent!', 'default', array('class' => 'alert alert-success'));
}
else {
$this->Session->setFlash('An unexpected error occurred while sending the e-mail.', 'default', array('class' => 'alert alert-error'));
}
I'd like to be able to capture the HTML rendered by the e-mail in a variable in addition to actually sending the e-mail. This way, I can record in the database the exact content of the e-mail's body. Is this doable?
Per line 50 of the MailTransport class, it appears the actual send() function returns the message and the header. So instead of:
if($email->send()) {
Try:
$mySend = $email->send();
if($mySend) {
//...
Then, $mySend should be an array:
array('headers' => $headers, 'message' => $message);
Thats what I do in my EmailLib:
https://github.com/dereuromark/tools/blob/2.0/Lib/EmailLib.php
it logs email attempts and captures the email output into a log file (email_trace.log) in /tmp/logs/ - if you are in debug mode it will only log (no emails sent - this has been proven quite useful for local delopment).
you can write a similar wrapper for your case.
but if you want to write it back into the DB Dave's approach seems to fit better.

zend form email validation

I have the following code to generate an input field for user's email address
$email = new Zend_Form_Element_Text('email');
$email->setLabel('Email:')
->addFilters(array('StringTrim', 'StripTags'))
->addValidator('EmailAddress')
->addValidator(new Zend_Validate_Db_NoRecordExists(
array(
'adapter'=>Zend_Registry::get('user_db'),
'field'=>'email',
'table'=>'tbl_user'
)))
->setRequired(true)
->setDecorators(array(
array('Label', array('escape'=>false, 'placement'=>'append')),
array('ViewHelper'),
array('Errors'),
array('Description',array('escape'=>false,'tag'=>'div')),
array('HtmlTag', array('tag' => 'div')),
));
$this->addElement($email);
now the problem is if user enter invalid hostname for email, it generate 3 errors. lets say user enter 'admin#l' as email address, and the errors will be
* 'l' is no valid hostname for email address 'admin#l'
* 'l' does not match the expected structure for a DNS hostname
* 'l' appears to be a local network name but local network names are not allowed
I just want it to give only one custom error instead of all these. If I set error message "Invalid Email Address" by addErrorMessage method, it will again generate the same message against the db_validation.
Well, it's a late answer but I think is always useful.
Simply add true as second param of addValidator()
From Zend docs (http://framework.zend.com/apidoc/1.8/):
addValidator (line 67)
Adds a validator to the end of the chain
If $breakChainOnFailure is true, then if the validator fails, the next
validator in the chain, if one exists, will not be executed.
return: Provides a fluent interface
access: public
Here the signature:
Zend_Validate addValidator (Zend_Validate_Interface $validator, [boolean $breakChainOnFailure = false])
Zend_Validate_Interface $validator
boolean $breakChainOnFailure
So the code is:
$email = new Zend_Form_Element_Text('email');
$email->setLabel('Email:')
->addFilters(array('StringTrim', 'StripTags'))
->addValidator('EmailAddress', TRUE ) // added true here
->addValidator(new Zend_Validate_Db_NoRecordExists(
array(
'adapter'=>Zend_Registry::get('user_db'),
'field'=>'email',
'table'=>'tbl_user'
), TRUE )
);
You have to create an instance of the Zend_Validate_EmailAddress class and call the setMessages method and then override the messages that you like, to remove the ones that you mention it would be something like this:
$emailValidator->setMessages(array(
Zend_Validate_EmailAddress::INVALID_FORMAT => "Your error message",
Zend_Validate_Hostname::INVALID_HOSTNAME => "Your error message",
Zend_Validate_Hostname::LOCAL_NAME_NOT_ALLOWED => "Your error message"
));
I hope this help somebody :-)
$email->addErrorMessage("Please Enter Valid Email Address");
you can use custom validator. create a file Email.php inside folder Validate in your library folder at the root of project
class Validate_Email extends Zend_Validate_Abstract
{
const INVALID = 'Email is required';
protected $_messageTemplates = array(
self::INVALID => "Invalid Email Address",
self::ALREADYUSED => "Email is already registered"
);
public function isValid($value)
{
if(preg_match($email_regex, trim($value))){
$dataModel = new Application_Model_Data(); //check if the email exists
if(!$dataModel->email_exists($value)){
return true;
}
else{
$this->_error(self::ALREADYUSED);
return false;
}
}
else
{
$this->_error(self::INVALID);
return false;
}
}
}
and in you form.php file
$mailValidator = new Validate_Email();
$email->addValidator($mailValidator, true);
Don't know if it works or not but for me it worked in case of telephone. Courtesy of http://softwareobjects.net/technology/other/zend-framework-1-10-7-telephone-validator/
It seems to be missing quite a few lines...
probably should use this:
$mailValidator = new Zend_Validate_EmailAddress();
you can also do some other validations see here: http://framework.zend.com/manual/en/zend.validate.set.html
Using a custom validator is the only way I found to avoid this problem.
If what you want is:
Having only one error message if the email address is in a wrong format
If the format is good, then validate if the email address is already in the database
Then I suggest you to do something like this:
$where = array('users', 'email', array('field' => 'user_id',
'value' => $this->getAttrib('user_id')));
$email = new Zend_Form_Element_Text('email');
$email->setLabel('E-mail:')
->setRequired(true)
->setAttrib('required name', 'email') // html5
->setAttrib('maxlength', '50')
->addFilter('StripTags')
->addFilter('StringTrim')
->addFilter('StringToLower')
->addValidator('email', true)
->addValidator('stringLength', true, array(1, 50))
->addValidator('db_NoRecordExists', true, $where)
->addDecorators($this->_elementDecorators);
$this->addElement($email);
$this->getAttrib('user_id') represents the current user's id.
There are three validators here, all of them have their second parameter $breakOnFailureset to false, so if a validator fails, the other ones won't be called.
The first validator is email, which is my own custom validator:
class My_Validate_Email extends Zend_Validate_EmailAddress
{
public function getMessages()
{
return array('invalidEmail' => 'Your email address is not valid.');
}
}
You can add this validator in your library, in /application/library/My/Validate for example, and then add
$this->addElementPrefixPath('My_Validate', 'My/Validate', 'validator');
into your form. Of course, you need to replace "My" by the name of your library.
Now if an email is in the wrong format, it will always display 'Your email address is not valid.'. If your email is too long and doesn't fit into your database field (VARCHAR(100) for example), it's going to show your stringLength validator errors, and in the last case, if an entry already exists in the database, only this error will be shown.
Of course you can add more methods into your custom validator and overload setMessages, so that you can display your own messages whatever the form you are working on.
Hope it can help someone!