-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
314 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/vendor | ||
composer.lock | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"name": "hpolthof/laravel-translations-db", | ||
"description": "A database translations implementation for Laravel 5.", | ||
"license": "GPL2", | ||
"keywords": ["laravel", "translation", "localization", "database"], | ||
"authors": [ | ||
{ | ||
"name": "Paul Olthof", | ||
"email": "[email protected]" | ||
} | ||
], | ||
"require": { | ||
"php": ">=5.4.0", | ||
"illuminate/translation": "5.*", | ||
"illuminate/database": "5.*", | ||
"illuminate/cache": "5.*" | ||
}, | ||
|
||
"autoload": { | ||
"psr-4": { | ||
"Hpolthof\\Translation\\": "src" | ||
} | ||
}, | ||
"extra": { | ||
"branch-alias": { | ||
"dev-master": "0.1.x-dev" | ||
} | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
database/migrations/2015_06_10_144817_add_translations_table.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
|
||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Database\Migrations\Migration; | ||
|
||
class AddTranslationsTable extends Migration { | ||
|
||
/** | ||
* Run the migrations. | ||
* | ||
* @return void | ||
*/ | ||
public function up() | ||
{ | ||
Schema::create('translations', function(Blueprint $table) | ||
{ | ||
$table->increments('id'); | ||
$table->string('locale'); | ||
$table->string('group'); | ||
$table->string('name'); | ||
$table->text('value')->nullable(); | ||
$table->timestamp('viewed_at')->nullable(); | ||
$table->timestamps(); | ||
|
||
$table->index(['locale', 'group']); | ||
$table->unique(['locale', 'group', 'name']); | ||
}); | ||
} | ||
|
||
/** | ||
* Reverse the migrations. | ||
* | ||
* @return void | ||
*/ | ||
public function down() | ||
{ | ||
Schema::drop('translations'); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<?php namespace Hpolthof\Translation; | ||
|
||
use Illuminate\Database\Eloquent\ModelNotFoundException; | ||
use Illuminate\Translation\LoaderInterface; | ||
|
||
class DatabaseLoader implements LoaderInterface { | ||
|
||
/** | ||
* Load the messages for the given locale. | ||
* | ||
* @param string $locale | ||
* @param string $group | ||
* @param string $namespace | ||
* @return array | ||
*/ | ||
public function load($locale, $group, $namespace = null) | ||
{ | ||
return \DB::table('translations') | ||
->where('locale', $locale) | ||
->where('group', $group) | ||
->lists('value', 'name'); | ||
} | ||
|
||
/** | ||
* Add a new namespace to the loader. | ||
* This function will not be used but is required | ||
* due to the LoaderInterface. | ||
* We'll just leave it here as is. | ||
* | ||
* @param string $namespace | ||
* @param string $hint | ||
* @return void | ||
*/ | ||
public function addNamespace($namespace, $hint) {} | ||
|
||
/** | ||
* Adds a new translation to the database or | ||
* updates an existing record if the viewed_at | ||
* updates are allowed. | ||
* | ||
* @param string $locale | ||
* @param string $group | ||
* @param string $name | ||
* @return void | ||
*/ | ||
public function addTranslation($locale, $group, $key) | ||
{ | ||
if(!\Config::get('app.debug')) return; | ||
|
||
// Extract the real key from the translation. | ||
if (preg_match("/^{$group}\.(.*?)$/sm", $key, $match)) { | ||
$name = $match[1]; | ||
} else { | ||
throw new TranslationException('Could not extract key from translation.'); | ||
} | ||
|
||
$item = \DB::table('translations') | ||
->where('locale', $locale) | ||
->where('group', $group) | ||
->where('name', $name)->first(); | ||
|
||
$data = compact('locale', 'group', 'name'); | ||
$data = array_merge($data, [ | ||
'viewed_at' => date_create(), | ||
'updated_at' => date_create(), | ||
]); | ||
|
||
if($item === null) { | ||
$data = array_merge($data, [ | ||
'created_at' => date_create(), | ||
]); | ||
\DB::table('translations')->insert($data); | ||
} else { | ||
\DB::table('translations')->where('id', $item->id)->update($data); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?php namespace Hpolthof\Translation; | ||
|
||
use Illuminate\Translation\FileLoader; | ||
|
||
class ServiceProvider extends \Illuminate\Translation\TranslationServiceProvider { | ||
|
||
/** | ||
* Indicates if loading of the provider is deferred. | ||
* | ||
* @var bool | ||
*/ | ||
protected $defer = true; | ||
|
||
/** | ||
* Register the service provider. | ||
* | ||
* @return void | ||
*/ | ||
public function register() | ||
{ | ||
$this->registerDatabase(); | ||
$this->registerLoader(); | ||
|
||
$this->app->singleton('translator', function($app) | ||
{ | ||
$loader = $app['translation.loader']; | ||
$database = $app['translation.database']; | ||
|
||
// When registering the translator component, we'll need to set the default | ||
// locale as well as the fallback locale. So, we'll grab the application | ||
// configuration so we can easily get both of these values from there. | ||
$locale = $app['config']['app.locale']; | ||
|
||
$trans = new Translator($database, $loader, $locale); | ||
|
||
$trans->setFallback($app['config']['app.fallback_locale']); | ||
|
||
return $trans; | ||
}); | ||
} | ||
|
||
public function boot() | ||
{ | ||
$this->publishes([ | ||
__DIR__.'/../database/migrations/' => database_path('/migrations') | ||
], 'migrations'); | ||
} | ||
|
||
/** | ||
* Register the translation line loader. | ||
* | ||
* @return void | ||
*/ | ||
protected function registerLoader() | ||
{ | ||
$this->app->singleton('translation.loader', function($app) | ||
{ | ||
return new FileLoader($app['files'], $app['path.lang']); | ||
}); | ||
} | ||
|
||
protected function registerDatabase() | ||
{ | ||
$this->app->singleton('translation.database', function($app) | ||
{ | ||
return new DatabaseLoader(); | ||
}); | ||
} | ||
|
||
/** | ||
* Get the services provided by the provider. | ||
* | ||
* @return array | ||
*/ | ||
public function provides() | ||
{ | ||
return array('translator', 'translation.loader', 'translation.database'); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?php namespace Hpolthof\Translation;; | ||
|
||
class TranslationException extends \RuntimeException { | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?php namespace Hpolthof\Translation;; | ||
|
||
use Illuminate\Translation\LoaderInterface; | ||
use Symfony\Component\Translation\TranslatorInterface; | ||
|
||
class Translator extends \Illuminate\Translation\Translator implements TranslatorInterface { | ||
|
||
public function __construct(LoaderInterface $database, LoaderInterface $loader, $locale) | ||
{ | ||
$this->database = $database; | ||
parent::__construct($loader, $locale); | ||
} | ||
|
||
protected static function isNamespaced($namespace) | ||
{ | ||
return !(is_null($namespace) || $namespace == '*'); | ||
} | ||
|
||
/** | ||
* Get the translation for the given key. | ||
* | ||
* @param string $key | ||
* @param array $replace | ||
* @param string $locale | ||
* @return string | ||
*/ | ||
public function get($key, array $replace = array(), $locale = null) | ||
{ | ||
list($namespace, $group, $item) = $this->parseKey($key); | ||
|
||
// Here we will get the locale that should be used for the language line. If one | ||
// was not passed, we will use the default locales which was given to us when | ||
// the translator was instantiated. Then, we can load the lines and return. | ||
foreach ($this->parseLocale($locale) as $locale) | ||
{ | ||
if(!self::isNamespaced($namespace)) { | ||
// Database stuff | ||
$this->database->addTranslation($locale, $group, $key); | ||
} | ||
|
||
$this->load($namespace, $group, $locale); | ||
|
||
$line = $this->getLine( | ||
$namespace, $group, $locale, $item, $replace | ||
); | ||
|
||
if ( ! is_null($line)) break; | ||
} | ||
|
||
// If the line doesn't exist, we will return back the key which was requested as | ||
// that will be quick to spot in the UI if language keys are wrong or missing | ||
// from the application's language files. Otherwise we can return the line. | ||
if ( ! isset($line)) return $key; | ||
|
||
return $line; | ||
} | ||
|
||
public function load($namespace, $group, $locale) | ||
{ | ||
if ($this->isLoaded($namespace, $group, $locale)) return; | ||
|
||
// If a Namespace is give the Filesystem will be used | ||
// otherwise we'll use our database. | ||
// This will allow legacy support. | ||
if(!self::isNamespaced($namespace)) { | ||
// If debug is off then cache the result forever to ensure high performance. | ||
if(!\Config::get('app.debug')) { | ||
$that = $this; | ||
$lines = \Cache::rememberForever('__translations.'.$locale.'.'.$group, function() use ($that, $locale, $group, $namespace) { | ||
return $this->database->load($locale, $group, $namespace); | ||
}); | ||
} else { | ||
$lines = $this->database->load($locale, $group, $namespace); | ||
} | ||
} else { | ||
$lines = $this->loader->load($locale, $group, $namespace); | ||
} | ||
$this->loaded[$namespace][$group][$locale] = $lines; | ||
} | ||
} |