229 lines
8.5 KiB
PHP
229 lines
8.5 KiB
PHP
<?php
|
||
defined('ABSPATH') || exit;
|
||
|
||
// 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;
|
||
wp_enqueue_style('font-awesome-5', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css', [], '5.15.4');
|
||
});
|
||
|
||
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="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="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="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="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');
|
||
}
|
||
});
|
||
|
||
// ============================================================
|
||
// 评论提交:单一合同
|
||
// ------------------------------------------------------------
|
||
// 主路径:前端 comments.js → REST /comment/submit(aksrt_require_captcha)。
|
||
// 兜底 / 原生 wp-comments-post.php 经 preprocess_comment 做人机验证,避免绕过。
|
||
// 列表仍由 aksrt_comment_callback 统一渲染。
|
||
// ============================================================
|
||
|
||
// ============================================================
|
||
// 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();
|
||
$version = wp_get_theme()->get('Version');
|
||
|
||
$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
|
||
|
||
$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 src="' . $url . '" alt="' . $alt . '" loading="lazy"></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 过滤器
|
||
// ============================================================
|
||
|
||
/**
|
||
* 未付费内容:替换为付费墙。
|
||
*/
|
||
add_filter('the_content', 'aksrt_paid_content_filter', 20);
|
||
|
||
/**
|
||
* 已付费内容增强:追加图库轮播/视频播放器。
|
||
*/
|
||
add_filter('the_content', 'aksrt_paid_content_enhance', 25);
|
||
|
||
/**
|
||
* 付费/资源文章使用统一的 single.php。
|
||
*/
|
||
add_filter('single_template', function (string $template): string {
|
||
return $template;
|
||
});
|