Files
roi-theme/Shared/Domain
FrankZamora 36d5cf56de 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>
2025-12-04 11:46:21 -06:00
..

Capa de Dominio - Shared (Fundación)

Propósito

La capa de Dominio de shared/ contiene la lógica de negocio compartida que utilizan todos los contextos (admin y public). Es la fundación del proyecto y no debe tener dependencias de frameworks, librerías externas, o capas superiores.

Principios

  1. Sin dependencias externas: No depende de WordPress, plugins, o librerías
  2. Lógica pura: Solo reglas de negocio y objetos de dominio
  3. Inmutabilidad: Los Value Objects son inmutables
  4. Validación: Los objetos se validan a sí mismos

Estructura

shared/Domain/
├── ValueObjects/        # Value Objects compartidos (ComponentID, SettingValue, etc.)
├── Exceptions/          # Excepciones de dominio (InvalidComponentException, etc.)
└── Contracts/           # Interfaces de repositorios y servicios de dominio

Ejemplos de Uso

Value Objects

Value Objects que representan conceptos del dominio:

namespace ROITheme\Shared\Domain\ValueObjects;

final class ComponentID
{
    private int $value;

    public function __construct(int $value)
    {
        if ($value <= 0) {
            throw new \InvalidArgumentException('Component ID must be positive');
        }

        $this->value = $value;
    }

    public function value(): int
    {
        return $this->value;
    }

    public function equals(ComponentID $other): bool
    {
        return $this->value === $other->value;
    }
}

Excepciones

Excepciones específicas del dominio:

namespace ROITheme\Shared\Domain\Exceptions;

class InvalidComponentException extends \DomainException
{
    public static function withId(int $id): self
    {
        return new self("Component with ID {$id} is invalid");
    }
}

Contracts (Interfaces)

Interfaces que definen comportamientos:

namespace ROITheme\Shared\Domain\Contracts;

interface ComponentRepositoryInterface
{
    public function findById(ComponentID $id): ?Component;
    public function save(Component $component): void;
}

Reglas de Dependencia

PUEDE depender de:

  • Otros objetos dentro de shared/Domain/
  • SPL (Standard PHP Library)
  • Nada más

NO PUEDE depender de:

  • shared/Application/
  • shared/Infrastructure/
  • admin/ o public/
  • WordPress functions
  • Librerías externas

Testing

Los objetos de esta capa se testean con tests unitarios puros, sin necesidad de WordPress:

// tests/Unit/Shared/Domain/ValueObjects/ComponentIDTest.php
public function test_creates_valid_component_id()
{
    $id = new ComponentID(123);
    $this->assertEquals(123, $id->value());
}

Cuándo Agregar Código Aquí

Agrega código a shared/Domain/ cuando:

  • Es lógica de negocio pura (sin WordPress)
  • Es compartido por admin/ y public/
  • Es un concepto fundamental del dominio
  • Necesita alta cohesión y bajo acoplamiento

No agregues aquí:

  • Código que depende de WordPress
  • Lógica específica de un solo contexto
  • Implementaciones concretas de servicios