Files
roi-theme/shared/Infrastructure/README.md
FrankZamora 677fbd4368 Fase-00: Estructura Clean Architecture Context-First creada
- Creada estructura shared/ con Domain, Application, Infrastructure
- Documentación completa de arquitectura (5 READMEs, ~6150 líneas)
- Archivos .gitkeep para preservar estructura en Git
- Contextos admin/ y public/ documentados

Estructura shared/:
- Domain/ (ValueObjects, Exceptions, Contracts)
- Application/ (Contracts, Services)
- Infrastructure/ (Services, Traits)

Documentación incluye:
- Principios de Clean Architecture
- Reglas de dependencia
- Ejemplos de código
- Guías de testing
- Mejores prácticas

Preparación completa para implementación en Fase-1.
2025-11-18 23:36:06 -06:00

6.0 KiB

Capa de Infraestructura - Shared (Implementaciones Concretas)

Propósito

La capa de Infraestructura de shared/ contiene implementaciones concretas de los servicios definidos en Application, utilizando WordPress y otras librerías externas.

Principios

  1. Implementaciones concretas: Código que interactúa con WordPress y librerías
  2. Cumple contratos: Implementa las interfaces definidas en Application
  3. Detalles técnicos: Maneja aspectos técnicos como caché, base de datos, APIs
  4. Reusabilidad: Servicios compartidos por todos los contextos

Estructura

shared/Infrastructure/
├── Services/            # Implementaciones de servicios (WordPressCacheService, etc.)
└── Traits/              # Traits reutilizables (WordPress helpers, etc.)

Ejemplos de Uso

Services (Implementaciones Concretas)

Implementación de CacheService usando WordPress Transients:

namespace ROITheme\Shared\Infrastructure\Services;

use ROITheme\Shared\Application\Contracts\CacheServiceInterface;

final class WordPressCacheService implements CacheServiceInterface
{
    public function get(string $key): mixed
    {
        return get_transient($this->prefixKey($key));
    }

    public function set(string $key, mixed $value, int $ttl = 3600): bool
    {
        return set_transient($this->prefixKey($key), $value, $ttl);
    }

    public function delete(string $key): bool
    {
        return delete_transient($this->prefixKey($key));
    }

    public function flush(): bool
    {
        return wp_cache_flush();
    }

    private function prefixKey(string $key): string
    {
        return 'roi_theme_' . $key;
    }
}

Implementación de ValidationService usando WordPress Sanitization:

namespace ROITheme\Shared\Infrastructure\Services;

use ROITheme\Shared\Application\Services\BaseValidationService;

final class WordPressValidationService extends BaseValidationService
{
    public function validate(array $data, array $rules): array
    {
        $validated = [];

        foreach ($rules as $field => $rule) {
            if (!isset($data[$field])) {
                $this->errors[$field] = "Field {$field} is required";
                continue;
            }

            $validated[$field] = match($rule) {
                'email' => sanitize_email($data[$field]),
                'text' => sanitize_text_field($data[$field]),
                'int' => intval($data[$field]),
                'url' => esc_url_raw($data[$field]),
                default => $data[$field]
            };
        }

        return $validated;
    }
}

Traits (Helpers Reutilizables)

Traits para funcionalidad común de WordPress:

namespace ROITheme\Shared\Infrastructure\Traits;

trait WordPressMetaDataTrait
{
    private function getMeta(int $postId, string $key, bool $single = true): mixed
    {
        return get_post_meta($postId, $this->prefixMetaKey($key), $single);
    }

    private function updateMeta(int $postId, string $key, mixed $value): bool
    {
        return update_post_meta($postId, $this->prefixMetaKey($key), $value);
    }

    private function deleteMeta(int $postId, string $key): bool
    {
        return delete_post_meta($postId, $this->prefixMetaKey($key));
    }

    private function prefixMetaKey(string $key): string
    {
        return '_roi_' . $key;
    }
}

Relación con Application

La capa Infrastructure implementa los contratos definidos en Application:

shared/Application/Contracts/CacheServiceInterface.php (interface)
                    ↓ implementa
shared/Infrastructure/Services/WordPressCacheService.php (implementación)

Inyección de Dependencias

Los servicios se registran en el DI Container y se inyectan a través de constructores:

// En el DI Container (configuración)
$container->bind(
    CacheServiceInterface::class,
    WordPressCacheService::class
);

// En el código que usa el servicio
public function __construct(
    private readonly CacheServiceInterface $cache
) {}

Reglas de Dependencia

PUEDE depender de:

  • shared/Domain/ (Value Objects, Entities)
  • shared/Application/ (especialmente Contracts)
  • WordPress functions
  • Librerías externas (Composer packages)

NO PUEDE depender de:

  • admin/ o public/ (contextos específicos)

Testing

Los servicios de Infrastructure se testean con tests de integración que usan WordPress:

// tests/Integration/Shared/Infrastructure/Services/WordPressCacheServiceTest.php
public function test_stores_and_retrieves_from_cache()
{
    $cache = new WordPressCacheService();

    $cache->set('test_key', 'test_value', 3600);
    $result = $cache->get('test_key');

    $this->assertEquals('test_value', $result);
}

Cuándo Agregar Código Aquí

Agrega código a shared/Infrastructure/ cuando:

  • Implementas un servicio definido en Application/Contracts/
  • Necesitas interactuar con WordPress (base de datos, caché, opciones, etc.)
  • Integras una librería externa
  • Creas utilidades de bajo nivel compartidas

No agregues aquí:

  • Lógica de negocio (va en Domain/)
  • Definiciones de interfaces (van en Application/Contracts/)
  • Código específico de admin o public
  • Código sin contrato (sin interface)

Servicios Comunes en Infrastructure

Services/

  • WordPressCacheService: Caché usando WordPress Transients
  • WordPressValidationService: Validación con WordPress sanitization
  • WordPressLoggerService: Logging usando error_log o debug.log
  • WordPressDatabaseService: Interacciones directas con $wpdb

Traits/

  • WordPressMetaDataTrait: Helpers para post meta
  • WordPressTaxonomyTrait: Helpers para términos y taxonomías
  • WordPressHooksTrait: Helpers para actions y filters
  • WordPressSanitizationTrait: Helpers para sanitización

Patrón de Diseño

Seguimos el patrón Adapter:

  • WordPress es el "adaptee" (sistema externo)
  • Nuestros Services son "adapters"
  • Los Contracts son las interfaces que queremos

Esto permite cambiar WordPress por otro sistema en el futuro sin afectar el código de negocio.