~lzap/cupooy/trunk

« back to all changes in this revision

Viewing changes to lib/vendor/swift/classes/Swift/Transport/EsmtpTransport.php

  • Committer: Lukáš Zapletal
  • Date: 2009-11-16 15:18:26 UTC
  • Revision ID: lzap@shark-20091116151826-4287asrnx59j26g0
Mailing

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}