2021-08-18 02:16:45 +02:00
< ? php
/**
* This file was copied in from swiftmailer / swiftmailer v5 . 4.12 after it was removed from switftmailer v6
* It has been slightly modified to meet phpcs standards and to update method signatures to match the swiftmailer v6
*/
2023-02-28 23:36:08 +01:00
use SilverStripe\Dev\Deprecation ;
2021-08-18 02:16:45 +02:00
/*
* This file is part of SwiftMailer .
* ( c ) 2004 - 2009 Chris Corbyn
*
* For the full copyright and license information , please view the LICENSE file ( MIT )
* https :// github . com / swiftmailer / swiftmailer / blob / 181 b89f18a90f8925ef805f950d47a7190e9b950 / LICENSE
*/
/**
* Sends Messages using the mail () function .
*
* It is advised that users do not use this transport if at all possible
* since a number of plugin features cannot be used in conjunction with this
* transport due to the internal interface in PHP itself .
*
* The level of error reporting with this transport is incredibly weak , again
* due to limitations of PHP 's internal mail() function. You' ll get an
* all - or - nothing result from sending .
*
* @ author Chris Corbyn
*
2023-02-28 23:36:08 +01:00
* @ deprecated 4.12 . 0 Sending email using the mail () function is deprecated . Use sendmail or SMTP instead
2021-08-18 02:16:45 +02:00
*/
// @codingStandardsIgnoreStart
// ignore missing namespace
class Swift_Transport_MailTransport implements Swift_Transport
// @codingStandardsIgnoreEnd
{
/** Additional parameters to pass to mail() */
private $_extraParams = '-f%s' ;
/** The event dispatcher from the plugin API */
private $_eventDispatcher ;
/** An invoker that calls the mail() function */
private $_invoker ;
/**
* Create a new MailTransport with the $log .
*
* @ param Swift_Transport_MailInvoker $invoker
* @ param Swift_Events_EventDispatcher $eventDispatcher
*/
public function __construct ( Swift_Transport_MailInvoker $invoker , Swift_Events_EventDispatcher $eventDispatcher )
{
2023-02-28 23:36:08 +01:00
Deprecation :: withNoReplacement ( function () {
Deprecation :: notice ( '4.12.0' , 'Sending email using the mail() function is deprecated. Use sendmail or SMTP instead' , Deprecation :: SCOPE_CLASS );
});
2021-08-18 02:16:45 +02:00
// @trigger_error(sprintf('The %s class is deprecated since version 5.4.5 and will be removed in 6.0. Use the Sendmail or SMTP transport instead.', __CLASS__), E_USER_DEPRECATED);
$this -> _invoker = $invoker ;
$this -> _eventDispatcher = $eventDispatcher ;
}
/**
* Not used .
*/
public function isStarted ()
{
return false ;
}
/**
* Not used .
*/
public function start ()
{
}
/**
* Not used .
*/
public function stop ()
{
}
/**
* Set the additional parameters used on the mail () function .
*
* This string is formatted for sprintf () where % s is the sender address .
*
* @ param string $params
*
* @ return $this
*/
public function setExtraParams ( $params )
{
$this -> _extraParams = $params ;
return $this ;
}
/**
* Get the additional parameters used on the mail () function .
*
* This string is formatted for sprintf () where % s is the sender address .
*
* @ return string
*/
public function getExtraParams ()
{
return $this -> _extraParams ;
}
/**
* Send the given Message .
*
* Recipient / sender data will be retrieved from the Message API .
* The return value is the number of recipients who were accepted for delivery .
*
* @ param Swift_Mime_Message $message
* @ param string [] $failedRecipients An array of failures by - reference
*
* @ return int
*/
public function send ( Swift_Mime_SimpleMessage $message , & $failedRecipients = null )
{
$failedRecipients = ( array ) $failedRecipients ;
if ( $evt = $this -> _eventDispatcher -> createSendEvent ( $this , $message )) {
$this -> _eventDispatcher -> dispatchEvent ( $evt , 'beforeSendPerformed' );
if ( $evt -> bubbleCancelled ()) {
return 0 ;
}
}
$count = (
count (( array ) $message -> getTo ())
+ count (( array ) $message -> getCc ())
+ count (( array ) $message -> getBcc ())
);
$toHeader = $message -> getHeaders () -> get ( 'To' );
$subjectHeader = $message -> getHeaders () -> get ( 'Subject' );
if ( 0 === $count ) {
$this -> _throwException ( new Swift_TransportException ( 'Cannot send message without a recipient' ));
}
$to = $toHeader ? $toHeader -> getFieldBody () : '' ;
$subject = $subjectHeader ? $subjectHeader -> getFieldBody () : '' ;
$reversePath = $this -> _getReversePath ( $message );
// Remove headers that would otherwise be duplicated
$message -> getHeaders () -> remove ( 'To' );
$message -> getHeaders () -> remove ( 'Subject' );
$messageStr = $message -> toString ();
if ( $toHeader ) {
$message -> getHeaders () -> set ( $toHeader );
}
$message -> getHeaders () -> set ( $subjectHeader );
// Separate headers from body
2022-04-14 03:12:59 +02:00
if ( false !== $endHeaders = strpos ( $messageStr ? ? '' , " \r \n \r \n " )) {
$headers = substr ( $messageStr ? ? '' , 0 , $endHeaders ) . " \r \n " ; //Keep last EOL
$body = substr ( $messageStr ? ? '' , $endHeaders + 4 );
2021-08-18 02:16:45 +02:00
} else {
$headers = $messageStr . " \r \n " ;
$body = '' ;
}
unset ( $messageStr );
if ( " \r \n " != PHP_EOL ) {
// Non-windows (not using SMTP)
2022-04-14 03:12:59 +02:00
$headers = str_replace ( " \r \n " , PHP_EOL , $headers ? ? '' );
$subject = str_replace ( " \r \n " , PHP_EOL , $subject ? ? '' );
$body = str_replace ( " \r \n " , PHP_EOL , $body ? ? '' );
$to = str_replace ( " \r \n " , PHP_EOL , $to ? ? '' );
2021-08-18 02:16:45 +02:00
} else {
// Windows, using SMTP
2022-04-14 03:12:59 +02:00
$headers = str_replace ( " \r \n . " , " \r \n .. " , $headers ? ? '' );
$subject = str_replace ( " \r \n . " , " \r \n .. " , $subject ? ? '' );
$body = str_replace ( " \r \n . " , " \r \n .. " , $body ? ? '' );
$to = str_replace ( " \r \n . " , " \r \n .. " , $to ? ? '' );
2021-08-18 02:16:45 +02:00
}
if ( $this -> _invoker -> mail ( $to , $subject , $body , $headers , $this -> _formatExtraParams ( $this -> _extraParams , $reversePath ))) {
if ( $evt ) {
$evt -> setResult ( Swift_Events_SendEvent :: RESULT_SUCCESS );
$evt -> setFailedRecipients ( $failedRecipients );
$this -> _eventDispatcher -> dispatchEvent ( $evt , 'sendPerformed' );
}
} else {
$failedRecipients = array_merge (
$failedRecipients ,
array_keys (( array ) $message -> getTo ()),
array_keys (( array ) $message -> getCc ()),
array_keys (( array ) $message -> getBcc ())
);
if ( $evt ) {
$evt -> setResult ( Swift_Events_SendEvent :: RESULT_FAILED );
$evt -> setFailedRecipients ( $failedRecipients );
$this -> _eventDispatcher -> dispatchEvent ( $evt , 'sendPerformed' );
}
$message -> generateId ();
$count = 0 ;
}
return $count ;
}
/**
* Register a plugin .
*
* @ param Swift_Events_EventListener $plugin
*/
public function registerPlugin ( Swift_Events_EventListener $plugin )
{
$this -> _eventDispatcher -> bindEventListener ( $plugin );
}
/** Throw a TransportException, first sending it to any listeners */
protected function _throwException ( Swift_TransportException $e )
{
if ( $evt = $this -> _eventDispatcher -> createTransportExceptionEvent ( $this , $e )) {
$this -> _eventDispatcher -> dispatchEvent ( $evt , 'exceptionThrown' );
if ( ! $evt -> bubbleCancelled ()) {
throw $e ;
}
} else {
throw $e ;
}
}
/** Determine the best-use reverse path for this message */
private function _getReversePath ( Swift_Message $message )
{
$return = $message -> getReturnPath ();
// casting to array to fixed incorrect PHPDOC in Swift_Mime_SimpleMessage which specifies @string
$sender = ( array ) $message -> getSender ();
$from = $message -> getFrom ();
$path = null ;
if ( ! empty ( $return )) {
$path = $return ;
} elseif ( ! empty ( $sender )) {
2022-04-14 03:12:59 +02:00
$keys = array_keys ( $sender ? ? []);
2021-08-18 02:16:45 +02:00
$path = array_shift ( $keys );
} elseif ( ! empty ( $from )) {
2022-04-14 03:12:59 +02:00
$keys = array_keys ( $from ? ? []);
2021-08-18 02:16:45 +02:00
$path = array_shift ( $keys );
}
return $path ;
}
/**
* Fix CVE - 2016 - 10074 by disallowing potentially unsafe shell characters .
*
* Note that escapeshellarg and escapeshellcmd are inadequate for our purposes , especially on Windows .
*
* @ param string $string The string to be validated
*
* @ return bool
*/
private function _isShellSafe ( $string )
{
// Future-proof
2022-04-14 03:12:59 +02:00
if ( escapeshellcmd ( $string ? ? '' ) !== $string || ! in_array ( escapeshellarg ( $string ? ? '' ), [ " ' $string ' " , " \" $string\ " " ])) {
2021-08-18 02:16:45 +02:00
return false ;
}
2022-04-14 03:12:59 +02:00
$length = strlen ( $string ? ? '' );
2021-08-18 02:16:45 +02:00
for ( $i = 0 ; $i < $length ; ++ $i ) {
$c = $string [ $i ];
// All other characters have a special meaning in at least one common shell, including = and +.
// Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here.
// Note that this does permit non-Latin alphanumeric characters based on the current locale.
2022-04-14 03:12:59 +02:00
if ( ! ctype_alnum ( $c ) && strpos ( '@_-.' , $c ? ? '' ) === false ) {
2021-08-18 02:16:45 +02:00
return false ;
}
}
return true ;
}
/**
* Return php mail extra params to use for invoker -> mail .
*
* @ param $extraParams
* @ param $reversePath
*
* @ return string | null
*/
private function _formatExtraParams ( $extraParams , $reversePath )
{
2022-04-14 03:12:59 +02:00
if ( false !== strpos ( $extraParams ? ? '' , '-f%s' )) {
2021-08-18 02:16:45 +02:00
if ( empty ( $reversePath ) || false === $this -> _isShellSafe ( $reversePath )) {
2022-04-14 03:12:59 +02:00
$extraParams = str_replace ( '-f%s' , '' , $extraParams ? ? '' );
2021-08-18 02:16:45 +02:00
} else {
2022-04-14 03:12:59 +02:00
$extraParams = sprintf ( $extraParams ? ? '' , $reversePath );
2021-08-18 02:16:45 +02:00
}
}
return ! empty ( $extraParams ) ? $extraParams : null ;
}
/**
* { @ inheritdoc }
*/
public function ping ()
{
}
}