454 lines
9.8 KiB
PHP
454 lines
9.8 KiB
PHP
<?php
|
|
|
|
namespace Deblan\MailClient;
|
|
|
|
use Deblan\MailClient\Parser\Parser;
|
|
|
|
/**
|
|
* Class Client
|
|
* @author Simon Vieille <simon@deblan.fr>
|
|
*/
|
|
class Client
|
|
{
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $host;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $port;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $protocol;
|
|
|
|
/**
|
|
* @var boolean
|
|
*/
|
|
protected $ssl;
|
|
|
|
/**
|
|
* @var boolean
|
|
*/
|
|
protected $validateCertificate;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $inbox;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $username;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $password;
|
|
|
|
/**
|
|
* @var resource
|
|
*/
|
|
protected $conn;
|
|
|
|
/**
|
|
* @var Parser
|
|
*/
|
|
protected $parser;
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public function __construct(Parser $parser)
|
|
{
|
|
$this->setSsl(true);
|
|
$this->setValidateCertificate(false);
|
|
$this->setInbox('INBOX');
|
|
$this->setProtocol('imap');
|
|
$this->setParser($parser);
|
|
}
|
|
|
|
/**
|
|
* @param Parser $parser
|
|
* @return Client
|
|
*/
|
|
public function setParser(Parser $parser)
|
|
{
|
|
$this->parser = $parser;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return Parser $parser
|
|
*/
|
|
public function getParser()
|
|
{
|
|
return $this->parser;
|
|
}
|
|
|
|
/**
|
|
* Connect to mail server.
|
|
*
|
|
* @return boolean Successfull connection
|
|
*/
|
|
public function connect()
|
|
{
|
|
if ($this->conn !== null) {
|
|
return true;
|
|
}
|
|
|
|
$this->conn = @imap_open(
|
|
$this->getMailbox(),
|
|
$this->getUsername(),
|
|
$this->getPassword()
|
|
);
|
|
|
|
return $this->conn !== false;
|
|
}
|
|
|
|
/**
|
|
* @return resource|null The connection
|
|
*/
|
|
public function getLink()
|
|
{
|
|
return $this->getConnection();
|
|
}
|
|
|
|
/**
|
|
* @return resource|null The connection
|
|
*/
|
|
public function getConnection()
|
|
{
|
|
return $this->conn;
|
|
}
|
|
|
|
/**
|
|
* Close connection.
|
|
*
|
|
* @return boolean Successfull closing
|
|
*/
|
|
public function close()
|
|
{
|
|
if ($this->conn) {
|
|
return imap_close($this->conn);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Search mails
|
|
*
|
|
* @param string $criteria Search criteria
|
|
* @see https://secure.php.net/manual/fr/function.imap-search.php
|
|
* @return array $mails
|
|
*/
|
|
public function search(Criteria $criteria = null)
|
|
{
|
|
if (null === $criteria) {
|
|
$criteria = Criteria::create();
|
|
}
|
|
|
|
$mails = imap_search($this->conn, $criteria->build());
|
|
|
|
if (!is_array($mails)) {
|
|
$mails = [];
|
|
} else {
|
|
foreach ($mails as $k => $v) {
|
|
$mails[$k] = $this->fetchMail($v);
|
|
}
|
|
}
|
|
|
|
return $mails;
|
|
}
|
|
|
|
/**
|
|
* Fetch and parse an mail by resource
|
|
*
|
|
* @param resource $resource
|
|
* @param int $option The optional options are a bit mask with one or more of the following: FT_UID, FT_PEEK, FT_INTERNAL
|
|
* @return MimeMailParser
|
|
*/
|
|
public function fetchMail($resource, $options = 0)
|
|
{
|
|
$header = imap_fetchheader($this->conn, $resource);
|
|
$body = imap_body($this->conn, $resource, (int) $options);
|
|
$text = implode("\r\n", [$header, $body]);
|
|
|
|
$text = iconv(mb_detect_encoding($text, 'UTF-8, ASCII, ISO-8859-1, ISO-8859-15'), 'UTF-8', $text);
|
|
|
|
$mail = clone $this->parser;
|
|
$mail->setText($text);
|
|
$mail->setResource($resource);
|
|
$mail->setOverview(imap_fetch_overview($this->conn, $resource)[0]);
|
|
|
|
return $mail;
|
|
}
|
|
|
|
/**
|
|
* Sets flags on messages
|
|
*
|
|
* @param string $sequence A sequence of message numbers. You can enumerate desired messages with the X,Y syntax, or retrieve all messages within an interval with the X:Y syntax
|
|
* @param string $flag The flags which you can set are \Seen, \Answered, \Flagged, \Deleted, and \Draft as defined by » RFC2060.
|
|
* @param int $options The optional options are a bit mask with one or more of the following: FT_UID, FT_PEEK, FT_INTERNAL
|
|
* @return Client
|
|
*/
|
|
public function setFlag($sequence, $flag, $options = 0)
|
|
{
|
|
imap_setflag_full($this->conn, $sequence, $flag, $options);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Sets flags on message
|
|
*
|
|
* @param string $number The message number.
|
|
* @param string $flag The flags which you can set are \Seen, \Answered, \Flagged, \Deleted, and \Draft as defined by » RFC2060.
|
|
* @param int $options The optional options are a bit mask with one or more of the following: FT_UID, FT_PEEK, FT_INTERNAL
|
|
* @return Client
|
|
*/
|
|
public function setFlagOnMessage($number, $flag, $options = 0)
|
|
{
|
|
return $this->setFlag((int) $number, $flag, $options);
|
|
}
|
|
|
|
/**
|
|
* Unsets flags on messages
|
|
*
|
|
* @param string $sequence A sequence of message numbers. You can enumerate desired messages with the X,Y syntax, or retrieve all messages within an interval with the X:Y syntax
|
|
* @param string $flag The flags which you can unset are \Seen, \Answered, \Flagged, \Deleted, and \Draft as defined by » RFC2060.
|
|
* @param int $options The optional options are a bit mask with one or more of the following: ST_UID
|
|
* @return Client
|
|
*/
|
|
public function unsetFlag($sequence, $flag, $options = 0)
|
|
{
|
|
imap_clearflag_full($this->conn, $sequence, $flag, $options);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Unsets flags on message
|
|
*
|
|
* @param string $number The message number.
|
|
* @param string $flag The flags which you can unset are \Seen, \Answered, \Flagged, \Deleted, and \Draft as defined by » RFC2060.
|
|
* @param int $options The optional options are a bit mask with one or more of the following: ST_UID
|
|
* @return Client
|
|
*/
|
|
public function unsetFlagOnMessage($number, $flag, $options = 0)
|
|
{
|
|
return $this->unsetFlag((int) $number, $flag, $options);
|
|
}
|
|
|
|
/**
|
|
* Generates the mailbox path
|
|
*
|
|
* @return string Mailbox path
|
|
*/
|
|
public function getMailbox()
|
|
{
|
|
$mailbox = sprintf(
|
|
'{%1$s%5$s/%2$s/%3$s}%4$s',
|
|
$this->getHost(),
|
|
$this->getProtocol(),
|
|
$this->getMailboxSsl(),
|
|
$this->getInbox(),
|
|
$this->getPort() ? ':'.$this->getPort() : ''
|
|
);
|
|
|
|
return $mailbox;
|
|
}
|
|
|
|
/**
|
|
* Generates the mailbox ssl path
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getMailboxSsl()
|
|
{
|
|
$data = [];
|
|
|
|
if ($this->getSsl()) {
|
|
$data[] = 'ssl';
|
|
$data[] = $this->getValidateCertificate() ? 'validate-cert' : 'novalidate-cert';
|
|
}
|
|
|
|
return implode('/', $data);
|
|
}
|
|
|
|
/**
|
|
* @param string $host
|
|
* @return Client
|
|
*/
|
|
public function setHost($host)
|
|
{
|
|
$this->host = (string) $host;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string $host
|
|
*/
|
|
public function getHost()
|
|
{
|
|
return $this->host;
|
|
}
|
|
|
|
/**
|
|
* @param string $protocol
|
|
* @return Client
|
|
* @throws InvalidArgumentException Protocol not implemented
|
|
*/
|
|
public function setProtocol($protocol)
|
|
{
|
|
$protocol = (string) $protocol;
|
|
|
|
if (!in_array($protocol, self::getSupportedProtocols())) {
|
|
throw new InvalidArgumentException(sprintf('The protocol "%s" is not supported', $protocol));
|
|
}
|
|
|
|
$this->protocol = $protocol;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Returns the list of the supported procotols
|
|
*
|
|
* @return array Supported protocols
|
|
*/
|
|
public static function getSupportedProtocols()
|
|
{
|
|
return ['imap', 'imap2', 'imap2bis', 'imap4', 'imap4rev1', 'pop3'];
|
|
}
|
|
|
|
/**
|
|
* @param int $port
|
|
* @return Client
|
|
*/
|
|
public function setPort($port)
|
|
{
|
|
$this->port = (int) $port;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return int $port
|
|
*/
|
|
public function getPort()
|
|
{
|
|
return $this->port;
|
|
}
|
|
|
|
/**
|
|
* @return string $protocol
|
|
*/
|
|
public function getProtocol()
|
|
{
|
|
return $this->protocol;
|
|
}
|
|
|
|
/**
|
|
* @param bool $ssl
|
|
* @return Client
|
|
*/
|
|
public function setSsl($ssl)
|
|
{
|
|
$this->ssl = (bool) $ssl;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return bool $ssl
|
|
*/
|
|
public function getSsl()
|
|
{
|
|
return $this->ssl;
|
|
}
|
|
|
|
/**
|
|
* @param bool $validateCertificate
|
|
* @return Client
|
|
*/
|
|
public function setValidateCertificate($validateCertificate)
|
|
{
|
|
$this->validateCertificate = (bool) $validateCertificate;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return bool $validateCertificate
|
|
*/
|
|
public function getValidateCertificate()
|
|
{
|
|
return $this->validateCertificate;
|
|
}
|
|
|
|
/**
|
|
* @param string $inbox
|
|
* @return Client
|
|
*/
|
|
public function setInbox($inbox)
|
|
{
|
|
$this->inbox = (string) $inbox;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string $inbox
|
|
*/
|
|
public function getInbox()
|
|
{
|
|
return $this->inbox;
|
|
}
|
|
|
|
/**
|
|
* @param string $username
|
|
* @return Client
|
|
*/
|
|
public function setUsername($username)
|
|
{
|
|
$this->username = (string) $username;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string $username
|
|
*/
|
|
public function getUsername()
|
|
{
|
|
return $this->username;
|
|
}
|
|
|
|
/**
|
|
* @param string $password
|
|
* @return Client
|
|
*/
|
|
public function setPassword($password)
|
|
{
|
|
$this->password = (string) $password;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string $password
|
|
*/
|
|
public function getPassword()
|
|
{
|
|
return $this->password;
|
|
}
|
|
}
|