2009/02/09

How to File Upload with Ethna?

http://blog.cypher-works.com/?p=169

上記は Ethnaと組み合わせてファイルアップロードの処理を説明している。

だが、アップロードされた値を検証するのにくどくど長いコードが書いてあり、Ethnaのウリであるフォーム定義をまったく理解していないといわざるを得ない。

上記のような処理は、Ethna では、以下のようにすれば簡単にできる。コアは フォーム定義と、$this->af->validate() だ。

尚、以下のコードは安定版である 2.3.6 を前提にしている。
$ ethna add-project sample
$ cd sample
$ ethna add-action upload
$ ethna add-view -t upload

app/action/Upload.php を以下のように編集する
class Sample_Form_Upload extends Sample_ActionForm
{
/** @var bool バリデータにプラグインを使うフラグ */
var $use_validator_plugin = true;

var $form = array(
'sample' => array(
// ファイルアップロードのフォーム定義
// 複数アップロードしない場合は、'type' の array を外すこと
'type' => array(VAR_TYPE_FILE), // 入力値型
'form_type' => FORM_TYPE_FILE, // フォーム型
'name' => 'アップロードされるファイル', // 表示名

// バリデータ(記述順にバリデータが実行されます)
'required' => true, // 全てのアップロードが必須
'min' => '50', // 50KB「以上」のファイルが必要
'max' => '100', // 100KB「以下」のファイルが必要
),
);
}

class Sample_Action_Upload extends Sample_ActionClass
{
function prepare()
{
// フォーム定義に従ってアップロードしたファイルを検証
// エラーの場合は元の画面に戻り、エラーを表示する
// いちいち $this->af->get したものをループして全部確かめる
// 必要は全くない
if ($this->af->validate() > 0) {
return 'upload';
}
return null;
}

function perform()
{
// 検証済みのアップロードファイルの中身を取り出し、
// 一時ファイルに保存
$files = $this->af->get('sample');
$photo_ids = array();
foreach ($files as $idx => $file_info) {
// アップロードされている場合のみ、一時ファイルに保存
if ($file_info['error'] != UPLOAD_ERR_NO_FILE) {
$tmp_name = $file_info['tmp_name'];
$tmp_name_new = sha1($tmp_name);
// アップロードされたファイルを /tmp 以下に保存
// 別アクションで、$tmp_name_new を引数としてファイルを
// 見せるようにすれば、アップロードファイルの
// 確認画面も作ることができる
move_uploaded_file($tmp_name, '/tmp/' . $tmp_name_new);
$photo_ids[$idx]['new_tmp'] = $tmp_name_new;
}
}
// 保存したファイル名をフォームに設定する
// テンプレート側では、$form.sample で値が見える
$this->af->set('sample', $photo_ids);
}
}

template/ja/upload.tpl では、以下のようにする。{form_input} や {form} という Smartyタグは、Ethna組み込みの「フォームヘルパ」と呼ばれるもので、ethna_action で指定したフォーム定義にあわせて、入力フォームを自動で生成してくれる。この機能を知らなかった人は、マニュアルをよく読むこと!

ファイルアップロード用なので、{form} タグで、enctype="file" としているのに注意。

{if count($errors)} {* エラーで戻ってきた場合のメッセージ *}
{foreach from=$errors item=error}
{$error}
{/foreach}
{/if}
{* アップロードのフォーム *}
{form ethna_action="upload" enctype="file"}
{form_input name="sample"}
{form_input name="sample"}
{form_submit value="アップロード"}
{/form}


こうした上で、 index.php?action_upload=true にアクセスすれば、以下のような画面が見えるはずだ。50KB以上、100KB以下のファイルを全てアップロードしないとエラーになる。エラーが出なかったら、/tmp 以下にファイルが保存されているのを確認できるはず。


0 件のコメント: