tmi/translation-bundle 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

tmi/translation-bundle

最新稳定版本:v1.6.0

Composer 安装命令:

composer require tmi/translation-bundle

包简介

A Symfony bundle that manages translations with Doctrine.

README 文档

README

PHP 8.4+ Symfony 7.3+ Doctrine ORM 3.5+ codecov

A modern, high-performance translation bundle for Symfony that stores entity translations in the same table as the source entity - no expensive joins, no complex relations.

🚀 Why This Bundle?

This bundle solves: Symfony Doctrine translation, entity localization, multilingual entities, Doctrine translatable, Symfony translation bundle, database translations, entity translations

❌ Traditional Translation Problems:

  • Multiple tables with complex joins
  • Performance overhead on translated entities
  • Complex queries for simple translations
  • Schema changes required for each new translation

✅ Our Solution:

  • Single table for all translations
  • No performance penalty - same query speed as non-translated entities
  • Simple implementation - just add interface and trait
  • Zero schema changes when adding new languages

🎯 Key Features

  • 🏷️ Same-table storage - Translations stored with source entity (no joins needed)
  • ⚡ Blazing fast - No performance overhead on translated entities
  • 🔄 Auto-population - Automatic relation translation handling
  • 🎯 Inherited entity support - Works with complex entity hierarchies
  • 🛡️ Type-safe - Full PHP 8.4 type declarations throughout
  • 🧪 100% tested - Comprehensive test suite with full coverage

🏗️ About This Version

This is a complete refactoring based on PHP 8.4, Symfony 7.3, and Doctrine ORM 3.5 of the fork from umanit/translation-bundle, implemented with modern development practices and featuring 100% code coverage with comprehensive test suites.

⚠️ Limitations

  • ManyToMany associations are currently not supported. This includes usage with the SharedAmongstTranslations attribute.
  • There is currently no handler for unique fields (e.g. uuid, slug). When translating entities with unique columns, the translation process may fail with a unique constraint violation. See the Quick Fix for unique fields section below.
  • Requires PHP 8.4+, Symfony 7.3+ and Doctrine ORM 3.5+ (see legacy versions for older support)

📦 Installation

composer require tmi/translation-bundle

Register the bundle to your config/bundles.php.

return [
// ...
Tmi\TranslationBundle\TmiTranslationBundle::class => ['all' => true],
];

⚙️ Configuration

Configure your available locales and, optionally, the default one and disabled firewalls. That's it!

# config/packages/tmi_translation.yaml
tmi_translation:
    locales: ['en_US', 'de_DE', 'it_IT'] # Required: available locales
    # default_locale: 'en_US'            # Optional: uses kernel.default_locale if not set
    # disabled_firewalls: ['main']       # Optional: disable filter for specific firewalls

Doctrine DBAL Custom Type - TuuidType

To use the TuuidType in your Symfony project, you must register it in your Doctrine configuration:

# config/packages/doctrine.yaml
doctrine:
    dbal:
        types:
            tuuid: Tmi\TranslationBundle\Doctrine\Type\TuuidType

This ensures that Doctrine recognizes the tuuid type and avoids errors like:

Unknown column type "tuuid" requested. Any Doctrine type that you use has to be registered with \Doctrine\DBAL\Types\Type::addType(). 

🚀 Quick Start

Make your entity translatable

Implement Tmi\TranslationBundle\Doctrine\TranslatableInterface and use the trait Tmi\TranslationBundle\Doctrine\ModelTranslatableTraiton an entity you want to make translatable.

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Tmi\TranslationBundle\Doctrine\Model\TranslatableInterface;
use Tmi\TranslationBundle\Doctrine\Model\TranslatableTrait;

#[ORM\Entity]
class Product implements TranslatableInterface
{
    use TranslatableTrait;
    
    #[ORM\Column]
    private string $name;
    
    // ... your other fields
}

Translate your entity

Use the service tmi_translation.translator.entity_translator to translate a source entity to a target language.

$translatedEntity = $this->get('tmi_translation.translator.entity_translator')->translate($entity, 'de_DE');

Every attribute of the source entity will be cloned into a new entity, unless specified otherwise with the EmptyOnTranslate attribute.

🔧 Advanced Usage

Usually, you don't wan't to get all fields of your entity to be cloned. Some should be shared throughout all translations, others should be emptied in a new translation. Two special attributes are provided in order to solve this.

SharedAmongstTranslations

Using this attribute will make the value of your field identical throughout all translations: if you update this field in any translation, all the others will be synchronized. If the attribute is a relation to a translatable entity, it will associate the correct translation to each language.

Note: ManyToMany associations are not supported with SharedAmongstTranslations yet.

#[ORM\ManyToOne(targetEntity: Media::class)]
#[SharedAmongstTranslations]
private Media $video; // Shared across all translations

EmptyOnTranslate

This attribute will empty the field when creating a new translation. ATTENTION: The field has to be nullable or instance of Doctrine\Common\Collections\Collection!

#[ORM\ManyToOne(targetEntity: Owner::class, cascade: ['persist'], inversedBy: 'product')]
#[ORM\JoinColumn(name: 'owner_id', referencedColumnName: 'id', nullable: true)]
#[EmptyOnTranslate]
private Owner|null $owner = null

#[ORM\Column(type: 'string', nullable: true)]
#[EmptyOnTranslate]
private string|null $title = null;

Translate event

You can alter the entities to translate or translated, before and after translation using the Tmi\TranslationBundle\Event\TranslateEvent

  • TranslateEvent::PRE_TRANSLATE called before starting to translate the properties. The new translation is just instanciated with the right oid and locale
  • TranslateEvent::POST_TRANSLATE called after saving the translation

Filtering your contents

To fetch your contents out of your database in the current locale, you'd usually do something like $repository->findByLocale($request->getLocale()).

Alternatively, you can use the provided filter that will automatically filter any Translatable entity by the current locale, every time you query the ORM. This way, you can simply do $repository->findAll() instead of the previous example.

Add this to your config.yml file:

# Doctrine Configuration
doctrine:
  orm:
    filters:
      # ...
      tmi_translation_locale_filter:
        class:   'Tmi\TranslationBundle\Doctrine\Filter\LocaleFilter'
        enabled: true

(Optional) Disable the filter for a specific firewall

Usually you'll need to administrate your contents. For doing so, you can disable the filter by configuring the disabled_firewalls option in your configuration:

# config/packages/tmi_translation.yaml
tmi_translation:
  locales: [en, de, it]
  disabled_firewalls: ['main']  # Disable filter for 'main' firewall

Quick Fix for unique fields

If you need a translatable slug (or UUID), adjust your database schema to make the slug unique per locale, instead of globally:

#[ORM\Entity]
#[ORM\Table(name: 'product')]
#[ORM\UniqueConstraint(
    name: "uniq_slug_locale",
    columns: ["slug_value", "locale"]
)]
class Product
{
    #[ORM\Column(length: 255)]
    private ?string $slug = null;

    #[ORM\Column(length: 5)]
    private string $locale;
}

📊 Performance Comparison

Operation Traditional Bundles TMI Translation Bundle
Fetch translated entity 3-5 SQL queries 1 SQL query
Schema complexity Multiple tables Single table
Join operations Required None
Cache efficiency Low High

🤝 Contributing

We welcome contributions!

📄 License

This bundle is licensed under the MIT License.

🙏 Acknowledgments

Based on the original work by umanit/translation-bundle, now completely modernized for current PHP and Symfony ecosystems.

⭐ If this bundle helps you, please give it a star on GitHub!

统计信息

  • 总下载量: 33
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-09-09