Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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
//@require 'Swift/Transport/AbstractSmtpTransport.php';
12
//@require 'Swift/Transport/EsmtpHandler.php';
13
//@require 'Swift/Transport/IoBuffer.php';
14
//@require 'Swift/Transport/SmtpAgent.php';
15
//@require 'Swift/TransportException.php';
16
//@require 'Swift/Mime/Message.php';
17
//@require 'Swift/Events/EventDispatcher.php';
18
 
19
/**
20
 * Sends Messages over SMTP with ESMTP support.
21
 * @package Swift
22
 * @subpackage Transport
23
 * @author Chris Corbyn
24
 */
25
class Swift_Transport_EsmtpTransport
26
  extends Swift_Transport_AbstractSmtpTransport
27
  implements Swift_Transport_SmtpAgent
28
{
29
 
30
  /**
31
   * ESMTP extension handlers.
32
   * @var Swift_Transport_EsmtpHandler[]
33
   * @access private
34
   */
35
  private $_handlers = array();
36
 
37
  /**
38
   * ESMTP capabilities.
39
   * @var string[]
40
   * @access private
41
   */
42
  private $_capabilities = array();
43
 
44
  /**
45
   * Connection buffer parameters.
46
   * @var array
47
   * @access protected
48
   */
49
  private $_params = array(
50
    'protocol' => 'tcp',
51
    'host' => 'localhost',
52
    'port' => 25,
53
    'timeout' => 30,
54
    'blocking' => 1,
55
    'type' => Swift_Transport_IoBuffer::TYPE_SOCKET
56
    );
57
 
58
  /**
59
   * Creates a new EsmtpTransport using the given I/O buffer.
60
   * @param Swift_Transport_IoBuffer $buf
61
   * @param Swift_Transport_EsmtpHandler[] $extensionHandlers
62
   * @param Swift_Events_EventDispatcher $dispatcher
63
   */
64
  public function __construct(Swift_Transport_IoBuffer $buf,
65
    array $extensionHandlers, Swift_Events_EventDispatcher $dispatcher)
66
  {
67
    parent::__construct($buf, $dispatcher);
68
    $this->setExtensionHandlers($extensionHandlers);
69
  }
70
 
71
  /**
72
   * Set the host to connect to.
73
   * @param string $host
74
   */
75
  public function setHost($host)
76
  {
77
    $this->_params['host'] = $host;
78
    return $this;
79
  }
80
 
81
  /**
82
   * Get the host to connect to.
83
   * @return string
84
   */
85
  public function getHost()
86
  {
87
    return $this->_params['host'];
88
  }
89
 
90
  /**
91
   * Set the port to connect to.
92
   * @param int $port
93
   */
94
  public function setPort($port)
95
  {
96
    $this->_params['port'] = (int) $port;
97
    return $this;
98
  }
99
 
100
  /**
101
   * Get the port to connect to.
102
   * @return int
103
   */
104
  public function getPort()
105
  {
106
    return $this->_params['port'];
107
  }
108
 
109
  /**
110
   * Set the connection timeout.
111
   * @param int $timeout seconds
112
   */
113
  public function setTimeout($timeout)
114
  {
115
    $this->_params['timeout'] = (int) $timeout;
116
    return $this;
117
  }
118
 
119
  /**
120
   * Get the connection timeout.
121
   * @return int
122
   */
123
  public function getTimeout()
124
  {
125
    return $this->_params['timeout'];
126
  }
127
 
128
  /**
129
   * Set the encryption type (tls or ssl)
130
   * @param string $encryption
131
   */
132
  public function setEncryption($enc)
133
  {
134
    $this->_params['protocol'] = $enc;
135
    return $this;
136
  }
137
 
138
  /**
139
   * Get the encryption type.
140
   * @return string
141
   */
142
  public function getEncryption()
143
  {
144
    return $this->_params['protocol'];
145
  }
146
 
147
  /**
148
   * Set ESMTP extension handlers.
149
   * @param Swift_Transport_EsmtpHandler[] $handlers
150
   */
151
  public function setExtensionHandlers(array $handlers)
152
  {
153
    $assoc = array();
154
    foreach ($handlers as $handler)
155
    {
156
      $assoc[$handler->getHandledKeyword()] = $handler;
157
    }
158
    uasort($assoc, array($this, '_sortHandlers'));
159
    $this->_handlers = $assoc;
160
    $this->_setHandlerParams();
161
    return $this;
162
  }
163
 
164
  /**
165
   * Get ESMTP extension handlers.
166
   * @return Swift_Transport_EsmtpHandler[]
167
   */
168
  public function getExtensionHandlers()
169
  {
170
    return array_values($this->_handlers);
171
  }
172
 
173
  /**
174
   * Run a command against the buffer, expecting the given response codes.
175
   * If no response codes are given, the response will not be validated.
176
   * If codes are given, an exception will be thrown on an invalid response.
177
   * @param string $command
178
   * @param int[] $codes
179
   * @param string[] &$failures
180
   * @return string
181
   */
182
  public function executeCommand($command, $codes = array(), &$failures = null)
183
  {
184
    $failures = (array) $failures;
185
    $stopSignal = false;
186
    $response = null;
187
    foreach ($this->_getActiveHandlers() as $handler)
188
    {
189
      $response = $handler->onCommand(
190
        $this, $command, $codes, $failures, $stopSignal
191
        );
192
      if ($stopSignal)
193
      {
194
        return $response;
195
      }
196
    }
197
    return parent::executeCommand($command, $codes, $failures);
198
  }
199
 
200
  // -- Mixin invocation code
201
 
202
  /** Mixin handling method for ESMTP handlers */
203
  public function __call($method, $args)
204
  {
205
    foreach ($this->_handlers as $handler)
206
    {
207
      if (in_array(strtolower($method),
208
        array_map('strtolower', (array) $handler->exposeMixinMethods())
209
        ))
210
      {
211
        $return = call_user_func_array(array($handler, $method), $args);
212
        //Allow fluid method calls
213
        if (is_null($return) && substr($method, 0, 3) == 'set')
214
        {
215
          return $this;
216
        }
217
        else
218
        {
219
          return $return;
220
        }
221
      }
222
    }
223
    trigger_error('Call to undefined method ' . $method, E_USER_ERROR);
224
  }
225
 
226
  // -- Protected methods
227
 
228
  /** Get the params to initialize the buffer */
229
  protected function _getBufferParams()
230
  {
231
    return $this->_params;
232
  }
233
 
234
  /** Overridden to perform EHLO instead */
235
  protected function _doHeloCommand()
236
  {
237
    try
238
    {
239
      $response = $this->executeCommand(
240
        sprintf("EHLO %s\r\n", $this->_domain), array(250)
241
        );
242
      $this->_capabilities = $this->_getCapabilities($response);
243
      $this->_setHandlerParams();
244
      foreach ($this->_getActiveHandlers() as $handler)
245
      {
246
        $handler->afterEhlo($this);
247
      }
248
    }
249
    catch (Swift_TransportException $e)
250
    {
251
      parent::_doHeloCommand();
252
    }
253
  }
254
 
255
  /** Overridden to add Extension support */
256
  protected function _doMailFromCommand($address)
257
  {
258
    $handlers = $this->_getActiveHandlers();
259
    $params = array();
260
    foreach ($handlers as $handler)
261
    {
262
      $params = array_merge($params, (array) $handler->getMailParams());
263
    }
264
    $paramStr = !empty($params) ? ' ' . implode(' ', $params) : '';
265
    $this->executeCommand(
266
      sprintf("MAIL FROM: <%s>%s\r\n", $address, $paramStr), array(250)
267
      );
268
  }
269
 
270
  /** Overridden to add Extension support */
271
  protected function _doRcptToCommand($address)
272
  {
273
    $handlers = $this->_getActiveHandlers();
274
    $params = array();
275
    foreach ($handlers as $handler)
276
    {
277
      $params = array_merge($params, (array) $handler->getRcptParams());
278
    }
279
    $paramStr = !empty($params) ? ' ' . implode(' ', $params) : '';
280
    $this->executeCommand(
281
      sprintf("RCPT TO: <%s>%s\r\n", $address, $paramStr), array(250, 251, 252)
282
      );
283
  }
284
 
285
  // -- Private methods
286
 
287
  /** Determine ESMTP capabilities by function group */
288
  private function _getCapabilities($ehloResponse)
289
  {
290
    $capabilities = array();
291
    $ehloResponse = trim($ehloResponse);
292
    $lines = explode("\r\n", $ehloResponse);
293
    array_shift($lines);
294
    foreach ($lines as $line)
295
    {
296
      if (preg_match('/^[0-9]{3}[ -]([A-Z0-9-]+)((?:[ =].*)?)$/Di', $line, $matches))
297
      {
298
        $keyword = strtoupper($matches[1]);
299
        $paramStr = strtoupper(ltrim($matches[2], ' ='));
300
        $params = !empty($paramStr) ? explode(' ', $paramStr) : array();
301
        $capabilities[$keyword] = $params;
302
      }
303
    }
304
    return $capabilities;
305
  }
306
 
307
  /** Set parameters which are used by each extension handler */
308
  private function _setHandlerParams()
309
  {
310
    foreach ($this->_handlers as $keyword => $handler)
311
    {
312
      if (array_key_exists($keyword, $this->_capabilities))
313
      {
314
        $handler->setKeywordParams($this->_capabilities[$keyword]);
315
      }
316
    }
317
  }
318
 
319
  /** Get ESMTP handlers which are currently ok to use */
320
  private function _getActiveHandlers()
321
  {
322
    $handlers = array();
323
    foreach ($this->_handlers as $keyword => $handler)
324
    {
325
      if (array_key_exists($keyword, $this->_capabilities))
326
      {
327
        $handlers[] = $handler;
328
      }
329
    }
330
    return $handlers;
331
  }
332
 
333
  /** Custom sort for extension handler ordering */
334
  private function _sortHandlers($a, $b)
335
  {
336
    return $a->getPriorityOver($b->getHandledKeyword());
337
  }
338
 
339
}