403Webshell
Server IP : 202.61.199.114  /  Your IP : 216.73.217.139
Web Server : nginx/1.22.1
System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64
User : web20 ( 1018)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/www/clients/client2/web20/web/wp-content/themes/drogentest-online/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/clients/client2/web20/web/wp-content/themes/drogentest-online/functions.php
<?php
/**
 * Drogentest Online – Theme-Funktionen
 *
 * - Lädt Bootstrap 5 + eigenes Design lokal (kein CDN)
 * - Inter-Font wird per @font-face in main.css lokal eingebunden
 * - Sticky-Navigation + responsives Layout
 *
 * @package drogentest-online
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Direktzugriff verhindern
}

if ( ! defined( 'DGT_VERSION' ) ) {
	define( 'DGT_VERSION', '1.4.0' );
}

// Benutzer-Sitemap deaktivieren (keine Autorennamen exponieren).
add_filter( 'wp_sitemaps_add_provider', function ( $provider, $name ) {
	return 'users' === $name ? false : $provider;
}, 10, 2 );

// wp-emoji deaktivieren.
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
add_filter( 'emoji_svg_url', '__return_false' );

// Suchtberatung: /vcard/ URLs → 301 zum Originalbeitrag.
add_action( 'template_redirect', function () {
	if ( preg_match( '#^(.+)/vcard/?$#', $_SERVER['REQUEST_URI'], $m ) ) {
		wp_redirect( home_url( $m[1] ) . '/', 301 );
		exit;
	}
} );

add_filter( 'author_rewrite_rules', '__return_empty_array' );
add_action( 'template_redirect', function () {
	if ( is_author() ) {
		global $wp_query;
		$wp_query->set_404();
		status_header( 404 );
		nocache_headers();
	}
} );


// Suchtberatung-Verzeichnis (Datenzugriff, SEO-Routing).
require_once get_template_directory() . '/inc/suchtberatung.php';

// Suchtberatung: Meldungen & Vorschläge (E-Mail-Backend, Modals, Autocomplete).
require_once get_template_directory() . '/inc/suchtberatung-forms.php';

// Kontaktformular – Shortcode [ticket] inkl. ArNi-CRM-Ticket-Anbindung.
require_once get_template_directory() . '/inc/kontakt-form.php';

// Suchtberatung: Admin-Inline-Bearbeitung (Edit-Modal, Aktiv/Inaktiv-Toggle).
require_once get_template_directory() . '/inc/suchtberatung-admin.php';

// Wiederverwendbare Inhalts-Sektionen für die Ratgeber-/Themenseiten.
require_once get_template_directory() . '/inc/content-sections.php';

// Drogenpolitik: Kontinent-Struktur, Routing und SEO.
require_once get_template_directory() . '/inc/drogenpolitik-continents.php';

// SEO: Meta-Tags, Open Graph, Schema.org + Backend-Felder (Seiten & Kategorien).
require_once get_template_directory() . '/inc/seo.php';

// HTML-Minify der Ausgabe für nicht eingeloggte Besucher.
require_once get_template_directory() . '/inc/minify.php';

// Promille-Rechner-Shortcode.
require_once get_template_directory() . '/inc/promille.php';

// Facebook-Post-Modal für Blog-Beiträge.
require_once get_template_directory() . '/inc/facebook-blog.php';

// Verkehrsmonitor-Menüpunkt auf allen /verkehrsmonitor/-Unterseiten aktiv halten.
// Blog-Menüpunkt auf Drogenpolitik-Seiten NICHT als aktiv anzeigen.
add_filter( 'nav_menu_css_class', function ( $classes, $item ) {
	if ( get_query_var( 'dgt_vm' ) && str_contains( $item->url, '/verkehrsmonitor/' ) ) {
		$classes[] = 'current-menu-item';
	}
	if ( is_singular( 'drogenpolitik' ) || is_post_type_archive( 'drogenpolitik' ) || get_query_var( 'dgt_dp_continent' ) || get_query_var( 'dgt_dp_category' ) ) {
		if ( str_contains( $item->url, '/blog/' ) ) {
			$classes = array_diff( $classes, array( 'current_page_parent', 'current-menu-item', 'current-menu-ancestor' ) );
		}
	}
	return $classes;
}, 10, 2 );

/**
 * Rewrite-Regeln einmalig flushen, wenn sich die Theme-/Routing-Version ändert.
 * (Greift auch, wenn das Theme bereits aktiv ist.)
 */
function dgt_maybe_flush_rewrites() {
	if ( get_option( 'dgt_rewrites_version' ) !== DGT_VERSION ) {
		dgt_sb_rewrite_rules();
		flush_rewrite_rules( false );
		update_option( 'dgt_rewrites_version', DGT_VERSION );
	}
}
add_action( 'init', 'dgt_maybe_flush_rewrites', 99 );

/**
 * Theme-Grundfunktionen registrieren.
 */
function dgt_theme_setup() {
	// Dynamischer <title> über WordPress.
	add_theme_support( 'title-tag' );

	// Beitragsbilder.
	add_theme_support( 'post-thumbnails' );

	// HTML5-Markup.
	add_theme_support(
		'html5',
		array( 'search-form', 'comment-form', 'comment-list', 'gallery', 'caption', 'style', 'script' )
	);

	// Eigenes Logo (optional über den Customizer austauschbar).
	add_theme_support(
		'custom-logo',
		array(
			'height'      => 44,
			'width'       => 232,
			'flex-width'  => true,
			'flex-height' => true,
		)
	);

	// Navigations-Menü registrieren.
	register_nav_menus(
		array(
			'primary' => __( 'Hauptmenü', 'drogentest-online' ),
			'footer'  => __( 'Footer-Menü', 'drogentest-online' ),
		)
	);

	// Eigene Bildgröße für Blog-/Produktkarten.
	add_image_size( 'dgt-card', 720, 460, true );

	// WooCommerce-Unterstützung (Produktübersicht).
	add_theme_support( 'woocommerce' );
}
add_action( 'after_setup_theme', 'dgt_theme_setup' );

