refactor(autoload): migrate theme classes to Composer PSR-4
Move 288 types from global AKSRT_* + inc/classes manual requires into
namespace AKSRT\{Domain} under src/AKSRT/, wire composer.json psr-4,
and slim bootstrap to helpers/modules/hooks only. Split multi-class
widget/gateway files, update admin contract audit paths, and document
the layout in ADR/README.
This commit is contained in:
1 parent
8f349b40fb
commit
aaf458af1c
404 files changed
+13602
-7705
No files matched your search
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
/**
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Forum;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
trait TopicServicePart4 {
|
||||
|
||||
|
||||
/**
|
||||
* Get review options.
|
||||
*/
|
||||
public function get_review_options(): array {
|
||||
$options = [];
|
||||
foreach ($this->get_review_map() as $value => $label) {
|
||||
$options[] = ['label' => $label, 'value' => $value];
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a user can publish directly.
|
||||
*/
|
||||
public function can_user_publish_directly(int $user_id, int $board_id = 0): bool {
|
||||
if ($user_id <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (user_can($user_id, 'manage_options')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->forum->is_forum_admin($user_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($board_id > 0 && $this->forum->is_board_moderator($user_id, $board_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ── AJAX edit (extracted from facade) ──
|
||||
|
||||
public function ajax_edit_topic(): void {
|
||||
check_ajax_referer('aksrt_forum_compose', '_nonce');
|
||||
$user_id = get_current_user_id();
|
||||
$topic_id = (int) ($_POST['topic_id'] ?? 0);
|
||||
|
||||
if ($user_id <= 0) {
|
||||
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
|
||||
}
|
||||
if (!$this->forum->can_edit_topic($user_id, $topic_id)) {
|
||||
wp_send_json_error(['message' => __('无编辑权限', 'aksrt')]);
|
||||
}
|
||||
|
||||
$title = sanitize_text_field((string) ($_POST['title'] ?? ''));
|
||||
$content = wp_kses_post((string) ($_POST['content'] ?? ''));
|
||||
if ($title === '' || $content === '') {
|
||||
wp_send_json_error(['message' => __('标题和内容不能为空', 'aksrt')]);
|
||||
}
|
||||
|
||||
$result = wp_update_post([
|
||||
'ID' => $topic_id,
|
||||
'post_title' => $title,
|
||||
'post_content' => $content,
|
||||
], true);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
wp_send_json_error(['message' => $result->get_error_message()]);
|
||||
}
|
||||
|
||||
$tags = $this->split_tags((string) ($_POST['tags'] ?? ''));
|
||||
$clean_tags = array_slice(array_values(array_filter(array_map('sanitize_text_field', $tags))), 0, 5);
|
||||
wp_set_object_terms($topic_id, $clean_tags, 'aksrt_forum_tag');
|
||||
|
||||
if (isset($_POST['special_topic'])) {
|
||||
update_post_meta($topic_id, '_aksrt_special_topic', sanitize_text_field((string) $_POST['special_topic']));
|
||||
}
|
||||
|
||||
if (isset($_POST['topic_cat']) && taxonomy_exists('aksrt_forum_topic_cat')) {
|
||||
$topic_cat = sanitize_text_field((string) $_POST['topic_cat']);
|
||||
wp_set_object_terms($topic_id, $topic_cat !== '' ? [$topic_cat] : [], 'aksrt_forum_topic_cat');
|
||||
}
|
||||
|
||||
$caps = $this->forum->get_compose_capabilities($user_id);
|
||||
|
||||
if ($caps['can_set_visibility'] && isset($_POST['visibility'])) {
|
||||
$visibility = sanitize_key((string) $_POST['visibility']);
|
||||
if (isset($this->get_visibility_map()[$visibility])) {
|
||||
update_post_meta($topic_id, '_aksrt_visibility', $visibility);
|
||||
if ($visibility === self::VISIBILITY_CREDITS) {
|
||||
update_post_meta($topic_id, '_aksrt_credits_cost', max(0, (int) ($_POST['credits_cost'] ?? 0)));
|
||||
}
|
||||
if ($visibility === self::VISIBILITY_PAY) {
|
||||
update_post_meta($topic_id, '_aksrt_pay_price', sanitize_text_field((string) ($_POST['pay_price'] ?? '')));
|
||||
}
|
||||
if ($visibility === self::VISIBILITY_ROLE) {
|
||||
$roles = isset($_POST['visibility_roles']) && is_array($_POST['visibility_roles'])
|
||||
? array_map('sanitize_key', $_POST['visibility_roles']) : [];
|
||||
update_post_meta($topic_id, '_aksrt_visibility_roles', $roles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($caps['can_set_cover']) {
|
||||
$this->save_cover_meta($topic_id, [
|
||||
'cover_type' => sanitize_key((string) ($_POST['cover_type'] ?? '')),
|
||||
'cover_image' => esc_url_raw((string) ($_POST['cover_image'] ?? '')),
|
||||
'featured_slide' => (string) ($_POST['featured_slide'] ?? ''),
|
||||
'featured_video' => esc_url_raw((string) ($_POST['featured_video'] ?? '')),
|
||||
]);
|
||||
}
|
||||
|
||||
if ($caps['can_set_vote'] && isset($_POST['vote_enabled'])) {
|
||||
$vote_data = [
|
||||
'vote_enabled' => !empty($_POST['vote_enabled']),
|
||||
'vote_title' => sanitize_text_field((string) ($_POST['vote_title'] ?? '')),
|
||||
'vote_options_text' => sanitize_textarea_field((string) ($_POST['vote_options'] ?? '')),
|
||||
'vote_multiple' => !empty($_POST['vote_multiple']),
|
||||
'vote_type' => sanitize_key((string) ($_POST['vote_type'] ?? 'standard')),
|
||||
'vote_expiry_days' => (int) ($_POST['vote_expiry_days'] ?? 0),
|
||||
];
|
||||
$vote_meta = $this->prepare_vote_meta($vote_data);
|
||||
$this->save_vote_meta($topic_id, $vote_meta);
|
||||
}
|
||||
|
||||
wp_send_json_success([
|
||||
'message' => __('帖子已更新', 'aksrt'),
|
||||
'redirect' => get_permalink($topic_id),
|
||||
]);
|
||||
}
|
||||
|
||||
public function can_edit_topic(int $user_id, int $topic_id): bool {
|
||||
if ($user_id <= 0 || $topic_id <= 0) {
|
||||
return false;
|
||||
}
|
||||
// Moderators and above can always edit
|
||||
if ($this->forum->forum_user_can($user_id, 'topic_edit_other', $topic_id)) {
|
||||
return true;
|
||||
}
|
||||
// Authors can edit their own unlocked topics
|
||||
$post = get_post($topic_id);
|
||||
if (!$post || $post->post_type !== 'aksrt_forum_topic') {
|
||||
return false;
|
||||
}
|
||||
if ((int) $post->post_author !== $user_id) {
|
||||
return false;
|
||||
}
|
||||
return get_post_meta($topic_id, '_aksrt_locked', true) !== '1';
|
||||
}
|
||||
|
||||
public function update_topic_meta(int $topic_id, array $meta): bool {
|
||||
if ($topic_id <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->forum->can_moderate_topic(get_current_user_id(), $topic_id) && !current_user_can('manage_options')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$allowed_keys = ['_aksrt_sticky', '_aksrt_featured', '_aksrt_locked', '_aksrt_highlight'];
|
||||
foreach ($meta as $key => $value) {
|
||||
if (!in_array($key, $allowed_keys, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
update_post_meta($topic_id, $key, !empty($value) ? '1' : '0');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ajax_update_topic(): void {
|
||||
$user_id = get_current_user_id();
|
||||
$topic_id = (int) ($_POST['topic_id'] ?? 0);
|
||||
if ($topic_id <= 0 || !$this->forum->forum_user_can($user_id, 'topic_moderate', $topic_id)) {
|
||||
wp_send_json_error(['message' => __('权限不足', 'aksrt')]);
|
||||
}
|
||||
|
||||
$meta = [];
|
||||
if (isset($_POST['sticky'])) {
|
||||
$meta['_aksrt_sticky'] = !empty($_POST['sticky']);
|
||||
}
|
||||
if (isset($_POST['featured'])) {
|
||||
$meta['_aksrt_featured'] = !empty($_POST['featured']);
|
||||
}
|
||||
if (isset($_POST['locked'])) {
|
||||
$meta['_aksrt_locked'] = !empty($_POST['locked']);
|
||||
}
|
||||
|
||||
if ($this->update_topic_meta($topic_id, $meta)) {
|
||||
wp_send_json_success(['message' => __('已更新', 'aksrt')]);
|
||||
}
|
||||
|
||||
wp_send_json_error(['message' => __('更新失败', 'aksrt')]);
|
||||
}
|
||||
|
||||
public function ajax_create_topic(): void {
|
||||
check_ajax_referer('aksrt_forum_compose', '_nonce');
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
if ($user_id <= 0) {
|
||||
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'board_id' => (int) ($_POST['board_id'] ?? 0),
|
||||
'title' => sanitize_text_field((string) ($_POST['title'] ?? '')),
|
||||
'content' => wp_kses_post((string) ($_POST['content'] ?? '')),
|
||||
'tags' => $this->split_tags((string) ($_POST['tags'] ?? '')),
|
||||
'special_topic' => sanitize_text_field((string) ($_POST['special_topic'] ?? '')),
|
||||
'visibility' => sanitize_key((string) ($_POST['visibility'] ?? self::VISIBILITY_PUBLIC)),
|
||||
'bbs_type' => sanitize_key((string) ($_POST['bbs_type'] ?? self::BBS_TYPE_STANDARD)),
|
||||
'topic_cat' => sanitize_text_field((string) ($_POST['topic_cat'] ?? '')),
|
||||
'vote_enabled' => !empty($_POST['vote_enabled']),
|
||||
'vote_title' => sanitize_text_field((string) ($_POST['vote_title'] ?? '')),
|
||||
'vote_options_text' => sanitize_textarea_field((string) ($_POST['vote_options'] ?? '')),
|
||||
'vote_multiple' => !empty($_POST['vote_multiple']),
|
||||
'cover_type' => sanitize_key((string) ($_POST['cover_type'] ?? '')),
|
||||
'cover_image' => esc_url_raw((string) ($_POST['cover_image'] ?? '')),
|
||||
'featured_slide' => (string) ($_POST['featured_slide'] ?? ''),
|
||||
'featured_video' => esc_url_raw((string) ($_POST['featured_video'] ?? '')),
|
||||
'credits_cost' => (int) ($_POST['credits_cost'] ?? 0),
|
||||
'pay_price' => sanitize_text_field((string) ($_POST['pay_price'] ?? '')),
|
||||
'visibility_roles' => isset($_POST['visibility_roles']) && is_array($_POST['visibility_roles'])
|
||||
? array_map('sanitize_key', $_POST['visibility_roles']) : [],
|
||||
];
|
||||
|
||||
$draft_id = (int) ($_POST['draft_id'] ?? 0);
|
||||
if ($draft_id > 0) {
|
||||
$result = $this->forum->publish_draft($user_id, $draft_id, $data);
|
||||
} else {
|
||||
$result = $this->create_topic($user_id, $data);
|
||||
}
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
wp_send_json_error(['message' => $result->get_error_message()]);
|
||||
}
|
||||
|
||||
wp_send_json_success([
|
||||
'message' => (string) ($result['message'] ?? __('主题已提交', 'aksrt')),
|
||||
'post_id' => (int) ($result['post_id'] ?? 0),
|
||||
'redirect' => (string) ($result['redirect'] ?? aksrt_get_forum_home_url()),
|
||||
]);
|
||||
}
|
||||
|
||||
public function ajax_unlock_topic(): void {
|
||||
check_ajax_referer('aksrt_forum_action', '_nonce');
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
if ($user_id <= 0) {
|
||||
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
|
||||
}
|
||||
|
||||
$topic_id = (int) ($_POST['topic_id'] ?? 0);
|
||||
if ($topic_id <= 0) {
|
||||
wp_send_json_error(['message' => __('主题不存在', 'aksrt')]);
|
||||
}
|
||||
|
||||
$result = $this->unlock_topic_with_credits($user_id, $topic_id);
|
||||
if (!empty($result['success'])) {
|
||||
wp_send_json_success($result);
|
||||
} else {
|
||||
wp_send_json_error(['message' => $result['message'] ?? __('解锁失败', 'aksrt')]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user