Use the symfony/mailer component without the symfony framework - php

I am working on a project that doesn't use any framework and I would like to use Symfony Mailer component to handle sending emails.
The installation part (composer require) was well handled and everything is included in my code without any error. However, I still have a problem : the documentation of the component seems to be written only for using it with the symfony framework.
Indeed, it is refering to autoloaded config files that o
bviously don't exist in my app.
This implementation seems to be very tricky and I was wondering if any of you guys already faced the same problem and what solution you came up with?

Your question made me wonder too how it is easy to send mail only with the mailer component.
So I created a new project from scratch and tried the simplest possible version following the mailer component documentation.
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mime\Email;
class MyMailer
{
// googleDns format is gmail+smtp://USERNAME:PASSWORD#default
public function __construct(private string $googleDsn)
{
}
public function send()
{
$template = file_get_contents('https://raw.githubusercontent.com/leemunroe/responsive-html-email-template/master/email.html');
$transport = Transport::fromDsn($this->googleDsn);
$mailer = new Mailer($transport);
$email = (new Email())
->from('mygmail#address.com')
->to('thedelivery#gmail.com')
->subject('Time for Symfony Mailer!')
->html($template);
$mailer->send($email);
}
}
And I successfully received my mail. I send my mail with gmail, for your information. Transport class should do the sending job for you, but if not you can have a look to inside vendor/symfony/mailer/Transport folder

Related

How can i send Mails within my Typo3 extension

I get results from a jQuery Survey in JSON within my Typo3 Extension. Now I want to send these results with the Typo3 Mail API to my Inbox. According to the documentations following shoud do the work
$mail = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
$mail->from(new \Symfony\Component\Mime\Address('john.doe#example.org', 'John Doe'));
$mail->to(
new \Symfony\Component\Mime\Address('receiver#example.com', 'Max Mustermann'),
new \Symfony\Component\Mime\Address('other#example.net')
);
$mail->subject('Your subject');
$mail->text('Here is the message itself');
$mail->html('<p>Here is the message itself</p>');
$mail->attachFromPath('/path/to/my-document.pdf');
$mail->send();
so my code looks like this:
namespace TYPO3\CMS\Core\Mail;
if (!file_exists( dirname(__DIR__, 2).'/vendor/autoload.php' )) {
throw new \RuntimeException(
'Could not find vendor/autoload.php, make sure you ran composer.'
);
} else {
require dirname(__DIR__, 2).'/vendor/autoload.php';
}
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MailUtility;
$mail = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
$mail->from(new \Symfony\Component\Mime\Address('john.doe#example.org', 'John Doe'));
$mail->to(
new \Symfony\Component\Mime\Address('receiver#example.com', 'Max Mustermann'),
new \Symfony\Component\Mime\Address('other#example.net')
);
$mail->subject('Your subject');
$mail->text('Here is the message itself');
$mail->html('<p>Here is the message itself</p>');
$mail->attachFromPath('/path/to/my-document.pdf');
$mail->send();
I just getting errors. Does anyone know how i can achieve this?
Following error i get
Notice: Undefined index: TYPO3_CONF_VARS in /var/www/html/local_packages/ext_sitepackage/public/typo3/sysext/core/Classes/Mail/Mailer.php on line 170
Apparently this is the same question as you already posted here.
This will never work like this. You need to either build a fully fledged TYPO3 extension or a standalone application using symfony/mailer directly.
Your script is missing $GLOBALS['TYPO3_CONF_VARS']['MAIL'].
You stumble over the fact that you're programming past the conventions and requirements of TYPO3, but then you're surprised that the framework's functions don't work...
Create a middleware in your sitepackage, and register it correctly. Check for a special route and let the rest run. If handling, use the code there.
You need to run the mailing code in a (full) bootstrapped Typo3 context:
in a middleware
extbase plugin registered with pageNum directly
Your pasted code looks weired in a lot of ways. Just putting a file in a extension folder do not mean that is correctly a typo3 extension.
Maybe you want to start and have a proper extension setup first, with the corresponding readings:
ext_emconf.php / composer.json as a minimum
code files in 'Classes/' subfolders
then decide with which way you want to handle the "ajax" call and send the email, there are several possibilities (as already mentioned above) .. than read and implement that solution the proper and correct way.
Just having a php file directly referenced/called and just bootstpping the composer autoloader do not and never will be bootstrapping Typo3 with all needed configuration bootstrapping (gathering confings from extensions, Local/AdditionalConfiguration, siteconfig and and and).
And generally a package/extension should have a namespace something like following (as a convention):
<extensionname.....
an thus registered as psr-4 autoloading in your extension composer.json ..
Starting to implement the peaces to simulate a Typo3 bootstpraping in that file is not good and will make a lot of headache ... it's easier to have a proper sitepacke/extension structure.

