}> */ public static function items(): array { $value = json_decode((string) Setting::where('key', self::SETTING_KEY)->value('value'), true); return is_array($value) ? $value : []; } /** * @return array */ public static function rules(): array { return [ 'items' => 'present|array|max:30', 'items.*' => 'array', 'items.*.title' => 'required|string|max:60', 'items.*.icon' => ['nullable', 'string', 'max:100', 'regex:' . self::ICON_PATTERN], 'items.*.href' => ['nullable', 'required_without:items.*.children', 'string', 'max:255', 'regex:' . self::HREF_PATTERN], 'items.*.disabled' => 'sometimes|boolean', 'items.*.children' => 'sometimes|array|max:20', 'items.*.children.*.title' => 'required|string|max:60', 'items.*.children.*.icon' => ['nullable', 'string', 'max:100', 'regex:' . self::ICON_PATTERN], 'items.*.children.*.href' => ['required', 'string', 'max:255', 'regex:' . self::HREF_PATTERN], 'items.*.children.*.disabled' => 'sometimes|boolean', ]; } /** * @param array> $items */ public static function save(array $items): array { $normalized = array_map(fn (array $item) => [ ...self::normalizeLink($item), 'children' => array_map(self::normalizeLink(...), array_values($item['children'] ?? [])), ], array_values($items)); Setting::updateOrCreate(['key' => self::SETTING_KEY], ['value' => json_encode($normalized, JSON_UNESCAPED_UNICODE)]); return $normalized; } /** * @param array $item * @return array{title: string, icon: ?string, href: ?string, disabled: bool} */ public static function normalizeLink(array $item): array { return [ 'title' => trim((string) $item['title']), 'icon' => ($item['icon'] ?? '') !== '' ? (string) $item['icon'] : null, 'href' => ($item['href'] ?? '') !== '' ? (string) $item['href'] : null, 'disabled' => (bool) ($item['disabled'] ?? false), ]; } }