どうも、Uploadをすると、Uploadクラスのバリデーションを使うことになりますが、これとfieldsetのValidationクラスとの連動がいまいちうまくできない。Fieldsetはform.phpの、inline_errorsをtrueにすると勝手にエラーを表示してくれるが、このエラーに自動的にuploadのエラーも連動するようにしたい。他にやり方があるかもしれないが、Upload関連のエラーをValidationのカスタマイズルールとして作成することで、実現してみる。
モデルでFieldsetを作成する
fileというフィールドに、uploadというルールを設定している。これはデフォルトではないので、カスタマイズルールになります。引数は、フィールド名。あとでこのuploadというルールを作成します。
public static function fieldset() { //大カテゴリー取得 $big_categories = Model_Category::get_big_category_list(); $fset = Fieldset::forge(); $fset->add('file', '動画ファイル', array('type' => 'file'))->add_rule('upload', 'file'); $fset->add('title', 'タイトル')->add_rule('required')->add_rule('max_length', 150); $fset->add('description', '説明', array('type' => 'textarea'))->add_rule('required')->add_rule('max_length', 500); $fset->add('big_category_id', '大カテゴリー', array('type' => 'select', 'options' => $big_categories)); $fset->add('category_id', '小カテゴリー', array('type' => 'select'))->add_rule('required'); $fset->add('order_no', '表示順')->add_rule('required')->add_rule('numeric_between', 1, 100); return $fset; }
カスタムバリデーションのクラスファイルを作成する
fuel/app/classes/model/validation/upload.phpというのを作成してみる。
<?php class Model_Validation_Upload { public static function _validation_upload($field_name) { if(Upload::is_valid()) { Upload::save(); return true; } else { $error = Upload::get_errors($field_name); if(!empty($error['errors'][0]['message'])) { Validation::active()->set_message('upload', $error['errors'][0]['message']); }else{ Validation::active()->set_message('upload', 'ファイルのアップロードでエラーが発生しました'); } return false; } } }
コントローラを作成する
フィールドセットを作って、Upload:processを走らせて、フィールドセットからバリデーションを取りだして、バリデーションにuploadルールを読めるように設定する。
public function action_add() { //フィールドセットの取得 $fset = Model_Movie::fieldset(); if (Input::post()){ Upload::process(); // バリデーションチェック $val = $fset->validation(); $val->add_callable('Model_Validation_Upload'); if( $val->run() ){ //動画情報をデータベースに登録 $file = Upload::get_files( 0 ); if( Model_Movie::add( Input::post(), $file ) ){ Session::set_flash( 'msg', '動画を登録しました。' ); return Response::redirect( 'admin/movies/' ); }else{ //保存ファイルの削除 File::delete( DOCROOT . 'assets/movie/' . $file[ 'saved_as' ] ); } } //小カテゴリのoptionsの取得・設定 $big_id = Input::post( 'big_category_id' ); $fset = Model_Category::set_small_cat_options( $big_id, $fset ); $fset->repopulate(); Session::set_flash( 'msg', '動画が登録できませんでした。恐れ入りますが、再度お試しください。' ); } //set view $this->template->content = View::forge('admin/movies/add'); $this->template->content->set_safe('fset', $fset); }
View
uploadは、enctypeの表示が必要。Fieldsetのフィールドをbuildしてるだけ。bootstrapを使っているので、set_attributeでform-controlクラスを設定している。
<?php echo Form::open(array('enctype' => 'multipart/form-data'))?> <?php echo $fset->field('file')->set_attribute('class', 'form-control')->build()?> <?php echo $fset->field('title')->set_attribute('class', 'form-control')->build()?> <?php echo $fset->field('description')->set_attribute('class', 'form-control')->build()?> <?php echo $fset->field('big_category_id') ->set_attribute('class', 'form-control') ->set_attribute('onchange', 'get_small_cat("' . Uri::create('rest/admin/categories/small_cat.json') . '");') ->build()?> <?php echo $fset->field('category_id')->set_attribute('class', 'form-control')->build()?> <?php echo $fset->field('order_no')->set_attribute('class', 'form-control')->build()?> <button type="submit" class="btn btn-primary">登録</button> <?php echo Html::anchor('admin/movies/', 'キャンセル', array('class' => 'btn btn-default'))?> <?php echo Form::close()?>