Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Type Converter Laravel Package

apie/type-converter

Apie Type Converter converts values and objects to other types, ideal for mapping between DTOs and domain objects. Includes a default converter factory and lets you register custom converters to handle your own conversion rules.

View on GitHub
Deep Wiki
Context7

Latest Stable Version Total Downloads Latest Unstable Version License PHP Version Require Code coverage Donate

Apie is a suite of composer packages to work with domain objects. It tries to aim to follow a Domain-objects-first approach and not a database first approach that you find in many PHP frameworks nowadays.

This type converter package is written outside the monorepo and provides a simple tooling to convert objects into other objects.

Usage

Easiest usage:

<?php
use Apie\TypeConverter\DefaultConvertersFactory;
$converter = DefaultConvertersFactory::create();
var_dump($converter->convertTo(12, 'string')); // '12'

This is not a very useful example. Normally you try to convert a DTO to a domain object or the other way around.

More serious example:

<?php
use Apie\TypeConverter\DefaultConvertersFactory;

class Dto {
    public string $description;

    public string $name;
}

class DomainObject {
    public function __construct(
        private string $description,
        private string $name
    ) {
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getDescription(): string
    {
        return $this->description;
    }
}
use Apie\TypeConverter\DefaultConvertersFactory;
$converter = DefaultConvertersFactory::create();
$dto = ($converter->convertTo(new DomainObject('description', 'name'), Dto::class));
var_dump($dto->name); // 'name'
$converter->convertTo($dto, DomainObject::class);

Creating your own converters

It's very easy to create your own converters. All you need to do is make a class that implements ConverterInterface. In case you use phpstan for static code analysis a small phpdoc can be added to make phpstan understand the type conversion.

<?php
use Apie\Core\ValueObjects\Interfaces\StringValueObjectInterface;
use Apie\TypeConverter\ConverterInterface;

/**
 * @implements ConverterInterface<StringValueObjectInterface, string>
 */
class StringValueObjectToStringConverter implements ConverterInterface
{
    public function convert(StringValueObjectInterface $valueObject): string
    {
        return $valueObject->toNative();
    }
}

use Apie\TypeConverter\DefaultConvertersFactory;
$converter = DefaultConvertersFactory::create(new StringValueObjectToStringConverter());
$converter->convertTo(new Email('test@example.com'), 'string');

Customizing the TypeConverter

DefaultConvertsFactory creates an instance of TypeConverter with sensible defaults. You can configure everything by just calling the constructor. Remember that all default converters require to be added manually too.

<?php
use Apie\TypeConverter\Converters\FloatToStringConverter;
use Apie\TypeConverter\Converters\IntToStringConverter;
use Apie\TypeConverter\Converters\ObjectToObjectConverter;
use Apie\TypeConverter\TypeConverter;
$converter = new TypeConverter(
    new ObjectToObjectConverter(),
    new IntToStringConverter(),
    new FloatToStringConverter()
);

Complex converters

In the example above we can convert a string value object to string, but how do we make it the other way around?

We could make a converter for every value object, but that would mean many similar classes.

<?php
use Apie\Core\ValueObjects\Interfaces\StringValueObjectInterface;
use Apie\TypeConverter\ConverterInterface;

/**
 * @implements ConverterInterface<string, Email>
 */
class StringToEmailConverter implements ConverterInterface
{
    public function convert(string $value): Email
    {
        return Email::fromNative($value);
    }
}

Luckily we have a better solution by providing the wanted type as second argument.

<?php
use Apie\Core\ValueObjects\Interfaces\StringValueObjectInterface;
use Apie\TypeConverter\ConverterInterface;

/**
 * @implements ConverterInterface<string, StringValueObjectInterface>
 */
class StringToStringValueObjectConverter implements ConverterInterface
{
    public function convert(string $value, \ReflectionNamedType $wantedType): StringValueObjectInterface
    {
        $className = $wantedType->getName();
        return $className::fromNative($value);
    }
}

It is also possible to get the TypeConverter instance to make recursive conversions.

<?php
use Apie\Core\ValueObjects\Interfaces\StringValueObjectInterface;
use Apie\TypeConverter\ConverterInterface;
use Apie\TypeConverter\TypeConverter;

/**
 * @implements ConverterInterface<int, StringValueObjectInterface>
 */
class IntToStringValueObjectConverter implements ConverterInterface
{
    public function convert(int $value, \ReflectionNamedType $wantedType, TypeConverter $typeConverter): StringValueObjectInterface
    {
        $value = $typeConverter->convertTo($value, 'string');
        $className = $wantedType->getName();
        return $className::fromNative($value);
    }
}

Converter preference

If multiple converters could perform the conversion, then the most accurate one is the one that gets the priority.

<?php
use Apie\TypeConverter\Converters\FloatToStringConverter;
use Apie\TypeConverter\Converters\IntToStringConverter;
use Apie\TypeConverter\Converters\ObjectToObjectConverter;
use Apie\TypeConverter\TypeConverter;
$converter = new TypeConverter(
    new ObjectToObjectConverter(),
    new IntToStringConverter(),
    new FloatToStringConverter()
);

If I would try to convert '1' IntToStringConverter and FloatToStringConverter would apply, but since int is more accurate it uses IntToStringConverter.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle