Magento: Send Custom Transactional Email in Custom Observer - email

I'm trying send a email when admin cancel a order manually. I'm using the order_cancel_after event and my observer method run fine.
But my email is not fired. I get the following exception (above), despite all code be run.
exception 'Zend_Mail_Protocol_Exception' with message 'No recipient forward path has been supplied' in /home/mydomain/www/loja/lib/Zend/Mail/Protocol/Smtp.php:309
I tested sending a new email on my order observer: $order->sendNewOrderEmail(), and the new order email arrived correctly, so my SMTP is ok.
My code in observer:
class Spalenza_Cancelorder_Model_Observer
{
public function enviamail(Varien_Event_Observer $observer)
{
$order = $observer->getOrder();
if ($order->getId()) {
try {
$translate = Mage::getSingleton('core/translate');
$email = Mage::getModel('core/email_template');
$template = 16;//Mage::getModel('core/email_template') ->loadByCode('Cancelamento Manual by Denis')->getTemplateId();
Mage::log('Codigo do template: '.$template,null,'events.log');
$sender = array(
'name' => Mage::getStoreConfig('trans_email/ident_support/name', Mage::app()->getStore()->getId()),
'email' => Mage::getStoreConfig('trans_email/ident_support/email', Mage::app()->getStore()->getId())
);
Mage::log($sender,null,'events.log');
$customerName = $order->getShippingAddress()->getFirstname() . " " . $order->getShippingAddress()->getLastname();
$customerEmail = $order->getPayment()->getOrder()->getEmail();
$vars = Array( 'order' => $order );
$storeId = Mage::app()->getStore()->getId();
$translate = Mage::getSingleton('core/translate');
Mage::getModel('core/email_template')
->sendTransactional($template, $sender, $customerEmail, $customerName, $vars, $storeId);
$translate->setTranslateInline(true);
Mage::log('Order successfully sent',null,'events.log');
} catch (Exception $e) {
Mage::log($e->getMessage(),null,'events.log');
}
} else {
Mage::log('Order not found',null,'events.log');
}
}
}
Magento version: 1.5.1.0

This line
$customerEmail = $order->getPayment()->getOrder()->getEmail();
should probably be
$customerEmail = $order->getPayment()->getOrder()->getCustomerEmail();
You should pay attention to what the error message says and check the output of your variables.

Related

attachment is not sent in email in CodeIgniter [duplicate]

