Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 168 additions & 1 deletion app/Plugins/User/Forms/FormsPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ public function getPublicFunctions()
'editInput',
'thanks',
'editSpamFilter',
'indexCount',
];
$functions['post'] = [
'index',
Expand All @@ -127,6 +128,7 @@ public function getPublicFunctions()
'addSpamList',
'deleteSpamList',
'addToSpamListFromInput',
'indexCount',
];
return $functions;
}
Expand Down Expand Up @@ -3020,12 +3022,16 @@ public function listInputs($request, $page_id, $frame_id, $forms_id = null)
// カラムの取得
$columns = FormsColumns::where('forms_id', $form->id)->orderBy('display_sequence', 'asc')->get();

$search_condition = $this->getListInputsSearchCondition($request);

$inputs_query = FormsInputs::where('forms_id', $form->id);
$this->appendListInputsSearchWhere($inputs_query, $search_condition);
// $inputs_query->orderBy('forms_inputs.id', 'asc');
$inputs_query->orderBy('forms_inputs.created_at', 'desc');

// データ取得
$get_count = 10;
$get_count = session("view_count_spectator_{$frame_id}", $this->getListInputsDefaultPerPage());
$get_count = $this->normalizeListInputsPerPage($get_count);
$inputs = $inputs_query->paginate($get_count, ["*"], "frame_{$frame_id}_page");

// 登録データ詳細の取得
Expand Down Expand Up @@ -3060,9 +3066,170 @@ public function listInputs($request, $page_id, $frame_id, $forms_id = null)
'inputs' => $inputs,
'input_cols' => $input_cols,
'has_email_map' => $has_email_map,
'search_condition' => $search_condition,
'per_page_options' => $this->getListInputsPerPageOptions(),
'view_count' => $get_count,
]);
}

/**
* 登録一覧の件数指定
*/
public function indexCount($request, $page_id, $frame_id)
{
session(["view_count_spectator_{$frame_id}" => $this->normalizeListInputsPerPage($request->input("view_count_spectator"))]);

// リダイレクト先を指定しないため、画面から渡されたredirect_pathに飛ぶ
}

/**
* 登録一覧の検索条件を画面入力から取得する。
*/
private function getListInputsSearchCondition($request): array
{
return [
'keyword' => trim((string)$request->input('keyword', '')),
'status' => $this->normalizeListInputsStatus($request->input('status')),
'created_from' => $this->normalizeListInputsDate($request->input('created_from')),
'created_to' => $this->normalizeListInputsDate($request->input('created_to')),
];
}

/**
* 登録一覧の検索条件をクエリに反映する。
*/
private function appendListInputsSearchWhere($inputs_query, array $search_condition): void
{
if ($search_condition['keyword'] !== '') {
$keyword = $this->escapeLikeValue($search_condition['keyword']);
$like_keyword = '%' . $keyword . '%';

$inputs_query->where(function ($query) use ($like_keyword) {
$query->where('forms_inputs.number_with_prefix', 'like', $like_keyword)
->orWhere('forms_inputs.created_name', 'like', $like_keyword)
->orWhere('forms_inputs.ip_address', 'like', $like_keyword)
->orWhereExists(function ($sub_query) use ($like_keyword) {
$sub_query->select(DB::raw(1))
->from('forms_input_cols')
->join('forms_columns', 'forms_columns.id', '=', 'forms_input_cols.forms_columns_id')
->whereColumn('forms_input_cols.forms_inputs_id', 'forms_inputs.id')
->where('forms_columns.column_type', '<>', FormColumnType::file)
->where('forms_input_cols.value', 'like', $like_keyword);
})
->orWhereExists(function ($sub_query) use ($like_keyword) {
$sub_query->select(DB::raw(1))
->from('forms_input_cols')
->join('forms_columns', 'forms_columns.id', '=', 'forms_input_cols.forms_columns_id')
->join('uploads', 'uploads.id', '=', 'forms_input_cols.value')
->whereColumn('forms_input_cols.forms_inputs_id', 'forms_inputs.id')
->where('forms_columns.column_type', FormColumnType::file)
->where('uploads.client_original_name', 'like', $like_keyword);
});
});
}

if ($search_condition['status'] !== '') {
$inputs_query->where('forms_inputs.status', (int)$search_condition['status']);
}

if ($search_condition['created_from'] !== '') {
$inputs_query->whereDate('forms_inputs.created_at', '>=', $search_condition['created_from']);
}

if ($search_condition['created_to'] !== '') {
$inputs_query->whereDate('forms_inputs.created_at', '<=', $search_condition['created_to']);
}
}

