[ Index ]

MailPress 7.2

[ Index ]     [ Classes ]     [ Functions ]     [ Variables ]     [ Constants ]     [ Statistics ]    

title

Body

[close]

/mp-includes/composer/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/ -> EsmtpTransport.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of SwiftMailer.
   5   * (c) 2004-2009 Chris Corbyn
   6   *
   7   * For the full copyright and license information, please view the LICENSE
   8   * file that was distributed with this source code.
   9   */
  10  
  11  /**
  12   * Sends Messages over SMTP with ESMTP support.
  13   *
  14   * @author Chris Corbyn
  15   */
  16  class Swift_Transport_EsmtpTransport extends Swift_Transport_AbstractSmtpTransport implements Swift_Transport_SmtpAgent
  17  {
  18      /**
  19       * ESMTP extension handlers.
  20       *
  21       * @var Swift_Transport_EsmtpHandler[]
  22       */
  23      private $handlers = [];
  24  
  25      /**
  26       * ESMTP capabilities.
  27       *
  28       * @var string[]
  29       */
  30      private $capabilities = [];
  31  
  32      /**
  33       * Connection buffer parameters.
  34       *
  35       * @var array
  36       */
  37      private $params = [
  38          'protocol' => 'tcp',
  39          'host' => 'localhost',
  40          'port' => 25,
  41          'timeout' => 30,
  42          'blocking' => 1,
  43          'tls' => false,
  44          'type' => Swift_Transport_IoBuffer::TYPE_SOCKET,
  45          'stream_context_options' => [],
  46          ];
  47  
  48      /**
  49       * Creates a new EsmtpTransport using the given I/O buffer.
  50       *
  51       * @param Swift_Transport_EsmtpHandler[] $extensionHandlers
  52       * @param string                         $localDomain
  53       */
  54      public function __construct(Swift_Transport_IoBuffer $buf, array $extensionHandlers, Swift_Events_EventDispatcher $dispatcher, $localDomain = '127.0.0.1', Swift_AddressEncoder $addressEncoder = null)
  55      {
  56          parent::__construct($buf, $dispatcher, $localDomain, $addressEncoder);
  57          $this->setExtensionHandlers($extensionHandlers);
  58      }
  59  
  60      /**
  61       * Set the host to connect to.
  62       *
  63       * Literal IPv6 addresses should be wrapped in square brackets.
  64       *
  65       * @param string $host
  66       *
  67       * @return $this
  68       */
  69      public function setHost($host)
  70      {
  71          $this->params['host'] = $host;
  72  
  73          return $this;
  74      }
  75  
  76      /**
  77       * Get the host to connect to.
  78       *
  79       * @return string
  80       */
  81      public function getHost()
  82      {
  83          return $this->params['host'];
  84      }
  85  
  86      /**
  87       * Set the port to connect to.
  88       *
  89       * @param int $port
  90       *
  91       * @return $this
  92       */
  93      public function setPort($port)
  94      {
  95          $this->params['port'] = (int) $port;
  96  
  97          return $this;
  98      }
  99  
 100      /**
 101       * Get the port to connect to.
 102       *
 103       * @return int
 104       */
 105      public function getPort()
 106      {
 107          return $this->params['port'];
 108      }
 109  
 110      /**
 111       * Set the connection timeout.
 112       *
 113       * @param int $timeout seconds
 114       *
 115       * @return $this
 116       */
 117      public function setTimeout($timeout)
 118      {
 119          $this->params['timeout'] = (int) $timeout;
 120          $this->buffer->setParam('timeout', (int) $timeout);
 121  
 122          return $this;
 123      }
 124  
 125      /**
 126       * Get the connection timeout.
 127       *
 128       * @return int
 129       */
 130      public function getTimeout()
 131      {
 132          return $this->params['timeout'];
 133      }
 134  
 135      /**
 136       * Set the encryption type (tls or ssl).
 137       *
 138       * @param string $encryption
 139       *
 140       * @return $this
 141       */
 142      public function setEncryption($encryption)
 143      {
 144          $encryption = strtolower($encryption);
 145          if ('tls' == $encryption) {
 146              $this->params['protocol'] = 'tcp';
 147              $this->params['tls'] = true;
 148          } else {
 149              $this->params['protocol'] = $encryption;
 150              $this->params['tls'] = false;
 151          }
 152  
 153          return $this;
 154      }
 155  
 156      /**
 157       * Get the encryption type.
 158       *
 159       * @return string
 160       */
 161      public function getEncryption()
 162      {
 163          return $this->params['tls'] ? 'tls' : $this->params['protocol'];
 164      }
 165  
 166      /**
 167       * Sets the stream context options.
 168       *
 169       * @param array $options
 170       *
 171       * @return $this
 172       */
 173      public function setStreamOptions($options)
 174      {
 175          $this->params['stream_context_options'] = $options;
 176  
 177          return $this;
 178      }
 179  
 180      /**
 181       * Returns the stream context options.
 182       *
 183       * @return array
 184       */
 185      public function getStreamOptions()
 186      {
 187          return $this->params['stream_context_options'];
 188      }
 189  
 190      /**
 191       * Sets the source IP.
 192       *
 193       * IPv6 addresses should be wrapped in square brackets.
 194       *
 195       * @param string $source
 196       *
 197       * @return $this
 198       */
 199      public function setSourceIp($source)
 200      {
 201          $this->params['sourceIp'] = $source;
 202  
 203          return $this;
 204      }
 205  
 206      /**
 207       * Returns the IP used to connect to the destination.
 208       *
 209       * @return string
 210       */
 211      public function getSourceIp()
 212      {
 213          return $this->params['sourceIp'] ?? null;
 214      }
 215  
 216      /**
 217       * Sets whether SMTP pipelining is enabled.
 218       *
 219       * By default, support is auto-detected using the PIPELINING SMTP extension.
 220       * Use this function to override that in the unlikely event of compatibility
 221       * issues.
 222       *
 223       * @param bool $enabled
 224       *
 225       * @return $this
 226       */
 227      public function setPipelining($enabled)
 228      {
 229          $this->pipelining = $enabled;
 230  
 231          return $this;
 232      }
 233  
 234      /**
 235       * Returns whether SMTP pipelining is enabled.
 236       *
 237       * @return bool|null a boolean if pipelining is explicitly enabled or disabled,
 238       *                   or null if support is auto-detected.
 239       */
 240      public function getPipelining()
 241      {
 242          return $this->pipelining;
 243      }
 244  
 245      /**
 246       * Set ESMTP extension handlers.
 247       *
 248       * @param Swift_Transport_EsmtpHandler[] $handlers
 249       *
 250       * @return $this
 251       */
 252      public function setExtensionHandlers(array $handlers)
 253      {
 254          $assoc = [];
 255          foreach ($handlers as $handler) {
 256              $assoc[$handler->getHandledKeyword()] = $handler;
 257          }
 258          uasort($assoc, function ($a, $b) {
 259              return $a->getPriorityOver($b->getHandledKeyword());
 260          });
 261          $this->handlers = $assoc;
 262          $this->setHandlerParams();
 263  
 264          return $this;
 265      }
 266  
 267      /**
 268       * Get ESMTP extension handlers.
 269       *
 270       * @return Swift_Transport_EsmtpHandler[]
 271       */
 272      public function getExtensionHandlers()
 273      {
 274          return array_values($this->handlers);
 275      }
 276  
 277      /**
 278       * Run a command against the buffer, expecting the given response codes.
 279       *
 280       * If no response codes are given, the response will not be validated.
 281       * If codes are given, an exception will be thrown on an invalid response.
 282       *
 283       * @param string   $command
 284       * @param int[]    $codes
 285       * @param string[] $failures An array of failures by-reference
 286       * @param bool     $pipeline Do not wait for response
 287       * @param string   $address  The address, if command is RCPT TO.
 288       *
 289       * @return string|null The server response, or null if pipelining is enabled
 290       */
 291      public function executeCommand($command, $codes = [], &$failures = null, $pipeline = false, $address = null)
 292      {
 293          $failures = (array) $failures;
 294          $stopSignal = false;
 295          $response = null;
 296          foreach ($this->getActiveHandlers() as $handler) {
 297              $response = $handler->onCommand(
 298                  $this, $command, $codes, $failures, $stopSignal
 299                  );
 300              if ($stopSignal) {
 301                  return $response;
 302              }
 303          }
 304  
 305          return parent::executeCommand($command, $codes, $failures, $pipeline, $address);
 306      }
 307  
 308      /** Mixin handling method for ESMTP handlers */
 309      public function __call($method, $args)
 310      {
 311          foreach ($this->handlers as $handler) {
 312              if (in_array(strtolower($method),
 313                  array_map('strtolower', (array) $handler->exposeMixinMethods())
 314                  )) {
 315                  $return = call_user_func_array([$handler, $method], $args);
 316                  // Allow fluid method calls
 317                  if (null === $return && 'set' == substr($method, 0, 3)) {
 318                      return $this;
 319                  } else {
 320                      return $return;
 321                  }
 322              }
 323          }
 324          trigger_error('Call to undefined method '.$method, E_USER_ERROR);
 325      }
 326  
 327      /** Get the params to initialize the buffer */
 328      protected function getBufferParams()
 329      {
 330          return $this->params;
 331      }
 332  
 333      /** Overridden to perform EHLO instead */
 334      protected function doHeloCommand()
 335      {
 336          try {
 337              $response = $this->executeCommand(
 338                  sprintf("EHLO %s\r\n", $this->domain), [250]
 339                  );
 340          } catch (Swift_TransportException $e) {
 341              return parent::doHeloCommand();
 342          }
 343  
 344          if ($this->params['tls']) {
 345              try {
 346                  $this->executeCommand("STARTTLS\r\n", [220]);
 347  
 348                  if (!$this->buffer->startTLS()) {
 349                      throw new Swift_TransportException('Unable to connect with TLS encryption');
 350                  }
 351  
 352                  try {
 353                      $response = $this->executeCommand(
 354                          sprintf("EHLO %s\r\n", $this->domain), [250]
 355                          );
 356                  } catch (Swift_TransportException $e) {
 357                      return parent::doHeloCommand();
 358                  }
 359              } catch (Swift_TransportException $e) {
 360                  $this->throwException($e);
 361              }
 362          }
 363  
 364          $this->capabilities = $this->getCapabilities($response);
 365          if (!isset($this->pipelining)) {
 366              $this->pipelining = isset($this->capabilities['PIPELINING']);
 367          }
 368  
 369          $this->setHandlerParams();
 370          foreach ($this->getActiveHandlers() as $handler) {
 371              $handler->afterEhlo($this);
 372          }
 373      }
 374  
 375      /** Overridden to add Extension support */
 376      protected function doMailFromCommand($address)
 377      {
 378          $address = $this->addressEncoder->encodeString($address);
 379          $handlers = $this->getActiveHandlers();
 380          $params = [];
 381          foreach ($handlers as $handler) {
 382              $params = array_merge($params, (array) $handler->getMailParams());
 383          }
 384          $paramStr = !empty($params) ? ' '.implode(' ', $params) : '';
 385          $this->executeCommand(
 386              sprintf("MAIL FROM:<%s>%s\r\n", $address, $paramStr), [250], $failures, true
 387              );
 388      }
 389  
 390      /** Overridden to add Extension support */
 391      protected function doRcptToCommand($address)
 392      {
 393          $address = $this->addressEncoder->encodeString($address);
 394          $handlers = $this->getActiveHandlers();
 395          $params = [];
 396          foreach ($handlers as $handler) {
 397              $params = array_merge($params, (array) $handler->getRcptParams());
 398          }
 399          $paramStr = !empty($params) ? ' '.implode(' ', $params) : '';
 400          $this->executeCommand(
 401              sprintf("RCPT TO:<%s>%s\r\n", $address, $paramStr), [250, 251, 252], $failures, true, $address
 402              );
 403      }
 404  
 405      /** Determine ESMTP capabilities by function group */
 406      private function getCapabilities($ehloResponse)
 407      {
 408          $capabilities = [];
 409          $ehloResponse = trim($ehloResponse);
 410          $lines = explode("\r\n", $ehloResponse);
 411          array_shift($lines);
 412          foreach ($lines as $line) {
 413              if (preg_match('/^[0-9]{3}[ -]([A-Z0-9-]+)((?:[ =].*)?)$/Di', $line, $matches)) {
 414                  $keyword = strtoupper($matches[1]);
 415                  $paramStr = strtoupper(ltrim($matches[2], ' ='));
 416                  $params = !empty($paramStr) ? explode(' ', $paramStr) : [];
 417                  $capabilities[$keyword] = $params;
 418              }
 419          }
 420  
 421          return $capabilities;
 422      }
 423  
 424      /** Set parameters which are used by each extension handler */
 425      private function setHandlerParams()
 426      {
 427          foreach ($this->handlers as $keyword => $handler) {
 428              if (array_key_exists($keyword, $this->capabilities)) {
 429                  $handler->setKeywordParams($this->capabilities[$keyword]);
 430              }
 431          }
 432      }
 433  
 434      /** Get ESMTP handlers which are currently ok to use */
 435      private function getActiveHandlers()
 436      {
 437          $handlers = [];
 438          foreach ($this->handlers as $keyword => $handler) {
 439              if (array_key_exists($keyword, $this->capabilities)) {
 440                  $handlers[] = $handler;
 441              }
 442          }
 443  
 444          return $handlers;
 445      }
 446  }


Generated: Tue May 19 15:55:14 2020 Cross-referenced by PHPXref 0.7.1