661 lines
25 KiB
PHP
661 lines
25 KiB
PHP
<?php
|
||
/**
|
||
* AKSRT Theme Core Hooks
|
||
*
|
||
* Central registration for the theme's WordPress hooks.
|
||
*
|
||
* @package AKSRT
|
||
* @version 3.2.0
|
||
*/
|
||
|
||
defined('ABSPATH') || exit;
|
||
|
||
// ============================================================
|
||
// 评论功能开关
|
||
// ============================================================
|
||
|
||
add_filter('comments_open', function ($open, $post_id) {
|
||
if (class_exists('\AKSRT\Settings\Settings')) {
|
||
$display = \AKSRT\Settings\Settings::get_comment_display_settings();
|
||
if (!empty($display['close_comments'])) {
|
||
return false;
|
||
}
|
||
}
|
||
return $open;
|
||
}, 10, 2);
|
||
|
||
add_filter('comment_text', function ($comment_text, $comment = null, $args = []) {
|
||
if (function_exists('aksrt_render_comment_content')) {
|
||
return aksrt_render_comment_content((string) $comment_text);
|
||
}
|
||
return $comment_text;
|
||
}, 20, 3);
|
||
|
||
// ============================================================
|
||
// 文章预置参数:新建文章按区间随机填入浏览/点赞(参考主题 post_default_mate)
|
||
// ============================================================
|
||
|
||
add_action('save_post', static function ($post_id, $post = null): void {
|
||
$post_id = (int) $post_id;
|
||
if ($post_id <= 0 || wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) {
|
||
return;
|
||
}
|
||
if (!($post instanceof \WP_Post) || $post->post_type !== 'post') {
|
||
return;
|
||
}
|
||
if (!class_exists('\AKSRT\Settings\Settings')) {
|
||
return;
|
||
}
|
||
$page = \AKSRT\Settings\Settings::get_post_page_settings();
|
||
$views_min = max(0, (int) ($page['default_views_min'] ?? 20));
|
||
$views_max = max($views_min, (int) ($page['default_views_max'] ?? 50));
|
||
$likes_min = max(0, (int) ($page['default_likes_min'] ?? 5));
|
||
$likes_max = max($likes_min, (int) ($page['default_likes_max'] ?? 15));
|
||
|
||
if ('' === (string) get_post_meta($post_id, \AKSRT\Core\DomainModel::POST_VIEW_COUNT_KEY, true)) {
|
||
update_post_meta($post_id, \AKSRT\Core\DomainModel::POST_VIEW_COUNT_KEY, wp_rand($views_min, $views_max));
|
||
}
|
||
if ('' === (string) get_post_meta($post_id, '_aksrt_like_count', true)) {
|
||
update_post_meta($post_id, '_aksrt_like_count', wp_rand($likes_min, $likes_max));
|
||
}
|
||
}, 10, 2);
|
||
|
||
// ============================================================
|
||
|
||
// 前端隐藏 WordPress Admin Bar:由 SystemTools 按「扩展&增强 → 系统工具」
|
||
// 的 hide_admin_bar 设置门控(默认开启),不再无条件注入。
|
||
// ============================================================
|
||
|
||
// ============================================================
|
||
// SMTP 邮件配置注入
|
||
// ============================================================
|
||
|
||
add_filter('wp_mail_from', function ($from) {
|
||
if (!class_exists('\AKSRT\Settings\Settings')) return $from;
|
||
$mail = \AKSRT\Settings\Settings::get_smtp();
|
||
if (empty($mail['enabled'])) return $from;
|
||
$configured = sanitize_email((string) ($mail['from_address'] ?? ''));
|
||
return $configured !== '' ? $configured : $from;
|
||
});
|
||
|
||
add_filter('wp_mail_from_name', function ($from_name) {
|
||
if (!class_exists('\AKSRT\Settings\Settings')) return $from_name;
|
||
$mail = \AKSRT\Settings\Settings::get_smtp();
|
||
if (empty($mail['enabled'])) return $from_name;
|
||
$configured = trim((string) ($mail['from_name'] ?? ''));
|
||
return $configured !== '' ? $configured : $from_name;
|
||
});
|
||
|
||
add_action('phpmailer_init', function ($phpmailer) {
|
||
$mail = class_exists('\\AKSRT\\Settings\\Settings')
|
||
? \AKSRT\Settings\Settings::get_smtp()
|
||
: [];
|
||
if (empty($mail['enabled']) || empty($mail['host'])) return;
|
||
|
||
$phpmailer->isSMTP();
|
||
$phpmailer->Host = $mail['host'];
|
||
$phpmailer->Port = (int) ($mail['port'] ?? 465);
|
||
$phpmailer->SMTPAuth = !empty($mail['auth']) && !empty($mail['username']);
|
||
$phpmailer->Username = (string) ($mail['username'] ?? '');
|
||
$phpmailer->Password = (string) ($mail['password'] ?? '');
|
||
$phpmailer->SMTPSecure = (string) ($mail['encryption'] ?? 'ssl');
|
||
$phpmailer->Timeout = 10;
|
||
$phpmailer->Timelimit = 15;
|
||
});
|
||
|
||
// mail_title_prefix is applied by the canonical renderer and by third-party wp_mail callers.
|
||
add_filter('wp_mail', function ($atts) {
|
||
if (!class_exists('\AKSRT\Settings\Settings') || empty($atts['subject'])) return $atts;
|
||
$branding = \AKSRT\Settings\Settings::get_mail_branding();
|
||
$subject = (string) $atts['subject'];
|
||
$site = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
|
||
$subject = preg_replace('/^\[' . preg_quote($site, '/') . '\]\s*/u', '', $subject);
|
||
if ($branding['title_prefix'] !== '' && strpos($subject, $branding['title_prefix']) !== 0) {
|
||
$atts['subject'] = $branding['title_prefix'] . ' ' . $subject;
|
||
} else {
|
||
$atts['subject'] = $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);
|
||
?>
|
||
<tr class="form-field">
|
||
<th scope="row"><label for="aksrt_category_cover_id"><?php esc_html_e('分类封面图', 'aksrt'); ?></label></th>
|
||
<td>
|
||
<div id="aksrt-cover-preview" style="margin-bottom:8px;">
|
||
<?php if ($cover_url) : ?>
|
||
<img src="<?php echo esc_url($cover_url); ?>" style="max-width:200px;height:auto;border-radius:6px;" alt="">
|
||
<?php endif; ?>
|
||
</div>
|
||
<input type="hidden" id="aksrt_category_cover_id" name="aksrt_category_cover_id" value="<?php echo esc_attr((string) $cover_id); ?>">
|
||
<button type="button" class="button" id="aksrt-pick-cover"><?php esc_html_e('选择图片', 'aksrt'); ?></button>
|
||
<button type="button" class="button" id="aksrt-remove-cover" <?php echo $cover_id > 0 ? '' : 'style="display:none;"'; ?>><?php esc_html_e('移除', 'aksrt'); ?></button>
|
||
<p class="description"><?php esc_html_e('分类推荐模块的封面图片。', 'aksrt'); ?></p>
|
||
</td>
|
||
</tr>
|
||
<tr class="form-field">
|
||
<th scope="row"><label for="aksrt_category_recommend_desc"><?php esc_html_e('推荐描述', 'aksrt'); ?></label></th>
|
||
<td>
|
||
<textarea id="aksrt_category_recommend_desc" name="aksrt_category_recommend_desc" rows="3" class="large-text"><?php echo esc_textarea($recommend_desc); ?></textarea>
|
||
<p class="description"><?php esc_html_e('分类推荐模块中显示的描述文字。留空则使用分类默认描述。', 'aksrt'); ?></p>
|
||
</td>
|
||
</tr>
|
||
<?php
|
||
}
|
||
|
||
/**
|
||
* 新增分类页面 - 显示自定义字段
|
||
*/
|
||
function aksrt_category_meta_fields_add() {
|
||
?>
|
||
<div class="form-field">
|
||
<label for="aksrt_category_cover_id"><?php esc_html_e('分类封面图', 'aksrt'); ?></label>
|
||
<div id="aksrt-cover-preview" style="margin-bottom:8px;"></div>
|
||
<input type="hidden" id="aksrt_category_cover_id" name="aksrt_category_cover_id" value="">
|
||
<button type="button" class="button" id="aksrt-pick-cover"><?php esc_html_e('选择图片', 'aksrt'); ?></button>
|
||
<button type="button" class="button" id="aksrt-remove-cover" style="display:none;"><?php esc_html_e('移除', 'aksrt'); ?></button>
|
||
<p class="description"><?php esc_html_e('分类推荐模块的封面图片。', 'aksrt'); ?></p>
|
||
</div>
|
||
<div class="form-field">
|
||
<label for="aksrt_category_recommend_desc"><?php esc_html_e('推荐描述', 'aksrt'); ?></label>
|
||
<textarea id="aksrt_category_recommend_desc" name="aksrt_category_recommend_desc" rows="3"></textarea>
|
||
<p class="description"><?php esc_html_e('分类推荐模块中显示的描述文字。留空则使用分类默认描述。', 'aksrt'); ?></p>
|
||
</div>
|
||
<?php
|
||
}
|
||
|
||
add_action('category_edit_form_fields', 'aksrt_category_meta_fields', 10, 1);
|
||
add_action('category_add_form_fields', 'aksrt_category_meta_fields_add', 10, 1);
|
||
|
||
/**
|
||
* 保存分类 term meta
|
||
*/
|
||
function aksrt_save_category_meta(int $term_id) {
|
||
if (!current_user_can('manage_categories')) return;
|
||
|
||
$cover_id = isset($_POST['aksrt_category_cover_id']) ? absint($_POST['aksrt_category_cover_id']) : 0;
|
||
$recommend_desc = isset($_POST['aksrt_category_recommend_desc']) ? sanitize_textarea_field(wp_unslash($_POST['aksrt_category_recommend_desc'])) : '';
|
||
|
||
if ($cover_id > 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\Settings')) {
|
||
\AKSRT\Settings\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;
|
||
?>
|
||
<script>
|
||
jQuery(function($) {
|
||
var frame;
|
||
|
||
$(document).on('click', '#aksrt-pick-cover', function(e) {
|
||
e.preventDefault();
|
||
if (typeof wp === 'undefined' || !wp.media) return;
|
||
if (frame) { frame.open(); return; }
|
||
|
||
frame = wp.media({
|
||
title: '<?php echo esc_js(__('选择分类封面图', 'aksrt')); ?>',
|
||
button: { text: '<?php echo esc_js(__('使用此图片', 'aksrt')); ?>' },
|
||
multiple: false
|
||
});
|
||
|
||
frame.on('select', function() {
|
||
var attachment = frame.state().get('selection').first().toJSON();
|
||
$('#aksrt_category_cover_id').val(attachment.id);
|
||
$('#aksrt-cover-preview').html('<img src="' + attachment.url + '" style="max-width:200px;height:auto;border-radius:6px;" alt="">');
|
||
$('#aksrt-remove-cover').show();
|
||
});
|
||
|
||
frame.open();
|
||
});
|
||
|
||
$(document).on('click', '#aksrt-remove-cover', function(e) {
|
||
e.preventDefault();
|
||
$('#aksrt_category_cover_id').val('');
|
||
$('#aksrt-cover-preview').html('');
|
||
$(this).hide();
|
||
});
|
||
});
|
||
</script>
|
||
<?php
|
||
}
|
||
|
||
add_action('admin_footer', 'aksrt_category_meta_admin_js');
|
||
|
||
// ============================================================
|
||
// 资源列表:/resources 虚拟归档(post + _aksrt_is_resource)
|
||
// ============================================================
|
||
|
||
add_action('init', function () {
|
||
add_rewrite_rule('^resources/?$', 'index.php?aksrt_is_resource_archive=1', 'top');
|
||
add_rewrite_rule('^resources/page/([0-9]+)/?$', 'index.php?aksrt_is_resource_archive=1&paged=$matches[1]', 'top');
|
||
// 旧单篇路径 /resource/{slug} → 301 到 post 永久链接
|
||
add_rewrite_rule('^resource/([^/]+)/?$', 'index.php?aksrt_legacy_resource=$matches[1]', 'top');
|
||
});
|
||
|
||
add_filter('query_vars', function ($vars) {
|
||
$vars[] = 'aksrt_is_resource_archive';
|
||
$vars[] = 'aksrt_legacy_resource';
|
||
$vars[] = 'type';
|
||
$vars[] = 'trem';
|
||
return $vars;
|
||
});
|
||
|
||
add_action('template_redirect', function () {
|
||
$slug = get_query_var('aksrt_legacy_resource');
|
||
if (!$slug) {
|
||
return;
|
||
}
|
||
$page = get_page_by_path((string) $slug, OBJECT, 'post');
|
||
if ($page) {
|
||
wp_redirect(get_permalink($page->ID), 301);
|
||
exit;
|
||
}
|
||
});
|
||
|
||
add_action('pre_get_posts', function ($query) {
|
||
if (is_admin() || !$query->is_main_query()) {
|
||
return;
|
||
}
|
||
|
||
if ((bool) $query->get('aksrt_is_resource_archive')) {
|
||
$query->set('post_type', 'post');
|
||
$query->set('post_status', 'publish');
|
||
|
||
$orderby = isset($_GET['orderby']) ? sanitize_key((string) $_GET['orderby']) : 'date';
|
||
if ($orderby === 'downloads') {
|
||
$query->set('meta_key', \AKSRT\Core\DomainModel::RESOURCE_DOWNLOAD_COUNT_KEY);
|
||
$query->set('orderby', 'meta_value_num');
|
||
$query->set('order', 'DESC');
|
||
} elseif ($orderby === 'views') {
|
||
$query->set('meta_key', \AKSRT\Core\DomainModel::RESOURCE_VIEW_COUNT_KEY);
|
||
$query->set('orderby', 'meta_value_num');
|
||
$query->set('order', 'DESC');
|
||
}
|
||
|
||
$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;
|
||
|
||
$meta_query = [
|
||
'relation' => 'AND',
|
||
[
|
||
'key' => \AKSRT\Core\DomainModel::RESOURCE_MARKER_KEY,
|
||
'value' => '1',
|
||
'compare' => '=',
|
||
],
|
||
];
|
||
|
||
if ($price_filter === 'free') {
|
||
$meta_query[] = [
|
||
'relation' => 'OR',
|
||
[
|
||
'key' => \AKSRT\Core\DomainModel::PAY_PRICE_KEY,
|
||
'value' => 0,
|
||
'compare' => '=',
|
||
'type' => 'NUMERIC',
|
||
],
|
||
[
|
||
'key' => \AKSRT\Core\DomainModel::PAY_PRICE_KEY,
|
||
'compare' => 'NOT EXISTS',
|
||
],
|
||
];
|
||
} elseif ($price_filter === 'paid') {
|
||
$meta_query[] = [
|
||
'key' => \AKSRT\Core\DomainModel::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\Core\DomainModel::PAY_PRICE_KEY,
|
||
'value' => [$price_min, $price_max],
|
||
'compare' => 'BETWEEN',
|
||
'type' => 'NUMERIC',
|
||
];
|
||
} elseif ($price_min !== null) {
|
||
$meta_query[] = [
|
||
'key' => \AKSRT\Core\DomainModel::PAY_PRICE_KEY,
|
||
'value' => $price_min,
|
||
'compare' => '>=',
|
||
'type' => 'NUMERIC',
|
||
];
|
||
} else {
|
||
$meta_query[] = [
|
||
'key' => \AKSRT\Core\DomainModel::PAY_PRICE_KEY,
|
||
'value' => $price_max,
|
||
'compare' => '<=',
|
||
'type' => 'NUMERIC',
|
||
];
|
||
}
|
||
}
|
||
|
||
$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)
|
||
if ($query->is_search() && empty($query->get('post_type'))) {
|
||
$search_type = sanitize_key((string) $query->get('type'));
|
||
$trem = absint($query->get('trem'));
|
||
if ($trem > 0) {
|
||
$query->set('cat', $trem);
|
||
}
|
||
|
||
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),
|
||
]]);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
add_filter('template_include', function ($template) {
|
||
if (!get_query_var('aksrt_is_resource_archive')) {
|
||
return $template;
|
||
}
|
||
$candidate = locate_template(['archive-resources.php']);
|
||
return $candidate ?: $template;
|
||
});
|
||
|
||
add_filter('document_title_parts', function ($parts) {
|
||
if (get_query_var('aksrt_is_resource_archive')) {
|
||
$parts['title'] = __('资源', 'aksrt');
|
||
}
|
||
return $parts;
|
||
});
|
||
|
||
// EnlighterJS 代码高亮 — 白名单 data-enlighter-* 属性
|
||
// ============================================================
|
||
|
||
add_filter('wp_kses_allowed_html', function ($allowed, $context) {
|
||
if ($context !== 'post') {
|
||
return $allowed;
|
||
}
|
||
|
||
// Allow data-enlighter-* attributes on <pre> and <code>
|
||
$enlighter_attrs = [
|
||
'data-enlighter-language' => true,
|
||
'data-enlighter-theme' => true,
|
||
'data-enlighter-group' => true,
|
||
'data-enlighter-title' => true,
|
||
'data-enlighter-linenumbers' => true,
|
||
'data-enlighter-highlight' => true,
|
||
'data-enlighter-lineoffset' => true,
|
||
];
|
||
|
||
if (isset($allowed['pre'])) {
|
||
$allowed['pre'] = array_merge($allowed['pre'], $enlighter_attrs);
|
||
}
|
||
if (isset($allowed['code'])) {
|
||
$allowed['code'] = array_merge($allowed['code'], $enlighter_attrs);
|
||
}
|
||
|
||
return $allowed;
|
||
}, 10, 2);
|
||
|
||
// ============================================================
|
||
// WP 后台文章列表增强列 — 浏览/点赞/收藏/下载
|
||
// ============================================================
|
||
|
||
add_filter('manage_post_posts_columns', function ($columns) {
|
||
$new_columns = [];
|
||
foreach ($columns as $key => $label) {
|
||
$new_columns[$key] = $label;
|
||
if ($key === 'title') {
|
||
$new_columns['aksrt_stats'] = __('互动数据', 'aksrt');
|
||
}
|
||
}
|
||
return $new_columns;
|
||
});
|
||
|
||
add_action('admin_enqueue_scripts', function ($hook) {
|
||
if ($hook !== 'edit.php') return;
|
||
aksrt_enqueue_fontawesome();
|
||
});
|
||
|
||
add_action('manage_post_posts_custom_column', function ($column, $post_id) {
|
||
if ($column !== 'aksrt_stats') return;
|
||
|
||
$views = (int) get_post_meta($post_id, 'views', true);
|
||
$likes = (int) get_post_meta($post_id, 'like', true);
|
||
$favorites = (int) get_post_meta($post_id, 'favorite', true);
|
||
$downloads = (int) get_post_meta($post_id, 'download_count', true);
|
||
|
||
$format = function (int $n): string {
|
||
if ($n >= 10000) return round($n / 10000, 1) . '万';
|
||
if ($n >= 1000) return round($n / 1000, 1) . 'k';
|
||
return (string) $n;
|
||
};
|
||
|
||
$parts = [];
|
||
$parts[] = '<span title="' . esc_attr__('浏览', 'aksrt') . '" style="margin-right:4px;"><i class="fa fas fa-eye" style="color:#8a909c;font-size:12px;"></i> ' . esc_html($format($views)) . '</span>';
|
||
$parts[] = '<span title="' . esc_attr__('点赞', 'aksrt') . '" style="margin-right:4px;"><i class="fa fas fa-thumbs-up" style="color:#1890ff;font-size:12px;"></i> ' . esc_html($format($likes)) . '</span>';
|
||
$parts[] = '<span title="' . esc_attr__('收藏', 'aksrt') . '" style="margin-right:4px;"><i class="fa fas fa-star" style="color:#f39c12;font-size:12px;"></i> ' . esc_html($format($favorites)) . '</span>';
|
||
|
||
if ($downloads > 0) {
|
||
$parts[] = '<span title="' . esc_attr__('下载', 'aksrt') . '"><i class="fa fas fa-download" style="color:#52c41a;font-size:12px;"></i> ' . esc_html($format($downloads)) . '</span>';
|
||
}
|
||
|
||
echo implode(' · ', $parts);
|
||
}, 10, 2);
|
||
|
||
// Support sorting by views/likes/favorites in admin
|
||
add_action('pre_get_posts', function ($query) {
|
||
if (!is_admin() || !$query->is_main_query()) return;
|
||
|
||
$orderby = $query->get('orderby');
|
||
$allowed = ['views', 'like', 'favorite', 'download_count'];
|
||
|
||
if (in_array($orderby, $allowed, true)) {
|
||
$query->set('meta_key', $orderby);
|
||
$query->set('orderby', 'meta_value_num');
|
||
}
|
||
});
|
||
|
||
// ============================================================
|
||
// Gutenberg 自定义块注册
|
||
// ============================================================
|
||
|
||
// Register category server-side so it exists before JS registerBlockType runs.
|
||
// Keep untyped + defensive: some plugins pass unexpected shapes; typed params can 500 the editor.
|
||
add_filter('block_categories_all', static function ($categories, $context = null) {
|
||
if (!is_array($categories)) {
|
||
return $categories;
|
||
}
|
||
|
||
foreach ($categories as $category) {
|
||
$slug = '';
|
||
if (is_array($category)) {
|
||
$slug = (string) ($category['slug'] ?? '');
|
||
} elseif (is_object($category) && isset($category->slug)) {
|
||
$slug = (string) $category->slug;
|
||
}
|
||
if ($slug === 'aksrt-blocks') {
|
||
return $categories;
|
||
}
|
||
}
|
||
|
||
$categories[] = [
|
||
'slug' => 'aksrt-blocks',
|
||
'title' => 'AKSRT',
|
||
'icon' => null,
|
||
];
|
||
|
||
return $categories;
|
||
}, 10, 2);
|
||
|
||
add_action('enqueue_block_editor_assets', function () {
|
||
$base_uri = get_template_directory_uri();
|
||
|
||
$blocks_js = get_template_directory() . '/assets/js/gutenberg-blocks.js';
|
||
if (file_exists($blocks_js)) {
|
||
wp_enqueue_script(
|
||
'aksrt-gutenberg-blocks',
|
||
$base_uri . '/assets/js/gutenberg-blocks.js',
|
||
// wp-media-utils: MediaUpload for carousel block
|
||
['wp-blocks', 'wp-element', 'wp-components', 'wp-block-editor', 'wp-hooks', 'wp-media-utils', 'wp-data'],
|
||
(string) filemtime($blocks_js),
|
||
true
|
||
);
|
||
}
|
||
|
||
$blocks_css = get_template_directory() . '/assets/css/gutenberg-blocks.css';
|
||
if (file_exists($blocks_css)) {
|
||
wp_enqueue_style(
|
||
'aksrt-gutenberg-blocks',
|
||
$base_uri . '/assets/css/gutenberg-blocks.css',
|
||
[],
|
||
(string) filemtime($blocks_css)
|
||
);
|
||
}
|
||
});
|
||
|
||
// Front-end styles for Gutenberg blocks
|
||
add_action('enqueue_block_assets', function () {
|
||
if (is_admin()) return; // Already loaded in editor
|
||
|
||
$posts = [];
|
||
$queried = get_queried_object();
|
||
if ($queried instanceof \WP_Post) {
|
||
$posts[$queried->ID] = $queried;
|
||
}
|
||
|
||
global $wp_query;
|
||
if ($wp_query instanceof \WP_Query) {
|
||
foreach ((array) $wp_query->posts as $post) {
|
||
if ($post instanceof \WP_Post) {
|
||
$posts[$post->ID] = $post;
|
||
}
|
||
}
|
||
}
|
||
|
||
$has_carousel = false;
|
||
foreach ($posts as $post) {
|
||
if (has_block('aksrt/carousel', $post)) {
|
||
$has_carousel = true;
|
||
break;
|
||
}
|
||
}
|
||
if (!$has_carousel) return;
|
||
|
||
$base_uri = get_template_directory_uri();
|
||
$blocks_css = get_template_directory() . '/assets/css/gutenberg-blocks.css';
|
||
if (file_exists($blocks_css)) {
|
||
wp_enqueue_style(
|
||
'aksrt-gutenberg-blocks-front',
|
||
$base_uri . '/assets/css/gutenberg-blocks.css',
|
||
[],
|
||
(string) filemtime($blocks_css)
|
||
);
|
||
}
|
||
});
|
||
|
||
// ============================================================
|
||
// Gutenberg Carousel Block 渲染回调
|
||
// ============================================================
|
||
add_action('init', function () {
|
||
if (!function_exists('register_block_type')) return;
|
||
|
||
register_block_type('aksrt/carousel', [
|
||
'render_callback' => function (array $attributes): string {
|
||
$images = $attributes['images'] ?? [];
|
||
if (empty($images)) return '';
|
||
|
||
$autoplay = !empty($attributes['autoplay']) ? 'true' : 'false';
|
||
$delay = absint($attributes['delay'] ?? 3000);
|
||
$effect = sanitize_text_field($attributes['effect'] ?? 'slide');
|
||
|
||
$slides = '';
|
||
foreach ($images as $img) {
|
||
if (empty($img['url'])) continue;
|
||
$alt = esc_attr($img['alt'] ?? '');
|
||
$url = esc_url($img['url']);
|
||
$slides .= '<div class="swiper-slide"><img' . aksrt_get_lazy_attr('lazy_sider', (string) $url, '', aksrt_get_lazy_thumb('lg')) . ' alt="' . $alt . '"></div>';
|
||
}
|
||
|
||
if (empty($slides)) return '';
|
||
|
||
return '<div class="aksrt-carousel-block swiper" data-autoplay="' . $autoplay . '" data-delay="' . $delay . '" data-effect="' . $effect . '">'
|
||
. '<div class="swiper-wrapper">' . $slides . '</div>'
|
||
. '<div class="swiper-pagination"></div>'
|
||
. '<div class="swiper-button-prev"></div><div class="swiper-button-next"></div>'
|
||
. '</div>';
|
||
},
|
||
]);
|
||
});
|
||
|
||
// ============================================================
|
||
// 付费内容系统:the_content 过滤器
|
||
// ============================================================
|
||
|
||
/**
|
||
* 未购买的图库/视频正文只保留公开预览;购买卡由 single 模板渲染。
|
||
*/
|
||
add_filter('the_content', 'aksrt_paid_content_filter', 20);
|