/**
* 登録一覧の状態検索条件を有効な値に丸める。
*/
private function normalizeListInputsStatus($status): string
{
if (is_null($status) || $status === '') {
return '';
}

$allowed_statuses = array_map('strval', array_keys(FormStatusType::enum));
$status = (string)$status;

return in_array($status, $allowed_statuses, true) ? $status : '';
}

/**
* 登録一覧の日付検索条件を有効な年月日に丸める。
*/
private function normalizeListInputsDate($date): string
{
if (!is_string($date) || $date === '') {
return '';
}

$date = trim($date);
if (!preg_match('/\A[0-9]{4}-[0-9]{2}-[0-9]{2}\z/', $date)) {
return '';
}

[$year, $month, $day] = array_map('intval', explode('-', $date));

return checkdate($month, $day, $year) ? $date : '';
}

/**
* 登録一覧の表示件数を許可された値に丸める。
*/
private function normalizeListInputsPerPage($per_page): int
{
$per_page = (int)$per_page;
$per_page_options = $this->getListInputsPerPageOptions();

return in_array($per_page, $per_page_options, true) ? $per_page : $this->getListInputsDefaultPerPage();
}

/**
* 登録一覧の表示件数候補を設定から取得する。
*/
private function getListInputsPerPageOptions(): array
{
$per_page_options = config('forms.list_inputs.per_page_options', []);
if (!is_array($per_page_options)) {
return [10];
}

$per_page_options = collect($per_page_options)
->map(function ($per_page) {
return (int)$per_page;
})
->filter(function ($per_page) {
return $per_page > 0;
})
->unique()
->sort()
->values()
->all();

return $per_page_options ?: [10];
}

/**
* 登録一覧の初期表示件数を設定から取得する。
*/
private function getListInputsDefaultPerPage(): int
{
$default_per_page = (int)config('forms.list_inputs.default_per_page');
$per_page_options = $this->getListInputsPerPageOptions();

return in_array($default_per_page, $per_page_options, true) ? $default_per_page : $per_page_options[0];
}

/**
* LIKE 検索用にワイルドカード文字をエスケープする。
*/
private function escapeLikeValue(string $value): string
{
return str_replace(['\\', '%', '_'], ['\\\\', '\%', '\_'], $value);
}

/**
* 登録一覧からの編集画面表示
*/
Expand Down
9 changes: 9 additions & 0 deletions config/forms.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

