Files
wordpress-theme-aksrt/inc/helpers/jio-user-home.php
T
kate522andClaude Opus 5 427968a721 chore(branding): remove leftover upstream theme identifiers
The theme was renamed Zibll/子比 → AKSRT → Jio, but upstream branding
survived the sweeps in CSS classes, the SVG sprite prefix, a persisted
widget field ID, JS events, admin Vue class names, test infrastructure
and docblocks.

Renames:
- zib-widget / zib-widget-wrap / zib-slider → jio-widget-box /
  jio-widget-box-wrap / jio-slider-box (jio-widget is taken by the modern
  widget shell, jio-box-* by the card primitives)
- zib-partners-scroll + zps-* → jio-partners-scroll + jps-*
- zib-combo-info-card + zci-* → jio-combo-info-card + jci-*
- zibsvg- → jiosvg-, including the exported picker helpers and the
  fa-zibsvg- family-prefix guard
- zibpay_type → pay_type; the dual-read fallback in PostQuery collapses
  to a single key
- [zibajax="submit"] dropped (no PHP emitter); zib_ajax.success →
  jio_ajax.success
- aks-* admin Vue classes → jio-*
- zib_palette() → palette()

User-facing vendor traces are gone: the floating "more" button default no
longer ships a zibll.com link or 子比主题 marketing copy, the notice
widget ships no preset promo entries, and the four 官网教程 links are
removed from the post-list admin schema.

Test infrastructure renamed to neutral names (docker-compose.reference.yml,
Caddyfile, article-baseline.json, modern-widgets-contract.test.cjs) with
their DB/volume/env/slug identifiers following.

Kept intentionally, documented in tests/fixtures/README.md: the golden
fixture reference fingerprint (a SHA-256 record of an external directory,
read by validate-widget-golden / generate-widget-golden-fixture /
audit-widget-system), the doesNotMatch guards that prove the old tokens are
gone, and the reference theme's own meta key in the visual fixtures.

No backward-compat or data migration: saved widget configs holding old
icon keys or the old field ID silently lose them, per the project's
rewrite-over-compatibility rule.

Verified: 132/132 node contract tests, php tests/widget-system/run.php
(146 assertions), audit-admin-contracts, audit-psr4-paths and
validate-widget-golden all green; tracked bundles regenerated and in sync.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-02 00:06:54 +08:00

