CakePHP3のUpload Plugin 3.0をバリデーションなど実運用向けのカスタマイズ方法解説・その2
2017/11/26
CakePHP3にファイルアップロードプラグイン Upload Plugin 3.0をカスタマイズする方法
この記事は、CakePHP3でファイルや画像をアップロードするプラグイン「Upload Plugin 3.0」の解説記事の 3本立てのうちの「その2」です。
Upload Plugin 3.0の基本的な設置方法を解説した記事は下記にありますので、基本的な設置方法から理解したい場合は、下記の記事から読んでください。
CakePHP3の画像、ファイルアップロードプラグインUpload Plugin 3.0の設置解説・その1
この記事では、基本的な設置方法を踏まえたうえで、アップロードする画像、ファイルのバリデーションや、アップロードするファイルを複数にする場合や、記事を削除したときに画像も一緒に削除する処理など、実用的な利用を想定したカスタマイズ方法を解説していきます。
CakePHP3のUpload Plugin 3.0をバリデーションなど実運用向けのカスタマイズ方法解説・その2
最後の記事では、2記事までで解説した画像を新規登録でアップロードする処理に続く処理として、記事を更新する際の処理、および、登録した画像を表示する処理について解説します。
CakePHP3の更新画面でUpload Plugin 3.0を使う方法、viewで使う方法解説・その3
というわけで、ここから先は実用に即した形でカスタマイズする方法を紹介します。
また、サンプルのソースコードは、「CakePHP3の画像、ファイルアップロードプラグインUpload Plugin 3.0の設置解説・その1」で紹介したソースコードの一部をカスタマイズする前提で書いていますので、全体のソースコードは「CakePHP3の画像、ファイルアップロードプラグインUpload Plugin 3.0の設置解説・その1」を参照してください。
ちなみに、ファイルのアップロード処理は、PHP自体がサポートしていますので、プラグインを使わなくても比較的簡単に実装することができます。
その CakePHP3でファイルのアップロード処理を自作した際の、ソースコード付きの解説記事を下記で書いていますので合わせて参考にしてみてください。
CakePHP3でファイルのアップロード処理を自作・解説付き・その1
CakePHP3で画像・ファイルのアップロード処理を自作・解説付き・その2
ファイルアップロード処理の理解のために読んでみるのもいいかもしれません。
複数のファイルをアップロードしたい!
先に説明した内容は、アップロードするファイルが 1つだけでしたが、複数のファイルをアップロードする処理も構築が可能です。
3.画像データを保存するカラムをテーブルに追加
アップロードする画像を保存するカラムを設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
mysql> show columns from topics; +--------------------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------------+------------+------+-----+---------+----------------+ : : | image1 | text | YES | | NULL | | | image1_path | text | YES | | NULL | | | image1_type | text | YES | | NULL | | | image1_size | int(11) | YES | | NULL | | | image2 | text | YES | | NULL | | | image2_path | text | YES | | NULL | | | image2_type | text | YES | | NULL | | | image2_size | int(11) | YES | | NULL | | |
「image1」「image2」のファイルに対して、それぞれ「保存フォルダのパス」「ファイルのタイプ」「ファイルのサイズ」を設定しています。
5.モデルクラスにプラグインを利用する処理を追記
モデルのクラスにファイルをアップロードする情報を追記します。
(「$this->addBehavior()」の部分のみ記載しています。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Upload Plugin $this->addBehavior('Josegonzalez/Upload.Upload', [ 'image1' => [ 'fields' => [ 'dir' => 'image1_path', 'type' => 'image1_type', 'size' => 'image1_size', ] ], 'image2' => [ 'fields' => [ 'dir' => 'image2_path', 'type' => 'image2_type', 'size' => 'image2_size', ] ], ]); |
デフォルト設定では以下の設定になっています。
1 2 3 4 5 6 7 8 9 10 |
// Upload Plugin $this->addBehavior('Josegonzalez/Upload.Upload', [ 'image' => [ 'fields' => [ 'dir' => 'dir', 'type' => 'type', 'size' => 'size', ] ], ]); |
また、「保存フォルダのパス」「ファイルのタイプ」「ファイルのサイズ」は取得しなくていい、ということであれば、下記の様に簡潔に記述することも可能です。
1 2 3 4 5 |
// Upload Plugin $this->addBehavior('Josegonzalez/Upload.Upload', [ 'image1' => [], 'image2' => [], ]); |
6.フォームテンプレートにファイルアップロード処理を追記
フォームタグの inputに「type」を追記
わざわざ書く必要もないかとも思いますが、フォームタグの inputも「image1」「image2」とそれぞれ typeを追加します。
1 2 |
echo $this->Form->control('image1',["type"=>"file"]); echo $this->Form->control('image2',["type"=>"file"]); |
これで、複数のファイルもアップロードできるようになります。
ファイルを保存する場所を指定したい!
アップロードしたファイルが保存される場所は、デフォルトの設定では、下記の場所になっています。
/ webroot / files / { テーブル名 } / { フィールド名 }
これを変更する方法は、以下の通りです。
5.モデルクラスにプラグインを利用する処理を追記
モデルのクラスに「path」を追記します。
(「$this->addBehavior()」の部分のみ記載しています。)
1 2 3 4 5 6 7 8 9 |
// Upload Plugin $this->addBehavior('Josegonzalez/Upload.Upload', [ 'image1' => [ 'path' => 'webroot{DS}upload_img{DS}{model}{DS}{field}{DS}', ], 'image2' => [ 'path' => 'webroot{DS}upload_img{DS}{model}{DS}{field}{DS}', ], ]); |
「{DS}」は、「DIRECTORY SEPARATOR(ディレクトリーセパレーター)」のことです。
Linuxでは「/」、Windowsでは「\」のように差異があるため、OSが変わっても動作するように「{DS}」と記述します。
ちなみに、パスの指定について、CakePHP3では、ドキュメントルートなら「WWW_ROOT」というように、あらかじめパスを定数で定めているものがいくつかあります。
ですが、ここでパスを指定する場合、下記の様に書いてしまうと、エラーになります。
ここで指定するパスは、アプリのルートからのパスを指定する箇所であるためです。
1 |
'path' => WWW_ROOT . 'upload_img{DS}{model}{DS}{field}{DS}', |
「WWW_ROOT」以外に CakePHP3で定数として設定されているファイルのパス、フォルダのパスについては下記の記事を参考にしてください。
CakePHP3でDocumentRootやtmp、webroot、logsなどのフォルダへのパスの定数
CakePHP3でDocumentRootやwebroot、imgフォルダのURLやドメイン、パスを取得
保存するファイル名を変更したい!
「保存するファイル名を変更したい」では、分かりにくいですが、アップロードしたファイルは、ローカルに保存されていたファイル名のまま保存されます。
具体的には、ローカルにある「aaa.jpg」というファイルをアップロードすると、「aaa.jpg」として保存されます。
このままでは、同じファイル名で、違う画像をアップロードすると、すでにアップされていたファイルが上書きされてしまう問題が発生します。
そのため、ファイル名が被らないように適切に処理をする必要があります。
なので、この処理は必ず設定した方がいいカスタマイズということになりますので、説明の順番としては、もっと前の方で説明するべきものかもしれません。
5.モデルクラスにプラグインを利用する処理を追記
モデルのクラスに「nameCallback」を追記します。
(「$this->addBehavior()」の部分のみ記載しています。)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Upload Plugin $this->addBehavior('Josegonzalez/Upload.Upload', [ 'image1' => [ 'nameCallback' => function ($data, $settings) { return uniqid().'-'.strtolower($data['name']); } ], 'image2' => [ 'nameCallback' => function ($data, $settings) { return uniqid().'-'.strtolower($data['name']); } ], ]); |
記事を削除したとき、画像ファイルも一緒に削除したい!
デフォルトの設定では、画像を登録した記事を削除しても、自動的に画像は削除されません。
そのため、画像フォルダの中には削除された記事の画像が残り続ける、という結果になります。
この状況を解消するため、記事を削除した際に、関連する画像も一緒に削除するというオプションが用意されています。
このオプションを有効にする方法を解説します。
5.モデルクラスにプラグインを利用する処理を追記
モデルのクラスに「keepFilesOnDelete」を追記します。
(「$this->addBehavior()」の部分のみ記載しています。)
1 2 3 4 5 6 7 8 9 |
// Upload Plugin $this->addBehavior('Josegonzalez/Upload.Upload', [ 'image1' => [ 'keepFilesOnDelete' => false ], 'image2' => [ 'keepFilesOnDelete' => false ], ]); |
「keepFilesOnDelete」を追記することで、記事を削除するとファイルも一緒に削除されます。
アップロードするファイルをバリデーションをしたい!
アップロードするファイルは、バリデーション(入力チェック)しないとどんなファイルでもアップロードできてしまいますので、アップロードするファイルをバリデーションする機能を追加する方法を解説します。
5.モデルクラスにバリデーションの処理を追記
編集するファイルは「/src/Model/Table/TopicsTable.php」です。
まず、useで「Cake\Validation\Validator」を使えるように設定します。
Bakeで自動生成している場合はすでに追加されている場合もあるでしょう。
1 |
use Cake\Validation\Validator; |
また、Bakeで自動生成している場合は、「image1」の入力に対するバリデーションの設定は以下のようになっているでしょう。
1 2 |
$validator ->allowEmpty('image1'); |
これを下記の様に変更を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$validator->provider('upload', \Josegonzalez\Upload\Validation\DefaultValidation::class); $validator ->allowEmpty('image1') ->add('image1', 'fileBelowMaxSize', [ 'rule' => ['isBelowMaxSize', 4000], 'message' => 'ファイルサイズは最大 4000byteまでです。', 'provider' => 'upload' ]) ->add('image1', 'fileAboveMinWidth', [ 'rule' => ['isAboveMinWidth', 100], 'message' => '画像の横幅は 100px以上必要です。', 'provider' => 'upload' ]) ->add('image1', 'fileExtension', [ 'rule' => ['extension', ['gif', 'jpeg', 'png', 'jpg']], 'message' => 'ファイル形式は、gif、jpeg、png、jpgのいずれかです。' ]) ; |
1行目は、デフォルトでは設定されていないオプションのバリデーションルールを読み込む記述です。
バリデーションルールを読み込むことで、ファイルサイズや、画像の高さ、幅などのチェックを行うことができるようになります。
上記では、5行目から「isBelowMaxSize:ファイルの最大サイズ」、10行目から「isAboveMinWidth:画像ファイルの最小の横幅」を設定したサンプルです。
それ以外のバリデーションの詳細な解説は、公式サイトも参照してください。
http://cakephp-upload.readthedocs.io/en/latest/validation.html
ちなみに、5行目の「fileBelowMaxSize」、10行目の「fileAboveMinWidth」、15行目の「fileExtension」は、バリデーションの名前として設定しているものですので、自由な名称を付けてください。
また、15行目からはファイルの拡張子をチェックする処理の設定を記述しています。
拡張子のバリデーションの詳細については、下記を参照してください。
https://api.cakephp.org/3.2/class-Cake.Validation.Validation.html#_extension
また、サンプルには記述していませんが、下記を参考にすることで、「mimeType」でバリデーションを行うことも可能になります。
CakePHP3 Book 条件付バリデーション
https://book.cakephp.org/3.0/ja/core-libraries/validation.html#id9
画像をアップロードしたときにサムネイルも作りたい!
アップロードした画像のサムネイルを作成する方法は、下記の記事の「Advanced example」にサンプルソースがありますので、これを参考にすることで、画像をアップロードしつつサムネイルの画像も生成することが可能になります。
http://cakephp-upload.readthedocs.io/en/latest/examples.html#advanced-example
ちなみに、CakePHP2の頃は、下記のような形で記述方法でサムネイルの設定を行うことができたようです。
ですが、CakePHP3では動作しませんでした。
(現在調査中ですが、分かり次第情報を更新します。)
5.モデルクラスにプラグインを利用する処理を追記
モデルのクラスに「keepFilesOnDelete」を追記します。
(「$this->addBehavior()」の部分のみ記載しています。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Upload Plugin $this->addBehavior('Josegonzalez/Upload.Upload', [ 'image1' => [ 'thumbnails' => true, 'thumbnailMethod' => 'imagick', 'thumbnailPath' => 'webroot{DS}upload_img_thumbnail{DS}{model}{DS}{field}{DS}', 'thumbnailSizes' => [ 'thumb150' => '150x150', 'normal' => '200x200', 'big' => '300x300' ], 'thumbnailName' => '{size}_{filename}', ], ]); |
「thumbnails」は、サムネイルを生成するか、否かを指定するものです。
設定値は、「true」「false」で、デフォルト値は「false」です。
「true」を指定すると、サムネイルを生成します。
「thumbnailMethod」は、サムネイルを生成するメソッドを指定します。
設定値は、「imagick」「php」で、デフォルト値は「imagick」です。
「imagick」を指定すると「Imagine」を使用し、「php」を指定すると「PHP GD」を使用します。
「Imagine」がインストールされていない環境の場合は、まず先にインストールしてください。
https://github.com/burzum/cakephp-imagine-plugin
「thumbnailPath」は、サムネイルを保存するフォルダを指定します。
設定値は、「null」、もしくは、具体的なパスの指定です。デフォルト値は「null」です。
「null」を指定した場合は、オリジナルのファイルが保存される場所と同じフォルダに保存されます。
「thumbnailSizes」は、生成するサムネイルのサイズを指定します。
配列で指定することで、複数のサイズのサムネイルを生成することができます。
「thumbnailName」は、生成するサムネイルのファイル名称を指定します。
CakePHP3の関連記事
CakePHP4のCSS、JavaScript、画像のブラウザへのキャッシュをコントロールするCakePHP3でレコードを保存(追加、更新、Insert、Update)する複数の方法を紹介
CakePHP3でモデルなしフォームからCSVをアップロードしレコードを更新する方法解説
CakePHP3でPHP Simple HTML DOM Parserを使ってスクレイピングする方法
CakePHP3のInsert On Duplicate Key Update(upsert)構文を解説・バルク処理も
CakePHP3の1対多での連携を中間テーブルを使った多対多の連携に変更するときの手順
CakePHP3でデフォルトのソート条件を設定してユーザの選択肢たソート条件を有効にする方法
CakePHP3で Ajaxを使う方法の解説。3.6以降対応。Successとthenの両方を解説。
CakePHP3でパンくずの指定は HTMLヘルパーを使って指定する方法を解説
CakePHP3にOGPをfetch、asignを利用してテンプレートごとに指定する方法を解説
その他の「CakePHP3」に関する記事一覧
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
CakePHP3でレコードを保存(追加、更新、Insert、Update)する複数の方法を紹介
CakePHP3でレコードを追加、更新(Insert、Update)する記述方法を解説。1件ずつ処理、全件をまとめて処理、条件に該当する複数件のレコードを処理方法をサンプルコードを用いて解説。
-
CakePHP3でDocumentRootやtmp、webroot、logsなどのフォルダへのパスの定数
CakePHP3で特定フォルダのパスの定数を解説。root、DocumentRoot、app、config、webroot、tests、tmp、cache、vendor、コア、コアの srcが設定済み。realpath()関数を使うと柔軟なパス指定が可能。
-
CakePHP3で値を入力直後にバリデーションする方法解説
CakePHP3でバリデーションの実行を保存する時から入力情報を受け取るときに変更する処理の解説。CakePHP3ではnewEntity()の処理でバリデートするため1行追加で対応可能。
-
CakePHP 2.3 Search Pluginで検索処理 その4前方一致検索、後方一致検索、不等号による検索、between句による範囲検索
CakePHPの検索プラグイン Search Pluginの検索処理の中で前方一致検索、後方一致検索、不等号による検索、between句による範囲検索の解説です。
-
CakePHP3、CakePHP4のキャッシュをクリアする方法「bin/cake cache clear_all」を使う
CakePHP3、CakePHP4では処理を高速化する手法の一つとしてキャッシュを利用している。しかし、その情報は元の情報を更新しても反映されない場合がある。そんなときはキャッシュを削除する必要がある。
-
Windows環境の XAMPPを利用して CakePHPの開発する際の注意点
WindowsベースにXAMPPで環境を構築しCakePHP4を利用したWebシステムを構築する際は、大文字と小文字の違いを意識する必要がある。LinuxベースのWebサーバに移動させたときに不具合で動作しないこともある。
-
Google Analytics APIを CakePHP3で動かしてレポートデータを取得する方法の解説
CakePHP3で Google Analytics APIからレポートデータを取得する処理の解説。PHPのサンプルソースをCakePHP3で動くように改造。加えて、ディメンションやメトリックスを条件に設定する方法なども。
-
CakePHP3で /Layout/defult.ctpにある titleタグ、h1タグを編集する方法
CakePHP3でtitleタグ、h1タグのテキストをデフォルトから変更する方法を解説。テンプレートファイルに「$this->assign()」でテキストを指定して「/Layout/defult.ctp」で受け取る。
-
CakePHP4の定数定義ファイルを環境変数によって本番と開発を振り分ける方法解説
CakePHP4で開発環境と本番環境とで違う設定ファイルを読み込ませて環境ごとに定数を切り替える方法を解説。Apacheのhttpd.confに環境変数を設定しそれを読み込み判別する。
-
CakePHP4のCakeDC/Usersのログイン時のリダイレクトとユーザ権限管理の設定解説
CakeDC謹製UsersプラグインのCakePHP4版の紹介。ログイン認証後にリダイレクトする先の設定方法についての解説と実運用するために必要なコツを解説。便利な仕組みも仕様の理解があって初めてうまく使いこなせる。