name); return end($exploded); } public function getProperties(bool $deep = true) : array { return $deep ? array_replace( $this->parent ? $this->parent->getProperties(true) : [], $this->properties ) : $this->properties; } public function getMethods(bool $deep = true) : array { $m = array_merge(...array_map(fn($e) => $e->getMethods(true), $this->traits)); return $deep ? array_replace( $this->parent ? $this->parent->getMethods(true) : [], array_merge(...array_map(fn($e) => $e->getMethods(true), $this->interfaces)), array_merge(...array_map(fn($e) => $e->getMethods(true), $this->traits)), $this->methods ) : $this->methods; } public function getAttributes(bool $deep = true, ? string $attributeType = null) : array { return array_reverse($this->getOrderedAttributes($deep, $attributeType)); } protected function getOrderedAttributes(bool $deep = true, ? string $attributeType = null) : array { $attributes = $deep ? array_merge( $this->parent ? $this->parent->getOrderedAttributes(true) : [], array_merge(...array_map(fn($e) => $e->getOrderedAttributes(true), $this->interfaces)), array_merge(...array_map(fn($e) => $e->getOrderedAttributes(true), $this->traits)), $this->attributes ) : $this->attributes; if ($attributeType) { $list = []; foreach($attributes as $attribute) { if ($attribute->object instanceof $attributeType) { $list[] = $attribute; } } return $list; } return $attributes; } # Get Attributes based on Native attributes's target public function getClassAttributeList(array|string $className, bool $deepSearch, bool $throwOnError = true) : array { $list = []; foreach((array) $className as $class) { $reflection = new \ReflectionClass($class); $attributes = $reflection->getAttributes(); foreach($attributes as $attribute) { # Native PHP Attribute if ($attribute->getName() === 'Attribute') { if ($attribute->getTarget() && \Attribute::TARGET_CLASS) { $list = $this->getClassAttributeListFromClassname($class, $deepSearch, false); } if ($attribute->getTarget() && \Attribute::TARGET_METHOD) { $list = array_merge($list, $this->getMethodAttributeListFromClassname($class, $deepSearch, false)); } if ($attribute->getTarget() && \Attribute::TARGET_PROPERTY) { $list = array_merge($list, $this->getPropertyAttributeListFromClassname($class, $deepSearch, false)); } } } } if ( empty($list) && $throwOnError ) { $className = implode(',', (array) $className); throw new \InvalidArgumentException("Attribute(s) `$className` was not found within class {$this->name} (or it's parents / traits)"); } return $list; } public function getClassAttributeListFromClassname(array|string $className, bool $deepSearch, bool $throwOnError = true) : array { $list = []; foreach((array) $className as $class) { foreach ($this->getAttributes($deepSearch) as $item) { if ($item->object instanceof $class) { $list[] = $item->object; } } } if ( empty($list) && $throwOnError ) { $className = implode(',', (array) $className); throw new \InvalidArgumentException("Attribute(s) `$className` was not found within class {$this->name} (or it's parents / traits)"); } return $list; } public function getPropertyAttributeListFromClassname(array|string $className, bool $deepSearch, bool $throwOnError = true) : array { $list = []; foreach((array) $className as $class) { foreach ($this->getProperties($deepSearch) as $property) { foreach ($property->attributes as $item) { if ($item->object instanceof $class) { $list[$property->name] ??= []; $list[$property->name][] = $item->object; } } } } if ( empty($list) && $throwOnError ) { $className = implode(',', (array) $className); throw new \InvalidArgumentException("Attribute(s) `$className` was not found within properties of {$this->name} (or it's parents / traits)"); } return $list; } public function getMethodAttributeListFromClassname(array|string $className, bool $deepSearch, bool $throwOnError = true) : array { $list = []; foreach((array) $className as $class) { foreach ($this->getMethods($deepSearch) as $method) { foreach ($method->attributes as $item) { if ($item->object instanceof $class) { $list[$method->name] ??= []; $list[$method->name][] = $item->object; } } } } if ( empty($list) && $throwOnError ) { $className = implode(',', (array) $className); throw new \InvalidArgumentException("Attribute(s) `$className` was not found within methods of {$this->name} (or it's parents / traits)"); } return $list; } public function getAttribute(string $attributeType): ?object { foreach($this->getAttributes(true, $attributeType) as $attribute) { return $attribute; } return null; } }