PHP code example of martingold / autotype

1. Go to this page and download the library: Download martingold/autotype library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

martingold / autotype example snippets


final readonly class Url
{
    private function __construct(
        private string $value,
    ) {
    }
    
    // Regular constructor is used when attribute not found
    #[Constructor]
    public static function create(string $url): self
    {
        if (filter_var($value, FILTER_VALIDATE_URL) === false) {
            throw MalformedUrl::fromString($value);
        }
        
        return new self($url)
    }
    
    #[ValueGetter]
    public function getValue(): string
    {
        return $this->value;
    }
    
    public function isSecure(): bool
    {
        return str_starts_with('https://', $this->value);
    }
}

// Get a PSR-6 cache instance
$cache = $this->container->get(CacheItemPoolInterface::class);

// Alternatively, use Doctrine's PSR-6 metadata cache
$entityManager = $this->container->get(EntityManagerInterface::class);
$cache = $entityManager->getConfiguration()->getMetadataCache();

// Create a type provider
$cachedTypeFinder = new CachedTypeDefinitionProvider(
    new DefaultTypeDefinitionProvider(__DIR__ . '/../ValueObject'),
    $cache
);

// Register dynamic types
(new DynamicTypeRegistry($cachedTypeFinder))->register();

#[Entity]
class Company
{
    #[Column]
    private string $name;

    #[Column(type: Url::class)]
    private Url $url;
}

$typeDefinitionProvider = new CachedTypeDefinitionProvider(
    new ScanTypeDefinitionProvider($sourceFolder, [
        new CustomTypeDefinitionDriver(),
    ]),
    $cache,
);

(new DynamicTypeRegistry($typeDefinitionProvider))->register();

class CustomTypeDefinitionDriver implements TypeDefinitionDriver
{
    /**
     * Should be the class treated as doctrine type?
     * @param ReflectionClass<object> $class
     */
    public function supports(ReflectionClass $class): bool
    {
        return str_ends_with($class->getShortName(), 'Crate');
    }

    /**
     * Get dynamic type class. Whether it is value a string or int.
     * @param ReflectionClass<object> $class
     *
     * @return class-string<DynamicType&Type>
     */
    public function getDynamicTypeClass(ReflectionClass $class): string
    {
        return match ($this->getValueMethodReturnType($class)) {
            'string' => StringDynamicType::class,
            'int' => IntegerDynamicType::class,
            default => throw new UnsupportedType('Only string|int type is supported.'),
        };
    }

    /**
     * Name of the method which should be used when persisting object to database. 
     * @param ReflectionClass<object> $class
     */
    public function getValueMethodName(ReflectionClass $class): string
    {
        return 'getValue';
    }

    /**
     * Method to use when creating the object from database value. Must have single argument. 
     * When null returned, the regular constructor is used.  
     */
    public function getConstructorMethodName(ReflectionClass $class): string|null
    {
        return $class->hasMethod('of') ? 'of' : null;
    }

    /**
     * Get value getter method return type to determine if database value should be string or int
     * @param ReflectionClass<object> $class
     *
     * @throws UnsupportedType
     */
    private function getValueMethodReturnType(ReflectionClass $class): string
    {
        $returnType = $class->getMethod('getValue')->getReturnType();

        if (!$returnType instanceof ReflectionNamedType) {
            throw new UnsupportedType("Intersection or union return type not supported in method {$class->getName()}::getValue()");
        }

        if (!$returnType->isBuiltin()) {
            throw new UnsupportedType("Only scalar return types are supported in {$class->getName()}::getValue()");
        }

        return $returnType->getName();
    }
}