janwebdev / translatable-entity-bundle
使实体可翻译
v1.0.0
2022-06-06 18:05 UTC
Requires
- php: ^7.4|^8.0|^8.1
- doctrine/orm: ^2.5
- symfony/config: ^4.4||^5.4||^6
- symfony/dependency-injection: ^4.4||^5.4||^6
- symfony/framework-bundle: ^4.4||^5.4||^6
Requires (Dev)
- phpro/grumphp: ^1.3
- phpstan/phpstan: ^1.7.10
- phpunit/phpunit: ^9
- roave/security-advisories: dev-latest
- squizlabs/php_codesniffer: ^3.5
- symfony/test-pack: *
Conflicts
README
先决条件
- 安装
- 启用 Bundle
- 实体
- 仓库
- 表单
- 自定义默认翻译和未找到翻译的行为
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)。请参阅 许可证文件 以获取更多信息。