Support PHP8 Attribute for hyperf/constants. (#6640)

This commit is contained in:
李铭昕 2024-03-31 19:35:28 +08:00 committed by GitHub
parent 478858a5dd
commit 941758a639
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 142 additions and 1 deletions

View File

@ -10,6 +10,10 @@
- [#6633](https://github.com/hyperf/hyperf/pull/6633) Fixed bug that crontab will be skipped sometimes.
- [#6635](https://github.com/hyperf/hyperf/pull/6635) Fixed AMQP `ConsumerMessage::getQueue` return type.
## Optimized
- [#6640](https://github.com/hyperf/hyperf/pull/6640) Support PHP8 Attribute for `hyperf/constants`.
# v3.1.15 - 2024-03-28
## Added

View File

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace Hyperf\Constants\Annotation;
use Attribute;
#[Attribute(Attribute::TARGET_CLASS_CONSTANT | Attribute::IS_REPEATABLE)]
class Message
{
public function __construct(public string $value, public string $key = 'message')
{
}
}

View File

@ -13,6 +13,7 @@ declare(strict_types=1);
namespace Hyperf\Constants;
use BackedEnum;
use Hyperf\Constants\Annotation\Message;
use Hyperf\Stringable\Str;
use ReflectionClassConstant;
@ -35,6 +36,14 @@ class AnnotationReader
if ($docComment && (is_int($code) || is_string($code))) {
$result[$code] = $this->parse($docComment, $result[$code] ?? []);
}
// Support PHP8 Attribute.
foreach ($classConstant->getAttributes() as $ref) {
$attribute = $ref->newInstance();
if ($attribute instanceof Message) {
$result[$code][$attribute->key] = $attribute->value;
}
}
}
return $result;

View File

@ -39,6 +39,7 @@ trait EnumConstantsTrait
$this instanceof UnitEnum => $this->name,
default => throw new ConstantsException('This trait must in enum'),
};
return static::getValue($name, [$code, ...$arguments]);
}

View File

@ -20,7 +20,9 @@ use Hyperf\Contract\ContainerInterface;
use Hyperf\Contract\TranslatorInterface;
use Hyperf\Translation\ArrayLoader;
use Hyperf\Translation\Translator;
use HyperfTest\Constants\Stub\CannotNewInstance;
use HyperfTest\Constants\Stub\ErrorCodeStub;
use HyperfTest\Constants\Stub\WarnCode;
use Mockery;
use PHPUnit\Framework\Attributes\CoversNothing;
use PHPUnit\Framework\TestCase;
@ -43,6 +45,11 @@ class AnnotationReaderTest extends TestCase
$data = $reader->getAnnotations($classConstants);
ConstantsCollector::set(ErrorCodeStub::class, $data);
$ref = new ReflectionClass(WarnCode::class);
$classConstants = $ref->getReflectionConstants();
$data = $reader->getAnnotations($classConstants);
ConstantsCollector::set(WarnCode::class, $data);
Context::set(sprintf('%s::%s', TranslatorInterface::class, 'locale'), null);
}
@ -120,6 +127,34 @@ class AnnotationReaderTest extends TestCase
$this->assertSame('TypeString', ErrorCodeStub::getMessage(ErrorCodeStub::TYPE_STRING));
}
public function testPHP8Attribute()
{
$this->getContainer(true);
$this->assertSame('Not Found.', ErrorCodeStub::getMessage(ErrorCodeStub::NOT_FOUND));
}
public function testEnum()
{
$this->getContainer(true);
$this->assertSame('不存在', WarnCode::NOT_FOUND->getMessage());
$this->assertSame('越权操作', WarnCode::PERMISSION_DENY->getMessage());
$this->assertSame('系统内部错误', WarnCode::SERVER_ERROR->getMessage());
}
public function testCannotNewInstance()
{
$reader = new AnnotationReader();
$ref = new ReflectionClass(CannotNewInstance::class);
$classConstants = $ref->getReflectionConstants();
$this->expectExceptionMessage('Attribute class "HyperfTest\Constants\Stub\NotFound" not found');
$data = $reader->getAnnotations($classConstants);
}
protected function getContainer($has = false)
{
$container = Mockery::mock(ContainerInterface::class);

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace HyperfTest\Constants\Stub;
use Hyperf\Constants\Annotation\Constants;
use Hyperf\Constants\Annotation\Message;
#[Constants]
enum CannotNewInstance: int
{
/**
* @Message("Server Error")
*/
#[Message('系统内部错误')]
#[NotFound('不存在的注解')]
case SERVER_ERROR = 500;
}

View File

@ -13,9 +13,13 @@ declare(strict_types=1);
namespace HyperfTest\Constants\Stub;
use Hyperf\Constants\AbstractConstants;
use Hyperf\Constants\Annotation\Message;
class ErrorCodeStub extends AbstractConstants
{
#[Message('Not Found.')]
public const NOT_FOUND = 404;
/**
* @Message("Server Error!")
*/
@ -23,8 +27,9 @@ class ErrorCodeStub extends AbstractConstants
/**
* @Message("SHOW ECHO")
* @Echo("ECHO")
* @Echo("Don't ECHO")
*/
#[Message('ECHO', 'echo')]
public const SHOW_ECHO = 501;
public const NO_MESSAGE = 502;

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace HyperfTest\Constants\Stub;
use Hyperf\Constants\Annotation\Constants;
use Hyperf\Constants\Annotation\Message;
use Hyperf\Constants\EnumConstantsTrait;
#[Constants]
enum WarnCode: int
{
use EnumConstantsTrait;
#[Message('越权操作')]
case PERMISSION_DENY = 403;
/**
* @Message("不存在")
*/
case NOT_FOUND = 404;
/**
* @Message("Server Error")
*/
#[Message('系统内部错误')]
case SERVER_ERROR = 500;
}