- '); }
+function wp_json_encode($value): string { return (string) json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); }
+function absint($value): int { return abs((int) $value); }
+function checked($actual, $expected = true, bool $display = true): string {
+ $result = $actual == $expected ? 'checked="checked"' : '';
+ if ($display) echo $result;
+ return $result;
+}
+function selected($actual, $expected = true, bool $display = true): string {
+ $result = $actual == $expected ? 'selected="selected"' : '';
+ if ($display) echo $result;
+ return $result;
+}
+function number_format_i18n($number): string { return number_format((float) $number); }
+function wp_trim_words($text, int $count = 55): string {
+ $words = preg_split('/\s+/', trim((string) $text)) ?: [];
+ return implode(' ', array_slice($words, 0, $count));
+}
+
+function get_option(string $name, $default = false) { return $GLOBALS['aksrt_test_state']['options'][$name] ?? $default; }
+function update_option(string $name, $value): bool { $GLOBALS['aksrt_test_state']['options'][$name] = $value; return true; }
+function wp_get_sidebars_widgets(): array { return $GLOBALS['aksrt_test_state']['sidebars']; }
+function wp_set_sidebars_widgets(array $sidebars): void { $GLOBALS['aksrt_test_state']['sidebars'] = $sidebars; }
+function register_rest_route(string $namespace, string $route, array $args): bool {
+ $GLOBALS['aksrt_test_state']['routes'][$namespace . $route] = $args;
+ return true;
+}
+function rest_ensure_response($data): WP_REST_Response { return $data instanceof WP_REST_Response ? $data : new WP_REST_Response($data); }
+function is_wp_error($value): bool { return $value instanceof WP_Error; }
+function is_singular(): bool { return (bool) $GLOBALS['aksrt_test_state']['singular']; }
+function get_queried_object_id(): int { return (int) $GLOBALS['aksrt_test_state']['current_id']; }
+function get_post($post = null) {
+ if ($post instanceof WP_Post) return $post;
+ return $GLOBALS['aksrt_test_state']['current_post'];
+}
+function aksrt_get_widget_null(string $message): string { return '
' . esc_html($message) . '
'; }
+function aksrt_get_pay_meta($post = null): array { unset($post); return $GLOBALS['aksrt_test_state']['pay_meta']; }
+function aksrt_has_paid_access($post = null): bool { unset($post); return (bool) $GLOBALS['aksrt_test_state']['paid_access']; }
+function aksrt_get_paywall_html(WP_Post $post, array|bool $options = false): string {
+ unset($post, $options);
+ $meta = $GLOBALS['aksrt_test_state']['pay_meta'];
+ if ((string) ($meta['pay_type'] ?? 'no') === 'no') {
+ return '';
+ }
+ if ((bool) $GLOBALS['aksrt_test_state']['paid_access']) {
+ return '内容已解锁
';
+ }
+ $state = $GLOBALS['aksrt_test_state']['logged_in'] ? 'member-locked' : 'guest-locked';
+ return 'PAYWALL
';
+}
+function aksrt_get_pay_attributes_html($post, string $class): string { unset($post); return ''; }
+function aksrt_get_demo_link_html($post, string $class): string { unset($post); return 'DEMO'; }
+function is_user_logged_in(): bool { return (bool) $GLOBALS['aksrt_test_state']['logged_in']; }
+function wp_parse_args($args, array $defaults = []): array {
+ return array_merge($defaults, is_array($args) ? $args : []);
+}
+function wp_is_mobile(): bool { return false; }
+function wp_strip_all_tags(string $value): string { return trim(strip_tags($value)); }
+function wp_kses(string $value, array $allowed_html = [], array $allowed_protocols = []): string {
+ unset($allowed_html, $allowed_protocols);
+ // 桩环境信任来源:生产侧的 wp_kses 白名单允许 div/badge 等组合卡标记。
+ return (string) $value;
+}
+function aksrt_is_lazy(string $key, bool $default = false): bool { unset($key, $default); return true; }
+function aksrt_get_lazy_thumb(string $size = ''): string {
+ return 'https://example.test/thumbnail' . ($size !== '' ? '-' . sanitize_key($size) : '') . '.svg';
+}
+function aksrt_get_lazy_attr(string $key, string $src, string $class = '', string $lazy_src = ''): string {
+ unset($key);
+ $class = trim($class);
+ if ($src === '') {
+ return ' class="' . esc_attr($class) . '" src=""';
+ }
+ $lazy_src = $lazy_src !== '' ? $lazy_src : aksrt_get_lazy_thumb();
+ return ' class="lazyload ' . esc_attr($class) . '" src="' . esc_url($lazy_src) . '" data-src="' . esc_url($src) . '"';
+}
+
+require dirname(__DIR__, 2) . '/inc/helpers/aksrt-icons.php';
+require dirname(__DIR__, 2) . '/inc/helpers/aksrt-graphic-card.php';
+require dirname(__DIR__, 2) . '/vendor/autoload.php';
diff --git a/tests/widget-system/post-visual-contract.test.cjs b/tests/widget-system/post-visual-contract.test.cjs
index 07b81c7f..50890041 100644
--- a/tests/widget-system/post-visual-contract.test.cjs
+++ b/tests/widget-system/post-visual-contract.test.cjs
@@ -184,7 +184,8 @@ test('list, card, media, badge and Mini DOM follow dedicated legacy structures',
assert.ok(commentMeta >= 0 && commentMeta < viewMeta && viewMeta < likeMeta);
assert.match(data, /comments_open.*close_comments/s);
assert.match(data, /show_like.*post_type.*=== 'post'/s);
- assert.match(data, /