How to style (HTML) Monolog emails sent via Symfony Mailer - swiftmailer

Due to depreciation, I'm converting my Monolog email logging from Swiftmailer to Symfony Mailer (as recommended here).
I have successfully completed the conversion and am receiving the emails.
However, with Swift Mailer all Monolog emails were nicely formatted (see example).
With Symfony Mailer, I only have a text version of the email.
Is there a way to get similar HTML output with Symfony Mailer?
By the way, I'm only using "symfony/mailer" and "symfony/monolog-bridge", not the full framework
My code:
$logger = new Logger('My Logger');
$transport = Transport::fromDsn('MYDSN');
$mailer = new Mailer($transport);
$message = (new Email())
->from(new Address('from#example.com', 'John Doe'))
->to(new Address('to#example.com', 'Jane Doe'))
->subject('My Subject');
$logger->pushHandler(
new MailerHandler(
$mailer,
$message,
Logger::ERROR
)
);

Got it working, I had to add an HtmlFormatter (this was not necessary with Swift Mailer):
$logger->pushHandler(
(new MailerHandler(
$mailer,
$message,
Logger::ERROR
)->setFormatter(new HtmlFormatter())
);

Related

Laravel send mail

I'm trying to send an email and I get this error
Typed property Symfony\Component\Mailer\Transport\AbstractTransport::$dispatcher must not be accessed before initialization
use Illuminate\Support\Facades\Mail; use App\Mail\Signups as MailSignup;
Route::get('/test_mail', function (){
Mail::to('test#mail.com')->send(new MailSignup(array('field' => null), 'Test subject'));
});
This is the stack trace, it uses just Laravel packages, no custom code beside the route.
It broke after I updated with composer update and composer upgrade
You need to initialize MailSignup before calling send() in route
Route::get('/test_mail', function (){
$mailsignup = new MailSignup(array('field' => null), 'Test subject');
Mail::to('test#mail.com')->send($mailsignup);
});

Laravel + Twilio SDK: Class 'Services_Twilio_Twiml' not found

I new to Laravel and newer to Twilio.
I have a working laravel 5.4 server installed w/ Composer. I installed the Twilio SDK in the root directory of my Twilio project w/ Composer.
I receive the following error when loading some basic code from the "Getting Started with Twilio and the Laravel framework for PHP" tutorial.
Class 'Services_Twilio_Twiml' not found
I really don't know what to do now.
Does anyone have any suggestions?
Route::match(array('GET', 'POST'), '/incoming', function()
{
$twiml = new Services_Twilio_Twiml();
$twiml->say('Hello - your app just answered the phone.
Neat, eh?', array('voice' => 'alice'));
$response = Response::make($twiml, 200);
$response->header('Content-Type', 'text/xml');
return $response;
});
Twilio developer evangelist here.
I think you're trying to call the old version of the Twilio PHP library there.
To use TwiML with version 5 of the PHP library you would use the Twilio\Twiml object, like this:
Route::match(array('GET', 'POST'), '/incoming', function()
{
$twiml = new Twilio\Twiml;
$twiml->say('Hello - your app just answered the phone.
Neat, eh?', array('voice' => 'alice'));
$response = Response::make($twiml, 200);
$response->header('Content-Type', 'text/xml');
return $response;
});
There are a bunch of Twilio and Laravel tutorials available here that might help you too.
Let me know if that helps at all.

How to set dynamic SMTP data in Laravel 5.4 for queued emails?

In my application each user can use his own SMTP server. Therefor the config must be provided. I'm using Laravel Notifications to send the emails. If I'm using no queue (that means sync), there is no problem.
I made a CustomNotifiable Trait:
config([
'mail.host' => $setting->smtp_host,
'mail.port' => $setting->smtp_port,
'mail.username' => $setting->smtp_username,
'mail.password' => $setting->smtp_password,
'mail.encryption' => $setting->smtp_encryption,
'mail.from.address' => $setting->smtp_from_address,
'mail.from.name' => $setting->smtp_from_name,
]);
(new \Illuminate\Mail\MailServiceProvider(app()))->register();
After that, I restore the original config:
config([
'mail' => $originalMailConfig
]);
(new \Illuminate\Mail\MailServiceProvider(app()))->register();
No problem until now.
But if it's queued, just the first config after starting the queue worker will be taken for all further emails, even if any other SMTP config is provided. The default config from config/mail.php will be overridden. But this only works the first time.
I've made in the AppServiceProvider::boot method (the SMTP config is stored at the notification):
Queue::before(function (JobProcessing $event) {
// Handle queued notifications before they get executed
if (isset($event->job->payload()['data']['command']))
{
$payload = $event->job->payload();
$command = unserialize($payload['data']['command']);
// setting dynamic SMTP data if required
if (isset($command->notification->setting))
{
config([
'mail.host' => $command->notification->setting->smtp_host,
'mail.port' => $command->notification->setting->smtp_port,
'mail.username' => $command->notification->setting->smtp_username,
'mail.password' => $command->notification->setting->smtp_password,
'mail.encryption' => $command->notification->setting->smtp_encryption,
'mail.from.address' => $command->notification->setting->smtp_from_address,
'mail.from.name' => $command->notification->setting->smtp_from_name,
]);
(new \Illuminate\Mail\MailServiceProvider(app()))->register();
}
}
});
Of course, the original config get restored:
Queue::after(function (JobProcessed $event) use ($originalMailConfig) {
$payload = $event->job->payload();
$command = unserialize($payload['data']['command']);
// restore global mail settings
if (isset($command->notification->setting))
{
config([
'mail' => $originalMailConfig
]);
(new \Illuminate\Mail\MailServiceProvider(app()))->register();
}
});
It seems, as the Swift Mailer has a cache or something like that. I registered a new MailServiceProvider, which should simply replace the old one. So if I set the config with the new SMTP data, the new registered provider should take them. Logging the config shows even in the TransportManager, that the correct SMTP data were set, right before sending the mail, but the mail was sent with the first set config.
I found this thread and tried the linked solution, but with the same result: How to set dynamic SMTP details laravel
So I need a way to override the Services / ServiceProvider / SMTP config. Even if the Supervisor restarts the queue, there is a chance that multiple emails with different configs should be send at the same time.
In Laravel 5.4+, as I see that the Mailer Class is a singleton that hold a MailTransport Class, which is responsible for the config of SMTP mail and is a singleton,too; I just have to override the config using the following approach:
First, I setup a trait so I can just turn this feature on some Mails:
trait MailSenderChangeable
{
/**
* #param array $settings
*/
public function changeMailSender($settings)
{
$mailTransport = app()->make('mailer')->getSwiftMailer()->getTransport();
if ($mailTransport instanceof \Swift_SmtpTransport) {
/** #var \Swift_SmtpTransport $mailTransport */
$mailTransport->setUsername($settings['email']);
$mailTransport->setPassword($settings['password']);
}
}
}
Then, in the build() method of your mail class, you can utilize the above trait and call:
$this->changeMailSender([
'email'=>$this->company->email,
'password'=>$this->company->email_password,
]);
Boom, let the Laravel do the rest.
After a lot of researching I stumbled upon the different queue commands. I tried queue:listen (which is not described in the Laravel 5.4 docs) instead of queue:work and the problems are gone.
Of course, this doesn't really explain the described behavior, but fortunately it doesn't matter, because I can live with this solution/workaround.
Another strange behavior is, that from time to time the queue worker throws an exception because the database was locked. No idea, when or why this happened.
This post explained a little bit, why things can happen: What is the difference between queue:work --daemon and queue:listen
In a nutshell, queue:listen solved my problem and another very strange db lock problem as well.

magento pass variable from controller to another model

I want to send custom mail through smtp.For which I installed http://www.magentocommerce.com/magento-connect/aschroder-com-smtp-pro-email-free-and-easy-magento-emailing-for-smtp-gmail-or-google-apps-email.html.
Which works properly for every mail provided by magento as default.
Now since the admin is having mail Id of google apps , my custom mail is not received by admin.So for this reason I want to Integrate my controller with the sending mail function of ashrodder extension.
My Controller code:
$frm = 'mail#domainname.com';
$to = 'admin#domainname.com';
$subject = "UPDATE";
$mail = new Zend_Mail('utf-8');
$mail->setBodyHtml($message)
->setFrom($frm, 'Admin')
->addTo($to, 'Site Admin')
->setSubject($subject);
try {
$mail->send();
Mage::getSingleton('core/session')->addSuccess('Mail sent successfully.');
}
catch(Exception $e) {
Mage::getSingleton('core/session')->addError('Unable to send email.');
}
My question is simple : How should I pass [to,from,body] variable to any other model/controller ?
Please Help .Thanks in Advance
I think overriding the extensions controller would be the best solution.Check this link How to extend a controller

CakePHP email not sending but showing in debug mode

My CakePHP should send an email when a button is clicked, however it doesn't. Also, the email will be displayed as a flash message if I run it in debug mode: ($this->Email->delivery = 'debug';).
Note: Email is set up to set up to use PHP mail() function.
Code to call the email function:
$this->_sendUpdateEmail( $this->Auth->user('id'), $about_id );
Email function
function _sendUpdateEmail($from_user_id, $about_id) {
$fromUser = $this->User->read(null, $from_user_id);
$users = $this->User->find('all', array(
'conditions' => array('User.distribution =' => 1)
));
# loop to send email to all users who are marked as on the distribution list
for($i = 0, $size = sizeof($users); $i < $size; ++$i) {
$user = $users[$i]['User'];
$this->Email->from = $fromUser['User']['email'];
$this->Email->replyTo = $fromUser['User']['email'];
$this->Email->to = $user['email'];
$this->Email->subject = 'Test email';
$this->Email->template = 'update';
$this->Email->sendAs = 'both'; // both = html and text
$this->set('user', $user);
$this->set('about', $about_id);
$this->Email->send();
$this->Email->reset();
}
}
Any ideas as to why the emails show in debug mode but won't actually send?
I think the reason why my emails were not sending was because there was no mail server configured on the web server my CakePHP was running on so there was no way to route the emails. However, this meant they would show up in the debug because they were generated successfully, just not sent.
In the end, I ended up using my company's Exchange mail server using the SMTP settings.
Code to use SMTP to send CakePHP emails
$this->Email->smtpOptions = array(
'port'=>'25',
'timeout'=>'30',
'host' => '192.168.0.244',
);
// Other email code here, e.g. from and to etc...
$this->Email->delivery = 'smtp';
I think the issue here is that mail server is not set right Linux comes built in with mail sending functionality but not windows (no idea on mac). look into smtp options as u can easily setup smtp email sender on Windows
Setting up smtp windows - http://publib.boulder.ibm.com/infocenter/cqhelp/v7r1m2/index.jsp?topic=/com.ibm.rational.clearquest.webadmin.doc/topics/c_config_email_smtp_win.htm
and
http://book.cakephp.org/view/1290/Sending-A-Message-Using-SMTP

Resources