| 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/inc/ |
Upload File : |
<?php
/**
* Suchtberatung-Verzeichnis – Datenzugriff & SEO-Routing.
*
* Nutzt die bereits dedizierten, performanten Tabellen des Connections-Plugins
* (dk_connections + dk_connections_address/_phone/_email/_link). Das Bundesland
* wird read-only zur Laufzeit aus der PLZ abgeleitet (keine Mutation der
* Plugin-Daten). 1175 Datensätze → sehr schnell.
*
* SEO-Linkstruktur:
* /suchtberatung/ → Übersicht (Bundesland-Raster + Suche)
* /suchtberatung/bundesland/{bl}/ → Beratungsstellen je Bundesland
* /suchtberatung/bundesland/{bl}/{stadt}/ → je Stadt
* /suchtberatung/bundesland/{bl}/{slug}/ → Einzelansicht
*
* @package drogentest-online
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/** Tabellen-Namen. */
function dgt_sb_table( $name = '' ) {
global $wpdb;
return $wpdb->prefix . 'connections' . ( $name ? '_' . $name : '' );
}
/** Die 16 Bundesländer (Slug => Name). */
function dgt_sb_bundeslaender() {
return array(
'baden-wuerttemberg' => 'Baden-Württemberg',
'bayern' => 'Bayern',
'berlin' => 'Berlin',
'brandenburg' => 'Brandenburg',
'bremen' => 'Bremen',
'hamburg' => 'Hamburg',
'hessen' => 'Hessen',
'mecklenburg-vorpommern' => 'Mecklenburg-Vorpommern',
'niedersachsen' => 'Niedersachsen',
'nordrhein-westfalen' => 'Nordrhein-Westfalen',
'rheinland-pfalz' => 'Rheinland-Pfalz',
'saarland' => 'Saarland',
'sachsen' => 'Sachsen',
'sachsen-anhalt' => 'Sachsen-Anhalt',
'schleswig-holstein' => 'Schleswig-Holstein',
'thueringen' => 'Thüringen',
);
}
/** PLZ-2-Steller (Leitregion) → Bundesland-Slug. */
function dgt_sb_plz_map() {
static $map = null;
if ( null !== $map ) {
return $map;
}
$groups = array(
'sachsen' => array( '01', '02', '04', '08', '09' ),
'brandenburg' => array( '03', '14', '15', '16' ),
'sachsen-anhalt' => array( '06', '39' ),
'thueringen' => array( '07', '98', '99' ),
'berlin' => array( '10', '11', '12', '13' ),
'mecklenburg-vorpommern' => array( '17', '18', '19' ),
'hamburg' => array( '20', '22' ),
'niedersachsen' => array( '21', '26', '27', '29', '30', '31', '37', '38', '49' ),
'schleswig-holstein' => array( '23', '24', '25' ),
'bremen' => array( '28' ),
'nordrhein-westfalen' => array( '32', '33', '40', '41', '42', '44', '45', '46', '47', '48', '50', '51', '52', '53', '57', '58', '59' ),
'hessen' => array( '34', '35', '36', '60', '61', '63', '64', '65' ),
'rheinland-pfalz' => array( '54', '55', '56', '67' ),
'saarland' => array( '66' ),
'baden-wuerttemberg' => array( '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '88' ),
'bayern' => array( '80', '81', '82', '83', '84', '85', '86', '87', '89', '90', '91', '92', '93', '94', '95', '96', '97' ),
);
$map = array();
foreach ( $groups as $slug => $prefixes ) {
foreach ( $prefixes as $p ) {
$map[ $p ] = $slug;
}
}
return $map;
}
/** PLZ → Bundesland-Slug (oder '' wenn unbekannt). */
function dgt_sb_bundesland_from_plz( $plz ) {
$map = dgt_sb_plz_map();
$pre = substr( preg_replace( '/\D/', '', (string) $plz ), 0, 2 );
return isset( $map[ $pre ] ) ? $map[ $pre ] : '';
}
/** Slug → Bundesland-Name. */
function dgt_sb_bundesland_name( $slug ) {
$all = dgt_sb_bundeslaender();
return isset( $all[ $slug ] ) ? $all[ $slug ] : '';
}
/** Liste der PLZ-Präfixe eines Bundeslandes (für WHERE … IN). */
function dgt_sb_prefixes_for( $bundesland_slug ) {
$out = array();
foreach ( dgt_sb_plz_map() as $pre => $slug ) {
if ( $slug === $bundesland_slug ) {
$out[] = $pre;
}
}
return $out;
}
/** Anzahl Beratungsstellen je Bundesland (eine Query, gecacht). */
function dgt_sb_counts() {
global $wpdb;
$cached = wp_cache_get( 'dgt_sb_counts' );
if ( false !== $cached ) {
return $cached;
}
$c = dgt_sb_table();
$addr = dgt_sb_table( 'address' );
$rows = $wpdb->get_results( "SELECT LEFT(TRIM(a.zipcode),2) AS pre, COUNT(*) AS c FROM {$addr} a JOIN {$c} c ON c.id=a.entry_id WHERE a.zipcode <> '' AND c.status='approved' AND c.visibility='public' GROUP BY pre", ARRAY_A ); // phpcs:ignore
$map = dgt_sb_plz_map();
$out = array_fill_keys( array_keys( dgt_sb_bundeslaender() ), 0 );
foreach ( (array) $rows as $r ) {
if ( isset( $map[ $r['pre'] ] ) ) {
$out[ $map[ $r['pre'] ] ] += (int) $r['c'];
}
}
wp_cache_set( 'dgt_sb_counts', $out, '', HOUR_IN_SECONDS );
return $out;
}
/**
* Beratungsstellen abfragen.
*
* @param array $args bundesland (slug), stadt (name), search, paged, per_page.
* @return array{items:array,total:int,pages:int,paged:int,per_page:int}
*/
function dgt_sb_query( $args = array() ) {
global $wpdb;
$args = wp_parse_args(
$args,
array(
'bundesland' => '',
'stadt' => '',
'search' => '',
'paged' => 1,
'per_page' => 24,
)
);
$c = dgt_sb_table();
$a = dgt_sb_table( 'address' );
$where = array( "c.status='approved'", "c.visibility='public'", "a.zipcode <> ''" );
$wargs = array();
if ( $args['bundesland'] ) {
$prefixes = dgt_sb_prefixes_for( $args['bundesland'] );
if ( $prefixes ) {
$where[] = 'LEFT(TRIM(a.zipcode),2) IN (' . implode( ',', array_fill( 0, count( $prefixes ), '%s' ) ) . ')';
$wargs = array_merge( $wargs, $prefixes );
}
}
if ( $args['stadt'] ) {
$where[] = 'a.city = %s';
$wargs[] = $args['stadt'];
}
if ( $args['search'] ) {
$like = '%' . $wpdb->esc_like( $args['search'] ) . '%';
$where[] = '(c.organization LIKE %s OR c.last_name LIKE %s OR a.city LIKE %s OR a.zipcode LIKE %s)';
array_push( $wargs, $like, $like, $like, $like );
}
$where_sql = implode( ' AND ', $where );
$per_page = max( 1, (int) $args['per_page'] );
$paged = max( 1, (int) $args['paged'] );
$offset = ( $paged - 1 ) * $per_page;
// Gesamtzahl.
$count_sql = "SELECT COUNT(DISTINCT c.id) FROM {$c} c JOIN {$a} a ON a.entry_id=c.id WHERE {$where_sql}";
$total = (int) $wpdb->get_var( $wargs ? $wpdb->prepare( $count_sql, $wargs ) : $count_sql ); // phpcs:ignore
// Datensätze.
$sql = "SELECT c.id, c.slug, c.organization, c.first_name, c.last_name,
a.line_1 AS street, a.city, a.zipcode
FROM {$c} c JOIN {$a} a ON a.entry_id=c.id
WHERE {$where_sql}
GROUP BY c.id
ORDER BY a.city ASC, c.organization ASC
LIMIT %d OFFSET %d";
$qargs = array_merge( $wargs, array( $per_page, $offset ) );
$items = $wpdb->get_results( $wpdb->prepare( $sql, $qargs ), ARRAY_A ); // phpcs:ignore
foreach ( $items as &$it ) {
$it['name'] = $it['organization'] ? $it['organization'] : trim( $it['first_name'] . ' ' . $it['last_name'] );
$it['bundesland'] = dgt_sb_bundesland_from_plz( $it['zipcode'] );
}
unset( $it );
return array(
'items' => $items,
'total' => $total,
'pages' => (int) ceil( $total / $per_page ),
'paged' => $paged,
'per_page' => $per_page,
);
}
/** Städte (mit Anzahl) innerhalb eines Bundeslandes. */
function dgt_sb_cities( $bundesland_slug ) {
global $wpdb;
$prefixes = dgt_sb_prefixes_for( $bundesland_slug );
if ( ! $prefixes ) {
return array();
}
$c = dgt_sb_table();
$a = dgt_sb_table( 'address' );
$in = implode( ',', array_fill( 0, count( $prefixes ), '%s' ) );
$sql = "SELECT a.city, COUNT(*) c FROM {$a} a JOIN {$c} c ON c.id=a.entry_id WHERE a.city <> '' AND c.status='approved' AND c.visibility='public' AND LEFT(TRIM(a.zipcode),2) IN ($in) GROUP BY a.city ORDER BY a.city ASC";
return $wpdb->get_results( $wpdb->prepare( $sql, $prefixes ), ARRAY_A ); // phpcs:ignore
}
/** Einzelne Beratungsstelle per Slug (inkl. Kontakt). */
function dgt_sb_get_by_slug( $slug ) {
global $wpdb;
$c = dgt_sb_table();
if ( current_user_can( 'manage_options' ) ) {
$row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$c} WHERE slug=%s LIMIT 1", $slug ), ARRAY_A ); // phpcs:ignore
} else {
$row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$c} WHERE slug=%s AND status='approved' AND visibility='public' LIMIT 1", $slug ), ARRAY_A ); // phpcs:ignore
}
if ( ! $row ) {
return null;
}
$id = (int) $row['id'];
$addr = dgt_sb_table( 'address' );
$phone = dgt_sb_table( 'phone' );
$mail = dgt_sb_table( 'email' );
$link = dgt_sb_table( 'link' );
$row['address'] = $wpdb->get_row( $wpdb->prepare( "SELECT line_1,line_2,city,zipcode,state,latitude,longitude FROM {$addr} WHERE entry_id=%d ORDER BY `preferred` DESC, `order` ASC LIMIT 1", $id ), ARRAY_A ); // phpcs:ignore
$row['phones'] = $wpdb->get_col( $wpdb->prepare( "SELECT number FROM {$phone} WHERE entry_id=%d AND number<>'' ORDER BY `preferred` DESC, `order` ASC", $id ) ); // phpcs:ignore
$row['emails'] = $wpdb->get_col( $wpdb->prepare( "SELECT address FROM {$mail} WHERE entry_id=%d AND address<>'' ORDER BY `preferred` DESC, `order` ASC", $id ) ); // phpcs:ignore
$row['links'] = $wpdb->get_col( $wpdb->prepare( "SELECT url FROM {$link} WHERE entry_id=%d AND url<>'' ORDER BY `preferred` DESC, `order` ASC", $id ) ); // phpcs:ignore
$row['name'] = $row['organization'] ? $row['organization'] : trim( $row['first_name'] . ' ' . $row['last_name'] );
$row['bundesland'] = isset( $row['address']['zipcode'] ) ? dgt_sb_bundesland_from_plz( $row['address']['zipcode'] ) : '';
return $row;
}
/* -------------------------------------------------------------------------
Render-Helfer (von Übersicht & Archiv genutzt)
------------------------------------------------------------------------- */
/** Ergebnis-Liste als Karten ausgeben. */
function dgt_sb_render_list( $items ) {
if ( empty( $items ) ) {
echo '<div class="dgt-empty"><h3 class="dgt-empty-title">Keine Beratungsstellen gefunden</h3><p class="dgt-empty-text">Versuche es mit einem anderen Ort, einer Postleitzahl oder einem anderen Bundesland.</p></div>';
return;
}
echo '<ul class="dgt-sb-list">';
foreach ( $items as $it ) {
$url = dgt_sb_single_url( $it['slug'], $it['bundesland'] );
$bl = dgt_sb_bundesland_name( $it['bundesland'] );
$haystack = mb_strtolower( $it['name'] . ' ' . $it['city'] . ' ' . $it['zipcode'] );
$title = dgt_sb_title_stelle( $it['name'], $it['city'] );
printf(
'<li class="dgt-sb-item" data-search="%s"><a class="dgt-sb-item-link" href="%s" title="%s">',
esc_attr( $haystack ),
esc_url( $url ),
esc_attr( $title )
);
printf(
'<span class="dgt-sb-item-icon" aria-hidden="true"><svg width="22" height="22" viewBox="0 0 24 24" fill="none"><path d="M12 21s-7-5.6-7-11a7 7 0 0 1 14 0c0 5.4-7 11-7 11Z" stroke="#108e6c" stroke-width="1.6"/><circle cx="12" cy="10" r="2.6" stroke="#108e6c" stroke-width="1.6"/></svg></span>'
. '<span class="dgt-sb-item-body"><span class="dgt-sb-item-name">%s</span>'
. '<span class="dgt-sb-item-meta">%s%s%s</span></span>'
. '<span class="dgt-sb-item-arrow" aria-hidden="true">›</span></a></li>',
esc_html( $it['name'] ),
$it['street'] ? esc_html( $it['street'] ) . ', ' : '',
esc_html( trim( $it['zipcode'] . ' ' . $it['city'] ) ),
$bl ? ' · ' . esc_html( $bl ) : ''
);
}
echo '</ul>';
}
/** Pagination für die Verzeichnis-Listen. */
function dgt_sb_render_pagination( $res, $base, $query_args = array() ) {
if ( $res['pages'] < 2 ) {
return;
}
echo '<nav class="dgt-pagination" aria-label="Seitennavigation"><div class="nav-links">';
for ( $i = 1; $i <= $res['pages']; $i++ ) {
$args = array_merge( $query_args, ( $i > 1 ? array( 'seite' => $i ) : array() ) );
$url = $args ? add_query_arg( array_filter( $args ), $base ) : $base;
if ( $i === $res['paged'] ) {
printf( '<span class="page-numbers current">%d</span>', $i );
} else {
printf( '<a class="page-numbers" href="%s">%d</a>', esc_url( $url ), $i );
}
}
echo '</div></nav>';
}
/* -------------------------------------------------------------------------
URL-Helfer
------------------------------------------------------------------------- */
function dgt_sb_base_url() {
return home_url( '/suchtberatung/' );
}
function dgt_sb_bundesland_url( $slug ) {
return home_url( '/suchtberatung/bundesland/' . $slug . '/' );
}
function dgt_sb_stadt_url( $bl_slug, $stadt ) {
return home_url( '/suchtberatung/bundesland/' . $bl_slug . '/' . sanitize_title( $stadt ) . '/' );
}
function dgt_sb_single_url( $slug, $bl_slug = '' ) {
if ( $bl_slug ) {
return home_url( '/suchtberatung/bundesland/' . $bl_slug . '/' . $slug . '/' );
}
return home_url( '/suchtberatung/stelle/' . $slug . '/' );
}
/* -------------------------------------------------------------------------
Rewrite-Regeln + Routing (SEO-freundliche URLs)
------------------------------------------------------------------------- */
/**
* Menüpunkt „Suchtberatung" auch auf den virtuellen Unterseiten
* (Bundesland-, Stadt-, Einzelansicht) als aktiv markieren.
*/
function dgt_sb_menu_active_class( $classes, $item ) {
if ( get_query_var( 'dgt_sb' ) && ! empty( $item->url ) ) {
if ( untrailingslashit( $item->url ) === untrailingslashit( dgt_sb_base_url() ) ) {
if ( ! in_array( 'current-menu-item', $classes, true ) ) {
$classes[] = 'current-menu-item';
}
}
}
return $classes;
}
add_filter( 'nav_menu_css_class', 'dgt_sb_menu_active_class', 10, 2 );
/**
* Menüpunkte „Blog" und „Produkte" auf ihren Unterseiten als aktiv markieren:
* - Blog: Einzelbeiträge, Kategorien, Schlagwörter, Beitrags-/Datums-Archive
* - Produkte: Einzelprodukt-Seiten und das Produkt-Archiv
*/
function dgt_nav_active_blog_products( $classes, $item ) {
if ( empty( $item->url ) ) {
return $classes;
}
$url = untrailingslashit( $item->url );
$blog_url = untrailingslashit( get_option( 'page_for_posts' ) ? get_permalink( (int) get_option( 'page_for_posts' ) ) : home_url( '/blog/' ) );
$prod_url = untrailingslashit( home_url( '/produkte/' ) );
$is_product_ctx = ( is_singular( 'dgt_product' ) || is_post_type_archive( 'dgt_product' ) );
$is_blog_ctx = ( ! is_front_page() && ! $is_product_ctx && ( is_singular( 'post' ) || is_home() || is_category() || is_tag() || is_archive() ) );
$mark = ( $is_blog_ctx && $url === $blog_url ) || ( $is_product_ctx && $url === $prod_url );
if ( $mark && ! in_array( 'current-menu-item', $classes, true ) ) {
$classes[] = 'current-menu-item';
}
return $classes;
}
add_filter( 'nav_menu_css_class', 'dgt_nav_active_blog_products', 10, 2 );
/**
* Eigenen Sitemap-Provider für die Suchtberatungs-URLs registrieren.
*/
function dgt_sb_register_sitemap() {
if ( ! function_exists( 'wp_register_sitemap_provider' ) || ! class_exists( 'WP_Sitemaps_Provider' ) ) {
return;
}
require_once get_template_directory() . '/inc/class-sb-sitemap.php';
if ( class_exists( 'DGT_SB_Sitemap_Provider' ) ) {
wp_register_sitemap_provider( 'suchtberatung', new DGT_SB_Sitemap_Provider() );
}
}
add_action( 'init', 'dgt_sb_register_sitemap' );
function dgt_sb_rewrite_rules() {
// Legacy: /suchtberatung/bundesland/{bl}/stelle/{slug}/ → 301 via dgt_sb_legacy_redirects().
add_rewrite_rule( '^suchtberatung/bundesland/([^/]+)/stelle/([^/]+)/?$', 'index.php?dgt_sb=legacy_stelle&dgt_sb_bl=$matches[1]&dgt_sb_slug=$matches[2]', 'top' );
// Legacy: /suchtberatung/name/{slug}/ → 301.
add_rewrite_rule( '^suchtberatung/name/([^/]+)/?$', 'index.php?dgt_sb=legacy_name&dgt_sb_slug=$matches[1]', 'top' );
// Legacy: /suchtberatung/stelle/{slug}/ (ohne Bundesland) → 301.
add_rewrite_rule( '^suchtberatung/stelle/([^/]+)/?$', 'index.php?dgt_sb=legacy_stelle&dgt_sb_slug=$matches[1]', 'top' );
// Legacy: /suchtberatung/ort/{ort}/ → 301 auf Bundesland/Stadt-URL.
add_rewrite_rule( '^suchtberatung/ort/([^/]+)/?$', 'index.php?dgt_sb=legacy_ort&dgt_sb_slug=$matches[1]', 'top' );
// Kombiniert: Einzelansicht oder Stadt (disambiguiert im Template-Router).
add_rewrite_rule( '^suchtberatung/bundesland/([^/]+)/([^/]+)/?$', 'index.php?dgt_sb=detail&dgt_sb_bl=$matches[1]&dgt_sb_detail=$matches[2]', 'top' );
// Bundesland-Übersicht.
add_rewrite_rule( '^suchtberatung/bundesland/([^/]+)/?$', 'index.php?dgt_sb=bundesland&dgt_sb_bl=$matches[1]', 'top' );
}
add_action( 'init', 'dgt_sb_rewrite_rules' );
function dgt_sb_query_vars( $vars ) {
$vars[] = 'dgt_sb';
$vars[] = 'dgt_sb_slug';
$vars[] = 'dgt_sb_bl';
$vars[] = 'dgt_sb_stadt';
$vars[] = 'dgt_sb_detail';
return $vars;
}
add_filter( 'query_vars', 'dgt_sb_query_vars' );
function dgt_sb_legacy_redirects() {
$view = get_query_var( 'dgt_sb' );
if ( 'legacy_stelle' === $view || 'legacy_name' === $view ) {
$slug = sanitize_title( get_query_var( 'dgt_sb_slug' ) );
$stelle = dgt_sb_get_by_slug( $slug );
if ( $stelle && $stelle['bundesland'] ) {
wp_safe_redirect( dgt_sb_single_url( $stelle['slug'], $stelle['bundesland'] ), 301 );
exit;
}
}
if ( 'legacy_ort' === $view ) {
$raw = get_query_var( 'dgt_sb_slug' );
$slug = sanitize_title( $raw );
$map = array(
'essenoldb' => array( 'nordrhein-westfalen', 'essen' ),
);
if ( isset( $map[ $slug ] ) ) {
wp_safe_redirect( dgt_sb_stadt_url( $map[ $slug ][0], $map[ $slug ][1] ), 301 );
exit;
}
wp_safe_redirect( dgt_sb_base_url(), 301 );
exit;
}
}
add_action( 'template_redirect', 'dgt_sb_legacy_redirects' );
/** Für die virtuellen Verzeichnis-Seiten kein 404, korrektes Template laden. */
function dgt_sb_template( $template ) {
$view = get_query_var( 'dgt_sb' );
if ( ! $view ) {
return $template;
}
global $wp_query;
$wp_query->is_404 = false;
$wp_query->is_home = false;
status_header( 200 );
if ( 'detail' === $view ) {
$detail = sanitize_title( get_query_var( 'dgt_sb_detail' ) );
$stelle = dgt_sb_get_by_slug( $detail );
if ( $stelle ) {
set_query_var( 'dgt_sb', 'single' );
set_query_var( 'dgt_sb_slug', $detail );
$file = 'suchtberatung-single.php';
} else {
set_query_var( 'dgt_sb_stadt', $detail );
$file = 'suchtberatung-archive.php';
}
} elseif ( 'single' === $view ) {
$file = 'suchtberatung-single.php';
} else {
$file = 'suchtberatung-archive.php';
}
$located = locate_template( $file );
return $located ? $located : $template;
}
add_filter( 'template_include', 'dgt_sb_template' );
/* -------------------------------------------------------------------------
SEO-Title-Helpers (konsistente <title>- und title=""-Strings im SB-Bereich)
------------------------------------------------------------------------- */
/** "Suchtberatungen in {Bundesland}". */
function dgt_sb_title_bundesland( $bl_slug_or_name ) {
$name = dgt_sb_bundesland_name( $bl_slug_or_name );
if ( ! $name ) { $name = $bl_slug_or_name; }
return sprintf( 'Suchtberatungen in %s', $name );
}
/** "Suchtberatungen in {Stadt} ({Bundesland})". */
function dgt_sb_title_stadt( $stadt_name, $bl_slug_or_name ) {
$bl = dgt_sb_bundesland_name( $bl_slug_or_name );
if ( ! $bl ) { $bl = $bl_slug_or_name; }
return sprintf( 'Suchtberatungen in %s (%s)', $stadt_name, $bl );
}
/**
* "{Name} in {Ort}" – Ortsname nur anhängen, wenn er nicht bereits im
* Einrichtungsnamen enthalten ist.
*
* @param string|array $name_or_stelle Beratungs-Name oder Stelle-Array.
* @param string $stadt Stadtname (optional, wenn Array übergeben wird).
* @return string
*/
function dgt_sb_title_stelle( $name_or_stelle, $stadt = '' ) {
if ( is_array( $name_or_stelle ) ) {
$name = isset( $name_or_stelle['name'] ) ? $name_or_stelle['name'] : '';
if ( '' === $stadt && isset( $name_or_stelle['city'] ) ) {
$stadt = $name_or_stelle['city'];
}
} else {
$name = (string) $name_or_stelle;
}
if ( '' === $name ) { return ''; }
if ( '' === $stadt ) { return $name; }
return ( false !== mb_stripos( $name, $stadt ) ) ? $name : $name . ' in ' . $stadt;
}
/**
* Hero-Bild für die Suchtberatung-Pageheads (Hauptseite + Bundesland/Stadt + Einrichtung).
*
* @return string HTML <img>-Tag mit Srcset.
*/
function dgt_sb_hero_image() {
$base = home_url( '/wp-content/uploads/2026/06/' );
return sprintf(
'<img class="dgt-pagehead-image" '
. 'src="%s" '
. 'srcset="%s 600w, %s 720w, %s 1024w" '
. 'sizes="(max-width: 768px) 0, 420px" '
. 'alt="%s" '
. 'width="600" height="400" loading="eager" decoding="async">',
esc_url( $base . 'suchtberatung-600x400.webp' ),
esc_url( $base . 'suchtberatung-600x400.webp' ),
esc_url( $base . 'suchtberatung-720x460.webp' ),
esc_url( $base . 'suchtberatung-1024x683.webp' ),
esc_attr__( 'Suchtberatung: vertrauliche Unterstützung und Hilfsangebote bei Sucht und Prävention', 'drogentest-online' )
);
}
/**
* Lokalisierter Substanz-/Multitest-Block für die Suchtberatungs-Seiten.
* Rendert einen kurzen SEO-Text mit Verlinkungen zu allen relevanten Substanz-Archiven
* und darunter vier Multi-Drogentests aus dem Affiliate-Sortiment.
*
* @param string $location Stadt- oder Bundesland-Name (z. B. "Berlin", "München").
* @param string $bl_name Bundesland (bei Stadt-Kontext zusätzlich).
* @return string HTML.
*/
function dgt_sb_substance_promotions( $location = '', $bl_name = '' ) {
if ( ! function_exists( 'dgt_aff_products' ) ) {
return '';
}
$where = 'in Deutschland';
$h2_suffix = '';
if ( $location ) {
$where = sprintf( 'in %s', esc_html( $location ) );
$h2_suffix = ' ' . $where;
if ( $bl_name && trim( $bl_name ) !== trim( $location ) ) {
$where .= sprintf( ' (%s)', esc_html( $bl_name ) );
}
} elseif ( $bl_name ) {
$where = sprintf( 'in %s', esc_html( $bl_name ) );
$h2_suffix = ' ' . $where;
}
$href_thc = esc_url( home_url( '/substanz/thc-cannabis/' ) );
$href_coc = esc_url( home_url( '/substanz/kokain/' ) );
$href_amp = esc_url( home_url( '/substanz/amphetamin/' ) );
$href_mdma = esc_url( home_url( '/substanz/mdma-ecstasy/' ) );
$href_opi = esc_url( home_url( '/substanz/opiate-morphin/' ) );
$href_bzo = esc_url( home_url( '/substanz/benzodiazepine/' ) );
ob_start();
?>
<div class="dgt-section dgt-sb-substance">
<div class="dgt-sb-substance-intro">
<h2 class="dgt-section-title">Multi-Drogentests zur Selbstkontrolle<?php echo $h2_suffix; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></h2>
<p>Bevor Sie sich an eine Suchtberatung <?php echo $where; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> wenden, kann ein <strong>Multi-Drogentest</strong> Klarheit schaffen: Ein einziger Schnelltest prüft die häufigsten Substanzen aus einer Urinprobe – darunter <a href="<?php echo $href_thc; ?>" title="Cannabis (THC) nachweisen">Cannabis (THC)</a>, <a href="<?php echo $href_coc; ?>" title="Kokain nachweisen">Kokain</a>, <a href="<?php echo $href_amp; ?>" title="Amphetamin (Speed) nachweisen">Amphetamin</a>, <a href="<?php echo $href_mdma; ?>" title="MDMA / Ecstasy nachweisen">MDMA</a>, <a href="<?php echo $href_opi; ?>" title="Opiate und Morphin nachweisen">Opiate</a> und <a href="<?php echo $href_bzo; ?>" title="Benzodiazepine nachweisen">Benzodiazepine</a>. Diese geprüften Multi-Tests eignen sich für die diskrete Anwendung zuhause:</p>
</div>
<?php
echo dgt_aff_products( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
array(
'ids' => '983,1012,1014,993',
'limit' => 4,
'columns' => 4,
'layout' => 'card',
)
);
?>
</div>
<?php
return ob_get_clean();
}
/* -------------------------------------------------------------------------
SEO-Meta-Tags für alle Suchtberatungs-Unterseiten
(single / bundesland / stadt – die Hauptseite nutzt das Standard-SEO-Modul)
------------------------------------------------------------------------- */
function dgt_sb_seo_head() {
$view = get_query_var( 'dgt_sb' );
if ( ! $view || in_array( $view, array( 'legacy_name', 'legacy_stelle', 'legacy_ort' ), true ) ) {
return;
}
$title = '';
$desc = '';
$kw = '';
$url = '';
$image = home_url( '/wp-content/uploads/2026/06/suchtberatung-1024x683.webp' );
if ( 'single' === $view ) {
$slug = sanitize_title( get_query_var( 'dgt_sb_slug' ) );
$stelle = dgt_sb_get_by_slug( $slug );
if ( ! $stelle ) {
return;
}
$name = $stelle['name'];
$city = isset( $stelle['address']['city'] ) ? $stelle['address']['city'] : '';
$bl_slug = $stelle['bundesland'];
$bl_name = dgt_sb_bundesland_name( $bl_slug );
$url = dgt_sb_single_url( $slug, $bl_slug );
$title = dgt_sb_title_stelle( $name, $city );
$location = $city ? $city : ( $bl_name ? $bl_name : 'Deutschland' );
$region = ( $city && $bl_name ) ? ' (' . $bl_name . ')' : '';
$has_phone = ! empty( $stelle['phones'] );
$has_web = ! empty( $stelle['links'] );
$contact = $has_phone && $has_web ? ' Telefon, Adresse & Website' : ( $has_phone ? ' Telefon & Adresse' : ' Adresse & Kontakt' );
$desc = $name . ' – kostenlose Suchtberatung in ' . $location . $region . '.' . $contact . ' auf einen Blick. Vertrauliche Hilfe bei Sucht.';
if ( mb_strlen( $desc ) > 160 ) {
$desc = $name . ' – Suchtberatung in ' . $location . $region . '. Kostenlose, vertrauliche Hilfe bei Abhängigkeit –' . $contact . '.';
}
if ( mb_strlen( $desc ) > 160 ) {
$desc = $name . ' – Suchtberatung in ' . $location . '. Vertrauliche Hilfe bei Abhängigkeit –' . $contact . '.';
}
if ( mb_strlen( $desc ) > 160 ) {
$desc = 'Suchtberatung ' . $name . ' in ' . $location . '. Kostenlose, vertrauliche Hilfe bei Sucht –' . $contact . '.';
}
if ( mb_strlen( $desc ) > 160 ) {
$max = max( 30, 80 - mb_strlen( $location ) );
$short = mb_substr( $name, 0, $max );
$last = mb_strrpos( $short, ' ' );
if ( $last > 20 ) {
$short = mb_substr( $short, 0, $last );
}
$short = rtrim( $short, ' -–,;:/' );
$desc = $short . ' – Suchtberatung in ' . $location . '. Vertrauliche Hilfe bei Abhängigkeit. Adresse & Kontakt.';
}
$kw_parts = array( $name );
if ( $city ) {
$kw_parts[] = 'Suchtberatung ' . $city;
$kw_parts[] = 'Drogenberatung ' . $city;
}
if ( $bl_name ) {
$kw_parts[] = 'Suchthilfe ' . $bl_name;
}
$kw_parts[] = 'Suchtberatung';
$kw_parts[] = 'Drogenberatung';
$kw = implode( ', ', $kw_parts );
} elseif ( 'bundesland' === $view || 'detail' === $view ) {
$bl_slug = sanitize_title( get_query_var( 'dgt_sb_bl' ) );
$bl_name = dgt_sb_bundesland_name( $bl_slug );
$stadt_raw = sanitize_title( get_query_var( 'dgt_sb_stadt' ) );
if ( ! $bl_name ) {
return;
}
$stadt_name = '';
if ( $stadt_raw ) {
foreach ( dgt_sb_cities( $bl_slug ) as $city ) {
if ( sanitize_title( $city['city'] ) === $stadt_raw ) {
$stadt_name = $city['city'];
break;
}
}
}
if ( 'detail' === $view && ! $stadt_name ) {
return;
}
if ( $stadt_name ) {
$url = dgt_sb_stadt_url( $bl_slug, $stadt_name );
$title = dgt_sb_title_stadt( $stadt_name, $bl_name );
$res = dgt_sb_query( array( 'bundesland' => $bl_slug, 'stadt' => $stadt_name, 'per_page' => 1 ) );
$count = $res['total'];
$desc = $count . ' Suchtberatungsstellen in ' . $stadt_name . ' (' . $bl_name . ') – kostenlose, vertrauliche Hilfe bei Alkohol- und Drogenabhängigkeit. Adressen, Telefon & Kontakt.';
if ( mb_strlen( $desc ) > 160 ) {
$desc = $count . ' Suchtberatungsstellen in ' . $stadt_name . ' – vertrauliche Hilfe bei Sucht. Adressen, Telefon & Kontakt im Überblick.';
}
$kw = 'Suchtberatung ' . $stadt_name . ', Drogenberatung ' . $stadt_name . ', Suchthilfe ' . $stadt_name . ', Beratungsstelle ' . $stadt_name . ', ' . $bl_name;
} else {
$url = dgt_sb_bundesland_url( $bl_slug );
$title = dgt_sb_title_bundesland( $bl_name );
$counts = dgt_sb_counts();
$count = isset( $counts[ $bl_slug ] ) ? $counts[ $bl_slug ] : 0;
$desc = $count . ' Suchtberatungsstellen in ' . $bl_name . ' – kostenlose, vertrauliche Hilfe bei Alkohol-, Drogen- und Medikamentenabhängigkeit. Alle Einrichtungen mit Kontaktdaten.';
if ( mb_strlen( $desc ) > 160 ) {
$desc = $count . ' Suchtberatungsstellen in ' . $bl_name . ' – vertrauliche Hilfe bei Sucht. Adressen und Kontaktdaten aller Einrichtungen.';
}
$kw = 'Suchtberatung ' . $bl_name . ', Drogenberatung ' . $bl_name . ', Suchthilfe ' . $bl_name . ', Beratungsstelle ' . $bl_name;
}
}
if ( ! $desc ) {
return;
}
$desc = trim( wp_strip_all_tags( $desc ) );
$title = $title ? $title : wp_get_document_title();
echo "\n<!-- SEO: suchtberatung -->\n";
printf( '<meta name="description" content="%s">' . "\n", esc_attr( $desc ) );
if ( $kw ) {
printf( '<meta name="keywords" content="%s">' . "\n", esc_attr( $kw ) );
}
printf( '<meta property="og:locale" content="de_DE">' . "\n" );
printf( '<meta property="og:type" content="website">' . "\n" );
printf( '<meta property="og:site_name" content="%s">' . "\n", esc_attr( get_bloginfo( 'name' ) ) );
printf( '<meta property="og:title" content="%s">' . "\n", esc_attr( $title ) );
printf( '<meta property="og:description" content="%s">' . "\n", esc_attr( $desc ) );
if ( $url ) {
printf( '<meta property="og:url" content="%s">' . "\n", esc_url( $url ) );
}
printf( '<meta property="og:image" content="%s">' . "\n", esc_url( $image ) );
printf( '<meta property="og:image:width" content="1024">' . "\n" );
printf( '<meta property="og:image:height" content="683">' . "\n" );
printf( '<meta property="og:image:type" content="image/webp">' . "\n" );
printf( '<meta property="og:image:alt" content="%s">' . "\n", esc_attr( $title ) );
printf( '<meta name="twitter:card" content="summary_large_image">' . "\n" );
printf( '<meta name="twitter:title" content="%s">' . "\n", esc_attr( $title ) );
printf( '<meta name="twitter:description" content="%s">' . "\n", esc_attr( $desc ) );
printf( '<meta name="twitter:image" content="%s">' . "\n", esc_url( $image ) );
printf( '<meta name="twitter:image:alt" content="%s">' . "\n", esc_attr( $title ) );
if ( $url ) {
printf( '<link rel="alternate" hreflang="de" href="%s">' . "\n", esc_url( $url ) );
printf( '<link rel="alternate" hreflang="x-default" href="%s">' . "\n", esc_url( $url ) );
}
}
add_action( 'wp_head', 'dgt_sb_seo_head', 1 );