Logicky Blog

Logickyの開発ブログです

cakePHP 2.3 ファイルアップロード - FileBinderプラグイン

最初、FileBinderを使おうと思ったが、uploadのが人気ありそうなので、uploadを使ってみようと思った。しかし結局日本人が作ってるし、まだ元気なプラグインだとどこかに書いてあったのでFileBinderを使うことにした。こっちのが書くこと少なくてすみそうだったし。

FileBuinderの参考: CakePHPの超便利なファイルアップロードプラグイン、FileBinderプラグインの使い方をまとめてみた。 FileBinderプラグイン

uploadの参考: cakePHP 2.x 画像アップロードプラグイン“upload”の使い方

CREATE TABLE `attachments` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `model` text NOT NULL,
 `model_id` int(11) NOT NULL,
 `field_name` text NOT NULL,
 `file_name` text NOT NULL,
 `file_content_type` text NOT NULL,
 `file_size` int(11) NOT NULL,
 `file_object` longtext,
 `created` datetime DEFAULT NULL,
 `modified` datetime DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
<?php
App::uses('AppModel', 'Model');

class User extends AppModel {
    public $actsAs = array('Filebinder.Bindable');
    public $displayField = 'username';

    public $bindFields = array(
        array('field' => 'photo')
    );

    public $validate = array(
        'username' => array('notempty'),
        'photo' => array(
            'allowExtention' => array(
                'rule' => array('checkExtension', array('jpg','pdf')),
                'message' => '拡張子が無効です',
                'allowEmpty' => true
            ),
            'fileSize' => array(
                'rule' => array('checkFileSize', '1MB'),
                'message' => 'ファイルサイズが1MBを超過しています'
            ),
            'illegalCode' => array(
                'rule' => array('funcCheckFile', 'checkIllegalCode'),
                'allowEmpty' => true
            )
        )
    );

    /**
    * checkIllegalCode
    * check include illegal code
    *
    * @param $filePath
    * @return
   */
    public function checkIllegalCode($filePath){
        $fp = fopen($filePath, "r");
        $ofile = fread($fp, filesize($filePath));
        fclose($fp);

        if (preg_match('/<\\?php./i', $ofile)) {
            return false;
        }
        return true;
    }
}
?>
<?php
App::uses('AppController', 'Controller');

class UsersController extends AppController {
    public $components = array('Session', 'Filebinder.Ring');

    //ユーザ登録画面
    public function index(){
        if($this->request->is('post')){
            $this->Ring->bindUp();
            $this->log($this->request->data);
            if($this->User->save($this->request->data)){
                $this->Session->setFlash('登録完了しました');
            }else{
                $this->Session->setFlash('登録が失敗しました');
            }
        }
    }

    //ユーザ一覧画面
    public function view(){
        $this->set('users',$this->User->find('all'));
    }
}
<h2>ユーザー登録</h2>
<div class="posts form">
  <?php echo $this->Form->create('User', array('action' => 'index', 'type' => 'file'));?>
  <?php echo $this->Form->input('username', array('type' => 'text'));?>
  <?php echo $this->Form->input('photo', array('type' => 'file'));?>
  <?php echo $this->Form->submit(__('Submit', true));?>
  <?php echo $this->Form->end();?>
</div>
<h2>ユーザー一覧</h2>
<?php foreach($users as $u):?>
<table>
<tr><td>名前</td><td><?php echo $u['User']['username']?></td></tr>
<tr><td>添付ファイル(ダウンロード)</td><td><?php echo $this->Label->link($u['User']['photo'])?></td></tr>
</table>
<?php endforeach;?>

/ 追記 /

ただいま2013年5月31日です。 上記のFileBinderに関しまして超ウルトラスーパーはまったので追記します。 上記と同様にコードを書いているつもりなのに一向にうんともすんともいわない状況が続いておりました。 $this->Ring->bindUp();を実行しても、$this->request->dataのファイルの内容が変わらない状態です。 なぜだか全く分からなかったのですが、$this->Ring->bindUp('モデル名');とやると、解決しました。 どーして書かなくてもOKな場合と、NGな場合に分かれるのか分かりませんが、今度調べるとして、モデル名はしっかり書くようにしようと思った次第です。