/**
 * Custom Post Type: Drogenpolitik.
 */
function dgt_register_cpt_drogenpolitik() {
	register_post_type(
		'drogenpolitik',
		array(
			'labels'       => array(
				'name'          => 'Drogenpolitik',
				'singular_name' => 'Drogenpolitik',
				'menu_name'     => 'Drogenpolitik',
			),
			'hierarchical' => true,
			'public'       => true,
			'show_ui'      => true,
			'show_in_menu' => true,
			'has_archive'  => 'einfach-aufgeklaert/drogenpolitik',
			'rewrite'      => array( 'slug' => 'einfach-aufgeklaert/drogenpolitik', 'with_front' => false ),
			'supports'     => array( 'title', 'editor', 'thumbnail', 'page-attributes' ),
		)
	);
}
add_action( 'init', 'dgt_register_cpt_drogenpolitik' );

function dgt_drogenpolitik_301_redirect() {
	if ( ! isset( $_SERVER['REQUEST_URI'] ) ) {
		return;
	}
	$uri = $_SERVER['REQUEST_URI'];
	if ( preg_match( '#^/drogenpolitik(/.*)?$#', $uri, $m ) ) {
		$tail = isset( $m[1] ) ? $m[1] : '/';
		wp_redirect( home_url( '/einfach-aufgeklaert/drogenpolitik' . $tail ), 301 );
		exit;
	}
}
add_action( 'template_redirect', 'dgt_drogenpolitik_301_redirect' );

add_action( 'template_redirect', function () {
	if ( ! isset( $_SERVER['REQUEST_URI'] ) || strpos( $_SERVER['REQUEST_URI'], '/shop/' ) !== 0 ) {
		return;
	}
	$map = array(
		'kokain-wischtest-fuer-oberflaechen'            => '/drogentest/wischtest/',
		'boo-drogenwischtest-fuer-oberflaechen-10-drogenarten' => '/drogentest/wischtest/',
		'drugnostic-self-test-drogenschnelltest-urin-feststoffe-schweiss' => '/drogentest/',
	);
	$slug = trim( str_replace( '/shop/', '', $_SERVER['REQUEST_URI'] ), '/' );
	$dest = isset( $map[ $slug ] ) ? $map[ $slug ] : '/drogentest/';
	wp_redirect( home_url( $dest ), 301 );
	exit;
} );

add_action( 'template_redirect', function () {
	if ( ! isset( $_SERVER['REQUEST_URI'] ) ) {
		return;
	}
	$uri = $_SERVER['REQUEST_URI'];

	if ( preg_match( '#^/erklaert-aufgeklaert(/.*)?$#', $uri, $m ) ) {
		$tail = isset( $m[1] ) ? $m[1] : '/';
		wp_redirect( home_url( '/einfach-aufgeklaert' . $tail ), 301 );
		exit;
	}

	$old_cat_slugs = array( 'allgemein', 'safer-use', 'ratgeber' );
	if ( preg_match( '#^/(' . implode( '|', $old_cat_slugs ) . ')/([^/]+)/?$#', $uri, $m ) ) {
		$post = get_page_by_path( $m[2], OBJECT, 'post' );
		if ( $post ) {
			wp_redirect( get_permalink( $post->ID ), 301 );
			exit;
		}
	}

	if ( preg_match( '#^/blog/([^/]+)/?$#', $uri, $m ) && ! preg_match( '#^/blog/\d{4}/#', $uri ) ) {
		$post = get_page_by_path( $m[1], OBJECT, 'post' );
		if ( $post ) {
			wp_redirect( get_permalink( $post->ID ), 301 );
			exit;
		}
	}

	if ( preg_match( '#^/category/blog/?$#', $uri ) ) {
		wp_redirect( home_url( '/blog/allgemein/' ), 301 );
		exit;
	}
	if ( preg_match( '#^/category/(.+)$#', $uri, $m ) ) {
		wp_redirect( home_url( '/blog/' . $m[1] ), 301 );
		exit;
	}
	if ( preg_match( '#^/blog/category/(.+)$#', $uri, $m ) ) {
		wp_redirect( home_url( '/blog/' . $m[1] ), 301 );
		exit;
	}
} );

add_action( 'init', function () {
	add_rewrite_rule( 'blog/(?!category/|tag/|type/|author/|page/|feed/|embed/|[0-9]{4}/)([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?category_name=$matches[1]&feed=$matches[2]', 'top' );
	add_rewrite_rule( 'blog/(?!category/|tag/|type/|author/|page/|feed/|embed/|[0-9]{4}/)([^/]+)/(feed|rdf|rss|rss2|atom)/?$', 'index.php?category_name=$matches[1]&feed=$matches[2]', 'top' );
	add_rewrite_rule( 'blog/(?!category/|tag/|type/|author/|page/|feed/|embed/|[0-9]{4}/)([^/]+)/page/?([0-9]{1,})/?$', 'index.php?category_name=$matches[1]&paged=$matches[2]', 'top' );
	add_rewrite_rule( 'blog/(?!category/|tag/|type/|author/|page/|feed/|embed/|[0-9]{4}/)([^/]+)/?$', 'index.php?category_name=$matches[1]', 'top' );
} );

