stackoverflowなどを見ているとCakePHP3の画像アップロードにはCakeManagerが良いらしいですね。
ちょっと使ってみたのですが、installationとUploadable-Behaviorを参考にmodelとtemplateに設定すると簡単に画像のアップロードが行えるようになりました。画像の更新(置き換え)や元となるデータを削除した場合も連動して削除してくれるなど機能的に申し分ないです。
しかし、更新画面等で既にアップロード済みの画像を変更することなく(つまり未指定)他のデータを更新した場合、デフォルトでは画像が削除されてしまいます。以下はその時に対処したメモです。
modelの該当カラムでremoveFileOnUpdateをfalseにします。
$this->addBehavior('Utils.Uploadable', [
'main_image' => [
'field' => 'id',
'fileName' => '{field}.{extension}',
'removeFileOnUpdate' => false, // ここをfalseにする
'removeFileOnDelete' => true,
'fields' => [
'directory' => 'main_image_directory',
'url' => 'main_image_url',
'type' => 'main_image_type',
'size' => 'main_image_size',
'fileName' => 'main_image_name',
'filePath' => 'main_image'
],
],
]);
modelに対応するcontrollerのeditアクションで、画像がアップロードされているかをサイズで判断し、更新するフィールドを振り分けます。
public function edit($id = null)
{
...
if ($this->request->is(['patch', 'post', 'put'])) {
// 画像の有無により更新するフィールドを分ける
$size = $this->request->data['main_image']['size']; // imageのサイズを取得
if($size > 0){
// imageあり 全フィールド更新
$mymodel = $this->MyModel->patchEntity($mymodel, $this->request->data);
}else{
// imageなし main_imageフィールドを除外
$mymodel = $this->MyModel->patchEntity($mymodel, $this->request->data,
['fieldList' => ['title', 'comment', 'published_date', 'modified']
]);
}
...
}
...
}
controllerで更新フィールドを除外するだけでうまくいきそうな感じですが、modelでremoveFileOnUpdateをfalseにしないと削除されてしまいます。
また、配列のメソッドなどを駆使すれば、該当の画像カラムを除外したカラム名配列を作ることができると思うのですが、それほど詳しくないのでここまでです。あと、アップロード済みの画像の削除は今後試す予定です。