'; foreach (array_values($sections) as $index => $section) { if (!is_array($section)) continue; $type = sanitize_key($section['type'] ?? 'content'); $html .= self::render_section($type, $section, intval($index)); } return $html . ''; } protected static function render_section($type, $s, $index) { $map = ['hero'=>'hero','cards'=>'cards','article_grid'=>'cards','steps'=>'steps','faq'=>'faq','cta'=>'cta','text_image'=>'soft','content'=>'content']; $role = $map[$type] ?? 'content'; $id = $type === 'faq' ? 'aiwest-faq' : ($type === 'cta' ? 'aiwest-contact' : ($index === 1 ? 'aiwest-main' : '')); $open = '
'; if ($type === 'hero') return $open . self::hero($s) . '
'; if ($type === 'cards' || $type === 'article_grid') return $open . self::cards($s, $role) . ''; if ($type === 'steps') return $open . self::steps($s) . ''; if ($type === 'faq') return $open . self::faq($s) . ''; if ($type === 'cta') return $open . self::cta($s) . ''; if ($type === 'text_image') return $open . self::text_image($s) . ''; return $open . self::content($s) . ''; } protected static function hero($s) { $html = '

' . esc_html(get_bloginfo('name')) . '

' . esc_html($s['title'] ?? '') . '

'; if (!empty($s['subtitle'])) $html .= '

' . esc_html($s['subtitle']) . '

'; $buttons = self::link($s['primary_cta'] ?? '', $s['primary_cta_url'] ?? '', 'aiwest-btn'); $buttons .= self::link($s['secondary_cta'] ?? '', $s['secondary_cta_url'] ?? '', 'aiwest-btn-secondary'); return $html . ($buttons ? '
' . $buttons . '
' : ''); } protected static function cards($s, $role) { $html = '

' . esc_html($s['title'] ?? 'Key areas') . '

'; foreach ((array)($s['items'] ?? []) as $item) { if (!is_array($item)) continue; $html .= '

' . esc_html($item['title'] ?? '') . '

' . esc_html($item['text'] ?? $item['description'] ?? '') . '

'; $html .= self::link($item['link_label'] ?? '', $item['url'] ?? '', 'aiwest-card-link') . '
'; } return $html . '
'; } protected static function steps($s) { $html = '

' . esc_html($s['title'] ?? 'Step by step') . '

'; foreach ((array)($s['items'] ?? []) as $item) { if (!is_array($item)) continue; $html .= '

' . esc_html($item['title'] ?? '') . '

' . esc_html($item['text'] ?? $item['description'] ?? '') . '

'; } return $html . '
'; } protected static function faq($s) { $html = '

' . esc_html($s['title'] ?? 'Frequently Asked Questions') . '

'; foreach ((array)($s['items'] ?? []) as $item) { if (!is_array($item)) continue; $html .= '
' . esc_html($item['question'] ?? $item['title'] ?? '') . '

' . esc_html($item['answer'] ?? $item['text'] ?? '') . '

'; } return $html . '
'; } protected static function cta($s) { $html = '

' . esc_html($s['title'] ?? '') . '

' . esc_html($s['text'] ?? '') . '

'; return $html . self::link($s['button'] ?? '', $s['button_url'] ?? '', 'aiwest-btn'); } protected static function text_image($s) { $html = '

' . esc_html($s['title'] ?? '') . '

' . esc_html($s['text'] ?? '') . '

'; $url = self::safe_url($s['image_url'] ?? ''); if ($url) $html .= '
' . esc_attr($s['image_alt'] ?? $s['title'] ?? '') . '
'; return $html . '
'; } protected static function content($s) { return '

' . esc_html($s['title'] ?? '') . '

' . esc_html($s['text'] ?? '') . '

'; } protected static function link($label, $url, $class) { $label = trim((string)$label); $url = self::safe_url($url); return ($label !== '' && $url !== '') ? '' . esc_html($label) . '' : ''; } protected static function safe_url($url) { $url = trim((string)$url); if ($url === '') return ''; if (in_array($url, ['#aiwest-main','#aiwest-contact','#aiwest-faq'], true)) return $url; if (stripos($url, 'mailto:') === 0) return is_email(substr($url, 7)) ? $url : ''; $absolute = wp_http_validate_url($url) ? $url : home_url('/' . ltrim($url, '/')); $home_host = strtolower((string)wp_parse_url(home_url('/'), PHP_URL_HOST)); $url_host = strtolower((string)wp_parse_url($absolute, PHP_URL_HOST)); if ($home_host === '' || $url_host !== $home_host) return self::$allow_external_links ? esc_url_raw($absolute) : ''; if (function_exists('url_to_postid') && url_to_postid($absolute) < 1 && untrailingslashit($absolute) !== untrailingslashit(home_url('/'))) return ''; return esc_url_raw($absolute); } }