Sync folders
This commit is contained in:
parent
25d2ec43ca
commit
32c69d30c4
9 changed files with 2693 additions and 0 deletions
37
ansico-diagnosekoder/README.txt
Normal file
37
ansico-diagnosekoder/README.txt
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
=== Ansico Diagnosekoder ===
|
||||
Contributors: aphandersen
|
||||
Tags: icd-10, diagnosis, gutenberg, search
|
||||
Requires at least: 6.2
|
||||
Tested up to: 6.5
|
||||
Stable tag: 1.0.0
|
||||
License: GPLv3 or later
|
||||
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Et WordPress-plugin der tilføjer Gutenberg-blokke til søgning i ICD-10 diagnosekoder baseret på en uploadet tekstfil.
|
||||
|
||||
== Beskrivelse ==
|
||||
- Tilføjer blokken "Ansico Diagnosekoder" med live resultater
|
||||
- Tilføjer blokken "Ansico Diagnosekoder Søgefelt" til sidebar eller andre kompakte områder
|
||||
- Tilføjer blokken "Ansico Diagnosekoder Kodekort" til visning af side-tilknyttede koder
|
||||
- Backend-side under Indstillinger
|
||||
- Upload af ny tekstfil erstatter eksisterende datagrundlag
|
||||
- Søger kun i felterne kode og tekst
|
||||
- Søgeord highlightes i resultaterne
|
||||
- Klik på et resultat kopierer diagnosekoden
|
||||
|
||||
== Installation ==
|
||||
1. Upload plugin-mappen til /wp-content/plugins/ eller installer ZIP-filen via WordPress.
|
||||
2. Aktivér pluginet.
|
||||
3. Gå til Indstillinger → Ansico Diagnosekoder.
|
||||
4. Upload din tekstfil.
|
||||
5. Indsæt blokken "Ansico Diagnosekoder" på en side.
|
||||
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 1.0.0 =
|
||||
* Første stabile release.
|
||||
|
||||
|
||||
== Support ==
|
||||
Support: https://ansico.dk/Ansico/Ansico-diagnosekoder
|
||||
55
ansico-diagnosekoder/ansico-diagnosekoder.php
Normal file
55
ansico-diagnosekoder/ansico-diagnosekoder.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/**
|
||||
* Plugin Name: Ansico Diagnosekoder
|
||||
* Plugin URI: https://ansico.dk/Ansico/Ansico-diagnosekoder
|
||||
* Description: Gutenberg-blokke og backend-import til søgning i ICD-10 diagnosekoder fra en uploadet tekstfil.
|
||||
* Version: 1.0.0
|
||||
* Author: Andreas Andersen (Ansico)
|
||||
* Author URI: https://ansico.dk
|
||||
* License: GPL-3.0-or-later
|
||||
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
||||
* Text Domain: ansico-diagnosekoder
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
define('ANSICO_DIAGNOSEKODER_VERSION', '1.0.0');
|
||||
define('ANSICO_DIAGNOSEKODER_PAGE_LINKS_META', 'ansico_diagnosekoder_page_links');
|
||||
define('ANSICO_DIAGNOSEKODER_PAGE_FAVORITES_META', 'ansico_diagnosekoder_page_favorites');
|
||||
define('ANSICO_DIAGNOSEKODER_OPTION_RESULTS_URL', 'ansico_diagnosekoder_results_url');
|
||||
define('ANSICO_DIAGNOSEKODER_PLUGIN_FILE', __FILE__);
|
||||
define('ANSICO_DIAGNOSEKODER_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||
define('ANSICO_DIAGNOSEKODER_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||
define('ANSICO_DIAGNOSEKODER_OPTION_DATA', 'ansico_diagnosekoder_data');
|
||||
define('ANSICO_DIAGNOSEKODER_OPTION_META', 'ansico_diagnosekoder_meta');
|
||||
|
||||
require_once ANSICO_DIAGNOSEKODER_PLUGIN_DIR . 'includes/class-ansico-diagnosekoder-parser.php';
|
||||
require_once ANSICO_DIAGNOSEKODER_PLUGIN_DIR . 'includes/class-ansico-diagnosekoder-admin.php';
|
||||
require_once ANSICO_DIAGNOSEKODER_PLUGIN_DIR . 'includes/class-ansico-diagnosekoder-rest.php';
|
||||
require_once ANSICO_DIAGNOSEKODER_PLUGIN_DIR . 'includes/class-ansico-diagnosekoder-block.php';
|
||||
|
||||
Ansico_Diagnosekoder_Admin::init();
|
||||
Ansico_Diagnosekoder_REST::init();
|
||||
Ansico_Diagnosekoder_Block::init();
|
||||
|
||||
add_action('template_redirect', function () {
|
||||
$results_url = (string) get_option(ANSICO_DIAGNOSEKODER_OPTION_RESULTS_URL, '');
|
||||
$results_page_id = $results_url !== '' ? absint(url_to_postid($results_url)) : 0;
|
||||
$current_page_id = function_exists('get_queried_object_id') ? absint(get_queried_object_id()) : 0;
|
||||
|
||||
if (($results_page_id && $current_page_id === $results_page_id) || isset($_GET['q'])) {
|
||||
nocache_headers();
|
||||
}
|
||||
});
|
||||
|
||||
register_activation_hook(__FILE__, function () {
|
||||
if (false === get_option(ANSICO_DIAGNOSEKODER_OPTION_DATA, false)) {
|
||||
add_option(ANSICO_DIAGNOSEKODER_OPTION_DATA, []);
|
||||
}
|
||||
|
||||
if (false === get_option(ANSICO_DIAGNOSEKODER_OPTION_META, false)) {
|
||||
add_option(ANSICO_DIAGNOSEKODER_OPTION_META, []);
|
||||
}
|
||||
});
|
||||
438
ansico-diagnosekoder/assets/css/style.css
Normal file
438
ansico-diagnosekoder/assets/css/style.css
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
.ansico-diagnosekoder {
|
||||
border: 1px solid #dcdcde;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__search {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__search--inline {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__input {
|
||||
width: 100%;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #8c8f94;
|
||||
border-radius: 6px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__message {
|
||||
margin: 0;
|
||||
color: #50575e;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__item {
|
||||
border-top: 1px solid #f0f0f1;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__item:first-child {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__code {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__separator {
|
||||
color: #50575e;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__text {
|
||||
color: #1d2327;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__highlight {
|
||||
padding: 0 0.12em;
|
||||
background: #fff2a8;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder-editor-preview {
|
||||
border: 1px dashed #c3c4c7;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
background: #f6f7f7;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder--search-only {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__submit {
|
||||
white-space: nowrap;
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #2271b1;
|
||||
border-radius: 6px;
|
||||
background: #2271b1;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__submit:hover {
|
||||
background: #135e96;
|
||||
border-color: #135e96;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__entry-link,
|
||||
.ansico-diagnosekoder__entry-link:visited {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__entry-link:hover,
|
||||
.ansico-diagnosekoder__entry-link:focus-visible {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__entry {
|
||||
min-width: 0;
|
||||
flex: 1 1 auto;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__linked-badge {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
font-size: 12px;
|
||||
color: #50575e;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__icon-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 1px solid #dcdcde;
|
||||
border-radius: 999px;
|
||||
background: #fff;
|
||||
color: #50575e;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
transition: transform 120ms ease, background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease, color 120ms ease;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__icon-button:hover,
|
||||
.ansico-diagnosekoder__icon-button:focus-visible {
|
||||
background: #f6f7f7;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__icon-button.is-feedback-visible::after {
|
||||
content: attr(aria-label);
|
||||
position: absolute;
|
||||
top: calc(100% + 6px);
|
||||
right: 0;
|
||||
white-space: nowrap;
|
||||
background: #1d2327;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
padding: 4px 6px;
|
||||
border-radius: 4px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__icon-button.is-pressed,
|
||||
.ansico-diagnosekoder__icon-button:active {
|
||||
transform: scale(0.92);
|
||||
background: #e9f2f9;
|
||||
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__icon-button svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: block;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__copy-button.is-pressed,
|
||||
.ansico-diagnosekoder__copy-button:active {
|
||||
background: #dfeffb;
|
||||
border-color: #2271b1;
|
||||
color: #2271b1;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__favorite-button.is-active {
|
||||
color: #111111;
|
||||
border-color: #111111;
|
||||
background: #f3f4f5;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__favorite-button.is-active svg {
|
||||
fill: #111111 !important;
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__link-button.is-active {
|
||||
color: #b32d2e;
|
||||
border-color: #b32d2e;
|
||||
background: #fff1f1;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.ansico-diagnosekoder__search--inline {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__row {
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ansico-diagnosekoder__favorite-button svg {
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-width: 1.8;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__favorite-button.is-active svg {
|
||||
fill: #111111 !important;
|
||||
stroke: #111111;
|
||||
stroke-width: 0;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__item.has-link .ansico-diagnosekoder__entry-link {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__item[data-is-favorite="0"] .ansico-diagnosekoder__favorite-button svg {
|
||||
fill: none !important;
|
||||
stroke: currentColor !important;
|
||||
stroke-width: 1.8;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__item[data-is-favorite="1"] .ansico-diagnosekoder__favorite-button svg {
|
||||
fill: #111111 !important;
|
||||
stroke: #111111 !important;
|
||||
stroke-width: 0;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__item.has-link {
|
||||
background: #f6f7f7;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__item.has-link:hover {
|
||||
background: #eef0f1;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 999999;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-backdrop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-dialog {
|
||||
position: relative;
|
||||
max-width: 720px;
|
||||
margin: 8vh auto 0;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.2);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-header,
|
||||
.ansico-diagnosekoder__modal-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid #f0f0f1;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-footer {
|
||||
border-bottom: 0;
|
||||
border-top: 1px solid #f0f0f1;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-title {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-close {
|
||||
appearance: none;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
font-size: 28px;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
color: #50575e;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-field {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-label {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
font-weight: 600;
|
||||
color: #1d2327;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-input {
|
||||
width: 100%;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #8c8f94;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-hint,
|
||||
.ansico-diagnosekoder__modal-message {
|
||||
margin: 0 0 16px;
|
||||
color: #50575e;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-search-results {
|
||||
max-height: 240px;
|
||||
overflow: auto;
|
||||
border: 1px solid #dcdcde;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-result-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-result-item + .ansico-diagnosekoder__modal-result-item {
|
||||
border-top: 1px solid #f0f0f1;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-result-button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 12px 14px;
|
||||
border: 0;
|
||||
background: #fff;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-result-button:hover,
|
||||
.ansico-diagnosekoder__modal-result-button:focus {
|
||||
background: #f6f7f7;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-result-title {
|
||||
display: block;
|
||||
font-weight: 600;
|
||||
color: #1d2327;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-result-meta {
|
||||
display: block;
|
||||
margin-top: 4px;
|
||||
color: #50575e;
|
||||
font-size: 13px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-button {
|
||||
appearance: none;
|
||||
border: 1px solid #2271b1;
|
||||
border-radius: 6px;
|
||||
padding: 10px 14px;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-button--primary {
|
||||
background: #2271b1;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder__modal-button--secondary {
|
||||
background: #fff;
|
||||
color: #2271b1;
|
||||
}
|
||||
|
||||
body.ansico-diagnosekoder-modal-open {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder-kodekort {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder-kodekort__list {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder-kodekort__item {
|
||||
padding: 12px 14px;
|
||||
border: 1px solid #dcdcde;
|
||||
border-radius: 8px;
|
||||
background: #f6f7f7;
|
||||
line-height: 1.5;
|
||||
color: #1d2327;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder-kodekort__code {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.ansico-diagnosekoder-kodekort__separator {
|
||||
color: #50575e;
|
||||
}
|
||||
66
ansico-diagnosekoder/assets/js/block.js
Normal file
66
ansico-diagnosekoder/assets/js/block.js
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
(function (blocks, element, i18n) {
|
||||
var el = element.createElement;
|
||||
var __ = i18n.__;
|
||||
|
||||
blocks.registerBlockType('ansico/diagnosekoder', {
|
||||
title: __('Ansico Diagnosekoder', 'ansico-diagnosekoder'),
|
||||
icon: 'search',
|
||||
category: 'widgets',
|
||||
description: __('Søgefelt med live søgeresultater i ICD-10 diagnosekoder.', 'ansico-diagnosekoder'),
|
||||
edit: function () {
|
||||
return el(
|
||||
'div',
|
||||
{ className: 'ansico-diagnosekoder-editor-preview' },
|
||||
[
|
||||
el('strong', {}, __('Ansico Diagnosekoder', 'ansico-diagnosekoder')),
|
||||
el('p', {}, __('Denne blok viser et søgefelt og søgeresultater på forsiden.', 'ansico-diagnosekoder'))
|
||||
]
|
||||
);
|
||||
},
|
||||
save: function () {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
blocks.registerBlockType('ansico/diagnosekoder-kodekort', {
|
||||
title: __('Ansico Diagnosekoder Kodekort', 'ansico-diagnosekoder'),
|
||||
icon: 'index-card',
|
||||
category: 'widgets',
|
||||
description: __('Viser kode og beskrivelse på sider, der er tilknyttet en diagnosekode via pluginets URL-kobling.', 'ansico-diagnosekoder'),
|
||||
edit: function () {
|
||||
return el(
|
||||
'div',
|
||||
{ className: 'ansico-diagnosekoder-editor-preview' },
|
||||
[
|
||||
el('strong', {}, __('Ansico Diagnosekoder Kodekort', 'ansico-diagnosekoder')),
|
||||
el('p', {}, __('Denne blok vises kun på frontend, hvis den aktuelle side er koblet til en diagnosekode via en URL-tilknytning.', 'ansico-diagnosekoder'))
|
||||
]
|
||||
);
|
||||
},
|
||||
save: function () {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
blocks.registerBlockType('ansico/diagnosekoder-soegefelt', {
|
||||
title: __('Ansico Diagnosekoder Søgefelt', 'ansico-diagnosekoder'),
|
||||
icon: 'search',
|
||||
category: 'widgets',
|
||||
description: __('Kompakt søgefelt, der sender brugeren til en valgt resultatside.', 'ansico-diagnosekoder'),
|
||||
edit: function () {
|
||||
return el(
|
||||
'div',
|
||||
{ className: 'ansico-diagnosekoder-editor-preview' },
|
||||
[
|
||||
el('strong', {}, __('Ansico Diagnosekoder Søgefelt', 'ansico-diagnosekoder')),
|
||||
el('p', {}, __('Denne blok viser kun søgefeltet og sender brugeren videre til resultatsiden angivet i pluginets indstillinger.', 'ansico-diagnosekoder'))
|
||||
]
|
||||
);
|
||||
},
|
||||
save: function () {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
})(window.wp.blocks, window.wp.element, window.wp.i18n);
|
||||
774
ansico-diagnosekoder/assets/js/frontend.js
Normal file
774
ansico-diagnosekoder/assets/js/frontend.js
Normal file
|
|
@ -0,0 +1,774 @@
|
|||
(function () {
|
||||
var favoriteCodes = [];
|
||||
var codeLinks = {};
|
||||
|
||||
function getPageId(root) {
|
||||
var value = root && root.getAttribute ? root.getAttribute('data-page-id') : '';
|
||||
var pageId = parseInt(value || '0', 10);
|
||||
|
||||
if (!Number.isFinite(pageId) || pageId <= 0) {
|
||||
var stateNode = root ? root.querySelector('.ansico-diagnosekoder__page-state') : null;
|
||||
if (stateNode) {
|
||||
try {
|
||||
var state = JSON.parse(stateNode.textContent || '{}');
|
||||
pageId = parseInt(state.pageId || '0', 10);
|
||||
} catch (error) {}
|
||||
}
|
||||
}
|
||||
|
||||
if ((!Number.isFinite(pageId) || pageId <= 0) && typeof AnsicoDiagnosekoderConfig.resultsPageId !== 'undefined') {
|
||||
pageId = parseInt(AnsicoDiagnosekoderConfig.resultsPageId || '0', 10);
|
||||
}
|
||||
|
||||
if ((!Number.isFinite(pageId) || pageId <= 0) && document.body) {
|
||||
var match = (document.body.className || '').match(/(?:^|\s)page-id-(\d+)(?:\s|$)/);
|
||||
if (match) {
|
||||
pageId = parseInt(match[1], 10);
|
||||
}
|
||||
}
|
||||
|
||||
return Number.isFinite(pageId) && pageId > 0 ? pageId : 0;
|
||||
}
|
||||
|
||||
function preloadPageState(root) {
|
||||
if (!root || !root.getAttribute) {
|
||||
return;
|
||||
}
|
||||
|
||||
var stateNode = root.querySelector('.ansico-diagnosekoder__page-state');
|
||||
if (stateNode) {
|
||||
try {
|
||||
var state = JSON.parse(stateNode.textContent || '{}');
|
||||
if (Array.isArray(state.favorites)) {
|
||||
favoriteCodes = state.favorites.map(normalizeCode);
|
||||
}
|
||||
if (state.links && typeof state.links === 'object') {
|
||||
codeLinks = {};
|
||||
Object.keys(state.links).forEach(function (code) {
|
||||
codeLinks[normalizeCode(code)] = state.links[code];
|
||||
});
|
||||
}
|
||||
if (state.pageId && root.getAttribute('data-page-id') !== String(state.pageId)) {
|
||||
root.setAttribute('data-page-id', String(state.pageId));
|
||||
}
|
||||
return;
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
var favoritesRaw = root.getAttribute('data-page-favorites') || '[]';
|
||||
var linksRaw = root.getAttribute('data-page-links') || '{}';
|
||||
|
||||
try {
|
||||
var parsedFavorites = JSON.parse(favoritesRaw);
|
||||
if (Array.isArray(parsedFavorites)) {
|
||||
favoriteCodes = parsedFavorites.map(normalizeCode);
|
||||
}
|
||||
} catch (error) {}
|
||||
|
||||
try {
|
||||
var parsedLinks = JSON.parse(linksRaw);
|
||||
if (parsedLinks && typeof parsedLinks === 'object') {
|
||||
codeLinks = {};
|
||||
Object.keys(parsedLinks).forEach(function (code) {
|
||||
codeLinks[normalizeCode(code)] = parsedLinks[code];
|
||||
});
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
function debounce(fn, delay) {
|
||||
var timer;
|
||||
return function () {
|
||||
var context = this;
|
||||
var args = arguments;
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function () {
|
||||
fn.apply(context, args);
|
||||
}, delay);
|
||||
};
|
||||
}
|
||||
|
||||
function escapeHtml(str) {
|
||||
return String(str)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
function escapeRegExp(str) {
|
||||
return String(str).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
|
||||
function normalizeCode(code) {
|
||||
return String(code || '').replace(/\s+/g, '').toUpperCase();
|
||||
}
|
||||
|
||||
function highlightText(text, query) {
|
||||
var safeText = escapeHtml(text);
|
||||
var trimmedQuery = String(query || '').trim();
|
||||
|
||||
if (!trimmedQuery) {
|
||||
return safeText;
|
||||
}
|
||||
|
||||
var parts = trimmedQuery.split(/\s+/).filter(Boolean);
|
||||
if (!parts.length) {
|
||||
return safeText;
|
||||
}
|
||||
|
||||
var pattern = parts.map(escapeRegExp).join('|');
|
||||
return safeText.replace(new RegExp('(' + pattern + ')', 'gi'), '<mark class="ansico-diagnosekoder__highlight">$1</mark>');
|
||||
}
|
||||
|
||||
function getCopyIcon() {
|
||||
return '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M16 1H6c-1.1 0-2 .9-2 2v12h2V3h10V1zm3 4H10c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H10V7h9v14z"></path></svg>';
|
||||
}
|
||||
|
||||
function getStarIcon(isActive) {
|
||||
if (isActive) {
|
||||
return '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" fill="currentColor"></path></svg>';
|
||||
}
|
||||
|
||||
return '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="none"><path d="M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"></path></svg>';
|
||||
}
|
||||
|
||||
function getPlusIcon() {
|
||||
return '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M19 11H13V5h-2v6H5v2h6v6h2v-6h6z"></path></svg>';
|
||||
}
|
||||
|
||||
function getMinusIcon() {
|
||||
return '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M19 11H5v2h14z"></path></svg>';
|
||||
}
|
||||
|
||||
function isFavorite(code) {
|
||||
return favoriteCodes.indexOf(normalizeCode(code)) !== -1;
|
||||
}
|
||||
|
||||
function getLinkedUrl(code, fallback) {
|
||||
var normalized = normalizeCode(code);
|
||||
if (normalized && typeof codeLinks[normalized] === 'string' && codeLinks[normalized]) {
|
||||
return codeLinks[normalized];
|
||||
}
|
||||
return fallback || '';
|
||||
}
|
||||
|
||||
function setTemporaryLabel(button, label, duration) {
|
||||
var originalLabel = button.getAttribute('data-label-default') || button.getAttribute('aria-label') || '';
|
||||
button.setAttribute('aria-label', label);
|
||||
button.classList.add('is-feedback-visible');
|
||||
window.setTimeout(function () {
|
||||
button.setAttribute('aria-label', originalLabel);
|
||||
button.classList.remove('is-feedback-visible');
|
||||
}, duration || 1400);
|
||||
}
|
||||
|
||||
function pulseButton(button) {
|
||||
button.classList.remove('is-pressed');
|
||||
void button.offsetWidth;
|
||||
button.classList.add('is-pressed');
|
||||
window.setTimeout(function () {
|
||||
button.classList.remove('is-pressed');
|
||||
}, 220);
|
||||
}
|
||||
|
||||
function copyText(value, button) {
|
||||
var successLabel = button.getAttribute('data-label-success') || button.getAttribute('aria-label') || '';
|
||||
var errorLabel = button.getAttribute('data-label-error') || button.getAttribute('aria-label') || '';
|
||||
pulseButton(button);
|
||||
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
navigator.clipboard.writeText(value).then(function () {
|
||||
setTemporaryLabel(button, successLabel, 1400);
|
||||
}).catch(function () {
|
||||
setTemporaryLabel(button, errorLabel, 1400);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var temp = document.createElement('textarea');
|
||||
temp.value = value;
|
||||
temp.setAttribute('readonly', 'readonly');
|
||||
temp.style.position = 'absolute';
|
||||
temp.style.left = '-9999px';
|
||||
document.body.appendChild(temp);
|
||||
temp.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(temp);
|
||||
setTemporaryLabel(button, successLabel, 1400);
|
||||
} catch (error) {
|
||||
setTemporaryLabel(button, errorLabel, 1400);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function searchInternalContent(query) {
|
||||
if (!AnsicoDiagnosekoderConfig.contentSearchUrl) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
var url = AnsicoDiagnosekoderConfig.contentSearchUrl + '?q=' + encodeURIComponent(query) + '&limit=8';
|
||||
return fetch(url, {
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'X-WP-Nonce': AnsicoDiagnosekoderConfig.nonce
|
||||
},
|
||||
cache: 'no-store'
|
||||
}).then(function (response) {
|
||||
if (!response.ok) {
|
||||
throw new Error('Internal content search failed');
|
||||
}
|
||||
return response.json();
|
||||
}).then(function (data) {
|
||||
return Array.isArray(data.results) ? data.results : [];
|
||||
});
|
||||
}
|
||||
|
||||
function ensureLinkModal() {
|
||||
var existing = document.getElementById('ansico-diagnosekoder-link-modal');
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
var wrapper = document.createElement('div');
|
||||
wrapper.id = 'ansico-diagnosekoder-link-modal';
|
||||
wrapper.className = 'ansico-diagnosekoder__modal';
|
||||
wrapper.setAttribute('hidden', 'hidden');
|
||||
wrapper.innerHTML = '' +
|
||||
'<div class="ansico-diagnosekoder__modal-backdrop" data-modal-close="1"></div>' +
|
||||
'<div class="ansico-diagnosekoder__modal-dialog" role="dialog" aria-modal="true" aria-labelledby="ansico-diagnosekoder-link-modal-title">' +
|
||||
'<div class="ansico-diagnosekoder__modal-header">' +
|
||||
'<h3 id="ansico-diagnosekoder-link-modal-title" class="ansico-diagnosekoder__modal-title"></h3>' +
|
||||
'<button type="button" class="ansico-diagnosekoder__modal-close" data-modal-close="1" aria-label="Luk">×</button>' +
|
||||
'</div>' +
|
||||
'<div class="ansico-diagnosekoder__modal-body">' +
|
||||
'<div class="ansico-diagnosekoder__modal-field">' +
|
||||
'<label class="ansico-diagnosekoder__modal-label" for="ansico-diagnosekoder-link-modal-code"></label>' +
|
||||
'<input id="ansico-diagnosekoder-link-modal-code" class="ansico-diagnosekoder__modal-input" type="text" readonly />' +
|
||||
'</div>' +
|
||||
'<p class="ansico-diagnosekoder__modal-hint"></p>' +
|
||||
'<div class="ansico-diagnosekoder__modal-field">' +
|
||||
'<label class="ansico-diagnosekoder__modal-label" for="ansico-diagnosekoder-link-modal-url"></label>' +
|
||||
'<input id="ansico-diagnosekoder-link-modal-url" class="ansico-diagnosekoder__modal-input" type="url" />' +
|
||||
'</div>' +
|
||||
'<div class="ansico-diagnosekoder__modal-field">' +
|
||||
'<label class="ansico-diagnosekoder__modal-label" for="ansico-diagnosekoder-link-modal-search"></label>' +
|
||||
'<input id="ansico-diagnosekoder-link-modal-search" class="ansico-diagnosekoder__modal-input" type="search" />' +
|
||||
'</div>' +
|
||||
'<div class="ansico-diagnosekoder__modal-search-results"></div>' +
|
||||
'</div>' +
|
||||
'<div class="ansico-diagnosekoder__modal-footer">' +
|
||||
'<button type="button" class="ansico-diagnosekoder__modal-button ansico-diagnosekoder__modal-button--secondary" data-modal-cancel="1"></button>' +
|
||||
'<button type="button" class="ansico-diagnosekoder__modal-button ansico-diagnosekoder__modal-button--primary" data-modal-save="1"></button>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
document.body.appendChild(wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
function openLinkModal(code, currentUrl) {
|
||||
var modal = ensureLinkModal();
|
||||
var titleNode = modal.querySelector('.ansico-diagnosekoder__modal-title');
|
||||
var labels = modal.querySelectorAll('.ansico-diagnosekoder__modal-label');
|
||||
var hintNode = modal.querySelector('.ansico-diagnosekoder__modal-hint');
|
||||
var codeInput = modal.querySelector('#ansico-diagnosekoder-link-modal-code');
|
||||
var urlInput = modal.querySelector('#ansico-diagnosekoder-link-modal-url');
|
||||
var searchInput = modal.querySelector('#ansico-diagnosekoder-link-modal-search');
|
||||
var resultsNode = modal.querySelector('.ansico-diagnosekoder__modal-search-results');
|
||||
var cancelButton = modal.querySelector('[data-modal-cancel="1"]');
|
||||
var saveButton = modal.querySelector('[data-modal-save="1"]');
|
||||
var closeButtons = modal.querySelectorAll('[data-modal-close="1"]');
|
||||
var activeSearchToken = 0;
|
||||
|
||||
titleNode.textContent = currentUrl ? AnsicoDiagnosekoderConfig.strings.linkModalTitleEdit : AnsicoDiagnosekoderConfig.strings.linkModalTitleAdd;
|
||||
labels[0].textContent = AnsicoDiagnosekoderConfig.strings.linkModalCodeLabel;
|
||||
labels[1].textContent = AnsicoDiagnosekoderConfig.strings.linkModalUrlLabel;
|
||||
labels[2].textContent = AnsicoDiagnosekoderConfig.strings.linkModalSearchLabel;
|
||||
hintNode.textContent = AnsicoDiagnosekoderConfig.strings.linkModalHint;
|
||||
cancelButton.textContent = AnsicoDiagnosekoderConfig.strings.linkModalCancel;
|
||||
saveButton.textContent = AnsicoDiagnosekoderConfig.strings.linkModalSave;
|
||||
codeInput.value = code || '';
|
||||
urlInput.value = currentUrl || '';
|
||||
urlInput.placeholder = AnsicoDiagnosekoderConfig.strings.linkPromptDefault || 'https://';
|
||||
searchInput.value = '';
|
||||
searchInput.placeholder = AnsicoDiagnosekoderConfig.strings.linkModalSearchPlaceholder;
|
||||
resultsNode.innerHTML = '<p class="ansico-diagnosekoder__modal-message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.linkModalSearchEmpty) + '</p>';
|
||||
modal.removeAttribute('hidden');
|
||||
document.body.classList.add('ansico-diagnosekoder-modal-open');
|
||||
|
||||
function closeModal() {
|
||||
modal.setAttribute('hidden', 'hidden');
|
||||
document.body.classList.remove('ansico-diagnosekoder-modal-open');
|
||||
saveButton.onclick = null;
|
||||
cancelButton.onclick = null;
|
||||
closeButtons.forEach(function (button) { button.onclick = null; });
|
||||
searchInput.oninput = null;
|
||||
document.removeEventListener('keydown', onKeyDown);
|
||||
}
|
||||
|
||||
function onKeyDown(event) {
|
||||
if (event.key === 'Escape') {
|
||||
closeModal();
|
||||
}
|
||||
}
|
||||
|
||||
function renderSearchResults(items) {
|
||||
if (!items.length) {
|
||||
resultsNode.innerHTML = '<p class="ansico-diagnosekoder__modal-message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.linkModalSearchNone) + '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
var html = '<ul class="ansico-diagnosekoder__modal-result-list">';
|
||||
items.forEach(function (item) {
|
||||
html += '<li class="ansico-diagnosekoder__modal-result-item">';
|
||||
html += '<button type="button" class="ansico-diagnosekoder__modal-result-button" data-url="' + escapeHtml(item.url || '') + '">';
|
||||
html += '<span class="ansico-diagnosekoder__modal-result-title">' + escapeHtml(item.title || item.url || '') + '</span>';
|
||||
html += '<span class="ansico-diagnosekoder__modal-result-meta">' + escapeHtml(item.url || '') + '</span>';
|
||||
html += '</button></li>';
|
||||
});
|
||||
html += '</ul>';
|
||||
resultsNode.innerHTML = html;
|
||||
resultsNode.querySelectorAll('.ansico-diagnosekoder__modal-result-button').forEach(function (button) {
|
||||
button.addEventListener('click', function () {
|
||||
urlInput.value = button.getAttribute('data-url') || '';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
searchInput.oninput = debounce(function () {
|
||||
var query = searchInput.value.trim();
|
||||
activeSearchToken += 1;
|
||||
var token = activeSearchToken;
|
||||
|
||||
if (!query) {
|
||||
resultsNode.innerHTML = '<p class="ansico-diagnosekoder__modal-message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.linkModalSearchEmpty) + '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
resultsNode.innerHTML = '<p class="ansico-diagnosekoder__modal-message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.loading) + '</p>';
|
||||
searchInternalContent(query).then(function (items) {
|
||||
if (token !== activeSearchToken) {
|
||||
return;
|
||||
}
|
||||
renderSearchResults(items);
|
||||
}).catch(function () {
|
||||
resultsNode.innerHTML = '<p class="ansico-diagnosekoder__modal-message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.linkSearchError) + '</p>';
|
||||
});
|
||||
}, 180);
|
||||
|
||||
var resolver;
|
||||
var promise = new Promise(function (resolve) {
|
||||
resolver = resolve;
|
||||
});
|
||||
|
||||
saveButton.onclick = function () {
|
||||
resolver(String(urlInput.value || '').trim());
|
||||
closeModal();
|
||||
};
|
||||
cancelButton.onclick = function () {
|
||||
resolver(null);
|
||||
closeModal();
|
||||
};
|
||||
closeButtons.forEach(function (button) {
|
||||
button.onclick = function () {
|
||||
resolver(null);
|
||||
closeModal();
|
||||
};
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', onKeyDown);
|
||||
window.setTimeout(function () { urlInput.focus(); urlInput.select(); }, 0);
|
||||
return promise;
|
||||
}
|
||||
|
||||
function fetchPageState(pageId) {
|
||||
if (!pageId || !AnsicoDiagnosekoderConfig.pageStateUrl) {
|
||||
return Promise.resolve({ favorites: favoriteCodes, links: codeLinks, page_id: pageId || 0 });
|
||||
}
|
||||
|
||||
var url = AnsicoDiagnosekoderConfig.pageStateUrl + '?page_id=' + encodeURIComponent(pageId) + '&_ansico_ts=' + Date.now();
|
||||
return fetch(url, {
|
||||
credentials: 'same-origin',
|
||||
cache: 'no-store'
|
||||
}).then(function (response) {
|
||||
if (!response.ok) {
|
||||
throw new Error('Page state failed');
|
||||
}
|
||||
return response.json();
|
||||
}).then(function (data) {
|
||||
syncClientCollections(data || {});
|
||||
return data || {};
|
||||
}).catch(function () {
|
||||
return { favorites: favoriteCodes, links: codeLinks, page_id: pageId || 0 };
|
||||
});
|
||||
}
|
||||
|
||||
function mergeAndSortResults(results) {
|
||||
var merged = (Array.isArray(results) ? results : []).map(function (item, index) {
|
||||
var normalizedCode = normalizeCode(item.code);
|
||||
var favorite = isFavorite(normalizedCode) || !!item.is_favorite;
|
||||
var linkedUrl = getLinkedUrl(normalizedCode, item.linked_url || '');
|
||||
return Object.assign({}, item, {
|
||||
is_favorite: favorite,
|
||||
linked_url: linkedUrl,
|
||||
_normalized_code: normalizedCode,
|
||||
_render_index: index
|
||||
});
|
||||
});
|
||||
|
||||
merged.sort(function (a, b) {
|
||||
if (!!a.is_favorite !== !!b.is_favorite) {
|
||||
return a.is_favorite ? -1 : 1;
|
||||
}
|
||||
return a._render_index - b._render_index;
|
||||
});
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
function renderResults(container, results, query) {
|
||||
if (!results.length) {
|
||||
container.innerHTML = '<p class="ansico-diagnosekoder__message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.noResults) + '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
var sortedResults = mergeAndSortResults(results);
|
||||
var html = '<ul class="ansico-diagnosekoder__list">';
|
||||
sortedResults.forEach(function (item) {
|
||||
var normalizedCode = item._normalized_code || normalizeCode(item.code);
|
||||
var favorite = !!item.is_favorite;
|
||||
var linkedUrl = item.linked_url || '';
|
||||
var hasLink = !!linkedUrl;
|
||||
var copyValue = item.code + ' - ' + item.text;
|
||||
var copyAria = AnsicoDiagnosekoderConfig.strings.copyCodeAria.replace('%s', copyValue);
|
||||
var favoriteAria = favorite ? AnsicoDiagnosekoderConfig.strings.removeFavorite : AnsicoDiagnosekoderConfig.strings.addFavorite;
|
||||
var linkAria = hasLink ? AnsicoDiagnosekoderConfig.strings.removeLink : AnsicoDiagnosekoderConfig.strings.addLink;
|
||||
var entryTagStart = hasLink ? '<a class="ansico-diagnosekoder__entry-link" href="' + escapeHtml(linkedUrl) + '">' : '';
|
||||
var entryTagEnd = hasLink ? '</a>' : '';
|
||||
|
||||
html += '<li class="ansico-diagnosekoder__item' + (favorite ? ' is-favorite' : '') + (hasLink ? ' has-link' : '') + '" data-code="' + escapeHtml(normalizedCode) + '" data-is-favorite="' + (favorite ? '1' : '0') + '" data-has-link="' + (hasLink ? '1' : '0') + '">';
|
||||
html += '<div class="ansico-diagnosekoder__row">';
|
||||
html += entryTagStart + '<div class="ansico-diagnosekoder__entry">';
|
||||
html += '<span class="ansico-diagnosekoder__code">' + highlightText(item.code, query) + '</span>';
|
||||
html += '<span class="ansico-diagnosekoder__separator"> – </span>';
|
||||
html += '<span class="ansico-diagnosekoder__text">' + highlightText(item.text, query) + '</span>';
|
||||
if (hasLink) {
|
||||
html += '<span class="ansico-diagnosekoder__linked-badge">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.openLink) + '</span>';
|
||||
}
|
||||
html += '</div>' + entryTagEnd;
|
||||
html += '<div class="ansico-diagnosekoder__actions">';
|
||||
html += '<button type="button" class="ansico-diagnosekoder__icon-button ansico-diagnosekoder__copy-button" data-copy-value="' + escapeHtml(copyValue) + '"';
|
||||
html += ' data-label-default="' + escapeHtml(copyAria) + '"';
|
||||
html += ' data-label-success="' + escapeHtml(AnsicoDiagnosekoderConfig.strings.copied) + '"';
|
||||
html += ' data-label-error="' + escapeHtml(AnsicoDiagnosekoderConfig.strings.copyError) + '"';
|
||||
html += ' aria-label="' + escapeHtml(copyAria) + '" title="' + escapeHtml(AnsicoDiagnosekoderConfig.strings.copyIcon) + '">';
|
||||
html += getCopyIcon() + '</button>';
|
||||
|
||||
if (AnsicoDiagnosekoderConfig.isLoggedIn) {
|
||||
html += '<button type="button" class="ansico-diagnosekoder__icon-button ansico-diagnosekoder__favorite-button' + (favorite ? ' is-active' : '') + '" data-code="' + escapeHtml(normalizedCode) + '" aria-pressed="' + (favorite ? 'true' : 'false') + '" data-label-default="' + escapeHtml(favoriteAria) + '" aria-label="' + escapeHtml(favoriteAria) + '" title="' + escapeHtml(AnsicoDiagnosekoderConfig.strings.favoriteIcon) + '">';
|
||||
html += getStarIcon(favorite) + '</button>';
|
||||
html += '<button type="button" class="ansico-diagnosekoder__icon-button ansico-diagnosekoder__link-button' + (hasLink ? ' is-active' : '') + '" data-code="' + escapeHtml(normalizedCode) + '" data-current-url="' + escapeHtml(linkedUrl) + '" data-label-default="' + escapeHtml(linkAria) + '" aria-label="' + escapeHtml(linkAria) + '" title="' + escapeHtml(hasLink ? AnsicoDiagnosekoderConfig.strings.removeLinkIcon : AnsicoDiagnosekoderConfig.strings.addLinkIcon) + '">';
|
||||
html += hasLink ? getMinusIcon() : getPlusIcon();
|
||||
html += '</button>';
|
||||
}
|
||||
|
||||
html += '</div></div></li>';
|
||||
});
|
||||
html += '</ul>';
|
||||
container.innerHTML = html;
|
||||
}
|
||||
|
||||
function getQueryParam(name) {
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
return params.get(name) || '';
|
||||
}
|
||||
|
||||
function getSelectorEscaped(value) {
|
||||
if (window.CSS && typeof window.CSS.escape === 'function') {
|
||||
return window.CSS.escape(value);
|
||||
}
|
||||
return String(value).replace(/"/g, '\\"');
|
||||
}
|
||||
|
||||
function updateFavoriteButtons(code, isFav, pageId) {
|
||||
var normalizedCode = normalizeCode(code);
|
||||
var selector = '.ansico-diagnosekoder__favorite-button[data-code="' + getSelectorEscaped(normalizedCode) + '"]';
|
||||
if (pageId) {
|
||||
selector = '.ansico-diagnosekoder[data-page-id="' + getSelectorEscaped(String(pageId)) + '"] ' + selector;
|
||||
}
|
||||
var buttons = document.querySelectorAll(selector);
|
||||
buttons.forEach(function (button) {
|
||||
var label = isFav ? AnsicoDiagnosekoderConfig.strings.removeFavorite : AnsicoDiagnosekoderConfig.strings.addFavorite;
|
||||
button.classList.toggle('is-active', isFav);
|
||||
button.setAttribute('aria-pressed', isFav ? 'true' : 'false');
|
||||
button.setAttribute('aria-label', label);
|
||||
button.setAttribute('data-label-default', label);
|
||||
button.innerHTML = getStarIcon(isFav);
|
||||
var item = button.closest('.ansico-diagnosekoder__item');
|
||||
if (item) {
|
||||
item.classList.toggle('is-favorite', isFav);
|
||||
item.setAttribute('data-is-favorite', isFav ? '1' : '0');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateLinkButtons(code, url) {
|
||||
var normalizedCode = normalizeCode(code);
|
||||
var buttons = document.querySelectorAll('.ansico-diagnosekoder__link-button[data-code="' + getSelectorEscaped(normalizedCode) + '"]');
|
||||
var hasLink = !!url;
|
||||
buttons.forEach(function (button) {
|
||||
var label = hasLink ? AnsicoDiagnosekoderConfig.strings.removeLink : AnsicoDiagnosekoderConfig.strings.addLink;
|
||||
button.classList.toggle('is-active', hasLink);
|
||||
button.setAttribute('aria-label', label);
|
||||
button.setAttribute('data-label-default', label);
|
||||
button.setAttribute('data-current-url', url || '');
|
||||
button.setAttribute('title', hasLink ? AnsicoDiagnosekoderConfig.strings.removeLinkIcon : AnsicoDiagnosekoderConfig.strings.addLinkIcon);
|
||||
button.innerHTML = hasLink ? getMinusIcon() : getPlusIcon();
|
||||
var item = button.closest('.ansico-diagnosekoder__item');
|
||||
if (item) {
|
||||
item.classList.toggle('has-link', hasLink);
|
||||
item.setAttribute('data-has-link', hasLink ? '1' : '0');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function syncClientCollections(data) {
|
||||
if (Array.isArray(data.favorites)) {
|
||||
favoriteCodes = data.favorites.map(normalizeCode);
|
||||
}
|
||||
if (data.links && typeof data.links === 'object') {
|
||||
codeLinks = {};
|
||||
Object.keys(data.links).forEach(function (code) {
|
||||
codeLinks[normalizeCode(code)] = data.links[code];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function toggleFavorite(code, button, refreshCallback, pageId) {
|
||||
fetch(AnsicoDiagnosekoderConfig.favoritesUrl, {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-WP-Nonce': AnsicoDiagnosekoderConfig.nonce
|
||||
},
|
||||
body: JSON.stringify({ code: normalizeCode(code), page_id: pageId || 0 })
|
||||
}).then(function (response) {
|
||||
if (!response.ok) {
|
||||
throw new Error('Favorite toggle failed');
|
||||
}
|
||||
return response.json();
|
||||
}).then(function (data) {
|
||||
syncClientCollections(data);
|
||||
pulseButton(button);
|
||||
updateFavoriteButtons(code, !!data.is_favorite, pageId || 0);
|
||||
if (typeof refreshCallback === 'function') {
|
||||
refreshCallback();
|
||||
}
|
||||
}).catch(function () {
|
||||
setTemporaryLabel(button, AnsicoDiagnosekoderConfig.strings.favoriteError, 1400);
|
||||
});
|
||||
}
|
||||
|
||||
function saveCodeLink(code, url, button, refreshCallback, pageId) {
|
||||
fetch(AnsicoDiagnosekoderConfig.linksUrl, {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-WP-Nonce': AnsicoDiagnosekoderConfig.nonce
|
||||
},
|
||||
body: JSON.stringify({ code: normalizeCode(code), url: url, page_id: pageId || 0 })
|
||||
}).then(function (response) {
|
||||
if (!response.ok) {
|
||||
throw new Error('Link save failed');
|
||||
}
|
||||
return response.json();
|
||||
}).then(function (data) {
|
||||
syncClientCollections(data);
|
||||
pulseButton(button);
|
||||
updateLinkButtons(code, data.url || '');
|
||||
setTemporaryLabel(button, AnsicoDiagnosekoderConfig.strings.linkSaved, 1200);
|
||||
if (typeof refreshCallback === 'function') {
|
||||
refreshCallback();
|
||||
}
|
||||
}).catch(function () {
|
||||
setTemporaryLabel(button, AnsicoDiagnosekoderConfig.strings.linkError, 1400);
|
||||
});
|
||||
}
|
||||
|
||||
function removeCodeLink(code, button, refreshCallback, pageId) {
|
||||
var url = AnsicoDiagnosekoderConfig.linksUrl + '?code=' + encodeURIComponent(normalizeCode(code)) + '&page_id=' + encodeURIComponent(pageId || 0);
|
||||
fetch(url, {
|
||||
method: 'DELETE',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'X-WP-Nonce': AnsicoDiagnosekoderConfig.nonce
|
||||
}
|
||||
}).then(function (response) {
|
||||
if (!response.ok) {
|
||||
throw new Error('Link removal failed');
|
||||
}
|
||||
return response.json();
|
||||
}).then(function (data) {
|
||||
syncClientCollections(data);
|
||||
pulseButton(button);
|
||||
updateLinkButtons(code, '');
|
||||
setTemporaryLabel(button, AnsicoDiagnosekoderConfig.strings.linkRemoved, 1200);
|
||||
if (typeof refreshCallback === 'function') {
|
||||
refreshCallback();
|
||||
}
|
||||
}).catch(function () {
|
||||
setTemporaryLabel(button, AnsicoDiagnosekoderConfig.strings.linkError, 1400);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function initResultsBlock(root) {
|
||||
preloadPageState(root);
|
||||
var input = root.querySelector('.ansico-diagnosekoder__input');
|
||||
var results = root.querySelector('.ansico-diagnosekoder__results');
|
||||
var hasData = root.getAttribute('data-has-data') === '1';
|
||||
|
||||
if (!input || !results || !hasData) {
|
||||
return;
|
||||
}
|
||||
|
||||
var runSearch = function () {
|
||||
var query = input.value.trim();
|
||||
|
||||
if (!query) {
|
||||
results.innerHTML = '<p class="ansico-diagnosekoder__message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.empty) + '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
results.innerHTML = '<p class="ansico-diagnosekoder__message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.loading) + '</p>';
|
||||
var pageId = getPageId(root);
|
||||
var url = AnsicoDiagnosekoderConfig.restUrl + '?q=' + encodeURIComponent(query) + '&limit=50&page_id=' + encodeURIComponent(pageId) + '&_ansico_ts=' + Date.now();
|
||||
|
||||
fetchPageState(pageId).then(function () {
|
||||
return fetch(url, {
|
||||
credentials: 'same-origin',
|
||||
cache: 'no-store'
|
||||
});
|
||||
})
|
||||
.then(function (response) {
|
||||
if (!response.ok) {
|
||||
throw new Error('Request failed');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
syncClientCollections(data);
|
||||
if (
|
||||
(!Array.isArray(data.favorites) || !data.favorites.length) &&
|
||||
(!data.links || !Object.keys(data.links).length) &&
|
||||
(!favoriteCodes.length && !Object.keys(codeLinks).length)
|
||||
) {
|
||||
preloadPageState(root);
|
||||
}
|
||||
renderResults(results, data.results || [], query);
|
||||
})
|
||||
.catch(function () {
|
||||
results.innerHTML = '<p class="ansico-diagnosekoder__message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.error) + '</p>';
|
||||
});
|
||||
};
|
||||
|
||||
var debouncedSearch = debounce(runSearch, 200);
|
||||
input.addEventListener('input', debouncedSearch);
|
||||
|
||||
results.addEventListener('click', function (event) {
|
||||
var copyButton = event.target.closest('.ansico-diagnosekoder__copy-button');
|
||||
if (copyButton) {
|
||||
copyText(copyButton.getAttribute('data-copy-value') || '', copyButton);
|
||||
return;
|
||||
}
|
||||
|
||||
var favoriteButton = event.target.closest('.ansico-diagnosekoder__favorite-button');
|
||||
if (favoriteButton) {
|
||||
toggleFavorite(favoriteButton.getAttribute('data-code') || '', favoriteButton, runSearch, getPageId(root));
|
||||
return;
|
||||
}
|
||||
|
||||
var linkButton = event.target.closest('.ansico-diagnosekoder__link-button');
|
||||
if (linkButton) {
|
||||
var code = linkButton.getAttribute('data-code') || '';
|
||||
var currentUrl = linkButton.getAttribute('data-current-url') || '';
|
||||
if (currentUrl) {
|
||||
removeCodeLink(code, linkButton, runSearch, getPageId(root));
|
||||
return;
|
||||
}
|
||||
openLinkModal(code, currentUrl).then(function (enteredUrl) {
|
||||
if (enteredUrl === null) {
|
||||
return;
|
||||
}
|
||||
enteredUrl = String(enteredUrl).trim();
|
||||
if (!enteredUrl) {
|
||||
return;
|
||||
}
|
||||
saveCodeLink(code, enteredUrl, linkButton, runSearch, getPageId(root));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var stateNode = root.querySelector('.ansico-diagnosekoder__page-state');
|
||||
var hasServerRenderedResults = false;
|
||||
|
||||
if (stateNode) {
|
||||
try {
|
||||
var initialState = JSON.parse(stateNode.textContent || '{}');
|
||||
hasServerRenderedResults = !!(initialState && initialState.hasInitialResults);
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
fetchPageState(getPageId(root)).then(function () {
|
||||
var presetQuery = getQueryParam('q');
|
||||
if (presetQuery) {
|
||||
input.value = presetQuery;
|
||||
if (!hasServerRenderedResults) {
|
||||
runSearch();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initSearchOnlyBlock(form) {
|
||||
form.addEventListener('submit', function (event) {
|
||||
var input = form.querySelector('.ansico-diagnosekoder__input');
|
||||
var query = input ? input.value.trim() : '';
|
||||
var resultsUrl = form.getAttribute('data-results-url') || AnsicoDiagnosekoderConfig.resultsUrl || '';
|
||||
|
||||
if (!resultsUrl) {
|
||||
event.preventDefault();
|
||||
var message = form.querySelector('.ansico-diagnosekoder__message');
|
||||
if (message) {
|
||||
message.textContent = AnsicoDiagnosekoderConfig.strings.missingResultsUrl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!query) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
var url = new URL(resultsUrl, window.location.origin);
|
||||
url.searchParams.set('q', query);
|
||||
window.location.href = url.toString();
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var resultsBlocks = document.querySelectorAll('.wp-block-ansico-diagnosekoder.ansico-diagnosekoder');
|
||||
resultsBlocks.forEach(initResultsBlock);
|
||||
|
||||
var searchOnlyBlocks = document.querySelectorAll('.wp-block-ansico-diagnosekoder-soegefelt.ansico-diagnosekoder--search-only');
|
||||
searchOnlyBlocks.forEach(initSearchOnlyBlock);
|
||||
});
|
||||
})();
|
||||
|
|
@ -0,0 +1,388 @@
|
|||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class Ansico_Diagnosekoder_Admin {
|
||||
public static function init() {
|
||||
add_action('admin_menu', [__CLASS__, 'register_admin_page']);
|
||||
add_action('admin_post_ansico_diagnosekoder_save_settings', [__CLASS__, 'handle_save_settings']);
|
||||
add_action('admin_post_ansico_diagnosekoder_import_data', [__CLASS__, 'handle_import_data']);
|
||||
add_action('admin_post_ansico_diagnosekoder_remove_data', [__CLASS__, 'handle_remove_data']);
|
||||
add_action('admin_post_ansico_diagnosekoder_remove_favorite', [__CLASS__, 'handle_remove_favorite']);
|
||||
add_action('admin_post_ansico_diagnosekoder_remove_link', [__CLASS__, 'handle_remove_link']);
|
||||
}
|
||||
|
||||
public static function register_admin_page() {
|
||||
add_options_page(
|
||||
__('Ansico Diagnosekoder', 'ansico-diagnosekoder'),
|
||||
__('Ansico Diagnosekoder', 'ansico-diagnosekoder'),
|
||||
'manage_options',
|
||||
'ansico-diagnosekoder',
|
||||
[__CLASS__, 'render_admin_page']
|
||||
);
|
||||
}
|
||||
|
||||
public static function render_admin_page() {
|
||||
if (!current_user_can('manage_options')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$meta = get_option(ANSICO_DIAGNOSEKODER_OPTION_META, []);
|
||||
$results_url = get_option(ANSICO_DIAGNOSEKODER_OPTION_RESULTS_URL, '');
|
||||
$status = isset($_GET['status']) ? sanitize_key(wp_unslash($_GET['status'])) : '';
|
||||
$favorite_rows = self::get_results_page_favorite_rows();
|
||||
$link_rows = self::get_results_page_link_rows();
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1><?php esc_html_e('Ansico Diagnosekoder', 'ansico-diagnosekoder'); ?></h1>
|
||||
|
||||
<?php if ($status === 'success') : ?>
|
||||
<div class="notice notice-success is-dismissible"><p><?php esc_html_e('Filen blev importeret.', 'ansico-diagnosekoder'); ?></p></div>
|
||||
<?php elseif ($status === 'settings_saved') : ?>
|
||||
<div class="notice notice-success is-dismissible"><p><?php esc_html_e('Indstillingerne blev gemt.', 'ansico-diagnosekoder'); ?></p></div>
|
||||
<?php elseif ($status === 'data_removed') : ?>
|
||||
<div class="notice notice-success is-dismissible"><p><?php esc_html_e('Datakilden blev fjernet.', 'ansico-diagnosekoder'); ?></p></div>
|
||||
<?php elseif ($status === 'no_file') : ?>
|
||||
<div class="notice notice-warning is-dismissible"><p><?php esc_html_e('Vælg en ny fil for at importere og erstatte det eksisterende datagrundlag.', 'ansico-diagnosekoder'); ?></p></div>
|
||||
<?php elseif ($status === 'favorite_removed') : ?>
|
||||
<div class="notice notice-success is-dismissible"><p><?php esc_html_e('Favoritten blev fjernet.', 'ansico-diagnosekoder'); ?></p></div>
|
||||
<?php elseif ($status === 'link_removed') : ?>
|
||||
<div class="notice notice-success is-dismissible"><p><?php esc_html_e('URL-tilknytningen blev fjernet.', 'ansico-diagnosekoder'); ?></p></div>
|
||||
<?php elseif ($status === 'error') : ?>
|
||||
<div class="notice notice-error is-dismissible"><p><?php echo esc_html(get_transient('ansico_diagnosekoder_admin_error') ?: __('Importen mislykkedes.', 'ansico-diagnosekoder')); ?></p></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2><?php esc_html_e('Favoritter på resultatsiden', 'ansico-diagnosekoder'); ?></h2>
|
||||
<?php if (!empty($favorite_rows)) : ?>
|
||||
<table class="widefat striped" style="max-width: 1100px; margin-bottom: 24px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php esc_html_e('Kode', 'ansico-diagnosekoder'); ?></th>
|
||||
<th><?php esc_html_e('Beskrivelse', 'ansico-diagnosekoder'); ?></th>
|
||||
<th style="width: 120px;"><?php esc_html_e('Handling', 'ansico-diagnosekoder'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($favorite_rows as $row) : ?>
|
||||
<tr>
|
||||
<td><strong><?php echo esc_html($row['code']); ?></strong></td>
|
||||
<td><?php echo esc_html($row['text']); ?></td>
|
||||
<td>
|
||||
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
|
||||
<?php wp_nonce_field('ansico_diagnosekoder_remove_favorite_' . $row['code']); ?>
|
||||
<input type="hidden" name="action" value="ansico_diagnosekoder_remove_favorite" />
|
||||
<input type="hidden" name="code" value="<?php echo esc_attr($row['code']); ?>" />
|
||||
<?php submit_button(__('Fjern', 'ansico-diagnosekoder'), 'secondary small', '', false); ?>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else : ?>
|
||||
<p><?php esc_html_e('Der er endnu ikke gemt nogen side-favoritter for den valgte resultatside.', 'ansico-diagnosekoder'); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2><?php esc_html_e('Kode-URL-tilknytninger på resultatsiden', 'ansico-diagnosekoder'); ?></h2>
|
||||
<?php if (!empty($link_rows)) : ?>
|
||||
<table class="widefat striped" style="max-width: 1200px; margin-bottom: 24px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php esc_html_e('Kode', 'ansico-diagnosekoder'); ?></th>
|
||||
<th><?php esc_html_e('Beskrivelse', 'ansico-diagnosekoder'); ?></th>
|
||||
<th><?php esc_html_e('URL', 'ansico-diagnosekoder'); ?></th>
|
||||
<th style="width: 120px;"><?php esc_html_e('Handling', 'ansico-diagnosekoder'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($link_rows as $row) : ?>
|
||||
<tr>
|
||||
<td><strong><?php echo esc_html($row['code']); ?></strong></td>
|
||||
<td><?php echo esc_html($row['text']); ?></td>
|
||||
<td><a href="<?php echo esc_url($row['url']); ?>"><?php echo esc_html($row['url']); ?></a></td>
|
||||
<td>
|
||||
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
|
||||
<?php wp_nonce_field('ansico_diagnosekoder_remove_link_' . $row['code']); ?>
|
||||
<input type="hidden" name="action" value="ansico_diagnosekoder_remove_link" />
|
||||
<input type="hidden" name="code" value="<?php echo esc_attr($row['code']); ?>" />
|
||||
<?php submit_button(__('Fjern', 'ansico-diagnosekoder'), 'secondary small', '', false); ?>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else : ?>
|
||||
<p><?php esc_html_e('Der er endnu ikke gemt nogen kode-URL-tilknytninger for den valgte resultatside.', 'ansico-diagnosekoder'); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2><?php esc_html_e('Aktuelt datagrundlag', 'ansico-diagnosekoder'); ?></h2>
|
||||
<?php if (!empty($meta)) : ?>
|
||||
<table class="widefat striped" style="max-width: 900px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong><?php esc_html_e('Kilde', 'ansico-diagnosekoder'); ?></strong></td>
|
||||
<td><?php echo esc_html($meta['source_name'] ?? ''); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><?php esc_html_e('Importeret', 'ansico-diagnosekoder'); ?></strong></td>
|
||||
<td><?php echo esc_html($meta['imported_at'] ?? ''); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><?php esc_html_e('Antal rækker', 'ansico-diagnosekoder'); ?></strong></td>
|
||||
<td><?php echo esc_html((string) ($meta['row_count'] ?? 0)); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><?php esc_html_e('Header fundet', 'ansico-diagnosekoder'); ?></strong></td>
|
||||
<td><?php echo !empty($meta['header_found']) ? esc_html__('Ja', 'ansico-diagnosekoder') : esc_html__('Nej', 'ansico-diagnosekoder'); ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else : ?>
|
||||
<p><?php esc_html_e('Ingen data importeret endnu.', 'ansico-diagnosekoder'); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2><?php esc_html_e('Datakilde', 'ansico-diagnosekoder'); ?></h2>
|
||||
<p><?php esc_html_e('Upload en tekstfil med SKS/ICD-10 koder. En ny import erstatter kun det eksisterende datagrundlag, hvis der er valgt en ny fil.', 'ansico-diagnosekoder'); ?></p>
|
||||
|
||||
<div style="display:flex; align-items:flex-end; gap:8px; flex-wrap:wrap; margin-bottom:40px;">
|
||||
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" enctype="multipart/form-data" style="margin:0;">
|
||||
<?php wp_nonce_field('ansico_diagnosekoder_import_data'); ?>
|
||||
<input type="hidden" name="action" value="ansico_diagnosekoder_import_data" />
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row"><label for="ansico_diagnosekoder_file"><?php esc_html_e('Datafil', 'ansico-diagnosekoder'); ?></label></th>
|
||||
<td>
|
||||
<input type="file" name="ansico_diagnosekoder_file" id="ansico_diagnosekoder_file" accept=".txt,.csv,text/plain" />
|
||||
<p class="description"><?php esc_html_e('Forventet format: semikolon-separeret tekstfil med kolonnerne "Kode" og "Tekst".', 'ansico-diagnosekoder'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php submit_button(__('Importer datakilde', 'ansico-diagnosekoder'), 'primary', 'submit', false); ?>
|
||||
</form>
|
||||
|
||||
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" onsubmit="return confirm('<?php echo esc_js(__('Er du sikker på, at du vil fjerne datakilden?', 'ansico-diagnosekoder')); ?>');" style="margin:0 0 8px 0;">
|
||||
<?php wp_nonce_field('ansico_diagnosekoder_remove_data'); ?>
|
||||
<input type="hidden" name="action" value="ansico_diagnosekoder_remove_data" />
|
||||
<?php submit_button(__('Fjern datakilde', 'ansico-diagnosekoder'), 'delete', 'submit', false); ?>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<h2><?php esc_html_e('Opsætning', 'ansico-diagnosekoder'); ?></h2>
|
||||
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
|
||||
<?php wp_nonce_field('ansico_diagnosekoder_save_settings'); ?>
|
||||
<input type="hidden" name="action" value="ansico_diagnosekoder_save_settings" />
|
||||
|
||||
<table class="form-table" role="presentation">
|
||||
<tr>
|
||||
<th scope="row"><label for="ansico_diagnosekoder_results_url"><?php esc_html_e('URL til resultatside', 'ansico-diagnosekoder'); ?></label></th>
|
||||
<td>
|
||||
<input type="url" name="ansico_diagnosekoder_results_url" id="ansico_diagnosekoder_results_url" class="regular-text code" value="<?php echo esc_attr($results_url); ?>" placeholder="https://example.dk/diagnosekoder/" />
|
||||
<p class="description"><?php esc_html_e('Bruges af blokken med kun søgefelt. Ved submit sendes brugeren til denne side med søgetermen i URL-parameteren q.', 'ansico-diagnosekoder'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php submit_button(__('Gem indstillinger', 'ansico-diagnosekoder')); ?>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
delete_transient('ansico_diagnosekoder_admin_error');
|
||||
}
|
||||
|
||||
public static function handle_save_settings() {
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_die(esc_html__('Du har ikke rettigheder til dette.', 'ansico-diagnosekoder'));
|
||||
}
|
||||
|
||||
check_admin_referer('ansico_diagnosekoder_save_settings');
|
||||
|
||||
$results_url = isset($_POST['ansico_diagnosekoder_results_url']) ? esc_url_raw(wp_unslash($_POST['ansico_diagnosekoder_results_url'])) : '';
|
||||
update_option(ANSICO_DIAGNOSEKODER_OPTION_RESULTS_URL, $results_url, false);
|
||||
|
||||
wp_safe_redirect(add_query_arg([
|
||||
'page' => 'ansico-diagnosekoder',
|
||||
'status' => 'settings_saved',
|
||||
], admin_url('options-general.php')));
|
||||
exit;
|
||||
}
|
||||
|
||||
public static function handle_import_data() {
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_die(esc_html__('Du har ikke rettigheder til dette.', 'ansico-diagnosekoder'));
|
||||
}
|
||||
|
||||
check_admin_referer('ansico_diagnosekoder_import_data');
|
||||
|
||||
if (empty($_FILES['ansico_diagnosekoder_file']) || empty($_FILES['ansico_diagnosekoder_file']['tmp_name'])) {
|
||||
wp_safe_redirect(add_query_arg([
|
||||
'page' => 'ansico-diagnosekoder',
|
||||
'status' => 'no_file',
|
||||
], admin_url('options-general.php')));
|
||||
exit;
|
||||
}
|
||||
|
||||
$file = $_FILES['ansico_diagnosekoder_file'];
|
||||
$overrides = [
|
||||
'test_form' => false,
|
||||
'mimes' => [
|
||||
'txt' => 'text/plain',
|
||||
'csv' => 'text/plain',
|
||||
],
|
||||
];
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
$uploaded = wp_handle_upload($file, $overrides);
|
||||
|
||||
if (!empty($uploaded['error'])) {
|
||||
self::redirect_with_error($uploaded['error']);
|
||||
}
|
||||
|
||||
$parsed = Ansico_Diagnosekoder_Parser::parse_file($uploaded['file']);
|
||||
if (!empty($parsed['meta']['error'])) {
|
||||
self::redirect_with_error($parsed['meta']['error']);
|
||||
}
|
||||
|
||||
if (empty($parsed['rows'])) {
|
||||
self::redirect_with_error(__('Filen indeholdt ingen importerbare diagnosekoder.', 'ansico-diagnosekoder'));
|
||||
}
|
||||
|
||||
update_option(ANSICO_DIAGNOSEKODER_OPTION_DATA, $parsed['rows'], false);
|
||||
update_option(ANSICO_DIAGNOSEKODER_OPTION_META, $parsed['meta'], false);
|
||||
|
||||
wp_safe_redirect(add_query_arg([
|
||||
'page' => 'ansico-diagnosekoder',
|
||||
'status' => 'success',
|
||||
], admin_url('options-general.php')));
|
||||
exit;
|
||||
}
|
||||
|
||||
public static function handle_remove_data() {
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_die(esc_html__('Du har ikke rettigheder til dette.', 'ansico-diagnosekoder'));
|
||||
}
|
||||
|
||||
check_admin_referer('ansico_diagnosekoder_remove_data');
|
||||
|
||||
delete_option(ANSICO_DIAGNOSEKODER_OPTION_DATA);
|
||||
delete_option(ANSICO_DIAGNOSEKODER_OPTION_META);
|
||||
|
||||
wp_safe_redirect(add_query_arg([
|
||||
'page' => 'ansico-diagnosekoder',
|
||||
'status' => 'data_removed',
|
||||
], admin_url('options-general.php')));
|
||||
exit;
|
||||
}
|
||||
|
||||
public static function handle_remove_favorite() {
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_die(esc_html__('Du har ikke rettigheder til dette.', 'ansico-diagnosekoder'));
|
||||
}
|
||||
|
||||
$code = isset($_POST['code']) ? sanitize_text_field(wp_unslash($_POST['code'])) : '';
|
||||
if ($code === '') {
|
||||
self::redirect_with_error(__('Der mangler en kode.', 'ansico-diagnosekoder'));
|
||||
}
|
||||
|
||||
check_admin_referer('ansico_diagnosekoder_remove_favorite_' . $code);
|
||||
|
||||
$results_page_id = self::get_results_page_id();
|
||||
if (!$results_page_id) {
|
||||
self::redirect_with_error(__('Resultatsiden kunne ikke findes.', 'ansico-diagnosekoder'));
|
||||
}
|
||||
|
||||
$favorites = Ansico_Diagnosekoder_REST::get_page_favorites($results_page_id);
|
||||
$normalized_code = strtoupper(preg_replace('/\s+/', '', $code));
|
||||
$favorites = array_values(array_filter($favorites, static function ($item) use ($normalized_code) {
|
||||
return $item !== $normalized_code;
|
||||
}));
|
||||
update_post_meta($results_page_id, ANSICO_DIAGNOSEKODER_PAGE_FAVORITES_META, $favorites);
|
||||
|
||||
wp_safe_redirect(add_query_arg([
|
||||
'page' => 'ansico-diagnosekoder',
|
||||
'status' => 'favorite_removed',
|
||||
], admin_url('options-general.php')));
|
||||
exit;
|
||||
}
|
||||
|
||||
public static function handle_remove_link() {
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_die(esc_html__('Du har ikke rettigheder til dette.', 'ansico-diagnosekoder'));
|
||||
}
|
||||
|
||||
$code = isset($_POST['code']) ? sanitize_text_field(wp_unslash($_POST['code'])) : '';
|
||||
if ($code === '') {
|
||||
self::redirect_with_error(__('Der mangler en kode.', 'ansico-diagnosekoder'));
|
||||
}
|
||||
|
||||
check_admin_referer('ansico_diagnosekoder_remove_link_' . $code);
|
||||
|
||||
$results_page_id = self::get_results_page_id();
|
||||
if (!$results_page_id) {
|
||||
self::redirect_with_error(__('Resultatsiden kunne ikke findes.', 'ansico-diagnosekoder'));
|
||||
}
|
||||
|
||||
$normalized_code = strtoupper(preg_replace('/\s+/', '', $code));
|
||||
$links = Ansico_Diagnosekoder_REST::get_page_links($results_page_id);
|
||||
unset($links[$normalized_code]);
|
||||
update_post_meta($results_page_id, ANSICO_DIAGNOSEKODER_PAGE_LINKS_META, $links);
|
||||
|
||||
wp_safe_redirect(add_query_arg([
|
||||
'page' => 'ansico-diagnosekoder',
|
||||
'status' => 'link_removed',
|
||||
], admin_url('options-general.php')));
|
||||
exit;
|
||||
}
|
||||
|
||||
protected static function get_results_page_favorite_rows() {
|
||||
$results_page_id = self::get_results_page_id();
|
||||
if (!$results_page_id) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Ansico_Diagnosekoder_Parser::get_rows_by_codes(Ansico_Diagnosekoder_REST::get_page_favorites($results_page_id));
|
||||
}
|
||||
|
||||
protected static function get_results_page_id() {
|
||||
$results_url = (string) get_option(ANSICO_DIAGNOSEKODER_OPTION_RESULTS_URL, '');
|
||||
if ($results_url === '') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$page_id = url_to_postid($results_url);
|
||||
return absint($page_id);
|
||||
}
|
||||
|
||||
protected static function get_results_page_link_rows() {
|
||||
$results_page_id = self::get_results_page_id();
|
||||
if (!$results_page_id) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$links = Ansico_Diagnosekoder_REST::get_page_links($results_page_id);
|
||||
if (empty($links)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = Ansico_Diagnosekoder_Parser::get_rows_by_codes(array_keys($links));
|
||||
foreach ($rows as &$row) {
|
||||
$row['url'] = isset($links[$row['code']]) ? $links[$row['code']] : '';
|
||||
}
|
||||
unset($row);
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
protected static function redirect_with_error($message) {
|
||||
set_transient('ansico_diagnosekoder_admin_error', wp_strip_all_tags((string) $message), 60);
|
||||
wp_safe_redirect(add_query_arg([
|
||||
'page' => 'ansico-diagnosekoder',
|
||||
'status' => 'error',
|
||||
], admin_url('options-general.php')));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,350 @@
|
|||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class Ansico_Diagnosekoder_Block {
|
||||
public static function init() {
|
||||
add_action('init', [__CLASS__, 'register_assets']);
|
||||
add_action('init', [__CLASS__, 'register_block']);
|
||||
}
|
||||
|
||||
public static function register_assets() {
|
||||
wp_register_script(
|
||||
'ansico-diagnosekoder-block-editor',
|
||||
ANSICO_DIAGNOSEKODER_PLUGIN_URL . 'assets/js/block.js',
|
||||
['wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-i18n', 'wp-block-editor'],
|
||||
ANSICO_DIAGNOSEKODER_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_register_script(
|
||||
'ansico-diagnosekoder-frontend',
|
||||
ANSICO_DIAGNOSEKODER_PLUGIN_URL . 'assets/js/frontend.js',
|
||||
[],
|
||||
ANSICO_DIAGNOSEKODER_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script('ansico-diagnosekoder-frontend', 'AnsicoDiagnosekoderConfig', [
|
||||
'restUrl' => esc_url_raw(rest_url('ansico-diagnosekoder/v1/search')),
|
||||
'favoritesUrl' => esc_url_raw(rest_url('ansico-diagnosekoder/v1/favorites')),
|
||||
'pageStateUrl' => esc_url_raw(rest_url('ansico-diagnosekoder/v1/page-state')),
|
||||
'contentSearchUrl' => esc_url_raw(rest_url('ansico-diagnosekoder/v1/content-search')),
|
||||
'linksUrl' => esc_url_raw(rest_url('ansico-diagnosekoder/v1/links')),
|
||||
'resultsUrl' => esc_url_raw((string) get_option(ANSICO_DIAGNOSEKODER_OPTION_RESULTS_URL, '')),
|
||||
'nonce' => wp_create_nonce('wp_rest'),
|
||||
'isLoggedIn' => is_user_logged_in(),
|
||||
'resultsPageId' => self::get_results_page_id(),
|
||||
'strings' => [
|
||||
'placeholder' => __('Søg efter diagnosekode eller beskrivelse', 'ansico-diagnosekoder'),
|
||||
'empty' => __('Skriv for at søge i diagnosekoder.', 'ansico-diagnosekoder'),
|
||||
'noResults' => __('Ingen resultater fundet.', 'ansico-diagnosekoder'),
|
||||
'loading' => __('Søger...', 'ansico-diagnosekoder'),
|
||||
'error' => __('Der opstod en fejl under søgningen.', 'ansico-diagnosekoder'),
|
||||
'goToResults' => __('Gå til søgeresultater', 'ansico-diagnosekoder'),
|
||||
'missingResultsUrl' => __('Resultatsidens URL er ikke angivet i pluginets indstillinger.', 'ansico-diagnosekoder'),
|
||||
'copyCode' => __('Kopiér kode og beskrivelse', 'ansico-diagnosekoder'),
|
||||
'copied' => __('Kopieret', 'ansico-diagnosekoder'),
|
||||
'copyError' => __('Kunne ikke kopiere', 'ansico-diagnosekoder'),
|
||||
'copyCodeAria' => __('Kopiér %s', 'ansico-diagnosekoder'),
|
||||
'addFavorite' => __('Tilføj til favoritter', 'ansico-diagnosekoder'),
|
||||
'removeFavorite' => __('Fjern fra favoritter', 'ansico-diagnosekoder'),
|
||||
'favoriteAdded' => __('Favorit gemt', 'ansico-diagnosekoder'),
|
||||
'favoriteRemoved' => __('Favorit fjernet', 'ansico-diagnosekoder'),
|
||||
'favoriteError' => __('Kunne ikke gemme favorit', 'ansico-diagnosekoder'),
|
||||
'copyIcon' => __('Kopiér', 'ansico-diagnosekoder'),
|
||||
'favoriteIcon' => __('Favorit', 'ansico-diagnosekoder'),
|
||||
'addLink' => __('Tilknyt URL', 'ansico-diagnosekoder'),
|
||||
'removeLink' => __('Fjern URL-tilknytning', 'ansico-diagnosekoder'),
|
||||
'linkSaved' => __('URL gemt', 'ansico-diagnosekoder'),
|
||||
'linkRemoved' => __('URL fjernet', 'ansico-diagnosekoder'),
|
||||
'linkError' => __('Kunne ikke gemme URL', 'ansico-diagnosekoder'),
|
||||
'linkPrompt' => __('Indtast URL for %s', 'ansico-diagnosekoder'),
|
||||
'linkPromptDefault' => __('https://', 'ansico-diagnosekoder'),
|
||||
'openLink' => __('Åbn link', 'ansico-diagnosekoder'),
|
||||
'linkIcon' => __('Link', 'ansico-diagnosekoder'),
|
||||
'addLinkIcon' => __('Tilknyt URL', 'ansico-diagnosekoder'),
|
||||
'removeLinkIcon' => __('Fjern URL', 'ansico-diagnosekoder'),
|
||||
'linkModalTitleAdd' => __('Tilknyt link til kode', 'ansico-diagnosekoder'),
|
||||
'linkModalTitleEdit' => __('Rediger link til kode', 'ansico-diagnosekoder'),
|
||||
'linkModalCodeLabel' => __('Diagnosekode', 'ansico-diagnosekoder'),
|
||||
'linkModalUrlLabel' => __('URL-adresse', 'ansico-diagnosekoder'),
|
||||
'linkModalSearchLabel' => __('Søg efter interne sider', 'ansico-diagnosekoder'),
|
||||
'linkModalSearchPlaceholder' => __('Søg efter side eller indlæg', 'ansico-diagnosekoder'),
|
||||
'linkModalSearchEmpty' => __('Skriv for at søge efter interne sider.', 'ansico-diagnosekoder'),
|
||||
'linkModalSearchNone' => __('Ingen interne sider fundet.', 'ansico-diagnosekoder'),
|
||||
'linkModalChoose' => __('Vælg', 'ansico-diagnosekoder'),
|
||||
'linkModalCancel' => __('Annuller', 'ansico-diagnosekoder'),
|
||||
'linkModalSave' => __('Gem link', 'ansico-diagnosekoder'),
|
||||
'linkModalOpen' => __('Åbn link-dialog', 'ansico-diagnosekoder'),
|
||||
'linkModalHint' => __('Du kan enten indsætte en URL eller vælge en intern side.', 'ansico-diagnosekoder'),
|
||||
'linkSearchError' => __('Kunne ikke søge efter interne sider.', 'ansico-diagnosekoder'),
|
||||
],
|
||||
]);
|
||||
|
||||
wp_register_style(
|
||||
'ansico-diagnosekoder-style',
|
||||
ANSICO_DIAGNOSEKODER_PLUGIN_URL . 'assets/css/style.css',
|
||||
[],
|
||||
ANSICO_DIAGNOSEKODER_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
public static function register_block() {
|
||||
register_block_type('ansico/diagnosekoder', [
|
||||
'api_version' => 2,
|
||||
'editor_script' => 'ansico-diagnosekoder-block-editor',
|
||||
'style' => 'ansico-diagnosekoder-style',
|
||||
'script' => 'ansico-diagnosekoder-frontend',
|
||||
'render_callback' => [__CLASS__, 'render_block'],
|
||||
]);
|
||||
|
||||
register_block_type('ansico/diagnosekoder-soegefelt', [
|
||||
'api_version' => 2,
|
||||
'editor_script' => 'ansico-diagnosekoder-block-editor',
|
||||
'style' => 'ansico-diagnosekoder-style',
|
||||
'script' => 'ansico-diagnosekoder-frontend',
|
||||
'render_callback' => [__CLASS__, 'render_search_form_block'],
|
||||
]);
|
||||
|
||||
register_block_type('ansico/diagnosekoder-kodekort', [
|
||||
'api_version' => 2,
|
||||
'editor_script' => 'ansico-diagnosekoder-block-editor',
|
||||
'style' => 'ansico-diagnosekoder-style',
|
||||
'render_callback' => [__CLASS__, 'render_linked_code_block'],
|
||||
]);
|
||||
}
|
||||
|
||||
public static function render_block($attributes = [], $content = '', $block = null) {
|
||||
$meta = get_option(ANSICO_DIAGNOSEKODER_OPTION_META, []);
|
||||
$input_id = wp_unique_id('ansico-diagnosekoder-input-');
|
||||
$page_id = self::get_current_page_id();
|
||||
if (!$page_id) {
|
||||
$page_id = self::get_results_page_id();
|
||||
}
|
||||
$favorites = Ansico_Diagnosekoder_REST::get_page_favorites($page_id);
|
||||
$links = Ansico_Diagnosekoder_REST::get_page_links($page_id);
|
||||
$page_state = wp_json_encode([
|
||||
'pageId' => absint($page_id),
|
||||
'favorites' => array_values($favorites),
|
||||
'links' => $links,
|
||||
]);
|
||||
$preset_query = isset($_GET['q']) ? sanitize_text_field(wp_unslash($_GET['q'])) : '';
|
||||
$initial_results = $preset_query !== '' ? Ansico_Diagnosekoder_Parser::search($preset_query, 50, $favorites, $links) : [];
|
||||
ob_start();
|
||||
?>
|
||||
<div class="wp-block-ansico-diagnosekoder ansico-diagnosekoder" data-has-data="<?php echo !empty($meta['row_count']) ? '1' : '0'; ?>" data-page-id="<?php echo esc_attr((string) absint($page_id)); ?>" data-page-favorites='<?php echo esc_attr(wp_json_encode(array_values($favorites))); ?>' data-page-links='<?php echo esc_attr(wp_json_encode($links)); ?>'>
|
||||
<script type="application/json" class="ansico-diagnosekoder__page-state"><?php echo wp_json_encode([
|
||||
'pageId' => absint($page_id),
|
||||
'favorites' => array_values($favorites),
|
||||
'links' => $links,
|
||||
'query' => $preset_query,
|
||||
'results' => $initial_results,
|
||||
'hasInitialResults' => $preset_query !== '' && !empty($initial_results),
|
||||
]); ?></script>
|
||||
<div class="ansico-diagnosekoder__search">
|
||||
<label class="screen-reader-text" for="<?php echo esc_attr($input_id); ?>"><?php esc_html_e('Søg diagnosekode', 'ansico-diagnosekoder'); ?></label>
|
||||
<input
|
||||
id="<?php echo esc_attr($input_id); ?>"
|
||||
type="search"
|
||||
class="ansico-diagnosekoder__input"
|
||||
placeholder="<?php esc_attr_e('Søg efter diagnosekode eller beskrivelse', 'ansico-diagnosekoder'); ?>"
|
||||
autocomplete="off"
|
||||
value="<?php echo esc_attr($preset_query); ?>"
|
||||
/>
|
||||
</div>
|
||||
<div class="ansico-diagnosekoder__results" aria-live="polite">
|
||||
<?php if ($preset_query !== '' && !empty($initial_results)) : ?>
|
||||
<ul class="ansico-diagnosekoder__list">
|
||||
<?php foreach ($initial_results as $item) :
|
||||
$normalized_code = strtoupper(preg_replace('/\s+/', '', (string) $item['code']));
|
||||
$is_favorite = !empty($item['is_favorite']);
|
||||
$linked_url = !empty($item['linked_url']) ? (string) $item['linked_url'] : '';
|
||||
$has_link = $linked_url !== '';
|
||||
$copy_value = (string) $item['code'] . ' - ' . (string) $item['text'];
|
||||
$copy_aria = sprintf(__('Kopiér %s', 'ansico-diagnosekoder'), $copy_value);
|
||||
?>
|
||||
<li class="ansico-diagnosekoder__item<?php echo $is_favorite ? ' is-favorite' : ''; ?><?php echo $has_link ? ' has-link' : ''; ?>" data-code="<?php echo esc_attr($normalized_code); ?>" data-is-favorite="<?php echo $is_favorite ? '1' : '0'; ?>" data-has-link="<?php echo $has_link ? '1' : '0'; ?>">
|
||||
<div class="ansico-diagnosekoder__row">
|
||||
<?php if ($has_link) : ?><a class="ansico-diagnosekoder__entry-link" href="<?php echo esc_url($linked_url); ?>"><?php endif; ?>
|
||||
<div class="ansico-diagnosekoder__entry">
|
||||
<span class="ansico-diagnosekoder__code"><?php echo esc_html($item['code']); ?></span>
|
||||
<span class="ansico-diagnosekoder__separator"> – </span>
|
||||
<span class="ansico-diagnosekoder__text"><?php echo esc_html($item['text']); ?></span>
|
||||
<?php if ($has_link) : ?><span class="ansico-diagnosekoder__linked-badge"><?php esc_html_e('Åbn link', 'ansico-diagnosekoder'); ?></span><?php endif; ?>
|
||||
</div>
|
||||
<?php if ($has_link) : ?></a><?php endif; ?>
|
||||
<div class="ansico-diagnosekoder__actions">
|
||||
<button type="button" class="ansico-diagnosekoder__icon-button ansico-diagnosekoder__copy-button" data-copy-value="<?php echo esc_attr($copy_value); ?>" data-label-default="<?php echo esc_attr($copy_aria); ?>" data-label-success="<?php esc_attr_e('Kopieret', 'ansico-diagnosekoder'); ?>" data-label-error="<?php esc_attr_e('Kunne ikke kopiere', 'ansico-diagnosekoder'); ?>" aria-label="<?php echo esc_attr($copy_aria); ?>" title="<?php esc_attr_e('Kopiér', 'ansico-diagnosekoder'); ?>">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M16 1H6c-1.1 0-2 .9-2 2v12h2V3h10V1zm3 4H10c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H10V7h9v14z"></path></svg>
|
||||
</button>
|
||||
<?php if (is_user_logged_in()) : ?>
|
||||
<button type="button" class="ansico-diagnosekoder__icon-button ansico-diagnosekoder__favorite-button<?php echo $is_favorite ? ' is-active' : ''; ?>" data-code="<?php echo esc_attr($normalized_code); ?>" aria-pressed="<?php echo $is_favorite ? 'true' : 'false'; ?>" data-label-default="<?php echo esc_attr($is_favorite ? __('Fjern fra favoritter', 'ansico-diagnosekoder') : __('Tilføj til favoritter', 'ansico-diagnosekoder')); ?>" aria-label="<?php echo esc_attr($is_favorite ? __('Fjern fra favoritter', 'ansico-diagnosekoder') : __('Tilføj til favoritter', 'ansico-diagnosekoder')); ?>" title="<?php esc_attr_e('Favorit', 'ansico-diagnosekoder'); ?>">
|
||||
<?php if ($is_favorite) : ?><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" fill="currentColor"></path></svg><?php else : ?><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="none"><path d="M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"></path></svg><?php endif; ?>
|
||||
</button>
|
||||
<button type="button" class="ansico-diagnosekoder__icon-button ansico-diagnosekoder__link-button<?php echo $has_link ? ' is-active' : ''; ?>" data-code="<?php echo esc_attr($normalized_code); ?>" data-current-url="<?php echo esc_attr($linked_url); ?>" data-label-default="<?php echo esc_attr($has_link ? __('Fjern URL-tilknytning', 'ansico-diagnosekoder') : __('Tilknyt URL', 'ansico-diagnosekoder')); ?>" aria-label="<?php echo esc_attr($has_link ? __('Fjern URL-tilknytning', 'ansico-diagnosekoder') : __('Tilknyt URL', 'ansico-diagnosekoder')); ?>" title="<?php echo esc_attr($has_link ? __('Fjern URL', 'ansico-diagnosekoder') : __('Tilknyt URL', 'ansico-diagnosekoder')); ?>">
|
||||
<?php if ($has_link) : ?><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M19 11H5v2h14z"></path></svg><?php else : ?><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M19 11H13V5h-2v6H5v2h6v6h2v-6h6z"></path></svg><?php endif; ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php else : ?>
|
||||
<p class="ansico-diagnosekoder__message">
|
||||
<?php
|
||||
if ($preset_query !== '') {
|
||||
esc_html_e('Ingen resultater fundet.', 'ansico-diagnosekoder');
|
||||
} elseif (!empty($meta['row_count'])) {
|
||||
esc_html_e('Skriv for at søge i diagnosekoder.', 'ansico-diagnosekoder');
|
||||
} else {
|
||||
esc_html_e('Der er endnu ikke importeret et datagrundlag i pluginets indstillinger.', 'ansico-diagnosekoder');
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
public static function render_search_form_block($attributes = [], $content = '', $block = null) {
|
||||
$results_url = (string) get_option(ANSICO_DIAGNOSEKODER_OPTION_RESULTS_URL, '');
|
||||
$input_id = wp_unique_id('ansico-diagnosekoder-form-input-');
|
||||
ob_start();
|
||||
?>
|
||||
<form class="wp-block-ansico-diagnosekoder-soegefelt ansico-diagnosekoder ansico-diagnosekoder--search-only" data-results-url="<?php echo esc_url($results_url); ?>">
|
||||
<div class="ansico-diagnosekoder__search ansico-diagnosekoder__search--inline">
|
||||
<label class="screen-reader-text" for="<?php echo esc_attr($input_id); ?>"><?php esc_html_e('Søg diagnosekode', 'ansico-diagnosekoder'); ?></label>
|
||||
<input
|
||||
id="<?php echo esc_attr($input_id); ?>"
|
||||
type="search"
|
||||
name="q"
|
||||
class="ansico-diagnosekoder__input"
|
||||
placeholder="<?php esc_attr_e('Søg efter diagnosekode eller beskrivelse', 'ansico-diagnosekoder'); ?>"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<button type="submit" class="ansico-diagnosekoder__submit"><?php esc_html_e('Søg', 'ansico-diagnosekoder'); ?></button>
|
||||
</div>
|
||||
<?php if (empty($results_url)) : ?>
|
||||
<p class="ansico-diagnosekoder__message"><?php esc_html_e('Angiv først URL til resultatsiden under Indstillinger → Ansico Diagnosekoder.', 'ansico-diagnosekoder'); ?></p>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
|
||||
public static function render_linked_code_block($attributes = [], $content = '', $block = null) {
|
||||
$current_page_id = self::get_current_page_id();
|
||||
if (!$current_page_id) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$current_url = self::normalize_url(get_permalink($current_page_id));
|
||||
if ($current_url === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$results_page_id = self::get_results_page_id();
|
||||
if (!$results_page_id) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$links = Ansico_Diagnosekoder_REST::get_page_links($results_page_id);
|
||||
if (empty($links) || !is_array($links)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$matched_codes = [];
|
||||
foreach ($links as $code => $url) {
|
||||
if (self::normalize_url($url) === $current_url) {
|
||||
$matched_codes[] = $code;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($matched_codes)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$rows = Ansico_Diagnosekoder_Parser::get_rows_by_codes($matched_codes);
|
||||
if (empty($rows)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="wp-block-ansico-diagnosekoder-kodekort ansico-diagnosekoder-kodekort">
|
||||
<div class="ansico-diagnosekoder-kodekort__list">
|
||||
<?php foreach ($rows as $row) : ?>
|
||||
<div class="ansico-diagnosekoder-kodekort__item">
|
||||
<span class="ansico-diagnosekoder-kodekort__code"><?php echo esc_html($row['code']); ?></span>
|
||||
<span class="ansico-diagnosekoder-kodekort__separator"> – </span>
|
||||
<span class="ansico-diagnosekoder-kodekort__text"><?php echo esc_html($row['text']); ?></span>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
protected static function normalize_url($url) {
|
||||
$url = trim((string) $url);
|
||||
if ($url === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$url = esc_url_raw($url);
|
||||
if ($url === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$parts = wp_parse_url($url);
|
||||
if (!is_array($parts) || empty($parts['host'])) {
|
||||
return untrailingslashit($url);
|
||||
}
|
||||
|
||||
$scheme = !empty($parts['scheme']) ? strtolower($parts['scheme']) : 'https';
|
||||
$host = strtolower($parts['host']);
|
||||
$port = !empty($parts['port']) ? ':' . (int) $parts['port'] : '';
|
||||
$path = isset($parts['path']) ? untrailingslashit($parts['path']) : '';
|
||||
$query = isset($parts['query']) && $parts['query'] !== '' ? '?' . $parts['query'] : '';
|
||||
|
||||
return $scheme . '://' . $host . $port . $path . $query;
|
||||
}
|
||||
|
||||
|
||||
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 get_current_page_id() {
|
||||
$page_id = 0;
|
||||
|
||||
if (function_exists('get_queried_object_id')) {
|
||||
$page_id = absint(get_queried_object_id());
|
||||
}
|
||||
|
||||
if (!$page_id) {
|
||||
$page_id = absint(get_the_ID());
|
||||
}
|
||||
|
||||
global $post;
|
||||
if (!$page_id && isset($post->ID)) {
|
||||
$page_id = absint($post->ID);
|
||||
}
|
||||
|
||||
return $page_id;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class Ansico_Diagnosekoder_Parser {
|
||||
public static function parse_file($file_path) {
|
||||
if (!file_exists($file_path) || !is_readable($file_path)) {
|
||||
return [
|
||||
'rows' => [],
|
||||
'meta' => [
|
||||
'error' => __('Filen kunne ikke læses.', 'ansico-diagnosekoder'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$handle = fopen($file_path, 'r');
|
||||
if (!$handle) {
|
||||
return [
|
||||
'rows' => [],
|
||||
'meta' => [
|
||||
'error' => __('Filen kunne ikke åbnes.', 'ansico-diagnosekoder'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$rows = [];
|
||||
$header_found = false;
|
||||
$line_number = 0;
|
||||
|
||||
while (($line = fgets($handle)) !== false) {
|
||||
$line_number++;
|
||||
$line = trim($line);
|
||||
|
||||
if ($line === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$columns = str_getcsv($line, ';', '"', '\\');
|
||||
if (!is_array($columns) || count($columns) < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$col1 = isset($columns[0]) ? trim((string) $columns[0]) : '';
|
||||
$col2 = isset($columns[1]) ? trim((string) $columns[1]) : '';
|
||||
|
||||
if (!$header_found) {
|
||||
if (strcasecmp($col1, 'Kode') === 0 && strcasecmp($col2, 'Tekst') === 0) {
|
||||
$header_found = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($col1 === '' || $col2 === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$rows[] = [
|
||||
'code' => sanitize_text_field($col1),
|
||||
'text' => sanitize_text_field($col2),
|
||||
];
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
return [
|
||||
'rows' => $rows,
|
||||
'meta' => [
|
||||
'imported_at' => current_time('mysql'),
|
||||
'row_count' => count($rows),
|
||||
'source_name' => basename($file_path),
|
||||
'header_found' => $header_found,
|
||||
'line_count' => $line_number,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public static function search($query, $limit = 50, $favorite_codes = [], $links = []) {
|
||||
$query = trim((string) $query);
|
||||
if ($query === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = get_option(ANSICO_DIAGNOSEKODER_OPTION_DATA, []);
|
||||
if (!is_array($data) || empty($data)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$limit = $limit > 0 ? min($limit, 100) : 50;
|
||||
$query_lower = function_exists('mb_strtolower') ? mb_strtolower($query, 'UTF-8') : strtolower($query);
|
||||
$favorite_lookup = [];
|
||||
foreach ((array) $favorite_codes as $favorite_code) {
|
||||
$favorite_lookup[self::normalize_code($favorite_code)] = true;
|
||||
}
|
||||
$link_lookup = is_array($links) ? $links : [];
|
||||
|
||||
$results = [];
|
||||
foreach ($data as $index => $row) {
|
||||
if (!is_array($row) || empty($row['code']) || empty($row['text'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$code = (string) $row['code'];
|
||||
$text = (string) $row['text'];
|
||||
$normalized_code = self::normalize_code($code);
|
||||
$haystack_code = function_exists('mb_strtolower') ? mb_strtolower($code, 'UTF-8') : strtolower($code);
|
||||
$haystack_text = function_exists('mb_strtolower') ? mb_strtolower($text, 'UTF-8') : strtolower($text);
|
||||
|
||||
if (strpos($haystack_code, $query_lower) === false && strpos($haystack_text, $query_lower) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$results[] = [
|
||||
'code' => $code,
|
||||
'text' => $text,
|
||||
'is_favorite' => isset($favorite_lookup[$normalized_code]),
|
||||
'linked_url' => isset($link_lookup[$normalized_code]) ? $link_lookup[$normalized_code] : '',
|
||||
'_original_index' => $index,
|
||||
];
|
||||
}
|
||||
|
||||
if (empty($results)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
usort($results, static function ($a, $b) {
|
||||
$a_favorite = !empty($a['is_favorite']);
|
||||
$b_favorite = !empty($b['is_favorite']);
|
||||
|
||||
if ($a_favorite !== $b_favorite) {
|
||||
return $a_favorite ? -1 : 1;
|
||||
}
|
||||
|
||||
return ((int) ($a['_original_index'] ?? 0)) <=> ((int) ($b['_original_index'] ?? 0));
|
||||
});
|
||||
|
||||
foreach ($results as &$result) {
|
||||
unset($result['_original_index']);
|
||||
}
|
||||
unset($result);
|
||||
|
||||
return array_slice($results, 0, $limit);
|
||||
}
|
||||
|
||||
public static function get_rows_by_codes($codes = []) {
|
||||
$normalized_codes = [];
|
||||
foreach ((array) $codes as $code) {
|
||||
$normalized = self::normalize_code($code);
|
||||
if ($normalized !== '') {
|
||||
$normalized_codes[] = $normalized;
|
||||
}
|
||||
}
|
||||
$normalized_codes = array_values(array_unique($normalized_codes));
|
||||
if (empty($normalized_codes)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$lookup = array_fill_keys($normalized_codes, true);
|
||||
$data = get_option(ANSICO_DIAGNOSEKODER_OPTION_DATA, []);
|
||||
if (!is_array($data) || empty($data)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = [];
|
||||
foreach ($data as $row) {
|
||||
if (!is_array($row) || empty($row['code']) || empty($row['text'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$code = (string) $row['code'];
|
||||
$normalized_code = self::normalize_code($code);
|
||||
if (!isset($lookup[$normalized_code])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$rows[$normalized_code] = [
|
||||
'code' => $code,
|
||||
'text' => (string) $row['text'],
|
||||
];
|
||||
}
|
||||
|
||||
$ordered = [];
|
||||
foreach ($normalized_codes as $normalized_code) {
|
||||
if (isset($rows[$normalized_code])) {
|
||||
$ordered[] = $rows[$normalized_code];
|
||||
}
|
||||
}
|
||||
|
||||
return $ordered;
|
||||
}
|
||||
|
||||
protected static function normalize_code($code) {
|
||||
$code = sanitize_text_field((string) $code);
|
||||
$code = preg_replace('/\s+/', '', $code);
|
||||
return strtoupper((string) $code);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,387 @@
|
|||
<?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);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue