aksrt_sanitize_icon_value((string) ($raw['icon'] ?? '')), 'badge' => sanitize_text_field((string) ($raw['badge'] ?? '')), 'badge_class' => sanitize_html_class((string) ($raw['badge_class'] ?? '')), 'submenu_s' => !empty($raw['submenu_s']), 'submenu_type' => sanitize_key((string) ($raw['submenu_type'] ?? '')), ]; $graphic = self::decode_json_field((string) ($raw['graphic_card_opts_json'] ?? '')); if (is_array($graphic)) { $clean['graphic_card_opts'] = self::sanitize_graphic_opts($graphic); } $multi = self::decode_json_field((string) ($raw['multi_column_links_opts_json'] ?? '')); if (is_array($multi)) { $clean['multi_column_links_opts'] = self::sanitize_multi_opts($multi); } update_post_meta($menu_item_db_id, 'aksrt_menu_options', $clean); } /** * @return array|null */ private static function decode_json_field(string $json): ?array { $json = trim($json); if ($json === '') { return null; } $data = json_decode($json, true); return is_array($data) ? $data : null; } /** * @param array $opts * @return array */ private static function sanitize_graphic_opts(array $opts): array { $items_in = is_array($opts['items'] ?? null) ? $opts['items'] : []; $items = []; foreach ($items_in as $item) { if (!is_array($item)) { continue; } $items[] = [ 'img' => esc_url_raw((string) ($item['img'] ?? '')), 'title' => sanitize_text_field((string) ($item['title'] ?? '')), 'badge' => sanitize_text_field((string) ($item['badge'] ?? '')), 'badge_class' => sanitize_html_class((string) ($item['badge_class'] ?? '')), 'link' => [ 'url' => esc_url_raw((string) ($item['link']['url'] ?? '')), 'text' => sanitize_text_field((string) ($item['link']['text'] ?? '')), 'target' => sanitize_text_field((string) ($item['link']['target'] ?? '')), ], ]; } return [ 'arrangement' => sanitize_key((string) ($opts['arrangement'] ?? '')), 'align' => sanitize_key((string) ($opts['align'] ?? '')), 'size' => sanitize_key((string) ($opts['size'] ?? '')), 'img_scale' => max(0, min(200, (int) ($opts['img_scale'] ?? 100))), 'items' => $items, ]; } /** * @param array $opts * @return array */ private static function sanitize_multi_opts(array $opts): array { $columns_in = is_array($opts['columns'] ?? null) ? $opts['columns'] : []; $columns = []; foreach ($columns_in as $col) { if (!is_array($col)) { continue; } $items = []; if (!empty($col['items']) && is_array($col['items'])) { foreach ($col['items'] as $item) { if (!is_array($item)) { continue; } $items[] = [ 'title' => sanitize_text_field((string) ($item['title'] ?? '')), 'icon' => sanitize_text_field((string) ($item['icon'] ?? '')), 'img_icon' => esc_url_raw((string) ($item['img_icon'] ?? '')), 'link' => [ 'url' => esc_url_raw((string) ($item['link']['url'] ?? '')), 'text' => sanitize_text_field((string) ($item['link']['text'] ?? '')), 'target' => sanitize_text_field((string) ($item['link']['target'] ?? '')), ], ]; } } $columns[] = [ 'title' => sanitize_text_field((string) ($col['title'] ?? '')), 'icon' => sanitize_text_field((string) ($col['icon'] ?? '')), 'img_icon' => esc_url_raw((string) ($col['img_icon'] ?? '')), 'link' => [ 'url' => esc_url_raw((string) ($col['link']['url'] ?? '')), 'text' => sanitize_text_field((string) ($col['link']['text'] ?? '')), 'target' => sanitize_text_field((string) ($col['link']['target'] ?? '')), ], 'items' => $items, ]; } return ['columns' => $columns]; } private static function sample_graphic_json(): string { $sample = [ 'arrangement' => '', 'size' => 'md', 'img_scale' => 100, 'items' => [ [ 'img' => '', 'title' => '卡片标题', 'badge' => '', 'badge_class' => 'jb-red', 'link' => ['url' => home_url('/'), 'text' => '', 'target' => ''], ], ], ]; return (string) wp_json_encode($sample, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); } private static function sample_multi_json(): string { $sample = [ 'columns' => [ [ 'title' => '栏目一', 'icon' => 'fa fas fa-folder', 'link' => ['url' => '', 'text' => '', 'target' => ''], 'items' => [ ['title' => '链接 A', 'icon' => '', 'link' => ['url' => home_url('/'), 'text' => '', 'target' => '']], ], ], ], ]; return (string) wp_json_encode($sample, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); } }