<?php class emailcatcher { protected string $sMailData='emaildata.txt'; protected string $sId=''; protected array $aSelectedEmail=[]; public function __construct() { $this->sMailData=dirname(__DIR__) . '/data/' . $this->sMailData; // $this->_readEmails(); } // ------------------------------------------------------------------ // STORE NEW EMAIL // ------------------------------------------------------------------ /** * Fetch email of a single email from stdin and store it. * It returns the return value of file_put_contents(). * * @return bool|int */ public function catchEmail(){ $fp = fopen('php://stdin', 'rb'); $sMaildata=''; while (!feof($fp)) { $sMaildata.=fgets($fp, 4096); } fclose($fp); return $this->storeEmail($sMaildata); } /** * Store a new email. * It returns the return value of file_put_contents(). * * @param string $sMaildata maildata with header and body * @return bool|int */ public function storeEmail($sMaildata): bool|int { $sLogentry=json_encode(["date"=>date("Y-m-d H:i:s"), "mail"=>$sMaildata])."\n"; return file_put_contents($this->sMailData, $sLogentry, FILE_APPEND | LOCK_EX); } // ------------------------------------------------------------------ // READ STORED DATA // ------------------------------------------------------------------ protected function _readEmails(string $sEmail2Show=''): array { if(!file_exists($this->sMailData)){ return []; } foreach(file($this->sMailData) as $line) { $aLinedata=json_decode($line, true); [$sHead, $sBody] = explode("\r\n\r\n", $aLinedata['mail']); $sHead="\n$sHead"; preg_match('/\nfrom: (.*)/i', $sHead, $aFrom); preg_match('/\nto: (.*)/i', $sHead, $aTo); preg_match('/\ncc: (.*)/i', $sHead, $aCc); preg_match('/\nbcc: (.*)/i', $sHead, $aBcc); preg_match('/\nsubject: (.*)/i', $sHead, $aSubject); preg_match('/\Content-Type: (.*)/i', $sHead, $aContentType); $aEntry=[ "date" => $aLinedata['date'], "from" => $aFrom[1] ?? false, "to" => $aTo[1] ?? false, "cc" => $aCc[1] ?? false, "bcc" => $aBcc[1] ?? false, "subject" => $aSubject[1] ?? false, "contentType" => $aContentType[1] ?? false, ]; $sId=md5($aEntry['date'].' - to '.$aEntry['to'].': '.$aEntry['subject']); $aEntry['id']=$sId; if($sId==$sEmail2Show){ $aEntry['head']=$sHead; $aEntry['body']=$sBody; return $aEntry; } $aEmails[$aLinedata['date']]=$aEntry; } krsort($aEmails); return $aEmails; } /** * Get a list of emails to render an inbox like selection. * It doesn't contain header and body - just metadata * * @return array */ public function readEmails(): array { return $this->_readEmails(); } // ------------------------------------------------------------------ // SINGLE EMAIL // ------------------------------------------------------------------ /** * Set a single email by id. * It returns a bool for success: false = failed * * @param string $sId * @return bool */ public function setId(string $sId): bool{ $this->sId=$sId; $this->aSelectedEmail=$this->_readEmails($sId); if(! isset($this->aSelectedEmail['id'])){ $this->sId=''; $this->aSelectedEmail=[]; return false; } return true; } /** * Get hash for a single email with all metadata and body * @param string $sEmail2Show optional: email id to show * @return array */ public function getEmail($sEmail2Show=''): array { if($sEmail2Show){ $this->setId($sEmail2Show); } return $this->aSelectedEmail; } /** * Get a Meta value of the selected email * @param string $sField * @return mixed */ public function getField(string $sField): mixed { return $this->aSelectedEmail[$sField] ?? null; } /** * Get message body of the selected email * @return mixed */ public function getBody(): mixed { return $this->getField('body'); } /** * get message header of the selected email * @return mixed */ public function getHeader(): mixed { return $this->getField('head'); } }