Using mandrill as a mail transport layer in Zend 1

Currently, I am trying to integrate Mandrill functionality into a Zend 1 legacy application, and I'm not too familiar with the way they handle mail transports. Currently, I'm including the mandrill/mandrill composer package and attempting to follow the pattern of the other transport layers included in Zend 1:
class MandrillTransport extends Zend_Mail_Transport_Abstract
{
private $message = array();
protected function _formatMandrillArray()
{
//grab all the relavant data from the pre-existing mail object and put it into a Mandrill-friendly array
}
protected function _getAttachments() {
//loop through and format attachments that get added to array
}
protected function _sendMail()
{
//send Mandrill message with included data
$mandrill = new Mandrill(Zend::registry('config')->mandrill->APIKey);
$mandrill->messages->send($this->message);
}
public function send() {
//Format all the stuff and send it
}
}
And then I'm assuming I can use this in the "send()" function, which appears to take the transport as a parameter:
//TODO: Put this in a better spot
require_once __DIR__ . "/ZendFramework/Zend/Mail/Transport/MandrillTransport.php";
$tr = new MandrillTransport();
$email->send($tr);
Am I on the right track here? The reason I'd like to do this as a transport layer rather than just ripping out the existing code and replacing it with Mandrill is because there are a lot of different business processes sending mail, and we'd like to be able to pick and choose which is using the Sendmail transport and which are using Mandrill.
Thanks in advance,
-Chris

Laravel 5: Signing e-mail with DKIM

In my project I'm trying to send e-mail through my own SMTP server using Laravel 5. I have everything set up correctly using the SMTP driver and I'm managing to send and receive e-mail fine.
I want to get set up using DKIM. I've set up my public key and made it available in my DNS and I have a private key ready to start signing my messages.
However, I can't find any documentation on how to set up DKIM signing using Laravel/Swift Mailer. I've managed to sign my e-mails with DKIM before in another non-Laravel project that used PHPMailer but can't find any way of doing it here. I've had a browse through Illuminate\Mail\Message and Illuminte\Mail\Mailer but can't find anything relevant.
Does anyone know how to do this?
Current example code:
public function handle(UserWasRegistered $event)
{
$user = $event->getUser();
$this->mailer->send(['emails.users.welcome.html', 'emails.users.welcome.text'], ['user' => $user], function($message) use($user) {
$message->subject('Welcome to XXXXXX');
$message->to($user->email);
});
}
Ideally, I would like to be able to provide my DKIM private key in the config somewhere and have Laravel/Swift Mailer (Or write some code once) sign my messages for me.
Cheers
I wrote decorator of MailServiceProvider for Laravel 5 that provides ability to sign outgoing messages with DKIM:
https://github.com/vitalybaev/laravel5-dkim
You have to extend Laravel Mailer and mail service provider. Default laravel mailer using new Swift_Message class not Swift_SignedMessage thats why you don't have options for signing.
Here is a package for laravel 4.

Laravel Mail Queue: change transport on fly

I'm trying to use different SMTP configuration for each user of my application. So, using Swift_SmtpTransport set a new transport instance, assign it to Swift_Mailer and then assign it to Laravel Mailer.
Below the full snippet:
$transport = Swift_SmtpTransport::newInstance($mailConfig['smtp_host'], $mailConfig['smtp_port'], 'ssl');
$transport->setUsername($mailConfig['smtp_user']);
$transport->setPassword($mailConfig['smtp_pass']);
$smtp = new Swift_Mailer($transport);
Mail::setSwiftMailer($smtp);
Mail::queue(....);
Messages are added to the queue but never dispatched. I guess that since the "real" send is asyncronous it uses default SMTP configuration, and not the transport set before Mail::queue().
So, the question is: how to change mail transport when using Mail::queue()?
Instead of using Mail::queue, try creating a queue job class that handles sending the email. That way the transport switching code will be executed when the job is processed.
The Job Class Structure Documentation actually uses a mailing scenario as an example, which receives a Mailer instance that you can manipulate. Just use your code in the class's handle method:
public function handle(Mailer $mailer)
{
$transport = Swift_SmtpTransport::newInstance($mailConfig['smtp_host'], $mailConfig['smtp_port'], 'ssl');
$transport->setUsername($mailConfig['smtp_user']);
$transport->setPassword($mailConfig['smtp_pass']);
$smtp = new Swift_Mailer($transport);
$mailer->setSwiftMailer($smtp);
$mailer->send('viewname', ['data'], function ($m) {
//
});
}
Best way from notifications since Laravel 7 : https://laravel.com/docs/9.x/notifications#customizing-the-mailer
public function toMail($notifiable)
{
return (new MailMessage)
->mailer('postmark')
->line('...');
}
I am working on a test where I need 300 different mailers (to fill Mailtrap Enterprise) so having 300 different configs was not good for me.
I am posting the simple solution I found looking at Illuminate\Mail\Mailer class
$transport = Transport::fromDsn('smtp://user:pass#host:port');
Mail::setSymfonyTransport($transport);
Mail::to('to#email.com')
->send((new LaravelMail())
->subject('Subject')
);
Having this you can do some string manipulation to switch between transport configurations