add_filter( 'category_link', function ( $link ) {
	return str_replace( '/blog/category/', '/blog/', $link );
} );

/**
 * Inhaltsbreite (WordPress-Standardwert).
 */
function dgt_content_width() {
	$GLOBALS['content_width'] = 820;
}
add_action( 'after_setup_theme', 'dgt_content_width', 0 );

/**
 * Excerpt-Länge und "Weiterlesen"-Zeichen anpassen.
 */
function dgt_excerpt_length() {
	return 24;
}
add_filter( 'excerpt_length', 'dgt_excerpt_length' );

function dgt_excerpt_more() {
	return '&hellip;';
}
add_filter( 'excerpt_more', 'dgt_excerpt_more' );

/**
 * Styles & Scripts lokal einbinden (kein CDN).
 */
function dgt_enqueue_assets() {
	$uri = get_template_directory_uri();
	$dir = get_template_directory();

	// Cache-Busting anhand der Datei-Änderungszeit, sonst Theme-Version.
	$bs_css_ver  = file_exists( $dir . '/assets/css/bootstrap.min.css' ) ? filemtime( $dir . '/assets/css/bootstrap.min.css' ) : DGT_VERSION;
	$main_ver    = file_exists( $dir . '/assets/css/main.css' ) ? filemtime( $dir . '/assets/css/main.css' ) : DGT_VERSION;
	$bs_js_ver   = file_exists( $dir . '/assets/js/bootstrap.bundle.min.js' ) ? filemtime( $dir . '/assets/js/bootstrap.bundle.min.js' ) : DGT_VERSION;
	$main_js_ver = file_exists( $dir . '/assets/js/main.js' ) ? filemtime( $dir . '/assets/js/main.js' ) : DGT_VERSION;

	/* ---------- CSS ---------- */
	// Bootstrap zuerst …
	wp_enqueue_style( 'bootstrap', $uri . '/assets/css/bootstrap.min.css', array(), $bs_css_ver );
	// … dann das eigene Design (überschreibt Bootstrap).
	wp_enqueue_style( 'dgt-main', $uri . '/assets/css/main.css', array( 'bootstrap' ), $main_ver );
	// WordPress-Pflicht-Stylesheet (Theme-Header).
	wp_enqueue_style( 'dgt-style', get_stylesheet_uri(), array( 'dgt-main' ), DGT_VERSION );

	/* ---------- JS ---------- */
	// Bootstrap-Bundle (inkl. Popper) im Footer.
	wp_enqueue_script( 'bootstrap', $uri . '/assets/js/bootstrap.bundle.min.js', array(), $bs_js_ver, true );
	// Eigenes JS (Sticky-Header, Mobile-Menü).
	wp_enqueue_script( 'dgt-main', $uri . '/assets/js/main.js', array( 'bootstrap' ), $main_js_ver, true );

	// DSGVO-Cookie-Consent (ohne Abhängigkeit, früh im Footer).
	$cc_ver = file_exists( $dir . '/assets/js/cookie-consent.js' ) ? filemtime( $dir . '/assets/js/cookie-consent.js' ) : DGT_VERSION;
	wp_enqueue_script( 'dgt-cookie-consent', $uri . '/assets/js/cookie-consent.js', array(), $cc_ver, true );

	// Kommentar-Reply-Script nur wo nötig.
	if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
		wp_enqueue_script( 'comment-reply' );
	}

	$vmt = $dir . '/assets/js/vm-teaser-tracking.js';
	if ( file_exists( $vmt ) && wp_script_is( 'arni-crm-tracking', 'enqueued' ) ) {
		wp_enqueue_script( 'dgt-vm-teaser-tracking', $uri . '/assets/js/vm-teaser-tracking.js', array( 'arni-crm-tracking' ), filemtime( $vmt ), true );
	}

	if ( is_singular( 'drogenpolitik' ) || is_post_type_archive( 'drogenpolitik' ) || get_query_var( 'dgt_dp_continent' ) || get_query_var( 'dgt_dp_category' ) ) {
		$dp_s = $dir . '/assets/js/dp-search.js';
		wp_enqueue_script( 'dgt-dp-search', $uri . '/assets/js/dp-search.js', array(), file_exists( $dp_s ) ? filemtime( $dp_s ) : DGT_VERSION, true );
	}

	if ( is_singular() ) {
		$gal = $dir . '/assets/js/gallery.js';
		if ( file_exists( $gal ) ) {
			wp_enqueue_script( 'dgt-gallery', $uri . '/assets/js/gallery.js', array(), filemtime( $gal ), true );
		}
	}
}
add_action( 'wp_enqueue_scripts', 'dgt_enqueue_assets' );

/**
 * Inter-Fonts früh vorladen (schnellerer First Paint).
 */
function dgt_preload_fonts() {
	$uri = get_template_directory_uri();
	foreach ( array( '400', '600', '800' ) as $weight ) {
		printf(
			'<link rel="preload" href="%s/assets/fonts/inter-%s.woff2" as="font" type="font/woff2" crossorigin>' . "\n",
			esc_url( $uri ),
			esc_attr( $weight )
		);
	}
}
add_action( 'wp_head', 'dgt_preload_fonts', 1 );

/**
 * Favicons / App-Icons fachgerecht im <head> einbinden.
 * Quelle: aus dem Logo-Icon abgeleitet (assets/favicon/).
 */
