跳至正文

更新日志 0.9.0 — 2022 年 5 月 23 日

重要变更

缓存注入和预热

缓存功能已被重新审视,以便让用户更好地控制如何以及何时使用它。

方法MapperBuilder::withCacheDir()已被弃用,取而代之的是接受任何 PSR-16 兼容实现的新方法MapperBuilder::withCache() 。

警告

这些更改导致默认缓存不再自动注册。如果您仍然想启用缓存(您应该这样做),则必须显式注入它(见下文)。

开箱即用地提供了默认实现,它将缓存条目保存到文件系统中。

当应用程序在开发环境中运行时,缓存实现应使用FileWatchingCache进行修饰,它将监视应用程序的文件,并在开发人员修改 PHP 文件时使缓存条目失效,从而防止库在属性或方法的签名更改时无法按预期运行。

缓存可以预热,例如在应用程序构建和部署期间的管道中 - 感谢 @boesing 的该功能!

注意必须先注册缓存,否则预热将毫无用处。

$cache = new \CuyZ\Valinor\Cache\FileSystemCache('path/to/cache-directory');

if ($isApplicationInDevelopmentEnvironment) {
    $cache = new \CuyZ\Valinor\Cache\FileWatchingCache($cache);
}

$mapperBuilder = (new \CuyZ\Valinor\MapperBuilder())->withCache($cache);

// During the build:
$mapperBuilder->warmup(SomeClass::class, SomeOtherClass::class);

// In the application:
$mapperBuilder->mapper()->map(SomeClass::class, [/* … */]);

消息格式和翻译

对映射错误时返回的消息进行了重大更改:实际文本现在更加准确并显示更好的信息。

警告

NodeMessage::format方法已被删除,应使用消息格式化程序。如果需要,可以使用格式化程序PlaceHolderMessageFormatter检索旧行为,但强烈建议使用新的占位符功能(见下文)。

MessageFormatter::format方法的签名也已更改。

现在,格式化消息也变得更加容易,例如当需要翻译消息时。占位符现在可以在消息正文中使用,并将替换为有用的信息。

占位符 描述
{message_code} 消息代码
{node_name} 消息绑定的节点名称
{node_path} 消息绑定的节点路径
{node_type} 消息绑定的节点类型
{original_value} 赋予节点的源值
{original_message} 定制之前的原始消息
try {
    (new \CuyZ\Valinor\MapperBuilder())
        ->mapper()
        ->map(SomeClass::class, [/* … */]);
} catch (\CuyZ\Valinor\Mapper\MappingError $error) {
    $node = $error->node();
    $messages = new \CuyZ\Valinor\Mapper\Tree\Message\MessagesFlattener($node);

    foreach ($messages as $message) {
        if ($message->code() === 'some_code') {
            $message = $message->withBody('new message / {original_message}');
        }

        echo $message;
    }
}

这些消息使用ICU 库进行格式化,使占位符能够使用高级语法来执行正确的翻译,例如货币支持。

try {
    (new \CuyZ\Valinor\MapperBuilder())->mapper()->map('int<0, 100>', 1337);
} catch (\CuyZ\Valinor\Mapper\MappingError $error) {
    $message = $error->node()->messages()[0];

    if (is_numeric($message->value())) {
        $message = $message->withBody(
            'Invalid amount {original_value, number, currency}'
        );    
    } 

    // Invalid amount: $1,337.00
    echo $message->withLocale('en_US');

    // Invalid amount: £1,337.00
    echo $message->withLocale('en_GB');

    // Invalid amount: 1 337,00 €
    echo $message->withLocale('fr_FR');
}

有关可用语法的更多信息,请参阅ICU 文档。

警告如果未安装intl扩展,则可以使用填充程序来替换占位符,但它不会处理如上所述的高级语法。

格式化程序TranslationMessageFormatter可用于翻译消息的内容。

该库提供了所有可以返回的消息的列表;可以使用自定义翻译来填充或修改此列表。

\CuyZ\Valinor\Mapper\Tree\Message\Formatter\TranslationMessageFormatter::default()
    // Create/override a single entry…
    ->withTranslation('fr', 'some custom message', 'un message personnalisé')
    // …or several entries.
    ->withTranslations([
        'some custom message' => [
            'en' => 'Some custom message',
            'fr' => 'Un message personnalisé',
            'es' => 'Un mensaje personalizado',
        ], 
        'some other message' => [
            // …
        ], 
    ])
    ->format($message);

可以使用AggregateMessageFormatter将多个格式化程序连接到一个格式化程序中。然后可以轻松地将这个实例注入到处理消息的服务中。

格式化程序将以与聚合相同的顺序被调用。

(new \CuyZ\Valinor\Mapper\Tree\Message\Formatter\AggregateMessageFormatter(
    new \CuyZ\Valinor\Mapper\Tree\Message\Formatter\LocaleMessageFormatter('fr'),
    new \CuyZ\Valinor\Mapper\Tree\Message\Formatter\MessageMapFormatter([
        // …
    ],
    \CuyZ\Valinor\Mapper\Tree\Message\Formatter\TranslationMessageFormatter::default(),
))->format($message)

⚠ 重大变更

  • 使用格式化程序改进消息自定义 ( 60a665 )
  • 撤销ObjectBuilder API 访问权限 ( 11e126 )

新功能

  • 允许注入映射器使用的缓存实现( 69ad3f )
  • 在自己的缓存实现中提取文件监视功能( 2d70ef )
  • 改进映射错误消息 ( 05cf4a )
  • 介绍预热缓存的方法( ccf09f )

错误修复

  • 使接口类型与未定义的对象类型匹配( 105eef )

其他

  • 更改InvalidParameterIndex异常继承类型 ( b75adb )
  • 引入对象构建器参数层( 48f936 )