' . $content . '
';
+ if ($doc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD)) {
+ foreach ($doc->getElementsByTagName('a') as $link) {
+ $href = $link->getAttribute('href');
+ $parsed = self::normalize_external_source($href, $home_host);
+ if ($parsed && !empty($parsed['url'])) {
+ $sources[$parsed['url']] = $parsed;
+ }
+ }
+ }
+ libxml_clear_errors();
+ libxml_use_internal_errors($internal_errors);
+
+ return array_values($sources);
+ }
+
+ public static function normalize_external_source($url, $home_host = '') {
+ $url = trim((string) $url);
+ if ($url === '' || strpos($url, '#') === 0) {
+ return null;
+ }
+ if (preg_match('/^(mailto:|tel:|javascript:)/i', $url)) {
+ return null;
+ }
+ if (strpos($url, '//') === 0) {
+ $url = is_ssl() ? 'https:' . $url : 'http:' . $url;
+ }
+ if (!preg_match('#^https?://#i', $url)) {
+ return null;
+ }
+
+ $host = wp_parse_url($url, PHP_URL_HOST);
+ if (!$host) {
+ return null;
+ }
+ $normalized_host = preg_replace('/^www\./i', '', strtolower($host));
+ if ($home_host && $normalized_host === $home_host) {
+ return null;
+ }
+
+ return array(
+ 'url' => esc_url_raw($url),
+ 'label' => $normalized_host,
+ );
+ }
+
+ public function filter_author_link($link, $author_id, $author_nicename) {
+ if (is_admin()) {
+ return $link;
+ }
+ $settings = self::get_settings();
+ if (($settings['author_link_mode'] ?? 'archive') === 'custom' && !empty($settings['author_custom_url'])) {
+ return esc_url($settings['author_custom_url']);
+ }
+ return $link;
+ }
+
+ public function filter_author_posts_link($link_html) {
+ if (is_admin()) {
+ return $link_html;
+ }
+ $post_type = self::get_context_post_type();
+ if ($post_type && self::should_hide_author_for_post_type($post_type)) {
+ return '';
+ }
+ return $link_html;
+ }
+
+ public function filter_the_date($the_date, $format, $post) {
+ if (is_admin()) {
+ return $the_date;
+ }
+ $post_obj = $post ? get_post($post) : get_post();
+ if (!$post_obj) {
+ return $the_date;
+ }
+ if (self::should_hide_date_for_post_type($post_obj->post_type)) {
+ return '';
+ }
+ if (self::should_use_modified_date_for_post_type($post_obj->post_type)) {
+ $format = $format ? $format : get_option('date_format');
+ return get_the_modified_date($format, $post_obj);
+ }
+ return $the_date;
+ }
+
+ public static function get_context_post_type() {
+ $post = get_post();
+ if ($post && !empty($post->post_type)) {
+ return $post->post_type;
+ }
+ if (is_singular()) {
+ $queried = get_queried_object();
+ if ($queried && !empty($queried->post_type)) {
+ return $queried->post_type;
+ }
+ }
+ return '';
+ }
+
+ public static function should_hide_author_for_post_type($post_type) {
+ $settings = self::get_settings();
+ return !empty($post_type) && in_array($post_type, (array) $settings['hide_author_post_types'], true);
+ }
+
+ public static function should_hide_date_for_post_type($post_type) {
+ $settings = self::get_settings();
+ return !empty($post_type) && in_array($post_type, (array) $settings['hide_date_post_types'], true);
+ }
+
+ public static function should_use_modified_date_for_post_type($post_type) {
+ $settings = self::get_settings();
+ return !empty($post_type) && in_array($post_type, (array) $settings['modified_date_post_types'], true);
+ }
+
+ public static function should_insert_citations_for_post_type($post_type) {
+ $settings = self::get_settings();
+ return !empty($post_type) && in_array($post_type, (array) $settings['citation_post_types'], true);
+ }
+
+ public static function get_settings() {
+ $saved = get_option(self::OPTION_KEY, array());
+ $defaults = array(
+ 'post_type_order' => array(),
+ 'hidden_post_types' => array(),
+ 'archive_post_types' => array(),
+ 'archive_taxonomies' => array(),
+ 'toc_enabled' => 0,
+ 'toc_title' => 'INDHOLD',
+ 'toc_post_types' => array('post', 'page'),
+ 'toc_min_headings' => 3,
+ 'toc_list_type' => 'bullets',
+ 'toc_collapsible' => 1,
+ 'toc_scrollspy' => 1,
+ 'author_link_mode' => 'archive',
+ 'author_custom_url' => '',
+ 'hide_author_post_types' => array(),
+ 'hide_date_post_types' => array(),
+ 'modified_date_post_types'=> array(),
+ 'citation_post_types' => array(),
+ );
+ $settings = wp_parse_args(is_array($saved) ? $saved : array(), $defaults);
+ foreach (self::get_available_post_types() as $post_type_name => $object) {
+ if (!isset($settings['post_type_order'][$post_type_name])) {
+ $settings['post_type_order'][$post_type_name] = count($settings['post_type_order']) + 1;
+ }
+ }
+ return $settings;
+ }
+
+ public static function get_available_post_types() {
+ $post_types = get_post_types(array('public' => true), 'objects');
+ foreach ($post_types as $name => $obj) {
+ if ($name === 'attachment' || (!$obj->publicly_queryable && !$obj->show_ui)) {
+ unset($post_types[$name]);
+ }
+ }
+ return $post_types;
+ }
+
+ public static function get_ordered_available_post_types() {
+ $post_types = self::get_available_post_types();
+ $settings = self::get_settings();
+ uasort($post_types, function ($a, $b) use ($settings) {
+ $order_a = isset($settings['post_type_order'][$a->name]) ? (int) $settings['post_type_order'][$a->name] : 9999;
+ $order_b = isset($settings['post_type_order'][$b->name]) ? (int) $settings['post_type_order'][$b->name] : 9999;
+ if ($order_a === $order_b) return strnatcasecmp($a->labels->name, $b->labels->name);
+ return $order_a - $order_b;
+ });
+ return $post_types;
+ }
+
+ public static function get_available_taxonomies_for_settings() {
+ $taxonomies = get_taxonomies(array('public' => true), 'objects');
+ foreach ($taxonomies as $taxonomy_name => $taxonomy_object) {
+ if (in_array($taxonomy_name, array('post_format', 'nav_menu', 'link_category'), true)) {
+ unset($taxonomies[$taxonomy_name]);
+ }
+ }
+ uasort($taxonomies, function ($a, $b) { return strnatcasecmp($a->labels->name, $b->labels->name); });
+ return $taxonomies;
+ }
+
+ public static function get_available_taxonomies_for_block() {
+ return self::get_available_taxonomies_for_settings();
+ }
+
+ public static function get_searchable_post_types() {
+ $settings = self::get_settings();
+ $post_types = self::get_ordered_available_post_types();
+ $searchable = array();
+ foreach ($post_types as $post_type_name => $obj) {
+ if (in_array($post_type_name, $settings['hidden_post_types'], true)) continue;
+ if (!empty($obj->exclude_from_search)) continue;
+ $searchable[] = $post_type_name;
+ }
+ return $searchable;
+ }
+
+ public static function get_grouped_search_results() {
+ $search_term = get_search_query();
+ $grouped_results = array();
+ $ordered_post_types = self::get_ordered_available_post_types();
+ $selected_post_types = self::get_searchable_post_types();
+ if (empty($selected_post_types) || $search_term === '') return array();
+ foreach ($ordered_post_types as $post_type_name => $post_type_object) {
+ if (in_array($post_type_name, $selected_post_types, true)) {
+ $grouped_results[$post_type_name] = array('label' => $post_type_object->labels->name, 'results' => array());
+ }
+ }
+ $search_query = new WP_Query(array(
+ 'post_type' => $selected_post_types,
+ 'post_status' => 'publish',
+ 's' => $search_term,
+ 'posts_per_page' => -1,
+ 'orderby' => 'title',
+ 'order' => 'ASC',
+ 'ignore_sticky_posts' => true,
+ 'no_found_rows' => true,
+ ));
+ foreach ($search_query->posts as $post) {
+ if (isset($grouped_results[$post->post_type])) {
+ $grouped_results[$post->post_type]['results'][] = array('title' => get_the_title($post), 'url' => get_permalink($post));
+ }
+ }
+ wp_reset_postdata();
+ foreach ($grouped_results as $post_type_name => $group) {
+ if (empty($group['results'])) unset($grouped_results[$post_type_name]);
+ }
+ return $grouped_results;
+ }
+
+ public static function get_total_results_count($grouped_results = null) {
+ if (!is_array($grouped_results)) $grouped_results = self::get_grouped_search_results();
+ $total = 0; foreach ($grouped_results as $group) $total += count($group['results']);
+ return $total;
+ }
+
+ public static function get_total_results_text($total_results) {
+ return ((int) $total_results === 1) ? 'Fandt i alt 1 resultat.' : sprintf('Fandt i alt %d resultater.', (int) $total_results);
+ }
+
+ public static function render_group_results_list($results) {
+ if (empty($results)) return '';
+ $visible_results = array_slice($results, 0, 10);
+ $hidden_results = array_slice($results, 10);
+ ob_start();
+ echo '
+
+
+
+
+
+ Der blev ikke fundet nogen resultater.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Der blev ikke fundet nogen resultater.
+
+
+
+
+
+
+
+
+
+ $group) : ?>
+
+
+
+ Der blev ikke fundet nogen resultater.
+
+
+
+