function dgt_favicons() {
	$u = get_template_directory_uri() . '/assets/favicon';
	echo "\n<!-- Favicons -->\n";
	printf( '<link rel="icon" href="%s/favicon.ico" sizes="32x32">' . "\n", esc_url( $u ) );
	printf( '<link rel="icon" type="image/svg+xml" href="%s/favicon.svg">' . "\n", esc_url( $u ) );
	printf( '<link rel="icon" type="image/png" sizes="32x32" href="%s/favicon-32.png">' . "\n", esc_url( $u ) );
	printf( '<link rel="icon" type="image/png" sizes="16x16" href="%s/favicon-16.png">' . "\n", esc_url( $u ) );
	printf( '<link rel="apple-touch-icon" sizes="180x180" href="%s/apple-touch-icon.png">' . "\n", esc_url( $u ) );
	printf( '<link rel="manifest" href="%s/site.webmanifest">' . "\n", esc_url( $u ) );
	echo '<meta name="theme-color" content="#108e6c">' . "\n";
}
add_action( 'wp_head', 'dgt_favicons', 2 );

/**
 * WordPress-eigene (ggf. fehlende) Site-Icon-Ausgabe nicht doppeln:
 * Falls unter Einstellungen kein Site-Icon gesetzt ist, liefert das Theme die Icons.
 */
function dgt_has_site_icon_guard() {
	// Wenn ein Site-Icon im Customizer gesetzt ist, übernimmt WordPress die Ausgabe;
	// dann entfernen wir die Theme-Variante, um Dopplungen zu vermeiden.
	if ( function_exists( 'has_site_icon' ) && has_site_icon() ) {
		remove_action( 'wp_head', 'dgt_favicons', 2 );
	}
}
add_action( 'wp_head', 'dgt_has_site_icon_guard', 1 );

/**
 * Body-Klassen für sauberes Styling.
 */
function dgt_body_classes( $classes ) {
	$classes[] = 'dgt-site';
	return $classes;
}
add_filter( 'body_class', 'dgt_body_classes' );

/**
 * Kleiner Helfer: Bildpfad im Theme-Asset-Ordner.
 *
 * @param string $file Dateiname in /assets/img/.
 * @return string      Vollständige URL.
 */
function dgt_img( $file ) {
	return get_template_directory_uri() . '/assets/img/' . ltrim( $file, '/' );
}

function dgt_pixabay_credit( $attachment_id ) {
	$c = get_post_meta( $attachment_id, '_dgt_pixabay_credit', true );
	if ( $c ) {
		printf( '<small class="dgt-pixabay-credit">%s</small>', esc_html( $c ) );
	}
}

/**
 * Grünes Häkchen-Icon (Checkliste). Gibt fertiges, sicheres SVG-Markup zurück.
 *
 * @return string SVG.
 */
function dgt_check() {
	return '<svg class="dgt-check" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true"><circle cx="10" cy="10" r="9" fill="#108e6c" fill-opacity=".12"/><path d="m6 10.2 2.6 2.6L14 7.4" stroke="#108e6c" stroke-width="1.7" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>';
}

/**
 * Fallback-Navigation, falls (noch) kein WordPress-Menü unter "primary"
 * zugewiesen ist. Bildet die Menüpunkte aus dem Mockup ab.
 */
function dgt_default_menu() {
	$items = array(
		array( 'label' => 'Drogentest', 'url' => home_url( '/drogentest/' ), 'caret' => false ),
		array( 'label' => 'Einfach aufgeklärt', 'url' => home_url( '/einfach-aufgeklaert/' ), 'caret' => false ),
		array( 'label' => 'Informationen', 'url' => home_url( '/informationen/' ), 'caret' => false ),
		array( 'label' => 'Suchtberatung', 'url' => home_url( '/suchtberatung/' ), 'caret' => false ),
	);

	echo '<ul id="primary-menu" class="navbar-nav dgt-nav mx-md-auto">';
	foreach ( $items as $item ) {
		printf(
			'<li class="nav-item"><a class="nav-link%s" href="%s">%s%s</a></li>',
			$item['caret'] ? ' dgt-has-caret' : '',
			esc_url( $item['url'] ),
			esc_html( $item['label'] ),
			$item['caret'] ? ' <svg class="dgt-caret" width="10" height="6" viewBox="0 0 10 6" aria-hidden="true"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>' : ''
		);
	}
	echo '</ul>';
}

/**
 * Beitrags-Meta (Datum · Kategorie · Lesezeit) für Blog-Listen und Einzelbeitrag.
 */
function dgt_post_meta() {
	$cats = get_the_category();
	echo '<ul class="dgt-meta">';
	printf(
		'<li class="dgt-meta-date"><time datetime="%s">%s</time></li>',
		esc_attr( get_the_date( DATE_W3C ) ),
		esc_html( get_the_date() )
	);
	if ( ! empty( $cats ) ) {
		printf(
			'<li class="dgt-meta-cat"><a href="%s">%s</a></li>',
			esc_url( get_category_link( $cats[0]->term_id ) ),
			esc_html( $cats[0]->name )
		);
	}
	printf(
		'<li class="dgt-meta-read">%s Min. Lesezeit</li>',
		esc_html( max( 1, (int) round( str_word_count( wp_strip_all_tags( get_the_content() ) ) / 200 ) ) )
	);
	echo '</ul>';
}

