snappymail/rainloop/v/1.3.6.461/app/libraries/MailSo/Pop3/Pop3Client.php
RainLoop Team 486aedb57b v1.3.6.461
2013-10-29 04:54:17 +04:00

365 lines
7.7 KiB
PHP

<?php
namespace MailSo\Pop3;
/**
* @category MailSo
* @package Pop3
*/
class Pop3Client extends \MailSo\Net\NetClient
{
/**
* @var bool
*/
private $bIsLoggined;
/**
* @var int
*/
private $iRequestTime;
/**
* @var array
*/
private $aCapa;
/**
* @var string
*/
private $sLastMessage;
/**
* @access protected
*/
protected function __construct()
{
parent::__construct();
$this->bIsLoggined = false;
$this->iRequestTime = 0;
$this->aCapa = null;
$this->sLastMessage = '';
}
/**
* @return \MailSo\Pop3\Pop3Client
*/
public static function NewInstance()
{
return new self();
}
/**
* @param string $sServerName
* @param int $iPort = 110
* @param int $iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT
*
* @return \MailSo\Pop3\Pop3Client
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
* @throws \MailSo\Net\Exceptions\Exception
* @throws \MailSo\Pop3\Exceptions\ResponseException
*/
public function Connect($sServerName, $iPort = 110,
$iSecurityType = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT)
{
$this->iRequestTime = microtime(true);
parent::Connect($sServerName, $iPort, $iSecurityType);
$this->validateResponse();
if (\MailSo\Net\Enumerations\ConnectionSecurityType::UseStartTLS(
in_array('STLS', $this->Capa()), $this->iSecurityType))
{
$this->sendRequestWithCheck('STLS');
if (!@stream_socket_enable_crypto($this->rConnect, true, STREAM_CRYPTO_METHOD_TLS_CLIENT))
{
$this->writeLogException(
new \MailSo\Pop3\Exceptions\RuntimeException('Cannot enable STARTTLS'),
\MailSo\Log\Enumerations\Type::ERROR, true);
}
$this->aCapa = null;
}
else if (\MailSo\Net\Enumerations\ConnectionSecurityType::STARTTLS === $this->iSecurityType)
{
$this->writeLogException(
new \MailSo\Net\Exceptions\SocketUnsuppoterdSecureConnectionException('STARTTLS is not supported'),
\MailSo\Log\Enumerations\Type::ERROR, true);
}
return $this;
}
/**
* @param string $sLogin = ''
* @param string $sPassword = ''
*
* @return \MailSo\Pop3\Pop3Client
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
* @throws \MailSo\Net\Exceptions\Exception
* @throws \MailSo\Pop3\Exceptions\ResponseException
*/
public function Login($sLogin, $sPassword)
{
if ($this->bIsLoggined)
{
$this->writeLogException(
new Exceptions\RuntimeException('Already authenticated for this session'),
\MailSo\Log\Enumerations\Type::ERROR, true);
}
$sLogin = trim($sLogin);
$sPassword = $sPassword;
try
{
$this->sendRequestWithCheck('USER', $sLogin);
$this->sendRequestWithCheck('PASS', $sPassword);
}
catch (\MailSo\Pop3\Exceptions\NegativeResponseException $oException)
{
$this->writeLogException(
new \MailSo\Pop3\Exceptions\LoginBadCredentialsException(
$oException->GetResponses(), '', 0, $oException),
\MailSo\Log\Enumerations\Type::NOTICE, true);
}
$this->bIsLoggined = true;
$this->aCapa = null;
return $this;
}
/**
* @return bool
*/
public function IsLoggined()
{
return $this->IsConnected() && $this->bIsLoggined;
}
/**
* @return \MailSo\Pop3\Pop3Client
*
* @throws \MailSo\Net\Exceptions\Exception
* @throws \MailSo\Pop3\Exceptions\Exception
*/
public function Noop()
{
$this->sendRequestWithCheck('NOOP');
return $this;
}
/**
* @return array [MessagesCount, Size]
*
* @throws \MailSo\Net\Exceptions\Exception
* @throws \MailSo\Pop3\Exceptions\Exception
*/
public function Status()
{
$this->sendRequestWithCheck('STAT');
$iMessageCount = $iSize = 0;
sscanf($this->sLastMessage, '%d %d', $iMessageCount, $iSize);
return array((int) $iMessageCount, (int) $iSize);
}
/**
* @return \MailSo\Pop3\Pop3Client
*
* @throws \MailSo\Net\Exceptions\Exception
* @throws \MailSo\Pop3\Exceptions\Exception
*/
public function Capa()
{
if (null === $this->aCapa)
{
$this->sendRequestWithCheck('CAPA');
$this->aCapa = array_filter(explode("\n", $this->readMultilineResponse()), function (&$sCapa) {
return 0 < strlen(trim($sCapa));
});
$this->aCapa = array_map('trim', $this->aCapa);
}
return $this->aCapa;
}
/**
* @return \MailSo\Pop3\Pop3Client
*
* @throws \MailSo\Net\Exceptions\Exception
* @throws \MailSo\Pop3\Exceptions\Exception
*/
public function Logout()
{
if ($this->bIsLoggined)
{
$this->sendRequestWithCheck('QUIT');
}
$this->bIsLoggined = false;
return $this;
}
/**
* @param string $sCommand
* @param string $sAddToCommand = ''
*
* @return \MailSo\Pop3\Pop3Client
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
* @throws \MailSo\Net\Exceptions\Exception
*/
protected function sendRequest($sCommand, $sAddToCommand = '')
{
if (0 === strlen(trim($sCommand)))
{
$this->writeLogException(
new \MailSo\Base\Exceptions\InvalidArgumentException(),
\MailSo\Log\Enumerations\Type::ERROR, true);
}
$this->IsConnected(true);
$sCommand = trim($sCommand);
$sRealCommand = $sCommand.(0 === strlen($sAddToCommand) ? '' : ' '.$sAddToCommand);
$sFakeCommand = '';
$sFakeAddToCommand = $this->secureRequestParams($sCommand, $sAddToCommand);
if (0 < strlen($sFakeAddToCommand))
{
$sFakeCommand = $sCommand.' '.$sFakeAddToCommand;
}
$this->iRequestTime = microtime(true);
$this->sendRaw($sRealCommand, true, $sFakeCommand);
return $this;
}
/**
* @param string $sCommand
* @param string $sAddToCommand
*
* @return string
*/
private function secureRequestParams($sCommand, $sAddToCommand)
{
$sResult = null;
if (0 < strlen($sAddToCommand))
{
switch ($sCommand)
{
case 'PASS':
$sResult = '*******';
break;
}
}
return $sResult;
}
/**
* @param string $sCommand
* @param string $sAddToCommand = ''
*
* @return \MailSo\Pop3\Pop3Client
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
* @throws \MailSo\Net\Exceptions\Exception
* @throws \MailSo\Pop3\Exceptions\Exception
*/
private function sendRequestWithCheck($sCommand, $sAddToCommand = '')
{
$this->sendRequest($sCommand, $sAddToCommand);
return $this->validateResponse();
}
/**
* @return string
*
* @throws \MailSo\Net\Exceptions\Exception
* @throws \MailSo\Pop3\Exceptions\ResponseException
*/
private function validateResponse()
{
$this->getNextBuffer();
$this->sLastMessage = '';
$sStatus = $sMessage = '';
$sBuffer = trim($this->sResponseBuffer);
$sStatus = $sBuffer;
if (false !== strpos($sBuffer, ' '))
{
list($sStatus, $sMessage) = explode(' ', $sBuffer, 2);
}
$this->sLastMessage = $sMessage;
if ($sStatus != '+OK')
{
$this->writeLogException(
new Exceptions\NegativeResponseException(),
\MailSo\Log\Enumerations\Type::WARNING, true);
}
$this->writeLog((microtime(true) - $this->iRequestTime),
\MailSo\Log\Enumerations\Type::TIME);
}
/**
* @return string
*
* @throws \MailSo\Net\Exceptions\Exception
*/
private function readMultilineResponse()
{
$this->iRequestTime = microtime(true);
$sResult = '';
do
{
$this->getNextBuffer();
if (0 === strpos($this->sResponseBuffer, '.'))
{
$sResult .= substr($this->sResponseBuffer, 1);
}
else
{
$sResult .= $this->sResponseBuffer;
}
}
while ('.' !== rtrim($this->sResponseBuffer, "\r\n"));
$this->writeLog((microtime(true) - $this->iRequestTime),
\MailSo\Log\Enumerations\Type::TIME);
return $sResult;
}
/**
* @return string
*/
protected function getLogName()
{
return 'POP3';
}
/**
* @param \MailSo\Log\Logger $oLogger
* @return \MailSo\Pop3\Pop3Client
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
*/
public function SetLogger($oLogger)
{
parent::SetLogger($oLogger);
return $this;
}
}