getData(); if (!$this->isEnabled($data)) { return ''; } if (!$this->shouldShowOnCurrentPage($data)) { return ''; } $classes = $this->buildSectionClasses($data); $styles = $this->buildInlineStyles($data); $html = sprintf( '
', esc_attr($classes), $styles ? ' style="' . esc_attr($styles) . '"' : '' ); $html .= '
'; // Categories badges if ($this->shouldShowCategories($data)) { $html .= $this->buildCategoriesBadges($data); } // Title $html .= $this->buildTitle($data); $html .= '
'; $html .= '
'; // Custom styles $html .= $this->buildCustomStyles($data); return $html; } private function isEnabled(array $data): bool { return isset($data['visibility']['is_enabled']) && $data['visibility']['is_enabled'] === true; } private function shouldShowOnCurrentPage(array $data): bool { $showOn = $data['visibility']['show_on_pages'] ?? 'posts'; switch ($showOn) { case 'all': return true; case 'home': return is_front_page(); case 'posts': return is_single() && get_post_type() === 'post'; case 'pages': return is_page(); case 'custom': $postTypes = $data['visibility']['custom_post_types'] ?? ''; $allowedTypes = array_map('trim', explode(',', $postTypes)); return in_array(get_post_type(), $allowedTypes, true); default: return true; } } private function shouldShowCategories(array $data): bool { return isset($data['categories']['show_categories']) && $data['categories']['show_categories'] === true; } private function buildSectionClasses(array $data): string { $classes = ['container-fluid', 'hero-title']; $paddingClass = $this->getPaddingClass($data['styles']['padding_vertical'] ?? 'normal'); $classes[] = $paddingClass; $marginClass = $this->getMarginClass($data['styles']['margin_bottom'] ?? 'normal'); if ($marginClass) { $classes[] = $marginClass; } return implode(' ', $classes); } private function getPaddingClass(string $padding): string { $paddings = [ 'compact' => 'py-3', 'normal' => 'py-5', 'spacious' => 'py-6', 'extra-spacious' => 'py-7' ]; return $paddings[$padding] ?? 'py-5'; } private function getMarginClass(string $margin): string { $margins = [ 'none' => '', 'small' => 'mb-2', 'normal' => 'mb-4', 'large' => 'mb-5' ]; return $margins[$margin] ?? 'mb-4'; } private function buildInlineStyles(array $data): string { $styles = []; $backgroundType = $data['styles']['background_type'] ?? 'gradient'; switch ($backgroundType) { case 'color': $bgColor = $data['styles']['background_color'] ?? '#1e3a5f'; $styles[] = "background-color: {$bgColor}"; break; case 'gradient': $startColor = $data['styles']['gradient_start_color'] ?? '#1e3a5f'; $endColor = $data['styles']['gradient_end_color'] ?? '#2c5282'; $angle = $data['styles']['gradient_angle'] ?? 135; $styles[] = "background: linear-gradient({$angle}deg, {$startColor}, {$endColor})"; break; case 'image': $imageUrl = $data['styles']['background_image_url'] ?? ''; if (!empty($imageUrl)) { $styles[] = "background-image: url('" . esc_url($imageUrl) . "')"; $styles[] = "background-size: cover"; $styles[] = "background-position: center"; $styles[] = "background-repeat: no-repeat"; if (isset($data['styles']['background_overlay']) && $data['styles']['background_overlay']) { $opacity = ($data['styles']['overlay_opacity'] ?? 60) / 100; $styles[] = "position: relative"; } } break; } // Text color if (!empty($data['styles']['text_color'])) { $styles[] = 'color: ' . $data['styles']['text_color']; } return implode('; ', $styles); } private function buildCategoriesBadges(array $data): string { $categories = $this->getCategories($data); if (empty($categories)) { return ''; } $maxCategories = $data['categories']['max_categories'] ?? 5; $categories = array_slice($categories, 0, $maxCategories); $alignment = $data['categories']['categories_alignment'] ?? 'center'; $alignmentClasses = [ 'left' => 'justify-content-start', 'center' => 'justify-content-center', 'right' => 'justify-content-end' ]; $alignmentClass = $alignmentClasses[$alignment] ?? 'justify-content-center'; $icon = $data['categories']['category_icon'] ?? 'bi-folder-fill'; if (strpos($icon, 'bi-') !== 0) { $icon = 'bi-' . $icon; } $html = sprintf('
', esc_attr($alignmentClass)); $html .= '
'; foreach ($categories as $category) { $html .= sprintf( '%s', esc_url($category['url']), esc_attr($icon), esc_html($category['name']) ); } $html .= '
'; $html .= '
'; return $html; } private function getCategories(array $data): array { $source = $data['categories']['categories_source'] ?? 'post_categories'; switch ($source) { case 'post_categories': return $this->getPostCategories(); case 'post_tags': return $this->getPostTags(); case 'custom_taxonomy': $taxonomy = $data['categories']['custom_taxonomy_name'] ?? ''; return $this->getCustomTaxonomyTerms($taxonomy); case 'custom_list': $list = $data['categories']['custom_categories_list'] ?? ''; return $this->parseCustomCategoriesList($list); default: return []; } } private function getPostCategories(): array { $categories = get_the_category(); if (empty($categories)) { return []; } $result = []; foreach ($categories as $category) { $result[] = [ 'name' => $category->name, 'url' => get_category_link($category->term_id) ]; } return $result; } private function getPostTags(): array { $tags = get_the_tags(); if (empty($tags)) { return []; } $result = []; foreach ($tags as $tag) { $result[] = [ 'name' => $tag->name, 'url' => get_tag_link($tag->term_id) ]; } return $result; } private function getCustomTaxonomyTerms(string $taxonomy): array { if (empty($taxonomy)) { return []; } $terms = get_the_terms(get_the_ID(), $taxonomy); if (empty($terms) || is_wp_error($terms)) { return []; } $result = []; foreach ($terms as $term) { $result[] = [ 'name' => $term->name, 'url' => get_term_link($term) ]; } return $result; } private function parseCustomCategoriesList(string $list): array { if (empty($list)) { return []; } $lines = explode("\n", $list); $result = []; foreach ($lines as $line) { $line = trim($line); if (empty($line)) { continue; } $parts = explode('|', $line); if (count($parts) >= 2) { $result[] = [ 'name' => trim($parts[0]), 'url' => trim($parts[1]) ]; } } return $result; } private function buildTitle(array $data): string { $titleText = $this->getTitleText($data); if (empty($titleText)) { return ''; } $titleTag = $data['title']['title_tag'] ?? 'h1'; $titleClasses = $data['title']['title_classes'] ?? 'display-5 fw-bold'; $alignment = $data['title']['title_alignment'] ?? 'center'; $alignmentClasses = [ 'left' => 'text-start', 'center' => 'text-center', 'right' => 'text-end' ]; $alignmentClass = $alignmentClasses[$alignment] ?? 'text-center'; $classes = trim($titleClasses . ' ' . $alignmentClass); $titleStyle = ''; if (isset($data['title']['enable_gradient']) && $data['title']['enable_gradient']) { $titleStyle = $this->buildGradientStyle($data); $classes .= ' roi-gradient-text'; } return sprintf( '<%s class="%s"%s>%s', esc_attr($titleTag), esc_attr($classes), $titleStyle ? ' style="' . esc_attr($titleStyle) . '"' : '', esc_html($titleText), esc_attr($titleTag) ); } private function getTitleText(array $data): string { $source = $data['title']['title_source'] ?? 'post_title'; switch ($source) { case 'post_title': return get_the_title(); case 'custom_field': $fieldName = $data['title']['custom_field_name'] ?? ''; if (!empty($fieldName)) { $value = get_post_meta(get_the_ID(), $fieldName, true); return is_string($value) ? $value : ''; } return ''; case 'custom_text': return $data['title']['custom_text'] ?? ''; default: return get_the_title(); } } private function buildGradientStyle(array $data): string { $startColor = $data['title']['gradient_color_start'] ?? '#1e3a5f'; $endColor = $data['title']['gradient_color_end'] ?? '#FF8600'; $direction = $data['title']['gradient_direction'] ?? 'to-right'; $directions = [ 'to-right' => 'to right', 'to-left' => 'to left', 'to-bottom' => 'to bottom', 'to-top' => 'to top', 'diagonal' => '135deg' ]; $gradientDirection = $directions[$direction] ?? 'to right'; return "background: linear-gradient({$gradientDirection}, {$startColor}, {$endColor}); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;"; } private function buildCustomStyles(array $data): string { $badgeBg = $data['styles']['category_badge_background'] ?? 'rgba(255, 255, 255, 0.2)'; $badgeTextColor = $data['styles']['category_badge_text_color'] ?? '#FFFFFF'; $badgeBlur = isset($data['styles']['category_badge_blur']) && $data['styles']['category_badge_blur']; $blurStyle = $badgeBlur ? 'backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);' : ''; $overlayStyle = ''; if (($data['styles']['background_type'] ?? '') === 'image' && isset($data['styles']['background_overlay']) && $data['styles']['background_overlay']) { $opacity = ($data['styles']['overlay_opacity'] ?? 60) / 100; $overlayStyle = << .container { position: relative; z-index: 1; } CSS; } return << .category-badge-hero { background-color: {$badgeBg}; color: {$badgeTextColor}; padding: 0.5rem 1rem; border-radius: 2rem; text-decoration: none; font-size: 0.875rem; font-weight: 500; display: inline-flex; align-items: center; transition: all 0.3s ease; {$blurStyle} } .category-badge-hero:hover { background-color: rgba(255, 134, 0, 0.3); color: {$badgeTextColor}; transform: translateY(-2px); } .roi-gradient-text { display: inline-block; } {$overlayStyle} STYLES; } public function supports(string $componentType): bool { return $componentType === 'hero-section'; } }