I am trying to send email on codeigniter with attach file.
I always receive email successfully. However , I never receive with attach file. Below is code and highly appreciate for all comments.
$ci = get_instance();
$ci->load->library('email');
$config['protocol'] = "smtp";
$config['smtp_host'] = "ssl://smtp.gmail.com";
$config['smtp_port'] = "465";
$config['smtp_user'] = "test#gmail.com";
$config['smtp_pass'] = "test";
$config['charset'] = "utf-8";
$config['mailtype'] = "html";
$config['newline'] = "\r\n";
$ci->email->initialize($config);
$ci->email->from('test#test.com', 'Test Email');
$list = array('test2#gmail.com');
$ci->email->to($list);
$this->email->reply_to('my-email#gmail.com', 'Explendid Videos');
$ci->email->subject('This is an email test');
$ci->email->message('It is working. Great!');
$ci->email->attach( '/test/myfile.pdf');
$ci->email->send();
$this->email->attach()
Enables you to send an attachment. Put the file path/name in the first parameter. Note: Use a file path, not a URL. For multiple attachments use the function multiple times. For example:
public function setemail()
{
$email="xyz#gmail.com";
$subject="some text";
$message="some text";
$this->sendEmail($email,$subject,$message);
}
public function sendEmail($email,$subject,$message)
{
$config = Array(
'protocol' => 'smtp',
'smtp_host' => 'ssl://smtp.googlemail.com',
'smtp_port' => 465,
'smtp_user' => 'abc#gmail.com',
'smtp_pass' => 'passwrd',
'mailtype' => 'html',
'charset' => 'iso-8859-1',
'wordwrap' => TRUE
);
$this->load->library('email', $config);
$this->email->set_newline("\r\n");
$this->email->from('abc#gmail.com');
$this->email->to($email);
$this->email->subject($subject);
$this->email->message($message);
$this->email->attach('C:\Users\xyz\Desktop\images\abc.png');
if($this->email->send())
{
echo 'Email send.';
}
else
{
show_error($this->email->print_debugger());
}
}
i have this problem before , the problem with the path file , so i change the path file to
$attched_file= $_SERVER["DOCUMENT_ROOT"]."/uploads/".$file_name;
$this->email->attach($attched_file);
And it works fine with me
With Codeigniter 3.1.0 I had same problem. Seems that there is missing a "\r\n":
Content-Type: application/pdf; name="test.pdf"<br>
Content-Disposition: attachment;<br>
Content-Transfer-Encoding: base64<br>
JVBERi0xLjYNJeLjz9MNCjQzNyAwIG9iag08PC9MaW5lYXJpemVkIDEvTCA3OTUyMTYvTyA0Mzkv<br>
RSA2ODEwODcvTiA0L1QgNzk0ODA3L0ggWyA1NjQgMjYxXT4+DWVuZG9iag0gICAgICAgICAgICAg<br>
should be:
Content-Type: application/pdf; name="test.pdf"<br>
Content-Disposition: attachment;<br>
Content-Transfer-Encoding: base64<br>
<br>
JVBERi0xLjYNJeLjz9MNCjQzNyAwIG9iag08PC9MaW5lYXJpemVkIDEvTCA3OTUyMTYvTyA0Mzkv<br>
RSA2ODEwODcvTiA0L1QgNzk0ODA3L0ggWyA1NjQgMjYxXT4+DWVuZG9iag0gICAgICAgICAgICAg<br>
I changed line 725 in system/libraries/Email from
'content' => chunk_split(base64_encode($file_content)),<br>
to
'content' => "\r\n" . chunk_split(base64_encode($file_content)),<br>
It works for me, but not the perfect fix.
Try putting the full path in $ci->email->attach();
On windows this would like something like
$ci->email->attach('d:/www/website/test/myfile.pdf');
This method has worked well for me in the past.
If you want to send attachment in email Without uploading file on server, please refer below.
HTML View file
echo form_input(array('type'=>'file','name'=>'attach_file','id'=>'attach_file','accept'=>'.pdf,.jpg,.jpeg,.png'));
Controller file
echo '<pre>'; print_r($_FILES); shows below uploaded data.
[attach_file] => Array
(
[name] => my_attachment_file.png
[type] => image/png
[tmp_name] => C:\wamp64\tmp\php3NOM.tmp
[error] => 0
[size] => 120853
)
We will use temporary upload path [tmp_name] where attachment is uploaded, because we DO NOT want to upload attachment file on server.
$this->email->clear(TRUE); //any attachments in loop will be cleared.
$this->email->from('your#example.com', 'Your Name');
$this->email->to('someone#example.com');
$this->email->subject('Email Test');
$this->email->message('Testing the email class.');
//Check if there is an attachment
if ( $_FILES['attach_file']['name']!='' && $_FILES['attach_file']['size'] > 0 )
{
$attach_path = $_FILES['attach_file']['tmp_name'];
$attach_name = $_FILES['attach_file']['name'];
$this->email->attach($attach_path,'attachment',$attach_name);
}
$this->email->send();
use path helper
$this->load->helper('path');
$path = set_realpath('./images/');
on email line
$this->email->attach($path . $your_file);
here i am using phpmailer to send mail
here full code is mention below
$this->load->library('My_phpmailer');
$mail = new PHPMailer();
$mailBody = "test mail comes here2";
$body = $mailBody;
$mail->IsSMTP(); // telling the class to use SMTP
$mail->Host = "ssl://smtp.gmail.com"; // SMTP server
$mail->SMTPDebug = 1;// enables SMTP debug information (for testing)
// 1 = errors and messages
// 2 = messages only
$mail->SMTPAuth = true;// enable SMTP authentication
$mail->Host = "ssl://smtp.gmail.com"; // sets the SMTP server
$mail->Port = 465;// set the SMTP port for the GMAIL server
$mail->Username = "YourAccountIdComesHere#gmail.com"; // SMTP account username
$mail->Password = "PasswordComesHere";// SMTP account password
$mail->SetFrom('SetFromId#gmail.com', 'From Name Here');
$mail->AddReplyTo("SetReplyTo#gmail.com", "Reply To Name Here");
$mail->Subject = "Mail send by php mailer";
$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test
$mail->MsgHTML($body);
$mail->AddAttachment($cdnStorage . '/' . $fileName);
$address ='WhomeToSendMailId#gmail.com';
$mail->AddAddress($address, "John Doe");
if (!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}
Here Is Full Source Code
$validation_rules = array(
array('field' => 'name', 'rules' => COMMON_RULES),
array('field' => 'email', 'rules' => COMMON_RULES),
array('field' => 'message', 'rules' => COMMON_RULES),
);
$this->validation_errors($validation_rules);
$name = $this->input->post('name');
$email = $this->input->post('email');
$message = $this->input->post('message');
$this->load->library('email');
//upload file
$attachment_file = "";
if (!empty($_FILES) && isset($_FILES["attachment_file"])) {
$image_name = $_FILES["attachment_file"]['name'];
$ext = pathinfo($image_name, PATHINFO_EXTENSION);
$new_name = time() . '_' . $this->get_random_string();
$config['file_name'] = $new_name . $ext;
$config['upload_path'] = "uploads/email/";
$config['allowed_types'] = "*";
$this->load->library('upload', $config);
$this->upload->initialize($config);
if ($this->upload->do_upload('attachment_file')) {
$finfo = $this->upload->data();
$attachment_file = base_url() . 'uploads/email/' . $finfo['file_name'];
} else {
$error = $this->upload->display_errors();
$this->msg = $error;
$this->_sendResponse(5);
}
}
$this->email->from($email, "$name")
->to("example#gmail.com")
->subject("FeedBack From $name")
->message($message)
->attach($attachment_file);
if ($this->email->send()) {
// temp pass updated.
$this->msg = "Email send successfully.";
$this->_sendResponse(1);
} else {
$this->msg = "Internal server error/Something went wrong.";
$this->_sendResponse(0);
}
$this->load->library('email'); // Loading the email library.
$this->email->clear(TRUE);
$this->email->from($user_email, $name);
$this->email->to('email#gmail.com');
$this->email->subject("Some subject");
$this->email->message("Some message");
if($_FILES['userfile']['name']!='' && $_FILES['userfile'['size'] > 0){
$attach_path = $_FILES['userfile']['tmp_name'];
$attach_name = $_FILES['userfile']['name'];
$this->email->attach($attach_path,'attachment',$attach_name);
}
$this->email->send();

Why was the mail sent but not received in zend framework?

I'm new to the zend framework.
I have a code to send a mail and it's working, but the message is not received by the customer side, but it returns that the mail was sent successfully. Can you teach me how to work with zend_email?
public function sendMailStatements($qid,$emails=array()) {
require_once 'Zend/Mail.php';
require_once 'Zend/Mail/Transport/Smtp.php';
try {
$config = array('ssl' => 'ssl',
'port' => 465,
'auth' => 'login',
'host' => '127.0.0.1',
'username' => 'username#gmail.com',
'password' => 'password');
$transport = new Zend_Mail_Transport_Smtp('smtp.gmail.com', $config);
Zend_Mail::setDefaultTransport($transport);
$mail = new Zend_Mail();
$mail->setSubject("Quotation LL Sports Exim");
$body="Dear Sir/Madam<br>Kindly find the attached Quotation and give us your Feed BAck";
$mail->setBodyHtml($body);
foreach ($emails as $email):
$mail->addTo($email);
endforeach;
var_dump($emails);
if($qid!=""):
$fullBaseUrl = getcwd();
$full_path = $fullBaseUrl . "\\pdfs\\" .$qid.".pdf";
$content = file_get_contents($full_path); // e.g. ("attachment/abc.pdf")
$attachment = new Zend_Mime_Part($content);
$attachment->type = 'application/pdf';
$attachment->disposition = Zend_Mime::DISPOSITION_ATTACHMENT;
$attachment->encoding = Zend_Mime::ENCODING_BASE64;
$attachment->filename ="quotation.pdf"; // name of file
$mail->addAttachment($attachment);
endif;
$mail->send($transport);
return true;
} catch (Zend_Exception $e) {
echo "Caught exception: " . get_class($e) . "\n";
echo "Message: " . $e->getMessage() . "\n";
exit;
// Other code to recover from the error
}
}
Please let me know where I did wrong?
Thanks in advance.

Setting mail template in ses client

I am developing a web application using cakephp 3.0 and I have an email sending function earlier I was use php mail function. Now I am using AWS ses client. So in that ses client how I can render a template. In cake php email function it was possible. But I don't know how to do it in aws ses client.
My code is
public function testMail() {
if ($this->request->is('post')) {
$client = SesClient::factory(Configure::read('AWScredentials'));
$formData = $this->request->data;
$body = $formData['body'];
$ToAddresses = $formData['ToAddresses'];
$request = array();
$request['Source'] = 's#gmail.com';
$request['Destination']['ToAddresses'] = array($ToAddresses);
$request['Destination']['CcAddresses'] = 'ss#gmail.com';
$request['Message']['Subject']['Data'] = 'Test mail from vcollect ses';
$request['Message']['Subject']['Charset'] = 'ISO-2022-JP';
$request['Message']['Body']['Text']['Data'] = $body;
$request['Message']['Body']['Text']['Charset'] = 'ISO-2022-JP';
try {
$result = $client->sendEmail($request);
$messageId = $result->get('MessageId');
$this->log("Email sent! Message ID: $messageId", "info");
} catch (Exception $e) {
$this->log("The email was not sent. Error message:" . $e->getMessage(), "error");
}
} }
You must create a debug sender in app.php, just add it to your EmailTransport array like this, it's allow you to do a fake email without send it
'EmailTransport' => [
'default' => [
'className' => 'Mail',
// The following keys are used in SMTP transports
'host' => 'localhost',
'port' => 25,
'timeout' => 30,
'username' => 'user',
'password' => 'secret',
'client' => null,
'tls' => null,
'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),
],
'debug' => [
'className' => 'Debug',
],
],
after to generate the email with your your template you can use this function for exemple
public function setTemplate($template,$layout = null,$viewVars = array(),$debug = 0)
{
if(empty($layout)) $layout = 'default';
$Email = new Email();
$Email->template($template, $layout)
->transport('debug') //<---- Allows you to simulate the message without sending it
->to(array('foo#bar.org'=>'toto'))
->emailFormat('html');
->viewVars($viewVars);
$Email->send();
/* Once email is generate, personally i duplicate the object for access to the protected proprety ( it's not very clean but i don't have a greatest solution)
The idea is to get _htmlMessage in the object */
$refObj = new ReflectionObject($Email);
$refProp1 = $refObj->getProperty('_htmlMessage');
$refProp1->setAccessible(TRUE);
if($debug == 1)
{
die(debug($refProp1->getValue($Email)));
}
return $refProp1->getValue($Email); // <---- your html code
}

Send mail via MailGun in CakePHP

i run a cloud app (using CakePHP) on Rackspace and i wanna send emails using cakephp.
I used this: https://github.com/kochb/cakephp-mailgun
but it returns me an
"Could not send email.
Error: An Internal Error Has Occurred."
error.
The way i try to send an email is with the following code:
$Email = new CakeEmail();
$from = $this->request->data['Mail']['from'];
$to = ($this->request->data['Mail']['to']);
$subject = $this->request->data['Mail']['subject'];
$message = $this->request->data['Mail']['message'];
$Email->sender($from, 'TestName');
$Email->from($from)
->bcc($to)
->replyTo($from)
->subject($subject)
->send($message);
$this->Session->setFlash('On the way to recipient');
$this->redirect(array('action' => 'index'));
I have edited the Config/Email.php file inserting the MailGun API credentials etc.
What's possibly going on? Can you find out why this happens?
Thanks in advance!
(I was having the same errors you were)
The BasicTransport didn't have the right "pre-processing" nor the appropriate response handling.
I copied over the functionality from CurlTransport and it works for me now.
Specifically, we needed:
$post = array();
$post_preprocess = array_merge(
$email->getHeaders(array('from', 'sender', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc', 'subject')),
array(
'text' => $email->message(CakeEmail::MESSAGE_TEXT),
'html' => $email->message(CakeEmail::MESSAGE_HTML)
)
);
foreach ($post_preprocess as $k => $v) {
if (! empty($v)) {
$post[strtolower($k)] = $v;
}
}
and then:
$response = $http->post($url, $post, $request);
if ($response === false) {
throw new SocketException("Mailgun BasicTransport error, no response", 500);
}
$http_status = $response->code;
if ($http_status != 200) {
throw new SocketException("Mailgun request failed. Status: $http_status, Response: {$response->body}", 500);
}

Send Email in CakePHP afterSave

I'm trying to create an email component/model that will add an email to the database (with certain fields like, to, from, subject, message, created, modified, etc).
AFTER the data has been sucessfully saved (which it currently does), I'd like to actually send the message.
I figure this would be easiest with an afterSave() function, but I cannot get the email to send.
Here is some relevant code:
Email Model
<?php
class Email extends AppModel {
var $name = 'Email';
var $displayField = 'subject';
function afterSave() {
$this->Email->to = $this->data['Email']['email'];
$this->Email->subject = $this->data['Email']['subject'];
$this->Email->replyTo = $this->data['Email']['email'];
$this->Email->from = 'Private Message <' . $this->data['Email']['email'] . '>';
//$this->Email->template = 'simple_message';
$this->Email->send($this->data['Email']['email_text']);
}
}
add.ctp for email
<div class="universities form">
<?php echo $this->Form->create('Email');?>
<fieldset>
<legend><?php __('Add Email'); ?></legend>
<?php
echo $this->Form->input('subject');
echo $this->Form->input('email_text');
echo $this->Form->hidden('email', array('value' => $this->params['named']['contact_email']));
echo $this->Form->hidden('user_from', array('value' => $this->Session->read('User.id')));
echo $this->Form->hidden('created', array('value' => date("Y-m-d")));
echo $this->Form->hidden('modified', array('value' => date("Y-m-d")));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit', true));?>
</div>
Controller save code:
function add() {
if (!empty($this->data)) {
$this->Email->create();
// pr($this->data);
// die;
if ($this->Email->save($this->data)) {
$this->Session->setFlash(__('The email has been saved', true));
} else {
$this->Session->setFlash(__('The email could not be saved. Please, try again.', true));
}
}
}
Error I am getting on trying to send:
Fatal error: Call to undefined method stdClass::send() in /Users/[USER]/Sites/example_app/app/models/email.php on line 14
New Controller Code:
function add() {
if (!empty($this->data)) {
$this->Email->create();
// pr($this->data);
// die;
if ($this->Email->save($this->data)) {
$this->Session->setFlash(__('The email has been saved', true));
function _sendMail() {
$this->Email->to = $this->data['Email']['email'];
$this->Email->subject = $this->data['Email']['subject'];
$this->Email->replyTo = $this->data['Email']['email'];
$this->Email->from = 'Private Message <' . $this->data['Email']['email'] . '>';
$this->Email->sendAs = 'text'; //Send as 'html', 'text' or 'both' (default is 'text')
$email->send();
}
$this->_sendMail();
} else {
$this->Session->setFlash(__('The email could not be saved. Please, try again.', true));
}
}
}
components are meant to be used in a controller, not the model - so the cleanest way is to send the mail from controller when $this->Model->save() returns true.
Because you did name your Model "Email", i dont think you can use the component "Email" the standard way and need to load it manually:
In the controller (function add())
if ($this->Email->save($this->data)) {
// save was successfull
App::import('Component', 'Email');
$email = new EmailComponent();
$email->startup($this);
$email->from='joe#example.com';
$email->to = $this->data['Email']['email'];
$email->subject = $this->data['Email']['subject'];
$email->replyTo = $this->data['Email']['email'];
$email->from = 'Private Message <' . $this->data['Email']['email'] . '>';
$email->sendAs = 'text'; //Send as 'html', 'text' or 'both' (default is 'text')
$email->send();
$this->Session->setFlash(__('The email has been saved', true));
}
Nevertheless it is possible to send mails from the model, see the second answer of this (duplicate) thread:
How do I use the email component from a model in CakePHP?