| @@ -0,0 +1,44 @@ | |||||
| <?php | |||||
| namespace App\Http\Controllers\Web\FAQ; | |||||
| use App\Http\Controllers\Web\WebController; | |||||
| use App\Kintone\KintoneRecordQueryOperator; | |||||
| use App\Kintone\Models\Ask; | |||||
| use App\Kintone\Models\Customer; | |||||
| use App\Kintone\Models\FAQ; | |||||
| use App\Logic\AskManager; | |||||
| use App\Util\DateUtil; | |||||
| use Illuminate\Http\JsonResponse; | |||||
| use Illuminate\Http\Request; | |||||
| class AskController extends WebController | |||||
| { | |||||
| public function name(): string | |||||
| { | |||||
| return "問い合わせ登録"; | |||||
| } | |||||
| public function description(): string | |||||
| { | |||||
| return "問い合わせ"; | |||||
| } | |||||
| public function __construct(protected AskParam $param, private AskManager $manager) | |||||
| { | |||||
| parent::__construct(); | |||||
| $this->middleware('auth:sanctum'); | |||||
| } | |||||
| protected function run(Request $request): JsonResponse | |||||
| { | |||||
| $param = $this->param; | |||||
| $this->manager->setCustomer(Customer::getSelf()) | |||||
| ->register($param->genre, $param->ask); | |||||
| return $this->successResponse(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,20 @@ | |||||
| <?php | |||||
| namespace App\Http\Controllers\Web\FAQ; | |||||
| use App\Http\Controllers\Web\BaseParam; | |||||
| /** | |||||
| * @property string $genre | |||||
| * @property string $ask | |||||
| */ | |||||
| class AskParam extends BaseParam | |||||
| { | |||||
| public function rules(): array | |||||
| { | |||||
| return [ | |||||
| 'genre' => $this->str(), | |||||
| 'ask' => $this->str(['max:1000']), | |||||
| ]; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,38 @@ | |||||
| <?php | |||||
| namespace App\Http\Controllers\Web\FAQ; | |||||
| use App\Http\Controllers\Web\WebController; | |||||
| use App\Kintone\KintoneRecordQueryOperator; | |||||
| use App\Kintone\Models\FAQ; | |||||
| use App\Util\DateUtil; | |||||
| use Illuminate\Http\JsonResponse; | |||||
| use Illuminate\Http\Request; | |||||
| class FAQGenresController extends WebController | |||||
| { | |||||
| public function name(): string | |||||
| { | |||||
| return "FAQジャンル取得"; | |||||
| } | |||||
| public function description(): string | |||||
| { | |||||
| return "FAQジャンル一覧を取得する"; | |||||
| } | |||||
| public function __construct(protected FAQGenresParam $param) | |||||
| { | |||||
| parent::__construct(); | |||||
| $this->middleware('auth:sanctum'); | |||||
| } | |||||
| protected function run(Request $request): JsonResponse | |||||
| { | |||||
| $result = FAQ::getDropDownOptions(FAQ::FIELD_GENRE); | |||||
| return $this->successResponse($result); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,15 @@ | |||||
| <?php | |||||
| namespace App\Http\Controllers\Web\FAQ; | |||||
| use App\Http\Controllers\Web\BaseParam; | |||||
| /** | |||||
| */ | |||||
| class FAQGenresParam extends BaseParam | |||||
| { | |||||
| public function rules(): array | |||||
| { | |||||
| return []; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,49 @@ | |||||
| <?php | |||||
| namespace App\Http\Controllers\Web\FAQ; | |||||
| use App\Http\Controllers\Web\WebController; | |||||
| use App\Kintone\KintoneRecordQueryOperator; | |||||
| use App\Kintone\Models\FAQ; | |||||
| use App\Util\DateUtil; | |||||
| use Illuminate\Http\JsonResponse; | |||||
| use Illuminate\Http\Request; | |||||
| class FAQsController extends WebController | |||||
| { | |||||
| public function name(): string | |||||
| { | |||||
| return "FAQ一覧取得"; | |||||
| } | |||||
| public function description(): string | |||||
| { | |||||
| return "FAQ一覧を取得する"; | |||||
| } | |||||
| public function __construct(protected FAQsParam $param) | |||||
| { | |||||
| parent::__construct(); | |||||
| $this->middleware('auth:sanctum'); | |||||
| } | |||||
| protected function run(Request $request): JsonResponse | |||||
| { | |||||
| $nowStr = DateUtil::now()->format('Y-m-d'); | |||||
| $query = FAQ::getQuery() | |||||
| ->where(FAQ::FIELD_SHOW_START_DATE, $nowStr, KintoneRecordQueryOperator::LE) | |||||
| ->where(FAQ::FIELD_SHOW_END_DATE, $nowStr, KintoneRecordQueryOperator::GE) | |||||
| ->orderByDesc(FAQ::FIELD_GENRE); | |||||
| $list = FAQ::getAccess()->some($query); | |||||
| $result = []; | |||||
| foreach ($list as $ele) { | |||||
| $result[] = $ele->toArray(); | |||||
| } | |||||
| return $this->successResponse($result); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,15 @@ | |||||
| <?php | |||||
| namespace App\Http\Controllers\Web\FAQ; | |||||
| use App\Http\Controllers\Web\BaseParam; | |||||
| /** | |||||
| */ | |||||
| class FAQsParam extends BaseParam | |||||
| { | |||||
| public function rules(): array | |||||
| { | |||||
| return []; | |||||
| } | |||||
| } | |||||
| @@ -204,7 +204,7 @@ abstract class WebController extends BaseController | |||||
| if ($e->getStatusCode() === 401) { | if ($e->getStatusCode() === 401) { | ||||
| return $this->unAuthorizedResponse(); | return $this->unAuthorizedResponse(); | ||||
| } | } | ||||
| throw e; | |||||
| throw $e; | |||||
| } catch (Exception $e) { | } catch (Exception $e) { | ||||
| $this->transaction->rollBack(); | $this->transaction->rollBack(); | ||||
| logs()->error([ | logs()->error([ | ||||
| @@ -5,7 +5,7 @@ namespace App\Kintone; | |||||
| use App\Exceptions\ConfigException; | use App\Exceptions\ConfigException; | ||||
| use App\Kintone\Models\KintoneModel; | use App\Kintone\Models\KintoneModel; | ||||
| use Exception; | use Exception; | ||||
| use Illuminate\Http\Client\Response; | |||||
| use Illuminate\Http\UploadedFile; | |||||
| use Illuminate\Support\Collection; | use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\Http; | use Illuminate\Support\Facades\Http; | ||||
| use Log; | use Log; | ||||
| @@ -18,7 +18,7 @@ class KintoneAccess | |||||
| private string $appName; | private string $appName; | ||||
| private string $host; | private string $host; | ||||
| private string $apiToken; | |||||
| private string $apiToken = ""; | |||||
| private int $appId; | private int $appId; | ||||
| private const DEFAULT_FIELDS = [ | private const DEFAULT_FIELDS = [ | ||||
| @@ -38,6 +38,7 @@ class KintoneAccess | |||||
| private const URL_RECORDS = "/k/v1/records.json"; | private const URL_RECORDS = "/k/v1/records.json"; | ||||
| private const URL_CURSOL = "/k/v1/records/cursor.json"; | private const URL_CURSOL = "/k/v1/records/cursor.json"; | ||||
| private const URL_FILE = "/k/v1/file.json"; | private const URL_FILE = "/k/v1/file.json"; | ||||
| private const URL_APP_FORM_FIELDS = "/k/v1/app/form/fields.json"; | |||||
| public function __construct(string $appName) | public function __construct(string $appName) | ||||
| @@ -62,11 +63,23 @@ class KintoneAccess | |||||
| throw new ConfigException($key, $appId); | throw new ConfigException($key, $appId); | ||||
| } | } | ||||
| $this->addAppToken($appName); | |||||
| $this->host = $host; | $this->host = $host; | ||||
| $this->apiToken = $apiToken; | |||||
| $this->appId = $appId; | $this->appId = $appId; | ||||
| } | } | ||||
| public function addAppToken(string $appName): static | |||||
| { | |||||
| $key = "kintone.applications." . $appName . ".apiToken"; | |||||
| $apiToken = config($key); | |||||
| if (!$apiToken) { | |||||
| throw new ConfigException($key, $apiToken); | |||||
| } | |||||
| $this->apiToken = $this->apiToken ? $this->apiToken . "," . $apiToken : $apiToken; | |||||
| return $this; | |||||
| } | |||||
| public function setFields(array $fields): static | public function setFields(array $fields): static | ||||
| { | { | ||||
| $this->fields = [ | $this->fields = [ | ||||
| @@ -366,12 +379,18 @@ class KintoneAccess | |||||
| return $response; | return $response; | ||||
| } | } | ||||
| public function filePut($file): string | |||||
| /** | |||||
| * ファイルアップロード | |||||
| * | |||||
| * @param UploadedFile $file | |||||
| * @return string fileKey | |||||
| */ | |||||
| public function filePut(UploadedFile $file): string | |||||
| { | { | ||||
| $response = Http::withHeaders([ | $response = Http::withHeaders([ | ||||
| "X-Cybozu-API-Token" => $this->apiToken, | "X-Cybozu-API-Token" => $this->apiToken, | ||||
| "Content-Type" => "multipart/form-data", | "Content-Type" => "multipart/form-data", | ||||
| ])->post($this->getCursorUrl(), $file); | |||||
| ])->post($this->getFileUrl(), $file); | |||||
| if ($response->failed()) { | if ($response->failed()) { | ||||
| $e = $response->toException(); | $e = $response->toException(); | ||||
| @@ -380,7 +399,27 @@ class KintoneAccess | |||||
| throw $e; | throw $e; | ||||
| } | } | ||||
| } | } | ||||
| return $response['']; | |||||
| return $response['fileKey']; | |||||
| } | |||||
| public function getAppFormFields(): array | |||||
| { | |||||
| $response = Http::withHeaders([ | |||||
| "X-Cybozu-API-Token" => $this->apiToken, | |||||
| ])->get($this->getAppFormFieldsUrl(), [ | |||||
| "app" => $this->appId, | |||||
| ]); | |||||
| if ($response->failed()) { | |||||
| $e = $response->toException(); | |||||
| if ($e instanceof Exception) { | |||||
| Log::error($e->getMessage()); | |||||
| throw $e; | |||||
| } | |||||
| } | |||||
| return $response['properties']; | |||||
| } | } | ||||
| private function getRecordUrl() | private function getRecordUrl() | ||||
| @@ -401,6 +440,10 @@ class KintoneAccess | |||||
| { | { | ||||
| return $this->getUrl(self::URL_FILE); | return $this->getUrl(self::URL_FILE); | ||||
| } | } | ||||
| private function getAppFormFieldsUrl() | |||||
| { | |||||
| return $this->getUrl(self::URL_APP_FORM_FIELDS); | |||||
| } | |||||
| private function getUrl(string $path) | private function getUrl(string $path) | ||||
| { | { | ||||
| @@ -0,0 +1,28 @@ | |||||
| <?php | |||||
| namespace App\Kintone\Models; | |||||
| /** | |||||
| * アプリ名 問い合わせ | |||||
| */ | |||||
| class Ask extends KintoneModel | |||||
| { | |||||
| const CONFIG_KEY = "KINTONE_APP_ASK"; | |||||
| const FIELD_CUSTOMER_CODE = "顧客コード"; | |||||
| const FIELD_GENRE = "ジャンル"; | |||||
| const FIELD_ASK = "問い合わせ"; | |||||
| const FIELD_ASK_DATETIME = "問い合わせ日時"; | |||||
| protected const FIELDS = [ | |||||
| ...parent::FIELDS, | |||||
| self::FIELD_CUSTOMER_CODE => FieldType::SINGLE_LINE_TEXT, | |||||
| self::FIELD_GENRE => FieldType::SINGLE_LINE_TEXT, | |||||
| self::FIELD_ASK => FieldType::MULTI_LINE_TEXT, | |||||
| self::FIELD_ASK_DATETIME => FieldType::DATETIME, | |||||
| ]; | |||||
| protected const FIELD_NAMES = [ | |||||
| ...parent::FIELD_NAMES, | |||||
| ]; | |||||
| } | |||||
| @@ -16,6 +16,7 @@ class Customer extends KintoneModel | |||||
| const FIELD_CUSTOMER_NAME_KANA = "顧客名カナ"; | const FIELD_CUSTOMER_NAME_KANA = "顧客名カナ"; | ||||
| const FIELD_EMAIL = "メールアドレス"; | const FIELD_EMAIL = "メールアドレス"; | ||||
| const FIELD_PHONE_NUMBER = "電話番号"; | const FIELD_PHONE_NUMBER = "電話番号"; | ||||
| const FIELD_STUDENT_LICENSE_IMAGES = "学生証画像"; | |||||
| protected const FIELDS = [ | protected const FIELDS = [ | ||||
| ...parent::FIELDS, | ...parent::FIELDS, | ||||
| @@ -24,6 +25,7 @@ class Customer extends KintoneModel | |||||
| self::FIELD_CUSTOMER_NAME_KANA => FieldType::SINGLE_LINE_TEXT, | self::FIELD_CUSTOMER_NAME_KANA => FieldType::SINGLE_LINE_TEXT, | ||||
| self::FIELD_EMAIL => FieldType::LINK, | self::FIELD_EMAIL => FieldType::LINK, | ||||
| self::FIELD_PHONE_NUMBER => FieldType::LINK, | self::FIELD_PHONE_NUMBER => FieldType::LINK, | ||||
| self::FIELD_STUDENT_LICENSE_IMAGES => FieldType::FILE, | |||||
| ]; | ]; | ||||
| protected const FIELD_NAMES = [ | protected const FIELD_NAMES = [ | ||||
| @@ -0,0 +1,33 @@ | |||||
| <?php | |||||
| namespace App\Kintone\Models; | |||||
| /** | |||||
| * アプリ名 FAQ | |||||
| */ | |||||
| class FAQ extends KintoneModel | |||||
| { | |||||
| const CONFIG_KEY = "KINTONE_APP_FAQ"; | |||||
| const FIELD_GENRE = "ジャンル"; | |||||
| const FIELD_QUESTION = "質問"; | |||||
| const FIELD_ANSWER = "回答"; | |||||
| const FIELD_SHOW_START_DATE = "表示開始日"; | |||||
| const FIELD_SHOW_END_DATE = "表示終了日"; | |||||
| protected const FIELDS = [ | |||||
| ...parent::FIELDS, | |||||
| self::FIELD_GENRE => FieldType::DROP_DOWN, | |||||
| self::FIELD_QUESTION => FieldType::MULTI_LINE_TEXT, | |||||
| self::FIELD_ANSWER => FieldType::MULTI_LINE_TEXT, | |||||
| self::FIELD_SHOW_START_DATE => FieldType::DATE, | |||||
| self::FIELD_SHOW_END_DATE => FieldType::DATE, | |||||
| ]; | |||||
| protected const FIELD_NAMES = [ | |||||
| ...parent::FIELD_NAMES, | |||||
| self::FIELD_GENRE => 'genre', | |||||
| self::FIELD_QUESTION => 'question', | |||||
| self::FIELD_ANSWER => 'answer', | |||||
| ]; | |||||
| } | |||||
| @@ -197,6 +197,22 @@ abstract class KintoneModel | |||||
| return $ret; | return $ret; | ||||
| } | } | ||||
| public static function getDropDownOptions(string $fieldCode): array | |||||
| { | |||||
| $ret = []; | |||||
| $properties = static::getAccess()->getAppFormFields(); | |||||
| $options = Arr::get($properties, sprintf("%s.options", $fieldCode)); | |||||
| $ret = Arr::pluck(Arr::sort($options, function ($option) { | |||||
| return data_get($option, "index"); | |||||
| }), "label"); | |||||
| // foreach ($options as $option) { | |||||
| // $index = data_get($option, "index"); | |||||
| // $label = data_get($option, "label"); | |||||
| // $ret[$index] = $label; | |||||
| // } | |||||
| return $ret; | |||||
| } | |||||
| /** | /** | ||||
| * 変更前データを現在データで上書きする | * 変更前データを現在データで上書きする | ||||
| * | * | ||||
| @@ -0,0 +1,45 @@ | |||||
| <?php | |||||
| namespace App\Logic; | |||||
| use App\Features\InstanceAble; | |||||
| use App\Kintone\Models\Ask; | |||||
| use App\Kintone\Models\Customer; | |||||
| use App\Util\DateUtil; | |||||
| use LogicException; | |||||
| class AskManager | |||||
| { | |||||
| use InstanceAble; | |||||
| private Customer|null $customer = null; | |||||
| public function __construct(private Ask $model) | |||||
| { | |||||
| } | |||||
| public function setCustomer(Customer $customer): static | |||||
| { | |||||
| $this->customer = $customer; | |||||
| return $this; | |||||
| } | |||||
| public function register(string $genre, string $ask) | |||||
| { | |||||
| if ($this->customer === null) { | |||||
| throw new LogicException("顧客NULL"); | |||||
| } | |||||
| $this->model->set(Ask::FIELD_ASK_DATETIME, DateUtil::now()); | |||||
| $this->model->set(Ask::FIELD_GENRE, $genre); | |||||
| $this->model->set(Ask::FIELD_ASK, $ask); | |||||
| $this->model->set(Ask::FIELD_CUSTOMER_CODE, $this->customer->getStr(Customer::FIELD_CUSTOMER_CODE)); | |||||
| $this->model->getAccess() | |||||
| ->addAppToken(Customer::class) | |||||
| ->create($this->model); | |||||
| } | |||||
| } | |||||
| @@ -31,6 +31,8 @@ return [ | |||||
| ...App\Kintone\Models\SeasonTicketContract::setConfig(), | ...App\Kintone\Models\SeasonTicketContract::setConfig(), | ||||
| ...App\Kintone\Models\PaymentPlan::setConfig(), | ...App\Kintone\Models\PaymentPlan::setConfig(), | ||||
| ...App\Kintone\Models\GeneralApplication::setConfig(), | ...App\Kintone\Models\GeneralApplication::setConfig(), | ||||
| ...App\Kintone\Models\FAQ::setConfig(), | |||||
| ...App\Kintone\Models\Ask::setConfig(), | |||||
| ], | ], | ||||
| ]; | ]; | ||||
| @@ -0,0 +1,20 @@ | |||||
| <?php | |||||
| return [ | |||||
| /* | |||||
| |-------------------------------------------------------------------------- | |||||
| | Authentication Language Lines | |||||
| |-------------------------------------------------------------------------- | |||||
| | | |||||
| | The following language lines are used during authentication for various | |||||
| | messages that we need to display to the user. You are free to modify | |||||
| | these language lines according to your application's requirements. | |||||
| | | |||||
| */ | |||||
| 'failed' => 'These credentials do not match our records.', | |||||
| 'password' => 'The provided password is incorrect.', | |||||
| 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', | |||||
| ]; | |||||
| @@ -0,0 +1,19 @@ | |||||
| <?php | |||||
| return [ | |||||
| /* | |||||
| |-------------------------------------------------------------------------- | |||||
| | Pagination Language Lines | |||||
| |-------------------------------------------------------------------------- | |||||
| | | |||||
| | The following language lines are used by the paginator library to build | |||||
| | the simple pagination links. You are free to change them to anything | |||||
| | you want to customize your views to better match your application. | |||||
| | | |||||
| */ | |||||
| 'previous' => '« Previous', | |||||
| 'next' => 'Next »', | |||||
| ]; | |||||
| @@ -0,0 +1,22 @@ | |||||
| <?php | |||||
| return [ | |||||
| /* | |||||
| |-------------------------------------------------------------------------- | |||||
| | Password Reset Language Lines | |||||
| |-------------------------------------------------------------------------- | |||||
| | | |||||
| | The following language lines are the default lines which match reasons | |||||
| | that are given by the password broker for a password update attempt | |||||
| | has failed, such as for an invalid token or invalid new password. | |||||
| | | |||||
| */ | |||||
| 'reset' => 'Your password has been reset.', | |||||
| 'sent' => 'We have emailed your password reset link.', | |||||
| 'throttled' => 'Please wait before retrying.', | |||||
| 'token' => 'This password reset token is invalid.', | |||||
| 'user' => "We can't find a user with that email address.", | |||||
| ]; | |||||
| @@ -0,0 +1,184 @@ | |||||
| <?php | |||||
| return [ | |||||
| /* | |||||
| |-------------------------------------------------------------------------- | |||||
| | Validation Language Lines | |||||
| |-------------------------------------------------------------------------- | |||||
| | | |||||
| | The following language lines contain the default error messages used by | |||||
| | the validator class. Some of these rules have multiple versions such | |||||
| | as the size rules. Feel free to tweak each of these messages here. | |||||
| | | |||||
| */ | |||||
| 'accepted' => 'The :attribute field must be accepted.', | |||||
| 'accepted_if' => 'The :attribute field must be accepted when :other is :value.', | |||||
| 'active_url' => 'The :attribute field must be a valid URL.', | |||||
| 'after' => 'The :attribute field must be a date after :date.', | |||||
| 'after_or_equal' => 'The :attribute field must be a date after or equal to :date.', | |||||
| 'alpha' => 'The :attribute field must only contain letters.', | |||||
| 'alpha_dash' => 'The :attribute field must only contain letters, numbers, dashes, and underscores.', | |||||
| 'alpha_num' => 'The :attribute field must only contain letters and numbers.', | |||||
| 'array' => 'The :attribute field must be an array.', | |||||
| 'ascii' => 'The :attribute field must only contain single-byte alphanumeric characters and symbols.', | |||||
| 'before' => 'The :attribute field must be a date before :date.', | |||||
| 'before_or_equal' => 'The :attribute field must be a date before or equal to :date.', | |||||
| 'between' => [ | |||||
| 'array' => 'The :attribute field must have between :min and :max items.', | |||||
| 'file' => 'The :attribute field must be between :min and :max kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be between :min and :max.', | |||||
| 'string' => 'The :attribute field must be between :min and :max characters.', | |||||
| ], | |||||
| 'boolean' => 'The :attribute field must be true or false.', | |||||
| 'confirmed' => 'The :attribute field confirmation does not match.', | |||||
| 'current_password' => 'The password is incorrect.', | |||||
| 'date' => 'The :attribute field must be a valid date.', | |||||
| 'date_equals' => 'The :attribute field must be a date equal to :date.', | |||||
| 'date_format' => 'The :attribute field must match the format :format.', | |||||
| 'decimal' => 'The :attribute field must have :decimal decimal places.', | |||||
| 'declined' => 'The :attribute field must be declined.', | |||||
| 'declined_if' => 'The :attribute field must be declined when :other is :value.', | |||||
| 'different' => 'The :attribute field and :other must be different.', | |||||
| 'digits' => 'The :attribute field must be :digits digits.', | |||||
| 'digits_between' => 'The :attribute field must be between :min and :max digits.', | |||||
| 'dimensions' => 'The :attribute field has invalid image dimensions.', | |||||
| 'distinct' => 'The :attribute field has a duplicate value.', | |||||
| 'doesnt_end_with' => 'The :attribute field must not end with one of the following: :values.', | |||||
| 'doesnt_start_with' => 'The :attribute field must not start with one of the following: :values.', | |||||
| 'email' => 'The :attribute field must be a valid email address.', | |||||
| 'ends_with' => 'The :attribute field must end with one of the following: :values.', | |||||
| 'enum' => 'The selected :attribute is invalid.', | |||||
| 'exists' => 'The selected :attribute is invalid.', | |||||
| 'file' => 'The :attribute field must be a file.', | |||||
| 'filled' => 'The :attribute field must have a value.', | |||||
| 'gt' => [ | |||||
| 'array' => 'The :attribute field must have more than :value items.', | |||||
| 'file' => 'The :attribute field must be greater than :value kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be greater than :value.', | |||||
| 'string' => 'The :attribute field must be greater than :value characters.', | |||||
| ], | |||||
| 'gte' => [ | |||||
| 'array' => 'The :attribute field must have :value items or more.', | |||||
| 'file' => 'The :attribute field must be greater than or equal to :value kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be greater than or equal to :value.', | |||||
| 'string' => 'The :attribute field must be greater than or equal to :value characters.', | |||||
| ], | |||||
| 'image' => 'The :attribute field must be an image.', | |||||
| 'in' => 'The selected :attribute is invalid.', | |||||
| 'in_array' => 'The :attribute field must exist in :other.', | |||||
| 'integer' => 'The :attribute field must be an integer.', | |||||
| 'ip' => 'The :attribute field must be a valid IP address.', | |||||
| 'ipv4' => 'The :attribute field must be a valid IPv4 address.', | |||||
| 'ipv6' => 'The :attribute field must be a valid IPv6 address.', | |||||
| 'json' => 'The :attribute field must be a valid JSON string.', | |||||
| 'lowercase' => 'The :attribute field must be lowercase.', | |||||
| 'lt' => [ | |||||
| 'array' => 'The :attribute field must have less than :value items.', | |||||
| 'file' => 'The :attribute field must be less than :value kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be less than :value.', | |||||
| 'string' => 'The :attribute field must be less than :value characters.', | |||||
| ], | |||||
| 'lte' => [ | |||||
| 'array' => 'The :attribute field must not have more than :value items.', | |||||
| 'file' => 'The :attribute field must be less than or equal to :value kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be less than or equal to :value.', | |||||
| 'string' => 'The :attribute field must be less than or equal to :value characters.', | |||||
| ], | |||||
| 'mac_address' => 'The :attribute field must be a valid MAC address.', | |||||
| 'max' => [ | |||||
| 'array' => 'The :attribute field must not have more than :max items.', | |||||
| 'file' => 'The :attribute field must not be greater than :max kilobytes.', | |||||
| 'numeric' => 'The :attribute field must not be greater than :max.', | |||||
| 'string' => 'The :attribute field must not be greater than :max characters.', | |||||
| ], | |||||
| 'max_digits' => 'The :attribute field must not have more than :max digits.', | |||||
| 'mimes' => 'The :attribute field must be a file of type: :values.', | |||||
| 'mimetypes' => 'The :attribute field must be a file of type: :values.', | |||||
| 'min' => [ | |||||
| 'array' => 'The :attribute field must have at least :min items.', | |||||
| 'file' => 'The :attribute field must be at least :min kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be at least :min.', | |||||
| 'string' => 'The :attribute field must be at least :min characters.', | |||||
| ], | |||||
| 'min_digits' => 'The :attribute field must have at least :min digits.', | |||||
| 'missing' => 'The :attribute field must be missing.', | |||||
| 'missing_if' => 'The :attribute field must be missing when :other is :value.', | |||||
| 'missing_unless' => 'The :attribute field must be missing unless :other is :value.', | |||||
| 'missing_with' => 'The :attribute field must be missing when :values is present.', | |||||
| 'missing_with_all' => 'The :attribute field must be missing when :values are present.', | |||||
| 'multiple_of' => 'The :attribute field must be a multiple of :value.', | |||||
| 'not_in' => 'The selected :attribute is invalid.', | |||||
| 'not_regex' => 'The :attribute field format is invalid.', | |||||
| 'numeric' => 'The :attribute field must be a number.', | |||||
| 'password' => [ | |||||
| 'letters' => 'The :attribute field must contain at least one letter.', | |||||
| 'mixed' => 'The :attribute field must contain at least one uppercase and one lowercase letter.', | |||||
| 'numbers' => 'The :attribute field must contain at least one number.', | |||||
| 'symbols' => 'The :attribute field must contain at least one symbol.', | |||||
| 'uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different :attribute.', | |||||
| ], | |||||
| 'present' => 'The :attribute field must be present.', | |||||
| 'prohibited' => 'The :attribute field is prohibited.', | |||||
| 'prohibited_if' => 'The :attribute field is prohibited when :other is :value.', | |||||
| 'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.', | |||||
| 'prohibits' => 'The :attribute field prohibits :other from being present.', | |||||
| 'regex' => 'The :attribute field format is invalid.', | |||||
| 'required' => 'The :attribute field is required.', | |||||
| 'required_array_keys' => 'The :attribute field must contain entries for: :values.', | |||||
| 'required_if' => 'The :attribute field is required when :other is :value.', | |||||
| 'required_if_accepted' => 'The :attribute field is required when :other is accepted.', | |||||
| 'required_unless' => 'The :attribute field is required unless :other is in :values.', | |||||
| 'required_with' => 'The :attribute field is required when :values is present.', | |||||
| 'required_with_all' => 'The :attribute field is required when :values are present.', | |||||
| 'required_without' => 'The :attribute field is required when :values is not present.', | |||||
| 'required_without_all' => 'The :attribute field is required when none of :values are present.', | |||||
| 'same' => 'The :attribute field must match :other.', | |||||
| 'size' => [ | |||||
| 'array' => 'The :attribute field must contain :size items.', | |||||
| 'file' => 'The :attribute field must be :size kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be :size.', | |||||
| 'string' => 'The :attribute field must be :size characters.', | |||||
| ], | |||||
| 'starts_with' => 'The :attribute field must start with one of the following: :values.', | |||||
| 'string' => 'The :attribute field must be a string.', | |||||
| 'timezone' => 'The :attribute field must be a valid timezone.', | |||||
| 'unique' => 'The :attribute has already been taken.', | |||||
| 'uploaded' => 'The :attribute failed to upload.', | |||||
| 'uppercase' => 'The :attribute field must be uppercase.', | |||||
| 'url' => 'The :attribute field must be a valid URL.', | |||||
| 'ulid' => 'The :attribute field must be a valid ULID.', | |||||
| 'uuid' => 'The :attribute field must be a valid UUID.', | |||||
| /* | |||||
| |-------------------------------------------------------------------------- | |||||
| | Custom Validation Language Lines | |||||
| |-------------------------------------------------------------------------- | |||||
| | | |||||
| | Here you may specify custom validation messages for attributes using the | |||||
| | convention "attribute.rule" to name the lines. This makes it quick to | |||||
| | specify a specific custom language line for a given attribute rule. | |||||
| | | |||||
| */ | |||||
| 'custom' => [ | |||||
| 'attribute-name' => [ | |||||
| 'rule-name' => 'custom-message', | |||||
| ], | |||||
| ], | |||||
| /* | |||||
| |-------------------------------------------------------------------------- | |||||
| | Custom Validation Attributes | |||||
| |-------------------------------------------------------------------------- | |||||
| | | |||||
| | The following language lines are used to swap our attribute placeholder | |||||
| | with something more reader friendly such as "E-Mail Address" instead | |||||
| | of "email". This simply helps us make our message more expressive. | |||||
| | | |||||
| */ | |||||
| 'attributes' => [], | |||||
| ]; | |||||
| @@ -0,0 +1,20 @@ | |||||
| <?php | |||||
| return [ | |||||
| /* | |||||
| |-------------------------------------------------------------------------- | |||||
| | Authentication Language Lines | |||||
| |-------------------------------------------------------------------------- | |||||
| | | |||||
| | The following language lines are used during authentication for various | |||||
| | messages that we need to display to the user. You are free to modify | |||||
| | these language lines according to your application's requirements. | |||||
| | | |||||
| */ | |||||
| 'failed' => 'These credentials do not match our records.', | |||||
| 'password' => 'The provided password is incorrect.', | |||||
| 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', | |||||
| ]; | |||||
| @@ -0,0 +1,19 @@ | |||||
| <?php | |||||
| return [ | |||||
| /* | |||||
| |-------------------------------------------------------------------------- | |||||
| | Pagination Language Lines | |||||
| |-------------------------------------------------------------------------- | |||||
| | | |||||
| | The following language lines are used by the paginator library to build | |||||
| | the simple pagination links. You are free to change them to anything | |||||
| | you want to customize your views to better match your application. | |||||
| | | |||||
| */ | |||||
| 'previous' => '« Previous', | |||||
| 'next' => 'Next »', | |||||
| ]; | |||||
| @@ -0,0 +1,22 @@ | |||||
| <?php | |||||
| return [ | |||||
| /* | |||||
| |-------------------------------------------------------------------------- | |||||
| | Password Reset Language Lines | |||||
| |-------------------------------------------------------------------------- | |||||
| | | |||||
| | The following language lines are the default lines which match reasons | |||||
| | that are given by the password broker for a password update attempt | |||||
| | has failed, such as for an invalid token or invalid new password. | |||||
| | | |||||
| */ | |||||
| 'reset' => 'Your password has been reset.', | |||||
| 'sent' => 'We have emailed your password reset link.', | |||||
| 'throttled' => 'Please wait before retrying.', | |||||
| 'token' => 'This password reset token is invalid.', | |||||
| 'user' => "We can't find a user with that email address.", | |||||
| ]; | |||||
| @@ -0,0 +1,205 @@ | |||||
| <?php | |||||
| return array_merge([ | |||||
| /* | |||||
| |-------------------------------------------------------------------------- | |||||
| | Validation Language Lines | |||||
| |-------------------------------------------------------------------------- | |||||
| | | |||||
| | The following language lines contain the default error messages used by | |||||
| | the validator class. Some of these rules have multiple versions such | |||||
| | as the size rules. Feel free to tweak each of these messages here. | |||||
| | | |||||
| */ | |||||
| 'accepted' => 'The :attribute field must be accepted.', | |||||
| 'accepted_if' => 'The :attribute field must be accepted when :other is :value.', | |||||
| 'active_url' => 'The :attribute field must be a valid URL.', | |||||
| 'after' => 'The :attribute field must be a date after :date.', | |||||
| 'after_or_equal' => 'The :attribute field must be a date after or equal to :date.', | |||||
| 'alpha' => 'The :attribute field must only contain letters.', | |||||
| 'alpha_dash' => 'The :attribute field must only contain letters, numbers, dashes, and underscores.', | |||||
| 'alpha_num' => 'The :attribute field must only contain letters and numbers.', | |||||
| 'array' => 'The :attribute field must be an array.', | |||||
| 'ascii' => 'The :attribute field must only contain single-byte alphanumeric characters and symbols.', | |||||
| 'before' => 'The :attribute field must be a date before :date.', | |||||
| 'before_or_equal' => 'The :attribute field must be a date before or equal to :date.', | |||||
| 'between' => [ | |||||
| 'array' => 'The :attribute field must have between :min and :max items.', | |||||
| 'file' => 'The :attribute field must be between :min and :max kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be between :min and :max.', | |||||
| 'string' => 'The :attribute field must be between :min and :max characters.', | |||||
| ], | |||||
| 'boolean' => 'The :attribute field must be true or false.', | |||||
| 'confirmed' => 'The :attribute field confirmation does not match.', | |||||
| 'current_password' => 'The password is incorrect.', | |||||
| 'date' => 'The :attribute field must be a valid date.', | |||||
| 'date_equals' => 'The :attribute field must be a date equal to :date.', | |||||
| 'date_format' => 'The :attribute field must match the format :format.', | |||||
| 'decimal' => 'The :attribute field must have :decimal decimal places.', | |||||
| 'declined' => 'The :attribute field must be declined.', | |||||
| 'declined_if' => 'The :attribute field must be declined when :other is :value.', | |||||
| 'different' => 'The :attribute field and :other must be different.', | |||||
| 'digits' => 'The :attribute field must be :digits digits.', | |||||
| 'digits_between' => 'The :attribute field must be between :min and :max digits.', | |||||
| 'dimensions' => 'The :attribute field has invalid image dimensions.', | |||||
| 'distinct' => 'The :attribute field has a duplicate value.', | |||||
| 'doesnt_end_with' => 'The :attribute field must not end with one of the following: :values.', | |||||
| 'doesnt_start_with' => 'The :attribute field must not start with one of the following: :values.', | |||||
| 'email' => 'The :attribute field must be a valid email address.', | |||||
| 'ends_with' => 'The :attribute field must end with one of the following: :values.', | |||||
| 'enum' => 'The selected :attribute is invalid.', | |||||
| 'exists' => 'The selected :attribute is invalid.', | |||||
| 'file' => 'The :attribute field must be a file.', | |||||
| 'filled' => 'The :attribute field must have a value.', | |||||
| 'gt' => [ | |||||
| 'array' => 'The :attribute field must have more than :value items.', | |||||
| 'file' => 'The :attribute field must be greater than :value kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be greater than :value.', | |||||
| 'string' => 'The :attribute field must be greater than :value characters.', | |||||
| ], | |||||
| 'gte' => [ | |||||
| 'array' => 'The :attribute field must have :value items or more.', | |||||
| 'file' => 'The :attribute field must be greater than or equal to :value kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be greater than or equal to :value.', | |||||
| 'string' => 'The :attribute field must be greater than or equal to :value characters.', | |||||
| ], | |||||
| 'image' => 'The :attribute field must be an image.', | |||||
| 'in' => 'The selected :attribute is invalid.', | |||||
| 'in_array' => 'The :attribute field must exist in :other.', | |||||
| 'integer' => 'The :attribute field must be an integer.', | |||||
| 'ip' => 'The :attribute field must be a valid IP address.', | |||||
| 'ipv4' => 'The :attribute field must be a valid IPv4 address.', | |||||
| 'ipv6' => 'The :attribute field must be a valid IPv6 address.', | |||||
| 'json' => 'The :attribute field must be a valid JSON string.', | |||||
| 'lowercase' => 'The :attribute field must be lowercase.', | |||||
| 'lt' => [ | |||||
| 'array' => 'The :attribute field must have less than :value items.', | |||||
| 'file' => 'The :attribute field must be less than :value kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be less than :value.', | |||||
| 'string' => 'The :attribute field must be less than :value characters.', | |||||
| ], | |||||
| 'lte' => [ | |||||
| 'array' => 'The :attribute field must not have more than :value items.', | |||||
| 'file' => 'The :attribute field must be less than or equal to :value kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be less than or equal to :value.', | |||||
| 'string' => 'The :attribute field must be less than or equal to :value characters.', | |||||
| ], | |||||
| 'mac_address' => 'The :attribute field must be a valid MAC address.', | |||||
| 'max' => [ | |||||
| 'array' => 'The :attribute field must not have more than :max items.', | |||||
| 'file' => 'The :attribute field must not be greater than :max kilobytes.', | |||||
| 'numeric' => 'The :attribute field must not be greater than :max.', | |||||
| 'string' => 'The :attribute field must not be greater than :max characters.', | |||||
| ], | |||||
| 'max_digits' => 'The :attribute field must not have more than :max digits.', | |||||
| 'mimes' => 'The :attribute field must be a file of type: :values.', | |||||
| 'mimetypes' => 'The :attribute field must be a file of type: :values.', | |||||
| 'min' => [ | |||||
| 'array' => 'The :attribute field must have at least :min items.', | |||||
| 'file' => 'The :attribute field must be at least :min kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be at least :min.', | |||||
| 'string' => 'The :attribute field must be at least :min characters.', | |||||
| ], | |||||
| 'min_digits' => 'The :attribute field must have at least :min digits.', | |||||
| 'missing' => 'The :attribute field must be missing.', | |||||
| 'missing_if' => 'The :attribute field must be missing when :other is :value.', | |||||
| 'missing_unless' => 'The :attribute field must be missing unless :other is :value.', | |||||
| 'missing_with' => 'The :attribute field must be missing when :values is present.', | |||||
| 'missing_with_all' => 'The :attribute field must be missing when :values are present.', | |||||
| 'multiple_of' => 'The :attribute field must be a multiple of :value.', | |||||
| 'not_in' => 'The selected :attribute is invalid.', | |||||
| 'not_regex' => 'The :attribute field format is invalid.', | |||||
| 'numeric' => 'The :attribute field must be a number.', | |||||
| 'password' => [ | |||||
| 'letters' => 'The :attribute field must contain at least one letter.', | |||||
| 'mixed' => 'The :attribute field must contain at least one uppercase and one lowercase letter.', | |||||
| 'numbers' => 'The :attribute field must contain at least one number.', | |||||
| 'symbols' => 'The :attribute field must contain at least one symbol.', | |||||
| 'uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different :attribute.', | |||||
| ], | |||||
| 'present' => 'The :attribute field must be present.', | |||||
| 'prohibited' => 'The :attribute field is prohibited.', | |||||
| 'prohibited_if' => 'The :attribute field is prohibited when :other is :value.', | |||||
| 'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.', | |||||
| 'prohibits' => 'The :attribute field prohibits :other from being present.', | |||||
| 'regex' => 'The :attribute field format is invalid.', | |||||
| 'required' => 'The :attribute field is required.', | |||||
| 'required_array_keys' => 'The :attribute field must contain entries for: :values.', | |||||
| 'required_if' => 'The :attribute field is required when :other is :value.', | |||||
| 'required_if_accepted' => 'The :attribute field is required when :other is accepted.', | |||||
| 'required_unless' => 'The :attribute field is required unless :other is in :values.', | |||||
| 'required_with' => 'The :attribute field is required when :values is present.', | |||||
| 'required_with_all' => 'The :attribute field is required when :values are present.', | |||||
| 'required_without' => 'The :attribute field is required when :values is not present.', | |||||
| 'required_without_all' => 'The :attribute field is required when none of :values are present.', | |||||
| 'same' => 'The :attribute field must match :other.', | |||||
| 'size' => [ | |||||
| 'array' => 'The :attribute field must contain :size items.', | |||||
| 'file' => 'The :attribute field must be :size kilobytes.', | |||||
| 'numeric' => 'The :attribute field must be :size.', | |||||
| 'string' => 'The :attribute field must be :size characters.', | |||||
| ], | |||||
| 'starts_with' => 'The :attribute field must start with one of the following: :values.', | |||||
| 'string' => 'The :attribute field must be a string.', | |||||
| 'timezone' => 'The :attribute field must be a valid timezone.', | |||||
| 'unique' => 'The :attribute has already been taken.', | |||||
| 'uploaded' => 'The :attribute failed to upload.', | |||||
| 'uppercase' => 'The :attribute field must be uppercase.', | |||||
| 'url' => 'The :attribute field must be a valid URL.', | |||||
| 'ulid' => 'The :attribute field must be a valid ULID.', | |||||
| 'uuid' => 'The :attribute field must be a valid UUID.', | |||||
| /* | |||||
| |-------------------------------------------------------------------------- | |||||
| | Custom Validation Language Lines | |||||
| |-------------------------------------------------------------------------- | |||||
| | | |||||
| | Here you may specify custom validation messages for attributes using the | |||||
| | convention "attribute.rule" to name the lines. This makes it quick to | |||||
| | specify a specific custom language line for a given attribute rule. | |||||
| | | |||||
| */ | |||||
| 'custom' => [ | |||||
| 'attribute-name' => [ | |||||
| 'rule-name' => 'custom-message', | |||||
| ], | |||||
| ], | |||||
| /* | |||||
| |-------------------------------------------------------------------------- | |||||
| | Custom Validation Attributes | |||||
| |-------------------------------------------------------------------------- | |||||
| | | |||||
| | The following language lines are used to swap our attribute placeholder | |||||
| | with something more reader friendly such as "E-Mail Address" instead | |||||
| | of "email". This simply helps us make our message more expressive. | |||||
| | | |||||
| */ | |||||
| 'attributes' => [], | |||||
| ], [ | |||||
| 'after' => '日付の前後関係が正しくありません', | |||||
| 'after_or_equal' => '日付の前後関係が正しくありません', | |||||
| 'before_or_equal' => '日付の前後関係が正しくありません', | |||||
| 'between' => [ | |||||
| 'string' => ':min から :max 文字入力してください', | |||||
| ], | |||||
| 'date' => '日付を入力してください', | |||||
| 'email' => 'Emailの形式が正しくありません', | |||||
| 'enum' => '正しい項目を選択してください', | |||||
| 'exists' => '存在しません', | |||||
| 'max' => [ | |||||
| 'string' => ':max 文字まで入力できます', | |||||
| ], | |||||
| 'numeric' => '数値を入力してください', | |||||
| 'required' => '必須項目です', | |||||
| 'size' => [ | |||||
| 'string' => ':size 桁で入力してください.', | |||||
| ], | |||||
| 'string' => '文字を入力してください', | |||||
| 'unique' => 'すでに使われています', | |||||
| ]); | |||||
| @@ -24,3 +24,8 @@ RouteHelper::post('/season-ticket-contract/sticker-re-order', App\Http\Controlle | |||||
| RouteHelper::post('/season-ticket-contract/parking-certificate-order', App\Http\Controllers\Web\SeasonTicketContract\ParkingCertificateOrderController::class); | RouteHelper::post('/season-ticket-contract/parking-certificate-order', App\Http\Controllers\Web\SeasonTicketContract\ParkingCertificateOrderController::class); | ||||
| RouteHelper::post('/season-ticket-contract/termination-order', App\Http\Controllers\Web\SeasonTicketContract\TerminationOrderController::class); | RouteHelper::post('/season-ticket-contract/termination-order', App\Http\Controllers\Web\SeasonTicketContract\TerminationOrderController::class); | ||||
| RouteHelper::post('/season-ticket-contract/update-vehicle-info-order', App\Http\Controllers\Web\SeasonTicketContract\UpdateVehicleInfoOrderController::class); | RouteHelper::post('/season-ticket-contract/update-vehicle-info-order', App\Http\Controllers\Web\SeasonTicketContract\UpdateVehicleInfoOrderController::class); | ||||
| RouteHelper::get('/faq', App\Http\Controllers\Web\FAQ\FAQsController::class); | |||||
| RouteHelper::get('/faq/genres', App\Http\Controllers\Web\FAQ\FAQGenresController::class); | |||||
| RouteHelper::post('/ask', App\Http\Controllers\Web\FAQ\AskController::class); | |||||
| RouteHelper::post('/upload/student-license-images', App\Http\Controllers\Web\Customer\UploadStudentLicenseImagesController::class); | |||||
| @@ -3,6 +3,7 @@ | |||||
| namespace Tests\Feature; | namespace Tests\Feature; | ||||
| use App\Kintone\Models\Customer; | use App\Kintone\Models\Customer; | ||||
| use App\Kintone\Models\FAQ; | |||||
| use App\Kintone\Models\SeasonTicketContract; | use App\Kintone\Models\SeasonTicketContract; | ||||
| use Illuminate\Support\Carbon; | use Illuminate\Support\Carbon; | ||||
| use Tests\TestCase; | use Tests\TestCase; | ||||
| @@ -55,4 +56,12 @@ class KintoneAccessTest extends TestCase | |||||
| $this->assertEquals("2023/05/01", $array['contract_start_date']); | $this->assertEquals("2023/05/01", $array['contract_start_date']); | ||||
| $this->assertEquals("2121/12/31", $array['contract_end_date']); | $this->assertEquals("2121/12/31", $array['contract_end_date']); | ||||
| } | } | ||||
| public function test_app_form_field(): void | |||||
| { | |||||
| $options = FAQ::getDropDownOptions(FAQ::FIELD_GENRE); | |||||
| $this->assertTrue(true); | |||||
| } | |||||
| } | } | ||||