Laravel開発、入力フォームを編集してカンマ区切りテキストからISBNを一括で登録できるようにする
複数のISBNコードを登録することはできましたが、フォーム内にinputタグを10件追加するという形で複数対応していました。
せっかくここまで実施できたので、inputフォームに個別に入力することから、テキストボックスに複数の値を入力できるようにして一括登録もできるようにしました。
今回の目的
ISBNをまとめて登録できるフォームを作成し、一括登録できるようにする
なぜやるか
複数登録フォームではinputタグ毎に値を入力する手間が発生するため、テキスト化したデータをコピーすることで一括登録できるようにするため
やりたいこと
- 一括登録フォームを用意して、一度にまとめて登録処理ができるようにする
やったこと
- 一括登録フォームを作成する
- 複数登録と一括登録で同じアクションを利用する
- 登録されたデータをカンマで区切って分割する
- 分割処理に改行コードにも対応させる
- ISBNにハイフンが含まれる場合は除外できるようにする
- 数値以外の情報は受付しないようにする
- 登録上限を設定する
実施内容
一括登録データを受け取れるようにする
フォームを変更する
まずは、カンマ区切りを受け付けるテキストフォームを作成しました。
前回同様に作成済みのフォームはそのまま残置し、新しく一括登録用のビューを作成しました。
# ~/resources/views/book/isbn_some_input.blade.php
複数登録フォームではinputタグを10件並べていましたが、textareaとして入力フォームを作成しました。
しかし、このままでは"isbns"という名前に対して入力値が全部セットされてしまいますので、カンマで区切って分割したいのです。
カンマ区切りで追加する
コントローラーで受け取ったデータを分割します。こちらの処理については、複数登録のアクションを流用し、差分となる箇所にifを利用してどちらにも対応できるようにする形で作成しました。
作成するにあたっては、以下のサイトを参考にさせて頂きました、ありがとうございます。
上記を参考にフォームより受け取ったデータを分割してみました。
textareaタグのisnbsのみ分割するので、キーの名前でif文で処理して分割することにしました。
配列キー確認
これで受け取った値によって処理できそうです。
コントローラを修正
# ~/app/Http/Controllers/BookController.php
isbnsという名前のキーがあれば追加の処理を実施します。
一度$dataという変数で受け取ってからexplode(',',$data)としてカンマで分割したデータを$isbnsに戻しています。
ifで分岐させているので、既存の複数ISBNインプットフォームにも対応した状態です。
# terminal
$isbns
=> [
"11111111111111",
"222222222222",
]
","で区切られた情報として$isbnsに格納できました。
データ分割ができたので、残りの処理を行うための配列に追加してやればよさそうです。
# ~/app/Http/Controllers/BookController.php
直後の$isbnrecords配列に処理状況ステータスを加えている所です。
前回は'isbn*'というフォーム受け取った配列のキー名でISBNを設定していました。
今回の配列にはキーがないので要素毎に取り出しすることでキー名にたよらずに全ての値が処理できるようにしました。
※しかし、これでは複数ISBNコードでは動かないことが後で分かりました。気づいてから修正しましたので、詳細は後述します。
処理用の配列にさえいれてしまえば、後の処理は同じです。
動作確認する
まずは動かす
今までの内容で問題なく動作することを確認していきます。
13桁コードをテキストでサンプル用意していたので、カンマをつけて貼付し登録。
2件目以降が13桁ではありませんとメッセージ出力されました。
早速失敗してます…。
受け取った値を詳しくみてみました。
# terminal
$isbnrecords
=> [
[
"process" => "processing",
"number" => 1,
"isbn" => "9784797398892",
"msg" => null,
],
[
"process" => "processing",
"number" => 2,
"isbn" => """
\r\n
9784756918765
""",
"msg" => null,
],
…
2件目以降に改行が入っていました。
確かに貼付したデータも改行しています。こちらが考慮されていなかったようです。
データを修正して動作させる
改行コードを削除し、ISBNコード+カンマのみのデータで再確認します。
当初のコードに対応するべきデータはこの状態でした。
改行をなくしたことで、正常に登録処理できました。
処理データも確認しておきます。
# terminal
$isbnrecords
=> [
[
"process" => "processing",
"number" => 1,
"isbn" => "9784797398892",
"msg" => null,
],
[
"process" => "processing",
"number" => 2,
"isbn" => "9784756918765",
"msg" => null,
],
…
想定通りの値が取得できていました。
改行を考慮した処理に修正する
カンマ区切りによるデータ分割対応はできました。
しかし、改行も考慮させたフォームとしておきたいところです。
実際、初めに実施したように改行してあるデータを扱うこともありますし、カンマなしの改行のみで複数データを扱うことも多いでしょう。
パターンをあげるときりがないので、改行とカンマが考慮されていれば良しとして進めます。
手順としては、正規表現による複数の区切りパターンを設定することにしました。こちらを参考にさせて頂きました、ありがとうございます。
カンマと空白文字で分割という例が上記サイトにありましたので、今のパターンにそのまま合うので適用しました。
# ~/app/Http/Controllers/BookController.php
カンマだけでなく空白文字についても分割の対象として追加しました。
この状態で再度動作確認します。
初めに動作確認した、カンマと改行があるパターンで登録を実施。
問題なく全て登録できました。
空白文字にも対応しているので、あわせて確認します。
カンマを削除し改行したリストで登録します。
正常に処理できました。
以上で、textareaタグでまとめてデータを受け取り一括登録することができるようになりました。
文字情報を判定する
更に考慮すべき情報に対応する
テキストエリア化することでまとめて登録することには対応できました。
しかし、他に考慮する点がまだあるので対応していきます。
ここで実施することは
- 特定の文字を予め削除する
- 数値以外のデータは対象外とする
この2点です。
特定の文字を削除する
特定の文字を削除すると突然でてきましたが、経緯は次のとおりです。
元々API情報を参考にするためにamazonの本検索でいくつかピックアップしていました。検索すれば簡単に情報が出てきます。
そこで、ISBNコードを確認すると…。
ISBNコードが記載されています。今回のAPIは13桁に対応していました。
13桁コードには"-"が付与されています。
今まで毎回削除して動作確認していましたが、自動的にハイフンを削除できるようにしておくことにしました。
特定文字削除の方法については、こちらを参考にさせて頂きました、ありがとうございます。
フォームより受け取ったデータに対してハイフンを取り除く設定を追加することで、ユーザーが削除する手間を省きます。
# ~/app/Http/Controllers/BookController.php
ISBN要素作成時に"-"を削除するように設定を追加しました。
こうすることで、ハイフンのついたテキストであってもそのまま貼付して登録できるようになります。
この状態でも登録可能になりました。
数値のみ受付できるようにする
テキストエリアでは入力できる文字全てが扱えます。
しかし、取得するISBNは数値の13桁と決まっていますので、これに対応していない場合は処理できないようにします。
元々inputフォームの時はどうしていたか…というと、inputフォームのタイプをnumberとしていました。数値のみ入力できる状態としていたのです。
しかし、この方法は今回は使えません。
そこで、ハイフンを取り除く作業は先程完了しているので、次のフォームデータ判定にて、取得したISBNが数値であるかどうかを判定することにしました。
数値判定はこちらを参考にさせて頂きました、ありがとうございます。
フォームデータ評価のパターンとして数値判定を追加します。
# ~/app/Http/Controllers/BookController.php
受け取った値に対して初めに数値であることを判定しています。ここで数値でなければメッセージを付与し処理エラーとしています。
動作確認をします。
パターンをいろいろ入力してためしてみました。
- 数値
- ハイフン付き数値
- 全角
- @がついている
- で区切られている
- "w"が入っている
上2つは正常に処理されていますが、残りは全て数値でないという扱いではじかれています。
ISBN複数登録フォームを修正する
既存フォームから登録が失敗する
本記事の途中でも触れましたが、既存のISBN複数登録フォームからの登録ができなくなっていました。
今回のコントローラー処理は、複数登録と一括登録で同じアクションを利用していますので、どちらにも対応できる状態…としていたつもりでした。
改めて内容を確認します。
複数ISBN入力フォームから登録しようとするとエラー発生。
# ビュー画面エラー表示
- // isbnsキーが設定されている場合は指定キーで区切る
- if(array_key_exists('isbns', $isbns)){
- $data = $isbns['isbns'];
- $isbns = preg_split("/[\s,]+/", $data); // カンマと空文字列で区切る
- }
- $count = count($isbns); // 取得件数
- $isbnrecords = ; // データ格納用配列
- // eval(\Psy\sh());
- // 処理用配列へ追加
- for ($i = 0; $i < $count; $i++){
- if ($isbns[$i] != null){
- // isbn設定
- $setisbn = str_replace('-', '', $isbns[$i]); // ハイフンを含んでいる場合は取り除く
- // 配列格納
- $isbnrecords = array(
- 'process' => 'processing',
- 'number' => $i+1,
- 'isbn' => $setisbn,
- 'msg' => null,
- );
- }
- }
$isbn[$i]でデータが選択できていないようです。
配列の取得方法に問題がある
一括登録作成時に、配列を番号指定で順番に取り出す記述に変更していました。ところが連想配列で番号指定はできないようです。
複数ISBN登録時のコード
$isbnsには["isbn0",1234567890123,"isbn1",2345678901234]といった配列が入っており、キー名によってISBN番号を取り出していました。
現在のコード
同じことを実施していたつもりですが、キー名のある配列に対して$isbns[0]、$isbns[1]としても値がとりだせていませんでした。
両方に対応させる
バリューの取得手順を見直す事にしました。
# ~/app/Http/Controllers/BookController.php
foreachによるバリュー取り出しに変更しました。
今回の処理ではキー名は結果的に不要となるので(ISBN番号さえ取得出来ればいい)、値だけ取り出しができれば問題ありません。こうすることでどちらの配列にも対応した処理内容となりました。
登録上限を設定する
これで一括登録対応は完了しました。
いまのままでは特に上限なくまとめて登録できる状態なのですが、大量投入に対しての対応を特に何もおこなっていません。
対応できればいいのですが、一端登録上限数をもうけておくことで対応することにしました。
# ~/app/Http/Controllers/BookController.php
件数条件を追加しました、大量のデータが送信されたとしてもこれによって制限をかけることができます。