*/ function aksrt_get_new_add_actions(array $types = ['post']): array { $out = []; foreach ($types as $type) { $type = sanitize_key((string) $type); if ($type === 'post') { // Front submit page may be unset → aksrt_get_new_post_url() returns ''. // Never drop the publish chip for that: fall back to WP post-new. $url = function_exists('aksrt_get_new_post_url') ? (string) aksrt_get_new_post_url() : ''; if ($url === '') { $url = admin_url('post-new.php'); } $out[] = [ 'type' => 'post', 'url' => $url, 'label' => __('写文章', 'aksrt'), 'icon' => 'fa fas fa-file-alt', ]; } } return $out; } endif; if (!function_exists('aksrt_normalize_header_cta_label')) : /** * Normalize CTA label HTML: map FA5 classes and keep a single leading icon. */ function aksrt_normalize_header_cta_label(string $label, string $fallback_icon = 'fa fas fa-pen'): string { $label = trim($label); if ($label === '') { return ' ' . esc_html__('发布', 'aksrt'); } if (stripos($label, ' .fa). $label = '' . esc_html(wp_strip_all_tags($label)) . ''; } else { $label = preg_replace( '/(<\/i>)\s*([^<].*)$/u', '$1$2', $label ) ?? $label; } return $label; } endif; if (!function_exists('aksrt_render_new_add_btns')) : /** * Multi-type publish button (zibll newadd-btns). * * @param string[] $types */ function aksrt_render_new_add_btns(array $types, string $class = '', string $label = ''): string { $actions = aksrt_get_new_add_actions($types); if (!$actions) { // Last resort: keep a write-post entry so the top-nav chip is never blank. $fallback = function_exists('aksrt_get_new_post_url') ? (string) aksrt_get_new_post_url() : ''; if ($fallback === '') { $fallback = admin_url('post-new.php'); } $actions = [[ 'type' => 'post', 'url' => $fallback, 'label' => __('写文章', 'aksrt'), 'icon' => 'fa fas fa-file-alt', ]]; } if ($label === '') { $label = __('发布', 'aksrt'); } $label_html = aksrt_normalize_header_cta_label((string) $label, 'fa fas fa-pen'); // Split paint classes vs wrapper tokens. $class_tokens = preg_split('/\s+/', trim($class), -1, PREG_SPLIT_NO_EMPTY) ?: []; $cta_tokens = []; $wrap_tokens = ['newadd-btns']; foreach ($class_tokens as $token) { if ($token === 'newadd-btns') { continue; } if ($token === 'btn-primary' || $token === 'but' || $token === 'navbar-cta' || $token === 'radius' || $token === 'main-radius' || $token === 'mini-radius' || str_starts_with($token, 'jb-') || str_starts_with($token, 'b-')) { $cta_tokens[] = $token; continue; } $wrap_tokens[] = $token; } if (!$cta_tokens) { $cta_tokens[] = 'jb-blue'; } if (!in_array('but', $cta_tokens, true)) { $cta_tokens[] = 'but'; } $cta_class = trim(implode(' ', array_unique($cta_tokens))); if (count($actions) === 1) { $a = $actions[0]; return '' . $label_html . ''; } // zibll: span.newadd-btns.hover-show > toggle chip + .hover-show-con.drop-newadd // Paint classes (jb-*, but, radius) MUST live on the toggle — wrapper is layout-only // (background forced transparent). Bare navbar-but has no .navbar-but-cluster shell. // data-aksrt-newadd: JS may portal menu to body so chip width cannot track menu. $html = ''; $html .= '' . $label_html . ''; $html .= ''; return $html; } endif; if (!function_exists('aksrt_render_header_menu_buttons')) : /** * Publish + optional VIP open button for header CTA. */ function aksrt_render_header_menu_buttons(): string { $settings = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::read_domain('page_display', 'header-nav') : []; $cfg = [ 'enabled' => !isset($settings['nav_newposts']) || !empty($settings['nav_newposts']), 'text' => trim((string) ($settings['nav_newposts_text'] ?? __('发布', 'aksrt'))), 'radius_pill' => !isset($settings['nav_newposts_radius']) || !empty($settings['nav_newposts_radius']), 'class' => sanitize_html_class((string) (($settings['nav_newposts_class'] ?? '') ?: 'jb-blue')), ]; $html = ''; if (!empty($cfg['enabled'])) { // zibll default: but nowave jb-blue (+ radius). $class = 'but nowave navbar-newposts'; $skin = trim((string) ($cfg['class'] ?? '')); if ($skin === '') { $skin = 'jb-blue'; } $class .= ' ' . $skin; $pill = !empty($cfg['radius_pill']); if ($pill && !str_contains($class, 'radius')) { $class .= ' radius'; } $label = (string) ($cfg['text'] ?? __('发布', 'aksrt')); $btn = aksrt_render_new_add_btns(['post'], $class, $label); if ($btn !== '') { $html .= $btn; } } // VIP open CTA for guests / non-VIP (zibll: .pay-vip modal). $user_id = get_current_user_id(); $show_vip = false; if (class_exists('\AKSRT\Settings\Settings')) { $vs = \AKSRT\Settings\Settings::get_payment_vip_settings(); $show_vip = !empty($vs['enabled']); } if ($show_vip) { $is_vip = false; if ($user_id > 0 && function_exists('aksrt_get_user_vip_level')) { $is_vip = (int) aksrt_get_user_vip_level($user_id) > 0; } if (!$is_vip) { $cls = $user_id > 0 ? 'pay-vip' : 'signin-loader'; $hover = ''; if (class_exists('\AKSRT\Content\VipService')) { $svc = \AKSRT\Content\VipService::get_instance(); if (method_exists($svc, 'render_vip_card')) { $cards = $svc->render_vip_card(1, $user_id) . $svc->render_vip_card(2, $user_id); if ($cards !== '') { $hover = ''; } } } // zibll: span.hover-show wraps button + .hover-show-con.sub-vip-card $html .= ''; $html .= ' 0 ? ' vip-level="1"' : '') . '>'; $html .= '' . '' . esc_html__('开通会员', 'aksrt') . ''; $html .= '' . $hover . ''; } } return $html; } endif;