From 4b24f236c8b3f658c15ba62ee0553a87d1153438 Mon Sep 17 00:00:00 2001 From: afinogen Date: Thu, 9 Jun 2016 14:04:09 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=D0=B3=20=D0=BA=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/test-file.php | 6 ++-- example/test-pop3.php | 9 +++++- src/message/Attachment.php | 1 + src/message/Content.php | 3 +- src/message/Headers.php | 36 +++++++++++---------- src/message/Message.php | 40 ++++++++++++++++------- src/protocol/File.php | 34 +++++++++++++++----- src/protocol/Pop3.php | 65 ++++++++++++++++++++++---------------- src/storage/File.php | 5 +++ src/storage/Pop3.php | 23 ++++++++------ 10 files changed, 143 insertions(+), 79 deletions(-) diff --git a/example/test-file.php b/example/test-file.php index fbb7782..d4cd5ef 100644 --- a/example/test-file.php +++ b/example/test-file.php @@ -30,16 +30,16 @@ //Перебор всех писем //echo $storage->countMessage().PHP_EOL; -for($i=0; $i< $storage->countMessage(); $i++) { +for ($i = 0; $i < $storage->countMessage(); $i++) { echo PHP_EOL.'---------------------------------------- '.$i.' ------------------------------------------------'.PHP_EOL; - + $msg = $storage->getMessage($i); echo $msg->getHeaders()->getFrom().PHP_EOL; echo $msg->getHeaders()->getFromName().PHP_EOL; echo $msg->getHeaders()->getTo().PHP_EOL; echo $msg->getHeaders()->getCC().PHP_EOL; - + echo $msg->getHeaders()->getSubject().PHP_EOL; foreach ($msg->getParts() as $part) { diff --git a/example/test-pop3.php b/example/test-pop3.php index 6d930ca..115169c 100644 --- a/example/test-pop3.php +++ b/example/test-pop3.php @@ -9,7 +9,14 @@ // Composer require('../vendor/autoload.php'); -$storage = new \afinogen89\getmail\storage\Pop3(['host' => 'pop.gmail.com', 'user' => 'test@gmail.com', 'password' => '123456', 'ssl' => 'SSL']); +$storage = new \afinogen89\getmail\storage\Pop3( + [ + 'host' => 'pop.gmail.com', + 'user' => 'test@gmail.com', + 'password' => '123456', + 'ssl' => 'SSL' + ] +); echo $storage->countMessages().PHP_EOL; diff --git a/src/message/Attachment.php b/src/message/Attachment.php index c0b0029..020e747 100644 --- a/src/message/Attachment.php +++ b/src/message/Attachment.php @@ -4,6 +4,7 @@ /** * Class Attachment + * * @package storage */ class Attachment diff --git a/src/message/Content.php b/src/message/Content.php index 2593793..3f2e4dd 100644 --- a/src/message/Content.php +++ b/src/message/Content.php @@ -4,6 +4,7 @@ /** * Class Content + * * @package storage */ class Content @@ -47,7 +48,7 @@ public function getContentDecode() $content = ''; if ($this->transferEncoding == 'base64') { $content = base64_decode($this->content); - } else if ($this->transferEncoding == 'quoted-printable'){ + } elseif ($this->transferEncoding == 'quoted-printable') { $content = quoted_printable_decode($this->content); } else { $content = $this->content; diff --git a/src/message/Headers.php b/src/message/Headers.php index 8d700d6..b43f07c 100644 --- a/src/message/Headers.php +++ b/src/message/Headers.php @@ -4,6 +4,7 @@ /** * Class Headers + * * @package storage */ class Headers @@ -36,7 +37,7 @@ class Headers /** @var string */ private $_transferEncoding; /** @var bool */ - private $_isAutoReply; + private $_isAutoReply; /** * @param string $headers @@ -60,38 +61,37 @@ protected function parserHeaders() $this->_subject = isset($headers['subject']) ? self::decodeMimeString(current($headers['subject'])) : ''; preg_match(self::EMAIL_PATTERN, $this->_from, $email); - if(!empty($email)){ - $email= $email[0]; - }else{ + if (!empty($email)) { + $email = $email[0]; + } else { $email = null; new \Exception('Email not found in "'.$this->_from.'"'); } $this->_fromName = str_replace($email, '', $this->_from); $this->_fromName = trim($this->_fromName, '<>,'); - $this->_fromName = trim($this->_fromName,' "'); + $this->_fromName = trim($this->_fromName, ' "'); $this->_from = $email; //TODO может быть несколько получателей preg_match(self::EMAIL_PATTERN, $this->_to, $email); - if(!empty($email)){ + if (!empty($email)) { $this->_to = $email[0]; } $part = current($headers['content-type']); $this->_messageContentType = trim(explode(';', $part)[0]); - if (preg_match_all('/(boundary|charset)\s*\=\s*["\']?([\w\-\/\=]+)/i', $part, $result)) - { - foreach($result[1] as $key=>$val) { + if (preg_match_all('/(boundary|charset)\s*\=\s*["\']?([\w\-\/\=]+)/i', $part, $result)) { + foreach ($result[1] as $key => $val) { $val = '_'.strtolower($val); $this->{$val} = $result[2][$key]; } } - + $this->parseAutoReply(); - + if (isset($headers['content-transfer-encoding'])) { $this->_transferEncoding = trim(current($headers['content-transfer-encoding'])); } @@ -101,7 +101,7 @@ public function parseAutoReply() { //TODO проверить другие варианты $replays = ['auto-replied']; - + $headers = $this->asArray(); if (isset($headers['auto-submitted']) && is_array($headers['auto-submitted'])) { $headers['auto-submitted'] = current($headers['auto-submitted']); @@ -118,13 +118,14 @@ public function parseAutoReply() /** * @param string $strMime + * * @return string */ public static function decodeMimeString($strMime) { $items = preg_split('/[\r\n]{2,}/si', $strMime); $result = ''; - foreach($items as $item) { + foreach ($items as $item) { $data = explode('?', $item); $str = ''; if (!empty($data)) { @@ -133,11 +134,11 @@ public static function decodeMimeString($strMime) $type = strtoupper(array_shift($data)); if ($type == 'B') { $str = base64_decode(array_shift($data)); - $str = $str . ltrim($data[0], '='); + $str = $str.ltrim($data[0], '='); } elseif ($type == 'Q') { $str = quoted_printable_decode(array_shift($data)); } - if (!empty($encode)){ + if (!empty($encode)) { $str = mb_convert_encoding($str, 'UTF-8', $encode); } } @@ -253,16 +254,17 @@ public function asArray() /** * @param string $headers + * * @return array */ public static function toArray($headers) { $headers .= "\r\n\r\n"; - preg_match_all('#[\r\n]*([\w-]+\:)(.+?)(?=([\r\n]+[\w-]+\:|[\r\n]{3,}|\n{2,}))#si',$headers,$result); + preg_match_all('#[\r\n]*([\w-]+\:)(.+?)(?=([\r\n]+[\w-]+\:|[\r\n]{3,}|\n{2,}))#si', $headers, $result); $headers = []; foreach ($result[1] as $k => $header) { - $header = strtolower(rtrim($header , ':')); + $header = strtolower(rtrim($header, ':')); $headers[$header][] = trim($result[2][$k]); } diff --git a/src/message/Message.php b/src/message/Message.php index eeb973a..b69a963 100644 --- a/src/message/Message.php +++ b/src/message/Message.php @@ -4,6 +4,7 @@ /** * Class Message + * * @package storage */ class Message @@ -48,6 +49,7 @@ public function __construct($header, $message, $id = null) /** * @param string $path + * * @return int */ public function saveToFile($path) @@ -89,6 +91,7 @@ public function getAttachments() /** * Текст письма + * * @return Content|null */ public function getMsgBody() @@ -114,6 +117,7 @@ public function getMsgBody() /** * Альтернативный текст письма + * * @return Content|null */ public function getMsgAlternativeBody() @@ -130,6 +134,7 @@ public function getMsgAlternativeBody() /** * Разбор тела сообщения + * * @param string $boundary * @param string $content */ @@ -155,7 +160,9 @@ protected function parserContent($boundary, $content) $type = trim($data[0]); //get body message - if ($type == Content::CT_MULTIPART_ALTERNATIVE || $type == Content::CT_TEXT_HTML || $type == Content::CT_TEXT_PLAIN || $type == Content::CT_MESSAGE_DELIVERY) { + if ($type == Content::CT_MULTIPART_ALTERNATIVE || $type == Content::CT_TEXT_HTML || $type == Content::CT_TEXT_PLAIN + || $type == Content::CT_MESSAGE_DELIVERY + ) { $this->parserBodyMessage($part); } elseif ($type == Content::CT_MESSAGE_RFC822) { $this->parserBodyMessage($part); @@ -246,7 +253,7 @@ protected function parserAttachment($part) $data = explode(';', current($headers['content-type'])); $attachment->contentType = trim($data[0]); - + array_shift($data); if (count($data) == 1) { $name = preg_replace('#.*name\s*\=\s*[\'"]([^\'"]+).*#si', '$1', $data[0]); @@ -261,7 +268,12 @@ protected function parserAttachment($part) } $name = Headers::decodeMimeString($name); - $encode = mb_detect_encoding($name, ['UTF-8', 'Windows-1251']); + $encode = mb_detect_encoding( + $name, [ + 'UTF-8', + 'Windows-1251' + ] + ); if ($encode && $encode !== 'UTF-8') { $name = mb_convert_encoding($name, 'UTF-8', $encode); } @@ -272,12 +284,12 @@ protected function parserAttachment($part) if (isset($headers['content-disposition'])) { $data = explode(';', current($headers['content-disposition'])); $attachment->contentDisposition = trim($data[0]); - + $tmpName = $data; unset($tmpName[0]); - foreach($tmpName as $key=>$val) { - if (preg_match('/[\w\-]{3,}\=/i', trim($val), $result) && stripos($result[0], 'name') ===false) { + foreach ($tmpName as $key => $val) { + if (preg_match('/[\w\-]{3,}\=/i', trim($val), $result) && stripos($result[0], 'name') === false) { unset($tmpName[$key]); } else { $tmpName[$key] = preg_replace('/(file)?name\s*(\*\d+\*)?\s*\=/i', '', $val); @@ -285,10 +297,10 @@ protected function parserAttachment($part) } $tmpName = implode($tmpName); - $tmpName=preg_replace('#\s+#s',"\n\n",$tmpName); - if(preg_match_all($pattern, $tmpName, $result)){ + $tmpName = preg_replace('#\s+#s', "\n\n", $tmpName); + if (preg_match_all($pattern, $tmpName, $result)) { $name = []; - foreach($result[3] as $v){ + foreach ($result[3] as $v) { $name[] = $v; } @@ -299,9 +311,9 @@ protected function parserAttachment($part) if (mb_detect_encoding($name) != 'UTF-8') { $name = mb_convert_encoding($name, 'UTF-8'); } - + $attachment->filename = $name; - }else{ + } else { $name = trim(preg_replace('/(file)?name\s*(\*\d+\*)?\s*\=/i', '', $name)); $attachment->filename = $name;//Headers::decodeMimeString($name); } @@ -322,12 +334,16 @@ protected function parserAttachment($part) /** * @param string $str + * * @return array */ public static function splitContent($str) { $data = preg_split('/[\r\n]{3,}/si', $str); - return ['header' => array_shift($data), 'content' => implode("\r\n", $data)]; + return [ + 'header' => array_shift($data), + 'content' => implode("\r\n", $data) + ]; } } \ No newline at end of file diff --git a/src/protocol/File.php b/src/protocol/File.php index 76931a2..29cea34 100644 --- a/src/protocol/File.php +++ b/src/protocol/File.php @@ -1,10 +1,12 @@ _path = rtrim($path, '/'); $this->readDir(); - } else if (is_file($path)) { + } elseif (is_file($path)) { $path_info = pathinfo($path); if ($path_info['extension'] == 'eml') { - $this->_mails[] = ['is_deleted' => 0, 'file_name' => $path]; + $this->_mails[] = [ + 'is_deleted' => 0, + 'file_name' => $path + ]; } } else { new \Exception('$path может быть либо папкой либо файлом'); @@ -48,7 +54,7 @@ public function __destruct() public function logout() { if ($this->_mails) { - foreach($this->_mails as $mail) { + foreach ($this->_mails as $mail) { if ($mail['is_deleted']) { unlink($this->_path.'/'.$mail['file_name']); } @@ -62,16 +68,20 @@ public function logout() public function readDir() { $files = scandir($this->_path); - foreach($files as $file) { + foreach ($files as $file) { $path_info = pathinfo($file); if ($path_info['extension'] == 'eml') { - $this->_mails[] = ['is_deleted' => 0, 'file_name' => $file]; + $this->_mails[] = [ + 'is_deleted' => 0, + 'file_name' => $file + ]; } } } /** * Количество сообщений + * * @return int */ public function countMessage() @@ -81,7 +91,9 @@ public function countMessage() /** * Получение размера писем + * * @param null|int $id + * * @return array|null */ public function getList($id = null) @@ -92,7 +104,7 @@ public function getList($id = null) } $result = []; - foreach($this->_mails as $mail) { + foreach ($this->_mails as $mail) { $result[] = filesize($this->_path.'/'.$mail['file_name']); } return $result; @@ -102,6 +114,7 @@ public function getList($id = null) /** * Удаление письма по номеру в списке + * * @param int $id */ public function delete($id) @@ -113,6 +126,7 @@ public function delete($id) /** * Отмена удаления письмо по id или всех писем в списке + * * @param null|int $id */ public function undelete($id = null) @@ -121,7 +135,7 @@ public function undelete($id = null) if ($id != null && isset($this->_mails[$id])) { $this->_mails[$id]['is_deleted'] = false; } else { - foreach($this->_mails as $mail) { + foreach ($this->_mails as $mail) { $mail['is_deleted'] = false; } } @@ -130,7 +144,9 @@ public function undelete($id = null) /** * Получение заголовков письма + * * @param $id + * * @return null|string */ public function top($id) @@ -152,7 +168,9 @@ public function top($id) /** * Получение всего контента письма + * * @param $id + * * @return null|string */ public function retrieve($id) diff --git a/src/protocol/Pop3.php b/src/protocol/Pop3.php index f932633..12e6fa1 100644 --- a/src/protocol/Pop3.php +++ b/src/protocol/Pop3.php @@ -4,16 +4,17 @@ /** * Class Pop3 + * * @package protocol */ class Pop3 { - /** @var int */ + /** @var int */ public $timeoutConnection = 30; private $hasTop; - /** @var */ + /** @var */ private $_socket; /** @var int */ @@ -42,9 +43,10 @@ public function __destruct() /** * Open connection to POP3 server * - * @param string $host hostname or IP address of POP3 server - * @param int|null $port of POP3 server, default is 110 (995 for ssl) - * @param string|bool $ssl use 'SSL', 'TLS' or false + * @param string $host hostname or IP address of POP3 server + * @param int|null $port of POP3 server, default is 110 (995 for ssl) + * @param string|bool $ssl use 'SSL', 'TLS' or false + * * @throws \RuntimeException * @return string welcome message */ @@ -58,7 +60,7 @@ public function connect($host, $port = null, $ssl = false) switch ($ssl) { case 'ssl': - $host = 'ssl://' . $host; + $host = 'ssl://'.$host; if (!$port) { $port = 995; } @@ -74,7 +76,7 @@ public function connect($host, $port = null, $ssl = false) try { $this->_socket = fsockopen($host, $port, $errno, $errstr, $this->timeoutConnection); - }catch (\Exception $e) { + } catch (\Exception $e) { //throw new \RuntimeException('cannot connect to host '.$host.PHP_EOL.$errstr, $errno); } @@ -89,7 +91,7 @@ public function connect($host, $port = null, $ssl = false) if (!strpos($this->_timestamp, '@')) { $this->_timestamp = null; } else { - $this->_timestamp = '<' . $this->_timestamp . '>'; + $this->_timestamp = '<'.$this->_timestamp.'>'; } if ($isTls) { @@ -107,13 +109,14 @@ public function connect($host, $port = null, $ssl = false) * Send a request * * @param string $request your request without newline + * * @throws \RuntimeException */ public function sendRequest($request) { try { - $result = fputs($this->_socket, $request . "\r\n"); - }catch (\Exception $e) { + $result = fputs($this->_socket, $request."\r\n"); + } catch (\Exception $e) { } @@ -126,6 +129,7 @@ public function sendRequest($request) * read a response * * @param bool $multiline response has multiple lines and should be read until "." + * * @throws \RuntimeException * @return string response */ @@ -133,7 +137,7 @@ public function readResponse($multiline = false) { try { $result = fgets($this->_socket); - }catch (\Exception $e){ + } catch (\Exception $e) { } @@ -173,8 +177,10 @@ public function readResponse($multiline = false) * * @see sendRequest() * @see readResponse() - * @param string $request request - * @param bool $multiline multiline response? + * + * @param string $request request + * @param bool $multiline multiline response? + * * @return string result from readResponse() */ public function request($request, $multiline = false) @@ -216,15 +222,15 @@ public function capa() /** * Login to POP3 server. Can use APOP * - * @param string $user username + * @param string $user username * @param string $password password - * @param bool $tryApop should APOP be tried? + * @param bool $tryApop should APOP be tried? */ public function login($user, $password, $tryApop = true) { if ($tryApop && $this->_timestamp) { try { - $this->request("APOP $user " . md5($this->_timestamp . $password)); + $this->request("APOP $user ".md5($this->_timestamp.$password)); return; } catch (\Exception $e) { // ignore @@ -239,8 +245,8 @@ public function login($user, $password, $tryApop = true) /** * Make STAT call for message count and size sum * - * @param int $messages out parameter with count of messages - * @param int $octets out parameter with size in octets of messages + * @param int $messages out parameter with count of messages + * @param int $octets out parameter with size in octets of messages */ public function status(&$messages, &$octets) { @@ -256,6 +262,7 @@ public function status(&$messages, &$octets) * Make LIST call for size of message(s) * * @param int|null $msgno number of message, null for all + * * @return int|array size of given message or list with array(num => size) */ public function getList($msgno = null) @@ -264,15 +271,15 @@ public function getList($msgno = null) $result = $this->request("LIST $msgno"); list(, $result) = explode(' ', $result); - return (int) $result; + return (int)$result; } $result = $this->request('LIST', true); - $messages = array(); + $messages = []; $line = strtok($result, "\n"); while ($line) { list($no, $size) = explode(' ', trim($line)); - $messages[(int) $no] = (int) $size; + $messages[(int)$no] = (int)$size; $line = strtok("\n"); } @@ -284,6 +291,7 @@ public function getList($msgno = null) * Make UIDL call for getting a uniqueid * * @param int|null $msgno number of message, null for all + * * @return string|array uniqueid of message or list with array(num => uniqueid) */ public function uniqueid($msgno = null) @@ -298,13 +306,13 @@ public function uniqueid($msgno = null) $result = $this->request('UIDL', true); $result = explode("\n", $result); - $messages = array(); + $messages = []; foreach ($result as $line) { if (!$line) { continue; } list($no, $id) = explode(' ', trim($line), 2); - $messages[(int) $no] = $id; + $messages[(int)$no] = $id; } return $messages; @@ -314,13 +322,13 @@ public function uniqueid($msgno = null) /** * Make TOP call for getting headers and maybe some body lines * This method also sets hasTop - before it it's not known if top is supported - * * The fallback makes normal RETR call, which retrieves the whole message. Additional * lines are not removed. * - * @param int $msgno number of message - * @param int $lines number of wanted body lines (empty line is inserted after header lines) + * @param int $msgno number of message + * @param int $lines number of wanted body lines (empty line is inserted after header lines) * @param bool $fallback fallback with full retrieve if top is not supported + * * @throws \RuntimeException * @throws \Exception * @return string message headers with wanted body lines @@ -336,7 +344,7 @@ public function top($msgno, $lines = 0, $fallback = false) } $this->hasTop = true; - $lines = (!$lines || $lines < 1) ? 0 : (int) $lines; + $lines = (!$lines || $lines < 1) ? 0 : (int)$lines; try { $result = $this->request("TOP $msgno $lines", true); @@ -355,7 +363,8 @@ public function top($msgno, $lines = 0, $fallback = false) /** * Make a RETR call for retrieving a full message with headers and body * - * @param int $msgno message number + * @param int $msgno message number + * * @return string message */ public function retrieve($msgno) diff --git a/src/storage/File.php b/src/storage/File.php index 026564c..7477a9d 100644 --- a/src/storage/File.php +++ b/src/storage/File.php @@ -7,6 +7,7 @@ /** * Class File + * * @package afinogen89\getmail\storage */ class File @@ -21,6 +22,7 @@ public function __construct($path) /** * Получение количества сообщений + * * @return int */ public function countMessage() @@ -38,6 +40,7 @@ public function close() /** * Удаление сообщения + * * @param int $id */ public function removeMessage($id) @@ -47,7 +50,9 @@ public function removeMessage($id) /** * Получение сообщения + * * @param int $id + * * @return Message */ public function getMessage($id) diff --git a/src/storage/Pop3.php b/src/storage/Pop3.php index 27921af..a2ae055 100644 --- a/src/storage/Pop3.php +++ b/src/storage/Pop3.php @@ -7,11 +7,12 @@ /** * Class Pop3 + * * @package storage */ class Pop3 { - /** @var protocol\Pop3 */ + /** @var protocol\Pop3 */ private $_protocol; /** @@ -20,7 +21,7 @@ class Pop3 public function __construct($params) { if (is_array($params)) { - $params = (object) $params; + $params = (object)$params; } if ($params instanceof protocol\Pop3) { @@ -32,10 +33,10 @@ public function __construct($params) throw new \InvalidArgumentException('need at least user in params'); } - $host = isset($params->host) ? $params->host : 'localhost'; + $host = isset($params->host) ? $params->host : 'localhost'; $password = isset($params->password) ? $params->password : ''; - $port = isset($params->port) ? $params->port : null; - $ssl = isset($params->ssl) ? $params->ssl : false; + $port = isset($params->port) ? $params->port : null; + $ssl = isset($params->ssl) ? $params->ssl : false; $this->_protocol = new protocol\Pop3(); $this->_protocol->connect($host, $port, $ssl); @@ -44,14 +45,15 @@ public function __construct($params) /** * Count Message + * * @return int */ public function countMessages() { - $count = 0; // "Declare" variable before first usage. + $count = 0; // "Declare" variable before first usage. $octets = 0; // "Declare" variable since it's passed by reference $this->_protocol->status($count, $octets); - return (int) $count; + return (int)$count; } /** @@ -79,6 +81,7 @@ public function noop() * identify the message. * * @param int $id number of message + * * @throws \RuntimeException */ public function removeMessage($id) @@ -88,10 +91,10 @@ public function removeMessage($id) /** * get unique id for one or all messages - * * if storage does not support unique ids it's the same as the message number * * @param int|null $id message number + * * @return array|string message number for given message or all messages as array * @throws \ExceptionInterface */ @@ -103,7 +106,7 @@ public function getUniqueId($id = null) } $count = $this->countMessages(); if ($count < 1) { - return array(); + return []; } $range = range(1, $count); return array_combine($range, $range); @@ -114,7 +117,9 @@ public function getUniqueId($id = null) /** * Fetch message + * * @param int $id + * * @return Message * @throws \Exception * @throws protocol\Exception