['required', 'array', 'size:23'], 'items.*.prize_type' => ['required', 'string', Rule::in(['first', 'second', 'third', 'starter', 'consolation'])], 'items.*.prize_index' => ['required', 'integer', 'min:0', 'max:9'], 'items.*.number_4d' => ['required', 'regex:/^[0-9]{4}$/'], ]; } public function withValidator($validator): void { $validator->after(function ($validator): void { $expected = $this->slotKeys(DrawPrizeLayout::slots()); $actual = $this->slotKeys((array) $this->input('items', [])); sort($expected); sort($actual); if ($actual !== $expected) { $validator->errors()->add('items', __('validation.exact.items_must_contain_23_slots')); } }); } /** * @param array> $items * @return list */ private function slotKeys(array $items): array { $keys = []; foreach ($items as $item) { $keys[] = (string) ($item['prize_type'] ?? '').':'.(string) ($item['prize_index'] ?? ''); } return $keys; } }