Laravelで多言語CMSをスクラッチ開発する時だった時に便利だった機能

この記事は、
[オールアバウトアドベントカレンダー](http://qiita.com/advent-calendar/2015/allabout)の記事です。

# まえがき
今回は12/5(土)にリッチメディアさんとLIGさんとの共同勉強会である[Remixing Vol.3 with オールアバウト and LIG](https://remixing.doorkeeper.jp/events/34982)で発表してきたフルスクラッチCMS開発ノウハウ With Laravel の補足記事になります。
詳しい発表内容は以下のスライドを参考にしてください。

http://www.slideshare.net/takumiyoshida14/20151205cms-with-laravel

なお、今回はLaravel5.0をベースにしています。
# 多言語実装
今回はCMSも多言語化する必要がありました。ただし、URLはそのままです。
例えばarticleの一覧ページが
http://test.cms.com/article
だったときに多言語サイトだと
http://test.cms.com/article/en や http://test.cms.com/article?lang=en
のようにURLが変わる(変える必要がある)ことが一般的ですが、今回はその対応は必要ありませんでした。

Laravelのデフォルトのディレクトリ構造だと

resources/lang/{国名}/{ファイル}.phpの用に言語ファイルを用意します。

![スクリーンショット 2015-12-10 午後5.12.47.png](https://qiita-image-store.s3.amazonaws.com/0/57634/f02d19b0-8e27-ebc9-b7ac-c442aade94ae.png "スクリーンショット 2015-12-10 午後5.12.47.png")

今回はmessagesに翻訳で使う文字列を入れ込んでいる。
なお、言語ファイルと言っても単純な配列を返しているだけである

```en.messages.php
return [
	'404'                => 'Page Not Found',
    '500'                => 'Internal Server Error',
    '503'                => 'Service Temporarily Unavailable',
    'logout'             => 'Logout',
    'edit_profile'       => 'Edit Profile',
    'close'              => 'Close',
    'yes'                => 'Yes',
    'no'                 => 'No'
];

```

```zh-CN.messages.php
return[
 	'404'                => '页面无法找到',
    '500'                => '内部服务错误',
    '503'                => '服务暂时中断',
    'logout'             => '登出',
    'edit_profile'       => '编辑简介',
    'close'              => '关闭',
    'yes'                => 'Yes',
    'no'                 => 'No'
];
```

表示される言語はconfig.app.phpのlocaleで設定される。

# ファイルシステム
実装を変更せずに書き込みするディスクをローカルストレージやS3等の変更ができるもの。
実装面の詳しいことは以下を参照に
http://qiita.com/yamato/items/7b8aab6e1f3556e9aadb

# リソースフルコントローラ
1. コマンドでひな形を作成できる

```
php artisan make:controller ArticleController
```


2.メソッド+パスで処理の切り分けができる。
![スクリーンショット 2015-12-10 午後5.44.35.png](https://qiita-image-store.s3.amazonaws.com/0/57634/6b164901-88be-a648-1a09-9529bee9c930.png "スクリーンショット 2015-12-10 午後5.44.35.png")


例えば、
/articleだけでアクセスした時には indexメソッドが実行されるし、
/article/createでアクセスした時にはcreateメソッドが実行される。

新規作成時には POSTで /articleにアクセスすれば storeメソッドが実行される。
基本的にstore時にはINSERT処理を実装すると思う。
また、更新時にはPUT/PATCHでアクセスするのでUPDATE処理を実装し実行できる。

弊社で昔使っていたフレームワークでは、POST/PUT/PATCHの切り分けができず、is_newみたいなフラグでINSERT/UPDATEを判断したりしていたので、このルーティングはかなり便利

# Validator
CMSからの入力はValidatorを行う必要がある。
デフォルトでかなり多くのヴァリデーションルールが用意されている。
http://readouble.com/laravel/5/0/0/ja/validation.html#available-validation-rules

実際にCMS開発時に使ったルールは以下の通り
|ルール名|説明|
|:--:|:--:|
|required|必須であることをバリデート|
|max:255|値が最大値であることをバリデートする|
|min:1|値が最小値であること(設定された値以上の値が入力されていること)をバリデートする|
|digits_between:a,b|値がa,bの間であることをバリデートする|
|url|urlであることをバリデート|

また、validatorを拡張してカスタムバリデートを作ることができる。
例えば、画像の高さが一定以上をバリデートするバリデータは

```
        \Validator::extend('isValidHeightImageSize', function($attribude, $value, $parameters) use ($limit_height)
        {
            $img_height = \Image::make($value)->height();
            if($img_height < $limit_height) {
                return false;
            }
            return true;
        });
```
のように作成でき、isValidHeightImageSizeをバリデーターのルールに設定すれば使える。

必須入力されているか。という点はよく使うので用意されていて便利

# Eloquent ORM
LaravelのORMで便利なメソッドや機能が用意されている
http://readouble.com/laravel/5/0/0/ja/eloquent.html

ここではクエリスコープを説明する。
クエリスコープはロジックを再利用するためのメソッドである。
CMSでよく使うスコープとしては
・公開済みの記事を取得するスコープ
・カテゴリがITのものを取得するスコープ
・人気な記事を(pvが100以上あるものを)取得するスコープなどであろう。

例えば、公開済みでカテゴリがITで人気な記事を取得する場合は

```
$article = Article:popular()->categoryIT()->published()->get();
```
のようにメソッドチェインでかける。

各scopeは

```
public function scopePopular($query)
{
	return $query->where('pv', '>', 100);
}
```
のようにかける。

# composerとPackagist
いまやモダンなPHPフレームワークではComposerが採用されていないということはないと思う。
PHPの依存管理システムで、ライブラリの導入がかなり楽になった。
また、ライブラリの検索にはPackagistというサイトを使うと良い。

# 画像処理ライブラリ
Intervation/Imageというライブラリを使うと便利。
使い方は後々載せます。

# まとめ
LaravelとCMS構築はかなり相性が良い。
1月にはLaravelのリファレンス本も出るし、もっとLaravelが流行ることを期待しています。