/** Datei: library/ARUNOX/API/PHP/Attributes/Database/Attributes/Attributes.php **/ * @copyright 2025 ARUNOX * @version 1.1.0 * * @since 1.0.0 File is created */ namespace ARUNOX\API\PHP\Attributes\Database; use Attribute; use ARUNOX\API\PHP; use ARUNOX\Database; #[Attribute( Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE )] class Attributes { use PHP\Attributes\Magic\Get\Helper; /* ### VARIABLES ################################################ # */ protected static array $ATTRIBUTES = [ "status" => Database\Attribute\Status::class, "date_create" => Database\Attribute\DateTime::class, "date_edit" => Database\Attribute\DateTime::class, ]; /* ### PROTECTED FUNCTIONS ###################################### # */ protected function getClass() { return $this->class ?? ( static::$ATTRIBUTES[ $this->column ] ?? NULL ); } /* ### MAGIC FUNCTIONS ########################################## # */ public function __construct( protected string $column, protected null|string $class = NULL ){ if( !$class ) $this->class = $this->getClass( $this->column ); } } /** Datei: library/ARUNOX/API/PHP/Attributes/Database/Attributes/Resolve/Helper.php **/ * @copyright 2025 ARUNOX * @version 1.1.0 * * @since 1.0.0 File is created */ namespace ARUNOX\API\PHP\Attributes\Database\Attributes\Resolve; use ARUNOX\API\PHP; use ReflectionClass; use ARUNOX\Interfaces\Supports; trait Helper { /* ### VARIABLES ################################################ # */ protected static array $__CACHED_RESOLVES = []; /* ### PUBLIC FUNCTIONS ######################################### # */ #[PHP\Attributes\Magic\Get( fallback: TRUE, priority: 5 )] public function handleGetResolve( string $column ) { if( static::existsResolve( $column ) ) { $resolves = static::getResolve( $column ); $result = NULL; foreach( $resolves as $resolve ) { if( preg_match( '/\$\{[a-z]+\}/', $resolve ) ) { $result = preg_replace_callback( '/\$\{([a-z]+)\}/', fn( $m ) => $this->attributes[ $m[1] ], $resolve ); } else if( is_string( $resolve ) ) $result = $this->attributes[ $resolve ]; if( preg_replace( "/\s+/", "", $result ) != NULL ) return $result; } return ""; } throw new PHP\Attributes\Magic\Get\Exceptions\FallbackFailed(); } /* ### PUBLIC STATIC FUNCTIONS ################################## # */ public static function existsResolve( string $column ) : bool { $resolves = static::getResolves(); return isset( $resolves[ $column ] ); } public static function getResolve( string $column ) : array { return static::resolveResolvesFromClass( $column ); } public static function getResolves() : array { return static::resolveResolvesFromClass(); } /* ### PRIVATE STATIC FUNCTIONS ################################# # */ private static function resolveResolvesFromClass( null|string $column = NULL ) : string|array { $reflection = new ReflectionClass( static::class ); $attributes = []; if( !isset( static::$__CACHED_RESOLVES[ static::class ] ) ) { do { foreach( $reflection->getAttributes( PHP\Attributes\Database\Attributes\Resolve::class ) as $attribute ) { $instance = $attribute->newInstance(); if( !empty( $attributes ) ) break 2; $attributes[ $instance->column ] = $instance->resolves; } $reflection = $reflection->getParentClass(); } while ($reflection); static::$__CACHED_RESOLVES[ static::class ] = $attributes; } if( $column ) { return static::$__CACHED_RESOLVES[ static::class ][ $column ] ?? ""; } return static::$__CACHED_RESOLVES[ static::class ] ?? ""; } } /** Datei: library/ARUNOX/API/PHP/Attributes/Database/Attributes/Resolve/Resolve.php **/ * @copyright 2025 ARUNOX * @version 1.1.0 * * @since 1.0.0 File is created */ namespace ARUNOX\API\PHP\Attributes\Database\Attributes; use Attribute; use ARUNOX\API\PHP; #[Attribute( Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE )] class Resolve { use PHP\Attributes\Magic\Get\Helper; /* ### VARIABLES ################################################ # */ protected array $resolves = []; /* ### PROTECTED FUNCTIONS ###################################### # */ /* ### MAGIC FUNCTIONS ########################################## # */ public function __construct( protected string $column, ...$resolves ){ $this->resolves = (array)$resolves; } } /** Datei: library/ARUNOX/API/PHP/Attributes/Database/Attributes/Helper.php **/ * @copyright 2025 ARUNOX * @version 1.1.0 * * @since 1.0.0 File is created */ namespace ARUNOX\API\PHP\Attributes\Database\Attributes; use ARUNOX\API\PHP; use ReflectionClass; use ARUNOX\Interfaces\Supports; trait Helper { /* ### VARIABLES ################################################ # */ protected static array $ATTRIBUTES = []; protected static array $__CACHED_ATTRS = []; protected static array $__CALLABLE_ATTRS = [ "toggle" => Supports\Toggle::class, ]; /* ### PUBLIC FUNCTIONS ######################################### # */ #[PHP\Attributes\Magic\Call( fallback: TRUE )] public function handleAttributesCall( string $name, ...$args ) { $name = preg_split('/([[:upper:]][[:lower:]]+)/', $name, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); if( is_array( $name ) ) { $name = array_map( "strtolower", $name ); if( key_exists( $name[0], static::$__CALLABLE_ATTRS ) ) { $class = static::$__CALLABLE_ATTRS[ $name[0] ]; if( isset( $this->{$name[1]} ) ) { if( $this->{$name[1]} instanceof $class ) { if( method_exists( $this->{$name[1]}, "setParent" ) ) { $this->{$name[1]}->setParent( $this ); } return $this->{$name[1]}->{$name[0]}( ...$args ); } } } } throw new PHP\Attributes\Magic\Call\Exceptions\FallbackFailed(); } /* ### PUBLIC STATIC FUNCTIONS ################################## # */ public static function existsAttribute( string $name ) : bool { $attrs = static::getAttributes(); return isset( $attrs[ $name ] ); } public static function getAttribute( string $name ) : mixed { $attrs = static::getAttributes(); return $attrs[ $name ] ?? NULL; } public static function getAttributes() : array { $class = static::class; if( !isset( static::$__CACHED_ATTRS[ $class ] ) ) { $attrs = static::resolveAttributesFromClass(); $attrs = static::getMergedAttributes( $attrs ); static::$__CACHED_ATTRS[ $class ] = $attrs; } return static::$__CACHED_ATTRS[ $class ]; } /* ### PRIVATE STATIC FUNCTIONS ################################# # */ private static function getMergedAttributes( null|array $defaults = []) : array { $result = $defaults; $class = static::class; do { if( property_exists( $class, "ATTRIBUTES" ) ) { $ref = new ReflectionClass( $class ); if( $ref->hasProperty("ATTRIBUTES") ) { $prop = $ref->getProperty("ATTRIBUTES"); if( $prop->isStatic() ) { $prop->setAccessible( TRUE ); $attrs = $prop->getValue(); if( is_array( $attrs ) ) { $result = array_merge( $attrs, $result ); } } } } } while( $class = get_parent_class( $class ) ); return $result; } private static function resolveAttributesFromClass() : array { $ref = new ReflectionClass( static::class ); $result = []; foreach( $ref->getAttributes( PHP\Attributes\Database\Attributes::class ) as $attr ) { $inst = $attr->newInstance(); $result[ $inst->column ] = $inst->class; } return $result; } }