- 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.
218 lines
6.0 KiB
Markdown
218 lines
6.0 KiB
Markdown
# 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:
|
|
|
|
```php
|
|
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:
|
|
|
|
```php
|
|
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:
|
|
|
|
```php
|
|
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:
|
|
|
|
```php
|
|
// 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:
|
|
|
|
```php
|
|
// 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.
|