Yii で 画像の処理、操作ができる Intervention Image Class を使ってみた。

## Yii と Intervention Image Class を Composer でインストール

~~~
mkdir testproject
cd testproject
vi composer.json
~~~

~~~composer.json
{
    "require": {
        "yiisoft/yii": "1.1.*",
        "intervention/image": "dev-master"
    }
}
~~~

~~~
composer install
./vendor/bin/yiic webapp .
~~~

あと index.php で vendor/autoload.php を読み込む。

~~~index.php
<?php
// change the following paths if necessary
$yii = dirname(__FILE__).'/vendor/yiisoft/yii/framework/yii.php';
$config = dirname(__FILE__).'/protected/config/main.php';

// remove the following lines when in production mode
defined('YII_DEBUG') or define('YII_DEBUG', true);
// specify how many levels of call stack should be shown in each log message
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', 3);

require_once($yii);
require 'vendor/autoload.php'; // 追加
Yii::createWebApplication($config)->run();
~~~

## モデル、コントローラ、ビューの作成

データベースの作成、設定を済ませておく。
とりあえず item テーブルを作成、カラムは id, title, image 。
Gii でモデルとコントローラ、ビューを生成。


**モデルにバリデーションルールを追加**
ファイル形式は png, jpg のみで、サイズは 1MB まで。

~~~Item.php
<?php
class Item extends CActiveRecord
{
    ...
    public function rules()
    {
        return array(
            ...
            array(
                'image',
                'file',
                'safe' => true,
                'types' => 'png,jpg',
                'mimeTypes' => 'image/png, image/x-png, image/jpeg, image/pjpeg',
                'maxSize' => 1024 * 1024 * 1,
                'on' => 'insert'
            ),
        );
    }
}
~~~

**コントローラに actionCreate() を追加**

今回は、画像を /images/ にアップロードしたあと、リサイズして上書きし、
データベースには画像のファイル名が挿入される形を取ります。

~~~ItemController.php
<?php
use Intervention\Image\Image;

class ItemController extends Controller
{
    ...
    public function actionCreate()
    {
        $item = new Item();

        if (isset($_POST['Item'])) {
            $item->attributes = $_POST['Item'];

            if ($item->validate()) {
                $image = CUploadedFile::getInstance($item, 'image');

                $item->image = sha1(microtime() . mt_rand()) . '.' . $image->extensionName;
                // /images/ に画像をアップロード
                $image->saveAs(Yii::app()->basePath . '/../images/' . $item->image);

                // アップロードした画像をリサイズして上書き
                Image::make('images/' . $item->image)
                    ->resize(170, null, true)
                    ->save('images/' . $item->image);

                $item->save(false);

                $this->redirect(array('index'));
            }
        }
        $this->render('create', compact('item'));
    }
    ...
~~~

**ビュー**

~~~create.php
<div class="form">
    <?php echo CHtml::form('', 'post', array('enctype' => 'multipart/form-data')); ?>

    <div class="row">
        <?php echo CHtml::activeLabel($item, 'title'); ?>
        <?php echo CHtml::activeTextField($item, 'title'); ?>
        <?php echo CHtml::error($item, 'title'); ?>
    </div><!-- /.row -->

    <div class="row">
        <?php echo CHtml::activeLabel($item, 'image'); ?>
        <?php echo CHtml::activeFileField($item, 'image'); ?>
        <?php echo CHtml::error($item, 'image'); ?>
    </div><!-- /.row -->

    <div class="row buttons">
        <?php echo CHtml::submitButton('追加'); ?>
    </div><!-- /.row buttons -->

    <?php echo CHtml::endForm(); ?>
</div><!-- /.form -->
~~~

## まとめ

Yii には [image](http://www.yiiframework.com/extension/image/) という extension で同じようなことができるんですが、
なんか更新されていない雰囲気なので、
良いのがないかなと思って [Intervention Image Class](http://intervention.olivervogel.net/) を使ってみました。
Laravel 4 ではもっと使いやすくなってるみたいです。