/**
 * Breadcrumb-Items automatisch aus dem aktuellen Seitenkontext ermitteln.
 *
 * Gibt ein Array von [ 'label' => …, 'url' => … ] zurück (inkl. Startseite
 * als erstes und aktuelle Seite als letztes Element). Wird zentral von
 * dgt_breadcrumb() und dgt_seo_breadcrumb_node() genutzt.
 *
 * @param string $current  Optionaler Label-Override für die letzte Stufe.
 * @param array  $ancestors Manuelle Zwischenstufen (überspringt Auto-Logik).
 * @return array
 */
function dgt_breadcrumb_items( $current = '', $ancestors = array() ) {
	static $short_labels = array(
		// Hauptseiten
		'einfach-aufgeklaert'  => 'Aufklärung',
		'erklaert-aufgeklaert' => 'Aufklärung',
		'informationen'        => 'Informationen',
		'drogentest'           => 'Drogentest',
		// Drogentest-Unterseiten
		'alkoholtester'        => 'Alkoholtester',
		'speicheltest'         => 'Speicheltest',
		'urintest'             => 'Urintest',
		'wischtest'            => 'Wischtest',
		'testosteron-tests'    => 'Testosteron-Test',
		// Informationen-Unterseiten
		'alkohol-wenn-das-trinken-zum-problem-wird' => 'Alkoholsucht',
		'cannabis-marihuanakonsum-nachweisen'        => 'Cannabis nachweisen',
		'nikotin-rauchertest-beweist-tabakkonsum'    => 'Nikotin-Nachweis',
		// Aufklärung-Unterseiten
		'promillegehalt-wie-kann-ich-den-alkohol-im-blut-berechnen'          => 'Promille-Rechner',
		'alkohol-welches-mittel-hilft-gegen-einen-kater'                     => 'Mittel gegen Kater',
		'findet-der-arzt-bei-einem-bluttest-drogenrueckstaende'              => 'Bluttest & Drogen',
		'gibt-es-coffee-shops-in-deutschland'                                => 'Coffee-Shops in Deutschland',
		'ist-es-rechtswidrig-wenn-der-arbeitgeber-einen-drogentest-durchfuehrt' => 'Drogentest Arbeitgeber',
		'leide-ich-bereits-unter-entzugserscheinungen'                       => 'Entzugserscheinungen',
		'nikotinkonsum-zuhause-gestatten'                                    => 'Nikotinkonsum zuhause',
		'polizeikontrolle-muss-ich-einen-urintest-machen'                    => 'Polizeikontrolle & Urintest',
		'substanzen-auf-drogen-testen'                                       => 'Substanzen testen',
		'urintest-ist-es-moeglich-einen-drogentest-zu-manipulieren'          => 'Drogentest manipulieren?',
		'was-koennen-sie-als-eltern-tun-um-den-drogenkonsum-bei-ihrem-kind-zu-verhindern' => 'Drogenkonsum verhindern',
		'was-versteht-man-unter-substanzen'                                  => 'Substanzen erklärt',
		'wie-kann-ich-testen-ob-mein-kind-drogen-zu-sich-nimmt'              => 'Drogentest Kind',
		'besteht-eine-drogensucht'                                           => 'Drogensucht erkennen',
		// Blog-Posts
		'cannabis-urlaub-europa-beste-reiseziele'            => 'Cannabis-Urlaub Europa',
		'drug-checking-rostock'                              => 'Drug-Checking Rostock',
		'mpu-drogen-abstinenznachweis-vorbereitung'          => 'MPU-Ratgeber',
		'nachweiszeiten-drogen-thc-kokain-amphetamin'        => 'Nachweiszeiten',
		'cannabis-am-steuer-2026-thc-grenzwert-fuehrerschein' => 'Cannabis am Steuer',
		'drogentest-gruende-fuer-ein-falsches-test-ergebnis' => 'Falsche Testergebnisse',
		'wie-lange-sind-pilze-magic-mushrooms-nachweisbar'   => 'Magic Mushrooms Nachweis',
		'was-hilft-bei-einem-klassischen-alkohol-kater'      => 'Alkohol-Kater',
		'cannabis-wie-gesund-ist-cannabidiol-cbd'            => 'CBD & Gesundheit',
		'alternative-methoden-gegen-schlafstoerungen'        => 'Schlafstörungen',
		'alkohol-am-steuer-erhoeht-das-unfallrisiko'         => 'Alkohol am Steuer',
		'die-gehirnkapazitaet-mehr-nutzen-lernen'            => 'Gehirnkapazität steigern',
		'esports-events-fuehren-drogentests-ein'             => 'eSports & Drogentests',
		'themenrelevante-informationen-zum-drogentest'       => 'Drogentest-Infos',
		// Drogenpolitik (lange Titel)
		'cannabis-social-clubs-barcelona'        => 'Cannabis Clubs Barcelona',
		'cannabis-social-clubs'                  => 'Cannabis Clubs Deutschland',
		'cannabis-kanarische-inseln'             => 'Kanaren & Cannabis',
		'cannabis-social-clubs-mallorca'         => 'Cannabis Clubs Mallorca',
		'vereinigte-arabische-emirate'           => 'Arabische Emirate',
		'dr-kongo'                               => 'DR Kongo',
		'magic-mushrooms-pilze-in-indonesien'    => 'Magic Mushrooms Indonesien',
		'alkoholkonsum-in-indonesien'            => 'Alkohol in Indonesien',
	);

	$items = array( array( 'label' => 'Start', 'url' => home_url( '/' ) ) );

	if ( ! empty( $ancestors ) ) {
		foreach ( $ancestors as $anc ) {
			$items[] = $anc;
		}
	} elseif ( is_singular( 'drogenpolitik' ) ) {
		$items[] = array( 'label' => 'Aufklärung', 'url' => home_url( '/einfach-aufgeklaert/' ) );
		$items[] = array( 'label' => 'Drogenpolitik', 'url' => home_url( '/einfach-aufgeklaert/drogenpolitik/' ) );
		$dp_parent = wp_get_post_parent_id( get_the_ID() );
		if ( $dp_parent ) {
			$items[] = array( 'label' => get_the_title( $dp_parent ), 'url' => get_permalink( $dp_parent ) );
		}
	} elseif ( is_singular( 'post' ) ) {
		$blog_id = (int) get_option( 'page_for_posts' );
		if ( $blog_id ) {
			$items[] = array( 'label' => 'Blog', 'url' => get_permalink( $blog_id ) );
		}
		$cats = get_the_category();
		if ( $cats && 'blog' !== $cats[0]->slug ) {
			$items[] = array( 'label' => $cats[0]->name, 'url' => get_category_link( $cats[0]->term_id ) );
		}
	} elseif ( is_page() ) {
		$ancestor_ids = array_reverse( get_post_ancestors( get_queried_object_id() ) );
		foreach ( $ancestor_ids as $aid ) {
			$slug  = get_post_field( 'post_name', $aid );
			$label = isset( $short_labels[ $slug ] ) ? $short_labels[ $slug ] : get_the_title( $aid );
			$items[] = array( 'label' => $label, 'url' => get_permalink( $aid ) );
		}
	} elseif ( is_singular( 'product' ) ) {
		$shop_id = function_exists( 'wc_get_page_id' ) ? wc_get_page_id( 'shop' ) : 0;
		if ( $shop_id > 0 ) {
			$slug  = get_post_field( 'post_name', $shop_id );
			$label = isset( $short_labels[ $slug ] ) ? $short_labels[ $slug ] : get_the_title( $shop_id );
			$items[] = array( 'label' => $label, 'url' => get_permalink( $shop_id ) );
		}
	} elseif ( is_post_type_archive( 'product' ) ) {
		// Shop-Archiv: keine Zwischenstufe nötig.
	} elseif ( is_home() && ! is_front_page() ) {
		// Blog-Index: keine Zwischenstufe nötig.
	} elseif ( is_category() || is_tag() || is_tax() ) {
		$blog_id = (int) get_option( 'page_for_posts' );
		if ( $blog_id ) {
			$items[] = array( 'label' => 'Blog', 'url' => get_permalink( $blog_id ) );
		}
	}

	$last_label = $current;
	if ( ! $last_label ) {
		if ( is_singular() || is_page() ) {
			$slug       = get_post_field( 'post_name', get_queried_object_id() );
			$last_label = isset( $short_labels[ $slug ] ) ? $short_labels[ $slug ] : get_the_title();
		} elseif ( is_home() && ! is_front_page() ) {
			$last_label = 'Blog';
		} elseif ( is_post_type_archive( 'product' ) ) {
			$last_label = 'Drogentest';
		} elseif ( is_category() || is_tag() || is_tax() ) {
			$last_label = single_term_title( '', false );
		}
	}

	if ( $last_label ) {
		$items[] = array( 'label' => $last_label, 'url' => '' );
	}

	return $items;
}

