00001 <?php
00002
00028 require_once 'Zend/Validate.php';
00029
00030
00034 require_once 'Zend/Validate/Hostname.php';
00035
00036
00050 abstract class Zend_Mail_Protocol_Abstract
00051 {
00055 const EOL = "\r\n";
00056
00057
00061 const TIMEOUT_CONNECTION = 30;
00062
00063
00068 protected $_host;
00069
00070
00075 protected $_port;
00076
00077
00082 protected $_validHost;
00083
00084
00089 protected $_socket;
00090
00091
00096 protected $_request;
00097
00098
00103 protected $_response;
00104
00105
00110 protected $_template = '%d%s';
00111
00112
00117 private $_log;
00118
00119
00128 public function __construct($host = '127.0.0.1', $port = null)
00129 {
00130 $this->_validHost = new Zend_Validate();
00131 $this->_validHost->addValidator(new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL));
00132
00133 if (!$this->_validHost->isValid($host)) {
00137 require_once 'Zend/Mail/Protocol/Exception.php';
00138 throw new Zend_Mail_Protocol_Exception(join(', ', $this->_validHost->getMessages()));
00139 }
00140
00141 $this->_host = $host;
00142 $this->_port = $port;
00143 }
00144
00145
00151 public function __destruct()
00152 {
00153 $this->_disconnect();
00154 }
00155
00156
00162 abstract public function connect();
00163
00164
00170 public function getRequest()
00171 {
00172 return $this->_request;
00173 }
00174
00175
00181 public function getResponse()
00182 {
00183 return $this->_response;
00184 }
00185
00186
00192 public function getLog()
00193 {
00194 return $this->_log;
00195 }
00196
00197
00203 public function resetLog()
00204 {
00205 $this->_log = '';
00206 }
00207
00208
00218 protected function _connect($remote)
00219 {
00220 $errorNum = 0;
00221 $errorStr = '';
00222
00223
00224 $this->_socket = @stream_socket_client($remote, $errorNum, $errorStr, self::TIMEOUT_CONNECTION);
00225
00226 if ($this->_socket === false) {
00227 if ($errorNum == 0) {
00228 $errorStr = 'Could not open socket';
00229 }
00233 require_once 'Zend/Mail/Protocol/Exception.php';
00234 throw new Zend_Mail_Protocol_Exception($errorStr);
00235 }
00236
00237 if (($result = stream_set_timeout($this->_socket, self::TIMEOUT_CONNECTION)) === false) {
00241 require_once 'Zend/Mail/Protocol/Exception.php';
00242 throw new Zend_Mail_Protocol_Exception('Could not set stream timeout');
00243 }
00244
00245 return $result;
00246 }
00247
00248
00254 protected function _disconnect()
00255 {
00256 if (is_resource($this->_socket)) {
00257 fclose($this->_socket);
00258 }
00259 }
00260
00261
00269 protected function _send($request)
00270 {
00271 if (!is_resource($this->_socket)) {
00275 require_once 'Zend/Mail/Protocol/Exception.php';
00276 throw new Zend_Mail_Protocol_Exception('No connection has been established to ' . $this->_host);
00277 }
00278
00279 $this->_request = $request;
00280
00281 $result = fwrite($this->_socket, $request . self::EOL);
00282
00283
00284 $this->_log .= $request . self::EOL;
00285
00286 if ($result === false) {
00290 require_once 'Zend/Mail/Protocol/Exception.php';
00291 throw new Zend_Mail_Protocol_Exception('Could not send request to ' . $this->_host);
00292 }
00293
00294 return $result;
00295 }
00296
00297
00305 protected function _receive($timeout = null)
00306 {
00307 if (!is_resource($this->_socket)) {
00311 require_once 'Zend/Mail/Protocol/Exception.php';
00312 throw new Zend_Mail_Protocol_Exception('No connection has been established to ' . $this->_host);
00313 }
00314
00315
00316 if ($timeout !== null) {
00317 stream_set_timeout($this->_socket, $timeout);
00318 }
00319
00320
00321 $reponse = fgets($this->_socket, 1024);
00322
00323
00324 $this->_log .= $reponse;
00325
00326
00327 $info = stream_get_meta_data($this->_socket);
00328
00329 if (!empty($info['timed_out'])) {
00333 require_once 'Zend/Mail/Protocol/Exception.php';
00334 throw new Zend_Mail_Protocol_Exception($this->_host . ' has timed out');
00335 }
00336
00337 if ($reponse === false) {
00341 require_once 'Zend/Mail/Protocol/Exception.php';
00342 throw new Zend_Mail_Protocol_Exception('Could not read from ' . $this->_host);
00343 }
00344
00345 return $reponse;
00346 }
00347
00348
00359 protected function _expect($code, $timeout = null)
00360 {
00361 $this->_response = array();
00362 $cmd = '';
00363 $msg = '';
00364 $errMsg = '';
00365
00366 if (!is_array($code)) {
00367 $code = array($code);
00368 }
00369
00370 do {
00371 $this->_response[] = $result = $this->_receive($timeout);
00372 sscanf($result, $this->_template, $cmd, $msg);
00373
00374 if ($errMsg !== '') {
00375 $errMsg .= $msg;
00376 } elseif ($cmd === null || !in_array($cmd, $code)) {
00377 $errMsg = $msg;
00378 }
00379
00380 } while (strpos($msg, '-') === 0);
00381
00382 if ($errMsg !== '') {
00386 require_once 'Zend/Mail/Protocol/Exception.php';
00387 throw new Zend_Mail_Protocol_Exception($errMsg);
00388 }
00389
00390 return $msg;
00391 }
00392 }