fix(wrappers): eliminar wrappers vacíos y corregir exclusiones AdSense (Plan 99.15)

## Problema
- Componentes deshabilitados/excluidos dejaban wrappers HTML vacíos
  (navbar 32px, sidebar col-lg-3 294px)
- AdSense ignoraba exclusiones por URL pattern en grupo _exclusions

## Solución Plan 99.15 (Clean Architecture)

### Domain Layer
- WrapperVisibilityCheckerInterface: contrato para verificar visibilidad

### Application Layer
- CheckWrapperVisibilityUseCase: orquesta verificaciones de visibilidad

### Infrastructure Layer
- WordPressComponentVisibilityRepository: consulta BD + PageVisibilityHelper
- WrapperVisibilityService: facade estático para templates
- BodyClassHooksRegistrar: agrega clases CSS failsafe al body

### Templates modificados
- header.php: renderizado condicional de <nav> wrapper
- page.php/single.php: lógica dinámica col-lg-9/col-lg-12 según sidebar

### CSS Failsafe
- css-global-utilities.css: reglas body.roi-hide-* como respaldo

## Fix AdSense (Inc/adsense-placement.php)
- Agregado PageVisibilityHelper::shouldShow() a todas las funciones:
  roi_render_ad_slot, roi_render_rail_ads, roi_enqueue_adsense_script,
  roi_inject_content_ads, roi_render_anchor_ads, roi_render_vignette_ad,
  roi_enqueue_anchor_vignette_scripts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2025-12-04 11:46:21 -06:00
parent 23339e3349
commit 36d5cf56de
12 changed files with 617 additions and 12 deletions

View File

@@ -37,6 +37,11 @@ use ROITheme\Shared\Infrastructure\Services\WordPressPageContextProvider;
use ROITheme\Shared\Infrastructure\Services\WordPressServerRequestProvider;
use ROITheme\Shared\Application\UseCases\EvaluateExclusions\EvaluateExclusionsUseCase;
use ROITheme\Shared\Application\UseCases\EvaluateComponentVisibility\EvaluateComponentVisibilityUseCase;
// Wrapper Visibility System (Plan 99.15)
use ROITheme\Shared\Domain\Contracts\WrapperVisibilityCheckerInterface;
use ROITheme\Shared\Infrastructure\Persistence\WordPress\WordPressComponentVisibilityRepository;
use ROITheme\Shared\Application\UseCases\CheckWrapperVisibilityUseCase;
use ROITheme\Shared\Infrastructure\Wordpress\BodyClassHooksRegistrar;
/**
* DIContainer - Contenedor de Inyección de Dependencias
@@ -443,4 +448,49 @@ final class DIContainer
}
return $this->instances['evaluateComponentVisibilityUseCase'];
}
// ===============================
// Wrapper Visibility System (Plan 99.15)
// ===============================
/**
* Obtiene el repositorio de visibilidad de wrappers
*
* Implementa WrapperVisibilityCheckerInterface
*/
public function getWrapperVisibilityChecker(): WrapperVisibilityCheckerInterface
{
if (!isset($this->instances['wrapperVisibilityChecker'])) {
$this->instances['wrapperVisibilityChecker'] = new WordPressComponentVisibilityRepository($this->wpdb);
}
return $this->instances['wrapperVisibilityChecker'];
}
/**
* Obtiene el caso de uso para verificar visibilidad de wrappers
*
* Usado por WrapperVisibilityService para templates
*/
public function getCheckWrapperVisibilityUseCase(): CheckWrapperVisibilityUseCase
{
if (!isset($this->instances['checkWrapperVisibilityUseCase'])) {
$this->instances['checkWrapperVisibilityUseCase'] = new CheckWrapperVisibilityUseCase(
$this->getWrapperVisibilityChecker()
);
}
return $this->instances['checkWrapperVisibilityUseCase'];
}
/**
* Obtiene el registrador de hooks para body_class
*
* CSS failsafe: Agrega clases cuando componentes están ocultos
*/
public function getBodyClassHooksRegistrar(): BodyClassHooksRegistrar
{
if (!isset($this->instances['bodyClassHooksRegistrar'])) {
$this->instances['bodyClassHooksRegistrar'] = new BodyClassHooksRegistrar();
}
return $this->instances['bodyClassHooksRegistrar'];
}
}