/**
 * Breadcrumb-Navigation mit Schema.org BreadcrumbList (Mikrodaten).
 *
 * @param string $current  Optionaler Label-Override für die letzte Stufe.
 * @param array  $ancestors Manuelle Zwischenstufen – [ [ 'label' => …, 'url' => … ], … ].
 */
function dgt_breadcrumb( $current = '', $ancestors = array() ) {
	$items = dgt_breadcrumb_items( $current, $ancestors );
	if ( count( $items ) < 2 ) {
		return;
	}

	echo '<nav class="dgt-breadcrumb" aria-label="Breadcrumb" itemscope itemtype="https://schema.org/BreadcrumbList"><ol>';
	$pos = 0;
	foreach ( $items as $i => $item ) {
		$is_last = ( $i === count( $items ) - 1 );
		$pos++;
		echo '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
		if ( $is_last ) {
			printf( '<span itemprop="name" aria-current="page">%s</span>', esc_html( $item['label'] ) );
			$item_url = $item['url'];
			if ( ! $item_url ) {
				if ( is_singular() || is_page() ) {
					$item_url = get_permalink();
				} elseif ( is_home() ) {
					$blog_id  = (int) get_option( 'page_for_posts' );
					$item_url = $blog_id ? get_permalink( $blog_id ) : home_url( '/' );
				} elseif ( is_post_type_archive() ) {
					$item_url = get_post_type_archive_link( get_post_type() );
				} elseif ( is_category() || is_tag() || is_tax() ) {
					$item_url = get_term_link( get_queried_object() );
				}
			}
			printf( '<meta itemprop="item" content="%s">', esc_url( $item_url ? $item_url : '' ) );
		} else {
			printf( '<a itemprop="item" href="%s"><span itemprop="name">%s</span></a>', esc_url( $item['url'] ), esc_html( $item['label'] ) );
		}
		printf( '<meta itemprop="position" content="%d">', $pos );
		echo '</li>';
	}
	echo '</ol></nav>';
}

