esc_html__('虚拟用户评价卡片横向滚动。', 'aksrt'), 'classname' => 'widget_aksrt_reviews', ] ); } public function widget($args, $instance): void { $reviews = $this->normalize($instance['reviews'] ?? []); if (!$reviews) { return; } $pc = max(1, min(6, (float) ($instance['desktop_per_view'] ?? 3))); $m = max(1, min(3, (float) ($instance['mobile_per_view'] ?? 1.2))); 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 } $style = sprintf('--aksrt-rev-pc:%s;--aksrt-rev-m:%s;', rtrim(rtrim(number_format($pc, 2, '.', ''), '0'), '.'), rtrim(rtrim(number_format($m, 2, '.', ''), '0'), '.')); echo '
'; echo '
'; foreach ($reviews as $r) { echo '
'; echo '
'; if ($r['avatar'] !== '') { echo ''; } else { echo ''; } echo '
'; if ($r['name'] !== '') { $name_html = esc_html($r['name']); if ($r['url'] !== '') { $name_html = '' . $name_html . ''; } echo '
' . $name_html . '
'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } if ($r['role'] !== '') { echo '
' . esc_html($r['role']) . '
'; } echo '
'; echo '
'; for ($i = 1; $i <= 5; $i++) { echo ''; } echo '
'; if ($r['content'] !== '') { echo '

' . nl2br(esc_html($r['content'])) . '

'; } echo ''; echo '
'; } echo '
'; echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } /** * @param mixed $raw * @return array */ private function normalize($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'] ?? '')); $content = sanitize_textarea_field((string) ($row['content'] ?? '')); if ($name === '' && $content === '') { continue; } $out[] = [ 'name' => $name, 'role' => sanitize_text_field((string) ($row['role'] ?? '')), 'avatar' => esc_url_raw(trim((string) ($row['avatar'] ?? ''))), 'content' => $content, 'rating' => max(0, min(5, (int) ($row['rating'] ?? 5))), 'url' => esc_url_raw(trim((string) ($row['url'] ?? ''))), ]; if (count($out) >= 20) { break; } } return $out; } public function form($instance): void { $json = is_string($instance['reviews'] ?? null) ? (string) $instance['reviews'] : wp_json_encode($this->normalize($instance['reviews'] ?? []), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>

sanitize_text_field((string) ($new_instance['title'] ?? '')), 'reviews' => $this->normalize($new_instance['reviews'] ?? []), 'desktop_per_view' => max(1, min(6, (float) ($new_instance['desktop_per_view'] ?? 3))), 'mobile_per_view' => max(1, min(3, (float) ($new_instance['mobile_per_view'] ?? 1.2))), ]; } }