#author("2022-05-20T05:52:33+09:00;2021-06-25T21:26:55+09:00","default:kanateko","kanateko")
#author("2022-07-06T04:29:04+09:00;2021-06-25T21:26:55+09:00","default:kanateko","kanateko")
&tag(カスタマイズ,プラグイン改造);

#title(【PukiWiki】attachプラグインを改造して複数のファイルを一括で添付・アップロードできるようにする)

#contentsx

*変更箇所のまとめ [#y367335b]
-複数ファイルの一括添付・アップロードに対応させる
-画像ファイルのプレビューを追加する

*変更の詳細 [#uc0730f7]
**複数ファイルの一括アップロードに対応する [#multiple]

大量の画像をページに添付する必要がある場合、デフォの状態だと1枚1枚ファイル選択→アップロードと手順を踏む必要があって非常に煩わしい。どうにかならないかといろいろ調べてみたところ、意外と少し手を加えるだけで済みそうだったので改造に着手することに。

まずはフォームを複数ファイル選択に対応させる。

#prism(diff-php diff-highlight){{
    $msg_maxsize
   </span><br />
-  <label for="_p_attach_file">{$_attach_messages['msg_file']}:</label> <input type="file" name="attach_file" id="_p_attach_file" />
+  <label for="_p_attach_file">{$_attach_messages['msg_file']}:</label> <input type="file" multiple name="attach_file[]" id="_p_attach_file" />
   $pass
   <input type="submit" value="{$_attach_messages['btn_upload']}" />
}}

あとはアップロード処理をファイルの数だけ行う必要があるため、attach_upload関数のreturn部分以外をfor文で囲う。

#prism(diff-php diff-highlight){{
function attach_upload($file, $page, $pass = null)
{
     global $_attach_messages, $notify, $notify_subject;
+    for ($i = 0; $i < count($file["name"]); $i++) {
         if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
     .
     .
     .
 		    pkwk_mail_notify($notify_subject, "\n", $footer) or
 			    die('pkwk_mail_notify(): Failed');
 	    }
+	}
 
 	return array(
 	'result'=>true,
 	'msg'=>$_attach_messages['msg_uploaded']);
}}

最後にfor文で囲った中にあるすべての$fileに[$i]を付ける

#prism(php){{
$file['name']
$file['tmp_name']
$file['size']
}}

これらを

#prism(php){{
$file['name'][$i]
$file['tmp_name'][$i]
$file['size'][$i]
}}

こうする。

これで複数ファイルを選択して一括でページに添付することが可能となる。

**アップロード前に選択したファイルをプレビューできるようにする [#i26a5e8b]

複数選択時はそのままだと選択したファイルの名前すら確認できないので、ついでにプレビュー機能をつけてみる。

まずはプレビューを表示するための場所を用意する。

#prism(diff-php diff-highlight){{
   $pass
   <input type="submit" value="{$_attach_messages['btn_upload']}" />
+  <output id="attach_preview"></output>
  </div>
 </form>
}}

あとは表示させるため以下のスクリプトを追加する。

#prism(javascript){{
<script>
  document.getElementById('_p_attach_file').onchange = function(event){
  initializeFiles();

  var files = event.target.files;

  for (var i = 0, f; f = files[i]; i++) {
    var reader = new FileReader;
    reader.readAsDataURL(f);

    reader.onload = (function(theFile) {
      return function (e) {
        var div = document.createElement('div');
        var fileName = encodeURIComponent(theFile.name);
        div.className = 'reader_file';
        div.innerHTML = '<div class="reader_title">' + fileName + '</div>';
        if (/(jpe?g|png|gif|svg)$/i.test(fileName)) {
          div.innerHTML += '<img class="reader_image" src="' + e.target.result + '" />';
        }
        document.getElementById('attach_preview').insertBefore(div, null);
      }
    })(f);
  }
}
function initializeFiles() {
  document.getElementById('attach_preview').innerHTML = '';
}
</script>
}}

コードは下記の参考サイトのものをほぼそのまま使用しているが、画像以外はファイル名だけを表示するよう手を加えてある。

プレビューサイズなど見た目は適当にcssで調整。

*参考 [#f3b0a561]
[[今更だけどPHPで複数のファイルアップロードをめっちゃシンプルに実装する - Qiita:https://qiita.com/hidepy/items/23ab9bb2c291e912763f]]
[[複数ファイルアップロードで、アップロード前に画像とファイル名を表示させるサンプル - Qiita:https://qiita.com/mochizukikotaro/items/ff6cd42e902e79b02649]]

大抵のことはQiita見れば解決するなぁと思う今日この頃。

*コメント [#edec4fc1]
質問や指摘などあればどうぞ
----
#pcomment(,10,above,reply)
#pcomment(reply)