Файл: vendor/laravel/framework/src/Illuminate/Support/Traits/ReadsClassAttributes.php
Строк: 112
<?php
namespace IlluminateSupportTraits;
use Exception;
use ReflectionClass;
trait ReadsClassAttributes
{
/**
* Get a configuration value from an attribute, falling back to a property.
*
* @param object $target
* @param class-string $attributeClass
* @param string|null $property
* @param mixed $default
* @return mixed
*/
protected function getAttributeValue($target, string $attributeClass, ?string $property = null, $default = null)
{
$reflection = new ReflectionClass($target);
$defaultProperties = $reflection->getDefaultProperties();
if (isset($target->{$property}) && $target->{$property} !== ($defaultProperties[$property] ?? null)) {
return $target->{$property};
}
if ($instance = $this->getAttributeInstance($target, $attributeClass, $attributeDeclaringClass)) {
if ($this->propertyOverridesAttribute($target, $reflection, $property, $attributeDeclaringClass)) {
return $target->{$property};
}
return $this->extractAttributeValue($instance);
}
return $target->{$property} ?? $default;
}
/**
* Extract the value from an attribute instance.
*
* @param object $instance
* @return mixed
*/
protected function extractAttributeValue($instance)
{
$properties = get_object_vars($instance);
return $properties === [] ? true : reset($properties);
}
/**
* Get an instance of the given attribute class from the target class or its parents.
*
* @param object $target
* @param class-string $attributeClass
* @param ReflectionClass|null $declaringClass
* @return object|null
*/
protected function getAttributeInstance($target, string $attributeClass, ?ReflectionClass &$declaringClass = null)
{
$reflection = new ReflectionClass($target);
try {
do {
$attributes = $reflection->getAttributes($attributeClass);
if (count($attributes) > 0) {
$declaringClass = $reflection;
return $attributes[0]->newInstance();
}
} while ($reflection = $reflection->getParentClass());
} catch (Exception) {
//
}
return null;
}
/**
* Determine if a property declared on a child class overrides an inherited attribute.
*
* @param object $target
* @param ReflectionClass $reflection
* @param string|null $property
* @param ReflectionClass $attributeDeclaringClass
* @return bool
*/
protected function propertyOverridesAttribute($target, ReflectionClass $reflection, ?string $property, ReflectionClass $attributeDeclaringClass)
{
if (is_null($property) || ! $reflection->hasProperty($property)) {
return false;
}
$property = $reflection->getProperty($property);
return $property->isPublic()
&& $property->isInitialized($target)
&& $property->getDeclaringClass()->isSubclassOf($attributeDeclaringClass->getName());
}
}