fix(frontend): close single 1:1 residuals without legacy paths
Unify TOC ownership, real video episode list, slider overlay, single-query related list, Zibll user-card after-box, and new-route subtitle/meta contracts.
This commit is contained in:
1 parent
48f7436030
commit
5ce43c4326
10 files changed
+1373
-1298
No files matched your search
@@ -43,8 +43,46 @@ class AKSRT_Post_Meta_Box {
|
||||
public static function get_meta(int $post_id): array {
|
||||
$defaults = AKSRT_Domain_Model::default_post_meta();
|
||||
$saved = get_post_meta($post_id, self::META_KEY, true);
|
||||
if (!is_array($saved)) $saved = [];
|
||||
return array_merge($defaults, $saved);
|
||||
if (!is_array($saved)) {
|
||||
$saved = [];
|
||||
}
|
||||
$meta = array_merge($defaults, $saved);
|
||||
// New route only: episodes is always a list of {url,title}.
|
||||
$meta['featured_video_episode'] = self::sanitize_video_episodes($meta['featured_video_episode'] ?? []);
|
||||
if (!in_array((string) ($meta['show_toc'] ?? ''), ['', '0', '1'], true)) {
|
||||
$meta['show_toc'] = '';
|
||||
}
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize video episode list (new route: array of url/title rows).
|
||||
*
|
||||
* @param mixed $raw Raw form / meta value.
|
||||
* @return array<int, array{url:string,title:string}>
|
||||
*/
|
||||
public static function sanitize_video_episodes($raw): array {
|
||||
if (!is_array($raw)) {
|
||||
return [];
|
||||
}
|
||||
$out = [];
|
||||
foreach ($raw as $row) {
|
||||
if (!is_array($row)) {
|
||||
continue;
|
||||
}
|
||||
$url = esc_url_raw((string) ($row['url'] ?? ''));
|
||||
if ($url === '') {
|
||||
continue;
|
||||
}
|
||||
$out[] = [
|
||||
'url' => $url,
|
||||
'title' => sanitize_text_field((string) ($row['title'] ?? '')),
|
||||
];
|
||||
if (count($out) >= 50) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,10 +185,12 @@ class AKSRT_Post_Meta_Box {
|
||||
</select>
|
||||
|
||||
<p>
|
||||
<label>
|
||||
<input type="checkbox" name="aksrt_post_meta[show_toc]" value="1" <?php checked($meta['show_toc'] === '1'); ?>>
|
||||
<?php esc_html_e('显示目录树', 'aksrt'); ?>
|
||||
</label>
|
||||
<label for="aksrt_show_toc"><strong><?php esc_html_e('目录树', 'aksrt'); ?></strong></label>
|
||||
<select name="aksrt_post_meta[show_toc]" id="aksrt_show_toc" class="widefat">
|
||||
<option value="" <?php selected((string) ($meta['show_toc'] ?? ''), ''); ?>><?php esc_html_e('跟随全局', 'aksrt'); ?></option>
|
||||
<option value="1" <?php selected((string) ($meta['show_toc'] ?? ''), '1'); ?>><?php esc_html_e('强制开启', 'aksrt'); ?></option>
|
||||
<option value="0" <?php selected((string) ($meta['show_toc'] ?? ''), '0'); ?>><?php esc_html_e('强制关闭', 'aksrt'); ?></option>
|
||||
</select>
|
||||
</p>
|
||||
|
||||
<p><strong><?php esc_html_e('单篇交互覆盖', 'aksrt'); ?></strong></p>
|
||||
@@ -210,11 +250,24 @@ class AKSRT_Post_Meta_Box {
|
||||
<small class="description"><?php esc_html_e('多张图片 URL 用逗号分隔,用于封面轮播。', 'aksrt'); ?></small>
|
||||
|
||||
<p><strong><?php esc_html_e('特色视频', 'aksrt'); ?></strong></p>
|
||||
<input type="url" name="aksrt_post_meta[featured_video]" value="<?php echo esc_url($meta['featured_video']); ?>" class="widefat" placeholder="<?php esc_attr_e('视频 URL(嵌入/直链)', 'aksrt'); ?>">
|
||||
<input type="url" name="aksrt_post_meta[featured_video]" value="<?php echo esc_url($meta['featured_video']); ?>" class="widefat" placeholder="<?php esc_attr_e('第 1 集视频 URL(直链)', 'aksrt'); ?>">
|
||||
|
||||
<p><strong><?php esc_html_e('视频集数', 'aksrt'); ?></strong></p>
|
||||
<input type="number" name="aksrt_post_meta[featured_video_episode]" value="<?php echo esc_attr((string) (int) $meta['featured_video_episode']); ?>" class="widefat" min="0" max="9999" step="1">
|
||||
<small class="description"><?php esc_html_e('0 表示非剧集,>0 表示第 N 集。', 'aksrt'); ?></small>
|
||||
<p><strong><?php esc_html_e('视频剧集列表', 'aksrt'); ?></strong></p>
|
||||
<?php
|
||||
$episodes = is_array($meta['featured_video_episode'] ?? null) ? $meta['featured_video_episode'] : [];
|
||||
// Always show at least 3 editable rows for new-route authoring.
|
||||
$rows = max(3, count($episodes));
|
||||
for ($i = 0; $i < $rows; $i++) :
|
||||
$ep = is_array($episodes[$i] ?? null) ? $episodes[$i] : [];
|
||||
$ep_url = (string) ($ep['url'] ?? '');
|
||||
$ep_title = (string) ($ep['title'] ?? '');
|
||||
?>
|
||||
<p class="aksrt-episode-row">
|
||||
<input type="text" name="aksrt_post_meta[featured_video_episode][<?php echo (int) $i; ?>][title]" value="<?php echo esc_attr($ep_title); ?>" class="widefat" placeholder="<?php echo esc_attr(sprintf(__('第 %d 集标题(可选)', 'aksrt'), $i + 1)); ?>" style="margin-bottom:4px;">
|
||||
<input type="url" name="aksrt_post_meta[featured_video_episode][<?php echo (int) $i; ?>][url]" value="<?php echo esc_url($ep_url); ?>" class="widefat" placeholder="<?php echo esc_attr(sprintf(__('第 %d 集视频 URL', 'aksrt'), $i + 1)); ?>">
|
||||
</p>
|
||||
<?php endfor; ?>
|
||||
<small class="description"><?php esc_html_e('新路线:每行一集(标题 + URL)。留空 URL 的行会被忽略。第 1 集可与上方「特色视频」二选一填写。', 'aksrt'); ?></small>
|
||||
|
||||
<hr>
|
||||
<p><strong><?php esc_html_e('手动计数覆盖', 'aksrt'); ?></strong></p>
|
||||
@@ -308,7 +361,8 @@ class AKSRT_Post_Meta_Box {
|
||||
'custom_excerpt' => isset($raw['custom_excerpt']) ? sanitize_textarea_field($raw['custom_excerpt']) : '',
|
||||
'layout_override' => isset($raw['layout_override']) ? sanitize_key($raw['layout_override']) : '',
|
||||
'header_image_mode' => isset($raw['header_image_mode']) ? sanitize_key($raw['header_image_mode']) : '',
|
||||
'show_toc' => !empty($raw['show_toc']) ? '1' : '',
|
||||
// New route: '' follow | '1' force on | '0' force off.
|
||||
'show_toc' => isset($raw['show_toc']) && in_array((string) $raw['show_toc'], ['', '0', '1'], true) ? (string) $raw['show_toc'] : '',
|
||||
'show_reading_progress' => isset($raw['show_reading_progress']) ? sanitize_key((string) $raw['show_reading_progress']) : '',
|
||||
'enable_lightbox' => isset($raw['enable_lightbox']) ? sanitize_key((string) $raw['enable_lightbox']) : '',
|
||||
'show_related' => isset($raw['show_related']) ? sanitize_key((string) $raw['show_related']) : '',
|
||||
@@ -324,7 +378,7 @@ class AKSRT_Post_Meta_Box {
|
||||
'thumbnail_url' => isset($raw['thumbnail_url']) ? esc_url_raw((string) $raw['thumbnail_url']) : '',
|
||||
'featured_slide' => isset($raw['featured_slide']) ? sanitize_text_field($raw['featured_slide']) : '',
|
||||
'featured_video' => isset($raw['featured_video']) ? esc_url_raw((string) $raw['featured_video']) : '',
|
||||
'featured_video_episode' => isset($raw['featured_video_episode']) ? max(0, (int) $raw['featured_video_episode']) : 0,
|
||||
'featured_video_episode' => self::sanitize_video_episodes($raw['featured_video_episode'] ?? []),
|
||||
'subtitle' => isset($raw['subtitle']) ? sanitize_text_field($raw['subtitle']) : '',
|
||||
'views' => isset($raw['views']) ? max(0, (int) $raw['views']) : 0,
|
||||
'likes' => isset($raw['likes']) ? max(0, (int) $raw['likes']) : 0,
|
||||
|
||||
Reference in new issue
Block a user