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/Events/TransportChangeListener.php';
12
//@require 'Swift/Events/TransportChangeEvent.php';
13
 
14
/**
15
 * Makes sure a connection to a POP3 host has been established prior to connecting to SMTP.
16
 *
17
 * @package Swift
18
 * @subpackage Plugins
19
 *
20
 * @author Chris Corbyn
21
 */
22
class Swift_Plugins_PopBeforeSmtpPlugin
23
  implements Swift_Events_TransportChangeListener, Swift_Plugins_Pop_Pop3Connection
24
{
25
 
26
  /** A delegate connection to use (mostly a test hook) */
27
  private $_connection;
28
 
29
  /** Hostname of the POP3 server */
30
  private $_host;
31
 
32
  /** Port number to connect on */
33
  private $_port;
34
 
35
  /** Encryption type to use (if any) */
36
  private $_crypto;
37
 
38
  /** Username to use (if any) */
39
  private $_username;
40
 
41
  /** Password to use (if any) */
42
  private $_password;
43
 
44
  /** Established connection via TCP socket */
45
  private $_socket;
46
 
47
  /** Connect timeout in seconds */
48
  private $_timeout = 10;
49
 
50
  /** SMTP Transport to bind to */
51
  private $_transport;
52
 
53
  /**
54
   * Create a new PopBeforeSmtpPlugin for $host and $port.
55
   *
56
   * @param string $host
57
   * @param int $port
58
   * @param string $cypto as "tls" or "ssl"
59
   */
60
  public function __construct($host, $port = 110, $crypto = null)
61
  {
62
    $this->_host = $host;
63
    $this->_port = $port;
64
    $this->_crypto = $crypto;
65
  }
66
 
67
  /**
68
   * Create a new PopBeforeSmtpPlugin for $host and $port.
69
   *
70
   * @param string $host
71
   * @param int $port
72
   * @param string $cypto as "tls" or "ssl"
73
   *
74
   * @return Swift_Plugins_PopBeforeSmtpPlugin
75
   */
76
  public static function newInstance($host, $port = 110, $crypto = null)
77
  {
78
    return new self($host, $port, $crypto);
79
  }
80
 
81
  /**
82
   * Set a Pop3Connection to delegate to instead of connecting directly.
83
   *
84
   * @param Swift_Plugins_Pop_Pop3Connection $connection
85
   */
86
  public function setConnection(Swift_Plugins_Pop_Pop3Connection $connection)
87
  {
88
    $this->_connection = $connection;
89
    return $this;
90
  }
91
 
92
  /**
93
   * Bind this plugin to a specific SMTP transport instance.
94
   *
95
   * @param Swift_Transport
96
   */
97
  public function bindSmtp(Swift_Transport $smtp)
98
  {
99
    $this->_transport = $smtp;
100
  }
101
 
102
  /**
103
   * Set the connection timeout in seconds (default 10).
104
   *
105
   * @param int $timeout
106
   */
107
  public function setTimeout($timeout)
108
  {
109
    $this->_timeout = (int) $timeout;
110
    return $this;
111
  }
112
 
113
  /**
114
   * Set the username to use when connecting (if needed).
115
   *
116
   * @param string $username
117
   */
118
  public function setUsername($username)
119
  {
120
    $this->_username = $username;
121
    return $this;
122
  }
123
 
124
  /**
125
   * Set the password to use when connecting (if needed).
126
   *
127
   * @param string $password
128
   */
129
  public function setPassword($password)
130
  {
131
    $this->_password = $password;
132
    return $this;
133
  }
134
 
135
  /**
136
   * Connect to the POP3 host and authenticate.
137
   *
138
   * @throws Swift_Plugins_Pop_Pop3Exception if connection fails
139
   */
140
  public function connect()
141
  {
142
    if (isset($this->_connection))
143
    {
144
      $this->_connection->connect();
145
    }
146
    else
147
    {
148
      if (!isset($this->_socket))
149
      {
150
        if (!$socket = fsockopen(
151
          $this->_getHostString(), $this->_port, $errno, $errstr, $this->_timeout))
152
        {
153
          throw new Swift_Plugins_Pop_Pop3Exception(
154
            sprintf('Failed to connect to POP3 host [%s]: %s', $this->_host, $errstr)
155
          );
156
        }
157
        $this->_socket = $socket;
158
 
159
        if (false === $greeting = fgets($this->_socket))
160
        {
161
          throw new Swift_Plugins_Pop_Pop3Exception(
162
            sprintf('Failed to connect to POP3 host [%s]', trim($greeting))
163
          );
164
        }
165
 
166
        $this->_assertOk($greeting);
167
 
168
        if ($this->_username)
169
        {
170
          $this->_command(sprintf("USER %s\r\n", $this->_username));
171
          $this->_command(sprintf("PASS %s\r\n", $this->_password));
172
        }
173
      }
174
    }
175
  }
176
 
177
  /**
178
   * Disconnect from the POP3 host.
179
   */
180
  public function disconnect()
181
  {
182
    if (isset($this->_connection))
183
    {
184
      $this->_connection->disconnect();
185
    }
186
    else
187
    {
188
      $this->_command("QUIT\r\n");
189
      if (!fclose($this->_socket))
190
      {
191
        throw new Swift_Plugins_Pop_Pop3Exception(
192
          sprintf('POP3 host [%s] connection could not be stopped', $this->_host)
193
        );
194
      }
195
      $this->_socket = null;
196
    }
197
  }
198
 
199
  /**
200
   * Invoked just before a Transport is started.
201
   *
202
   * @param Swift_Events_TransportChangeEvent $evt
203
   */
204
  public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt)
205
  {
206
    if (isset($this->_transport))
207
    {
208
      if ($this->_transport !== $evt->getTransport())
209
      {
210
        return;
211
      }
212
    }
213
 
214
    $this->connect();
215
    $this->disconnect();
216
  }
217
 
218
  /**
219
   * Not used.
220
   */
221
  public function transportStarted(Swift_Events_TransportChangeEvent $evt)
222
  {
223
  }
224
 
225
  /**
226
   * Not used.
227
   */
228
  public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt)
229
  {
230
  }
231
 
232
  /**
233
   * Not used.
234
   */
235
  public function transportStopped(Swift_Events_TransportChangeEvent $evt)
236
  {
237
  }
238
 
239
  // -- Private Methods
240
 
241
  private function _command($command)
242
  {
243
    if (!fwrite($this->_socket, $command))
244
    {
245
      throw new Swift_Plugins_Pop_Pop3Exception(
246
        sprintf('Failed to write command [%s] to POP3 host', trim($command))
247
      );
248
    }
249
 
250
    if (false === $response = fgets($this->_socket))
251
    {
252
      throw new Swift_Plugins_Pop_Pop3Exception(
253
        sprintf('Failed to read from POP3 host after command [%s]', trim($command))
254
      );
255
    }
256
 
257
    $this->_assertOk($response);
258
 
259
    return $response;
260
  }
261
 
262
  private function _assertOk($response)
263
  {
264
    if (substr($response, 0, 3) != '+OK')
265
    {
266
      throw new Swift_Plugins_Pop_Pop3Exception(
267
        sprintf('POP3 command failed [%s]', trim($response))
268
      );
269
    }
270
  }
271
 
272
  private function _getHostString()
273
  {
274
    $host = $this->_host;
275
    switch (strtolower($this->_crypto))
276
    {
277
      case 'ssl':
278
        $host = 'ssl://' . $host;
279
        break;
280
 
281
      case 'tls':
282
        $host = 'tls://' . $host;
283
        break;
284
    }
285
    return $host;
286
  }
287
 
288
}