Ansico-diagnosekoder/ansico-diagnosekoder/includes/class-ansico-diagnosekoder-block.php
2026-04-19 00:06:24 +02:00

350 lines
20 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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