/**
 * Legt beim Theme-Wechsel automatisch die Rechtsseiten an (falls nicht vorhanden):
 * Impressum, Datenschutz, Sitemap. Schreibt NICHTS, solange das Theme nicht aktiv ist.
 *
 * Hinweis: Impressum & Datenschutz enthalten Platzhalter [in eckigen Klammern]
 * und müssen mit den echten Daten gefüllt und rechtlich geprüft werden.
 */
function dgt_create_legal_pages() {
	$site = get_bloginfo( 'name' );
	$mail = get_bloginfo( 'admin_email' );

	$impressum = '<!-- wp:paragraph --><p><strong>Angaben gemäß § 5 TMG / § 18 MStV</strong></p><!-- /wp:paragraph -->'
		. '<!-- wp:paragraph --><p>[Vollständiger Name / Firmenname]<br>[Straße und Hausnummer]<br>[PLZ Ort]<br>[Land]</p><!-- /wp:paragraph -->'
		. '<!-- wp:heading {"level":3} --><h3>Vertreten durch</h3><!-- /wp:heading -->'
		. '<!-- wp:paragraph --><p>[Name der vertretungsberechtigten Person]</p><!-- /wp:paragraph -->'
		. '<!-- wp:heading {"level":3} --><h3>Kontakt</h3><!-- /wp:heading -->'
		. '<!-- wp:paragraph --><p>Telefon: [Telefonnummer]<br>E-Mail: ' . esc_html( $mail ) . '</p><!-- /wp:paragraph -->'
		. '<!-- wp:heading {"level":3} --><h3>Umsatzsteuer-ID</h3><!-- /wp:heading -->'
		. '<!-- wp:paragraph --><p>Umsatzsteuer-Identifikationsnummer gemäß § 27 a UStG: [USt-IdNr.]</p><!-- /wp:paragraph -->'
		. '<!-- wp:heading {"level":3} --><h3>Verantwortlich für den Inhalt nach § 18 Abs. 2 MStV</h3><!-- /wp:heading -->'
		. '<!-- wp:paragraph --><p>[Name, Anschrift]</p><!-- /wp:paragraph -->'
		. '<!-- wp:heading {"level":3} --><h3>Streitschlichtung</h3><!-- /wp:heading -->'
		. '<!-- wp:paragraph --><p>Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit: '
		. '<a href="https://ec.europa.eu/consumers/odr/" rel="nofollow noopener" target="_blank">https://ec.europa.eu/consumers/odr/</a>. '
		. 'Wir sind nicht verpflichtet und nicht bereit, an einem Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen.</p><!-- /wp:paragraph -->'
		. '<!-- wp:paragraph --><p><em>Hinweis: Diese Angaben sind eine Vorlage und müssen vom Betreiber vervollständigt und rechtlich geprüft werden.</em></p><!-- /wp:paragraph -->';

	$datenschutz = '<!-- wp:heading {"level":3} --><h3>1. Datenschutz auf einen Blick</h3><!-- /wp:heading -->'
		. '<!-- wp:paragraph --><p>Diese Datenschutzerklärung informiert dich über Art, Umfang und Zweck der Verarbeitung personenbezogener Daten auf dieser Website gemäß DSGVO.</p><!-- /wp:paragraph -->'
		. '<!-- wp:heading {"level":3} --><h3>2. Verantwortlicher</h3><!-- /wp:heading -->'
		. '<!-- wp:paragraph --><p>[Vollständiger Name / Firmenname]<br>[Anschrift]<br>E-Mail: ' . esc_html( $mail ) . '</p><!-- /wp:paragraph -->'
		. '<!-- wp:heading {"level":3} --><h3>3. Hosting</h3><!-- /wp:heading -->'
		. '<!-- wp:paragraph --><p>Die Website wird bei [Hosting-Anbieter] gehostet. Der Anbieter verarbeitet Daten zur Bereitstellung der Website auf Grundlage unseres berechtigten Interesses (Art. 6 Abs. 1 lit. f DSGVO). Ein Auftragsverarbeitungsvertrag (AVV) liegt vor.</p><!-- /wp:paragraph -->'
		. '<!-- wp:heading {"level":3} --><h3>4. Server-Logfiles</h3><!-- /wp:heading -->'
		. '<!-- wp:paragraph --><p>Der Provider erhebt automatisch Informationen in Server-Logfiles (Browsertyp, Betriebssystem, Referrer-URL, Hostname, Uhrzeit, IP-Adresse). Diese Daten sind nicht bestimmten Personen zuordenbar und dienen dem sicheren Betrieb (Art. 6 Abs. 1 lit. f DSGVO).</p><!-- /wp:paragraph -->'
		. '<!-- wp:heading {"level":3} --><h3>5. Cookies &amp; Einwilligung</h3><!-- /wp:heading -->'
		. '<!-- wp:paragraph --><p>Wir verwenden notwendige Cookies für den Betrieb der Seite. Optionale Cookies (Statistik, Marketing) setzen wir nur mit deiner ausdrücklichen Einwilligung (Art. 6 Abs. 1 lit. a DSGVO, § 25 TTDSG). Deine Auswahl kannst du jederzeit über den Link &bdquo;Cookie-Einstellungen&ldquo; im Footer ändern oder widerrufen.</p><!-- /wp:paragraph -->'
		. '<!-- wp:heading {"level":3} --><h3>6. Kontaktaufnahme</h3><!-- /wp:heading -->'
		. '<!-- wp:paragraph --><p>Bei Kontakt per E-Mail oder Formular werden deine Angaben zur Bearbeitung der Anfrage gespeichert (Art. 6 Abs. 1 lit. b bzw. f DSGVO).</p><!-- /wp:paragraph -->'
		. '<!-- wp:heading {"level":3} --><h3>7. Deine Rechte</h3><!-- /wp:heading -->'
		. '<!-- wp:paragraph --><p>Du hast jederzeit das Recht auf Auskunft, Berichtigung, Löschung, Einschränkung der Verarbeitung, Datenübertragbarkeit, Widerspruch sowie das Recht auf Beschwerde bei einer Aufsichtsbehörde.</p><!-- /wp:paragraph -->'
		. '<!-- wp:paragraph --><p><em>Hinweis: Diese Datenschutzerklärung ist eine Vorlage. Sie muss an die tatsächlich eingesetzten Dienste (z. B. Analyse-, Marketing- und Shop-Tools) angepasst und rechtlich geprüft werden.</em></p><!-- /wp:paragraph -->';

	$pages = array(
		'impressum'  => array( 'Impressum', $impressum ),
		'datenschutz' => array( 'Datenschutz', $datenschutz ),
		'sitemap'    => array( 'Sitemap', '<!-- wp:paragraph --><p>Übersicht aller Inhalte dieser Website.</p><!-- /wp:paragraph -->' ),
	);

	foreach ( $pages as $slug => $data ) {
		if ( get_page_by_path( $slug ) ) {
			continue; // existiert bereits
		}
		wp_insert_post(
			array(
				'post_title'   => $data[0],
				'post_name'    => $slug,
				'post_content' => $data[1],
				'post_status'  => 'publish',
				'post_type'    => 'page',
				'post_author'  => 1,
				'comment_status' => 'closed',
			)
		);
	}
}
add_action( 'after_switch_theme', 'dgt_create_legal_pages' );

