refactor: remove legacy HeroSection component (orphaned code)
BREAKING: Remove unused HeroSectionRenderer and content-hero template Analysis confirmed HeroSection was legacy orphaned code: - No JSON schema (hero-section.json didn't exist) - No FormBuilder for admin UI - No database records (component_name='hero-section') - No template usage (single.php uses 'hero' not 'hero-section') - Violated Clean Architecture (hardcoded CSS) Removed files: - Public/HeroSection/Infrastructure/Ui/HeroSectionRenderer.php - TemplateParts/content-hero.php - case 'hero-section' from functions-addon.php switch Active Hero component (Schemas/hero.json + HeroRenderer.php) remains unchanged. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,484 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ROITheme\Public\HeroSection\Infrastructure\Ui;
|
||||
|
||||
use ROITheme\Shared\Domain\Entities\Component;
|
||||
use ROITheme\Shared\Domain\Contracts\RendererInterface;
|
||||
use ROITheme\Shared\Infrastructure\Services\PageVisibilityHelper;
|
||||
|
||||
/**
|
||||
* HeroSectionRenderer - Renderiza la sección hero con badges y título
|
||||
*
|
||||
* RESPONSABILIDAD: Generar HTML de la sección hero
|
||||
*
|
||||
* CARACTERÍSTICAS:
|
||||
* - Badges de categorías con múltiples fuentes de datos
|
||||
* - Título H1 con gradiente opcional
|
||||
* - Múltiples tipos de fondo (color, gradiente, imagen)
|
||||
* - Lógica condicional de visibilidad por tipo de página
|
||||
*
|
||||
* @package ROITheme\Public\HeroSection\Presentation
|
||||
*/
|
||||
final class HeroSectionRenderer implements RendererInterface
|
||||
{
|
||||
public function render(Component $component): string
|
||||
{
|
||||
// Verificar visibilidad por tipo de página y exclusiones (Plan 99.10/99.11)
|
||||
if (!PageVisibilityHelper::shouldShow('hero-section')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$data = $component->getData();
|
||||
|
||||
if (!$this->isEnabled($data)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!$this->shouldShowOnCurrentPage($data)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$classes = $this->buildSectionClasses($data);
|
||||
$styles = $this->buildInlineStyles($data);
|
||||
|
||||
$html = sprintf(
|
||||
'<div class="%s"%s>',
|
||||
esc_attr($classes),
|
||||
$styles ? ' style="' . esc_attr($styles) . '"' : ''
|
||||
);
|
||||
|
||||
$html .= '<div class="container">';
|
||||
|
||||
// Categories badges
|
||||
if ($this->shouldShowCategories($data)) {
|
||||
$html .= $this->buildCategoriesBadges($data);
|
||||
}
|
||||
|
||||
// Title
|
||||
$html .= $this->buildTitle($data);
|
||||
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
// 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('<div class="mb-3 d-flex %s">', esc_attr($alignmentClass));
|
||||
$html .= '<div class="d-flex gap-2 flex-wrap justify-content-center">';
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$html .= sprintf(
|
||||
'<a href="%s" class="category-badge category-badge-hero"><i class="bi %s me-1"></i>%s</a>',
|
||||
esc_url($category['url']),
|
||||
esc_attr($icon),
|
||||
esc_html($category['name'])
|
||||
);
|
||||
}
|
||||
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
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</%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 = <<<CSS
|
||||
.hero-title::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, {$opacity});
|
||||
z-index: 0;
|
||||
}
|
||||
.hero-title > .container {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
CSS;
|
||||
}
|
||||
|
||||
return <<<STYLES
|
||||
<style>
|
||||
.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}
|
||||
</style>
|
||||
STYLES;
|
||||
}
|
||||
|
||||
public function supports(string $componentType): bool
|
||||
{
|
||||
return $componentType === 'hero-section';
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Hero Section Template
|
||||
*
|
||||
* Hero section con degradado azul para single posts
|
||||
*
|
||||
* @package ROI_Theme
|
||||
*/
|
||||
|
||||
if (!is_single()) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
|
||||
<section class="hero-section">
|
||||
<div class="container-fluid py-5">
|
||||
<div class="hero-content text-center">
|
||||
|
||||
<!-- Category Badges (ARRIBA del H1) -->
|
||||
<?php
|
||||
$categories = get_the_category();
|
||||
if (!empty($categories)) :
|
||||
?>
|
||||
<div class="hero-categories mb-3">
|
||||
<?php foreach ($categories as $category) : ?>
|
||||
<?php if ($category->name !== 'Uncategorized' && $category->name !== 'Sin categoría') : ?>
|
||||
<span class="hero-category-badge"><?php echo esc_html($category->name); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- H1 Title -->
|
||||
<h1 class="hero-title"><?php the_title(); ?></h1>
|
||||
|
||||
<!-- Post Meta -->
|
||||
<div class="hero-meta">
|
||||
<span class="hero-meta-item">
|
||||
<i class="bi bi-calendar3 me-1"></i>
|
||||
<?php echo get_the_date(); ?>
|
||||
</span>
|
||||
<span class="hero-meta-separator">|</span>
|
||||
<span class="hero-meta-item">
|
||||
<i class="bi bi-person me-1"></i>
|
||||
<?php the_author(); ?>
|
||||
</span>
|
||||
<?php
|
||||
$reading_time = roi_get_reading_time();
|
||||
if ($reading_time) :
|
||||
?>
|
||||
<span class="hero-meta-separator">|</span>
|
||||
<span class="hero-meta-item">
|
||||
<i class="bi bi-clock me-1"></i>
|
||||
<?php echo esc_html($reading_time); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -297,9 +297,6 @@ function roi_render_component(string $componentName): string {
|
||||
case 'cta-lets-talk':
|
||||
$renderer = new \ROITheme\Public\CtaLetsTalk\Infrastructure\Ui\CtaLetsTalkRenderer($cssGenerator);
|
||||
break;
|
||||
case 'hero-section':
|
||||
$renderer = new \ROITheme\Public\HeroSection\Infrastructure\Ui\HeroSectionRenderer();
|
||||
break;
|
||||
case 'featured-image':
|
||||
$renderer = new \ROITheme\Public\FeaturedImage\Infrastructure\Ui\FeaturedImageRenderer($cssGenerator);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user