Files
fvsjs/libs/imap_driver.php
Torsten Schulz 44da93c0e9 initial
2023-06-16 11:57:49 +02:00

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