Laravel pretend is not showing cc mail address

I had change pretend as true in mail config. please check http://laravel.com/docs/4.2/mail#mail-and-local-development
Now log is showing to address like this.
[2014-11-22 17:12:49] production.INFO: Pretending to mail message to: dinukathilanga#gmail.com, bbelekkaya#gmail.com [] []
But i need debug cc emails also. How can i do it?
This is my code.
Mail::send($view, $data, function($message) use ($to, $cc, $subject)
{
foreach ($to as $toUser) {
$message->to($toUser['email'], $toUser['first_name'] . ' ' . $toUser['last_name']);
}
foreach ($cc as $ccUser) {
$message->cc($ccUser['email'], $ccUser['first_name'] . ' ' . $ccUser['last_name']);
}
$message->subject($subject);
});
Allow me to be frank here. I am new to Laravel, but I will try my best to explain this.
I do know how to debug email platforms though, the easiest process is by doing it through C.
I will try to be succint as possible.
Firstly, try using the laravel-debugbar (the latest version is 4).
This is an application that is capable of filtering the PHP Debug Bar.
By using this application you will be able to attach and edit output functions (here is the link for more information: Debug bar.
If this won't work, try debugging through C.
Fristly, you will compile the C program by inserting the debug option, option -g.
Afterwards, you'll launch the gdb into the platform.
Thirdly, you'll break the point in the C program, specifically, insert the break line_number function.
After that, you'll print the variable values in the gdp debugger.
For instance, you'll type commands such as print j and (gdp) p i (I will post the website where I've got this information from; it will give you a more broader walkthrough).
There are various operation for this process.
I strongly advise you visiting:Debug C program using gdb. Hope this helped.
Create a new class named ExtendedMailer for the sake of this example and save the file somewhere the autoloader is able to find it. Depending on where you put the file, you may need to run composer dump-autoload once you've saved it.
<?php
use Illuminate\Mail\Mailer;
class ExtendedMailer extends Mailer
{
protected function logMessage($message)
{
parent::logMessage($message);
$emails = implode(', ', array_keys((array) $message->getCc()));
$this->logger->info("Pretending to mail message to: {$emails}");
}
}
Create a new service provider, somewhere your application is able to load classes. As above, you may need to run composer dump-autoload
The below code simply extends the original MailServiceProvider but allows us to bind a different class to in the IoC, you'll notice the new ExtendedMailer; the class we created earlier. Obviously if you namespaced the class, reflect that change here.
<?php
use Illuminate\Mail\MailServiceProvider;
class ExtendedMailServiceProvider extends MailServiceProvider
{
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
$me = $this;
$this->app->bindShared('mailer', function($app) use ($me)
{
$me->registerSwiftMailer();
// Once we have create the mailer instance, we will set a container instance
// on the mailer. This allows us to resolve mailer classes via containers
// for maximum testability on said classes instead of passing Closures.
$mailer = new ExtendedMailer(
$app['view'], $app['swift.mailer'], $app['events']
);
$this->setMailerDependencies($mailer, $app);
// If a "from" address is set, we will set it on the mailer so that all mail
// messages sent by the applications will utilize the same "from" address
// on each one, which makes the developer's life a lot more convenient.
$from = $app['config']['mail.from'];
if (is_array($from) && isset($from['address']))
{
$mailer->alwaysFrom($from['address'], $from['name']);
}
// Here we will determine if the mailer should be in "pretend" mode for this
// environment, which will simply write out e-mail to the logs instead of
// sending it over the web, which is useful for local dev environments.
$pretend = $app['config']->get('mail.pretend', false);
$mailer->pretend($pretend);
return $mailer;
});
}
}
In your config/app.php, you'll find a line which looks like
'Illuminate\Mail\MailServiceProvider',
You'll need to comment it out and add a line as below
'ExtendedMailServiceProvider',
What this does is replace the mailer which Laravel knows about with the one you've just created. The one you've just created is the same as the default one as it merely extends it, and adds functionality to the logMessage function.

Categories