php-mail-client/src/Deblan/MailClient/Client.php
2016-03-30 21:15:06 +02:00

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;
}
}