Skip to content

Instantly share code, notes, and snippets.

@e1himself
Last active October 24, 2016 00:54
Show Gist options
  • Save e1himself/58c53aeef31a45345172 to your computer and use it in GitHub Desktop.
Save e1himself/58c53aeef31a45345172 to your computer and use it in GitHub Desktop.
SwiftMailer hack: RFC 6531 (SMTP Extension for Internationalized Email)
{
"require": {
"egulias/email-validator": "^2.0@dev"
}
}
<?php namespace App\Mailer\Swift\Mime;
use Swift_Encoder;
use Swift_Mime_Grammar;
use Swift_Mime_Header;
use Swift_Mime_HeaderEncoder;
use Swift_Mime_SimpleHeaderFactory;
/**
* Hack SwiftMailer SimpleHeaderFactory to support RFC 6531
*/
class HackedHeaderFactory extends Swift_Mime_SimpleHeaderFactory
{
/** The HeaderEncoder used by these headers */
private $_encoder;
/** The Encoder used by parameters */
private $_paramEncoder;
/** The Grammar */
private $_grammar;
/** The charset of created Headers */
private $_charset;
/**
* Creates a new SimpleHeaderFactory using $encoder and $paramEncoder.
*
* @param Swift_Mime_HeaderEncoder $encoder
* @param Swift_Encoder $paramEncoder
* @param Swift_Mime_Grammar $grammar
* @param string|null $charset
*/
public function __construct(Swift_Mime_HeaderEncoder $encoder, Swift_Encoder $paramEncoder, Swift_Mime_Grammar $grammar, $charset = null)
{
$this->_encoder = $encoder;
$this->_paramEncoder = $paramEncoder;
$this->_grammar = $grammar;
$this->_charset = $charset;
parent::__construct($encoder, $paramEncoder, $grammar, $charset);
}
/**
* Hacked method to use hacked MailboxHeader implementation.
* Create a new Mailbox Header with a list of $addresses.
*
* @param string $name
* @param array|string|null $addresses
*
* @return Swift_Mime_Header
*/
public function createMailboxHeader($name, $addresses = null)
{
$header = new InternationalMailboxHeader($name, $this->_encoder, $this->_grammar);
if (isset($addresses)) {
$header->setFieldBodyModel($addresses);
}
if (isset($this->_charset)) {
$header->setCharset($this->_charset);
}
return $header;
}
/**
* Notify this observer that the entity's charset has changed.
*
* @param string $charset
*/
public function charsetChanged($charset)
{
$this->_charset = $charset;
parent::charsetChanged($charset);
}
public function __clone()
{
$this->_encoder = clone $this->_encoder;
parent::__clone();
}
}
<?php namespace App\Mailer\Swift\Mime;
use Egulias\EmailValidator\EmailValidator;
use Swift_Mime_Headers_MailboxHeader;
use Swift_RfcComplianceException;
/**
* Support for RFC 6531.
*
* Hack to change behavior of \Swift_Mime_Headers_MailboxHeader::_assertValidAddress() method.
* As _assertValidAddress() is private, we need to hack callee method: normalizeMailboxes and call local
* _assertValidAddress() method version.
*
* @see \Swift_Mime_Headers_MailboxHeader::_assertValidAddress()
*/
class InternationalMailboxHeader extends Swift_Mime_Headers_MailboxHeader
{
protected function normalizeMailboxes(array $mailboxes)
{
$actualMailboxes = [];
foreach ($mailboxes as $key => $value) {
if (is_string($key)) {
//key is email addr
$address = $key;
$name = $value;
} else {
$address = $value;
$name = null;
}
$this->_assertValidAddress($address);
$actualMailboxes[$address] = $name;
}
return $actualMailboxes;
}
/**
* Throws an Exception if the address passed does not comply with RFC 2822.
*
* @param string $address
*
* @throws Swift_RfcComplianceException If invalid.
*/
private function _assertValidAddress($address)
{
$validator = new EmailValidator();
if ( ! $validator->isValid($address)) {
throw new Swift_RfcComplianceException(
'Address in mailbox given [' . $address . '] does not comply with RFC 2822, 3.6.2 and RFC 6531.'
);
}
}
}
<?php namespace App\Mailer;
use App\Mailer\Swift\Mime\HackedHeaderFactory;
class InternationalSwiftMailer extends Swift_Mailer
{
public function __construct(Swift_Transport $transport)
{
// hack swift mailer to support RFC 6531
Swift_DependencyContainer::getInstance()
->register('mime.headerfactory')
->asNewInstanceOf(HackedHeaderFactory::class)
->withDependencies([
'mime.qpheaderencoder',
'mime.rfc2231encoder',
'mime.grammar',
'properties.charset',
]);
parent::__construct($transport);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment