merge([ 'contacts' => \collect($this->contacts)->filter() ->map(function ($contact) { $contact = \collect($contact); if ($contact->has('data')) { $contact->put('data', \collect($contact->get('data'))->all()); $contact->put('dataParsed', \collect($contact->get('data')) ->map(function ($value, $index) { return \call_user_func([$this, 'filterDataLine'], $value, $index); }) ->filter()->all()); } if ($contact->has('visits')) { $contact->put('visits', \collect($contact->get('visits'))->filter() ->map(function ($visit) { if (!\is_array($visit)) { return $visit; } $visit = \collect($visit); $visit->put('note', $visit->get('note') ?? ''); return $visit->all(); })->all()); } return $contact->all(); })->all() ]); } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'contacts' => 'present|array', 'contacts.*' => 'array', 'contacts.*.id' => 'nullable|uuid|exists:contacts,id', 'contacts.*.lastname' => 'required|string|max:255', 'contacts.*.firstname' => 'required|string|max:255', // * Dot not validate email here (soft validate), if it does not pass, app will be blocked. 'contacts.*.email' => 'required|string|max:255', 'contacts.*.phone' => 'nullable|string|max:255', // * DATA 'contacts.*.data' => 'present|array', 'contacts.*.dataParsed' => 'present', 'contacts.*.data.*' => 'array', 'contacts.*.data.*.title' => 'present|string|min:1', 'contacts.*.data.*.type' => ['present', new EnumIsValidRule(InputTypeEnum::class)], 'contacts.*.data.*.value' => 'present', 'contacts.*.data.*.required' => 'present|boolean', 'contacts.*.notes' => 'nullable|string', 'contacts.*.visits' => 'present|array', 'contacts.*.visits.*' => 'required|array', 'contacts.*.visits.*.title' => 'present|string', 'contacts.*.visits.*.note' => 'present|string', ]; } /** * Handle a line of data (input) * * @param array $data * @param mixed $index * @return mixed * @throws \Illuminate\Validation\ValidationException In case of parse failure. */ private function filterDataLine(array $data, $index) { $data = \collect($data); try { $title = $data->get('title') ? \strval($data->get('title')) : null; if (\is_null($title)) { throw ValidationException::withMessages([ 'error' => "wrong title on data index '{$index}'" ]); } $type = InputTypeEnum::make($data->get('type') ? $data->get('type') : null); $value = $data['value'] ?? null; $required = $data->get('required') ? true : false; $inputClass = $type->inputClass; return $inputClass::from(InputData::make( $title, $type, $value, $required ), $required); } catch (\TypeError | \BadMethodCallException $e) { throw ValidationException::withMessages([ 'error' => "wrong type on data index '{$index}'" ]); } catch (\RuntimeException $e) { $message = $e->getMessage(); throw ValidationException::withMessages([ 'error' => "wrong data on index '{$index}' '{$message}'" ]); } //end try } }