Skip to content

Commit 4fe614d

Browse files
committed
new attr methods
1 parent 13bff20 commit 4fe614d

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

packages/utilities/src/Attributes/AttributesAccessor.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,4 +168,96 @@ public static function getAttributesFromAny(
168168

169169
return array_merge(...$attrs);
170170
}
171+
172+
/**
173+
* @template Member of \Reflector
174+
* @template Attr of object
175+
*
176+
* @param string|object $ref
177+
* @param class-string<Attr> $name
178+
* @param int $flags
179+
* @param class-string<Member>|\Closure|null $filter
180+
*
181+
* @return \Generator<string, array{ Member, ReflectionAttribute<Attr> }>
182+
*/
183+
public static function getMembersWithAttribute(
184+
string|object $ref,
185+
string $name,
186+
int $flags = 0,
187+
\Closure|string|null $filter = null
188+
): \Generator {
189+
$ref = ReflectAccessor::reflect($ref);
190+
191+
foreach (static::findAttributeOfMembers($ref, $name, $flags) as $refName => [$memberRef, $attr]) {
192+
if (is_string($filter) && !is_a($memberRef, $filter, true)) {
193+
continue;
194+
}
195+
196+
if ($filter instanceof \Closure && !$filter($memberRef, $attr)) {
197+
continue;
198+
}
199+
200+
yield $refName => [$memberRef, $attr];
201+
}
202+
}
203+
204+
/**
205+
* @template Member of \Reflector
206+
* @template Attr of object
207+
*
208+
* @param string|object $ref
209+
* @param class-string<Attr> $name
210+
* @param int $flags
211+
* @param class-string<Member>|\Closure|null $filter
212+
*
213+
* @return array{ Member, ReflectionAttribute<Attr> }|null
214+
*/
215+
public static function getFirstMemberWithAttribute(
216+
string|object $ref,
217+
string $name,
218+
int $flags = 0,
219+
\Closure|string|null $filter = null
220+
): ?array {
221+
return static::getMembersWithAttribute($ref, $name, $flags, $filter)->current();
222+
}
223+
224+
/**
225+
* @param ReflectionClass $ref
226+
* @param string $name
227+
* @param int $flags
228+
*
229+
* @return \Generator<string, array{ \Reflector, ReflectionAttribute }>
230+
*/
231+
private static function findAttributeOfMembers(
232+
\ReflectionClass $ref,
233+
string $name,
234+
int $flags = 0
235+
): \Generator {
236+
/** @var \ReflectionClassConstant $constant */
237+
foreach ($ref->getConstants() as $constant) {
238+
if ($attr = static::getFirstAttribute($constant, $name, $flags)) {
239+
yield $constant->getName() => [$constant, $attr];
240+
}
241+
}
242+
243+
foreach ($ref->getProperties() as $property) {
244+
if ($attr = static::getFirstAttribute($property, $name, $flags)) {
245+
yield $property->getName() => [$property, $attr];
246+
}
247+
}
248+
249+
foreach ($ref->getMethods() as $method) {
250+
if ($attr = static::getFirstAttribute($method, $name, $flags)) {
251+
yield $method->getName() => [$method, $attr];
252+
}
253+
}
254+
255+
if ($ref instanceof \ReflectionEnum) {
256+
foreach ($ref->getCases() as $case) {
257+
if ($attr = static::getFirstAttribute($case, $name, $flags)) {
258+
yield $case->getName() => [$case, $attr];
259+
}
260+
}
261+
}
262+
}
171263
}

0 commit comments

Comments
 (0)