esc_html__('多列定价卡片 + 信任条(落地页/VIP 介绍)。', 'aksrt'), 'classname' => 'widget_aksrt_pricing_plans', ] ); } public function widget($args, $instance): void { $plans = $this->normalize_plans($instance['lists'] ?? $instance['plans'] ?? []); if (!$plans) { return; } $trust = $this->normalize_trust($instance['trust_items'] ?? []); $currency = sanitize_text_field((string) ($instance['currency'] ?? '¥')); if ($currency === '') { $currency = '¥'; } echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped $title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base); if ($title !== '') { echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } echo '
'; echo '
'; foreach ($plans as $plan) { $accent = sanitize_key((string) ($plan['color'] ?? 'blue')); if (!in_array($accent, ['pink', 'purple', 'blue', 'green', 'yellow', 'cyan'], true)) { $accent = 'blue'; } $featured = !empty($plan['is_featured']); $class = 'aksrt-pricing__card accent-' . $accent . ($featured ? ' is-featured' : ''); echo '
'; if ($featured || !empty($plan['tag'])) { $badge = (string) ($plan['tag'] !== '' ? $plan['tag'] : __('推荐', 'aksrt')); echo '' . esc_html($badge) . ''; } echo '

' . esc_html($plan['name']) . '

'; if ($plan['desc'] !== '') { echo '

' . esc_html($plan['desc']) . '

'; } $price = (float) $plan['price']; $show = (float) $plan['show_price']; echo '
'; echo '' . esc_html($currency) . '' . esc_html($this->fmt($price)) . ''; if ($show > $price && $show > 0) { echo '' . esc_html($currency) . '' . esc_html($this->fmt($show)) . ''; } echo '
'; if ($plan['features']) { echo '
    '; foreach ($plan['features'] as $ft) { echo '
  • ' . esc_html($ft) . '
  • '; } echo '
'; } if ($plan['btn_text'] !== '' && $plan['btn_url'] !== '') { $url = $plan['btn_url']; if (!empty($instance['go_link']) && function_exists('aksrt_go_link')) { $url = aksrt_go_link($url, true); } echo ''; } echo '
'; } echo '
'; if ($trust) { echo '
'; foreach ($trust as $ti) { echo '
'; if ($ti['icon'] !== '') { echo ''; } echo '
' . esc_html($ti['title']) . ''; if ($ti['desc'] !== '') { echo '' . esc_html($ti['desc']) . ''; } echo '
'; } echo '
'; } echo '
'; echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } private function fmt(float $n): string { if (abs($n - round($n)) < 0.001) { return (string) (int) round($n); } return number_format($n, 2, '.', ''); } /** * @param mixed $raw * @return array> */ private function normalize_plans($raw): array { if (is_string($raw)) { $decoded = json_decode($raw, true); $raw = is_array($decoded) ? $decoded : []; } if (!is_array($raw)) { return []; } $out = []; foreach ($raw as $row) { if (!is_array($row)) { continue; } $name = sanitize_text_field((string) ($row['name'] ?? $row['title'] ?? '')); if ($name === '') { continue; } $intro = (string) ($row['intro'] ?? $row['features'] ?? ''); if (is_array($row['features'] ?? null)) { $features = array_values(array_filter(array_map('sanitize_text_field', $row['features']))); } else { $features = array_values(array_filter(array_map('sanitize_text_field', preg_split('/\r\n|\r|\n/', $intro) ?: []))); } $btn = is_array($row['btn'] ?? null) ? $row['btn'] : []; $out[] = [ 'name' => $name, 'desc' => sanitize_text_field((string) ($row['desc'] ?? '')), 'price' => (float) ($row['price'] ?? 0), 'show_price' => (float) ($row['show_price'] ?? 0), 'color' => sanitize_key((string) ($row['color'] ?? 'blue')), 'is_featured' => !empty($row['is_featured']) ? 1 : 0, 'tag' => sanitize_text_field((string) ($row['tag'] ?? '')), 'features' => $features, 'btn_text' => sanitize_text_field((string) ($row['btn_text'] ?? $btn['text'] ?? '')), 'btn_url' => esc_url_raw(trim((string) ($row['btn_url'] ?? $btn['url'] ?? ''))), ]; if (count($out) >= 6) { break; } } return $out; } /** * @param mixed $raw * @return array */ private function normalize_trust($raw): array { if (is_string($raw)) { $decoded = json_decode($raw, true); $raw = is_array($decoded) ? $decoded : []; } if (!is_array($raw)) { return []; } $out = []; foreach ($raw as $row) { if (!is_array($row)) { continue; } $title = sanitize_text_field((string) ($row['title'] ?? '')); if ($title === '') { continue; } $out[] = [ 'title' => $title, 'desc' => sanitize_text_field((string) ($row['desc'] ?? '')), 'icon' => sanitize_text_field((string) ($row['icon'] ?? 'fa fa-check-circle')), ]; if (count($out) >= 6) { break; } } return $out; } public function form($instance): void { $plans = is_string($instance['lists'] ?? null) ? (string) $instance['lists'] : wp_json_encode($this->normalize_plans($instance['lists'] ?? []), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); $trust = is_string($instance['trust_items'] ?? null) ? (string) $instance['trust_items'] : wp_json_encode($this->normalize_trust($instance['trust_items'] ?? []), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>

sanitize_text_field((string) ($new_instance['title'] ?? '')), 'currency' => sanitize_text_field((string) ($new_instance['currency'] ?? '¥')), 'lists' => $this->normalize_plans($new_instance['lists'] ?? []), 'trust_items' => $this->normalize_trust($new_instance['trust_items'] ?? []), 'go_link' => !empty($new_instance['go_link']) ? 1 : 0, ]; } }