isSMTP(); $phpmailer->Host = $mail['host']; $phpmailer->Port = (int) (isset($mail['port']) ? $mail['port'] : 465); $phpmailer->SMTPAuth = !empty($mail['username']); $phpmailer->Username = $mail['username']; $phpmailer->Password = $mail['password']; $phpmailer->SMTPSecure = isset($mail['encryption']) ? $mail['encryption'] : 'ssl'; // 性能优化:超时 + 连接保持 $phpmailer->Timeout = 10; // 连接/读取超时 10 秒 $phpmailer->Timelimit = 15; // 总执行上限 15 秒 if (!empty($mail['from_address'])) { $from_name = isset($mail['from_name']) ? $mail['from_name'] : ''; // mail_showname 覆盖 from_name if (class_exists('AKSRT_Settings')) { $branding = AKSRT_Settings::get_mail_branding(); if ($branding['showname'] !== '') { $from_name = $branding['showname']; } } $phpmailer->setFrom($mail['from_address'], $from_name); } if (!empty($mail['from_name'])) { $phpmailer->FromName = $mail['from_name']; } // mail_showname 全局覆盖 FromName if (class_exists('AKSRT_Settings')) { $branding = AKSRT_Settings::get_mail_branding(); if ($branding['showname'] !== '') { $phpmailer->FromName = $branding['showname']; } } }); // mail_title_prefix:为所有邮件主题添加前缀 add_filter('wp_mail', function ($atts) { if (!class_exists('AKSRT_Settings') || empty($atts['subject'])) return $atts; $branding = AKSRT_Settings::get_mail_branding(); if ($branding['title_prefix'] !== '' && strpos($atts['subject'], $branding['title_prefix']) !== 0) { $atts['subject'] = $branding['title_prefix'] . ' ' . $atts['subject']; } return $atts; }); // ============================================================ // 分类 Term Meta 字段(封面图 + 推荐描述) // ============================================================ /** * 编辑分类页面 - 显示自定义字段 */ function aksrt_category_meta_fields($term) { $cover_id = (int) get_term_meta($term->term_id, 'aksrt_category_cover_id', true); $cover_url = $cover_id > 0 ? wp_get_attachment_url($cover_id) : ''; $recommend_desc = (string) get_term_meta($term->term_id, 'aksrt_category_recommend_desc', true); ?>

