388 lines
13 KiB
PHP
388 lines
13 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
if (!defined('ABSPATH')) {
|
||
|
|
exit;
|
||
|
|
}
|
||
|
|
|
||
|
|
class Ansico_Diagnosekoder_REST {
|
||
|
|
public static function init() {
|
||
|
|
add_action('rest_api_init', [__CLASS__, 'register_routes']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function register_routes() {
|
||
|
|
register_rest_route('ansico-diagnosekoder/v1', '/search', [
|
||
|
|
'methods' => WP_REST_Server::READABLE,
|
||
|
|
'callback' => [__CLASS__, 'search'],
|
||
|
|
'permission_callback' => '__return_true',
|
||
|
|
'args' => [
|
||
|
|
'q' => [
|
||
|
|
'type' => 'string',
|
||
|
|
'required' => false,
|
||
|
|
'sanitize_callback' => 'sanitize_text_field',
|
||
|
|
],
|
||
|
|
'limit' => [
|
||
|
|
'type' => 'integer',
|
||
|
|
'required' => false,
|
||
|
|
'default' => 50,
|
||
|
|
'sanitize_callback' => 'absint',
|
||
|
|
],
|
||
|
|
'page_id' => [
|
||
|
|
'type' => 'integer',
|
||
|
|
'required' => false,
|
||
|
|
'default' => 0,
|
||
|
|
'sanitize_callback' => 'absint',
|
||
|
|
],
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
|
||
|
|
register_rest_route('ansico-diagnosekoder/v1', '/page-state', [
|
||
|
|
'methods' => WP_REST_Server::READABLE,
|
||
|
|
'callback' => [__CLASS__, 'page_state'],
|
||
|
|
'permission_callback' => '__return_true',
|
||
|
|
'args' => [
|
||
|
|
'page_id' => [
|
||
|
|
'type' => 'integer',
|
||
|
|
'required' => false,
|
||
|
|
'default' => 0,
|
||
|
|
'sanitize_callback' => 'absint',
|
||
|
|
],
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
|
||
|
|
register_rest_route('ansico-diagnosekoder/v1', '/content-search', [
|
||
|
|
'methods' => WP_REST_Server::READABLE,
|
||
|
|
'callback' => [__CLASS__, 'content_search'],
|
||
|
|
'permission_callback' => static function () {
|
||
|
|
return is_user_logged_in();
|
||
|
|
},
|
||
|
|
'args' => [
|
||
|
|
'q' => [
|
||
|
|
'type' => 'string',
|
||
|
|
'required' => false,
|
||
|
|
'sanitize_callback' => 'sanitize_text_field',
|
||
|
|
],
|
||
|
|
'limit' => [
|
||
|
|
'type' => 'integer',
|
||
|
|
'required' => false,
|
||
|
|
'default' => 8,
|
||
|
|
'sanitize_callback' => 'absint',
|
||
|
|
],
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
|
||
|
|
register_rest_route('ansico-diagnosekoder/v1', '/favorites', [
|
||
|
|
'methods' => WP_REST_Server::CREATABLE,
|
||
|
|
'callback' => [__CLASS__, 'toggle_favorite'],
|
||
|
|
'permission_callback' => static function () {
|
||
|
|
return is_user_logged_in();
|
||
|
|
},
|
||
|
|
'args' => [
|
||
|
|
'code' => [
|
||
|
|
'type' => 'string',
|
||
|
|
'required' => true,
|
||
|
|
'sanitize_callback' => 'sanitize_text_field',
|
||
|
|
],
|
||
|
|
'page_id' => [
|
||
|
|
'type' => 'integer',
|
||
|
|
'required' => true,
|
||
|
|
'sanitize_callback' => 'absint',
|
||
|
|
],
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
|
||
|
|
register_rest_route('ansico-diagnosekoder/v1', '/links', [
|
||
|
|
'methods' => WP_REST_Server::CREATABLE,
|
||
|
|
'callback' => [__CLASS__, 'save_link'],
|
||
|
|
'permission_callback' => static function () {
|
||
|
|
return is_user_logged_in();
|
||
|
|
},
|
||
|
|
'args' => [
|
||
|
|
'code' => [
|
||
|
|
'type' => 'string',
|
||
|
|
'required' => true,
|
||
|
|
'sanitize_callback' => 'sanitize_text_field',
|
||
|
|
],
|
||
|
|
'url' => [
|
||
|
|
'type' => 'string',
|
||
|
|
'required' => true,
|
||
|
|
],
|
||
|
|
'page_id' => [
|
||
|
|
'type' => 'integer',
|
||
|
|
'required' => true,
|
||
|
|
'sanitize_callback' => 'absint',
|
||
|
|
],
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
|
||
|
|
register_rest_route('ansico-diagnosekoder/v1', '/links', [
|
||
|
|
'methods' => WP_REST_Server::DELETABLE,
|
||
|
|
'callback' => [__CLASS__, 'remove_link'],
|
||
|
|
'permission_callback' => static function () {
|
||
|
|
return is_user_logged_in();
|
||
|
|
},
|
||
|
|
'args' => [
|
||
|
|
'code' => [
|
||
|
|
'type' => 'string',
|
||
|
|
'required' => true,
|
||
|
|
'sanitize_callback' => 'sanitize_text_field',
|
||
|
|
],
|
||
|
|
'page_id' => [
|
||
|
|
'type' => 'integer',
|
||
|
|
'required' => true,
|
||
|
|
'sanitize_callback' => 'absint',
|
||
|
|
],
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function search(WP_REST_Request $request) {
|
||
|
|
$query = (string) $request->get_param('q');
|
||
|
|
$limit = (int) $request->get_param('limit');
|
||
|
|
$page_id = absint($request->get_param('page_id'));
|
||
|
|
if (!$page_id) {
|
||
|
|
$page_id = self::get_results_page_id();
|
||
|
|
}
|
||
|
|
$limit = $limit > 0 ? min($limit, 100) : 50;
|
||
|
|
|
||
|
|
$favorite_codes = self::get_page_favorites($page_id);
|
||
|
|
$links = self::get_page_links($page_id);
|
||
|
|
|
||
|
|
$response = rest_ensure_response([
|
||
|
|
'query' => $query,
|
||
|
|
'results' => Ansico_Diagnosekoder_Parser::search($query, $limit, $favorite_codes, $links),
|
||
|
|
'meta' => get_option(ANSICO_DIAGNOSEKODER_OPTION_META, []),
|
||
|
|
'favorites' => $favorite_codes,
|
||
|
|
'links' => $links,
|
||
|
|
'is_logged_in' => is_user_logged_in(),
|
||
|
|
'page_id' => $page_id,
|
||
|
|
]);
|
||
|
|
|
||
|
|
$response->header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');
|
||
|
|
$response->header('Pragma', 'no-cache');
|
||
|
|
return $response;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function page_state(WP_REST_Request $request) {
|
||
|
|
$page_id = absint($request->get_param('page_id'));
|
||
|
|
if (!$page_id) {
|
||
|
|
$page_id = self::get_results_page_id();
|
||
|
|
}
|
||
|
|
|
||
|
|
$response = rest_ensure_response([
|
||
|
|
'page_id' => $page_id,
|
||
|
|
'favorites' => self::get_page_favorites($page_id),
|
||
|
|
'links' => self::get_page_links($page_id),
|
||
|
|
]);
|
||
|
|
$response->header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');
|
||
|
|
$response->header('Pragma', 'no-cache');
|
||
|
|
return $response;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function content_search(WP_REST_Request $request) {
|
||
|
|
$query = trim((string) $request->get_param('q'));
|
||
|
|
$limit = (int) $request->get_param('limit');
|
||
|
|
$limit = $limit > 0 ? min($limit, 20) : 8;
|
||
|
|
|
||
|
|
if ($query === '') {
|
||
|
|
return rest_ensure_response(['results' => []]);
|
||
|
|
}
|
||
|
|
|
||
|
|
$all_post_types = get_post_types([], 'objects');
|
||
|
|
$excluded_types = ['attachment', 'revision', 'nav_menu_item', 'custom_css', 'customize_changeset', 'oembed_cache', 'user_request', 'wp_block', 'wp_navigation', 'wp_template', 'wp_template_part', 'wp_global_styles', 'wp_font_family', 'wp_font_face'];
|
||
|
|
|
||
|
|
$post_types = [];
|
||
|
|
foreach ($all_post_types as $post_type => $object) {
|
||
|
|
if (in_array($post_type, $excluded_types, true)) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (strpos($post_type, 'wp_') === 0) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Include posts, pages, and all custom post types that can reasonably have frontend URLs,
|
||
|
|
// even when the CPT is excluded from normal WordPress search.
|
||
|
|
if (!empty($object->public) || !empty($object->publicly_queryable) || !empty($object->show_ui)) {
|
||
|
|
$post_types[] = $post_type;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$post_types = array_values(array_unique($post_types));
|
||
|
|
|
||
|
|
if (empty($post_types)) {
|
||
|
|
$post_types = ['page', 'post'];
|
||
|
|
}
|
||
|
|
|
||
|
|
$posts = get_posts([
|
||
|
|
'post_type' => $post_types,
|
||
|
|
'post_status' => 'publish',
|
||
|
|
's' => $query,
|
||
|
|
'posts_per_page' => $limit,
|
||
|
|
'orderby' => 'relevance',
|
||
|
|
'order' => 'DESC',
|
||
|
|
'suppress_filters' => false,
|
||
|
|
]);
|
||
|
|
|
||
|
|
$results = [];
|
||
|
|
foreach ($posts as $post) {
|
||
|
|
$results[] = [
|
||
|
|
'id' => (int) $post->ID,
|
||
|
|
'title' => get_the_title($post),
|
||
|
|
'url' => get_permalink($post),
|
||
|
|
'type' => get_post_type($post),
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
return rest_ensure_response(['results' => $results]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function toggle_favorite(WP_REST_Request $request) {
|
||
|
|
$code = self::normalize_code((string) $request->get_param('code'));
|
||
|
|
$page_id = absint($request->get_param('page_id'));
|
||
|
|
if (!$page_id) {
|
||
|
|
$page_id = self::get_results_page_id();
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($code === '') {
|
||
|
|
return new WP_Error('ansico_empty_code', __('Der mangler en kode.', 'ansico-diagnosekoder'), ['status' => 400]);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!$page_id || get_post_status($page_id) === false) {
|
||
|
|
return new WP_Error('ansico_invalid_page', __('Der mangler en gyldig side.', 'ansico-diagnosekoder'), ['status' => 400]);
|
||
|
|
}
|
||
|
|
|
||
|
|
$favorites = self::get_page_favorites($page_id);
|
||
|
|
$index = array_search($code, $favorites, true);
|
||
|
|
$is_favorite = false;
|
||
|
|
|
||
|
|
if ($index === false) {
|
||
|
|
$favorites[] = $code;
|
||
|
|
$is_favorite = true;
|
||
|
|
} else {
|
||
|
|
unset($favorites[$index]);
|
||
|
|
$favorites = array_values($favorites);
|
||
|
|
}
|
||
|
|
|
||
|
|
update_post_meta($page_id, ANSICO_DIAGNOSEKODER_PAGE_FAVORITES_META, $favorites);
|
||
|
|
|
||
|
|
return rest_ensure_response([
|
||
|
|
'code' => $code,
|
||
|
|
'is_favorite' => $is_favorite,
|
||
|
|
'favorites' => $favorites,
|
||
|
|
'page_id' => $page_id,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function get_page_favorites($page_id) {
|
||
|
|
$page_id = absint($page_id);
|
||
|
|
if (!$page_id) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
|
||
|
|
$favorites = get_post_meta($page_id, ANSICO_DIAGNOSEKODER_PAGE_FAVORITES_META, true);
|
||
|
|
if (!is_array($favorites)) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
|
||
|
|
$favorites = array_map([__CLASS__, 'normalize_code'], $favorites);
|
||
|
|
return array_values(array_unique(array_filter($favorites)));
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function save_link(WP_REST_Request $request) {
|
||
|
|
$code = self::normalize_code((string) $request->get_param('code'));
|
||
|
|
$url = esc_url_raw((string) $request->get_param('url'));
|
||
|
|
$page_id = absint($request->get_param('page_id'));
|
||
|
|
if (!$page_id) {
|
||
|
|
$page_id = self::get_results_page_id();
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($code === '') {
|
||
|
|
return new WP_Error('ansico_empty_code', __('Der mangler en kode.', 'ansico-diagnosekoder'), ['status' => 400]);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!$url || !wp_http_validate_url($url)) {
|
||
|
|
return new WP_Error('ansico_invalid_url', __('URL-adressen er ikke gyldig.', 'ansico-diagnosekoder'), ['status' => 400]);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!$page_id || get_post_status($page_id) === false) {
|
||
|
|
return new WP_Error('ansico_invalid_page', __('Der mangler en gyldig side.', 'ansico-diagnosekoder'), ['status' => 400]);
|
||
|
|
}
|
||
|
|
|
||
|
|
$links = self::get_page_links($page_id);
|
||
|
|
$links[$code] = $url;
|
||
|
|
update_post_meta($page_id, ANSICO_DIAGNOSEKODER_PAGE_LINKS_META, $links);
|
||
|
|
|
||
|
|
return rest_ensure_response([
|
||
|
|
'code' => $code,
|
||
|
|
'url' => $url,
|
||
|
|
'links' => $links,
|
||
|
|
'page_id' => $page_id,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function remove_link(WP_REST_Request $request) {
|
||
|
|
$code = self::normalize_code((string) $request->get_param('code'));
|
||
|
|
$page_id = absint($request->get_param('page_id'));
|
||
|
|
if (!$page_id) {
|
||
|
|
$page_id = self::get_results_page_id();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!$page_id || get_post_status($page_id) === false) {
|
||
|
|
return new WP_Error('ansico_invalid_page', __('Der mangler en gyldig side.', 'ansico-diagnosekoder'), ['status' => 400]);
|
||
|
|
}
|
||
|
|
|
||
|
|
$links = self::get_page_links($page_id);
|
||
|
|
if ($code === '') {
|
||
|
|
return new WP_Error('ansico_empty_code', __('Der mangler en kode.', 'ansico-diagnosekoder'), ['status' => 400]);
|
||
|
|
}
|
||
|
|
|
||
|
|
unset($links[$code]);
|
||
|
|
update_post_meta($page_id, ANSICO_DIAGNOSEKODER_PAGE_LINKS_META, $links);
|
||
|
|
|
||
|
|
return rest_ensure_response([
|
||
|
|
'code' => $code,
|
||
|
|
'links' => $links,
|
||
|
|
'page_id' => $page_id,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function get_page_links($page_id) {
|
||
|
|
$page_id = absint($page_id);
|
||
|
|
if (!$page_id) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
|
||
|
|
$links = get_post_meta($page_id, ANSICO_DIAGNOSEKODER_PAGE_LINKS_META, true);
|
||
|
|
if (!is_array($links)) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
|
||
|
|
$normalized = [];
|
||
|
|
foreach ($links as $code => $url) {
|
||
|
|
$normalized_code = self::normalize_code((string) $code);
|
||
|
|
$normalized_url = esc_url_raw((string) $url);
|
||
|
|
if ($normalized_code === '' || $normalized_url === '' || !wp_http_validate_url($normalized_url)) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
$normalized[$normalized_code] = $normalized_url;
|
||
|
|
}
|
||
|
|
|
||
|
|
return $normalized;
|
||
|
|
}
|
||
|
|
|
||
|
|
protected static function get_results_page_id() {
|
||
|
|
$results_url = (string) get_option(ANSICO_DIAGNOSEKODER_OPTION_RESULTS_URL, '');
|
||
|
|
if ($results_url === '') {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return absint(url_to_postid($results_url));
|
||
|
|
}
|
||
|
|
|
||
|
|
protected static function normalize_code($code) {
|
||
|
|
$code = sanitize_text_field((string) $code);
|
||
|
|
$code = preg_replace('/\s+/', '', $code);
|
||
|
|
return strtoupper((string) $code);
|
||
|
|
}
|
||
|
|
}
|