*
* 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);
}
);
}
);
}
// }}}
}
?>