Sfoglia il codice sorgente

feat: mailchimp email service

M1Screw 1 anno fa
parent
commit
fe6365add4

+ 1 - 1
app/routes.php

@@ -318,7 +318,7 @@ return static function (Slim\App $app): void {
 
     // WebAPI V2(Aka Node API V1)
     //$app->group('/node/api/v1', function (RouteCollectorProxy $group): void {
-    //    $group->get('/heartbeat', App\Controllers\Api\NodeApiV1Controller::class . ':getHeartbeat');
+    //    $group->put('/heartbeat', App\Controllers\Api\NodeApiV1Controller::class . ':getHeartbeat');
     //    $group->get('/info', App\Controllers\Api\NodeApiV1Controller::class . ':getInfo');
     //    $group->get('/user', App\Controllers\Api\NodeApiV1Controller::class . ':getUser');
     //    $group->get('/detect_rule', App\Controllers\Api\NodeApiV1Controller::class . ':getDetectRule');

+ 1 - 0
composer.json

@@ -23,6 +23,7 @@
         "illuminate/pagination": "^10.44.0",
         "irazasyed/telegram-bot-sdk": "^3",
         "lcobucci/jwt": "^5",
+        "mailchimp/transactional": "^1.0",
         "mailgun/mailgun-php": "^4",
         "nikolaposa/rate-limit": "^3",
         "openai-php/client": "^0",

+ 180 - 125
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "f7e6edab9c07262546075ea15e3c323c",
+    "content-hash": "03de1f31b0fae31274317471f8bb4e16",
     "packages": [
         {
             "name": "alipaysdk/openapi",
@@ -124,16 +124,16 @@
         },
         {
             "name": "aws/aws-sdk-php",
-            "version": "3.300.4",
+            "version": "3.300.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
-                "reference": "27d59c22c121ce9c0041c563dc9d7270e180925c"
+                "reference": "2704b9b10b42d53066eb383f47541124296db77c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/27d59c22c121ce9c0041c563dc9d7270e180925c",
-                "reference": "27d59c22c121ce9c0041c563dc9d7270e180925c",
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2704b9b10b42d53066eb383f47541124296db77c",
+                "reference": "2704b9b10b42d53066eb383f47541124296db77c",
                 "shasum": ""
             },
             "require": {
@@ -213,9 +213,9 @@
             "support": {
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.300.4"
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.300.9"
             },
-            "time": "2024-02-23T19:10:30+00:00"
+            "time": "2024-03-01T19:04:32+00:00"
         },
         {
             "name": "bacon/bacon-qr-code",
@@ -1201,16 +1201,16 @@
         },
         {
             "name": "illuminate/collections",
-            "version": "v10.45.1",
+            "version": "v10.46.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/collections.git",
-                "reference": "04c24117515ab9b701e4b28506d3f3c15d14bd5f"
+                "reference": "dd0c652dfac0901c17bcfac94fe792e615b56e12"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/collections/zipball/04c24117515ab9b701e4b28506d3f3c15d14bd5f",
-                "reference": "04c24117515ab9b701e4b28506d3f3c15d14bd5f",
+                "url": "https://api.github.com/repos/illuminate/collections/zipball/dd0c652dfac0901c17bcfac94fe792e615b56e12",
+                "reference": "dd0c652dfac0901c17bcfac94fe792e615b56e12",
                 "shasum": ""
             },
             "require": {
@@ -1252,11 +1252,11 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2024-02-13T21:55:58+00:00"
+            "time": "2024-02-21T14:18:14+00:00"
         },
         {
             "name": "illuminate/conditionable",
-            "version": "v10.45.1",
+            "version": "v10.46.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/conditionable.git",
@@ -1302,7 +1302,7 @@
         },
         {
             "name": "illuminate/container",
-            "version": "v10.45.1",
+            "version": "v10.46.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/container.git",
@@ -1353,7 +1353,7 @@
         },
         {
             "name": "illuminate/contracts",
-            "version": "v10.45.1",
+            "version": "v10.46.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/contracts.git",
@@ -1401,16 +1401,16 @@
         },
         {
             "name": "illuminate/database",
-            "version": "v10.45.1",
+            "version": "v10.46.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/database.git",
-                "reference": "64394348243be403ac9edf21c400077304e005b2"
+                "reference": "d756278a38541ec2f25c75e2553398b37a6d4e42"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/database/zipball/64394348243be403ac9edf21c400077304e005b2",
-                "reference": "64394348243be403ac9edf21c400077304e005b2",
+                "url": "https://api.github.com/repos/illuminate/database/zipball/d756278a38541ec2f25c75e2553398b37a6d4e42",
+                "reference": "d756278a38541ec2f25c75e2553398b37a6d4e42",
                 "shasum": ""
             },
             "require": {
@@ -1470,11 +1470,11 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2024-02-20T15:20:15+00:00"
+            "time": "2024-02-26T16:14:36+00:00"
         },
         {
             "name": "illuminate/macroable",
-            "version": "v10.45.1",
+            "version": "v10.46.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/macroable.git",
@@ -1520,7 +1520,7 @@
         },
         {
             "name": "illuminate/pagination",
-            "version": "v10.45.1",
+            "version": "v10.46.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/pagination.git",
@@ -1570,16 +1570,16 @@
         },
         {
             "name": "illuminate/support",
-            "version": "v10.45.1",
+            "version": "v10.46.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/support.git",
-                "reference": "ef80b6c0d0faec648d0625f1bd2b604b61cba5e5"
+                "reference": "96d4512df39bee8cb60d50783f944a48242ea862"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/support/zipball/ef80b6c0d0faec648d0625f1bd2b604b61cba5e5",
-                "reference": "ef80b6c0d0faec648d0625f1bd2b604b61cba5e5",
+                "url": "https://api.github.com/repos/illuminate/support/zipball/96d4512df39bee8cb60d50783f944a48242ea862",
+                "reference": "96d4512df39bee8cb60d50783f944a48242ea862",
                 "shasum": ""
             },
             "require": {
@@ -1637,7 +1637,7 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2024-02-16T10:04:27+00:00"
+            "time": "2024-02-26T22:20:06+00:00"
         },
         {
             "name": "irazasyed/telegram-bot-sdk",
@@ -1913,6 +1913,60 @@
             },
             "time": "2022-10-29T09:31:25+00:00"
         },
+        {
+            "name": "mailchimp/transactional",
+            "version": "1.0.59",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/mailchimp/mailchimp-transactional-php.git",
+                "reference": "1783927027820dc1c624fd04abf5012a57f96feb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/mailchimp/mailchimp-transactional-php/zipball/1783927027820dc1c624fd04abf5012a57f96feb",
+                "reference": "1783927027820dc1c624fd04abf5012a57f96feb",
+                "shasum": ""
+            },
+            "require": {
+                "ext-curl": "*",
+                "ext-json": "*",
+                "ext-mbstring": "*",
+                "guzzlehttp/guzzle": "^6.4 || ^7.2",
+                "php": ">=7.2"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "~2.12",
+                "phpunit/phpunit": "^7",
+                "squizlabs/php_codesniffer": "~2.6"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "MailchimpTransactional\\": "lib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "proprietary"
+            ],
+            "authors": [
+                {
+                    "name": "Mailchimp",
+                    "homepage": "https://github.com/mailchimp/mailchimp-transactional-php"
+                }
+            ],
+            "homepage": "http://swagger.io",
+            "keywords": [
+                "api",
+                "php",
+                "sdk",
+                "swagger"
+            ],
+            "support": {
+                "source": "https://github.com/mailchimp/mailchimp-transactional-php/tree/v1.0.59"
+            },
+            "time": "2024-02-10T01:12:26+00:00"
+        },
         {
             "name": "mailgun/mailgun-php",
             "version": "v4.1.0",
@@ -4247,16 +4301,16 @@
         },
         {
             "name": "smarty/smarty",
-            "version": "v4.3.5",
+            "version": "v4.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/smarty-php/smarty.git",
-                "reference": "e0cbbdf6ea21768d0194e59d2f8c2e20d5f0868c"
+                "reference": "f4152e9b814ae2369b6e4935c05e1e0c3654318d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/smarty-php/smarty/zipball/e0cbbdf6ea21768d0194e59d2f8c2e20d5f0868c",
-                "reference": "e0cbbdf6ea21768d0194e59d2f8c2e20d5f0868c",
+                "url": "https://api.github.com/repos/smarty-php/smarty/zipball/f4152e9b814ae2369b6e4935c05e1e0c3654318d",
+                "reference": "f4152e9b814ae2369b6e4935c05e1e0c3654318d",
                 "shasum": ""
             },
             "require": {
@@ -4307,9 +4361,9 @@
             "support": {
                 "forum": "https://github.com/smarty-php/smarty/discussions",
                 "issues": "https://github.com/smarty-php/smarty/issues",
-                "source": "https://github.com/smarty-php/smarty/tree/v4.3.5"
+                "source": "https://github.com/smarty-php/smarty/tree/v4.4.1"
             },
-            "time": "2024-01-23T10:47:54+00:00"
+            "time": "2024-02-26T13:58:37+00:00"
         },
         {
             "name": "srmklive/paypal",
@@ -4422,16 +4476,16 @@
         },
         {
             "name": "stripe/stripe-php",
-            "version": "v13.12.0",
+            "version": "v13.13.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/stripe/stripe-php.git",
-                "reference": "8052da9058caae10c7297f85821f652b38e31d85"
+                "reference": "8dc58bab25f222a74d1157d4ca9e9e48451dd0c1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/stripe/stripe-php/zipball/8052da9058caae10c7297f85821f652b38e31d85",
-                "reference": "8052da9058caae10c7297f85821f652b38e31d85",
+                "url": "https://api.github.com/repos/stripe/stripe-php/zipball/8dc58bab25f222a74d1157d4ca9e9e48451dd0c1",
+                "reference": "8dc58bab25f222a74d1157d4ca9e9e48451dd0c1",
                 "shasum": ""
             },
             "require": {
@@ -4475,9 +4529,9 @@
             ],
             "support": {
                 "issues": "https://github.com/stripe/stripe-php/issues",
-                "source": "https://github.com/stripe/stripe-php/tree/v13.12.0"
+                "source": "https://github.com/stripe/stripe-php/tree/v13.13.0"
             },
