Skip to content

Commit 9dbcb70

Browse files
Support setting multiple annotations by inheriting AbstractMultipleAnnotation, such as @Middleware. (#3791)
Co-authored-by: assert <[email protected]> Co-authored-by: 李铭昕 <[email protected]>
1 parent 5ecf8bb commit 9dbcb70

File tree

4 files changed

+153
-2
lines changed

4 files changed

+153
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of Hyperf.
6+
*
7+
* @link https://www.hyperf.io
8+
* @document https://hyperf.wiki
9+
* @contact [email protected]
10+
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
11+
*/
12+
namespace Hyperf\Di\Annotation;
13+
14+
abstract class AbstractMultipleAnnotation extends AbstractAnnotation
15+
{
16+
public function collectClass(string $className): void
17+
{
18+
$annotation = AnnotationCollector::getClassAnnotation($className, static::class);
19+
20+
AnnotationCollector::collectClass($className, static::class, $this->formatAnnotation($annotation));
21+
}
22+
23+
public function collectMethod(string $className, ?string $target): void
24+
{
25+
$annotation = AnnotationCollector::getClassMethodAnnotation($className, $target)[static::class] ?? null;
26+
27+
AnnotationCollector::collectMethod($className, $target, static::class, $this->formatAnnotation($annotation));
28+
}
29+
30+
public function collectProperty(string $className, ?string $target): void
31+
{
32+
$annotation = AnnotationCollector::getClassPropertyAnnotation($className, $target)[static::class] ?? null;
33+
34+
AnnotationCollector::collectProperty($className, $target, static::class, $this->formatAnnotation($annotation));
35+
}
36+
37+
protected function formatAnnotation(?MultipleAnnotation $annotation): MultipleAnnotation
38+
{
39+
if ($annotation instanceof MultipleAnnotation) {
40+
return $annotation->insert($this);
41+
}
42+
43+
return new MultipleAnnotation($this);
44+
}
45+
}

src/Annotation/MultipleAnnotation.php

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of Hyperf.
6+
*
7+
* @link https://www.hyperf.io
8+
* @document https://hyperf.wiki
9+
* @contact [email protected]
10+
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
11+
*/
12+
namespace Hyperf\Di\Annotation;
13+
14+
use Hyperf\Di\Exception\AnnotationException;
15+
16+
class MultipleAnnotation implements MultipleAnnotationInterface
17+
{
18+
/**
19+
* @var AnnotationInterface[]
20+
*/
21+
protected $annotations = [];
22+
23+
/**
24+
* @var string
25+
*/
26+
protected $className;
27+
28+
public function __construct(AnnotationInterface $annotation)
29+
{
30+
$this->annotations = [$annotation];
31+
$this->className = get_class($annotation);
32+
}
33+
34+
public function __get(string $name)
35+
{
36+
if (count($this->annotations) > 1) {
37+
throw new AnnotationException('MultipleAnnotation[' . $this->className() . '] has more than one annotations.');
38+
}
39+
40+
return $this->annotations[0]->{$name};
41+
}
42+
43+
public function className(): string
44+
{
45+
return $this->className;
46+
}
47+
48+
public function insert(AnnotationInterface $annotation)
49+
{
50+
if (! $annotation instanceof $this->className) {
51+
throw new AnnotationException(get_class($annotation) . ' must instanceof ' . $this->className);
52+
}
53+
54+
$this->annotations[] = $annotation;
55+
return $this;
56+
}
57+
58+
public function toAnnotations(): array
59+
{
60+
return $this->annotations;
61+
}
62+
63+
public function collectClass(string $className): void
64+
{
65+
throw new AnnotationException('MultipleAnnotation[' . $this->className() . '] does not support collectClass()');
66+
}
67+
68+
public function collectMethod(string $className, ?string $target): void
69+
{
70+
throw new AnnotationException('MultipleAnnotation[' . $this->className() . '] does not support collectMethod()');
71+
}
72+
73+
public function collectProperty(string $className, ?string $target): void
74+
{
75+
throw new AnnotationException('MultipleAnnotation[' . $this->className() . '] does not support collectProperty()');
76+
}
77+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of Hyperf.
6+
*
7+
* @link https://www.hyperf.io
8+
* @document https://hyperf.wiki
9+
* @contact [email protected]
10+
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
11+
*/
12+
namespace Hyperf\Di\Annotation;
13+
14+
use Hyperf\Di\Exception\AnnotationException;
15+
16+
interface MultipleAnnotationInterface extends AnnotationInterface
17+
{
18+
public function className(): string;
19+
20+
/**
21+
* @throws AnnotationException
22+
*/
23+
public function insert(AnnotationInterface $annotation);
24+
25+
/**
26+
* @return AnnotationInterface[]
27+
*/
28+
public function toAnnotations(): array;
29+
}

src/Aop/ProxyManager.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ protected function retrieveAnnotations(string $annotationCollectorKey): array
181181
$defined = [];
182182
$annotations = AnnotationCollector::get($annotationCollectorKey, []);
183183

184-
foreach ($annotations as $k => $annotation) {
184+
foreach ($annotations as $name => $annotation) {
185185
if (is_object($annotation)) {
186-
$defined[] = $k;
186+
$defined[] = $name;
187187
} else {
188188
$defined = array_merge($defined, array_keys($annotation));
189189
}

0 commit comments

Comments
 (0)