正在显示
13 个修改的文件
包含
311 行增加
和
362 行删除
@@ -210,7 +210,7 @@ class Home extends Base { | @@ -210,7 +210,7 @@ class Home extends Base { | ||
210 | if(!empty($v['to_name'][0]['email'])){ | 210 | if(!empty($v['to_name'][0]['email'])){ |
211 | $v['to'] = $v['to_name'][0]['email']; | 211 | $v['to'] = $v['to_name'][0]['email']; |
212 | } | 212 | } |
213 | - $v['to_name'] = $v['to_name'][0]['name']??''; | 213 | + $v['to_name'] = MailFun::mb_coding($v['to_name'][0]['name']??''); |
214 | } | 214 | } |
215 | if(is_array($v['to_name'])){ | 215 | if(is_array($v['to_name'])){ |
216 | $v['to_name'] = ''; | 216 | $v['to_name'] = ''; |
@@ -840,6 +840,13 @@ class Home extends Base { | @@ -840,6 +840,13 @@ class Home extends Base { | ||
840 | $data['cc'] = $data['cc'] ? json_decode($data['cc'],true) : []; | 840 | $data['cc'] = $data['cc'] ? json_decode($data['cc'],true) : []; |
841 | $data['bcc'] = $data['bcc'] ? json_decode($data['bcc'],true) : []; | 841 | $data['bcc'] = $data['bcc'] ? json_decode($data['bcc'],true) : []; |
842 | 842 | ||
843 | + $data['to_name'] = array_map(function ($t){ | ||
844 | + if(empty($t['name'])){ | ||
845 | + $t['name'] = MailFun::mb_coding($t['name']); | ||
846 | + } | ||
847 | + return $t; | ||
848 | + },$data['to_name']); | ||
849 | + | ||
843 | // 是否再次 重新获取 | 850 | // 是否再次 重新获取 |
844 | $reload = app()->request('reload',0,'intval'); | 851 | $reload = app()->request('reload',0,'intval'); |
845 | if($reload){ | 852 | if($reload){ |
@@ -5,6 +5,7 @@ namespace Controller\fob_ai; | @@ -5,6 +5,7 @@ namespace Controller\fob_ai; | ||
5 | 5 | ||
6 | 6 | ||
7 | use Controller\Base; | 7 | use Controller\Base; |
8 | +use Lib\Mail\MailFun; | ||
8 | use Lib\Verify; | 9 | use Lib\Verify; |
9 | use Model\folderSql; | 10 | use Model\folderSql; |
10 | use function Swoole\Coroutine\Http\request; | 11 | use function Swoole\Coroutine\Http\request; |
@@ -246,7 +247,7 @@ class MailListV2 extends Base { | @@ -246,7 +247,7 @@ class MailListV2 extends Base { | ||
246 | if(!empty($v['to_name'][0]['email'])){ | 247 | if(!empty($v['to_name'][0]['email'])){ |
247 | $v['to'] = $v['to_name'][0]['email']; | 248 | $v['to'] = $v['to_name'][0]['email']; |
248 | } | 249 | } |
249 | - $v['to_name'] = $v['to_name'][0]['name']??''; | 250 | + $v['to_name'] = MailFun::mb_coding($v['to_name'][0]['name']??''); |
250 | } | 251 | } |
251 | if(is_array($v['to_name'])){ | 252 | if(is_array($v['to_name'])){ |
252 | $v['to_name'] = ''; | 253 | $v['to_name'] = ''; |
lib/Imap/DataArray.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace Lib\Imap; | ||
4 | + | ||
5 | +/** | ||
6 | + * 数据 | ||
7 | + * @author:dc | ||
8 | + * @time 2024/9/21 9:27 | ||
9 | + * Class DataArray | ||
10 | + * @package Lib\Imap | ||
11 | + */ | ||
12 | +class DataArray { | ||
13 | + | ||
14 | + /** | ||
15 | + * 存储的数据 | ||
16 | + * @var array | ||
17 | + */ | ||
18 | + private array $attribute = []; | ||
19 | + | ||
20 | + /** | ||
21 | + * @param string $name | ||
22 | + * @param mixed $val | ||
23 | + * @param bool $append | ||
24 | + * @author:dc | ||
25 | + * @time 2024/9/21 9:33 | ||
26 | + */ | ||
27 | + public function set(string $name, mixed $val, bool $append = false): void | ||
28 | + { | ||
29 | + $name = strtolower($name); | ||
30 | + if($append && is_string($val) && $this->get($name)!==null ){ | ||
31 | + $this->attribute[$name] .= $val; | ||
32 | + }else{ | ||
33 | + $this->attribute[$name] = $val; | ||
34 | + } | ||
35 | + } | ||
36 | + | ||
37 | + | ||
38 | + /** | ||
39 | + * @param string $name | ||
40 | + * @return mixed | ||
41 | + * @author:dc | ||
42 | + * @time 2024/9/21 9:34 | ||
43 | + */ | ||
44 | + public function get(string $name): mixed | ||
45 | + { | ||
46 | + if(isset($this->attribute[$name])){ | ||
47 | + return $this->attribute[$name]; | ||
48 | + } | ||
49 | + | ||
50 | + foreach ($this->attribute as $key=>$value){ | ||
51 | + // 不区分大小写对比 | ||
52 | + if(strcasecmp($key,$name)===0){ | ||
53 | + return $value; | ||
54 | + } | ||
55 | + } | ||
56 | + | ||
57 | + return null; | ||
58 | + } | ||
59 | + | ||
60 | + /** | ||
61 | + * 不区分大小写比较字符串 | ||
62 | + * @param string $name | ||
63 | + * @param mixed $value | ||
64 | + * @return bool | ||
65 | + * @author:dc | ||
66 | + * @time 2024/9/21 9:57 | ||
67 | + */ | ||
68 | + public function eq(string $name,mixed $value):bool { | ||
69 | + return strcasecmp($this->get($name),$value) === 0; | ||
70 | + } | ||
71 | + | ||
72 | + | ||
73 | + public function __get(string $name): mixed | ||
74 | + { | ||
75 | + return $this->get($name); | ||
76 | + } | ||
77 | + | ||
78 | + | ||
79 | + public function __set(string $name, $value): void | ||
80 | + { | ||
81 | + $this->set($name,$value); | ||
82 | + } | ||
83 | + | ||
84 | + | ||
85 | + | ||
86 | +} |
@@ -2,6 +2,8 @@ | @@ -2,6 +2,8 @@ | ||
2 | 2 | ||
3 | namespace Lib\Imap\Parse; | 3 | namespace Lib\Imap\Parse; |
4 | 4 | ||
5 | +use Lib\Imap\DataArray; | ||
6 | + | ||
5 | /** | 7 | /** |
6 | * 邮件内容 | 8 | * 邮件内容 |
7 | * @author:dc | 9 | * @author:dc |
@@ -18,18 +20,28 @@ class Body { | @@ -18,18 +20,28 @@ class Body { | ||
18 | protected string $raw = ''; | 20 | protected string $raw = ''; |
19 | 21 | ||
20 | /** | 22 | /** |
21 | - * 解析后的数据 | ||
22 | - * @var array | 23 | + * 消息结构,解析后的邮件体 header |
24 | + * @var MessageItem | ||
23 | */ | 25 | */ |
24 | - protected array $item = []; | 26 | + protected MessageItem $msg; |
27 | + | ||
25 | 28 | ||
29 | + /** | ||
30 | + * 解析后的body数据 | ||
31 | + * @var DataArray[] | ||
32 | + */ | ||
33 | + private array $items = []; | ||
26 | 34 | ||
27 | - public function __construct(string $result) | 35 | + /** |
36 | + * Body constructor. | ||
37 | + * @param string $result | ||
38 | + * @param MessageItem $msg | ||
39 | + */ | ||
40 | + public function __construct(string $result, MessageItem $msg) | ||
28 | { | 41 | { |
29 | - // 匹配出id和数据 | ||
30 | - if(preg_match("/\* (\d+) FETCH \(/",$result)){ | 42 | + $this->raw = $result; |
31 | 43 | ||
32 | - } | 44 | + $this->msg = $msg; |
33 | 45 | ||
34 | $this->parse(); | 46 | $this->parse(); |
35 | } | 47 | } |
@@ -42,11 +54,146 @@ class Body { | @@ -42,11 +54,146 @@ class Body { | ||
42 | * @time 2024/9/14 17:35 | 54 | * @time 2024/9/14 17:35 |
43 | */ | 55 | */ |
44 | protected function parse(){ | 56 | protected function parse(){ |
57 | + // 是否是多段 | ||
58 | + $boundary = $this->msg->header->getBoundary(); | ||
59 | + if($boundary){ | ||
60 | + // 切割成块 | ||
61 | + $items = explode($boundary,$this->raw); | ||
62 | + // 第一个块和最后一块 是没用的块 | ||
63 | + array_shift($items);array_pop($items); | ||
64 | + foreach ($items as $item){ | ||
65 | + $this->items[] = $this->parseItem($item); | ||
66 | + } | ||
67 | + } | ||
68 | + | ||
69 | + | ||
70 | + } | ||
71 | + | ||
72 | + /** | ||
73 | + * 解析每个 块 | ||
74 | + * @param string $body 块字符串 | ||
75 | + * @return DataArray | ||
76 | + * @author:dc | ||
77 | + * @time 2024/9/21 9:51 | ||
78 | + */ | ||
79 | + protected function parseItem(string $body):DataArray { | ||
80 | + list($mime_header,$text) = explode("\r\n\r\n",$body,2); | ||
45 | 81 | ||
82 | + $data = $this->parseMimeHeader($mime_header); | ||
46 | 83 | ||
47 | 84 | ||
85 | + // 处理body体 的编码 | ||
86 | + switch ($data->get('Content-Transfer-Encoding')){ | ||
87 | + case 'quoted-printable':{ | ||
88 | + $text = quoted_printable_decode($text);break; | ||
89 | + } | ||
90 | + case 'base64':{ | ||
91 | + $text = base64_decode($text);break; | ||
92 | + } | ||
93 | + } | ||
94 | + | ||
95 | + $data->body = $text; | ||
96 | + | ||
97 | + return $data; | ||
98 | + | ||
99 | + } | ||
100 | + | ||
101 | + /** | ||
102 | + * 解析邮件体里面的每个块 头部 | ||
103 | + * @param string $header | ||
104 | + * @return DataArray | ||
105 | + * @author:dc | ||
106 | + * @time 2024/9/21 9:18 | ||
107 | + */ | ||
108 | + protected function parseMimeHeader(string $header):DataArray { | ||
109 | + // 处理 描述信息, | ||
110 | + $header = explode("\r\n",trim($header)); | ||
111 | + $data = new DataArray(); | ||
112 | + $name = ''; | ||
113 | + foreach ($header as $head){ | ||
114 | + // 判断是否是上一行的 | ||
115 | + if(str_starts_with($head,' ') || str_starts_with($head,"\t")){ | ||
116 | + $data->set($name,' '.$head,true); | ||
117 | + }else{ | ||
118 | + list($name,$value) = explode(":",$head,2); | ||
119 | + $data->set($name,trim($value)); | ||
120 | + } | ||
121 | + } | ||
122 | + | ||
123 | + // 处理编码 | ||
124 | + if($data->get('Content-Type')){ | ||
125 | + // 切割成 每个小块 Content-Type: text/html;charset=utf-8 | ||
126 | + $contentType = explode(' ',trim(str_replace(';',' ',$data->get('Content-Type')))); | ||
127 | + foreach ($contentType as $ct){ | ||
128 | + $ct = trim($ct); | ||
129 | + if(str_contains($ct,'/')){ | ||
130 | + $data->set('Content-Type',$ct); | ||
131 | + }elseif (str_contains($ct,'=')){ | ||
132 | + list($name,$val) = explode('=',$ct); | ||
133 | + $data->set($name,trim($val)); | ||
134 | + } | ||
135 | + } | ||
48 | } | 136 | } |
49 | 137 | ||
138 | + // 默认编码 | ||
139 | + if(!$data->Charset) $data->Charset = 'utf-8'; | ||
140 | + | ||
141 | + return $data; | ||
142 | + } | ||
143 | + | ||
144 | + | ||
145 | + /** | ||
146 | + * 读取纯文本的内容 | ||
147 | + * @author:dc | ||
148 | + * @time 2024/9/21 9:55 | ||
149 | + */ | ||
150 | + public function getText():string { | ||
151 | + foreach ($this->items as $item){ | ||
152 | + if($item->eq('content-type','text/plain')){ | ||
153 | + return $item->body; | ||
154 | + } | ||
155 | + } | ||
156 | + | ||
157 | + // 没找到 text | ||
158 | + return strip_tags($this->getHtml()); | ||
159 | + | ||
160 | + } | ||
161 | + | ||
162 | + /** | ||
163 | + * 读取 html文本 | ||
164 | + * @return string | ||
165 | + * @author:dc | ||
166 | + * @time 2024/9/21 10:02 | ||
167 | + */ | ||
168 | + public function getHtml():string { | ||
169 | + foreach ($this->items as $item){ | ||
170 | + if($item->eq('content-type','text/html')){ | ||
171 | + return $item->body; | ||
172 | + } | ||
173 | + } | ||
174 | + } | ||
175 | + | ||
176 | + /** | ||
177 | + * 有些邮件里面的图片是通过附件的形式发来的 | ||
178 | + * <img src="cid:xxxx" /> 这种就是附件图片,需要替换的 | ||
179 | + * @return array | ||
180 | + * @author:dc | ||
181 | + * @time 2024/9/21 10:53 | ||
182 | + */ | ||
183 | + public function getHtmlAndImg():array { | ||
184 | + $html = $this->getHtml(); | ||
185 | + | ||
186 | + } | ||
187 | + | ||
188 | + /** | ||
189 | + * 读取附件 | ||
190 | + * @return DataArray[] | ||
191 | + * @author:dc | ||
192 | + * @time 2024/9/21 10:05 | ||
193 | + */ | ||
194 | + public function getAttachment():array { | ||
195 | + | ||
196 | + } | ||
50 | 197 | ||
51 | 198 | ||
52 | 199 |
lib/Imap/Parse/Fetch.php
已删除
100644 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace Lib\Imap\Parse; | ||
4 | - | ||
5 | - | ||
6 | -/** | ||
7 | - * 解析邮件 | ||
8 | - * @author:dc | ||
9 | - * @time 2024/9/10 16:54 | ||
10 | - * Class Header | ||
11 | - */ | ||
12 | -class Fetch{ | ||
13 | - | ||
14 | - /** | ||
15 | - * @var array | ||
16 | - */ | ||
17 | - private array $attributes = []; | ||
18 | - | ||
19 | - /** | ||
20 | - * 原始头信息 | ||
21 | - * @var string | ||
22 | - */ | ||
23 | - protected string $raw_header; | ||
24 | - | ||
25 | - /** | ||
26 | - * Header constructor. | ||
27 | - * @param string $raw_header | ||
28 | - */ | ||
29 | - public function __construct(string $raw_header) | ||
30 | - { | ||
31 | - $this->raw_header = $raw_header; | ||
32 | - | ||
33 | - $this->rfc822_parse_headers(); | ||
34 | - } | ||
35 | - | ||
36 | - | ||
37 | - /** | ||
38 | - * @param string $name | ||
39 | - * @param string $value | ||
40 | - * @param bool $append | ||
41 | - * @author:dc | ||
42 | - * @time 2024/9/11 16:24 | ||
43 | - */ | ||
44 | - public function setAttribute(string $name, string $value, bool $append = true){ | ||
45 | - $name = strtolower($name); | ||
46 | - | ||
47 | - if(!$append){ | ||
48 | - $this->attributes[$name] = $value; | ||
49 | - }else{ | ||
50 | - if(isset($this->attributes[$name])) | ||
51 | - $this->attributes[$name] .= "\r\n".$value; | ||
52 | - else | ||
53 | - $this->attributes[$name] = $value; | ||
54 | - } | ||
55 | - } | ||
56 | - | ||
57 | - | ||
58 | - /** | ||
59 | - * 解析邮件头部 | ||
60 | - * @author:dc | ||
61 | - * @time 2024/9/10 16:29 | ||
62 | - */ | ||
63 | - private function rfc822_parse_headers(){ | ||
64 | - $header = explode("\r\n",$this->raw_header); | ||
65 | - $name = ''; | ||
66 | - foreach ($header as $str){ | ||
67 | - // 判断是否是上一行的 | ||
68 | - if(str_starts_with($str,' ') || str_starts_with($str,"\t")){ | ||
69 | - $this->setAttribute($name,$str); | ||
70 | - }else{ | ||
71 | - $str = explode(":",$str); | ||
72 | - $name = $str[0]; | ||
73 | - unset($str[0]); | ||
74 | - $this->setAttribute($name,implode(':',$str)); | ||
75 | - } | ||
76 | - | ||
77 | - } | ||
78 | - | ||
79 | - foreach ($this->attributes as $name => $attribute){ | ||
80 | - $attribute = trim($attribute); | ||
81 | - $this->attributes[$name] = $attribute; | ||
82 | - } | ||
83 | - } | ||
84 | - | ||
85 | - | ||
86 | - public function __get(string $name) | ||
87 | - { | ||
88 | - return $this->get($name); | ||
89 | - } | ||
90 | - | ||
91 | - /** | ||
92 | - * 读取字段 | ||
93 | - * @param string $name | ||
94 | - * @return mixed | ||
95 | - * @author:dc | ||
96 | - * @time 2024/9/11 15:06 | ||
97 | - */ | ||
98 | - public function get(string $name):mixed { | ||
99 | - $name = strtolower($name); | ||
100 | - | ||
101 | - $m = 'get'.str_replace(' ','',ucwords(str_replace('-',' ',$name))); | ||
102 | - | ||
103 | - if(method_exists($this,$m)){ | ||
104 | - return $this->{$m}(); | ||
105 | - } | ||
106 | - | ||
107 | - return $this->attributes[$name]??''; | ||
108 | - } | ||
109 | - | ||
110 | - | ||
111 | - /** | ||
112 | - * 获取收件地址 可能是假地址 | ||
113 | - * @param bool $is_obj 是否解析成对象 Address | ||
114 | - * @return Address[] | ||
115 | - * @author:dc | ||
116 | - * @time 2024/9/11 15:03 | ||
117 | - */ | ||
118 | - public function getTo() { | ||
119 | - // 如果有这个字段,就用这个字段 to字段的邮箱可能被伪造 | ||
120 | - if(!empty($this->attributes['delivered-to'])){ | ||
121 | - $to = $this->attributes['delivered-to']; | ||
122 | - }else{ | ||
123 | - $to = $this->attributes['to']??''; | ||
124 | - } | ||
125 | - | ||
126 | - return $this->parseAddress($to); | ||
127 | - } | ||
128 | - | ||
129 | - /** | ||
130 | - * 解析地址 | ||
131 | - * @param string $address | ||
132 | - * @return array | ||
133 | - * @author:dc | ||
134 | - * @time 2024/9/11 15:53 | ||
135 | - */ | ||
136 | - private function parseAddress(string $address){ | ||
137 | - $arr = []; | ||
138 | - foreach (explode(',',$address) as $str){ | ||
139 | - $arr[] = Address::make($str); | ||
140 | - } | ||
141 | - return $arr; | ||
142 | - } | ||
143 | - | ||
144 | - /** | ||
145 | - * 抄送人 | ||
146 | - * @return array | ||
147 | - * @author:dc | ||
148 | - * @time 2024/9/11 15:53 | ||
149 | - */ | ||
150 | - public function getCc() | ||
151 | - { | ||
152 | - return $this->parseAddress($this->attributes['cc']??''); | ||
153 | - } | ||
154 | - | ||
155 | - /** | ||
156 | - * 密送人 | ||
157 | - * @return array | ||
158 | - * @author:dc | ||
159 | - * @time 2024/9/11 15:54 | ||
160 | - */ | ||
161 | - public function getBcc() | ||
162 | - { | ||
163 | - return $this->parseAddress($this->attributes['bcc']??''); | ||
164 | - } | ||
165 | - | ||
166 | - | ||
167 | - | ||
168 | - /** | ||
169 | - * 发件人 可能是欺炸 发件人 | ||
170 | - * @return Address | ||
171 | - * @author:dc | ||
172 | - * @time 2024/9/11 15:19 | ||
173 | - */ | ||
174 | - public function getFrom():Address { | ||
175 | - return Address::make($this->attributes['from']??''); | ||
176 | - } | ||
177 | - | ||
178 | - /** | ||
179 | - * 获取解码后的主题 | ||
180 | - * @return string | ||
181 | - * @author:dc | ||
182 | - * @time 2024/9/11 15:22 | ||
183 | - */ | ||
184 | - public function getSubject():string { | ||
185 | - $subject = explode("\n",$this->attributes['subject']??''); | ||
186 | - foreach ($subject as $ak=>$str){ | ||
187 | - $subject[$ak] = DeCode::decode($str); | ||
188 | - } | ||
189 | - | ||
190 | - return implode("\n",$subject); | ||
191 | - } | ||
192 | - | ||
193 | - | ||
194 | - /** | ||
195 | - * Boundary | ||
196 | - * @param string $str | ||
197 | - * @return string | ||
198 | - * @author:dc | ||
199 | - * @time 2024/9/11 16:05 | ||
200 | - */ | ||
201 | - public function getBoundary(string $str = ''): string | ||
202 | - { | ||
203 | - $pre = "/boundary=(.*?(?=;)|(.*))/i"; | ||
204 | - // 在内容类型中读取 大多少情况都在这里面 | ||
205 | - $contentType = $str ? $str: ($this->attributes['content-type']??''); | ||
206 | - if($contentType){ | ||
207 | - preg_match($pre,$contentType,$b); | ||
208 | - if(!empty($b[1])){ | ||
209 | - return trim(str_replace(['"',';'],'',$b[1])); | ||
210 | - } | ||
211 | - } | ||
212 | - if($this->raw_header && !$str){ | ||
213 | - return $this->getBoundary($this->raw_header); | ||
214 | - } | ||
215 | - | ||
216 | - return ''; | ||
217 | - } | ||
218 | - | ||
219 | - /** | ||
220 | - * 这个是是否加急 1加急 3普通 5不急 | ||
221 | - * @return string | ||
222 | - */ | ||
223 | - public function getPriority(): string | ||
224 | - { | ||
225 | - if(!empty($this->attributes['priority'])){ | ||
226 | - return $this->attributes['priority']; | ||
227 | - } | ||
228 | - | ||
229 | - if(!empty($this->attributes['x-priority'])){ | ||
230 | - return $this->attributes['x-priority']; | ||
231 | - } | ||
232 | - | ||
233 | - return '3'; | ||
234 | - } | ||
235 | - | ||
236 | - | ||
237 | - | ||
238 | - /** | ||
239 | - * @return array | ||
240 | - */ | ||
241 | - public function getAttributes(): array | ||
242 | - { | ||
243 | - return $this->attributes; | ||
244 | - } | ||
245 | - | ||
246 | - /** | ||
247 | - * @return array | ||
248 | - * @author:dc | ||
249 | - * @time 2024/9/11 16:15 | ||
250 | - */ | ||
251 | - public function toArray():array { | ||
252 | - $arr = []; | ||
253 | - foreach ($this->attributes as $key=>$attr){ | ||
254 | - $arr[$key] = $this->get($key); | ||
255 | - } | ||
256 | - | ||
257 | - return $arr; | ||
258 | - } | ||
259 | - | ||
260 | -} |
@@ -67,11 +67,9 @@ class Header{ | @@ -67,11 +67,9 @@ class Header{ | ||
67 | // 判断是否是上一行的 | 67 | // 判断是否是上一行的 |
68 | if(str_starts_with($str,' ') || str_starts_with($str,"\t")){ | 68 | if(str_starts_with($str,' ') || str_starts_with($str,"\t")){ |
69 | $this->setAttribute($name,$str); | 69 | $this->setAttribute($name,$str); |
70 | - }else{ | ||
71 | - $str = explode(":",$str); | ||
72 | - $name = $str[0]; | ||
73 | - unset($str[0]); | ||
74 | - $this->setAttribute($name,implode(':',$str)); | 70 | + }elseif(str_contains($str,':')){ |
71 | + list($name, $str) = explode(":",$str,2); | ||
72 | + $this->setAttribute($name,$str); | ||
75 | } | 73 | } |
76 | 74 | ||
77 | } | 75 | } |
@@ -146,7 +146,13 @@ class MessageItem { | @@ -146,7 +146,13 @@ class MessageItem { | ||
146 | * @time 2024/9/20 15:14 | 146 | * @time 2024/9/20 15:14 |
147 | */ | 147 | */ |
148 | public function getBody():Body { | 148 | public function getBody():Body { |
149 | - return $this->msg->folder->getBody($this->uid,true); | 149 | + if(isset($this->body)){ |
150 | + return $this->body; | ||
151 | + } | ||
152 | + | ||
153 | + $this->body = $this->msg->getBody($this); | ||
154 | + | ||
155 | + return $this->body; | ||
150 | } | 156 | } |
151 | 157 | ||
152 | 158 |
@@ -154,11 +154,11 @@ class Messager implements \IteratorAggregate { | @@ -154,11 +154,11 @@ class Messager implements \IteratorAggregate { | ||
154 | $header = substr($header,strlen($num[0]),strlen($header)); | 154 | $header = substr($header,strlen($num[0]),strlen($header)); |
155 | 155 | ||
156 | }else{ | 156 | }else{ |
157 | - // 以3个\r\n为结束 | ||
158 | - $str = explode("\r\n\r\n\r\n",trim($str)); | 157 | + // 以2个\r\n为结束 |
158 | + $str = explode("\r\n\r\n",trim($str)); | ||
159 | $header = array_shift($str); | 159 | $header = array_shift($str); |
160 | // 剩余的字符串 | 160 | // 剩余的字符串 |
161 | - $tokens = explode(' ',implode("\r\n\r\n\r\n",$str)); | 161 | + $tokens = explode(' ',implode("\r\n\r\n",$str)); |
162 | } | 162 | } |
163 | 163 | ||
164 | $this->item[$msgno]->header = new Header($header); | 164 | $this->item[$msgno]->header = new Header($header); |
@@ -183,6 +183,22 @@ class Messager implements \IteratorAggregate { | @@ -183,6 +183,22 @@ class Messager implements \IteratorAggregate { | ||
183 | } | 183 | } |
184 | 184 | ||
185 | 185 | ||
186 | + /** | ||
187 | + * 获取一条消息 | ||
188 | + * @return bool|MessageItem | ||
189 | + * @author:dc | ||
190 | + * @time 2024/9/20 16:48 | ||
191 | + */ | ||
192 | + public function first():bool|MessageItem { | ||
193 | + if($this->item){ | ||
194 | + return $this->item[array_key_first($this->item)]; | ||
195 | + } | ||
196 | + return false; | ||
197 | + } | ||
198 | + | ||
199 | + | ||
200 | + | ||
201 | + | ||
186 | } | 202 | } |
187 | 203 | ||
188 | 204 |
lib/Imap/Request/Body.php
已删除
100644 → 0
1 | -<?php | ||
2 | - | ||
3 | - | ||
4 | -namespace Lib\Imap\Request; | ||
5 | - | ||
6 | -use Lib\Imap\Imap; | ||
7 | - | ||
8 | -use Lib\Imap\Parse\Body as ParseBody; | ||
9 | - | ||
10 | -/** | ||
11 | - * body邮件内容 | ||
12 | - * @author:dc | ||
13 | - * @time 2024/9/20 14:53 | ||
14 | - * Class Body | ||
15 | - * @package Lib\Imap\Request | ||
16 | - */ | ||
17 | -class Body extends Request { | ||
18 | - | ||
19 | - /** | ||
20 | - * @var Folder | ||
21 | - */ | ||
22 | - protected Folder $folder; | ||
23 | - | ||
24 | - | ||
25 | - | ||
26 | - public function __construct(Imap $imap, Folder $folder) | ||
27 | - { | ||
28 | - parent::__construct($imap); | ||
29 | - | ||
30 | - $this->folder = $folder; | ||
31 | - } | ||
32 | - | ||
33 | - | ||
34 | - public function exec(): static{return $this;} | ||
35 | - | ||
36 | - | ||
37 | - /** | ||
38 | - * 读取邮件body | ||
39 | - * @param int $num | ||
40 | - * @param bool $is_uid | ||
41 | - * @return ParseBody | ||
42 | - * @author:dc | ||
43 | - * @time 2024/9/20 15:40 | ||
44 | - */ | ||
45 | - public function get(int $num, bool $is_uid = false):ParseBody { | ||
46 | - $this->folder->exec(); // 防止在其他文件夹下面 | ||
47 | - $this->cmd("%sFETCH %s (RFC822.BODY)", $is_uid ? 'UID ' : '', $num); | ||
48 | - | ||
49 | - return (new ParseBody($this->result ? $this->result[0] : '')); | ||
50 | - } | ||
51 | - | ||
52 | - | ||
53 | - | ||
54 | - | ||
55 | -} |
@@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
4 | namespace Lib\Imap\Request; | 4 | namespace Lib\Imap\Request; |
5 | 5 | ||
6 | use Lib\Imap\Imap; | 6 | use Lib\Imap\Imap; |
7 | +use Lib\Imap\Parse\MessageItem; | ||
7 | 8 | ||
8 | /** | 9 | /** |
9 | * 登录 | 10 | * 登录 |
@@ -218,20 +219,5 @@ class Folder extends Request{ | @@ -218,20 +219,5 @@ class Folder extends Request{ | ||
218 | } | 219 | } |
219 | 220 | ||
220 | 221 | ||
221 | - /** | ||
222 | - * 读取body体 | ||
223 | - * @param int $num | ||
224 | - * @param false $is_uid | ||
225 | - * @return \Lib\Imap\Parse\Body | ||
226 | - * @author:dc | ||
227 | - * @time 2024/9/20 15:37 | ||
228 | - */ | ||
229 | - public function getBody(int $num, bool $is_uid = false):\Lib\Imap\Parse\Body{ | ||
230 | - $body = (new Body($this->imap,$this)); | ||
231 | - return $body->get($num, $is_uid = false); | ||
232 | - } | ||
233 | - | ||
234 | - | ||
235 | - | ||
236 | 222 | ||
237 | } | 223 | } |
@@ -5,6 +5,8 @@ namespace Lib\Imap\Request; | @@ -5,6 +5,8 @@ namespace Lib\Imap\Request; | ||
5 | 5 | ||
6 | use Lib\Imap\Imap; | 6 | use Lib\Imap\Imap; |
7 | use Lib\Imap\ImapSearch; | 7 | use Lib\Imap\ImapSearch; |
8 | +use Lib\Imap\Parse\Body as ParseBody; | ||
9 | +use Lib\Imap\Parse\MessageItem; | ||
8 | use Lib\Imap\Parse\Messager; | 10 | use Lib\Imap\Parse\Messager; |
9 | 11 | ||
10 | /** | 12 | /** |
@@ -62,27 +64,27 @@ class Msg extends Request{ | @@ -62,27 +64,27 @@ class Msg extends Request{ | ||
62 | 64 | ||
63 | /** | 65 | /** |
64 | * 使用uid进行查询 | 66 | * 使用uid进行查询 |
65 | - * @param array $uids | 67 | + * @param array|int $uids |
66 | * @return $this | 68 | * @return $this |
67 | * @author:dc | 69 | * @author:dc |
68 | * @time 2024/9/14 14:06 | 70 | * @time 2024/9/14 14:06 |
69 | */ | 71 | */ |
70 | - public function uid(array $uids):static { | 72 | + public function uid(array|int $uids):static { |
71 | $this->isUid = true; | 73 | $this->isUid = true; |
72 | - $this->number = $uids; | 74 | + $this->number = is_array($uids) ? $uids : [$uids]; |
73 | return $this; | 75 | return $this; |
74 | } | 76 | } |
75 | 77 | ||
76 | /** | 78 | /** |
77 | * 使用编号进行查询 | 79 | * 使用编号进行查询 |
78 | - * @param array $msgno | 80 | + * @param array|int $msgno |
79 | * @return $this | 81 | * @return $this |
80 | * @author:dc | 82 | * @author:dc |
81 | * @time 2024/9/14 14:06 | 83 | * @time 2024/9/14 14:06 |
82 | */ | 84 | */ |
83 | - public function msgno(array $msgno):static { | 85 | + public function msgno(array|int $msgno):static { |
84 | $this->isUid = false; | 86 | $this->isUid = false; |
85 | - $this->number = $msgno; | 87 | + $this->number = is_array($msgno)?$msgno:[$msgno]; |
86 | return $this; | 88 | return $this; |
87 | } | 89 | } |
88 | 90 | ||
@@ -126,15 +128,20 @@ class Msg extends Request{ | @@ -126,15 +128,20 @@ class Msg extends Request{ | ||
126 | } | 128 | } |
127 | 129 | ||
128 | 130 | ||
129 | - public function getBody(){ | 131 | + /** |
132 | + * 读取body 体 | ||
133 | + * @param MessageItem $msg | ||
134 | + * @return ParseBody | ||
135 | + * @author:dc | ||
136 | + * @time 2024/9/20 17:09 | ||
137 | + */ | ||
138 | + public function getBody(MessageItem $msg){ | ||
130 | $this->folder->exec(); // 防止在其他文件夹下面 | 139 | $this->folder->exec(); // 防止在其他文件夹下面 |
131 | - $this->cmd( | ||
132 | - "%sFETCH %s (UID FLAGS INTERNALDATE RFC822.SIZE RFC822.HEADER)", | ||
133 | - $this->isUid?'UID ':'', | ||
134 | - implode(',',$this->number) | ||
135 | - ); | ||
136 | 140 | ||
137 | - return new Messager($this->result, $this); | 141 | + $this->cmd("UID FETCH %s (RFC822.TEXT)", $msg->uid); |
142 | + | ||
143 | + return (new ParseBody(implode('',$this->result),$msg)); | ||
144 | + | ||
138 | } | 145 | } |
139 | 146 | ||
140 | 147 |
@@ -75,6 +75,16 @@ if($login->isOk()){// 登录成功 | @@ -75,6 +75,16 @@ if($login->isOk()){// 登录成功 | ||
75 | // 获取某个字段 | 75 | // 获取某个字段 |
76 | $msg->header->get('subject'); | 76 | $msg->header->get('subject'); |
77 | 77 | ||
78 | + // html内容 | ||
79 | + $msg->body->getHtml(); | ||
80 | + // 纯文本内容 | ||
81 | + $msg->body->getText(); | ||
82 | + // 获取附件 | ||
83 | + foreach ($msg->body->getAttachment() as $attachment){ | ||
84 | + // 存起来 | ||
85 | + file_put_contents($attachment->get('filename'),$attachment->get('body')); | ||
86 | + } | ||
87 | + | ||
78 | }); | 88 | }); |
79 | 89 | ||
80 | 90 |
-
请 注册 或 登录 后发表评论