feat(admin): rebuild page display settings
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* Page/display schema option search.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
@@ -9,169 +11,62 @@ defined('ABSPATH') || exit;
|
||||
|
||||
class PageDisplayController extends ControllerBase {
|
||||
|
||||
private static $instance = null;
|
||||
private $admin;
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance(): self {
|
||||
if (null === self::$instance) self::$instance = new self();
|
||||
return self::$instance;
|
||||
}
|
||||
public static function get_instance(): self {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function set_admin(Admin $admin): void {
|
||||
$this->admin = $admin;
|
||||
}
|
||||
public function register_routes(): void {
|
||||
register_rest_route(self::API_NAMESPACE, '/settings/schema/page_display/search/(?P<source>posts|categories|tags)', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'search_options'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
'args' => [
|
||||
'query' => ['type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => ''],
|
||||
'include' => ['type' => 'array', 'items' => ['type' => 'integer'], 'default' => []],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function register_routes(): void {
|
||||
// Homepage content-stream banners.
|
||||
register_rest_route(self::API_NAMESPACE, '/banners', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'rest_get_banners'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]);
|
||||
register_rest_route(self::API_NAMESPACE, '/banners', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'rest_create_banner'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]);
|
||||
register_rest_route(self::API_NAMESPACE, '/banners/(?P<id>[\w-]+)', [
|
||||
'methods' => ['PUT', 'DELETE'],
|
||||
'callback' => [$this, 'rest_handle_banner_item'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]);
|
||||
}
|
||||
public function search_options(\WP_REST_Request $request): \WP_REST_Response {
|
||||
$source = sanitize_key((string) $request->get_param('source'));
|
||||
$query = sanitize_text_field((string) $request->get_param('query'));
|
||||
$include = array_values(array_filter(array_map('absint', (array) $request->get_param('include'))));
|
||||
|
||||
private function get_banner_kind_query(): array {
|
||||
return [
|
||||
[
|
||||
'key' => '_aksrt_kind',
|
||||
'value' => 'banner',
|
||||
],
|
||||
];
|
||||
}
|
||||
if ($source === 'posts') {
|
||||
$posts = get_posts([
|
||||
'post_type' => 'post',
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => 20,
|
||||
's' => $query,
|
||||
'include' => $include,
|
||||
'orderby' => $include ? 'post__in' : 'relevance',
|
||||
]);
|
||||
$items = array_map(static function ($post): array {
|
||||
return ['label' => get_the_title($post) ?: ('#' . $post->ID), 'value' => (int) $post->ID];
|
||||
}, $posts);
|
||||
return $this->success(['data' => $items]);
|
||||
}
|
||||
|
||||
public function rest_get_banners(\WP_REST_Request $request): \WP_REST_Response {
|
||||
$args = [
|
||||
'post_type' => 'aksrt_banner',
|
||||
'posts_per_page' => 100,
|
||||
'post_status' => 'any',
|
||||
'orderby' => 'menu_order',
|
||||
'order' => 'ASC',
|
||||
'meta_query' => $this->get_banner_kind_query(),
|
||||
];
|
||||
$posts = get_posts($args);
|
||||
$banners = array_map(function ($post) {
|
||||
$layers_json = get_post_meta($post->ID, '_layers', true);
|
||||
return [
|
||||
'id' => $post->ID,
|
||||
'title' => $post->post_title,
|
||||
'subtitle' => get_post_meta($post->ID, '_subtitle', true),
|
||||
'description' => get_post_meta($post->ID, '_description', true),
|
||||
'image_url' => get_post_meta($post->ID, '_image_url', true),
|
||||
'video_url' => get_post_meta($post->ID, '_video_url', true),
|
||||
'link_url' => get_post_meta($post->ID, '_link_url', true),
|
||||
'link_target' => get_post_meta($post->ID, '_link_target', true) ?: '_self',
|
||||
'text_align' => get_post_meta($post->ID, '_text_align', true) ?: 'left',
|
||||
'device_visibility' => get_post_meta($post->ID, '_device_visibility', true) ?: 'all',
|
||||
// Match frontend aksrt_get_banners(): missing _enabled means enabled.
|
||||
'enabled' => get_post_meta($post->ID, '_enabled', true) !== '0',
|
||||
'show_text' => get_post_meta($post->ID, '_show_text', true) !== '0',
|
||||
'show_meta' => get_post_meta($post->ID, '_show_meta', true) === '1',
|
||||
'sort_order' => $post->menu_order,
|
||||
'text_size_pc' => get_post_meta($post->ID, '_text_size_pc', true) ?: '',
|
||||
'text_size_m' => get_post_meta($post->ID, '_text_size_m', true) ?: '',
|
||||
'text_parallax' => get_post_meta($post->ID, '_text_parallax', true) === '1',
|
||||
'layers' => is_string($layers_json) && $layers_json !== '' ? (json_decode($layers_json, true) ?: []) : [],
|
||||
];
|
||||
}, $posts);
|
||||
return rest_ensure_response(['code' => 'success', 'data' => $banners]);
|
||||
}
|
||||
|
||||
public function rest_create_banner(\WP_REST_Request $request): \WP_REST_Response {
|
||||
$params = $this->get_json_params($request);
|
||||
$title = sanitize_text_field($params['title'] ?? '');
|
||||
$post_id = wp_insert_post([
|
||||
// Title is optional in admin UI; keep a non-empty WP title for list readability.
|
||||
'post_title' => '' !== $title ? $title : 'Banner Slide',
|
||||
'post_type' => 'aksrt_banner',
|
||||
'post_status' => 'publish',
|
||||
'menu_order' => (int) ($params['sort_order'] ?? 0),
|
||||
]);
|
||||
|
||||
if (is_wp_error($post_id)) {
|
||||
return new \WP_REST_Response(['code' => 'error', 'message' => $post_id->get_error_message()], 400);
|
||||
}
|
||||
|
||||
update_post_meta($post_id, '_image_url', esc_url_raw($params['image_url'] ?? ''));
|
||||
update_post_meta($post_id, '_link_url', esc_url_raw($params['link_url'] ?? ''));
|
||||
update_post_meta($post_id, '_link_target', in_array($params['link_target'] ?? '', ['_self', '_blank'], true) ? $params['link_target'] : '_self');
|
||||
update_post_meta($post_id, '_subtitle', sanitize_text_field($params['subtitle'] ?? ''));
|
||||
update_post_meta($post_id, '_description', sanitize_textarea_field($params['description'] ?? ''));
|
||||
update_post_meta($post_id, '_video_url', esc_url_raw($params['video_url'] ?? ''));
|
||||
update_post_meta($post_id, '_text_align', in_array($params['text_align'] ?? '', ['left', 'center', 'right'], true) ? $params['text_align'] : 'left');
|
||||
update_post_meta($post_id, '_device_visibility', in_array($params['device_visibility'] ?? '', ['all', 'pc', 'mobile'], true) ? $params['device_visibility'] : 'all');
|
||||
update_post_meta($post_id, '_enabled', !array_key_exists('enabled', $params) || !empty($params['enabled']) ? '1' : '0');
|
||||
update_post_meta($post_id, '_show_text', !array_key_exists('show_text', $params) || !empty($params['show_text']) ? '1' : '0');
|
||||
update_post_meta($post_id, '_show_meta', !empty($params['show_meta']) ? '1' : '0');
|
||||
update_post_meta($post_id, '_aksrt_kind', 'banner');
|
||||
update_post_meta($post_id, '_text_size_pc', sanitize_text_field($params['text_size_pc'] ?? ''));
|
||||
update_post_meta($post_id, '_text_size_m', sanitize_text_field($params['text_size_m'] ?? ''));
|
||||
update_post_meta($post_id, '_text_parallax', !empty($params['text_parallax']) ? '1' : '0');
|
||||
if (isset($params['layers']) && is_array($params['layers'])) {
|
||||
update_post_meta($post_id, '_layers', wp_json_encode(array_values($params['layers'])));
|
||||
}
|
||||
|
||||
return rest_ensure_response(['code' => 'success', 'data' => ['id' => $post_id], 'message' => __('幻灯片已创建', 'aksrt')]);
|
||||
}
|
||||
|
||||
public function rest_handle_banner_item(\WP_REST_Request $request): \WP_REST_Response {
|
||||
$id = absint($request['id']);
|
||||
if (!$id || get_post_type($id) !== 'aksrt_banner' || 'banner' !== get_post_meta($id, '_aksrt_kind', true)) {
|
||||
return new \WP_REST_Response(['code' => 'not_found', 'message' => __('幻灯片不存在', 'aksrt')], 404);
|
||||
}
|
||||
|
||||
if ($request->get_method() === 'DELETE') {
|
||||
wp_delete_post($id, true);
|
||||
return rest_ensure_response(['code' => 'success', 'message' => __('幻灯片已删除', 'aksrt')]);
|
||||
}
|
||||
|
||||
$params = $this->get_json_params($request);
|
||||
// Optional title: empty is allowed (UI shows “未命名”); do not 422.
|
||||
$title = sanitize_text_field($params['title'] ?? '');
|
||||
|
||||
wp_update_post([
|
||||
'ID' => $id,
|
||||
'post_title' => $title,
|
||||
]);
|
||||
|
||||
update_post_meta($id, '_aksrt_kind', 'banner');
|
||||
update_post_meta($id, '_subtitle', sanitize_text_field($params['subtitle'] ?? ''));
|
||||
update_post_meta($id, '_description', sanitize_textarea_field($params['description'] ?? ''));
|
||||
update_post_meta($id, '_image_url', esc_url_raw($params['image_url'] ?? ''));
|
||||
update_post_meta($id, '_video_url', esc_url_raw($params['video_url'] ?? ''));
|
||||
update_post_meta($id, '_link_url', esc_url_raw($params['link_url'] ?? ''));
|
||||
update_post_meta($id, '_link_target', in_array($params['link_target'] ?? '', ['_blank', '_self'], true) ? $params['link_target'] : '_self');
|
||||
update_post_meta($id, '_text_align', in_array($params['text_align'] ?? '', ['left', 'center', 'right'], true) ? $params['text_align'] : 'left');
|
||||
update_post_meta($id, '_device_visibility', in_array($params['device_visibility'] ?? '', ['all', 'pc', 'mobile'], true) ? $params['device_visibility'] : 'all');
|
||||
update_post_meta($id, '_enabled', !array_key_exists('enabled', $params) || !empty($params['enabled']) ? '1' : '0');
|
||||
update_post_meta($id, '_show_text', !array_key_exists('show_text', $params) || !empty($params['show_text']) ? '1' : '0');
|
||||
update_post_meta($id, '_show_meta', !empty($params['show_meta']) ? '1' : '0');
|
||||
update_post_meta($id, '_text_size_pc', sanitize_text_field($params['text_size_pc'] ?? ''));
|
||||
update_post_meta($id, '_text_size_m', sanitize_text_field($params['text_size_m'] ?? ''));
|
||||
update_post_meta($id, '_text_parallax', !empty($params['text_parallax']) ? '1' : '0');
|
||||
|
||||
if (isset($params['layers']) && is_array($params['layers'])) {
|
||||
update_post_meta($id, '_layers', wp_json_encode(array_values($params['layers'])));
|
||||
} else {
|
||||
delete_post_meta($id, '_layers');
|
||||
}
|
||||
|
||||
if (isset($params['sort_order'])) {
|
||||
wp_update_post([
|
||||
'ID' => $id,
|
||||
'menu_order' => (int) $params['sort_order'],
|
||||
]);
|
||||
}
|
||||
|
||||
return rest_ensure_response(['code' => 'success', 'message' => __('幻灯片已更新', 'aksrt')]);
|
||||
}
|
||||
$taxonomy = $source === 'categories' ? 'category' : 'post_tag';
|
||||
$terms = get_terms([
|
||||
'taxonomy' => $taxonomy,
|
||||
'hide_empty' => false,
|
||||
'number' => 20,
|
||||
'search' => $query,
|
||||
'include' => $include,
|
||||
'orderby' => $include ? 'include' : 'name',
|
||||
]);
|
||||
if (is_wp_error($terms)) {
|
||||
return $this->error($terms->get_error_message(), 400);
|
||||
}
|
||||
$items = array_map(static function ($term): array {
|
||||
return ['label' => $term->name, 'value' => (int) $term->term_id];
|
||||
}, $terms);
|
||||
return $this->success(['data' => $items]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user