Skip to content

Changelog 1.0.0 — 28th of November 2022

First stable version! 🥳 🎉

This release marks the end of the initial development phase. The library has been live for exactly one year at this date and is stable enough to start following the semantic versioning — it means that any backward incompatible change (aka breaking change) will lead to a bump of the major version.

This is the biggest milestone achieved by this project (yet™); I want to thank everyone who has been involved to make it possible, especially the contributors who submitted high-quality pull requests to improve the library.

There is also one person that I want to thank even more: my best friend Nathan, who has always been so supportive with my side-projects. Thanks, bro! 🙌

The last year marked a bigger investment of my time in OSS contributions; I've proven to myself that I am able to follow a stable way of managing my engagement to this community, and this is why I enabled sponsorship on my profile to allow people to ❤️ sponsor my work on GitHub — if you use this library in your applications, please consider offering me a 🍺 from time to time! 🤗

Notable changes

End of PHP 7.4 support

PHP 7.4 security support has ended on the 28th of November 2022; the minimum version supported by this library is now PHP 8.0.

New mapper to map arguments of a callable

This new mapper can be used to ensure a source has the right shape before calling a function/method.

The mapper builder can be configured the same way it would be with a tree mapper, for instance to customize the type strictness.

$someFunction = function(string $foo, int $bar): string {
    return "$foo / $bar";

try {
    $arguments = (new \CuyZ\Valinor\MapperBuilder())
        ->mapArguments($someFunction, [
            'foo' => 'some value',
            'bar' => 42,

    // some value / 42
    echo $someFunction(...$arguments);
} catch (\CuyZ\Valinor\Mapper\MappingError $error) {
    // Do something…

Support for TimeZone objects

Native TimeZone objects construction is now supported with a proper error handling.

try {
    (new \CuyZ\Valinor\MapperBuilder())
        ->map(DateTimeZone::class, 'Jupiter/Europa');
} catch (MappingError $exception) {
    $error = $exception->node()->messages()[0];

    // Value 'Jupiter/Europa' is not a valid timezone.
    echo $error->toString();

Mapping object with one property

When a class needs only one value, the source given to the mapper must match the type of the single property/parameter.

This change aims to bring consistency on how the mapper behaves when mapping an object that needs one argument. Before this change, the source could either match the needed type, or be an array with a single entry and a key named after the argument.

See example below:

final class Identifier
    public readonly string $value;

final class SomeClass
    public readonly Identifier $identifier;

    public readonly string $description;

(new \CuyZ\Valinor\MapperBuilder())->mapper()->map(SomeClass::class, [
    'identifier' => ['value' => 'some-identifier'], // ❌
    'description' => 'Lorem ipsum…',

(new \CuyZ\Valinor\MapperBuilder())->mapper()->map(SomeClass::class, [
    'identifier' => 'some-identifier', // ✅
    'description' => 'Lorem ipsum…',

Upgrading from 0.x to 1.0

As this is a major release, all deprecated features have been removed, leading to an important number of breaking changes.

You can click on the entries below to get advice on available replacements.

Doctrine annotations support removal

Doctrine annotations cannot be used anymore, PHP attributes must be used.

BackwardCompatibilityDateTimeConstructor class removal

You must use the method available in the mapper builder, see dealing with dates chapter.

Mapper builder flexible method removal

The flexible has been split in three disctint modes, see type strictness & flexibility chapter.

Mapper builder withCacheDir method removal

You must now register a cache instance directly, see performance & caching chapter.

StaticMethodConstructor class removal

You must now register the constructors using the mapper builder, see custom object constructors chapter.

Mapper builder bind method removal

You must now register the constructors using the mapper builder, see custom object constructors chapter.

ThrowableMessage class removal

You must now use the MessageBuilder class, see error handling chapter.

MessagesFlattener class removal

You must now use the Messages class, see error handling chapter.

TranslatableMessage class removal

You must now use the HasParameters class, see custom exception chapter.

Message methods removal

The following methods have been removed:

  • \CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::name()
  • \CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::path()
  • \CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::type()
  • \CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::value()
  • \CuyZ\Valinor\Mapper\Tree\Node::value()

It is still possible to get the wanted values using the method \CuyZ\Valinor\Mapper\Tree\Message\NodeMessage::node().

The placeholder {original_value} has also been removed, the same value can be fetched with {source_value}.

PlaceHolderMessageFormatter class removal

Other features are available to format message, see error messages customization chapter.

Identifier attribute removal

This feature has been part of the library since its first public release, but it was never documented because it did not fit one of the library's main philosophy which is to be almost entirely decoupled from an application's domain layer.

The feature is entirely removed and not planned to be replaced by an alternative, unless the community really feels like there is a need for something alike.


  • Disallow array when mapping to object with one argument (72cba3)
  • Mark tree mapper and arguments mapper as @pure (0d9855)
  • Remove deprecated backward compatibility datetime constructor (a65e8d)
  • Remove deprecated class ThrowableMessage (d36ca9)
  • Remove deprecated class to flatten messages (f9ed93)
  • Remove deprecated interface TranslatableMessage (ceb197)
  • Remove deprecated message methods (e6557d)
  • Remove deprecated method constructor attribute (d76467)
  • Remove deprecated method to enable flexible mode (a2bef3)
  • Remove deprecated method to set cache directory (b0d6d2)
  • Remove deprecated method used to bind a callback (b79ed8)
  • Remove deprecated placeholder message formatter (c2723d)
  • Remove Doctrine annotations support (66c182)
  • Remove identifier attribute (8a7486)
  • Remove PHP 7.4 support (5f5a50)
  • Remove support for strict-array type (22c3b4)


  • Add constructor for DateTimeZone with error support (a0a4d6)
  • Introduce mapper to map arguments of a callable (9c7e88)

Bug Fixes

  • Allow mapping null to single node nullable type (0a98ec)
  • Handle single argument mapper properly (d7bf6a)
  • Handle tree mapper call without argument in PHPStan extension (3f3a01)
  • Handle tree mapper call without argument in Psalm plugin (b425af)


  • Activate value altering feature only when callbacks are registered (0f33a5)
  • Bump psr/simple-cache supported version (e4059a)
  • Remove @ from comments for future PHP versions changes (68774c)
  • Update dependencies (4afcda)