|
9 | 9 |
|
10 | 10 | final class AttributeAnalyzer implements AttributeAnalyzerContract
|
11 | 11 | {
|
| 12 | + private array $cache = []; |
| 13 | + |
12 | 14 | public function __construct(private readonly string $attributeClass)
|
13 | 15 | {
|
14 | 16 | }
|
15 | 17 |
|
16 | 18 | public function analyzeObject(object $object): array
|
17 | 19 | {
|
18 | 20 | try {
|
19 |
| - $results = []; |
20 |
| - $reflection = new \ReflectionClass($object); |
21 |
| - |
22 |
| - foreach ($reflection->getProperties() as $property) { |
23 |
| - $propertyResult = $this->analyzeProperty($object, $property); |
24 |
| - if (null !== $propertyResult) { |
25 |
| - $results[$property->getName()] = $propertyResult; |
26 |
| - } |
| 21 | + $className = $object::class; |
| 22 | + |
| 23 | + // Usar cache se disponível |
| 24 | + if (!isset($this->cache[$className])) { |
| 25 | + $this->cacheObjectMetadata($object); |
27 | 26 | }
|
28 | 27 |
|
29 |
| - return $results; |
| 28 | + return $this->extractValues($object); |
30 | 29 | } catch (\ReflectionException $e) {
|
31 | 30 | throw new PropertyInspectionException('Failed to analyze object: ' . $e->getMessage(), 0, $e);
|
32 | 31 | } catch (\Error $e) {
|
33 | 32 | throw new PropertyInspectionException('An error occurred during object analysis: ' . $e->getMessage(), 0, $e);
|
34 | 33 | }
|
35 | 34 | }
|
36 | 35 |
|
37 |
| - private function analyzeProperty(object $object, \ReflectionProperty $property): ?array |
| 36 | + private function cacheObjectMetadata(object $object): void |
38 | 37 | {
|
39 |
| - $attributes = $property->getAttributes($this->attributeClass, \ReflectionAttribute::IS_INSTANCEOF); |
40 |
| - if (empty($attributes)) { |
41 |
| - return null; |
| 38 | + $className = $object::class; |
| 39 | + $reflection = new \ReflectionClass($object); |
| 40 | + $cachedProperties = []; |
| 41 | + |
| 42 | + foreach ($reflection->getProperties() as $property) { |
| 43 | + $attributes = $property->getAttributes($this->attributeClass, \ReflectionAttribute::IS_INSTANCEOF); |
| 44 | + |
| 45 | + if (!empty($attributes)) { |
| 46 | + $property->setAccessible(true); |
| 47 | + $attributeInstances = array_map( |
| 48 | + static fn (\ReflectionAttribute $attr): object => $attr->newInstance(), |
| 49 | + $attributes |
| 50 | + ); |
| 51 | + |
| 52 | + $cachedProperties[$property->getName()] = [ |
| 53 | + 'attributes' => $attributeInstances, |
| 54 | + 'property' => $property, |
| 55 | + ]; |
| 56 | + } |
42 | 57 | }
|
43 | 58 |
|
44 |
| - $property->setAccessible(true); |
45 |
| - $propertyValue = $property->getValue($object); |
| 59 | + $this->cache[$className] = $cachedProperties; |
| 60 | + } |
46 | 61 |
|
47 |
| - $attributeInstances = array_map( |
48 |
| - static fn (\ReflectionAttribute $attr): object => $attr->newInstance(), |
49 |
| - $attributes |
50 |
| - ); |
| 62 | + private function extractValues(object $object): array |
| 63 | + { |
| 64 | + $results = []; |
| 65 | + $className = $object::class; |
| 66 | + |
| 67 | + foreach ($this->cache[$className] as $propertyName => $data) { |
| 68 | + $results[$propertyName] = [ |
| 69 | + 'value' => $data['property']->getValue($object), |
| 70 | + 'attributes' => $data['attributes'], |
| 71 | + ]; |
| 72 | + } |
51 | 73 |
|
52 |
| - return [ |
53 |
| - 'value' => $propertyValue, |
54 |
| - 'attributes' => $attributeInstances, |
55 |
| - ]; |
| 74 | + return $results; |
| 75 | + } |
| 76 | + |
| 77 | + public function clearCache(): void |
| 78 | + { |
| 79 | + $this->cache = []; |
56 | 80 | }
|
57 | 81 | }
|
0 commit comments