Ansico-diagnosekoder/ansico-diagnosekoder/includes/class-ansico-diagnosekoder-block.php

351 lines
20 KiB
PHP
Raw Permalink Normal View History

2026-04-18 22:06:24 +00:00
<?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;
}
}