8月 282014
 

こんばんは。やっとPHPStormのXdebugでのリモートデバッグが出来るようになったファガイです。
そこで、LaravelのアップロードパッケージのLaravel-Staplerにて画像を保存する際に別の文字列に変換して保存する方法を色々情報を見つけつつ実装できたのでまとめます。

まずはじめに

まず、元のパッケージのstaplerには名前変更機能が付いていません。

近い話として

CodeSleeve/stapler Filename Slug #34

上記のように空白を別文字列に変換するSlugを入れる話があるので、こちらを参考にしています。

なお、関係ありませんがLaravelのSlugはどうも日本語に対応していない模様です。

前提

今回は前回の記事で紹介したモデルを例として利用します。

Laravel4のアップロードパッケージ、Laravel-Staplerを使ってみる

use Codesleeve\Stapler\ORM\StaplerableInterface;
use Codesleeve\Stapler\ORM\EloquentTrait;

class User extends Eloquent implements StaplerableInterface {
    use EloquentTrait;

    ...略

    protected $fillable = ['avatar'];

    public function __construct(array $attributes = array()) {
        $this->hasAttachedFile('avatar', [
            'styles' => [
            'medium' => '300x300',
            'thumb' => '100x100'
            ]
        ]);

        parent::__construct($attributes);
    }
}

これですね。分かりやすくしてるので、まあ大丈夫でしょう。

実装

実装結果です。

[php highlight_lines=”24,25,26,27,28,29,30,31,32,33,34,35,36,37″]
use Codesleeve\Stapler\ORM\StaplerableInterface;
use Codesleeve\Stapler\ORM\EloquentTrait;

class User extends Eloquent implements StaplerableInterface {
use EloquentTrait;

...略

protected $fillable = ['avatar'];

public function __construct(array $attributes = array()) {
    $this->hasAttachedFile('avatar', [
        'styles' => [
        'medium' => '300x300',
        'thumb' => '100x100'
        ]
    ]);

    parent::__construct($attributes);
}

public static function boot()
{
    parent::boot();

    static::bootStapler();

    static::saving(function(User $model){
        if($model->avatar->getUploadedFile() !== null)
        {
            setlocale(LC_ALL, 'ja_JP.UTF-8'); // locale指定

            $pathInfo = pathinfo($model->avatar->originalFilename());
            $newFilename = md5($pathInfo['filename']) . '.' . $pathInfo['extension'];
            $model->avatar->instanceWrite('file_name', $newFilename);
        }
    });
}

}
“`

解説

基本的に追加した部分はbootメソッドを追加したことです。

詳しく解説していきます。

parent::boot();
static::bootStapler();

親のbootメソッドを呼んでいます。また、EloquentTraitでbootメソッドが作られているため、そちらの内容のstatic::booStapler()を追加記述しています。
このstatic::bootStraplerを忘れるとファイルを保存してくれませんので注意しましょう。

static::saving

こちらはモデルイベントです。詳しくは

Laravel Eloquent ORM

上記のモデルイベントを参照して下さい。

setlocale(LC_ALL, 'ja_JP.UTF-8'); // locale指定

$pathInfo = pathinfo($model->avatar->originalFilename());
$newFilename = md5($pathInfo['filename']) . '.' . $pathInfo['extension'];
$model->avatar->instanceWrite('file_name', $newFilename);

イベントの中のこの4つ。setlocaleを呼んでいる理由はpathinfoメソッドが日本語含むファイル名だと使用できなかったからです。(日本語が無くなる)

attachedFilesはconstructorで指定していたattachしているファイルリストです。今回はavatarだけなので、直指定し、オリジナルのファイル名を取得しています。

その後新しいファイル名を決めてます。今回はmd5を使用していますがここは臨機応変に行えば良いかと。

最後に画像の名前を変更して終わりですね。意外と難しくなかった。時間は1時間半くらい掛かってしまったけど・・・w

まとめ

Laravelの強力さを再度確認することになりました。やっぱりフレームワークを理解しているかしてないかは大きくスピードを左右するのではないかと思います。

ではではー。

追記(2014/08/29 22:40)

先程やっていてバグがあったことに気づいたので記事の修正を行いました。

内容としてはsaving中の処理です。getUploadedFileメソッドを使用しアップロードがあったかどうかを判断しています。この判定が無いとアップロード無しの更新が走った際にもこのメソッドを通ってしまうのでバグとなっておりました。
ついでに、attachedFilesは必要なかったので削除してます。

Pocket

 Posted by at 2:59 AM

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*