PHP
laravel
Eloquent

Laravel テーブルやカラムに設定したコメントから翻訳ファイルを生成してみた

Laravel で開発していてマスタ管理画面を作っていると、表のタイトル部分、翻訳ファイルを作ったりが面倒だったので、migrationにカラムのコメントは全部設定しているし、これを使って翻訳ファイルを生成したら楽だよなーと思って、方法を模索してみました。

migration は以下のように全部コメント入れなきゃいけませんが、後々メンテナンスとか考えると、コメントはいれておくべき。(もちろんMySQL限定ですが)


public function up()
{
Schema::disableForeignKeyConstraints();

Schema::create('companies', function (Blueprint $table) {
$table->bigIncrements('id')->comment('会社ID');
$table->string('name', 64)->comment('会社名');
$table->timestamp('created_at')->nullable()->comment('作成日時');
$table->timestamp('updated_at')->nullable()->comment('更新日時');
$table->softDeletes()->comment('削除日時');

$table->unsignedBigInteger('created_by')->nullable()->comment('作成者');
$table->unsignedBigInteger('updated_by')->nullable()->comment('更新者');
$table->unsignedBigInteger('deleted_by')->nullable()->comment('削除者');

$table->foreign('created_by')->references('id')->on('users');
$table->foreign('updated_by')->references('id')->on('users');
$table->foreign('deleted_by')->references('id')->on('users');
});

DB::statement("ALTER TABLE `companies` COMMENT '会社'");

Schema::enableForeignKeyConstraints();
}

翻訳ファイルを生成するのは artisan コマンドを拡張してみます。

php artisan make:command Translation

でファイルを作成します。

app/Console/Commands/Translation.php

が作られるので、これを編集する。

それで、作ったのがこれ。

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Lang;

/**
* artisanコマンド拡張: 翻訳ファイルをDBの提示から生成する
*
* Class Translate
* @package App\Console\Commands
*/

class Translate extends Command
{

/**
* 出力先パス
* @var string|null
*/

private $path = null;

/**
* タブインデントに使用する文字列
* @var string
*/

private $tab = ' ';

/**
* テーブルのコメント
* @var array
*/

private $tables = [];

/**
* カラムのコメント
* @var array
*/

private $columns = [];

/**
* The name and signature of the console command.
*
* @var string
*/

protected $signature = 'make:translation {--force}';

/**
* The console command description.
*
* @var string
*/

protected $description = 'Generate language files from DB definitions.';

/**
* Create a new command instance.
*
* @return void
*/

public function __construct()
{
parent::__construct();
$this->path = sprintf('%s/resources/lang/%s/'
, \App::basePath()
, \App::getLocale()
);
}

/**
* Execute the console command.
*
* @return mixed
*/

public function handle()
{
Artisan::call('config:clear');

// 上書き
$force = $this->option('force');

if ($force && !$this->confirm('Do you wish to overwrite? [y|N]')) {
echo 'exit.' . PHP_EOL;
return;
}

$tables = DB::table('information_schema.TABLES')
->select(['TABLE_NAME', 'TABLE_COMMENT'])
->where('TABLE_SCHEMA', env('DB_DATABASE'))
->where('TABLE_TYPE', 'BASE TABLE')
->where('TABLE_NAME', '!=', 'migrations')
->orderBy('TABLE_NAME')
->get();

$tables->each(function ($table) use (&$buffer_tables, &$buffer_columns) {

$this->tables[$table->TABLE_NAME] = $table->TABLE_COMMENT;

DB::table('information_schema.COLUMNS')
->select(['TABLE_NAME', 'COLUMN_NAME', 'COLUMN_COMMENT'])
->where('TABLE_SCHEMA', env('DB_DATABASE'))
->where('TABLE_NAME', $table->TABLE_NAME)
->get()
->each(function ($column) use ($table, &$buffer_columns) {
$this->columns[$table->TABLE_NAME][$column->COLUMN_NAME] = $column->COLUMN_COMMENT;
$buffer_columns[] = sprintf("\t\t'%s' => '%s',"
, $column->COLUMN_NAME
, $column->COLUMN_COMMENT
);
});
});

// テーブル
$old = is_array(Lang::get('tables')) ? Lang::get('tables') : [];
$script = ($force) ? $this->tables : array_replace_recursive($this->tables, $old);
$this->write($script, 0, 'tables.php');

// カラム
$old = is_array(Lang::get('columns')) ? Lang::get('columns') : [];
$script = ($force) ? $this->columns : array_replace_recursive($this->columns, $old);
$this->write($script, 0, 'columns.php');

$this->info('success.');
}

/**
* ファイルを書き出す
* @param array $arr
* @param int $indent
* @param string|null $file
*/

private function write(array $arr, int $indent = 0, string $file = null)
{
$res = [];
$res[] = '<?php';
$res[] = '';
$res[] = '/**';
$res[] = sprintf(" * resource/lang/%s/%s", \App::getLocale(), $file);
$res[] = ' * Generated by artisan make:translate';
$res[] = ' */';
$res[] = sprintf('return %s;', $this->makeScript($arr, $indent));
$res[] = '';
$buffer = implode(PHP_EOL, $res);
file_put_contents($this->path . $file, $buffer, LOCK_EX);
}

/**
* コードを生成する
* @param $arr
* @param int $indent
* @return string
*/

private function makeScript($arr, int $indent = 0)
{
if (is_string($arr)) {
return sprintf('\'%s\'', $arr);
}
$res = [];
$indent++;
$res[] = str_repeat($this->tab, $indent - 1) . '[';
foreach ($arr as $k => $v) {
$res[] = sprintf("%s'%s' => %s,"
, str_repeat($this->tab, $indent)
, $k
, $this->makeScript($v, $indent)
);
}
$res[] = str_repeat($this->tab, $indent - 1) . ']';
return trim(implode(PHP_EOL, $res));
}
}

php artisan listmake:translation が表示されることがかくにんできれば、

migrateを実行した後で php artisan make:translation を実行すれば、resources/lang/ja/ 以下に、columns.phptables.php が生成されます。