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); } }