動機
WordPress でフォームから一度にファイルを複数アップロードすると画面遷移が重たくなります、対策としてAjaxにて非同期でアップロードします。
ログインしていない一般のサイト閲覧者がフォームからアップロードを想定しており、見積フォームなどで使う用途で作りました。
とはいえ、ほぼ出来のコードを組み合わせております(ページ下部に参考サイトを紹介させていただいております)
手順
STEP1
functions.php にて
wp_localize_script()
でPHPからJSに情報を渡す段取りをする。
wp_enqueue_script()
でJSファイル(STEP3)を登録する
STEP 2
functions.php にて
do_action( “wp_ajax_{$action}” )
で、Ajaxを引き受ける関数をPHPにて記述。
※上記の my_wp_ajax()
STEP 3
AjaxするJSファイルを用意、設置する。
https://blog.spicadots.com/2020/05/wordpress-file-upload-with-ajax/
を参考に、upload-image.js とした
STEP 4
投稿、固定ページにHTMLフォームを設置
ワンポイント説明
HTML部分
formタグが無いのが特徴です、フォームタグの入れ子など配慮無用となります。
upload-image.js にて
let data = new FormData;
で、新しいFormData オブジェクトを生成しています。
Ajaxを受け付ける関数、my_wp_ajax()について
POSTされたデータを保存するのに、Wordpress の
wp_upload_bits()
を使っています。
返り値は配列で、 ‘error’ key を見ることで成功を判定できます。
wp_upload_bits() は、記事に添付することなく、ファイルを uploads ディレクトリ配下へ保存してくれます。
同名ファイルの場合も、ファイル名-1.jpg、ファイル名-2.jpg のように枝番を自動で作ってくれます。
セキュリティ部分
wp_create_nonce( $action );
でnonceを生成・使用して
check_ajax_referer( $action, $query_arg, $die )
で、チェックしています。
参考にさせていただいたURL
WordPressでファイルアップロードをAjaxでやる方法
JSに関して、こちらの情報を参考にさせていただきました。
こちらのページでは、ファイルのアップロードは
async-upload.php
を使っておられます。この方法は、
WordPressにログイン中のユーザーが使用するという前提だと思われます。
ログイン中であれば、上記URLで紹介の方法が最も良いと思います。
ありがとうShizumiさん
WordPress Create Upload Files and Directories
wp_upload_bits()
でのファイルアップロードと保存について、参考にさせていただきました。
返り値は
array(4) {
["file"]=>
string(84) "/home/user/wp/wp-content/uploads/2022/12/aaaaaa.jpg"
["url"]=>
string(67) "http://xxxxx.com/wp/wp-content/uploads/2022/12/aaaaaa.jpg"
["type"]=>
string(10) "image/jpeg"
["error"]=>
bool(false)
}
です。
ありがとうJEFF STARRさん。