'required|string|between:3,255', 'view' => 'sometimes|nullable|string|between:3,255', 'config' => ['required', 'array', 'min:1'], ] + $this->configRules('config.*'); } /** * Recursively generates rules for a given key. * * @param string $prefix * @param integer $depth * @return array */ protected function configRules(string $prefix, int $depth = 1): array { $rules = [ "{$prefix}" => 'required|array|between:5,6', "{$prefix}.key" => [ 'required', 'string', 'between:3,255', 'regex:/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/', function ($attribute, $value, $fail) use ($prefix) { $parentPath = implode('.', array_slice(explode('.', $attribute), 0, -2)); $levelItems = data_get($this->input(), $parentPath, []); $keysAtLevel = collect($levelItems)->pluck('key')->filter()->toArray(); if (count(array_filter($keysAtLevel, fn($k) => $k === $value)) > 1) { $fail("The {$attribute} must be unique at its level."); } } ], "{$prefix}.order" => 'required|numeric|min:1', "{$prefix}.type" => ['required', new Enum(DynamicFieldTypes::class)], "{$prefix}.label" => 'required|string|between:3,255', "{$prefix}.validation" => 'required|string|between:3,255', ]; if ($depth < 10) { $rules["{$prefix}.children"] = ['sometimes', 'array']; $rules += $this->configRules("{$prefix}.children.*", $depth + 1); } return $rules; } /** * Get custom attributes for validator errors. * * @return array */ public function attributes(): array { return [ 'label' => trans('validation.custom.label'), 'view' => trans('validation.custom.view'), 'config' => trans('validation.custom.config'), ] + $this->configAttributes('config.*'); } /** * Recursively generates attributes for a given key. * * @param string $prefix * @param integer $depth * @return array */ protected function configAttributes(string $prefix, int $depth = 1): array { $rules = [ "{$prefix}" => trans('validation.custom.config'), "{$prefix}.key" => trans('validation.custom.key'), "{$prefix}.order" => trans('validation.custom.order'), "{$prefix}.type" => trans('validation.custom.type'), "{$prefix}.label" => trans('validation.custom.label'), "{$prefix}.validation" => trans('validation.custom.validation'), ]; if ($depth < 10) { $rules["{$prefix}.children"] = trans('validation.custom.children'); $rules += $this->configAttributes("{$prefix}.children.*", $depth + 1); } return $rules; } }