複数ファイルアップロードのバリデーション

複数ファイルアップロードのバリデーションを書いてみましょう。

HTML側

HTML側のファイルアップロードのフォームです。四つのファイルアプロードのフィールドがあります。エラー表示と削除に対応しているものです。

<form action=<%= url_for %> method="POST", enctype="multipart/form-data">
  %= hidden_field op => 'update';
  %= hidden_field id => $id;
  <ul>
    <li>
      画像1. <%= file_field 'image1' %>
      <div class="error"><%= $errors->{'image1'} ? $errors->{'image1'} : '' %></div>
      削除 <%= check_box 'image1_delete' %>
    </li>
    <li>
      画像2. <%= file_field 'image2' %>
      <div class="error"><%= $errors->{'image2'} ? $errors->{'image2'} : '' %></div>
      削除 <%= check_box 'image2_delete' %>
    </li>
    <li>
      画像3. <%= file_field 'image3' %>
      <div class="error"><%= $errors->{'image3'} ? $errors->{'image3'} : '' %></div>
      削除 <%= check_box 'image3_delete' %>
    </li>
    <li>
      画像4. <%= file_field 'image4' %>
      <div class="error"><%= $errors->{'image4'} ? $errors->{'image4'} : '' %></div>
      削除 <%= check_box 'image4_delete' %>
    </li>
  </ul>
</form>

プログラム側

プログラム側のサンプルコードです。パラメーターで取得したものは、Mojo::Uploadオブジェクトになります。複数のファイルフィールドの値をとって、画像情報を作成して、配列のリファレンスにしています。

ファイルのサイズがあった場合に、ファイルの種類を判定しています。

<%
  my $op = param('op') // '';
  my $id = param('id');

  my $errors = {};
  if ($self->req->method eq 'POST') {
    if ($op eq 'update') {

      # パラメーターの取得
      my $images = [];
      my $image_count = 4;
      for (my $number = 1; $number <= $image_count; $number++) {
        
        my $image_upload = param("image$number");
        
        my $image = {
          upload => $image_upload,
          number => $number,
        };
        
        push @$images, $image;
      }

      # バリデーション
      for my $image (@$images) {
        my $image_upload = $image->{upload};
        
        if ($image_upload->size > 0) {
          # コンテントタイプ
          my $image_content_type = $image_upload->headers->content_type;
          
          # 拡張子
          my $ext;

          # PNG
          if ($image_content_type =~ m|\bimage/png\b|) {
            $ext = 'png';
          }
          # JPEG
          elsif ($image_content_type =~ m|\bimage/jpeg\b|) {
            $ext = 'jpg';
          }
          # GIF
          elsif ($image_content_type =~ m|\bimage/gif\b|) {
            $ext = 'gif';
          }
          # PDF
          elsif ($image_content_type =~ m|\bapplication/pdf\b|) {
            $ext = 'pdf';
          }
          
          unless (defined $ext) {
            my $number = $image->{number};
            $errors->{"image$number"} = "画像$image->{number}のファイルの種類が不正です。";
          }
        }
      }
    }
  }
}
%>

関連情報