/* ─── Verkehrsmonitor-Teaser unter Beiträgen mit Tag „Alkohol am Steuer" ─── */

function dgt_vm_teaser_after_content( $content ) {
	if ( ! is_singular( 'post' ) || ! in_the_loop() || ! is_main_query() ) {
		return $content;
	}
	if ( ! has_tag( 'alkohol-am-steuer' ) && ! has_tag( 'drogen-am-steuer' ) ) {
		return $content;
	}

	ob_start();
	?>
	<aside class="dgt-vm-teaser">
		<div class="dgt-vm-teaser-inner">
			<div class="dgt-vm-teaser-icon">
				<svg width="42" height="42" viewBox="0 0 24 24" fill="none" aria-hidden="true">
					<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54A1.99 1.99 0 0016 16h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41C17.93 5.77 20 8.65 20 12c0 2.08-.8 3.97-2.1 5.39z" fill="#f0c430"/>
				</svg>
			</div>
			<div class="dgt-vm-teaser-body">
				<p class="dgt-vm-teaser-over">Verkehrsmonitor Deutschland</p>
				<p class="dgt-vm-teaser-title">Täglich neue Polizeimeldungen zu Alkohol &amp; Drogen am Steuer</p>
				<p class="dgt-vm-teaser-text">KI-analysierte Verkehrsdelikte aus ganz Deutschland &ndash; mit Karte, Statistiken und Einzelberichten.</p>
				<a class="dgt-vm-teaser-btn" href="/verkehrsmonitor/">
					Zum Verkehrsmonitor
					<svg width="16" height="12" viewBox="0 0 18 14" aria-hidden="true"><path d="M1 7h15m0 0-5.5-5.5M16 7l-5.5 5.5" stroke="currentColor" stroke-width="1.8" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>
				</a>
			</div>
		</div>
	</aside>
	<?php
	$teaser = ob_get_clean();

	return $content . $teaser;
}
add_filter( 'the_content', 'dgt_vm_teaser_after_content', 50 );

/**
 * Selbstreferenzierendes Canonical für alle Seiten,
 * die WordPress-Core nicht abdeckt (Archive, Custom Routing).
 */
function dgt_fallback_canonical() {
	if ( is_admin() || is_feed() || is_robots() || is_trackback() ) {
		return;
	}
	if ( is_singular() || is_front_page() ) {
		return;
	}
	if ( get_query_var( 'dgt_dp_continent' ) || get_query_var( 'dgt_dp_category' ) ) {
		return;
	}
	$url = home_url( remove_query_arg( wp_removable_query_args(), wp_unslash( $_SERVER['REQUEST_URI'] ) ) );
	$url = rtrim( $url, '/' ) . '/';
	printf( '<link rel="canonical" href="%s" />' . "\n", esc_url( $url ) );
}
add_action( 'wp_head', 'dgt_fallback_canonical', 1 );

/**
 * WordPress-Core setzt Canonical nur für is_singular(). Damit
 * unser Fallback nicht doppelt feuert: Core-Hook deaktivieren
 * für Nicht-Singular und stattdessen unseren nutzen.
 */
function dgt_disable_core_canonical_for_non_singular() {
	if ( ! is_singular() && ! is_front_page() ) {
		remove_action( 'wp_head', 'rel_canonical' );
	}
}
add_action( 'wp', 'dgt_disable_core_canonical_for_non_singular' );

/**
 * Pagination im Theme-Stil (kapselt the_posts_pagination mit eigenen Pfeilen).
 */
function dgt_pagination() {
	the_posts_pagination(
		array(
			'mid_size'           => 1,
			'prev_text'          => '&larr; Zurück',
			'next_text'          => 'Weiter &rarr;',
			'screen_reader_text' => __( 'Seitennavigation', 'drogentest-online' ),
			'class'              => 'dgt-pagination',
		)
	);
}

Youez - 2016 - github.com/yon3zu
LinuXploit