しっかり理解する CakePHP Upload プラグインの使い方 (2) View や Controller の修正

この記事を読むのに必要な時間は約 26 分です。


CakePHP で、画像のアップロードやサムネイル作成までを簡単に行える、Upload プラグインについて、使い方をご紹介したいと思います。

今回は、View や Controller の変更・作成について解説したいと思います。

[pn-box color=”lgray”]

Upload プラグインの動作の解説等は以下をご覧下さい。
→ CakePHP Upload プラグインの動作解説 : 画像のアップロードからサムネイル作成まで手軽にできる CakePHP Uploadプラグイン

導入方法や DB 変更、Model の変更・作成については以下をご覧下さい。
→ CakePHP Upload プラグインの使い方 (1) 導入・DB, Model 変更

[pn-box-close]
更新履歴
 2015/07/05 更新 : 正しいURLの取得方法が分かったため、画像の表示用のコードを修正しました。

Behavior の設定は、次回扱いたいと思います。
しっかり理解する CakePHP Upload プラグインの使い方 (3) Behavior の設定


cake-logo

これまでは、各項毎に、既存テーブルへのカラム追加 / 新規テーブル追加 を分けていましたが、今回は、先にそれぞれを分ける構成になります。

それぞれの例については、前回記事 2-1. 既存テーブルへのカラム追加、もしくは、2-2. 新規テーブル追加2-3. 複数カラムを利用する場合 などをご覧下さい。

1. 既存テーブルにカラム追加した場合

1-0. 例のおさらい

例としては、以下のように、users テーブルに photo, photo_dir のカラムを追加した場合です。

