1*ee5c0205SAndreas Gohr<?php 2*ee5c0205SAndreas Gohr/***************************************************\ 3*ee5c0205SAndreas Gohr * 4*ee5c0205SAndreas Gohr * Mailer (https://github.com/txthinking/Mailer) 5*ee5c0205SAndreas Gohr * 6*ee5c0205SAndreas Gohr * A lightweight PHP SMTP mail sender. 7*ee5c0205SAndreas Gohr * Implement RFC0821, RFC0822, RFC1869, RFC2045, RFC2821 8*ee5c0205SAndreas Gohr * 9*ee5c0205SAndreas Gohr * Support html body, don't worry that the receiver's 10*ee5c0205SAndreas Gohr * mail client can't support html, because Mailer will 11*ee5c0205SAndreas Gohr * send both text/plain and text/html body, so if the 12*ee5c0205SAndreas Gohr * mail client can't support html, it will display the 13*ee5c0205SAndreas Gohr * text/plain body. 14*ee5c0205SAndreas Gohr * 15*ee5c0205SAndreas Gohr * Create Date 2012-07-25. 16*ee5c0205SAndreas Gohr * Under the MIT license. 17*ee5c0205SAndreas Gohr * 18*ee5c0205SAndreas Gohr \***************************************************/ 19*ee5c0205SAndreas Gohr 20*ee5c0205SAndreas Gohrnamespace Tx\Mailer; 21*ee5c0205SAndreas Gohr 22*ee5c0205SAndreas Gohruse Psr\Log\LoggerInterface; 23*ee5c0205SAndreas Gohruse Tx\Mailer\Exceptions\CodeException; 24*ee5c0205SAndreas Gohruse Tx\Mailer\Exceptions\CryptoException; 25*ee5c0205SAndreas Gohruse Tx\Mailer\Exceptions\SMTPException; 26*ee5c0205SAndreas Gohr 27*ee5c0205SAndreas Gohrclass SMTP 28*ee5c0205SAndreas Gohr{ 29*ee5c0205SAndreas Gohr /** 30*ee5c0205SAndreas Gohr * smtp socket 31*ee5c0205SAndreas Gohr */ 32*ee5c0205SAndreas Gohr protected $smtp; 33*ee5c0205SAndreas Gohr 34*ee5c0205SAndreas Gohr /** 35*ee5c0205SAndreas Gohr * smtp server 36*ee5c0205SAndreas Gohr */ 37*ee5c0205SAndreas Gohr protected $host; 38*ee5c0205SAndreas Gohr 39*ee5c0205SAndreas Gohr /** 40*ee5c0205SAndreas Gohr * smtp server port 41*ee5c0205SAndreas Gohr */ 42*ee5c0205SAndreas Gohr protected $port; 43*ee5c0205SAndreas Gohr 44*ee5c0205SAndreas Gohr /** 45*ee5c0205SAndreas Gohr * smtp secure ssl tls tlsv1.0 tlsv1.1 tlsv1.2 46*ee5c0205SAndreas Gohr */ 47*ee5c0205SAndreas Gohr protected $secure; 48*ee5c0205SAndreas Gohr 49*ee5c0205SAndreas Gohr /** 50*ee5c0205SAndreas Gohr * EHLO message 51*ee5c0205SAndreas Gohr */ 52*ee5c0205SAndreas Gohr protected $ehlo; 53*ee5c0205SAndreas Gohr 54*ee5c0205SAndreas Gohr /** 55*ee5c0205SAndreas Gohr * smtp username 56*ee5c0205SAndreas Gohr */ 57*ee5c0205SAndreas Gohr protected $username; 58*ee5c0205SAndreas Gohr 59*ee5c0205SAndreas Gohr /** 60*ee5c0205SAndreas Gohr * smtp password 61*ee5c0205SAndreas Gohr */ 62*ee5c0205SAndreas Gohr protected $password; 63*ee5c0205SAndreas Gohr 64*ee5c0205SAndreas Gohr /** 65*ee5c0205SAndreas Gohr * oauth access token 66*ee5c0205SAndreas Gohr */ 67*ee5c0205SAndreas Gohr protected $oauthToken; 68*ee5c0205SAndreas Gohr 69*ee5c0205SAndreas Gohr /** 70*ee5c0205SAndreas Gohr * $this->CRLF 71*ee5c0205SAndreas Gohr * @var string 72*ee5c0205SAndreas Gohr */ 73*ee5c0205SAndreas Gohr protected $CRLF = "\r\n"; 74*ee5c0205SAndreas Gohr 75*ee5c0205SAndreas Gohr /** 76*ee5c0205SAndreas Gohr * @var Message 77*ee5c0205SAndreas Gohr */ 78*ee5c0205SAndreas Gohr protected $message; 79*ee5c0205SAndreas Gohr 80*ee5c0205SAndreas Gohr /** 81*ee5c0205SAndreas Gohr * @var LoggerInterface - Used to make things prettier than self::$logger 82*ee5c0205SAndreas Gohr */ 83*ee5c0205SAndreas Gohr protected $logger; 84*ee5c0205SAndreas Gohr 85*ee5c0205SAndreas Gohr /** 86*ee5c0205SAndreas Gohr * Stack of all commands issued to SMTP 87*ee5c0205SAndreas Gohr * @var array 88*ee5c0205SAndreas Gohr */ 89*ee5c0205SAndreas Gohr protected $commandStack = array(); 90*ee5c0205SAndreas Gohr 91*ee5c0205SAndreas Gohr /** 92*ee5c0205SAndreas Gohr * Stack of all results issued to SMTP 93*ee5c0205SAndreas Gohr * @var array 94*ee5c0205SAndreas Gohr */ 95*ee5c0205SAndreas Gohr protected $resultStack = array(); 96*ee5c0205SAndreas Gohr 97*ee5c0205SAndreas Gohr public function __construct(LoggerInterface $logger=null) 98*ee5c0205SAndreas Gohr { 99*ee5c0205SAndreas Gohr $this->logger = $logger; 100*ee5c0205SAndreas Gohr } 101*ee5c0205SAndreas Gohr 102*ee5c0205SAndreas Gohr /** 103*ee5c0205SAndreas Gohr * set server and port 104*ee5c0205SAndreas Gohr * @param string $host server 105*ee5c0205SAndreas Gohr * @param int $port port 106*ee5c0205SAndreas Gohr * @param string $secure ssl tls tlsv1.0 tlsv1.1 tlsv1.2 107*ee5c0205SAndreas Gohr * @return $this 108*ee5c0205SAndreas Gohr */ 109*ee5c0205SAndreas Gohr public function setServer($host, $port, $secure=null) 110*ee5c0205SAndreas Gohr { 111*ee5c0205SAndreas Gohr $this->host = $host; 112*ee5c0205SAndreas Gohr $this->port = $port; 113*ee5c0205SAndreas Gohr $this->secure = $secure; 114*ee5c0205SAndreas Gohr if(!$this->ehlo) $this->ehlo = $host; 115*ee5c0205SAndreas Gohr $this->logger && $this->logger->debug("Set: the server"); 116*ee5c0205SAndreas Gohr return $this; 117*ee5c0205SAndreas Gohr } 118*ee5c0205SAndreas Gohr 119*ee5c0205SAndreas Gohr /** 120*ee5c0205SAndreas Gohr * auth login with server 121*ee5c0205SAndreas Gohr * @param string $username 122*ee5c0205SAndreas Gohr * @param string $password 123*ee5c0205SAndreas Gohr * @return $this 124*ee5c0205SAndreas Gohr */ 125*ee5c0205SAndreas Gohr public function setAuth($username, $password) 126*ee5c0205SAndreas Gohr { 127*ee5c0205SAndreas Gohr $this->username = $username; 128*ee5c0205SAndreas Gohr $this->password = $password; 129*ee5c0205SAndreas Gohr $this->logger && $this->logger->debug("Set: the auth login"); 130*ee5c0205SAndreas Gohr return $this; 131*ee5c0205SAndreas Gohr } 132*ee5c0205SAndreas Gohr 133*ee5c0205SAndreas Gohr /** 134*ee5c0205SAndreas Gohr * auth oauthbearer with server 135*ee5c0205SAndreas Gohr * @param string $accessToken 136*ee5c0205SAndreas Gohr * @return $this 137*ee5c0205SAndreas Gohr */ 138*ee5c0205SAndreas Gohr public function setOAuth($accessToken) 139*ee5c0205SAndreas Gohr { 140*ee5c0205SAndreas Gohr $this->oauthToken = $accessToken; 141*ee5c0205SAndreas Gohr $this->logger && $this->logger->debug("Set: the auth oauthbearer"); 142*ee5c0205SAndreas Gohr return $this; 143*ee5c0205SAndreas Gohr } 144*ee5c0205SAndreas Gohr 145*ee5c0205SAndreas Gohr /** 146*ee5c0205SAndreas Gohr * set the EHLO message 147*ee5c0205SAndreas Gohr * @param $ehlo 148*ee5c0205SAndreas Gohr * @return $this 149*ee5c0205SAndreas Gohr */ 150*ee5c0205SAndreas Gohr public function setEhlo($ehlo) 151*ee5c0205SAndreas Gohr { 152*ee5c0205SAndreas Gohr $this->ehlo = $ehlo; 153*ee5c0205SAndreas Gohr return $this; 154*ee5c0205SAndreas Gohr } 155*ee5c0205SAndreas Gohr 156*ee5c0205SAndreas Gohr /** 157*ee5c0205SAndreas Gohr * Send the message 158*ee5c0205SAndreas Gohr * 159*ee5c0205SAndreas Gohr * @param Message $message 160*ee5c0205SAndreas Gohr * @return bool 161*ee5c0205SAndreas Gohr * @throws CodeException 162*ee5c0205SAndreas Gohr * @throws CryptoException 163*ee5c0205SAndreas Gohr * @throws SMTPException 164*ee5c0205SAndreas Gohr */ 165*ee5c0205SAndreas Gohr public function send(Message $message) 166*ee5c0205SAndreas Gohr { 167*ee5c0205SAndreas Gohr $this->logger && $this->logger->debug('Set: a message will be sent'); 168*ee5c0205SAndreas Gohr $this->message = $message; 169*ee5c0205SAndreas Gohr $this->connect() 170*ee5c0205SAndreas Gohr ->ehlo(); 171*ee5c0205SAndreas Gohr 172*ee5c0205SAndreas Gohr if ($this->secure === 'tls' || $this->secure === 'tlsv1.0' || $this->secure === 'tlsv1.1' | $this->secure === 'tlsv1.2') { 173*ee5c0205SAndreas Gohr $this->starttls() 174*ee5c0205SAndreas Gohr ->ehlo(); 175*ee5c0205SAndreas Gohr } 176*ee5c0205SAndreas Gohr 177*ee5c0205SAndreas Gohr if ($this->username !== null || $this->password !== null) { 178*ee5c0205SAndreas Gohr $this->authLogin(); 179*ee5c0205SAndreas Gohr } elseif ($this->oauthToken !== null) { 180*ee5c0205SAndreas Gohr $this->authOAuthBearer(); 181*ee5c0205SAndreas Gohr } 182*ee5c0205SAndreas Gohr $this->mailFrom() 183*ee5c0205SAndreas Gohr ->rcptTo() 184*ee5c0205SAndreas Gohr ->data() 185*ee5c0205SAndreas Gohr ->quit(); 186*ee5c0205SAndreas Gohr return fclose($this->smtp); 187*ee5c0205SAndreas Gohr } 188*ee5c0205SAndreas Gohr 189*ee5c0205SAndreas Gohr /** 190*ee5c0205SAndreas Gohr * connect the server 191*ee5c0205SAndreas Gohr * SUCCESS 220 192*ee5c0205SAndreas Gohr * @return $this 193*ee5c0205SAndreas Gohr * @throws CodeException 194*ee5c0205SAndreas Gohr * @throws SMTPException 195*ee5c0205SAndreas Gohr */ 196*ee5c0205SAndreas Gohr protected function connect() 197*ee5c0205SAndreas Gohr { 198*ee5c0205SAndreas Gohr $this->logger && $this->logger->debug("Connecting to {$this->host} at {$this->port}"); 199*ee5c0205SAndreas Gohr $host = ($this->secure == 'ssl') ? 'ssl://' . $this->host : $this->host; 200*ee5c0205SAndreas Gohr $this->smtp = @fsockopen($host, $this->port); 201*ee5c0205SAndreas Gohr //set block mode 202*ee5c0205SAndreas Gohr // stream_set_blocking($this->smtp, 1); 203*ee5c0205SAndreas Gohr if (!$this->smtp){ 204*ee5c0205SAndreas Gohr throw new SMTPException("Could not open SMTP Port."); 205*ee5c0205SAndreas Gohr } 206*ee5c0205SAndreas Gohr $code = $this->getCode(); 207*ee5c0205SAndreas Gohr if ($code !== '220'){ 208*ee5c0205SAndreas Gohr throw new CodeException('220', $code, array_pop($this->resultStack)); 209*ee5c0205SAndreas Gohr } 210*ee5c0205SAndreas Gohr return $this; 211*ee5c0205SAndreas Gohr } 212*ee5c0205SAndreas Gohr 213*ee5c0205SAndreas Gohr /** 214*ee5c0205SAndreas Gohr * SMTP STARTTLS 215*ee5c0205SAndreas Gohr * SUCCESS 220 216*ee5c0205SAndreas Gohr * @return $this 217*ee5c0205SAndreas Gohr * @throws CodeException 218*ee5c0205SAndreas Gohr * @throws CryptoException 219*ee5c0205SAndreas Gohr * @throws SMTPException 220*ee5c0205SAndreas Gohr */ 221*ee5c0205SAndreas Gohr protected function starttls() 222*ee5c0205SAndreas Gohr { 223*ee5c0205SAndreas Gohr $in = "STARTTLS" . $this->CRLF; 224*ee5c0205SAndreas Gohr $code = $this->pushStack($in); 225*ee5c0205SAndreas Gohr if ($code !== '220'){ 226*ee5c0205SAndreas Gohr throw new CodeException('220', $code, array_pop($this->resultStack)); 227*ee5c0205SAndreas Gohr } 228*ee5c0205SAndreas Gohr 229*ee5c0205SAndreas Gohr if ($this->secure !== 'tls' && version_compare(phpversion(), '5.6.0', '<')) { 230*ee5c0205SAndreas Gohr throw new CryptoException('Crypto type expected PHP 5.6 or greater'); 231*ee5c0205SAndreas Gohr } 232*ee5c0205SAndreas Gohr 233*ee5c0205SAndreas Gohr switch ($this->secure) { 234*ee5c0205SAndreas Gohr case 'tlsv1.0': 235*ee5c0205SAndreas Gohr $crypto_type = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT; 236*ee5c0205SAndreas Gohr break; 237*ee5c0205SAndreas Gohr case 'tlsv1.1': 238*ee5c0205SAndreas Gohr $crypto_type = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; 239*ee5c0205SAndreas Gohr break; 240*ee5c0205SAndreas Gohr case 'tlsv1.2': 241*ee5c0205SAndreas Gohr $crypto_type = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; 242*ee5c0205SAndreas Gohr break; 243*ee5c0205SAndreas Gohr default: 244*ee5c0205SAndreas Gohr $crypto_type = STREAM_CRYPTO_METHOD_TLS_CLIENT; 245*ee5c0205SAndreas Gohr break; 246*ee5c0205SAndreas Gohr } 247*ee5c0205SAndreas Gohr 248*ee5c0205SAndreas Gohr if(!\stream_socket_enable_crypto($this->smtp, true, $crypto_type)) { 249*ee5c0205SAndreas Gohr throw new CryptoException("Start TLS failed to enable crypto"); 250*ee5c0205SAndreas Gohr } 251*ee5c0205SAndreas Gohr return $this; 252*ee5c0205SAndreas Gohr } 253*ee5c0205SAndreas Gohr 254*ee5c0205SAndreas Gohr /** 255*ee5c0205SAndreas Gohr * SMTP EHLO 256*ee5c0205SAndreas Gohr * SUCCESS 250 257*ee5c0205SAndreas Gohr * @return $this 258*ee5c0205SAndreas Gohr * @throws CodeException 259*ee5c0205SAndreas Gohr * @throws SMTPException 260*ee5c0205SAndreas Gohr */ 261*ee5c0205SAndreas Gohr protected function ehlo() 262*ee5c0205SAndreas Gohr { 263*ee5c0205SAndreas Gohr $in = "EHLO " . $this->ehlo . $this->CRLF; 264*ee5c0205SAndreas Gohr $code = $this->pushStack($in); 265*ee5c0205SAndreas Gohr if ($code !== '250'){ 266*ee5c0205SAndreas Gohr throw new CodeException('250', $code, array_pop($this->resultStack)); 267*ee5c0205SAndreas Gohr } 268*ee5c0205SAndreas Gohr return $this; 269*ee5c0205SAndreas Gohr } 270*ee5c0205SAndreas Gohr 271*ee5c0205SAndreas Gohr /** 272*ee5c0205SAndreas Gohr * SMTP AUTH LOGIN 273*ee5c0205SAndreas Gohr * SUCCESS 334 274*ee5c0205SAndreas Gohr * SUCCESS 334 275*ee5c0205SAndreas Gohr * SUCCESS 235 276*ee5c0205SAndreas Gohr * @return $this 277*ee5c0205SAndreas Gohr * @throws CodeException 278*ee5c0205SAndreas Gohr * @throws SMTPException 279*ee5c0205SAndreas Gohr */ 280*ee5c0205SAndreas Gohr protected function authLogin() 281*ee5c0205SAndreas Gohr { 282*ee5c0205SAndreas Gohr $in = "AUTH LOGIN" . $this->CRLF; 283*ee5c0205SAndreas Gohr $code = $this->pushStack($in); 284*ee5c0205SAndreas Gohr if ($code !== '334'){ 285*ee5c0205SAndreas Gohr throw new CodeException('334', $code, array_pop($this->resultStack)); 286*ee5c0205SAndreas Gohr } 287*ee5c0205SAndreas Gohr $in = base64_encode($this->username) . $this->CRLF; 288*ee5c0205SAndreas Gohr $code = $this->pushStack($in); 289*ee5c0205SAndreas Gohr if ($code !== '334'){ 290*ee5c0205SAndreas Gohr throw new CodeException('334', $code, array_pop($this->resultStack)); 291*ee5c0205SAndreas Gohr } 292*ee5c0205SAndreas Gohr $in = base64_encode($this->password) . $this->CRLF; 293*ee5c0205SAndreas Gohr $code = $this->pushStack($in); 294*ee5c0205SAndreas Gohr if ($code !== '235'){ 295*ee5c0205SAndreas Gohr throw new CodeException('235', $code, array_pop($this->resultStack)); 296*ee5c0205SAndreas Gohr } 297*ee5c0205SAndreas Gohr return $this; 298*ee5c0205SAndreas Gohr } 299*ee5c0205SAndreas Gohr 300*ee5c0205SAndreas Gohr /** 301*ee5c0205SAndreas Gohr * SMTP AUTH OAUTHBEARER 302*ee5c0205SAndreas Gohr * SUCCESS 235 303*ee5c0205SAndreas Gohr * @return $this 304*ee5c0205SAndreas Gohr * @throws CodeException 305*ee5c0205SAndreas Gohr * @throws SMTPException 306*ee5c0205SAndreas Gohr */ 307*ee5c0205SAndreas Gohr protected function authOAuthBearer() 308*ee5c0205SAndreas Gohr { 309*ee5c0205SAndreas Gohr $authStr = sprintf("n,a=%s,%shost=%s%sport=%s%sauth=Bearer %s%s%s", 310*ee5c0205SAndreas Gohr $this->message->getFromEmail(), 311*ee5c0205SAndreas Gohr chr(1), 312*ee5c0205SAndreas Gohr $this->host, 313*ee5c0205SAndreas Gohr chr(1), 314*ee5c0205SAndreas Gohr $this->port, 315*ee5c0205SAndreas Gohr chr(1), 316*ee5c0205SAndreas Gohr $this->oauthToken, 317*ee5c0205SAndreas Gohr chr(1), 318*ee5c0205SAndreas Gohr chr(1) 319*ee5c0205SAndreas Gohr ); 320*ee5c0205SAndreas Gohr $authStr = base64_encode($authStr); 321*ee5c0205SAndreas Gohr $in = "AUTH OAUTHBEARER $authStr" . $this->CRLF; 322*ee5c0205SAndreas Gohr $code = $this->pushStack($in); 323*ee5c0205SAndreas Gohr if ($code !== '235'){ 324*ee5c0205SAndreas Gohr throw new CodeException('235', $code, array_pop($this->resultStack)); 325*ee5c0205SAndreas Gohr } 326*ee5c0205SAndreas Gohr return $this; 327*ee5c0205SAndreas Gohr } 328*ee5c0205SAndreas Gohr 329*ee5c0205SAndreas Gohr /** 330*ee5c0205SAndreas Gohr * SMTP AUTH XOAUTH2 331*ee5c0205SAndreas Gohr * SUCCESS 235 332*ee5c0205SAndreas Gohr * @return $this 333*ee5c0205SAndreas Gohr * @throws CodeException 334*ee5c0205SAndreas Gohr * @throws SMTPException 335*ee5c0205SAndreas Gohr */ 336*ee5c0205SAndreas Gohr protected function authXOAuth2() 337*ee5c0205SAndreas Gohr { 338*ee5c0205SAndreas Gohr $authStr = sprintf("user=%s%sauth=Bearer %s%s%s", 339*ee5c0205SAndreas Gohr $this->message->getFromEmail(), 340*ee5c0205SAndreas Gohr chr(1), 341*ee5c0205SAndreas Gohr $this->oauthToken, 342*ee5c0205SAndreas Gohr chr(1), 343*ee5c0205SAndreas Gohr chr(1) 344*ee5c0205SAndreas Gohr ); 345*ee5c0205SAndreas Gohr $authStr = base64_encode($authStr); 346*ee5c0205SAndreas Gohr $in = "AUTH XOAUTH2 $authStr" . $this->CRLF; 347*ee5c0205SAndreas Gohr $code = $this->pushStack($in); 348*ee5c0205SAndreas Gohr if ($code !== '235'){ 349*ee5c0205SAndreas Gohr throw new CodeException('235', $code, array_pop($this->resultStack)); 350*ee5c0205SAndreas Gohr } 351*ee5c0205SAndreas Gohr return $this; 352*ee5c0205SAndreas Gohr } 353*ee5c0205SAndreas Gohr 354*ee5c0205SAndreas Gohr /** 355*ee5c0205SAndreas Gohr * SMTP MAIL FROM 356*ee5c0205SAndreas Gohr * SUCCESS 250 357*ee5c0205SAndreas Gohr * @return $this 358*ee5c0205SAndreas Gohr * @throws CodeException 359*ee5c0205SAndreas Gohr * @throws SMTPException 360*ee5c0205SAndreas Gohr */ 361*ee5c0205SAndreas Gohr protected function mailFrom() 362*ee5c0205SAndreas Gohr { 363*ee5c0205SAndreas Gohr $in = "MAIL FROM:<{$this->message->getFromEmail()}>" . $this->CRLF; 364*ee5c0205SAndreas Gohr $code = $this->pushStack($in); 365*ee5c0205SAndreas Gohr if ($code !== '250') { 366*ee5c0205SAndreas Gohr throw new CodeException('250', $code, array_pop($this->resultStack)); 367*ee5c0205SAndreas Gohr } 368*ee5c0205SAndreas Gohr return $this; 369*ee5c0205SAndreas Gohr } 370*ee5c0205SAndreas Gohr 371*ee5c0205SAndreas Gohr /** 372*ee5c0205SAndreas Gohr * SMTP RCPT TO 373*ee5c0205SAndreas Gohr * SUCCESS 250 374*ee5c0205SAndreas Gohr * @return $this 375*ee5c0205SAndreas Gohr * @throws CodeException 376*ee5c0205SAndreas Gohr * @throws SMTPException 377*ee5c0205SAndreas Gohr */ 378*ee5c0205SAndreas Gohr protected function rcptTo() 379*ee5c0205SAndreas Gohr { 380*ee5c0205SAndreas Gohr $to = array_merge( 381*ee5c0205SAndreas Gohr $this->message->getTo(), 382*ee5c0205SAndreas Gohr $this->message->getCc(), 383*ee5c0205SAndreas Gohr $this->message->getBcc() 384*ee5c0205SAndreas Gohr ); 385*ee5c0205SAndreas Gohr foreach ($to as $toEmail=>$_) { 386*ee5c0205SAndreas Gohr $in = "RCPT TO:<" . $toEmail . ">" . $this->CRLF; 387*ee5c0205SAndreas Gohr $code = $this->pushStack($in); 388*ee5c0205SAndreas Gohr if ($code !== '250') { 389*ee5c0205SAndreas Gohr throw new CodeException('250', $code, array_pop($this->resultStack)); 390*ee5c0205SAndreas Gohr } 391*ee5c0205SAndreas Gohr } 392*ee5c0205SAndreas Gohr return $this; 393*ee5c0205SAndreas Gohr } 394*ee5c0205SAndreas Gohr 395*ee5c0205SAndreas Gohr /** 396*ee5c0205SAndreas Gohr * SMTP DATA 397*ee5c0205SAndreas Gohr * SUCCESS 354 398*ee5c0205SAndreas Gohr * SUCCESS 250 399*ee5c0205SAndreas Gohr * @return $this 400*ee5c0205SAndreas Gohr * @throws CodeException 401*ee5c0205SAndreas Gohr * @throws SMTPException 402*ee5c0205SAndreas Gohr */ 403*ee5c0205SAndreas Gohr protected function data() 404*ee5c0205SAndreas Gohr { 405*ee5c0205SAndreas Gohr $in = "DATA" . $this->CRLF; 406*ee5c0205SAndreas Gohr $code = $this->pushStack($in); 407*ee5c0205SAndreas Gohr if ($code !== '354') { 408*ee5c0205SAndreas Gohr throw new CodeException('354', $code, array_pop($this->resultStack)); 409*ee5c0205SAndreas Gohr } 410*ee5c0205SAndreas Gohr $in = $this->message->toString(); 411*ee5c0205SAndreas Gohr $code = $this->pushStack($in); 412*ee5c0205SAndreas Gohr if ($code !== '250'){ 413*ee5c0205SAndreas Gohr throw new CodeException('250', $code, array_pop($this->resultStack)); 414*ee5c0205SAndreas Gohr } 415*ee5c0205SAndreas Gohr return $this; 416*ee5c0205SAndreas Gohr } 417*ee5c0205SAndreas Gohr 418*ee5c0205SAndreas Gohr /** 419*ee5c0205SAndreas Gohr * SMTP QUIT 420*ee5c0205SAndreas Gohr * SUCCESS 221 421*ee5c0205SAndreas Gohr * @return $this 422*ee5c0205SAndreas Gohr * @throws CodeException 423*ee5c0205SAndreas Gohr * @throws SMTPException 424*ee5c0205SAndreas Gohr */ 425*ee5c0205SAndreas Gohr protected function quit() 426*ee5c0205SAndreas Gohr { 427*ee5c0205SAndreas Gohr $in = "QUIT" . $this->CRLF; 428*ee5c0205SAndreas Gohr $code = $this->pushStack($in); 429*ee5c0205SAndreas Gohr if ($code !== '221'){ 430*ee5c0205SAndreas Gohr throw new CodeException('221', $code, array_pop($this->resultStack)); 431*ee5c0205SAndreas Gohr } 432*ee5c0205SAndreas Gohr return $this; 433*ee5c0205SAndreas Gohr } 434*ee5c0205SAndreas Gohr 435*ee5c0205SAndreas Gohr protected function pushStack($string) 436*ee5c0205SAndreas Gohr { 437*ee5c0205SAndreas Gohr $this->commandStack[] = $string; 438*ee5c0205SAndreas Gohr fputs($this->smtp, $string, strlen($string)); 439*ee5c0205SAndreas Gohr $this->logger && $this->logger->debug('Sent: '. $string); 440*ee5c0205SAndreas Gohr return $this->getCode(); 441*ee5c0205SAndreas Gohr } 442*ee5c0205SAndreas Gohr 443*ee5c0205SAndreas Gohr /** 444*ee5c0205SAndreas Gohr * get smtp response code 445*ee5c0205SAndreas Gohr * once time has three digital and a space 446*ee5c0205SAndreas Gohr * @return string 447*ee5c0205SAndreas Gohr * @throws SMTPException 448*ee5c0205SAndreas Gohr */ 449*ee5c0205SAndreas Gohr protected function getCode() 450*ee5c0205SAndreas Gohr { 451*ee5c0205SAndreas Gohr while ($str = fgets($this->smtp, 515)) { 452*ee5c0205SAndreas Gohr $this->logger && $this->logger->debug("Got: ". $str); 453*ee5c0205SAndreas Gohr $this->resultStack[] = $str; 454*ee5c0205SAndreas Gohr if(substr($str,3,1) == " ") { 455*ee5c0205SAndreas Gohr $code = substr($str,0,3); 456*ee5c0205SAndreas Gohr return $code; 457*ee5c0205SAndreas Gohr } 458*ee5c0205SAndreas Gohr } 459*ee5c0205SAndreas Gohr throw new SMTPException("SMTP Server did not respond with anything I recognized"); 460*ee5c0205SAndreas Gohr } 461*ee5c0205SAndreas Gohr 462*ee5c0205SAndreas Gohr} 463*ee5c0205SAndreas Gohr 464