CakePHP3.6で以下のような仕様の画面を実装しようとしています。
- itemsテーブルに登録したitemに対して画像を任意で何枚でも登録できる
- 画像はitem_imagesテーブルに保存される
item_images
id | item_id | filename |
---|---|---|
1 | 1 | item1_a.png |
2 | 1 | item1_b.png |
3 | 2 | item2_a.png |
画像アップロードはJosegonzalez/Uploadというプラグインを用いて実装しました。
バリデーションを考えなければアップロード自体はできています。
(なおファイルの登録は任意で、1枚も選択しなくてもよく上限枚数もありません)
これに対して以下のバリデーションを実装したいです
- アップロードする場合はpng形式のみ
- 同じ商品に対して同じ名前の画像ファイルを登録できない(iItem_idとfilenameの重複を許可しない)
item編集のビューファイルで複数ファイルアップロードのフォーム
php
1// items/edit.ctp 2<?php echo $this->Form->control('item_images[].filename', [ 3 'type' => 'file', 4 'multiple', 5 ]);?>
コントローラー
php
1// itemsController.php 2 public function edit($id = null) 3 { 4 if(!$id){ 5 $item = $this->Items->newEntity(); 6 }else{ 7 $item = $this->Items->get($id, [ 8 'contain' => ['itemImages'] 9 ]); 10 } 11 if ($this->request->is(['patch', 'post', 'put'])) { 12 // ファイルを1つも選択しなかった時にitem_imagesに空のファイル名が保存されるのを防止 13 if(!$request['item_images'][0]['filename']['tmp_name']){ 14 unset($request['item_images']); 15 } 16 17 $item = $this->Items->patchEntity($item, $this->request->getData()); 18 $ret = $this->Items->save($item); 19 if ($ret) { 20 $this->Flash->success(__('詳細画面を保存しました。')); 21 22 return $this->redirect(['action' => 'index']); 23 } 24 $this->Flash->error(__('詳細画面の保存に失敗しました。再度お試しください。')); 25 } 26 }
テーブル
php
1// itemImagesTable.php 2 public function validationDefault(Validator $validator) 3 { 4 $validator->provider('upload', \Josegonzalez\Upload\Validation\DefaultValidation::class); 5 6 $validator 7 ->integer('id') 8 ->allowEmpty('id', 'create'); 9 10 $validator 11 ->allowEmpty('filename') 12 ->add('filename', 'fileSuccessfulWrite', [ 13 'rule' => 'isSuccessfulWrite', 14 'message' => 'アップロードできませんでした', 15 'provider' => 'upload', 16 ]) 17 ->add('filename', 'fileExtension', [ 18 'rule' => ['extension', ['png']], 19 'message' => 'アップロードできるファイル形式はpngのみです', 20 ]); 21 22 return $validator; 23 }
この状態で以下の問題があります
- エラーメッセージが出せない
- 同じ名前のファイルをアップできないバリデーションができていない
1についてはファイルを複数アップロードするとそれぞれに対してバリデーションが行われ、アップしたファイルそれぞれにエラーが返されるため、$this->Form->controlのデフォルトではエラーが表示されないようです。
「test3.jpg:アップロードできるファイル形式はpngのみです」
のような形でファイルごとにエラーを表示させる方法があればご教授頂けると幸いです。
2については
php
1// itemImagesTable.php 2 public function buildRules(RulesChecker $rules) 3 { 4 $rules->add($rules->isUnique(['item_id', 'filename'], '同名のファイルが既にアップロードされています。')); 5 return $rules; 6 }
のようにやれると公式ドキュメントにありましたが、おそらくプラグインを利用しているためリクエストデータ(画像2枚アップロード時)に
'item_images' => [ (int) 0 => [ 'filename' => [ 'tmp_name' => '/tmp/phpB5Wbc7', 'error' => (int) 0, 'name' => 'test.png', 'type' => 'image/png', 'size' => (int) 20498 ] ], (int) 1 => [ 'filename' => [ 'tmp_name' => '/tmp/phpV6Bnzb', 'error' => (int) 0, 'name' => 'test3.jpg', 'type' => 'image/jpeg', 'size' => (int) 20636 ] ] ]
のようにfilenameに配列が入ってしまい、これではうまくできないようでした。
上記2点についてどちらかでも構いませんので回答いただけるとありがたいです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。