feat(visibility): sistema de visibilidad por tipo de página
- Añadir PageVisibility use case y repositorio - Implementar PageTypeDetector para detectar home/single/page/archive - Actualizar FieldMappers con soporte show_on_[page_type] - Extender FormBuilders con UI de visibilidad por página - Refactorizar Renderers para evaluar visibilidad dinámica - Limpiar schemas removiendo campos de visibilidad legacy - Añadir MigrationCommand para migrar configuraciones existentes - Implementar adsense-loader.js para carga lazy de ads - Actualizar front-page.php con nueva estructura - Extender DIContainer con nuevos servicios 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -95,6 +95,16 @@ final class AdsensePlacementFieldMapper implements FieldMapperInterface
|
||||
'adsense-placementVignetteReshowEnabled' => ['group' => 'vignette_ads', 'attribute' => 'vignette_reshow_enabled'],
|
||||
'adsense-placementVignetteReshowTime' => ['group' => 'vignette_ads', 'attribute' => 'vignette_reshow_time'],
|
||||
'adsense-placementVignetteMaxPerSession' => ['group' => 'vignette_ads', 'attribute' => 'vignette_max_per_session'],
|
||||
|
||||
// SEARCH RESULTS (ROI APU Search)
|
||||
'adsense-placementSearchAdsEnabled' => ['group' => 'search_results', 'attribute' => 'search_ads_enabled'],
|
||||
'adsense-placementSearchTopAdEnabled' => ['group' => 'search_results', 'attribute' => 'search_top_ad_enabled'],
|
||||
'adsense-placementSearchTopAdFormat' => ['group' => 'search_results', 'attribute' => 'search_top_ad_format'],
|
||||
'adsense-placementSearchBetweenEnabled' => ['group' => 'search_results', 'attribute' => 'search_between_enabled'],
|
||||
'adsense-placementSearchBetweenMax' => ['group' => 'search_results', 'attribute' => 'search_between_max'],
|
||||
'adsense-placementSearchBetweenFormat' => ['group' => 'search_results', 'attribute' => 'search_between_format'],
|
||||
'adsense-placementSearchBetweenPosition' => ['group' => 'search_results', 'attribute' => 'search_between_position'],
|
||||
'adsense-placementSearchBetweenEvery' => ['group' => 'search_results', 'attribute' => 'search_between_every'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ final class AdsensePlacementFormBuilder
|
||||
$html .= $this->buildRailAdsGroup($componentId);
|
||||
$html .= $this->buildAnchorAdsGroup($componentId);
|
||||
$html .= $this->buildVignetteAdsGroup($componentId);
|
||||
$html .= $this->buildSearchResultsGroup($componentId);
|
||||
$html .= ' </div>';
|
||||
|
||||
$html .= '</div>';
|
||||
@@ -708,6 +709,101 @@ final class AdsensePlacementFormBuilder
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Seccion para anuncios en resultados de busqueda (ROI APU Search)
|
||||
*/
|
||||
private function buildSearchResultsGroup(string $cid): string
|
||||
{
|
||||
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #fd7e14;">';
|
||||
$html .= ' <div class="card-body">';
|
||||
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
||||
$html .= ' <i class="bi bi-search me-2" style="color: #fd7e14;"></i>';
|
||||
$html .= ' Resultados de Busqueda';
|
||||
$html .= ' <span class="badge bg-secondary ms-2">ROI APU Search</span>';
|
||||
$html .= ' </h5>';
|
||||
$html .= ' <p class="small text-muted mb-3">Insertar anuncios en los resultados del buscador de Analisis de Precios Unitarios.</p>';
|
||||
|
||||
// Master switch
|
||||
$searchAdsEnabled = $this->renderer->getFieldValue($cid, 'search_results', 'search_ads_enabled', false);
|
||||
$html .= $this->buildSwitch($cid . 'SearchAdsEnabled', 'Activar ads en busqueda', $searchAdsEnabled, 'bi-power');
|
||||
|
||||
// Anuncio superior
|
||||
$html .= '<div class="border rounded p-3 mb-3" style="background: #fff8f0;">';
|
||||
$html .= '<div class="d-flex align-items-center gap-2 mb-2">';
|
||||
$html .= ' <span class="badge" style="background: #fd7e14;">ANUNCIO SUPERIOR</span>';
|
||||
$html .= ' <small class="text-muted">Debajo del campo de busqueda</small>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div class="row g-2">';
|
||||
$html .= ' <div class="col-md-6">';
|
||||
$topEnabled = $this->renderer->getFieldValue($cid, 'search_results', 'search_top_ad_enabled', true);
|
||||
$html .= $this->buildSwitch($cid . 'SearchTopAdEnabled', 'Activar', $topEnabled);
|
||||
$html .= ' </div>';
|
||||
$html .= ' <div class="col-md-6">';
|
||||
$topFormat = $this->renderer->getFieldValue($cid, 'search_results', 'search_top_ad_format', 'auto');
|
||||
$html .= $this->buildSelect($cid . 'SearchTopAdFormat', 'Formato',
|
||||
(string)$topFormat,
|
||||
['auto' => 'Auto (responsive)', 'display' => 'Display (fijo)', 'in-article' => 'In-Article (fluid)']
|
||||
);
|
||||
$html .= ' </div>';
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
// Anuncios entre resultados
|
||||
$html .= '<div class="border rounded p-3" style="background: #fff8f0;">';
|
||||
$html .= '<div class="d-flex align-items-center gap-2 mb-2">';
|
||||
$html .= ' <span class="badge" style="background: #fd7e14;">ENTRE RESULTADOS</span>';
|
||||
$html .= ' <small class="text-muted">Intercalados con los resultados</small>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div class="row g-2 mb-2">';
|
||||
$html .= ' <div class="col-md-6">';
|
||||
$betweenEnabled = $this->renderer->getFieldValue($cid, 'search_results', 'search_between_enabled', true);
|
||||
$html .= $this->buildSwitch($cid . 'SearchBetweenEnabled', 'Activar', $betweenEnabled);
|
||||
$html .= ' </div>';
|
||||
$html .= ' <div class="col-md-6">';
|
||||
$betweenMax = $this->renderer->getFieldValue($cid, 'search_results', 'search_between_max', '1');
|
||||
$html .= $this->buildSelect($cid . 'SearchBetweenMax', 'Maximo ads',
|
||||
(string)$betweenMax,
|
||||
['1' => '1 anuncio', '2' => '2 anuncios', '3' => '3 anuncios (max)']
|
||||
);
|
||||
$html .= ' </div>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div class="row g-2 mb-2">';
|
||||
$html .= ' <div class="col-md-6">';
|
||||
$betweenFormat = $this->renderer->getFieldValue($cid, 'search_results', 'search_between_format', 'in-article');
|
||||
$html .= $this->buildSelect($cid . 'SearchBetweenFormat', 'Formato',
|
||||
(string)$betweenFormat,
|
||||
['in-article' => 'In-Article (fluid)', 'auto' => 'Auto (responsive)', 'autorelaxed' => 'Autorelaxed (feed)']
|
||||
);
|
||||
$html .= ' </div>';
|
||||
$html .= ' <div class="col-md-6">';
|
||||
$betweenPosition = $this->renderer->getFieldValue($cid, 'search_results', 'search_between_position', 'random');
|
||||
$html .= $this->buildSelect($cid . 'SearchBetweenPosition', 'Posicion',
|
||||
(string)$betweenPosition,
|
||||
['random' => 'Aleatorio', 'fixed' => 'Fijo (cada N)', 'first_half' => 'Primera mitad']
|
||||
);
|
||||
$html .= ' </div>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div class="row g-2">';
|
||||
$html .= ' <div class="col-md-6">';
|
||||
$betweenEvery = $this->renderer->getFieldValue($cid, 'search_results', 'search_between_every', '5');
|
||||
$html .= $this->buildSelect($cid . 'SearchBetweenEvery', 'Cada N resultados (si es fijo)',
|
||||
(string)$betweenEvery,
|
||||
['3' => 'Cada 3', '4' => 'Cada 4', '5' => 'Cada 5', '6' => 'Cada 6', '7' => 'Cada 7', '8' => 'Cada 8', '10' => 'Cada 10']
|
||||
);
|
||||
$html .= ' </div>';
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= ' </div>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
private function buildExclusionsGroup(string $cid): string
|
||||
{
|
||||
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #6c757d;">';
|
||||
|
||||
Reference in New Issue
Block a user