* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . **/ require_once ('qcEvents/Hookable.php'); require_once ('qcEvents/Stream/SMTP/Client.php'); require_once ('qcEvents/Socket/Pool.php'); /** * SMTP-Client * ----------- * Simple SMTP-Client-Implementation (RFC 5321) * * @class qcEvents_Client_SMTP * @extends qcEvents_Hookable * @package qcEvents * @revision 02 * @author Bernd Holzmueller **/ class qcEvents_Client_SMTP extends qcEvents_Hookable { /* Socket-Pool */ private $Pool = null; /* Hostname or IP to use as SMTP-Server */ private $remoteHost = ''; /* Port to connect to */ private $remotePort = 25; /* Enable/Disable TLS-Encryption (NULL: Auto-detect) */ private $remoteTLS = null; /* Username for authentication */ private $remoteUser = null; /* Password for authentication */ private $remotePassword = null; // {{{ __construct /** * Create a new SMTP-Client * * @param qcEvents_Base $eventBase * * @access friendly * @return void **/ function __construct (qcEvents_Base $eventBase, $Hostname = null, $Port = null, $TLS = null) { // Create new socket-pool $this->Pool = new qcEvents_Socket_Pool ($eventBase); $this->Pool->addHook ('socketConnected', function (qcEvents_Socket_Pool $Pool, qcEvents_Socket $Socket) { // Create a new SMTP-Client $Client = new qcEvents_Stream_SMTP_Client; // Connect ourself with that socket return $Socket->pipeStream ($Client, true, function (qcEvents_Socket $Socket, $Status) use ($Client) { // Check if SMTP was setup correctly if (!$Status) return $this->Pool->releaseSocket ($Socket); // Check wheter to enable TLS if (($this->remoteTLS === true) && !$Client->hasFeature ('STARTTLS') && !$Socket->tlsEnable ()) return $this->Pool->releaseSocket ($Socket); // Try to enable TLS if (($this->remoteTLS !== false) && $Client->hasFeature ('STARTTLS') && !$Socket->tlsEnable ()) return $Client->startTLS (function (qcEvents_Stream_SMTP_Client $Client, $Status) use ($Socket) { // Check if TLS was enabled (and is required) if (!$Status && ($this->remoteTLS !== null)) return $this->Pool->releaseSocket ($Socket); // Check wheter to perform authentication if ($this->remoteUser === null) return $this->Pool->enableSocket ($Socket, $Client); // Try to authenticate return $Client->authenticate ( $this->remoteUser, $this->remotePassword, function (qcEvents_Stream_SMTP_Client $Client, $Username, $Status) use ($Socket) { if (!$Status) return $this->Pool->releaseSocket ($Socket); return $this->Pool->enableSocket ($Socket, $Client); } ); }); // Check wheter to perform authentication if ($this->remoteUser === null) return $this->Pool->enableSocket ($Socket, $Client); // Try to authenticate return $Client->authenticate ( $this->remoteUser, $this->remotePassword, function (qcEvents_Stream_SMTP_Client $Client, $Username, $Status) use ($Socket) { if (!$Status) return $this->Pool->releaseSocket ($Socket); return $this->Pool->enableSocket ($Socket, $Client); } ); }); }); // Setup ourself if ($Hostname !== null) $this->setRemoteHost ($Hostname, $Port, $TLS); } // }}} // {{{ setRemoteHost /** * Store IP/Hostname and port to connect to * * @param mixed $Host * @param int $Port (optional) * @param bool $enableTLS (optional) * * @access public * @return void **/ public function setRemoteHost ($Host, $Port = null, $enableTLS = null) { $this->remoteHost = $Host; $this->remotePort = ($Port === null ? null : (int)$Port); $this->remoteTLS = ($enableTLS === null ? null : !!$enableTLS); if ($this->remoteTLS === false) trigger_error ('Forcing TLS-Encyption OFF is NOT RECOMMENDED!'); } // }}} // {{{ setCredentials /** * Store username/password for authentication * * @param string $Username * @param string $Password * * @access public * @return void **/ public function setCredentials ($Username, $Password) { $this->remoteUser = $Username; $this->remotePassword = $Password; } // }}} // {{{ sendMail /** * @param string $Originator * @param array $Receivers * @param string $Mail * @param callable $Callback (optional) * @param mixed $Private (optional) * * The callback will be raised in the form of * * function (qcEvents_Client_SMTP $Self, bool $Status, mixed $Private = null) { } * * @access public * @return void **/ public function sendMail ($Originator, array $Receivers, $Mail, callable $Callback = null, $Private = null) { return $this->Pool->acquireSocket ( $this->remoteHost, ($this->remotePort === null ? 25 : $this->remotePort), qcEvents_Socket::TYPE_TCP, ($this->remotePort == 465), function (qcEvents_Socket_Pool $Pool, qcEvents_Socket $Socket = null, qcEvents_Interface_Stream_Consumer $Client = null) use ($Originator, $Receivers, $Mail, $Callback, $Private) { // Check if a socket was aquired if (!$Socket || !$Client || !($Client instanceof qcEvents_Stream_SMTP_Client)) { // Release the socket if ($Socket) $Pool->releaseSocket ($Socket); // Indicate an error return $this->___raiseCallback ($Callback, false, $Private); } // Try to send the mail return $Client->sendMail ( $Originator, $Receivers, $Mail, function (qcEvents_Stream_SMTP_Client $Client, $Originator, $Receivers, $Mail, $Status) use ($Pool, $Socket, $Callback, $Private) { // Release the socket $Pool->releaseSocket ($Socket); // Forward the result return $this->___raiseCallback ($Callback, $Status, $Private); } ); } ); } // }}} } ?>