bruno-fernandes/laravel-multi-language

Simple approach to models multi-language support.

0.0.4 2020-03-17 13:07 UTC

This package is auto-updated.

Last update: 2024-10-17 23:37:44 UTC


README

IMPORTANT: Under active development. Do not use in production, api might change.

Latest Version on Packagist CircleCI CodeCoverage Quality Score Total Downloads

Simple approach to eloquent models translation. There are other packages that provide translation functionality, this is a different approach with some trade-offs. Priority is simplicity.

// TODO: add example database schema here.

Key points:

  • easy to get up running on existing applications
  • all eloquent model fields are translatable
  • original can be created in any language
  • translations can be copied from original
  • translations can be easily associated later on

Installation

You can install the package via composer:

composer require bruno-fernandes/laravel-multi-language

If you want to set custom column names, publish the config file and override the defaults:

php artisan vendor:publish --provider="BrunoFernandes\LaravelMultiLanguage\LaravelMultiLanguageServiceProvider"

Usage

// Import the Translatable trait into the eloquent model
use BrunoFernandes\LaravelMultiLanguage\Translatable;

class Page extends Model
{
    use Translatable;
}

// Create a migration to add the required columns to the model's table
// Example:
class AddMultilanguageFieldsToPagesTable extends Migration
{
    public function up()
    {
        Schema::table('pages', function (Blueprint $table) {
            // Create columns
            $table->string(config('laravel-multi-language.lang_key'), 6)
                ->default('en')->index()->after('id');
            $table->integer(config('laravel-multi-language.foreign_key'))
                ->unsigned()->nullable()->index()->after('id');
            
            // Create composite unique index to prevent multiple
            // records using the same lang key
            $table->unique([
                config('laravel-multi-language.foreign_key'), 
                config('laravel-multi-language.lang_key')
            ]);
        });

        // TODO: if there are already records on the table, create a migration to update
        // all of them and set the lang and the original_id with the correct values
    }
}

//
// Usage
// 
$page = Page::create(['title' => 'English title']);
$englishPage = $page->translateTo('es', ['title' => 'Spanish title']);

$originalPages = Page::onlyOriginals()->get();

// the package will apply the lang scope by default, so only  
// the current locale records are returned (it can be disable in the config file)
$currentLocalePages = Page::get();

// if apply lang global scope is disabled you can use the lang scope as follow:
$enPagesWithTranslations = Page::lang('en')->withTranslations()->get();
// NOTE: always use withTranslations() rather than with('translations) as it is more efficient
// using withTranslations() will exlude the current locale from the translations relationship

// if you would like to remove a global scope for a given query,
// you may use the  withoutGlobalScope method as follow:
use BrunoFernandes\LaravelMultiLanguage\Scopes\LangScope;
$allPagesOfAllLocales = Page::withoutGlobalScope(LangScope::class)->get();

// TODO: add usage samples to be added

Known issues

  • When used with Searchable package global scopes need to be removed and applied manually after the search method is used.

  • when using hasOne relationships, if foreign_key and local_key are not set the LangScope (Global Scope) is applied to the relationship, if the relationship model is not translatable an error is thrown.

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'live_players.original_id' in 'where clause' (SQL: select * from `live_players` where `live_players`.`original_id` in (35) and `live_players`.`deleted_at` is null) (View: /home/vagrant/code/resources/frontend/views/index.blade.php)
// This does not work
class Content extends Model
{
    public function livePlayer()
    {
        return $this->hasOne(LivePlayer::class);
    }
}

// This works
class Content extends Model
{
    public function livePlayer()
    {
        return $this->hasOne(LivePlayer::class, 'id', 'live_player_id');
    }
}

Testing

composer test

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email security@brunofernandes.com instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.