CREATE table users (
    `id` int(10) unsigned NOT NULL auto_increment,
    `username` varchar(20) NOT NULL,
    `photo` varchar(255) DEFAULT NULL,
    `photo_dir` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`)
);

1-1. (View) アップロード用の Form の用意

ファイルをアップロードするために、Form を用意します。

今回は、users テーブルにカラム photo, photo_dir を追加した場合のため、例えば app/View/Users/add.ctp に以下を用意します。

<?php echo $this->Form->create('User', array('type' => 'file')); ?>
    <?php echo $this->Form->input('User.username'); ?>
    <?php echo $this->Form->input('User.photo', array('type' => 'file')); ?>
    <?php echo $this->Form->input('User.photo_dir', array('type' => 'hidden')); ?>
<?php echo $this->Form->end(); ?>

ポイントは、以下の点です。

  • 1 行目 Form->create に、 type : file を指定します。これで、ファイルアップロード用の Form に切り替わります。忘れがちですので、ご注意下さい。
  • 3 行目 Behavior で指定したファイル名用のカラムに対応する input で、type : file を指定します。これでファイル選択用のボタンに切り替わります。

4 行目 の photo_dir が hidden で必要なのか少々不明です。無くても動作するのかも知れませんが、document に載っているので、入れておいた方が無難かと思います。

Form Helper を利用していますので、UsersController で Helper の指定もお忘れなく。

<?php
class UsersController extends AppController{
...
  public $helpers = array(
    "Form",
  );
...
}
?>

あとは、UserModel の save() が動作する際に、Behavior の設定によって、自動的に photo にファイル名が、photo_dir にディレクトリ名が登録されます。Controller の変更は不要です。

Update する時などについては、まだ試していないため、省略させていただきます… 。

 

1-2. 保存用ディレクトリベースの用意

保存用ディレクトリのベースを用意しておきます。

デフォルトでは、app/webroot/files/モデル名/カラム名 になります。したがって、例であれば、以下のパスになります。これを web から書き込み可能なパーミションで用意しておきます。

app/webroot/files/user/photo

※ 実際に格納されるのは、Behavior の設定に従い、上記ディレクトリ配下に {photo_dir:ディレクトリ名}/{photo:ファイル名} の形で登録されます。例えば、1/FILE.jpg、2/FILE.jpg … のように格納されます。詳細は、以下の記事をご覧下さい。
→ しっかり理解する CakePHP Upload プラグインの使い方 (3) Behavior の設定

1-3. 画像の表示

画像を表示する際には、例えば以下のようすれば良いかと思います。

$base = $this->Html->url( "/files/user/photo/" );
$this->Html->image( $base . $user["photo_dir"] . "/" . $user["photo"] );
[pn-box color=”lgray” size=”smaller”]

2015/07/05 正しいURLの取得方法が分かったため、以前の無理矢理な相対指定を削除します。

URL の取得方法については、以下の記事で解説しています。
CakePHP 2.x で webroot の URL を取得する方法

[pn-box-close]

以下のコードは以前の記述です。↓ではなく↑のコードを利用して下さい。

/* 以下は古い内容です。こちらではなく、前述の方法を利用して下さい。
$this->Html->image("../files/user/photo/" . $user["photo_dir"] . "/" . $user["photo"] );
*/

これで、<img src=”/x(CakeWebRoot)x/img/../files/user/photo/1/IMAGE01.jpg のように出力されます。

Html Helper の image() は、app/webroot/img からの相対パス指定になるため、美しくないですが、”../” をつけて webroot に移動させています。

 

2. 新規テーブル追加の場合

2-0. 例のおさらい

例としては、以下のように、attachments テーブルを用意し、 attachment カラムに Upload Behavior を適用した場合です。

CREATE table attachments (
    `id` int(10) unsigned NOT NULL auto_increment,
    `model` varchar(20) NOT NULL,
    `foreign_key` int(11) NOT NULL,
    `name` varchar(32) NOT NULL,
    `attachment` varchar(255) NOT NULL,
    `dir` varchar(255) DEFAULT NULL,
    `type` varchar(255) DEFAULT NULL,
    `size` int(11) DEFAULT 0,
    `active` tinyint(1) DEFAULT 1,
    PRIMARY KEY (`id`)
);

リレーションは以下を指定しています。

  • Attachment : belongsTo : Post
  • Attachment : belongsTo : Message
  • Post : hasMany : Image (Attachment)
  • Message : hasMany : Video (Attachment)

() は、エイリアス(=別名) を使って登録しています。

 

2-1. (View) アップロード用 Form の用意

新規テーブル利用であれば、アップロードおよびレコード登録するには、複数の方法が考えられます。

  1. Attachment モデル専用の登録を行う Form を用意
  2. 参照先 (Post、Message) を登録する時に、saveAll() を利用して、まとめて登録

実際の利用場面では、b. のケースが多いかと思います。Post を登録する際に、画像も合わせてアップロードする、というのが自然かと思います。

 

2-1-a. Attachment モデル専用の登録を行う Form を用意する場合

例えば app/View/Attachments/add.ctp で以下のような Form を用意すれば、とりあえず登録することはできます。

<?php echo $this->Form->create('Attachment', array('type' => 'file')); ?>
    <?php echo $this->Form->input('model'); ?>
    <?php echo $this->Form->input('foreign_key'); ?>
    <?php echo $this->Form->input('attachment', array('type' => 'file')); ?>
    <?php echo $this->Form->input('dir', array('type' => 'hidden')); ?>
    <?php echo $this->Form->input('active'); ?>
<?php echo $this->Form->end(); ?>

「1. 既存テーブルへのカラム追加」の場合と同様です。

 

model 名や foreign_key がただのテキスト入力になるため、必要に応じてチェック追加などした方が良いかと思います。

 

2-1-b. 参照先 (Post、Message) を登録する時に、saveAll() を利用してまとめて登録する場合

例えば、app/View/Posts/add.ctp で、以下のような Form を用意します。

<?php
  echo $this->Form->create('Post', array('type' => 'file'));
  echo $this->Form->input('Image.0.attachment', array('type' => 'file', 'label' => 'Image'));
  echo $this->Form->input('Image.0.model', array('type' => 'hidden', 'value' => 'Post'));
  /* … その他 Post のフィールド用 Form (省略) … */
  echo $this->Form->end(__('Add'));
?>

ポイントは、以下の通りです。

  • 2 行目 Form->createtype : file を指定します。
  • 3 行目 Behavior を適用する attachment の input にも type : file を指定します。
  • 3-4 行目 第一引数を “Image.0.カラム名” の形にします。
    • “Image” は、Post モデルで hasMany を登録した際のエイリアス名に合わせます
      ( Post -> hasMany -> Attachment であれば、Image ではなく Attachment を指定します )
    • “0” は固定です。これで Controller は $this->request->data[“Image”][0][カラム名] … といった感じで受け取れ、PostModel->saveAll() で扱えます。
    • もし、同時に n件 (Attachment を nレコード) 登録するならば、Image.1.カラム名, Image.2.カラム名 … といった感じで、並べて追加しておけば可能だと思います。

 

2-2. (Controller) save() メソッドの修正

2-2-a. Attachment モデル専用の登録を行う Form を用意する場合

特別な変更は不要です。普通に AttachmentsController で、

$this->Attachment->save( $this->request->data );

などで登録可能です。

 

2-2-b. 参照先 (Post、Message) を登録する時に、saveAll() を利用してまとめて登録する場合

app/Controller/PostsController.php を修正します。

$this->Post->save($this->request->data);
↓
$this->Post->saveAll($this->request->data);

saveAll は、(正しい形で入っていれば) リレーションの先のテーブルもまとめて登録してくれます。便利ですが、問題発生時の切り分けが大変にはなりますので、ご注意下さい。

 

2-3. 保存用ディレクトリの用意

この辺りは、1-2. と同じです。

保存用ディレクトリのベースを用意しておきます。

app/webroot/files/モデル名/カラム名 がデフォルトですので、以下のパスになります。これを web から書き込み可能なパーミションで用意しておきます。

app/webroot/files/attachment/attachment

※ 実際に格納されるのは、Behavior の設定に従い、上記ディレクトリ配下に {dir:ディレクトリ名}/{name:ファイル名} の形で登録されます。例えば、1/FILE.jpg、2/FILE.jpg … のように格納されます。詳細は、以下の記事をご覧下さい。
→ しっかり理解する CakePHP Upload プラグインの使い方 (3) Behavior の設定

2-4. 画像の表示

画像を表示する際には、例えば以下のようすれば良いかと思います。

$base = $this->Html->url( "/files/attachment/attachment/" );
$this->Html->image( $base . $post["Image"][$i]["dir"] . "/" . $post["Image"][$i]["attachment"] );

$i  は、1:多 で複数登録を想定しているためです。DB から取得された内容に合わせて、$post[“Image”] 等のループで回して下さい。 画像が 1 件のみ紐づくのであれば、0 固定で出来るかと思います。

 

[pn-box color=”lgray” size=”smaller”]

2015/07/05 正しいURLの取得方法が分かったため、以前の無理矢理な相対指定を削除します。

URL の取得方法については、以下の記事で解説しています。
CakePHP 2.x で webroot の URL を取得する方法

[pn-box-close]

以下のコードは以前の記述です。↓ではなく↑のコードを利用して下さい。

/* 以下は古い記述です。↑の記述を利用して下さい。
$this->Html->image("../files/attachment/attachment/" . $post["Image"][$i]["dir"] . "/" . $post["Image"][$i]["attachment"] );
*/

 

3. 複数カラムを追加した場合

3-0. 例のおさらい

users テーブルに icon, bg, dir カラムを追加した場合です。

CREATE table users (
    `id` int(10) unsigned NOT NULL auto_increment,
    `username` varchar(20) NOT NULL,
    `icon` varchar(255) DEFAULT NULL,
    `bg` varchar(255) DEFAULT NULL,
    `dir` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`)
);

 

