актуально для версий до коммита от третьего сентября. В версиях новее, это делается приблизительно так:
$mailer->getTransport()->setStreamOptions([#...]);
спасибо @lynicidn
Я уже давно ничего не писал... но наш бессменный лидер - Алексей aka @Butochnikov угрозами и шантажом убедил меня написать хоть небольшую заметку... Держите, други ))
Сегодня передо мной встала задача, рассылать e-mail по smtp через серевер с самоподписанным сертификатом SSL.
SwiftMailer категорически отказывался работать с таким сервером, выдавая что-то в духе
SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
и еще какую-то ересь...
Недолгое гуление проказало, что проблема известная, и легко решается добавлением пары строк в... исходный код!
Дело в том, что массив с опциями объявляется непосредственно в коде StreamBuffer;
И никакого апи для влияния на эти опции в SwiftMailer
'е просто не предусмотрено.
Вот там-то и нужно внедрить пару этих волшебных сток:
$options = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
),
);
Окей, дупустим мы внедрили этот код прямо куда надо, и все работает.
Однако, сразу ясно, что первый же composer update
снесет всё к чертвовой бабушке...
Разумеется нужно расширять класс. Вот только как его подсунуть назад в SM?
Прогулка по деревьям классов привела меня в святая святых SwiftMailer'а - Swift_DependencyContainer;
По методу getInstance()
сразу становится ясно, что это классический случай singleton - а значит бегать по провайдерам в поисках инициализации не придется.
// выполнять, само собой, после загрузки провайдеров.
dd(Swift_DependencyContainer::getInstance());
показало, что наш замечательный StreamBuffer
скрывается в этом самом контейнере за ключом transport.buffer
;
и имеет в зависимостях transport.replacementfactory
, после десяти минут изучения механики контейнера, я пришел к выводу, что заменить буффер в контeйнере не сложно:
Swift_DependencyContainer::getInstance()
->register('transport.buffer')
->asNewInstanceOf(InsecureStreamBuffer::class)
->addConstructorLookup('transport.replacementfactory');
// Где InSecureStreamBuffer - это расширенный StreamBuffer
С самим же InsecureStreamBuffer пришлось повозится чуть дольше. Сначала я пытался не перекрывать все методы наледуемого класса, а отделаться мимнимумом. Но ввиду того, что они почти все приватные, пришлось таки их переопределить, а к ним в довесок еще и все приватные свойства. В итоге, получился точно такой же класс, но с той самой парой строк, которые отключают проверку сертификата.
$options = array(
'ssl' => array(
'verify_peer' => env('MAIL_VERIFY_PEER', true),
'verify_peer_name' => env('MAIL_VERIFY_PEER_NAME', true),
),
);
Здесь я добавил подключение этих параметров из .env файла, чтобы можно было удобно настроить "в случае чего".
Покончив с кодом я зашел на свой сайт, спокойно зарегистрировался, потом перешел на сайт своей почты, и уже через минуту, довльный - наблюдал заветное письмо в папке "Спам" XD
Вот такая история ))
https://github.com/swiftmailer/swiftmailer/blob/5.x/lib/classes/Swift/Transport/StreamBuffer.php#L53
https://github.com/swiftmailer/swiftmailer/blob/5.x/lib/classes/Swift/Transport/StreamBuffer.php#L264
отсыпь