vkr/translation-bundle

将数据库中的文本进行非注释映射翻译,包括与谷歌翻译的集成

安装: 52

依赖: 0

建议者: 0

安全: 0

星标: 0

关注者: 3

分支: 3

开放问题: 0

类型:symfony-bundle

1.1.2 2017-03-23 21:49 UTC

This package is auto-updated.

Last update: 2024-09-20 22:23:06 UTC


README

此包处理翻译。尽管有其他几个Symfony包也执行相同的任务,但此包是算法无关和ORM无关的。翻译存储在实体中,这些实体可能与Doctrine实体相同,但从技术上讲,任何其他ORM都可以使用,以及非数据库持久化解决方案。用户可以使用与包一起提供的默认翻译算法,或自己创建一些算法。算法可以使用一个或多个驱动器。此包包含三个驱动器 - 一个使用Doctrine,专为每个可翻译实体存在一个翻译表的情况编写,第二个使用谷歌翻译,而第三个允许使用翻译实体的另一个字段作为后备。

安装

在使用此包之前需要执行几个步骤。

  1. config.yml 中创建以下条目
vkr_translation:
    language_entity: "MyBundle:MyLanguageEntity"
    locale_retriever_service: "my.locale_retriever"
  1. 创建一个区域检索服务。它必须实现 LocaleRetrieverInterface 并定义其两个方法。两种方法都可以返回ISO语言代码,形式为短(如“en”)或长(如“en_US”)。

  2. 定义一个语言实体。它必须实现 LanguageEntityInterfacegetCode() 方法应返回与您的区域检索器返回的形式相同的一个语言代码。

  3. 定义至少一对实体 - 下面将说明。

  4. (可选)如果您想使用谷歌翻译集成,请在 parameters.yml 中设置 vkr_translation.google_api_key 参数。

定义实体对

此包是基于为每个需要翻译的实体拥有单独的翻译实体的想法构建的。因此,需要两个实体 - 一个 可翻译实体,它将被翻译,以及一个包含翻译的 翻译实体

可翻译实体必须实现 TranslatableEntityInterface,而其翻译实体必须实现 TranslationEntityInterface。此外,还有一个命名约定:翻译实体的完整类名必须与可翻译实体相同(包括命名空间)加上“Translations”后缀。

建议(尽管不是必需的)使用为这两个接口提供的特性:TranslatableEntityTraitTranslationEntityTrait。第二个提供了翻译实体所需的所有方法,但可翻译实体需要手动定义一个额外的 getTranslatableFields 方法,该方法应返回翻译实体每个字段的名称数组,不包括主键和关联。对于返回的每个字段,需要在可翻译实体上手动定义一个getter和setter,其名称应与翻译实体上的名称相同。换句话说,如果您在翻译实体上有“name”字段,您需要在可翻译实体上写如下内容

public function getTranslatableFields()
{
    return ['name'];
}

private $name;

public function setName($name)
{
    $this->name = $name;
    return $this;
}

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

如果您使用Doctrine,这两个实体的YAML或XML映射都应该包含这些

  1. 名为 "id" 的PK字段。

  2. 在可翻译实体上到一个“translations”的一对多关联(强烈推荐使用懒加载)。

  3. 在翻译实体上到“language”和“entity”的多对一关联,分别指向语言实体和可翻译实体。

Examples 文件夹中提供了语言、可翻译和翻译实体的YAML映射示例。

可翻译实体的可选方法

可翻译实体可以定义两个额外的函数。

getTranslationFallback。在默认算法下,允许定义一个标量值或可翻译实体上的另一个字段作为默认值,以防找不到翻译。它接受一个可选参数$field,当存在多个可翻译字段时可以使用。在默认算法下,如果返回false,则组件将回退到默认行为,即抛出TranslationException异常。如果您不想抛出异常,但只想在找不到翻译时返回空字符串,只需让getTranslationFallback返回空字符串。

此示例将返回slug而不是名称,以及'foo'而不是描述

public function getTranslationFallback($field = '')
{
    if ($field == 'name') {
        return $this->getSlug();
    }
    if ($field == 'description) {
        return 'foo';
    }
    return '';
}

如果您想在自定义算法中使用此方法,必须包含对EntityTranslationDriver的依赖。

isGoogleTranslatable方法应返回true,如果您想为实体启用Google翻译。如果不存在,则默认算法下将禁用Google翻译。

如果您想在自定义算法中使用此方法,必须包含对GoogleTranslationDriver的依赖。

TranslationManager::translate()方法