0) { update_term_meta($term_id, 'aksrt_category_cover_id', $cover_id); } else { delete_term_meta($term_id, 'aksrt_category_cover_id'); } if ($recommend_desc !== '') { update_term_meta($term_id, 'aksrt_category_recommend_desc', $recommend_desc); } else { delete_term_meta($term_id, 'aksrt_category_recommend_desc'); } if (class_exists('AKSRT_Settings')) { AKSRT_Settings::flush_category_recommend_cache(); } } add_action('edited_category', 'aksrt_save_category_meta', 10, 1); add_action('created_category', 'aksrt_save_category_meta', 10, 1); /** * 分类编辑页加载媒体库脚本(wp_enqueue_media 仅在 AKSRT 面板加载,此处补上) */ add_action('admin_enqueue_scripts', function (string $hook_suffix) { if ($hook_suffix === 'edit-tags.php' || $hook_suffix === 'term.php') { wp_enqueue_media(); } }); /** * 分类编辑页内联 JS - 媒体选择器 */ function aksrt_category_meta_admin_js() { $screen = get_current_screen(); if (!$screen || $screen->taxonomy !== 'category') return; ?> ID), 301); exit; } }); add_action('pre_get_posts', function ($query) { if (is_admin() || !$query->is_main_query()) return; $is_resource_archive = (bool) $query->get('aksrt_is_resource_archive') || (post_type_exists('aksrt_resource') && $query->is_post_type_archive('aksrt_resource')); // 资源归档页:把查询锁定到「post + _aksrt_is_resource = 1」(含历史 CPT 兼容) if ($is_resource_archive) { $query->set('post_type', function_exists('aksrt_resource_post_types') ? aksrt_resource_post_types() : ['post']); $query->set('post_status', 'publish'); $orderby = isset($_GET['orderby']) ? sanitize_key((string) $_GET['orderby']) : 'date'; if ($orderby === 'downloads') { $query->set('meta_key', AKSRT_Domain_Model::RESOURCE_DOWNLOAD_COUNT_KEY); $query->set('orderby', 'meta_value_num'); $query->set('order', 'DESC'); } elseif ($orderby === 'views') { $query->set('meta_key', AKSRT_Domain_Model::RESOURCE_VIEW_COUNT_KEY); $query->set('orderby', 'meta_value_num'); $query->set('order', 'DESC'); } // 价格筛选:?price=free | paid | all // 价格区间:?price_min=0&price_max=99 $price_filter = isset($_GET['price']) ? sanitize_key((string) $_GET['price']) : ''; $price_min = isset($_GET['price_min']) && $_GET['price_min'] !== '' ? (float) $_GET['price_min'] : null; $price_max = isset($_GET['price_max']) && $_GET['price_max'] !== '' ? (float) $_GET['price_max'] : null; // 「是资源」基础约束:_aksrt_is_resource=1(兼容旧 CPT 时由 post_type 兜底) $meta_query = [ 'relation' => 'AND', [ 'relation' => 'OR', // 新形态:post + meta=1 [ 'key' => AKSRT_Domain_Model::RESOURCE_MARKER_KEY, 'value' => '1', 'compare' => '=', ], // 历史 CPT 兼容:通过 post_type 已被包含,meta 缺失也算资源 [ 'key' => AKSRT_Domain_Model::RESOURCE_MARKER_KEY, 'compare' => 'NOT EXISTS', ], ], ]; if ($price_filter === 'free') { $meta_query[] = [ 'relation' => 'OR', [ 'key' => AKSRT_Domain_Model::PAY_PRICE_KEY, 'value' => 0, 'compare' => '=', 'type' => 'NUMERIC', ], [ 'key' => AKSRT_Domain_Model::PAY_PRICE_KEY, 'compare' => 'NOT EXISTS', ], ]; } elseif ($price_filter === 'paid') { $meta_query[] = [ 'key' => AKSRT_Domain_Model::PAY_PRICE_KEY, 'value' => 0, 'compare' => '>', 'type' => 'NUMERIC', ]; } if ($price_min !== null || $price_max !== null) { if ($price_min !== null && $price_max !== null) { $meta_query[] = [ 'key' => AKSRT_Domain_Model::PAY_PRICE_KEY, 'value' => [$price_min, $price_max], 'compare' => 'BETWEEN', 'type' => 'NUMERIC', ]; } elseif ($price_min !== null) { $meta_query[] = [ 'key' => AKSRT_Domain_Model::PAY_PRICE_KEY, 'value' => $price_min, 'compare' => '>=', 'type' => 'NUMERIC', ]; } elseif ($price_max !== null) { $meta_query[] = [ 'key' => AKSRT_Domain_Model::PAY_PRICE_KEY, 'value' => $price_max, 'compare' => '<=', 'type' => 'NUMERIC', ]; } } // 仅在新形态(post)下加 _aksrt_is_resource=1 强约束; // 旧 CPT 仍在站点时,post_type 已含 aksrt_resource,配合上面 OR 兼容逻辑即可。 if (!post_type_exists('aksrt_resource')) { // 替换 OR 兼容片段为强等于 $meta_query[0] = [ 'key' => AKSRT_Domain_Model::RESOURCE_MARKER_KEY, 'value' => '1', 'compare' => '=', ]; } if (!empty($meta_query)) { $existing = $query->get('meta_query'); if (!is_array($existing)) $existing = []; $query->set('meta_query', array_merge($existing, $meta_query)); } // 资源归档不要分类/标签限制 $query->set('cat', 0); $query->set('tag', ''); } // 站内搜索:post 已默认覆盖(资源就是 post),仅在仍有旧 CPT 时合并 if ($query->is_search() && empty($query->get('post_type'))) { $search_type = sanitize_key((string) $query->get('aksrt_search_type')); if (in_array($search_type, ['category', 'tag'], true)) { $taxonomy = $search_type === 'category' ? 'category' : 'post_tag'; $term_ids = get_terms([ 'taxonomy' => $taxonomy, 'hide_empty' => false, 'fields' => 'ids', 'number' => 20, 'search' => (string) $query->get('s'), ]); $query->set('s', ''); if (is_wp_error($term_ids) || empty($term_ids)) { $query->set('post__in', [0]); } else { $query->set('tax_query', [[ 'taxonomy' => $taxonomy, 'field' => 'term_id', 'terms' => array_map('absint', $term_ids), ]]); } } if (post_type_exists('aksrt_resource')) { // 单一数据选择策略:搜索的内容类型与索引/推送共用同一 helper。 $search_types = function_exists('aksrt_searchable_post_types') ? aksrt_searchable_post_types() : ['post']; if (count($search_types) > 1) { $query->set('post_type', $search_types); } } } // 分类 / 标签归档:post 已自然包含资源(meta 标记),仅当历史 CPT 仍在时才需合并 post_type if (($query->is_category() || $query->is_tag()) && post_type_exists('aksrt_resource')) { $existing = $query->get('post_type'); if (empty($existing)) { $query->set('post_type', ['post', 'aksrt_resource']); } } // v4 起主题统一为 CMS / 资源站形态,所有归档都允许包含资源帖。 // 历史的 blog/cms 双流分流(按 site_profile + term flow 排除资源)已移除。 }); // 资源归档页:套 archive-aksrt_resource.php 模板(v3.4 起作为「资源虚拟归档」复用) add_filter('template_include', function ($template) { if (!get_query_var('aksrt_is_resource_archive')) return $template; $candidate = locate_template(['archive-aksrt_resource.php']); return $candidate ?: $template; }); // 标记为资源的 post:单页改用 single-aksrt_resource.php 模板 add_filter('single_template', function ($template) { if (!is_singular('post')) return $template; $post = get_queried_object(); if (!($post instanceof WP_Post)) return $template; if (!function_exists('aksrt_is_resource_post')) return $template; if (!aksrt_is_resource_post($post)) return $template; $candidate = locate_template(['single-aksrt_resource.php']); return $candidate ?: $template; }); // 资源归档页:标题 add_filter('document_title_parts', function ($parts) { if (get_query_var('aksrt_is_resource_archive')) { $parts['title'] = '资源'; } return $parts; }); // ============================================================