3-1. (View) アップロード用 Form の用意

ファイルをアップロードするために、Form を用意します。

今回は、users テーブルにカラム icon, bg, dir を追加した場合のため、例えば app/View/Users/add.ctp に以下を用意します。

<?php echo $this->Form->create('User', array('type' => 'file')); ?>
    <?php echo $this->Form->input('username'); ?>
    <?php echo $this->Form->input('icon', array('type' => 'file')); ?>
    <?php echo $this->Form->input('bg', array('type' => 'file')); ?>
    <?php echo $this->Form->input('dir', array('type' => 'hidden')); ?>
<?php echo $this->Form->end(); ?>

ポイントは、以下の点です。

  • 2,3 行目 type : file な input を icon 用、bg 用、それぞれに用意します。
  • 5 行目 dir 用の hidden な input は 1 つのみで OK です。

 

3-2. 保存用ディレクトリの用意

保存用ディレクトリのベースを用意しておきます。

デフォルトでは、app/webroot/files/モデル名/カラム名 になります。したがって、例であれば、以下のパスになります。これを web から書き込み可能なパーミションで用意しておきます。

app/webroot/files/user/icon
app/webroot/files/user/bg

※ 実際に格納されるのは、Behavior の設定に従い、上記ディレクトリ配下に {dir:ディレクトリ名}/{icon、bg :ファイル名} の形で登録されます。例えば、以下のようにファイルが生成されます。

  • 1 件目 : icon/1/icon-file.jpg・bg/1/bg-file.jpg
  • 2 件目 : icon/2/icon-file.jpg・bg/2/bg-file.jpg

詳細は、以下の記事をご覧下さい。
→ しっかり理解する CakePHP Upload プラグインの使い方 (3) Behavior の設定

 

3-3. 画像の表示

画像を表示する際には、例えば以下のようすれば良いかと思います。

$base = $this->Html->url( "/files/user/" );
$this->Html->image($base . "icon/" . $user["dir"] . "/" . $user["icon"] );
$this->Html->image($base . "bg/" . $user["dir"] . "/" . $user["bg"] );

 

[pn-box color=”lgray” size=”smaller”]

2015/07/05 正しいURLの取得方法が分かったため、以前の無理矢理な相対指定を削除します。

URL の取得方法については、以下の記事で解説しています。
CakePHP 2.x で webroot の URL を取得する方法

[pn-box-close]

以下のコードは以前の記述です。↓ではなく↑のコードを利用して下さい。

/* 以下は古い記述です。↑の記述を利用して下さい。
$this->Html->image("../files/user/icon/" . $user["dir"] . "/" . $user["icon"] );
$this->Html->image("../files/user/bg/" . $user["dir"] . "/" . $user["bg"] );
*/

 

ひとこと

今回で、実際のアップロードまで出来るようになったかと思います。

次回は、Upload Behavior の設定について扱いたいと思います。

楽しみにお待ちいただければ幸いです。

[pn-box color=”lgray”]

次の記事は、以下になります。良かったら以下もご覧下さい。
しっかり理解する CakePHP Upload プラグインの使い方 (3) Behavior の設定

[pn-box-close] [pn-cakephp-env plugins=”true”]

今回は以上です。


[pn-amzn-cakephp]

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です