此组件最基本的用法如下

$translationManager = $this->get('vkr_translation.translation_manager');
$translatedEntity = $translationManager->translate($entity);

它将返回第一个参数(可翻译实体),但现在可翻译字段将通过getter填充并可供访问。请注意,没有使用克隆,原始的$entity将被更改。

translate()的第一个参数可以更改为由Doctrine的findBy()findAll()返回的可翻译实体的数组。在这种情况下,将返回相同的实体数组。

还有两个其他可选参数。

第二个参数是locale字符串,其格式与语言实体的getCode()返回的格式相同。如果没有指定,目标语言将由您的locale检索服务的getCurrentLocale()确定。

第三个参数是排序列,应该是实体的一个可翻译字段的名称。如果第一个参数是数组,其元素将根据该字段重新排序。目前仅支持升序排序。

由于可能会抛出异常,建议在每次调用translate()时捕获TranslationException

算法和驱动

此组件可以与多个翻译算法一起工作。默认情况下,使用DefaultAlgorithm。您可以使用此语法切换算法

$algorithm = $this->get('my.algorithm');
$translationManager->setAlgorithm($algorithm);

您可以通过实现VKR\TranslationBundle\Interfaces\TranslationAlgorithmInterface来创建自己的算法。它必须包含返回翻译实体的getTranslation()方法。虽然技术上所有外部DB和API调用都可以包含在算法中,但建议将它们解耦到驱动程序类中。驱动程序是一个简单的PHP类,用于处理外部调用。此组件包含三个驱动程序:VKR\TranslationBundle\Services\DoctrineTranslationDriverVKR\TranslationBundle\Services\GoogleTranslationDriverVKR\TranslationBundle\Services\EntityTranslationDriver。第三个驱动程序使用另一个翻译实体的字段作为翻译,并设计为在没有找到其他翻译时作为回退使用。如果您想扩展组件,请注意,强烈建议除了算法之外,没有任何类依赖于驱动程序。

此组件包含三个算法。

DefaultAlgorithm

  1. 脚本在数据库中查找指定locale的翻译。

  2. 如果找不到,脚本将查找通过您locale检索器的getDefaultLocale()方法指定的locale的翻译。

  3. 如果在该默认locale中找到了翻译,并且Google翻译已启用,则脚本将尝试从Google获取指定locale的翻译。如果Google驱动程序抛出异常,则返回步骤2的翻译。

  4. 如果在指定的locale和默认locale中都没有找到翻译,则脚本将尝试从数据库中获取任何其他随机翻译。

  5. 然后,如果成功并且启用了Google翻译,脚本将尝试通过Google将该翻译翻译成指定的区域设置。如果Google驱动程序抛出异常,则返回第4步的翻译。

  6. 最后,如果在数据库中没有翻译存在,脚本将在实体上查找getTranslationFallback()方法,并返回其返回的任何值,除了false

  7. 如果getTranslationFallback()不存在或返回false,脚本将放弃并抛出TranslationException

无翻译算法

此算法实际上并不进行翻译,它只是在数据库中搜索任何翻译(如果有多个,则返回具有最小PK值的翻译)并在没有翻译时抛出TranslationException。在TranslationManager::translate()中的第二个和第三个参数不被使用。

按需算法

此算法的行为与DefaultAlgorithm非常相似,但在尝试查找翻译时不太坚持。它不使用TranslationManager::translate()的第三个参数。

  1. 脚本将在数据库中查找指定区域设置的翻译。

  2. 如果没有指定区域的翻译,脚本将尝试从数据库中检索任何其他随机翻译。

  3. 然后,如果成功并且启用了Google翻译,脚本将尝试通过Google将该翻译翻译成指定区域设置。如果Google驱动程序抛出异常,则返回第2步的翻译。

  4. 如果第2步不成功,脚本将放弃并抛出TranslationException

TranslationUpdater::updateTranslations()方法

此方法提供了创建和更新翻译的简单接口。它有三个必选参数 - 可翻译的实体、区域和值数组。基本使用示例如下

$translationUpdater = $this->get('vkr_translation.translation_updater');
$translationManager->translate($entity, 'fr', [
    'name' => 'French name',
    'description' => 'French description',
]);

第三个参数必须包含与实体上的可翻译字段一样多的字段-值对。该方法将搜索给定区域的翻译并更新可翻译字段,或者在不存在时创建翻译。

如果翻译实体上没有找到getter和/或setter,或者无法使用new关键字初始化翻译实体,则此方法可能还会抛出TranslationException