/** * Actually performs the SMTP Socket connection to send the appropriate commands to the SMTP server. * * Does absolutely no validation -- assumes that the raw data being sent in is valid. If not, * this will throw a QEmailException exception on any error. * * @param string $strMailFrom the email address to use for "MAIL FROM" * @param string[] $strRcptToArray the array of email addresse to send to via "RCPT TO" * @param mixed $mixMessageHeader can either be the raw string for the message header or a string-indexed array of header elements * @param string $strMessageBody * @return void */ public static function SendRawMessage($strMailFrom, $strRcptToArray, $mixMessageHeader, $strMessageBody) { self::$objSmtpSocket = null; if (QEmailServer::$TestMode) { // Open up a File Resource to the TestModeDirectory $strArray = explode(' ', microtime()); $strFileName = sprintf('%s/email_%s%s.txt', QEmailServer::$TestModeDirectory, $strArray[1], substr($strArray[0], 1)); self::$objSmtpSocket = fopen($strFileName, 'w'); if (!self::$objSmtpSocket) { throw new QEmailException(sprintf('Unable to open Test SMTP connection to: %s', $strFileName)); } // Clear the Read Buffer if (!feof(self::$objSmtpSocket)) { fgets(self::$objSmtpSocket, 4096); } // Write the Connection Command fwrite(self::$objSmtpSocket, sprintf("telnet %s %s\r\n", QEmailServer::$SmtpServer, QEmailServer::$SmtpPort)); } else { self::$objSmtpSocket = fsockopen(QEmailServer::$SmtpServer, QEmailServer::$SmtpPort); if (!self::$objSmtpSocket) { throw new QEmailException(sprintf('Unable to open SMTP connection to: %s %s', QEmailServer::$SmtpServer, QEmailServer::$SmtpPort)); } } // Connect self::ReceiveResponse('220', 'CONNECT'); // EHLO self::SendCommand(sprintf('EHLO %s', QEmailServer::$OriginatingServerIp)); self::ReceiveResponse('250', 'EHLO'); // AUTH PLAIN if (QEmailServer::$AuthPlain) { $strAuthorization = base64_encode(QEmailServer::$SmtpUsername . "" . QEmailServer::$SmtpUsername . "" . QEmailServer::$SmtpPassword); self::SendCommand(sprintf('AUTH PLAIN %s', $strAuthorization)); self::ReceiveResponse('235', 'AUTH PLAIN'); } // AUTH LOGIN if (QEmailServer::$AuthLogin) { $strUsername = base64_encode(QEmailServer::$SmtpUsername); $strPassword = base64_encode(QEmailServer::$SmtpPassword); self::SendCommand('AUTH LOGIN'); self::ReceiveResponse('334', 'AUTH LOGIN'); self::SendCommand($strUsername); self::ReceiveResponse('334', 'AUTH LOGIN - USERNAME'); self::SendCommand($strPassword); self::ReceiveResponse('235', 'AUTH LOGIN - PASSWORD'); } // MAIL FROM self::SendCommand(sprintf('MAIL FROM:<%s>', $strMailFrom)); self::ReceiveResponse('250', 'MAIL FROM'); // RCPT TO foreach ($strRcptToArray as $strRcptTo) { self::SendCommand(sprintf('RCPT TO:<%s>', $strRcptTo)); self::ReceiveResponse('250', 'RCPT TO for ' . $strRcptTo); } // DATA self::SendCommand('DATA'); self::ReceiveResponse('354', 'DATA'); // Header if (is_array($mixMessageHeader)) { foreach ($mixMessageHeader as $strName => $mixValue) { if (is_array($mixValue)) { foreach ($mixValue as $strValue) { self::SendData(sprintf("%s: %s\r\n", $strName, $strValue)); } } else { self::SendData(sprintf("%s: %s\r\n", $strName, $mixValue)); } } } else { self::SendData(trim($mixMessageHeader) . "\r\n"); } self::SendData("\r\n"); // Body self::SendData(str_replace("\n.", "\n..", trim($strMessageBody))); // Message End self::SendData("\r\n.\r\n"); self::ReceiveResponse('250', 'DATA FINISH'); // QUIT self::SendCommand('QUIT'); // Clear Buffer and Close Resource if (!feof(self::$objSmtpSocket)) { fgets(self::$objSmtpSocket); } fclose(self::$objSmtpSocket); if (QEmailServer::$TestMode) { chmod($strFileName, 0777); } }