FuelPHPで最初にやることあれこれ

いろいろ、こうやっておいた方がいいかなっていうまとめ

# ソース管理

* 無視ファイル

```/.gitignoire
/composer.lock
/composer.phar
*~
*.bak
Thumbs.db
desktop.ini
.DS_Store
.buildpath
.project
.settings
*.tmproj
build
.idea
/docs
/fuel/vendor
/fuel/packages
/fuel/core
/fuel/app/logs/*/*/*
/fuel/app/cache/*/*
/fuel/app/tmp/*
/fuel/app/config/development/*
/fuel/app/config/production/*
/fuel/app/config/stage/*
/fuel/app/config/test/*
/fuel/app/config/crypt.php
nbproject/
```

* オレオレスクリプトはGit管理しないようにする

```shell-session
vi .git/info/exclude
```

* .htaccessで環境設定を行った場合、デプロイ後にGit管理から除外する (と戻す)

```shell-session
git update-index --skip-worktree public/.htaccess
#git update-index --no-skip-worktree public/.htaccess
```

# パッケージ管理

* composerを使う（gitのsubmoduleは微妙だった）
* こちら参照　⇒　[FuelPHPの空プロジェクトを最速構築（カスタマイズ可）](http://qiita.com/goosys/items/50ef7afb784523655f90)

```shell-session
mkdir PROJECT
cd PROJECT
wget https://raw.githubusercontent.com/goosys/Fuel-Installer/master/composer.json -O composer.json  --no-check-certificate
wget https://raw.githubusercontent.com/fuel/fuel/1.7/master/oil -O oil --no-check-certificate
curl -s http://getcomposer.org/installer | php
php composer.phar install
```

# ディレクトリ構造

## fuel/app/assetsの作成

* jsもcssもアプリケーションの一部じゃないかと思うので、ちゃんとapp内に作成
* publicからはシンボリックリンクする
* アプリケーションではないjsはそのままpublicで使う（jQueryなど）
* シンボリックリンク状態でもちゃんとGit管理できるのですごい

```
mkdir fuel/app/assets/common/{css,js} -p
pushd public/assets
ln -s ../../fuel/app/assets/common common
popd
```

## LESSにしてみる

* こちら参照　⇒　[FuelPHPでLESSを使う](http://qiita.com/goosys/items/687c4811bc36c33dd775)

## app/classes内の構成

* ざっくりとはこんな感じ
* 場合によっては、コントローラーの中をadminとpublicに分けたりもする

```
fuel/app/
├── controller
├── helper
├── model
├── observer
└── validation
```

# コンフィグ

## 全環境共通設定

```php:fuel/app/config/config.php
	'language'           => 'ja',
	'language_fallback'  => 'en',
	'locale'             => 'ja_JP',
	'encoding'  => 'UTF-8',
	'default_timezone'   => 'Asia/Tokyo',

	// 'log_threshold'    => Fuel::L_WARNING, //各環境で再設定(後述)
	'log_path'         => APPPATH.'logs/'.Fuel::$env.'/', //各環境用のディレクトリに格納
	// 'log_date_format'  => 'Y-m-d H:i:s',

```

* aliasしておくと便利

```shell-session:~/.bash_profile
alias devlog='tail -n 30 -f fuel/app/logs/development/`date +\%Y/\%m/\%d`.php'
```

## 開発環境用設定

```php:fuel/app/config/development/config.php
	'log_threshold'    => array(
		Fuel::L_ERROR,
		Fuel::L_WARNING,
		Fuel::L_DEBUG,
		//Fuel::L_INFO,
	),
```

# コントローラー

* CRUD用パッケージ　⇒　[Fuel-Package-TraitCrud](https://github.com/goosys/Fuel-Package-TraitCrud)

```php
```

* Format用パッケージ　⇒　[Fuel-Package-TraitOrmFormat](https://github.com/goosys/Fuel-Package-TraitOrmFormat)

```php
echo $person->age // "12"
echo $person->formatted_age //"12歳"
```

解説ページはこちら ⇒ [FuelPHPのORMをフォーマット出力するパッケージが便利すぎるよ](http://qiita.com/goosys/items/f69c2bc11d619152fa80)

# ヘルパー

* ちょっとした計算とかをさせる 
* こんなの ⇒　```\Helper_Calc::tax( $price )```

# バリデーション

* [valid_stringのエラー時に、使用可能文字を日本語化したい](http://qiita.com/goosys/items/6a3ca075743537380f55)

```shell-session
wget https://gist.githubusercontent.com/goosys/644e48e00af211b9220d/raw/error.php --no-check-certificate -O fuel/app/classes/validation/error.php
```

* [FuelPHPのValidationに直接独自ルールを追加する（PHP>=5.3）](http://qiita.com/goosys/items/d5b0a9e68e145651cb27)

```shell-session
wget https://gist.githubusercontent.com/goosys/cf3882685df3869ce2ed/raw/validation.php --no-check-certificate -O fuel/app/classes/validation.php
```

* [FuelPHPでアップロードファイルをバリデーション](http://qiita.com/goosys/items/def51c4ea1b9b4f0bbea)

```shell-session
wget https://gist.githubusercontent.com/goosys/88165c3ca0d2538c293f/raw/asset.php --no-check-certificate -O fuel/app/classes/validation/asset.php
wget https://gist.githubusercontent.com/goosys/11b72462edbf18086783/raw/uploads.php  --no-check-certificate -O fuel/app/config/uploads.php
wget https://gist.githubusercontent.com/goosys/e6a1d39adad473d871b7/raw/upload.php  --no-check-certificate -O fuel/app/config/upload.php
```

* [FuelPHPでひらがな、カタカナ、ひらカタ混在をバリデーションする](http://qiita.com/goosys/items/1d5fd9a551ea61bb9aa1)

```shell-session
wget https://gist.githubusercontent.com/goosys/d7cb9a3af3381c4866ca/raw/japanese.php --no-check-certificate -O fuel/app/classes/validation/japanese.php
```

# ビューテンプレート

コントローラーで```$this->template->title=```とかやるのが嫌なので、タイトルもビューで設定できるように設定。
その他、ビュー毎の追加CSSやJSにも対応。

```php:fuel/app/views/template.php
<!DOCTYPE html><?php $content = (string) $content;/* コンテンツ部分のViewを先にレンダリング */ ?>
<html>
<head>
	<meta charset="utf-8">
	<title><?php echo View::get('title_bar',__('site.title')); ?></title>

	<?php /* スタイルシートの読み込み　*/ ?>
	<?php Asset::add_path('assets/common/', array('css', 'js', 'img')); ?>
	<?php echo Asset::css('style.css'); /*共通スタイルシート*/ ?>
	<?php echo Asset::render('extra_css'); /*View毎の追加スタイルシート*/ ?>
</head>
<body>
<div class="container"><!-- 共通のHTML構造をあれこれ -->
<?php echo $content; ?>
</div>
	<?php /* 読み込み速度向上のため、スクリプトは後方に記述　*/ ?>
	<?php echo Asset::js('jquery-1.10.2.js'); /*jQuery*/ ?>
	<?php echo Asset::js('bootstrap.min.js'); /*Twitterbootstrap*/ ?>
	<?php echo Asset::js('script.js'); /*共通スクリプト*/ ?>
	<?php echo Asset::render('extra_js'); /*View毎の追加スクリプト*/ ?>
</body>
</html>
```

```php:fuel/app/views/top.php
<?php View::set_global('title_bar','タイトルバーを変更'); ?>
<?php View::set_global('nav_bar','ナビゲーションバーのBrandを変更'); ?>
<?php Asses::js(array('top.js'),array(),'extra_js',false); /* トップページ用のスクリプトを追加 */ ?>
<?php Asses::css(array('top.css'),array(),'extra_css',false); /* トップページ用のCSSを追加 */ ?>
<div>ここからページの内容</div>
```
※もちろん、記述がなければデフォルト値になり、エラーにはなりません。
※参考：[共通のテンプレートにアクション毎に設定できる追加ファイルを読み込ませる](http://qiita.com/kiimiiis/items/c48cb7136ac88c70b724)

# マイグレーション

### 負荷対策

* [FuelPHPでMySQLにインデックスを追加するタスク](http://qiita.com/goosys/items/7b0b7609277871993c2a)

```shell-session
wget https://gist.githubusercontent.com/goosys/01e588dbc15235d4a908/raw/migrate_indexes.php --no-check-certificate -O fuel/app/tasks/migrate_indexes.php
```

# 多言語化

このくらいやっておくと、Viewを機械的に生成できるのでかなり便利。

### ORMの日本語化

* [FuelPHPのORMを日本語化する](http://qiita.com/goosys/items/c3750823523f8e56db56)

```shell-session
cat << EOF > fuel/app/lang/ja/model.php
<?php
return array(
	'model'=>array(
	)
);
EOF
```

### 選択肢の日本語化

* [FuelPHPで選択肢を日本語化する](http://qiita.com/goosys/items/5f34282d96b2bdba315b)

```shell-session
cat << EOF > fuel/app/lang/ja/selector.php
<?php
return array(
);
EOF
```

# ドキュメントルート

### index.php

* [FuelPHPでexec_timeとかmem_usageを出す仕組みが雑すぎると俺の中で話題に](http://qiita.com/moroya/items/62004d7663e96cc79f55)

こんな記事があったので、該当箇所は予め削除。
それか、以下のように開発環境だけで使用する。

```php:public/index.php
// This will add the execution time and memory usage to the output.
// Comment this out if you don't use it.
if ( Fuel::$env !== Fuel::PRODUCTION ){
if (strpos($response->body(), '{exec_time}') !== false or strpos($response->body(), '{mem_usage}') !== false)
{
	$bm = Profiler::app_total();
	$response->body(
		str_replace(
			array('{exec_time}', '{mem_usage}'),
			array(round($bm[0], 4), round($bm[1] / pow(1024, 2), 3)),
			$response->body()
		)
	);
}
}
```

* 500エラーの場合にCatchしてくれないのでするように (500ページは自前で用意する)

```php:public/index.php
catch (HttpServerErrorException $e)
{
	\Request::reset_request(true);

	$route = array_key_exists('_500_', Router::$routes) ? Router::$routes['_500_']->translation : Config::get('routes._500_');

	if($route instanceof Closure)
	{
		$response = $route();

		if( ! $response instanceof Response)
		{
			$response = Response::forge($response);
		}
	}
	elseif ($route)
	{
		$response = Request::forge($route, false)->execute()->response();
	}
	else
	{
		throw $e;
	}
}
catch (HttpNotFoundException $e)
{
```

### .htaccess

* favicon.icoが無い時余計に処理が走ってしまうのを防止

```public/.htaccess
# Send request via index.php (again, not if its a real file or folder)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(favicon\.ico)
```

# テスト

* 環境を指定してテストを実行

```
env FUEL_ENV=test php oil r migrate:down --version=0
env FUEL_ENV=test php oil r migrate
env FUEL_ENV=test php oil r test --group=AppModel
```

# おわり
他、まだあるけど思いついたら書く