janwebdev/translatable-entity-bundle

使实体可翻译

v1.0.0 2022-06-06 18:05 UTC

This package is auto-updated.

Last update: 2024-09-06 22:51:57 UTC


README

Unit Tests Latest Stable Version Total Downloads Latest Unstable Version License

先决条件

  1. 安装
  2. 启用 Bundle
  3. 实体
  4. 仓库
  5. 表单
  6. 自定义默认翻译和未找到翻译的行为

1. 安装

使用 composer

运行 composer 下载 bundle

$ composer require janwebdev/translatable-entity-bundle

2. 启用 bundle

检查 bundle 是否已启用

<?php
// ./config/bundles.php

return [
    // ...
    Janwebdev\TranslatableEntityBundle\TranslatableEntityBundle::class => ['all' => true],
];

3. 实体

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;

class Article
{    
    /**
     * @ORM\OneToMany(targetEntity="ArticleTranslation", mappedBy="translatable", cascade={"persist"})
     */
    protected $translations;

    public function __construct()
    {
        $this->translations = new ArrayCollection();
    }
}
<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;

class ArticleTranslation
{    
    /**
     * 
     * @ORM\Column(name="locale", type="string", length=128)
     */
    private $locale;

    /**
     * @ORM\ManyToOne(targetEntity="Article", inversedBy="translations")
     * @ORM\JoinColumn(name="article_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $translatable;

    /**
     *
     * @ORM\Column(name="name", type="string", length=128)
     */
    private $name;
}

然后运行 doctrine:generate:entities 并 移除生成的 addTranslation 方法(以示例中的 Article 为例)。现在您可以实现正确的接口。

<?php

namespace App\Entity;

use Janwebdev\TranslatableEntityBundle\Model\TranslatableWrapper;

class Article extends TranslatableWrapper
{    
    
}

TranslatableWrapper 继承自 Translatable(实现了 TranslatableInterface 的一些方法)并添加了一个包装 TranslatingInterface 实体方法的魔法方法。

<?php

namespace App\Entity;

use Janwebdev\TranslatableEntityBundle\Model\TranslatingInterface;
use Janwebdev\TranslatableEntityBundle\Model\TranslatableInterface;

class ArtcileTranslation implements TranslatingInterface
{    
    
}

请记住修改 ArticleTranslation::setTranslatable 的签名

如果您想“取消魔法”,可以直接扩展 Janwebdev\TranslatableEntityBundle\Model\Translatable 并自行创建所需的包装方法。

4. 仓库

<?php

namespace App\Repository;

use Doctrine\ORM\EntityRepository;

class ArticleRepository extends EntityRepository
{
    public function getArticleTranslatedQuery()
    {
        $qb = $this->createQueryBuilder('a')
            ->select(array('a', 'at'))
            ->leftJoin('a.translations', 'at');

        return $qb;
    }
}

5. 表单

可能的表单实现

<?php

namespace App\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class ArtcileTranslationFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('locale', 'hidden');
        $builder->add('name');
    }

    public function setDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'App\Entity\ArtcileTranslation',
        );
    }
}
<?php

namespace App\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class ArticleType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('translations', 'collection', array(
            'type' => new ArtcileTranslation
            'by_reference' => false,
        ));
    }
}

6. 自定义默认翻译和未找到翻译的行为

如果您想使用默认翻译,即找到的第一个翻译,即使它不是当前区域或默认区域的翻译

protected function acceptFirstTransaltionAsDefault()
{
    return true;
}

如果您想只有找到当前区域的翻译时才使用翻译

protected function acceptDefaultLocaleTransaltionAsDefault()
{
    return false;
}

如果您想在翻译未找到的情况下自行管理行为

protected function handleTranslationNotFound()
{
    //your logic
}

例如

protected function handleTranslationNotFound()
{
   $class = get_class($this) . 'Translation';
   if (class_exists($class)) {
       $this->translation = new $class;
   } else {
       $this->translation = null;
   }
}

单元测试

$ phpunit

变更日志

请参阅 变更日志 以获取有关最近更改的更多信息。

许可证

MIT 许可证 (MIT)。请参阅 许可证文件 以获取更多信息。