作者 邓超

1

@@ -20,6 +20,8 @@ define('APP_LANG','zh'); @@ -20,6 +20,8 @@ define('APP_LANG','zh');
20 define('ROOT_PATH',__DIR__); 20 define('ROOT_PATH',__DIR__);
21 // 对外的web目录 21 // 对外的web目录
22 define('PUBLIC_PATH',ROOT_PATH.'/public'); 22 define('PUBLIC_PATH',ROOT_PATH.'/public');
  23 +// 邮件存储目录
  24 +define('MAIL_ATTACHMENT_PATH', PUBLIC_PATH.'/attachment/');
23 25
24 26
25 // redis 27 // redis
@@ -39,6 +41,9 @@ define('DB_PASSWORD','pKnXKwhAFRpwcZAM'); @@ -39,6 +41,9 @@ define('DB_PASSWORD','pKnXKwhAFRpwcZAM');
39 // 调试 41 // 调试
40 define('APP_DEBUG',true); 42 define('APP_DEBUG',true);
41 43
  44 +// 当前的访问域名
  45 +define('APP_HOST','http://www.mail.cn');
  46 +
42 47
43 48
44 49
@@ -121,13 +121,32 @@ class Home extends Base { @@ -121,13 +121,32 @@ class Home extends Base {
121 121
122 $email = $this->getEmail(); 122 $email = $this->getEmail();
123 123
  124 + $yzemail = function(&$value,$field){
  125 + if($value){
  126 + if(!is_array($value)){
  127 + if(@json_decode($value,true)){
  128 + $value = json_decode($value,true);
  129 + }else{
  130 + $value = [['email'=>$value,'name'=>'']];
  131 + }
  132 + }
  133 + foreach ($value as $item){
  134 + if(!Verify::sEmail($item['email'])){
  135 + app()->e([$field.'_verify_error',$item['email']]);
  136 + }
  137 + }
  138 + }
  139 + };
  140 +
124 $formData = Verify::checks([ 141 $formData = Verify::checks([
125 'nickname|'.__('nickname') => ['required','max'=>50], 142 'nickname|'.__('nickname') => ['required','max'=>50],
126 'subject|'.__('subject') => ['required','max'=>150], 143 'subject|'.__('subject') => ['required','max'=>150],
127 'body|'.__('body_email') => ['required'], 144 'body|'.__('body_email') => ['required'],
128 - 'to|'.__('to_email') => ['required','array|string','email'], 145 + 'tos|'.__('to_email') => ['required',$yzemail],
  146 + 'cc|'.__('to_cc') => [$yzemail],
  147 + 'bcc|'.__('to_bcc') => [$yzemail],
129 'priority|'.__('priority_email') => ['in'=>[1,3,5]], 148 'priority|'.__('priority_email') => ['in'=>[1,3,5]],
130 - 'files|'.__('files_email') => [ 149 + 'attachment|'.__('files_email') => [
131 'file'=>[ 150 'file'=>[
132 'ext' => [], 151 'ext' => [],
133 'size' => 500, 152 'size' => 500,
@@ -144,10 +163,10 @@ class Home extends Base { @@ -144,10 +163,10 @@ class Home extends Base {
144 $email['email'], 163 $email['email'],
145 base64_decode($email['password']), 164 base64_decode($email['password']),
146 $formData['nickname']??'', 165 $formData['nickname']??'',
147 - $formData['to'], 166 + $formData['tos'],
148 $formData['subject'], 167 $formData['subject'],
149 $formData['body'], 168 $formData['body'],
150 - $formData['files']??'', 169 + $formData['attachment']??'',
151 $formData['receipt']??'', 170 $formData['receipt']??'',
152 $formData['priority']??3, 171 $formData['priority']??3,
153 ); 172 );
@@ -377,6 +396,34 @@ class Home extends Base { @@ -377,6 +396,34 @@ class Home extends Base {
377 $body = db()->first(bodySql::first($id)); 396 $body = db()->first(bodySql::first($id));
378 if($body){ 397 if($body){
379 $data['body'] = json_decode($body['text_html'],true); 398 $data['body'] = json_decode($body['text_html'],true);
  399 + $charset = '';
  400 + foreach ($data['body'] as $bd){
  401 + if(!empty($bd['charset'])){
  402 + $charset = $bd['charset'];
  403 + break;
  404 + }
  405 + }
  406 + foreach ($data['body'] as $bdk=>$bd){
  407 +
  408 + if(!empty($bd['path'])){
  409 +
  410 + if($charset){
  411 + $data['body'][$bdk]['name'] = @iconv($charset,'utf-8',@base64_decode($bd['name']));
  412 + $data['body'][$bdk]['filename'] = @iconv($charset,'utf-8',@base64_decode($bd['filename']));
  413 + }
  414 +
  415 + $data['body'][$bdk]['size'] = 0;
  416 + $data['body'][$bdk]['url'] = '';
  417 + if(is_file($bd['path'])){
  418 + // 文件大小
  419 + $data['body'][$bdk]['size'] = filesize($bd['path']);
  420 + // 文件访问地址
  421 + $data['body'][$bdk]['url'] = APP_HOST.str_replace(PUBLIC_PATH,'',$bd['path']);
  422 + }
  423 +
  424 + unset($data['body'][$bdk]['path']);
  425 + }
  426 + }
380 return [ 427 return [
381 'data' => $data 428 'data' => $data
382 ]; 429 ];
@@ -64,12 +64,18 @@ return [ @@ -64,12 +64,18 @@ return [
64 'body_email' => '邮件内容', 64 'body_email' => '邮件内容',
65 'files_email' => '邮件附件', 65 'files_email' => '邮件附件',
66 'receipt_email' => '邮件回执', 66 'receipt_email' => '邮件回执',
  67 + 'to_cc' => '抄送',
  68 + 'to_bcc' => '密送',
  69 + 'cc_verify_error' => '抄送人邮箱地址错误 %s',
  70 + 'bcc_verify_error' => '密送人邮箱地址错误 %s',
67 71
68 72
69 73
70 'mail_not' => '邮件不存在', 74 'mail_not' => '邮件不存在',
71 'mail_body_error' => '邮件内容拉取失败', 75 'mail_body_error' => '邮件内容拉取失败',
72 76
  77 + 'tos_verify_error' => '收件人邮箱地址错误 %s'
  78 +
73 79
74 80
75 81
@@ -318,6 +318,9 @@ class App { @@ -318,6 +318,9 @@ class App {
318 318
319 $data['error_message'] = $last_error['message']; 319 $data['error_message'] = $last_error['message'];
320 $data['status'] = 502; 320 $data['status'] = 502;
  321 + if($app->debug){
  322 + $data['debug'] = $last_error;
  323 + }
321 324
322 self::echo($data,502); 325 self::echo($data,502);
323 326
@@ -375,7 +375,7 @@ class Body { @@ -375,7 +375,7 @@ class Body {
375 mkdir($data['path'],0775,true); 375 mkdir($data['path'],0775,true);
376 } 376 }
377 $data['signName'] = md5($content).($ext ? '.'.$ext : ''); 377 $data['signName'] = md5($content).($ext ? '.'.$ext : '');
378 - $data['path'] = $data['path'].'/'.$data['signName']; 378 + $data['path'] = realpath($data['path'].'/'.$data['signName']);
379 // 保存文件 379 // 保存文件
380 @file_put_contents($data['path'],$content); 380 @file_put_contents($data['path'],$content);
381 } 381 }
@@ -320,7 +320,7 @@ class Mail { @@ -320,7 +320,7 @@ class Mail {
320 // 选择文件夹 320 // 选择文件夹
321 $this->client->selectFolder($folder_name); 321 $this->client->selectFolder($folder_name);
322 322
323 - $body = $this->client->fetchBody([$uid],PUBLIC_PATH.'/attachment/',true); 323 + $body = $this->client->fetchBody([$uid],MAIL_ATTACHMENT_PATH,true);
324 324
325 $body = array_values($body); 325 $body = array_values($body);
326 $body = $body[0]['RFC822.TEXT']??''; 326 $body = $body[0]['RFC822.TEXT']??'';
@@ -84,21 +84,23 @@ class Verify { @@ -84,21 +84,23 @@ class Verify {
84 } 84 }
85 85
86 86
87 -  
88 -  
89 /** 87 /**
90 * 验证数据 88 * 验证数据
91 * @param array $rule 89 * @param array $rule
92 * @param array $message 90 * @param array $message
93 - * @return array|false|float|int|mixed|null 91 + * @param array $data
  92 + * @return array|false|float|int
  93 + * @throws Err
94 * @author:dc 94 * @author:dc
95 - * @time 2023/3/10 17:56 95 + * @time 2023/4/6 10:27
96 */ 96 */
97 - public static function checks(array $rule, array $message=[]){ 97 + public static function checks(array $rule, array $message=[], array $data = []){
98 $verify = new static(); 98 $verify = new static();
99 $verify->message = $message; 99 $verify->message = $message;
100 100
  101 + if(!$data){
101 $data= app()->request(); 102 $data= app()->request();
  103 + }
102 if(is_array($data)){ 104 if(is_array($data)){
103 $verify->data = &$data; 105 $verify->data = &$data;
104 } 106 }
@@ -109,10 +111,16 @@ class Verify { @@ -109,10 +111,16 @@ class Verify {
109 $verify->alias[$key[0]] = $key[1]??$key[0]; 111 $verify->alias[$key[0]] = $key[1]??$key[0];
110 // 验证规则 112 // 验证规则
111 foreach ($item as $ak=>$av){ 113 foreach ($item as $ak=>$av){
112 - if(is_numeric($ak)){ 114 + // 是否是匿名函数
  115 + if($av instanceof \Closure){
  116 + $av($data[$key[0]], $key[0]);
  117 + continue;
  118 + }
  119 + else if(is_numeric($ak)){
113 $param = [$key[0]]; 120 $param = [$key[0]];
114 $ak = $av; 121 $ak = $av;
115 - }else{ 122 + }
  123 + else{
116 $param = [$key[0],$av]; 124 $param = [$key[0],$av];
117 } 125 }
118 126