mirror of
http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore.git
synced 2026-01-15 05:35:09 +08:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c060e84476 | ||
|
|
bebac5992a | ||
|
|
7d15d85515 | ||
|
|
04719839ad | ||
|
|
1c057722bc | ||
|
|
52f4867c72 | ||
|
|
b51699b0d9 | ||
|
|
a570e1964e | ||
|
|
def9f0469d | ||
|
|
5ed5070f32 | ||
|
|
8dcf586baf | ||
|
|
a7a8087509 | ||
|
|
e50a2e08df | ||
|
|
fca8f9d013 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
vendor/
|
||||
.phpunit.result.cache
|
||||
.php-cs-fixer.cache
|
||||
.php-cs-fixer.cache
|
||||
runtime/
|
||||
2
.idea/HDK-Core.iml
generated
2
.idea/HDK-Core.iml
generated
@@ -2,7 +2,6 @@
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="Singularity\HDK\Core\" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Singularity\HDK\Test\Core\" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
|
||||
@@ -92,7 +91,6 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-ctype" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php81" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
|
||||
|
||||
24
.idea/php-docker-settings.xml
generated
Normal file
24
.idea/php-docker-settings.xml
generated
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PhpDockerContainerSettings">
|
||||
<list>
|
||||
<map>
|
||||
<entry key="9fb85f67-19fd-423f-9358-1b155a12eb7d">
|
||||
<value>
|
||||
<DockerContainerSettings>
|
||||
<option name="version" value="1" />
|
||||
<option name="volumeBindings">
|
||||
<list>
|
||||
<DockerVolumeBindingImpl>
|
||||
<option name="containerPath" value="/opt/project" />
|
||||
<option name="hostPath" value="$PROJECT_DIR$" />
|
||||
</DockerVolumeBindingImpl>
|
||||
</list>
|
||||
</option>
|
||||
</DockerContainerSettings>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</list>
|
||||
</component>
|
||||
</project>
|
||||
14
.idea/php.xml
generated
14
.idea/php.xml
generated
@@ -107,7 +107,6 @@
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php80" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-ctype" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php81" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
|
||||
@@ -154,6 +153,19 @@
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/deprecations" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/clock" />
|
||||
<path value="$PROJECT_DIR$/vendor/hyperf/crontab" />
|
||||
<path value="$PROJECT_DIR$/vendor/fidry/cpu-core-counter" />
|
||||
<path value="$PROJECT_DIR$/vendor/carbonphp/carbon-doctrine-types" />
|
||||
<path value="$PROJECT_DIR$/vendor/cooper/hyperf-pest" />
|
||||
<path value="$PROJECT_DIR$/vendor/clue/ndjson-react" />
|
||||
<path value="$PROJECT_DIR$/vendor/evenement/evenement" />
|
||||
<path value="$PROJECT_DIR$/vendor/react/child-process" />
|
||||
<path value="$PROJECT_DIR$/vendor/react/cache" />
|
||||
<path value="$PROJECT_DIR$/vendor/react/dns" />
|
||||
<path value="$PROJECT_DIR$/vendor/react/stream" />
|
||||
<path value="$PROJECT_DIR$/vendor/react/event-loop" />
|
||||
<path value="$PROJECT_DIR$/vendor/react/socket" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="7.4" />
|
||||
|
||||
55
CHANGELOG.md
55
CHANGELOG.md
@@ -1,4 +1,59 @@
|
||||
# 版本更新日志
|
||||
### [0.1.9](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/compare/v0.1.8...v0.1.9) (2024-09-12)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **email:** 增加了单独定制发件人的方法 ([bebac59](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/commit/bebac5992a89ebe41eb20ea926938f4b3fde2cc1))
|
||||
|
||||
### [0.1.8](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/compare/v0.1.7...v0.1.8) (2024-09-12)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **email:** 增加了密送参数 ([1c05772](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/commit/1c057722bcf407ab1faf6b5feb285e1e472fc627))
|
||||
|
||||
|
||||
### 📦 Build System | 打包构建
|
||||
|
||||
* **composer:** 更新依赖 ([0471983](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/commit/04719839ad518ef3c00ffb67b8b563561de36858))
|
||||
|
||||
### [0.1.7](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/compare/v0.1.6...v0.1.7) (2023-07-05)
|
||||
|
||||
|
||||
### 📦 Build System | 打包构建
|
||||
|
||||
* **composer:** 更新依赖 ([a570e19](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/commit/a570e1964e01b9e29de05f4a7607a4ed567beffa))
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **session:** 增加了定制的 session 中间件 ([b51699b](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/commit/b51699b0d98322df33fb3a0bccebe5f4034e2a71))
|
||||
|
||||
### [0.1.6](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/compare/v0.1.5...v0.1.6) (2023-03-21)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes | Bug 修复
|
||||
|
||||
* **middleware.i18n:** 尝试修复了多语言无法正确获取的问题 ([a7a8087](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/commit/a7a80875092653e56d8dc9351743a08933d59282))
|
||||
|
||||
|
||||
### ✅ Tests | 测试
|
||||
|
||||
* **email:** 更新了邮件发送的测试账号 ([8dcf586](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/commit/8dcf586baf1960f906d63c15f3d659b16b456048))
|
||||
|
||||
|
||||
### 📦 Build System | 打包构建
|
||||
|
||||
* **composer:** 更新依赖 ([5ed5070](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/commit/5ed5070f323d0ea34b8c99b5ac826dc6c24431df))
|
||||
|
||||
### [0.1.5](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/compare/v0.1.4...v0.1.5) (2023-02-03)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes | Bug 修复
|
||||
|
||||
* **commonHandler:** 修复了一处兼容问题 ([fca8f9d](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/commit/fca8f9d013e1d121bf8bc997710d77ff038fdae0))
|
||||
|
||||
### [0.1.4](http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore/compare/v0.1.3...v0.1.4) (2023-02-02)
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
"firebase/php-jwt": "^6.3",
|
||||
"friendsofphp/php-cs-fixer": "^3.13",
|
||||
"guzzlehttp/guzzle": "^7.5",
|
||||
"hyperf/crontab": "<=3.0.9 || >3.0.13 <3.1",
|
||||
"hyperf/session": "^2.2",
|
||||
"hyperf/validation": "^2.2",
|
||||
"pestphp/pest": "^1.22",
|
||||
@@ -57,7 +58,11 @@
|
||||
"hyperf/session": "Session 鉴权必需",
|
||||
"symfony/mailer": "用于发送电子邮件",
|
||||
"guzzlehttp/guzzle": "需要发起 http 请求时必需",
|
||||
"alibabacloud/dysmsapi-20170525": "阿里云短信服务必需"
|
||||
"alibabacloud/dysmsapi-20170525": "阿里云短信服务必需",
|
||||
"laminas/laminas-text": "用于cli展示表格和大字",
|
||||
"gevman/interactive-cli": "用于提供漂亮的交互式命令行",
|
||||
"clue/stdio-react": "一个基于 reactphp 的交互式命令行",
|
||||
"brainmaestro/composer-git-hooks": "用于 php 项目的 git-hooks"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
@@ -109,5 +114,5 @@
|
||||
"url": "https://repo.huaweicloud.com/repository/php/"
|
||||
}
|
||||
},
|
||||
"version": "0.1.4"
|
||||
"version": "0.1.9"
|
||||
}
|
||||
|
||||
2548
composer.lock
generated
2548
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace Singularity\HDK\Core\Events;
|
||||
|
||||
use Singularity\HDK\Core\Service\EmailService;
|
||||
|
||||
/**
|
||||
* Singularity\HDK\Core\Events\EmailWillSent@HDK-Core
|
||||
*
|
||||
@@ -41,11 +43,21 @@ class EmailWillSent
|
||||
*/
|
||||
public array $cc = [];
|
||||
|
||||
/**
|
||||
* @var string[] $bcc
|
||||
*/
|
||||
public array $bcc = [];
|
||||
|
||||
/**
|
||||
* @var string 'text'|'html' $type
|
||||
*/
|
||||
public string $type = 'text';
|
||||
|
||||
/**
|
||||
* @var EmailService|null
|
||||
*/
|
||||
public ?EmailService $sender;
|
||||
|
||||
|
||||
public function __construct(
|
||||
/**
|
||||
@@ -58,12 +70,16 @@ class EmailWillSent
|
||||
* @var non-empty-string[] $cc
|
||||
*/
|
||||
array $cc = [],
|
||||
string $type = 'text'
|
||||
string $type = 'text',
|
||||
array $bcc = [],
|
||||
?EmailService $sender = null
|
||||
) {
|
||||
$this->type = $type;
|
||||
$this->cc = $cc;
|
||||
$this->content = $content;
|
||||
$this->subject = $subject;
|
||||
$this->target = $target;
|
||||
$this->bcc = $bcc;
|
||||
$this->sender = $sender;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ class CommonHandler extends ExceptionHandler
|
||||
$this->request->url();
|
||||
|
||||
$is_debug = $this->request->hasHeader('Postman-Token')
|
||||
|| str_starts_with($this->request->header('User-Agent'), 'apifox');
|
||||
|| str_starts_with($this->request->header('User-Agent', ''), 'apifox');
|
||||
|
||||
$request_data = Json::encode($this->request->getParsedBody());
|
||||
$request_headers = Json::encode($this->request->getHeaders());
|
||||
|
||||
@@ -9,11 +9,7 @@
|
||||
|
||||
namespace Singularity\HDK\Core\Listener;
|
||||
|
||||
use Hyperf\Contract\ContainerInterface;
|
||||
use Hyperf\Contract\StdoutLoggerInterface;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use JetBrains\PhpStorm\NoReturn;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use Singularity\HDK\Core\Constants\CommonErrorCode;
|
||||
@@ -43,7 +39,8 @@ class EmailWillSentListener extends AbstractListener
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EmailWillSent $event
|
||||
* @param object $event
|
||||
*
|
||||
* @return void
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
@@ -51,20 +48,24 @@ class EmailWillSentListener extends AbstractListener
|
||||
public function process(object $event): void
|
||||
{
|
||||
$stdoutLogger = $this->container->get(StdoutLoggerInterface::class);
|
||||
$emailService = $this->container->get(EmailService::class);
|
||||
|
||||
/** @var $event EmailWillSent */
|
||||
$emailService = $event->sender ?? EmailService::make();
|
||||
try {
|
||||
$event->type === 'html'
|
||||
? $emailService->sendHtml(
|
||||
$event->target,
|
||||
$event->subject,
|
||||
$event->content,
|
||||
$event->cc
|
||||
$event->cc,
|
||||
$event->bcc,
|
||||
)
|
||||
: $emailService->sendText(
|
||||
$event->target,
|
||||
$event->subject,
|
||||
$event->content,
|
||||
$event->cc
|
||||
$event->cc,
|
||||
$event->bcc,
|
||||
);
|
||||
|
||||
$stdoutLogger->info('邮件发送成功!');
|
||||
|
||||
@@ -36,10 +36,10 @@ class InternationalizationMiddleware implements MiddlewareInterface
|
||||
$language = $request->getHeaderLine('Accept-Language');
|
||||
if (!empty($language)) {
|
||||
switch (true) {
|
||||
case in_array($language, ['en', 'en_us', 'en-us', 'en-uk', 'en_uk']):
|
||||
case in_array(strtolower($language), ['en', 'en_us', 'en-us', 'en-uk', 'en_uk']):
|
||||
$language = 'en';
|
||||
break;
|
||||
case in_array($language, ['zh', 'zh_cn', 'zh-cn']):
|
||||
case in_array(strtolower($language), ['zh', 'zh_cn', 'zh-cn']):
|
||||
$language = 'zh_CN';
|
||||
break;
|
||||
default:
|
||||
|
||||
165
src/Middleware/SessionMiddleware.php
Normal file
165
src/Middleware/SessionMiddleware.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
/**
|
||||
* SessionMiddleware.php@HDK-Core
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/3/8
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Core\Middleware;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Contract\SessionInterface;
|
||||
use Hyperf\HttpMessage\Cookie\Cookie;
|
||||
use Hyperf\HttpMessage\Server\Response;
|
||||
use Hyperf\Session\SessionManager;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
|
||||
/**
|
||||
* Singularity\HDK\Auth\Middleware\SessionMiddleware@HDK-Core
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/3/8
|
||||
*/
|
||||
class SessionMiddleware implements MiddlewareInterface
|
||||
{
|
||||
private SessionManager $sessionManager;
|
||||
private ConfigInterface $config;
|
||||
|
||||
public function __construct(SessionManager $sessionManager, ConfigInterface $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->sessionManager = $sessionManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an incoming server request.
|
||||
* Processes an incoming server request in order to produce a response.
|
||||
* If unable to produce the response itself, it may delegate to the provided
|
||||
* request handler to do so.
|
||||
*/
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
if (!$this->isSessionAvailable()) {
|
||||
return $handler->handle($request);
|
||||
}
|
||||
|
||||
$session = $this->sessionManager->start($request);
|
||||
|
||||
try {
|
||||
$response = $handler->handle($request);
|
||||
} finally {
|
||||
$this->storeCurrentUrl($request, $session);
|
||||
$session = $this->sessionManager->getSession();
|
||||
|
||||
/*
|
||||
* 现在的机制,但凡写入 Redis 的数据,
|
||||
* 过期时间就是固定的 gc_maxlifetime
|
||||
*
|
||||
* 而 RedisHandler 只会被依赖注入时加载一次,
|
||||
* 后续无法临时修改 gc_maxlifetime
|
||||
*
|
||||
* 又因为现在没有其他情况用到 session
|
||||
* 只有登录之后才会记下用户信息
|
||||
*
|
||||
* 所以一个妥协的方案,就是只有登录了再写入 Redis
|
||||
*
|
||||
* (除非重写整套 RedisHandler/RedisHandlerFactory/...)
|
||||
*/
|
||||
if (!$this->auth($session)) {
|
||||
$this->sessionManager->end($session);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->addCookieToResponse($request, $response, $session);
|
||||
}
|
||||
|
||||
private function isSessionAvailable(): bool
|
||||
{
|
||||
return $this->config->has('session.handler');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the current URL for the request if necessary.
|
||||
*/
|
||||
private function storeCurrentUrl(RequestInterface $request, SessionInterface $session)
|
||||
{
|
||||
if ($request->getMethod() === 'GET') {
|
||||
$session->setPreviousUrl($this->fullUrl($request));
|
||||
}
|
||||
}
|
||||
|
||||
private function auth(SessionInterface $session): bool
|
||||
{
|
||||
return $session->has('userInfo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the session cookie to the response·.
|
||||
*/
|
||||
private function addCookieToResponse(
|
||||
ServerRequestInterface $request,
|
||||
ResponseInterface $response,
|
||||
SessionInterface $session
|
||||
): ResponseInterface {
|
||||
$cookie = new Cookie(
|
||||
$session->getName(),
|
||||
$session->getId(),
|
||||
$this->getCookieExpirationDate($session),
|
||||
$this->config->get('session.options.path', '/'),
|
||||
$this->config->get('session.options.domain', $request->getUri()->getHost()),
|
||||
$this->config->get(
|
||||
'session.options.secure',
|
||||
strtolower($request->getUri()->getScheme()) === 'https'
|
||||
),
|
||||
true,
|
||||
$this->config->get('session.options.samesite', Cookie::SAMESITE_LAX)
|
||||
);
|
||||
if (!method_exists($response, 'withCookie')) {
|
||||
return $response->withHeader('Set-Cookie', (string)$cookie);
|
||||
}
|
||||
/* @var Response $response */
|
||||
return $response->withCookie($cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full URL for the request.
|
||||
*/
|
||||
private function fullUrl(RequestInterface $request): string
|
||||
{
|
||||
$uri = $request->getUri();
|
||||
$query = $uri->getQuery();
|
||||
$question = $uri->getHost() . $uri->getPath() == '/' ? '/?' : '?';
|
||||
return $query ? $this->url($request) . $question . $query : $this->url($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the session lifetime in seconds.
|
||||
*/
|
||||
private function getCookieExpirationDate(SessionInterface $session): int
|
||||
{
|
||||
// if ($this->config->get('session.options.expire_on_close')) {
|
||||
if (!$this->auth($session)) {
|
||||
$expirationDate = 0;
|
||||
} else {
|
||||
$expireSeconds = $this->config->get('session.options.cookie_lifetime', 5 * 60 * 60);
|
||||
$expirationDate = Carbon::now()->addSeconds($expireSeconds)->getTimestamp();
|
||||
}
|
||||
return $expirationDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL (no query string) for the request.
|
||||
*/
|
||||
private function url(RequestInterface $request): string
|
||||
{
|
||||
return rtrim(preg_replace('/\?.*/', '', (string)$request->getUri()));
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,18 @@ class EmailService
|
||||
);
|
||||
}
|
||||
|
||||
public static function make(
|
||||
?string $dsn = null,
|
||||
?string $mailSenderName = null,
|
||||
?string $mailSender = null
|
||||
): EmailService {
|
||||
return new static(
|
||||
$dsn,
|
||||
$mailSenderName,
|
||||
$mailSender,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮件
|
||||
*
|
||||
@@ -66,9 +78,10 @@ class EmailService
|
||||
|
||||
/**
|
||||
* @param string|array<string> $target
|
||||
* @param string $subject
|
||||
* @param string $text
|
||||
* @param string $subject
|
||||
* @param string $text
|
||||
* @param array<string> $cc
|
||||
* @param array $bcc
|
||||
*
|
||||
* @return bool
|
||||
* @throws TransportExceptionInterface
|
||||
@@ -77,12 +90,14 @@ class EmailService
|
||||
$target,
|
||||
string $subject,
|
||||
string $text,
|
||||
array $cc = []
|
||||
array $cc = [],
|
||||
array $bcc = []
|
||||
): bool {
|
||||
$email = (new Email())
|
||||
->from(Address::create($this->from))
|
||||
->to(...(is_array($target) ? $target : [$target]))
|
||||
->cc(...$cc)
|
||||
->bcc(...$bcc)
|
||||
->subject($subject)
|
||||
->text($text);
|
||||
|
||||
@@ -95,9 +110,10 @@ class EmailService
|
||||
* 以 HTML 格式发送邮件
|
||||
*
|
||||
* @param string|array<string> $target
|
||||
* @param string $subject
|
||||
* @param string $html
|
||||
* @param string $subject
|
||||
* @param string $html
|
||||
* @param array<string> $cc
|
||||
* @param array $bcc
|
||||
*
|
||||
* @return bool
|
||||
* @throws TransportExceptionInterface
|
||||
@@ -106,12 +122,14 @@ class EmailService
|
||||
$target,
|
||||
string $subject,
|
||||
string $html,
|
||||
array $cc = []
|
||||
array $cc = [],
|
||||
array $bcc = []
|
||||
): bool {
|
||||
$email = (new Email())
|
||||
->from(Address::create($this->from))
|
||||
->to(...(is_array($target) ? $target : [$target]))
|
||||
->cc(...$cc)
|
||||
->bcc(...$bcc)
|
||||
->subject($subject)
|
||||
->html($html);
|
||||
|
||||
|
||||
@@ -12,25 +12,27 @@ namespace Singularity\HDK\Test\Core\Service;
|
||||
use Singularity\HDK\Core\Service\EmailService;
|
||||
use Symfony\Component\Mailer\Exception\TransportException;
|
||||
|
||||
$dsn = 'smtp://account@luxcreo.ai:Qfsd8866@smtp.qiye.aliyun.com:465';
|
||||
$dsn = 'smtp://account@luxcreo.com:Qfsd8866@smtp-mail.outlook.com:587';
|
||||
$mail_sender_name = 'LuxCreo';
|
||||
$mail_sender = 'account@luxcreo.ai';
|
||||
$mail_sender = 'account@luxcreo.com';
|
||||
$email = new EmailService($dsn, $mail_sender_name, $mail_sender);
|
||||
|
||||
it('assertions that send HTML is available', function () use ($email) {
|
||||
$result = $email->sendHtml(
|
||||
'dongyun.li@luxcreo.ai',
|
||||
'HDK Unit Test HTML',
|
||||
<<<HTML
|
||||
$target = 'dongyun.li@luxcreo.ai';
|
||||
|
||||
it('assertions that send HTML is available', function () use ($email, $target) {
|
||||
$result = $email->sendHtml(
|
||||
$target,
|
||||
'HDK Unit Test HTML',
|
||||
<<<HTML
|
||||
<h1>Hello, World!</h1>
|
||||
HTML
|
||||
);
|
||||
expect($result)->toBeTrue();
|
||||
);
|
||||
expect($result)->toBeTrue();
|
||||
});
|
||||
|
||||
it('assertions that send Text is available', function () use ($email) {
|
||||
it('assertions that send Text is available', function () use ($email, $target) {
|
||||
$result = $email->sendText(
|
||||
'dongyun.li@luxcreo.ai',
|
||||
$target,
|
||||
'HDK Unit Test Text',
|
||||
<<<Text
|
||||
<h1>Hello, World!</h1>
|
||||
@@ -41,24 +43,26 @@ Text
|
||||
|
||||
it('assertions Error Receiver can be catch', function () use ($email) {
|
||||
try {
|
||||
$email->sendHtml(
|
||||
$result = $email->sendHtml(
|
||||
'unknown@luxcreo.ai',
|
||||
'HDK Unit Test',
|
||||
<<<HTML
|
||||
<h1>Hello, World!</h1>
|
||||
HTML
|
||||
);
|
||||
expect($result)->toBeTrue();
|
||||
} catch (TransportException $t) {
|
||||
expect($t->getCode())->toBe(554);
|
||||
}
|
||||
try {
|
||||
$email->sendText(
|
||||
$result = $email->sendText(
|
||||
'unknown@luxcreo.ai',
|
||||
'HDK Unit Test',
|
||||
<<<Text
|
||||
<h1>Hello, World!</h1>
|
||||
Text
|
||||
);
|
||||
expect($result)->toBeTrue();
|
||||
} catch (TransportException $t) {
|
||||
expect($t->getCode())->toBe(554);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user