132 lines
4.5 KiB
PHP
132 lines
4.5 KiB
PHP
<?php
|
|
class ImapDriver {
|
|
private $fp;
|
|
public $error;
|
|
private $commandCounter = "00000001";
|
|
public $lastResponse = array();
|
|
public $lastEndline = "";
|
|
|
|
public function init(string $host, int $port): bool {
|
|
$errno = 0;
|
|
$errstr = '';
|
|
if (!($this->fp = fsockopen($host, $port, $errno, $errstr, 15))) {
|
|
$this->error = "Could not connect to host ($errno) $errstr";
|
|
return false;
|
|
}
|
|
if (!stream_set_timeout($this->fp, 15)) {
|
|
$this->error = "Could not set timeout";
|
|
return false;
|
|
}
|
|
fgets($this->fp);
|
|
return true;
|
|
}
|
|
|
|
private function close(): void {
|
|
fclose($this->fp);
|
|
}
|
|
|
|
private function command(string $command): void {
|
|
$this->lastResponse = array();
|
|
$this->lastEndline = "";
|
|
fwrite($this->fp, "$this->commandCounter $command\r\n");
|
|
while ($line = trim(fgets($this->fp))) {
|
|
$encodedLine = mb_convert_encoding($line, 'UTF-8');
|
|
$line_arr = preg_split('/\s+/', $encodedLine, 0, PREG_SPLIT_NO_EMPTY);
|
|
if (count($line_arr) > 0) {
|
|
$code = array_shift($line_arr);
|
|
if (strtoupper($code) == $this->commandCounter) {
|
|
$this->lastEndline = join(' ', $line_arr);
|
|
break;
|
|
}
|
|
$this->lastResponse[] = $line;
|
|
} else {
|
|
$this->lastResponse[] = $line;
|
|
}
|
|
}
|
|
$this->incrementCounter();
|
|
}
|
|
|
|
private function incrementCounter(): void {
|
|
$this->commandCounter = sprintf('%08d', intval($this->commandCounter) + 1);
|
|
}
|
|
|
|
public function login(string $login, string $pwd): bool {
|
|
$this->command("LOGIN $login $pwd");
|
|
if (preg_match('~^OK~', $this->lastEndline)) {
|
|
return true;
|
|
}
|
|
$this->error = join(', ', $this->lastResponse);
|
|
$this->close();
|
|
return false;
|
|
}
|
|
|
|
public function selectFolder(string $folder): bool{
|
|
$this->command("SELECT $folder");
|
|
if (preg_match('~^OK~', $this->lastEndline)) {
|
|
return true;
|
|
}
|
|
$this->error = join(', ', $this->lastResponse);
|
|
$this->close();
|
|
return false;
|
|
}
|
|
|
|
public function getUidsBySearch(string $criteria): array|false {
|
|
$this->command("SEARCH $criteria");
|
|
if (preg_match('~^OK~', $this->lastEndline)
|
|
&& is_array($this->lastResponse)
|
|
&& count($this->lastResponse) == 1) {
|
|
$splitted_response = explode(' ', $this->lastResponse[0]);
|
|
$uids = array();
|
|
foreach ($splitted_response as $item) {
|
|
if (preg_match('~^\d+$~', $item)) {
|
|
$uids[] = $item;
|
|
}
|
|
}
|
|
return $uids;
|
|
}
|
|
$this->error = join(', ', $this->lastResponse);
|
|
$this->close();
|
|
return false;
|
|
}
|
|
|
|
public function getHeadersFromUid(int $uid): array|false {
|
|
$this->command("FETCH $uid BODY.PEEK[HEADER]");
|
|
if (!preg_match('~^OK~', $this->lastEndline)) {
|
|
array_shift($this->lastResponse);
|
|
$headers = array();
|
|
$prev_match = '';
|
|
foreach ($this->lastResponse as $item) {
|
|
$match = [];
|
|
if (preg_match('~^([a-z][a-z0-9-_]+):~is', $item, $match)) {
|
|
$header_name = strtolower($match[1]);
|
|
$prev_match = $header_name;
|
|
$headers[$header_name] = trim(substr($item, strlen($header_name) + 1));
|
|
|
|
} else {
|
|
$headers[] .= " " . $item;
|
|
}
|
|
}
|
|
return $headers;
|
|
}
|
|
$this->error = join(', ', $this->lastResponse);
|
|
$this->close();
|
|
return false;
|
|
}
|
|
|
|
public function getEmail(string|int $uid): array|false {
|
|
$this->command('FETCH ' . $uid . ' BODY');
|
|
if (preg_match('~^OK~', $this->lastEndline)) {
|
|
return $this->parseEmailBody($this->lastResponse[0]);
|
|
}
|
|
$this->error = join(', ', $this->lastResponse);
|
|
$this->close();
|
|
return false;
|
|
}
|
|
|
|
protected function parseEmailBody(string $body): array {
|
|
$contentStart = stripos($body, 'body (');
|
|
$content = substr($body, $contentStart + 6, -1);
|
|
print_r($content);die;
|
|
return [];
|
|
}
|
|
} |