return [

// 登録一覧設定
'list_inputs' => [
// 1ページあたりの表示件数候補
'per_page_options' => [10, 20, 50, 100],

// 1ページあたりの初期表示件数
'default_per_page' => 10,
],

// ファイルアップロード許可設定
'upload' => [
// クライアント拡張子の許可リスト
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddListInputsSearchIndexesToFormsTables extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('forms_inputs', function (Blueprint $table) {
$table->index(['forms_id', 'created_at'], 'forms_inputs_forms_id_created_at_index');
});

Schema::table('forms_input_cols', function (Blueprint $table) {
$table->index('forms_inputs_id', 'forms_input_cols_forms_inputs_id_index');
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('forms_input_cols', function (Blueprint $table) {
$table->dropIndex('forms_input_cols_forms_inputs_id_index');
});

Schema::table('forms_inputs', function (Blueprint $table) {
$table->dropIndex('forms_inputs_forms_id_created_at_index');
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,27 @@

@section("plugin_setting_$frame->id")

@php
$search_condition = $search_condition ?? [
'keyword' => '',
'status' => '',
'created_from' => '',
'created_to' => '',
];
$per_page_options = $per_page_options ?? config('forms.list_inputs.per_page_options', []);
$view_count = $view_count ?? config('forms.list_inputs.default_per_page');
$list_inputs_url = url('/') . "/plugin/forms/listInputs/{$page->id}/{$frame_id}/{$form->id}";
$has_search_condition = $search_condition['keyword'] !== ''
|| $search_condition['status'] !== ''
|| $search_condition['created_from'] !== ''
|| $search_condition['created_to'] !== '';
$pagination_appends = array_filter($search_condition, function ($value) {
return !is_null($value) && $value !== '';
});
$list_inputs_redirect_query = array_merge($pagination_appends, ["frame_{$frame_id}_page" => 1]);
$list_inputs_redirect_path = $list_inputs_url . '?' . http_build_query($list_inputs_redirect_query) . "#frame-{$frame_id}";
@endphp

{{-- 登録後メッセージ表示 --}}
@include('plugins.common.flash_message')

Expand Down Expand Up @@ -59,13 +80,60 @@ function submit_register_other_plugins(id) {
})
</script>

<form action="{{$list_inputs_url}}#frame-{{$frame_id}}" method="GET" class="mb-3" role="search" aria-label="{{$form->forms_name}}の登録一覧検索">
<div class="form-row align-items-end">
<div class="form-group col-md-3 mb-2">
<label for="forms-inputs-keyword-{{$frame_id}}">
キーワード
<i class="fas fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="入力値・添付ファイル名・採番・登録ユーザ・IPアドレスを検索します。"></i>
</label>
<input type="text" name="keyword" id="forms-inputs-keyword-{{$frame_id}}" value="{{$search_condition['keyword']}}" class="form-control" placeholder="キーワード">
</div>
<div class="form-group col-md-2 mb-2">
<label for="forms-inputs-status-{{$frame_id}}">状態</label>
<select name="status" id="forms-inputs-status-{{$frame_id}}" class="form-control">
<option value="">すべて</option>
@foreach (FormStatusType::enum as $status_key => $status_label)
<option value="{{$status_key}}" @if((string)$search_condition['status'] === (string)$status_key) selected @endif>{{$status_label}}</option>
@endforeach
</select>
</div>
<div class="form-group col-md-3 mb-2">
<label for="forms-inputs-created-from-{{$frame_id}}">登録日From</label>
<input type="date" name="created_from" id="forms-inputs-created-from-{{$frame_id}}" value="{{$search_condition['created_from']}}" class="form-control forms-list-inputs-date">
</div>
<div class="form-group col-md-3 mb-2">
<label for="forms-inputs-created-to-{{$frame_id}}">登録日To</label>
<input type="date" name="created_to" id="forms-inputs-created-to-{{$frame_id}}" value="{{$search_condition['created_to']}}" class="form-control forms-list-inputs-date">
</div>
</div>
<div class="text-right mb-3">
<button type="submit" class="btn btn-primary"><i class="fas fa-search"></i> 検索</button>
@if ($has_search_condition)
<a href="{{$list_inputs_url}}#frame-{{$frame_id}}" class="btn btn-secondary"><i class="fas fa-times"></i> クリア</a>
@endif
</div>
</form>

<div class="row">
<div class="col-3 text-left d-flex align-items-end">
{{-- (左側)件数 --}}
<span class="badge badge-pill badge-light">{{ $inputs->total() }} 件</span>
</div>

<div class="col text-right">
{{-- (右側)表示件数変更 --}}
<form action="{{url('/')}}/redirect/plugin/forms/indexCount/{{$page->id}}/{{$frame_id}}#frame-{{$frame_id}}" method="POST" class="d-inline-block mr-2" name="view_count_spectator_{{$frame_id}}">
{{ csrf_field() }}
<input type="hidden" name="redirect_path" value="{{$list_inputs_redirect_path}}">
<label for="forms-inputs-view-count-{{$frame_id}}" class="mr-1 mb-0">表示件数</label>
<select name="view_count_spectator" id="forms-inputs-view-count-{{$frame_id}}" class="form-control form-control-sm d-inline-block w-auto" onchange="document.forms.view_count_spectator_{{$frame_id}}.submit();">
@foreach ($per_page_options as $per_page_option)
<option value="{{$per_page_option}}" @if((int)$view_count === (int)$per_page_option) selected @endif>{{$per_page_option}}件</option>
@endforeach
</select>
</form>

{{-- (右側)ダウンロードボタン --}}
<div class="btn-group">
<button type="button" class="btn btn-primary btn-sm" onclick="submit_download_shift_jis({{$form->id}});">
Expand Down Expand Up @@ -231,7 +299,7 @@ function submit_register_other_plugins(id) {
</table>

{{-- ページング処理 --}}
@include('plugins.common.user_paginate', ['posts' => $inputs, 'frame' => $frame, 'aria_label_name' => $form->forms_name, 'class' => 'form-group mt-3'])
@include('plugins.common.user_paginate', ['posts' => $inputs, 'frame' => $frame, 'aria_label_name' => $form->forms_name, 'class' => 'form-group mt-3', 'appends' => $pagination_appends])

{{-- ボタン --}}
<div class="text-center pt-2">
Expand Down
Loading
Loading