-            "time": "2024-02-22T22:19:58+00:00"
+            "time": "2024-02-29T20:22:15+00:00"
         },
         {
             "name": "symfony/deprecation-contracts",
@@ -4548,16 +4602,16 @@
         },
         {
             "name": "symfony/http-client",
-            "version": "v7.0.3",
+            "version": "v7.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-client.git",
-                "reference": "3d2605c07cd14aec294f72f5bf8147702f7a5ada"
+                "reference": "8384876f49a2316a63f88a9cd12436de6936bee6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-client/zipball/3d2605c07cd14aec294f72f5bf8147702f7a5ada",
-                "reference": "3d2605c07cd14aec294f72f5bf8147702f7a5ada",
+                "url": "https://api.github.com/repos/symfony/http-client/zipball/8384876f49a2316a63f88a9cd12436de6936bee6",
+                "reference": "8384876f49a2316a63f88a9cd12436de6936bee6",
                 "shasum": ""
             },
             "require": {
@@ -4620,7 +4674,7 @@
                 "http"
             ],
             "support": {
-                "source": "https://github.com/symfony/http-client/tree/v7.0.3"
+                "source": "https://github.com/symfony/http-client/tree/v7.0.4"
             },
             "funding": [
                 {
@@ -4636,7 +4690,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-01-29T15:41:16+00:00"
+            "time": "2024-02-15T11:33:06+00:00"
         },
         {
             "name": "symfony/http-client-contracts",
@@ -5418,16 +5472,16 @@
         },
         {
             "name": "symfony/translation",
-            "version": "v6.4.3",
+            "version": "v6.4.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation.git",
-                "reference": "637c51191b6b184184bbf98937702bcf554f7d04"
+                "reference": "bce6a5a78e94566641b2594d17e48b0da3184a8e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation/zipball/637c51191b6b184184bbf98937702bcf554f7d04",
-                "reference": "637c51191b6b184184bbf98937702bcf554f7d04",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/bce6a5a78e94566641b2594d17e48b0da3184a8e",
+                "reference": "bce6a5a78e94566641b2594d17e48b0da3184a8e",
                 "shasum": ""
             },
             "require": {
@@ -5493,7 +5547,7 @@
             "description": "Provides tools to internationalize your application",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/translation/tree/v6.4.3"
+                "source": "https://github.com/symfony/translation/tree/v6.4.4"
             },
             "funding": [
                 {
@@ -5509,7 +5563,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-01-29T13:11:52+00:00"
+            "time": "2024-02-20T13:16:58+00:00"
         },
         {
             "name": "symfony/translation-contracts",
@@ -6507,16 +6561,16 @@
         },
         {
             "name": "friendsofphp/php-cs-fixer",
-            "version": "v3.50.0",
+            "version": "v3.51.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
-                "reference": "dbea11dcb6d9a1f6c8d51c0e580ab4a8876f524c"
+                "reference": "127fa74f010da99053e3f5b62672615b72dd6efd"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/dbea11dcb6d9a1f6c8d51c0e580ab4a8876f524c",
-                "reference": "dbea11dcb6d9a1f6c8d51c0e580ab4a8876f524c",
+                "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/127fa74f010da99053e3f5b62672615b72dd6efd",
+                "reference": "127fa74f010da99053e3f5b62672615b72dd6efd",
                 "shasum": ""
             },
             "require": {
@@ -6587,7 +6641,7 @@
             ],
             "support": {
                 "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
-                "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.50.0"
+                "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.51.0"
             },
             "funding": [
                 {
@@ -6595,7 +6649,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-02-23T23:17:45+00:00"
+            "time": "2024-02-28T19:50:06+00:00"
         },
         {
             "name": "justinrainbow/json-schema",
@@ -7189,16 +7243,16 @@
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "10.1.11",
+            "version": "10.1.12",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "78c3b7625965c2513ee96569a4dbb62601784145"
+                "reference": "842f72662d6b9edda84c4b6f13885fd9cd53dc63"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/78c3b7625965c2513ee96569a4dbb62601784145",
-                "reference": "78c3b7625965c2513ee96569a4dbb62601784145",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/842f72662d6b9edda84c4b6f13885fd9cd53dc63",
+                "reference": "842f72662d6b9edda84c4b6f13885fd9cd53dc63",
                 "shasum": ""
             },
             "require": {
@@ -7255,7 +7309,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
                 "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
-                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.11"
+                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.12"
             },
             "funding": [
                 {
@@ -7263,7 +7317,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-12-21T15:38:30+00:00"
+            "time": "2024-03-02T07:22:05+00:00"
         },
         {
             "name": "phpunit/php-file-iterator",
@@ -7510,16 +7564,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "10.5.10",
+            "version": "10.5.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "50b8e314b6d0dd06521dc31d1abffa73f25f850c"
+                "reference": "0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/50b8e314b6d0dd06521dc31d1abffa73f25f850c",
-                "reference": "50b8e314b6d0dd06521dc31d1abffa73f25f850c",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4",
+                "reference": "0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4",
                 "shasum": ""
             },
             "require": {
@@ -7591,7 +7645,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.10"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.11"
             },
             "funding": [
                 {
@@ -7607,7 +7661,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-02-04T09:07:51+00:00"
+            "time": "2024-02-25T14:05:00+00:00"
         },
         {
             "name": "psr/cache",
@@ -7660,16 +7714,16 @@
         },
         {
             "name": "sebastian/cli-parser",
-            "version": "2.0.0",
+            "version": "2.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/cli-parser.git",
-                "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae"
+                "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae",
-                "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae",
+                "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084",
+                "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084",
                 "shasum": ""
             },
             "require": {
@@ -7704,7 +7758,8 @@
             "homepage": "https://github.com/sebastianbergmann/cli-parser",
             "support": {
                 "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
-                "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0"
+                "security": "https://github.com/sebastianbergmann/cli-parser/security/policy",
+                "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1"
             },
             "funding": [
                 {
@@ -7712,7 +7767,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-02-03T06:58:15+00:00"
+            "time": "2024-03-02T07:12:49+00:00"
         },
         {
             "name": "sebastian/code-unit",
@@ -7962,16 +8017,16 @@
         },
         {
             "name": "sebastian/diff",
-            "version": "5.1.0",
+            "version": "5.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/diff.git",
-                "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f"
+                "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/fbf413a49e54f6b9b17e12d900ac7f6101591b7f",
-                "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f",
+                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e",
+                "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e",
                 "shasum": ""
             },
             "require": {
@@ -7979,7 +8034,7 @@
             },
             "require-dev": {
                 "phpunit/phpunit": "^10.0",
-                "symfony/process": "^4.2 || ^5"
+                "symfony/process": "^6.4"
             },
             "type": "library",
             "extra": {
@@ -8017,7 +8072,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/diff/issues",
                 "security": "https://github.com/sebastianbergmann/diff/security/policy",
-                "source": "https://github.com/sebastianbergmann/diff/tree/5.1.0"
+                "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1"
             },
             "funding": [
                 {
@@ -8025,7 +8080,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-12-22T10:55:06+00:00"
+            "time": "2024-03-02T07:15:17+00:00"
         },
         {
             "name": "sebastian/environment",
@@ -8093,16 +8148,16 @@
         },
         {
             "name": "sebastian/exporter",
-            "version": "5.1.1",
+            "version": "5.1.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/exporter.git",
-                "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc"
+                "reference": "955288482d97c19a372d3f31006ab3f37da47adf"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc",
-                "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf",
+                "reference": "955288482d97c19a372d3f31006ab3f37da47adf",
                 "shasum": ""
             },
             "require": {
@@ -8159,7 +8214,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/exporter/issues",
                 "security": "https://github.com/sebastianbergmann/exporter/security/policy",
-                "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1"
+                "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2"
             },
             "funding": [
                 {
@@ -8167,20 +8222,20 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-09-24T13:22:09+00:00"
+            "time": "2024-03-02T07:17:12+00:00"
         },
         {
             "name": "sebastian/global-state",
-            "version": "6.0.1",
+            "version": "6.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/global-state.git",
-                "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4"
+                "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4",
-                "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4",
+                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9",
+                "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9",
                 "shasum": ""
             },
             "require": {
@@ -8214,14 +8269,14 @@
                 }
             ],
             "description": "Snapshotting of global state",
-            "homepage": "http://www.github.com/sebastianbergmann/global-state",
+            "homepage": "https://www.github.com/sebastianbergmann/global-state",
             "keywords": [
                 "global state"
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/global-state/issues",
                 "security": "https://github.com/sebastianbergmann/global-state/security/policy",
-                "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1"
+                "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2"
             },
             "funding": [
                 {
@@ -8229,7 +8284,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-07-19T07:19:23+00:00"
+            "time": "2024-03-02T07:19:19+00:00"
         },
         {
             "name": "sebastian/lines-of-code",
@@ -8720,16 +8775,16 @@
         },
         {
             "name": "symfony/cache",
-            "version": "v7.0.3",
+            "version": "v7.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/cache.git",
-                "reference": "2207eceb2433d74df81232d97439bf508cb9e050"
+                "reference": "fc822951dd360a593224bb2cef90a087d0dff60f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/cache/zipball/2207eceb2433d74df81232d97439bf508cb9e050",
-                "reference": "2207eceb2433d74df81232d97439bf508cb9e050",
+                "url": "https://api.github.com/repos/symfony/cache/zipball/fc822951dd360a593224bb2cef90a087d0dff60f",
+                "reference": "fc822951dd360a593224bb2cef90a087d0dff60f",
                 "shasum": ""
             },
             "require": {
@@ -8796,7 +8851,7 @@
                 "psr6"
             ],
             "support": {
-                "source": "https://github.com/symfony/cache/tree/v7.0.3"
+                "source": "https://github.com/symfony/cache/tree/v7.0.4"
             },
             "funding": [
                 {
@@ -8812,7 +8867,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-01-23T15:02:46+00:00"
+            "time": "2024-02-22T20:27:20+00:00"
         },
         {
             "name": "symfony/cache-contracts",
@@ -8892,16 +8947,16 @@
         },
         {
             "name": "symfony/console",
-            "version": "v7.0.3",
+            "version": "v7.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "c5010d50f1ee4b25cfa0201d9915cf1b14071456"
+                "reference": "6b099f3306f7c9c2d2786ed736d0026b2903205f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/c5010d50f1ee4b25cfa0201d9915cf1b14071456",
-                "reference": "c5010d50f1ee4b25cfa0201d9915cf1b14071456",
+                "url": "https://api.github.com/repos/symfony/console/zipball/6b099f3306f7c9c2d2786ed736d0026b2903205f",
+                "reference": "6b099f3306f7c9c2d2786ed736d0026b2903205f",
                 "shasum": ""
             },
             "require": {
@@ -8965,7 +9020,7 @@
                 "terminal"
             ],
             "support": {
-                "source": "https://github.com/symfony/console/tree/v7.0.3"
+                "source": "https://github.com/symfony/console/tree/v7.0.4"
             },
             "funding": [
                 {
@@ -8981,7 +9036,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-01-23T15:02:46+00:00"
+            "time": "2024-02-22T20:27:20+00:00"
         },
         {
             "name": "symfony/event-dispatcher",
@@ -9344,16 +9399,16 @@
         },
         {
             "name": "symfony/process",
-            "version": "v7.0.3",
+            "version": "v7.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "937a195147e0c27b2759ade834169ed006d0bc74"
+                "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/937a195147e0c27b2759ade834169ed006d0bc74",
-                "reference": "937a195147e0c27b2759ade834169ed006d0bc74",
+                "url": "https://api.github.com/repos/symfony/process/zipball/0e7727191c3b71ebec6d529fa0e50a01ca5679e9",
+                "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9",
                 "shasum": ""
             },
             "require": {
@@ -9385,7 +9440,7 @@
             "description": "Executes commands in sub-processes",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/process/tree/v7.0.3"
+                "source": "https://github.com/symfony/process/tree/v7.0.4"
             },
             "funding": [
                 {
@@ -9401,7 +9456,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-01-23T15:02:46+00:00"
+            "time": "2024-02-22T20:27:20+00:00"
         },
         {
             "name": "symfony/stopwatch",
@@ -9467,16 +9522,16 @@
         },
         {
             "name": "symfony/string",
-            "version": "v7.0.3",
+            "version": "v7.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/string.git",
-                "reference": "524aac4a280b90a4420d8d6a040718d0586505ac"
+                "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/string/zipball/524aac4a280b90a4420d8d6a040718d0586505ac",
-                "reference": "524aac4a280b90a4420d8d6a040718d0586505ac",
+                "url": "https://api.github.com/repos/symfony/string/zipball/f5832521b998b0bec40bee688ad5de98d4cf111b",
+                "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b",
                 "shasum": ""
             },
             "require": {
@@ -9533,7 +9588,7 @@
                 "utf8"
             ],
             "support": {
-                "source": "https://github.com/symfony/string/tree/v7.0.3"
+                "source": "https://github.com/symfony/string/tree/v7.0.4"
             },
             "funding": [
                 {
@@ -9549,20 +9604,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-01-29T15:41:16+00:00"
+            "time": "2024-02-01T13:17:36+00:00"
         },
         {
             "name": "symfony/var-exporter",
-            "version": "v7.0.3",
+            "version": "v7.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-exporter.git",
-                "reference": "1fb79308cb5fc2b44bff6e8af10a5af6812e05b8"
+                "reference": "dfb0acb6803eb714f05d97dd4c5abe6d5fa9fe41"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1fb79308cb5fc2b44bff6e8af10a5af6812e05b8",
-                "reference": "1fb79308cb5fc2b44bff6e8af10a5af6812e05b8",
+                "url": "https://api.github.com/repos/symfony/var-exporter/zipball/dfb0acb6803eb714f05d97dd4c5abe6d5fa9fe41",
+                "reference": "dfb0acb6803eb714f05d97dd4c5abe6d5fa9fe41",
                 "shasum": ""
             },
             "require": {
@@ -9607,7 +9662,7 @@
                 "serialize"
             ],
             "support": {
-                "source": "https://github.com/symfony/var-exporter/tree/v7.0.3"
+                "source": "https://github.com/symfony/var-exporter/tree/v7.0.4"
             },
             "funding": [
                 {
@@ -9623,7 +9678,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-01-23T15:02:46+00:00"
+            "time": "2024-02-26T10:35:24+00:00"
         },
         {
             "name": "theseer/tokenizer",

+ 30 - 0
config/settings.json

@@ -519,6 +519,36 @@
         "default": "",
         "mark": "aws ses发送者"
     },
+    {
+        "id": null,
+        "item": "mailchimp_key",
+        "value": "",
+        "class": "email",
+        "is_public": 0,
+        "type": "string",
+        "default": "",
+        "mark": "Mailchimp API密钥"
+    },
+    {
+        "id": null,
+        "item": "mailchimp_from_email",
+        "value": "",
+        "class": "email",
+        "is_public": 0,
+        "type": "string",
+        "default": "",
+        "mark": "Mailchimp Email"
+    },
+    {
+        "id": null,
+        "item": "mailchimp_from_name",
+        "value": "",
+        "class": "email",
+        "is_public": 0,
+        "type": "string",
+        "default": "",
+        "mark": "Mailchimp Sender"
+    },
     {
         "id": null,
         "item": "email_verify_code_ttl",

+ 61 - 31
resources/views/tabler/admin/setting/email.tpl

@@ -40,10 +40,10 @@
                                     <a href="#smtp" class="nav-link" data-bs-toggle="tab">SMTP</a>
                                 </li>
                                 <li class="nav-item">
-                                    <a href="#sendgrid" class="nav-link" data-bs-toggle="tab">Sendgrid</a>
+                                    <a href="#mailgun" class="nav-link" data-bs-toggle="tab">Mailgun</a>
                                 </li>
                                 <li class="nav-item">
-                                    <a href="#mailgun" class="nav-link" data-bs-toggle="tab">Mailgun</a>
+                                    <a href="#sendgrid" class="nav-link" data-bs-toggle="tab">Sendgrid</a>
                                 </li>
                                 <li class="nav-item">
                                     <a href="#postal" class="nav-link" data-bs-toggle="tab">Postal</a>
@@ -51,6 +51,8 @@
                                 <li class="nav-item">
                                     <a href="#ses" class="nav-link" data-bs-toggle="tab">AWS SES</a>
                                 </li>
+                                <li class="nav-item">
+                                    <a href="#mailchimp" class="nav-link" data-bs-toggle="tab">Mailchimp</a>
                             </ul>
                         </div>
                         <div class="card-body">
@@ -68,14 +70,14 @@
                                                     <option value="smtp"
                                                             {if $settings['email_driver'] === "smtp"}selected{/if}>smtp
                                                     </option>
-                                                    <option value="sendgrid"
-                                                            {if $settings['email_driver'] === "sendgrid"}selected{/if}>
-                                                        sendgrid
-                                                    </option>
                                                     <option value="mailgun"
                                                             {if $settings['email_driver'] === "mailgun"}selected{/if}>
                                                         mailgun
                                                     </option>
+                                                    <option value="sendgrid"
+                                                            {if $settings['email_driver'] === "sendgrid"}selected{/if}>
+                                                        sendgrid
+                                                    </option>
                                                     <option value="postal"
                                                             {if $settings['email_driver'] === "postal"}selected{/if}>
                                                         postal
@@ -83,6 +85,9 @@
                                                     <option value="ses"
                                                             {if $settings['email_driver'] === "ses"}selected{/if}>ses
                                                     </option>
+                                                    <option value="mailchimp"
+                                                            {if $settings['email_driver'] === "mailchimp"}selected{/if}>ses
+                                                    </option>
                                                 </select>
                                             </div>
                                         </div>
@@ -214,31 +219,6 @@
                                         </div>
                                     </div>
                                 </div>
-                                <div class="tab-pane" id="sendgrid">
-                                    <div class="card-body">
-                                        <div class="form-group mb-3 row">
-                                            <label class="form-label col-3 col-form-label">Sendgrid 密钥</label>
-                                            <div class="col">
-                                                <input id="sendgrid_key" type="text" class="form-control"
-                                                       value="{$settings['sendgrid_key']}">
-                                            </div>
-                                        </div>
-                                        <div class="form-group mb-3 row">
-                                            <label class="form-label col-3 col-form-label">Sendgrid 发信地址</label>
-                                            <div class="col">
-                                                <input id="sendgrid_sender" type="text" class="form-control"
-                                                       value="{$settings['sendgrid_sender']}">
-                                            </div>
-                                        </div>
-                                        <div class="form-group mb-3 row">
-                                            <label class="form-label col-3 col-form-label">Sendgrid 发件人名称</label>
-                                            <div class="col">
-                                                <input id="sendgrid_name" type="text" class="form-control"
-                                                       value="{$settings['sendgrid_name']}">
-                                            </div>
-                                        </div>
-                                    </div>
-                                </div>
                                 <div class="tab-pane" id="mailgun">
                                     <div class="card-body">
                                         <div class="form-group mb-3 row">
@@ -271,6 +251,31 @@
                                         </div>
                                     </div>
                                 </div>
+                                <div class="tab-pane" id="sendgrid">
+                                    <div class="card-body">
+                                        <div class="form-group mb-3 row">
+                                            <label class="form-label col-3 col-form-label">Sendgrid 密钥</label>
+                                            <div class="col">
+                                                <input id="sendgrid_key" type="text" class="form-control"
+                                                       value="{$settings['sendgrid_key']}">
+                                            </div>
+                                        </div>
+                                        <div class="form-group mb-3 row">
+                                            <label class="form-label col-3 col-form-label">Sendgrid 发信地址</label>
+                                            <div class="col">
+                                                <input id="sendgrid_sender" type="text" class="form-control"
+                                                       value="{$settings['sendgrid_sender']}">
+                                            </div>
+                                        </div>
+                                        <div class="form-group mb-3 row">
+                                            <label class="form-label col-3 col-form-label">Sendgrid 发件人名称</label>
+                                            <div class="col">
+                                                <input id="sendgrid_name" type="text" class="form-control"
+                                                       value="{$settings['sendgrid_name']}">
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
                                 <div class="tab-pane" id="postal">
                                     <div class="card-body">
                                         <div class="form-group mb-3 row">
@@ -335,6 +340,31 @@
                                         </div>
                                     </div>
                                 </div>
+                                <div class="tab-pane" id="mailchimp">
+                                    <div class="card-body">
+                                        <div class="form-group mb-3 row">
+                                            <label class="form-label col-3 col-form-label">Mailchimp API密钥</label>
+                                            <div class="col">
+                                                <input id="mailchimp_key" type="text" class="form-control"
+                                                       value="{$settings['mailchimp_key']}">
+                                            </div>
+                                        </div>
+                                        <div class="form-group mb-3 row">
+                                            <label class="form-label col-3 col-form-label">Mailchimp发件邮箱</label>
+                                            <div class="col">
+                                                <input id="mailchimp_from_email" type="text" class="form-control"
+                                                       value="{$settings['mailchimp_from_email']}">
+                                            </div>
+                                        </div>
+                                        <div class="form-group mb-3 row">
+                                            <label class="form-label col-3 col-form-label">Mailchimp发件人名称</label>
+                                            <div class="col">
+                                                <input id="mailchimp_from_name" type="text" class="form-control"
+                                                       value="{$settings['mailchimp_from_name']}">
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
                             </div>
                         </div>
                     </div>

+ 0 - 13
src/Command/ClientDownload.php

@@ -62,10 +62,6 @@ final class ClientDownload extends Command
 
     /**
      * 下载远程文件
-     *
-     * @param string $fileName
-     * @param string $savePath
-     * @param string $url
      */
     private function getSourceFile(string $fileName, string $savePath, string $url): bool
     {
@@ -98,8 +94,6 @@ final class ClientDownload extends Command
     /**
      * 获取 GitHub 常规 Release
      *
-     * @param string $repo
-     *
      * @throws GuzzleException
      */
     private function getLatestReleaseTagName(string $repo): string
@@ -117,8 +111,6 @@ final class ClientDownload extends Command
     /**
      * 获取 GitHub Pre-Release
      *
-     * @param string $repo
-     *
      * @throws GuzzleException
      */
     private function getLatestPreReleaseTagName(string $repo): string
@@ -190,11 +182,6 @@ final class ClientDownload extends Command
         );
     }
 
-    /**
-     * @param $name
-     * @param $taskName
-     * @param $tagName
-     */
     private static function getNames($name, $taskName, $tagName): array|string
     {
         return str_replace(

+ 0 - 4
src/Controllers/Admin/AnnController.php

@@ -67,10 +67,6 @@ final class AnnController extends BaseController
 
     /**
      * 后台添加公告
-     *
-     * @param ServerRequest $request
-     * @param Response $response
-     * @param array $args
      */
     public function add(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
     {

+ 0 - 4
src/Controllers/Admin/DocsController.php

@@ -121,10 +121,6 @@ final class DocsController extends BaseController
 
     /**
      * 后台编辑文档提交
-     *
-     * @param ServerRequest $request
-     * @param Response $response
-     * @param array $args
      */
     public function update(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
     {

+ 4 - 0
src/Controllers/Admin/Setting/EmailController.php

@@ -46,6 +46,10 @@ final class EmailController extends BaseController
         'postal_key',
         'postal_sender',
         'postal_name',
+        // Mailchimp
+        'mailchimp_key',
+        'mailchimp_from_email',
+        'mailchimp_from_name',
     ];
 
     /**

+ 0 - 4
src/Controllers/Admin/UserController.php

@@ -104,10 +104,6 @@ final class UserController extends BaseController
     }
 
     /**
-     * @param ServerRequest $request
-     * @param Response $response
-     * @param array $args
-     *
      * @throws Exception
      */
     public function create(ServerRequest $request, Response $response, array $args): Response|ResponseInterface

+ 0 - 19
src/Controllers/AuthController.php

@@ -53,11 +53,6 @@ final class AuthController extends BaseController
             ->fetch('auth/login.tpl'));
     }
 
-    /**
-     * @param ServerRequest $request
-     * @param Response $response
-     * @param array $args
-     */
     public function loginHandle(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
     {
         if (Config::obtain('enable_login_captcha') && ! Captcha::verify($request->getParams())) {
@@ -197,16 +192,6 @@ final class AuthController extends BaseController
     }
 
     /**
-     * @param Response $response
-     * @param $name
-     * @param $email
-     * @param $passwd
-     * @param $invite_code
-     * @param $imtype
-     * @param $imvalue
-     * @param $money
-     * @param $is_admin_reg
-     *
      * @throws Exception
      */
     public function registerHelper(
@@ -297,10 +282,6 @@ final class AuthController extends BaseController
     }
 
     /**
-     * @param ServerRequest $request
-     * @param Response $response
-     * @param array $args
-     *
      * @throws RedisException
      * @throws Exception
      */

+ 0 - 4
src/Controllers/SubController.php

@@ -21,10 +21,6 @@ use function strtotime;
 final class SubController extends BaseController
 {
     /**
-     * @param $request
-     * @param $response
-     * @param $args
-     *
      * @throws ClientExceptionInterface
      * @throws GuzzleException
      * @throws RedisException

+ 6 - 0
src/Controllers/WebAPI/FuncController.php

@@ -13,11 +13,17 @@ use Slim\Http\ServerRequest;
 
 final class FuncController extends BaseController
 {
+    /**
+     * GET /mod_mu/func/ping
+     */
     public function ping(ServerRequest $request, Response $response, array $args): ResponseInterface
     {
         return ResponseHelper::success($response, 'Pong? Pong!');
     }
 
+    /**
+     * GET /mod_mu/func/detect_rules
+     */
     public function getDetectRules(ServerRequest $request, Response $response, array $args): ResponseInterface
     {
         $rules = DetectRule::all()->toArray();

+ 3 - 0
src/Controllers/WebAPI/NodeController.php

@@ -16,6 +16,9 @@ use const VERSION;
 
 final class NodeController extends BaseController
 {
+    /**
+     * GET /mod_mu/nodes/{id}/info
+     */
     public function getInfo(ServerRequest $request, Response $response, array $args): ResponseInterface
     {
         $node_id = $args['id'];

+ 0 - 16
src/Controllers/WebAPI/UserController.php

@@ -27,10 +27,6 @@ final class UserController extends BaseController
 {
     /**
      * GET /mod_mu/users
-     *
-     * @param ServerRequest   $request
-     * @param Response  $response
-     * @param array     $args
      */
     public function index(ServerRequest $request, Response $response, array $args): ResponseInterface
     {
@@ -136,10 +132,6 @@ final class UserController extends BaseController
 
     /**
      * POST /mod_mu/users/traffic
-     *
-     * @param ServerRequest   $request
-     * @param Response  $response
-     * @param array     $args
      */
     public function addTraffic(ServerRequest $request, Response $response, array $args): ResponseInterface
     {
@@ -223,10 +215,6 @@ final class UserController extends BaseController
 
     /**
      * POST /mod_mu/users/aliveip
-     *
-     * @param ServerRequest   $request
-     * @param Response  $response
-     * @param array     $args
      */
     public function addAliveIp(ServerRequest $request, Response $response, array $args): ResponseInterface
     {
@@ -278,10 +266,6 @@ final class UserController extends BaseController
 
     /**
      * POST /mod_mu/users/detectlog
-     *
-     * @param ServerRequest   $request
-     * @param Response  $response
-     * @param array     $args
      */
     public function addDetectLog(ServerRequest $request, Response $response, array $args): ResponseInterface
     {

+ 0 - 3
src/Models/User.php

@@ -94,9 +94,6 @@ final class User extends Model
         'ref_by' => 'int',
     ];
 
-    /**
-     * @param $len
-     */
     public function getSs2022Pk($len): string
     {
         return Tools::genSs2022UserPk($this->passwd, $len);

+ 0 - 2
src/Services/Analytics.php

@@ -22,8 +22,6 @@ final class Analytics
 {
     /**
      * 获取累计收入
-     *
-     * @param string $req
      */
     public static function getIncome(string $req): float
     {

+ 8 - 7
src/Services/Mail.php

@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace App\Services;
 
 use App\Models\Config;
+use App\Services\Mail\Mailchimp;
 use App\Services\Mail\Mailgun;
 use App\Services\Mail\NullMail;
 use App\Services\Mail\Postal;
@@ -20,15 +21,16 @@ use Smarty;
  */
 final class Mail
 {
-    public static function getClient(): Mailgun|Smtp|SendGrid|NullMail|Ses|Postal
+    public static function getClient(): Mailchimp|Mailgun|NullMail|Postal|SendGrid|Ses|Smtp
     {
         $driver = Config::obtain('email_driver');
         return match ($driver) {
+            'mailchimp' => new Mailchimp(),
             'mailgun' => new Mailgun(),
+            'postal' => new Postal(),
+            'sendgrid' => new SendGrid(),
             'ses' => new Ses(),
             'smtp' => new Smtp(),
-            'sendgrid' => new SendGrid(),
-            'postal' => new Postal(),
             default => new NullMail(),
         };
     }
@@ -42,7 +44,6 @@ final class Mail
         $smarty->settemplatedir(BASE_PATH . '/resources/email/');
         $smarty->setcompiledir(BASE_PATH . '/storage/framework/smarty/compile/');
         $smarty->setcachedir(BASE_PATH . '/storage/framework/smarty/cache/');
-        // add config
         $smarty->assign('config', View::getConfig());
 
         foreach ($ary as $key => $value) {
@@ -56,10 +57,10 @@ final class Mail
      * @throws Exception
      * @throws ClientExceptionInterface
      */
-    public static function send($to, $subject, $template, $ary = [], $files = []): void
+    public static function send($to, $subject, $template, $array = []): void
     {
-        $text = self::genHtml($template, $ary);
+        $body = self::genHtml($template, $array);
 
-        self::getClient()->send($to, $subject, $text, $files);
+        self::getClient()->send($to, $subject, $body);
     }
 }

+ 1 - 1
src/Services/Mail/Base.php

@@ -6,5 +6,5 @@ namespace App\Services\Mail;
 
 abstract class Base
 {
-    abstract public function send($to, $subject, $text, $files): void;
+    abstract public function send($to, $subject, $body): void;
 }

+ 38 - 0
src/Services/Mail/Mailchimp.php

@@ -0,0 +1,38 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Services\Mail;
+
+use App\Models\Config;
+use MailchimpTransactional\ApiClient;
+
+final class Mailchimp extends Base
+{
+    private ApiClient $mc;
+    private string $from_email;
+    private string $from_name;
+
+    public function __construct()
+    {
+        $configs = Config::getClass('email');
+
+        $this->mc = new ApiClient();
+        $this->mc->setApiKey($configs['mailchimp_key']);
+        $this->from_email = $configs['mailchimp_from_email'];
+        $this->from_name = $configs['mailchimp_from_name'];
+    }
+
+    public function send($to, $subject, $body): void
+    {
+        $this->mc->messages->send([
+            'message' => [
+                'html' => $body,
+                'subject' => $subject,
+                'from_email' => $this->from_email,
+                'from_name' => $this->from_name,
+                'to' => [['email' => $to]],
+            ],
+        ]);
+    }
+}

+ 4 - 14
src/Services/Mail/Mailgun.php

@@ -8,13 +8,12 @@ use App\Models\Config;
 use Exception;
 use Mailgun\Mailgun as MG;
 use Psr\Http\Client\ClientExceptionInterface;
-use function basename;
 
 final class Mailgun extends Base
 {
     private MG $mg;
-    private mixed $domain;
-    private mixed $sender;
+    private string $domain;
+    private string $sender;
 
     public function __construct()
     {
@@ -29,22 +28,13 @@ final class Mailgun extends Base
      * @throws Exception
      * @throws ClientExceptionInterface
      */
-    public function send($to, $subject, $text, $files): void
+    public function send($to, $subject, $body): void
     {
-        $inline = [];
-
-        if ($files !== []) {
-            foreach ($files as $file_raw) {
-                $inline[] = ['filePath' => $file_raw, 'filename' => basename($file_raw)];
-            }
-        }
-
         $this->mg->messages()->send($this->domain, [
             'from' => $this->sender,
             'to' => $to,
             'subject' => $subject,
-            'html' => $text,
-            'inline' => $inline,
+            'html' => $body,
         ]);
     }
 }

+ 1 - 1
src/Services/Mail/NullMail.php

@@ -16,7 +16,7 @@ final class NullMail extends Base
         ];
     }
 
-    public function send($to, $subject, $text, $files): void
+    public function send($to, $subject, $body): void
     {
         echo '';
     }

+ 3 - 11
src/Services/Mail/Postal.php

@@ -7,8 +7,6 @@ namespace App\Services\Mail;
 use App\Models\Config;
 use Postal\Client;
 use Postal\Send\Message;
-use function basename;
-use function mime_content_type;
 
 final class Postal extends Base
 {
@@ -26,18 +24,12 @@ final class Postal extends Base
         $this->message->replyTo($configs['postal_sender']);
     }
 
-    public function send($to, $subject, $text, $files): void
+    public function send($to, $subject, $body): void
     {
         $this->message->subject($subject);
         $this->message->to($to);
-        $this->message->plainBody($text);
-        $this->message->htmlBody($text);
-
-        if ($files !== []) {
-            foreach ($files as $file_raw) {
-                $this->message->attach(basename($file_raw), mime_content_type($file_raw), $file_raw);
-            }
-        }
+        $this->message->plainBody($body);
+        $this->message->htmlBody($body);
 
         $this->client->send->message($this->message);
     }

+ 4 - 20
src/Services/Mail/SendGrid.php

@@ -8,9 +8,6 @@ use App\Models\Config;
 use SendGrid as SG;
 use SendGrid\Mail\Mail;
 use SendGrid\Mail\TypeException;
-use function base64_encode;
-use function basename;
-use function file_get_contents;
 
 final class SendGrid extends Base
 {
@@ -32,25 +29,12 @@ final class SendGrid extends Base
     /**
      * @throws TypeException
      */
-    public function send($to, $subject, $text, $files): void
+    public function send($to, $subject, $body): void
     {
         $this->email->setSubject($subject);
         $this->email->addTo($to);
-        $this->email->addContent('text/html', $text);
-
-        if ($files !== []) {
-            foreach ($files as $file_raw) {
-                $this->email->addAttachment(
-                    base64_encode(file_get_contents($file_raw)),
-                    'application/octet-stream',
-                    basename($file_raw),
-                    'attachment',
-                    'attachment'
-                );
-            }
-        }
-
-        $response = $this->sg->send($this->email);
-        echo $response->body();
+        $this->email->addContent('text/html', $body);
+
+        $this->sg->send($this->email);
     }
 }

+ 2 - 6
src/Services/Mail/Ses.php

@@ -27,7 +27,7 @@ final class Ses extends Base
         $this->ses = $ses;
     }
 
-    public function send($to, $subject, $text, $files): void
+    public function send($to, $subject, $body): void
     {
         $ses = $this->ses;
         $char_set = 'UTF-8';
@@ -41,11 +41,7 @@ final class Ses extends Base
                 'Body' => [
                     'Html' => [
                         'Charset' => $char_set,
-                        'Data' => $text,
-                    ],
-                    'Text' => [
-                        'Charset' => $char_set,
-                        'Data' => $text,
+                        'Data' => $body,
                     ],
                 ],
                 'Subject' => [

+ 10 - 20
src/Services/Mail/Smtp.php

@@ -20,18 +20,16 @@ final class Smtp extends Base
         $configs = Config::getClass('email');
 
         $mail = new PHPMailer();
-        //$mail->SMTPDebug = 3;                               // Enable verbose debug output
-        $mail->isSMTP();                                      // Set mailer to use SMTP
-        $mail->Host = $configs['smtp_host'];                  // Specify main and backup SMTP servers
-        $mail->Port = $configs['smtp_port'];                  // TCP port to connect to
-        $mail->SMTPAuth = true;                               // Enable SMTP authentication
-        $mail->CharSet = 'UTF-8';                             // Set utf-8 character set
-        $mail->Username = $configs['smtp_username'];          // SMTP username
-        $mail->Password = $configs['smtp_password'];          // SMTP password
+        $mail->isSMTP();
+        $mail->Host = $configs['smtp_host'];
+        $mail->Port = $configs['smtp_port'];
+        $mail->SMTPAuth = ! ($configs['smtp_username'] === '' && $configs['smtp_password'] === '');
+        $mail->CharSet = 'UTF-8';
+        $mail->Username = $configs['smtp_username'];
+        $mail->Password = $configs['smtp_password'];
         $mail->setFrom($configs['smtp_sender'], $configs['smtp_name']);
 
         if ($configs['smtp_ssl']) {
-            // Enable TLS encryption, `ssl` also accepted
             $mail->SMTPSecure = ($configs['smtp_port'] === '587' ? 'tls' : 'ssl');
         }
 
@@ -45,22 +43,14 @@ final class Smtp extends Base
     /**
      * @throws Exception
      */
-    public function send($to, $subject, $text, $files): void
+    public function send($to, $subject, $body): void
     {
         $mail = $this->mail;
         $mail->addAddress($to);     // Add a recipient
         $mail->isHTML();
         $mail->Subject = $subject;
-        $mail->Body = $text;
+        $mail->Body = $body;
 
-        if ($files !== []) {
-            foreach ($files as $file_raw) {
-                $mail->addAttachment($file_raw);
-            }
-        }
-
-        if (! $mail->send()) {
-            throw new Exception($mail->ErrorInfo);
-        }
+        $mail->send();
     }
 }

+ 0 - 4
src/Services/Subscribe.php

@@ -35,10 +35,6 @@ final class Subscribe
         return $_ENV['subUrl'] . '/sub/' . $token->token;
     }
 
-    /**
-     * @param $user
-     * @param bool $show_all_nodes
-     */
     public static function getUserNodes($user, bool $show_all_nodes = false): Collection
     {
         $query = Node::query();

+ 0 - 12
src/Utils/ResponseHelper.php

@@ -20,11 +20,6 @@ final class ResponseHelper
         ]);
     }
 
-    /**
-     * @param Response $response
-     * @param string $msg
-     * @param array $data
-     */
     public static function successWithData(Response $response, string $msg = '', array $data = []): ResponseInterface
     {
         return $response->withJson([
@@ -39,8 +34,6 @@ final class ResponseHelper
      *
      * **Note**: `RequestInterface` or `ResponseInterface` shouldn't be modified before/after calling this function.
      *
-     * @param RequestInterface $request
-     * @param ResponseInterface $response
      * @param mixed $data
      */
     public static function successWithDataEtag(
@@ -68,11 +61,6 @@ final class ResponseHelper
         ]);
     }
 
-    /**
-     * @param Response $response
-     * @param string $msg
-     * @param array $data
-     */
     public static function errorWithData(Response $response, string $msg = '', array $data = []): ResponseInterface
     {
         return $response->withJson([

+ 0 - 38
src/Utils/Tools.php

@@ -46,8 +46,6 @@ final class Tools
 {
     /**
      * 查询IP归属
-     *
-     * @param string $ip
      */
     public static function getIpLocation(string $ip): string
     {
@@ -88,9 +86,6 @@ final class Tools
 
     /**
      * 根据流量值自动转换单位输出
-     *
-     * @param $size
-     * @param int $precision
      */
     public static function autoBytes($size, int $precision = 2): string
     {
@@ -110,8 +105,6 @@ final class Tools
 
     /**
      * 根据含单位的流量值转换 B 输出
-     *
-     * @param $size
      */
     public static function autoBytesR($size): ?int
     {
@@ -132,9 +125,6 @@ final class Tools
 
     /**
      * 根据速率值自动转换单位输出
-     *
-     * @param $size
-     * @param int $precision
      */
     public static function autoMbps($size, int $precision = 2): string
     {
@@ -154,8 +144,6 @@ final class Tools
 
     /**
      * 虽然名字是toMB,但是实际上功能是from MB to B
-     *
-     * @param $traffic
      */
     public static function toMB($traffic): int
     {
@@ -164,25 +152,17 @@ final class Tools
 
     /**
      * 虽然名字是toGB,但是实际上功能是from GB to B
-     *
-     * @param $traffic
      */
     public static function toGB($traffic): int
     {
         return (int) $traffic * 1073741824;
     }
 
-    /**
-     * @param $traffic
-     */
     public static function flowToMB($traffic): float
     {
         return round($traffic / 1048576, 2);
     }
 
-    /**
-     * @param $traffic
-     */
     public static function flowToGB($traffic): float
     {
         return round($traffic / 1073741824, 2);
@@ -275,10 +255,6 @@ final class Tools
         return $dirArray;
     }
 
-    /**
-     * @param $type
-     * @param $str
-     */
     public static function isParamValidate($type, $str): bool
     {
         $list = self::getSsMethod($type);
@@ -352,9 +328,6 @@ final class Tools
         }
     }
 
-    /**
-     * @param $input
-     */
     public static function isEmail($input): bool
     {
         if (! filter_var($input, FILTER_VALIDATE_EMAIL)) {
@@ -364,9 +337,6 @@ final class Tools
         return true;
     }
 
-    /**
-     * @param $input
-     */
     public static function isIPv4($input): bool
     {
         if (! filter_var($input, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
@@ -376,9 +346,6 @@ final class Tools
         return true;
     }
 
-    /**
-     * @param $input
-     */
     public static function isIPv6($input): bool
     {
         if (! filter_var($input, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
@@ -388,9 +355,6 @@ final class Tools
         return true;
     }
 
-    /**
-     * @param $input
-     */
     public static function isInt($input): bool
     {
         if (! filter_var($input, FILTER_VALIDATE_INT)) {
@@ -403,8 +367,6 @@ final class Tools
     /**
      * 判断是否 JSON
      * TODO: Remove this function when PHP 8.3 is minimum requirement and replace it with native function
-     *
-     * @param string $string
      */
     public static function isJson(string $string): bool
     {