233 lines
8.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Public user-home template context builder.
*
* Keeps page-user-home.php as a thin shell that only mounts parts.
*
* @package Jio
*/
defined('ABSPATH') || exit;
if (!function_exists('jio_get_user_home_page_context')) {
/**
* Build the render context for the public user homepage shell.
*
* @param WP_User $user Target user.
* @return array<string, mixed>
*/
function jio_get_user_home_page_context(WP_User $user): array {
$user_id = (int) $user->ID;
$dashboard = function_exists('jio_get_user_dashboard_view')
? jio_get_user_dashboard_view($user_id, ['viewer_id' => get_current_user_id()])
: [];
$is_own_profile = !empty($dashboard['is_own_profile']);
$user_home_settings = class_exists('\Jio\Settings\Settings')
? \Jio\Settings\Settings::get_user_home_settings()
: [
'tabs' => ['posts', 'favorites', 'comments', 'follow'],
'sidebar' => false,
'cover' => true,
'follow' => true,
'posts_per_page' => 10,
];
$post_count = (int) ($dashboard['post_count'] ?? 0);
$comment_count = (int) ($dashboard['comment_count'] ?? 0);
$favorite_post_ids = $dashboard['favorite_post_ids'] ?? [];
$favorite_count = (int) ($dashboard['favorite_count'] ?? 0);
$profile_details = $dashboard['profile_details'] ?? [];
$per_page = max(1, (int) ($user_home_settings['posts_per_page'] ?? 10));
$credits_enabled = !empty($dashboard['credits_enabled']);
$credit_balance = $dashboard['credit_balance'] ?? 0.0;
$currency_name = $dashboard['currency_name'] ?? __('积分', 'jio');
$user_home_manager = class_exists('\Jio\User\Home') ? \Jio\User\Home::get_instance() : null;
$visible_tabs = $user_home_manager ? $user_home_manager->get_visible_tabs($is_own_profile) : [];
$enabled_tabs = array_keys($visible_tabs);
if (empty($enabled_tabs)) {
$enabled_tabs = ['posts', 'comments', 'favorites'];
}
// Apply admin-configured display order.
$order = $user_home_settings['tabs_order'] ?? [];
$ordered = [];
foreach ((array) $order as $tab_key) {
if (in_array($tab_key, $enabled_tabs, true)) {
$ordered[] = $tab_key;
}
}
foreach ($enabled_tabs as $tab_key) {
if (!in_array($tab_key, $ordered, true)) {
$ordered[] = $tab_key;
}
}
$enabled_tabs = $ordered;
$pc_hide = $user_home_settings['tabs_pc_hide'] ?? [];
$mobile_hide = $user_home_settings['tabs_mobile_hide'] ?? [];
$enabled_tabs_pc = array_values(array_diff($enabled_tabs, (array) $pc_hide));
$enabled_tabs_mobile = array_values(array_diff($enabled_tabs, (array) $mobile_hide));
$is_mobile = function_exists('wp_is_mobile') && wp_is_mobile();
$display_tabs = $is_mobile ? $enabled_tabs_mobile : $enabled_tabs_pc;
$default_tab = !empty($display_tabs) ? $display_tabs[0] : $enabled_tabs[0];
$empty_svgs = jio_empty_state_svgs();
$follow_count = 0;
if (class_exists('\Jio\User\Follow')) {
$follow_count = (int) \Jio\User\Follow::get_instance()->get_follower_count($user_id);
}
$tab_counts = [
'posts' => $post_count,
'comments' => $comment_count,
'favorites' => $favorite_count,
'credits' => $credits_enabled && $is_own_profile ? (int) round((float) $credit_balance) : 0,
'follow' => $follow_count,
];
$tab_labels = [
'posts' => __('文章', 'jio'),
'comments' => __('评论', 'jio'),
'favorites' => __('收藏', 'jio'),
'credits' => sprintf(__('我的%s', 'jio'), $currency_name),
'follow' => __('粉丝', 'jio'), // legacy: 粉丝
];
foreach ($visible_tabs as $tab_key => $tab_config) {
if (!empty($tab_config['label'])) {
$tab_labels[$tab_key] = (string) $tab_config['label'];
}
}
$active_tab = $default_tab;
$home_url = function_exists('jio_get_user_home_url') ? jio_get_user_home_url($user) : home_url('/');
return [
'user' => $user,
'user_id' => $user_id,
'dashboard' => $dashboard,
'is_own_profile' => $is_own_profile,
'user_home_settings' => $user_home_settings,
'profile_details' => $profile_details,
'post_count' => $post_count,
'comment_count' => $comment_count,
'favorite_post_ids' => $favorite_post_ids,
'favorite_count' => $favorite_count,
'per_page' => $per_page,
'credits_enabled' => $credits_enabled,
'credit_balance' => $credit_balance,
'currency_name' => $currency_name,
'enabled_tabs' => $enabled_tabs,
'tabs_pc_hide' => (array) $pc_hide,
'tabs_mobile_hide' => (array) $mobile_hide,
'default_tab' => $default_tab,
'active_tab' => $active_tab,
'tab_counts' => $tab_counts,
'tab_labels' => $tab_labels,
'home_url' => $home_url,
'posts_page' => 1,
'comments_page' => 1,
'favorites_page' => 1,
'follow_sub' => 'followers',
'follow_page' => 1,
'svg_empty_post' => $empty_svgs['post'],
'svg_empty_comment' => $empty_svgs['comment'],
'svg_empty_favorite' => $empty_svgs['favorite'],
'svg_empty_follow' => $empty_svgs['follow'],
];
}
}
if (!function_exists('jio_render_user_home_pagination')) {
/**
* 渲染公开用户主页面板的无刷新数字分页(按钮驱动,无 URL 参数)。
*
* 复用 .profile-pagination / .page-numbers 既有样式契约。
*
* @param int $total_pages 总页数。
* @param int $current 当前页。
*/
function jio_render_user_home_pagination(int $total_pages, int $current): void {
$total_pages = max(1, $total_pages);
$current = min(max(1, $current), $total_pages);
if ($total_pages <= 1) {
return;
}
$items = [];
for ($i = 1; $i <= $total_pages; $i++) {
if ($i === 1 || $i === $total_pages || abs($i - $current) <= 1) {
$items[] = (string) $i;
} elseif ($items && end($items) !== '…') {
$items[] = '…';
}
}
echo '<nav class="profile-pagination uh-pagination" aria-label="' . esc_attr__('分页', 'jio') . '">';
if ($current > 1) {
echo '<button type="button" class="page-numbers" data-uh-page="' . esc_attr((string) ($current - 1)) . '"><span aria-hidden="true">&lsaquo;</span><span class="screen-reader-text">' . esc_html__('上一页', 'jio') . '</span></button>';
}
foreach ($items as $item) {
if ($item === '…') {
echo '<span class="page-numbers dots">&hellip;</span>';
continue;
}
if ((int) $item === $current) {
echo '<span class="page-numbers current" aria-current="page">' . esc_html($item) . '</span>';
continue;
}
echo '<button type="button" class="page-numbers" data-uh-page="' . esc_attr($item) . '">' . esc_html($item) . '</button>';
}
if ($current < $total_pages) {
echo '<button type="button" class="page-numbers" data-uh-page="' . esc_attr((string) ($current + 1)) . '"><span aria-hidden="true">&rsaquo;</span><span class="screen-reader-text">' . esc_html__('下一页', 'jio') . '</span></button>';
}
echo '</nav>';
}
}
if (!function_exists('jio_get_user_home_follow_placeholder')) {
/**
* Skeleton cards used while the public home follow panel is loading.
*/
function jio_get_user_home_follow_placeholder(): string {
$item = '<div class="author-minicard radius8 flex ac uh-follow__placeholder" aria-hidden="true">'
. '<div class="avatar-img mr10"><div class="avatar placeholder"></div></div>'
. '<div class="flex1"><div class="placeholder k1 mb6"></div>'
. '<i><i class="placeholder s1"></i><i class="placeholder s1 ml10"></i></i></div></div>';
return '<div class="uh-follow__list uh-follow__list--placeholder" role="status" aria-label="' . esc_attr__('正在加载', 'jio') . '">'
. str_repeat($item, 6)
. '</div>';
}
}
if (!function_exists('jio_capture_user_home_panel')) {
/**
* 捕获公开用户主页面板 body(templates/parts/user-home/panel-{tab}.php)。
*
* @param string $tab 面板键名。
* @param array<string, mixed> $ctx jio_get_user_home_page_context() 上下文。
* @return string 捕获的 HTML,模板不存在时为空串。
*/
function jio_capture_user_home_panel(string $tab, array $ctx): string {
$template = locate_template(['templates/parts/user-home/panel-' . sanitize_key($tab) . '.php'], false, false);
if (!$template) {
return '';
}
// 面板 body 依赖的空态/分页助手位于模板侧共享文件,REST 片段上下文不会自动加载。
if (!function_exists('jio_render_profile_empty')) {
require_once JIO_DIR . '/templates/parts/user-shared-helpers.php';
}
ob_start();
load_template($template, false, $ctx);
return (string) ob_get_clean();
}
}