Files
roi-theme/shared/Infrastructure/Services/WordPressValidationService.php
FrankZamora 71cfd54166 fix: Corregir case de namespaces para compatibilidad Linux/PSR-4
Cambios realizados:
- \API\ → \Api\ (4 archivos)
- \WordPress → \Wordpress (12 archivos)
- \DI\ → \Di\ (4 archivos)

Los namespaces ahora coinciden exactamente con la estructura
de carpetas (Api/, Wordpress/, Di/) para garantizar
compatibilidad con sistemas case-sensitive (Linux/producción)
y cumplimiento de PSR-4.

Archivos corregidos: 16

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 18:12:05 -06:00

173 lines
4.6 KiB
PHP

<?php
declare(strict_types=1);
namespace ROITheme\Shared\Infrastructure\Services;
use ROITheme\Shared\Domain\Contracts\ValidationServiceInterface;
use ROITheme\Shared\Domain\ValidationResult;
use ROITheme\Component\Infrastructure\Persistence\Wordpress\WordPressDefaultsRepository;
/**
* WordPressValidationService - Validación contra schemas
*
* RESPONSABILIDAD: Validar y sanitizar datos de componentes
*
* ESTRATEGIA:
* 1. Obtener schema del componente desde BD
* 2. Validar estructura contra schema
* 3. Sanitizar datos usando funciones de WordPress
*
* @package ROITheme\Infrastructure\Services
*/
final class WordPressValidationService implements ValidationServiceInterface
{
public function __construct(
private WordPressDefaultsRepository $defaultsRepository
) {}
/**
* Validar datos contra schema
*
* @param array $data Datos a validar
* @param string $componentName Nombre del componente (para obtener schema)
* @return ValidationResult
*/
public function validate(array $data, string $componentName): ValidationResult
{
// 1. Obtener schema
$schema = $this->defaultsRepository->find($componentName);
if ($schema === null) {
return ValidationResult::failure([
"Schema not found for component: {$componentName}"
]);
}
// 2. Sanitizar datos primero
$sanitized = $this->sanitize($data, $componentName);
// 3. Validar estructura
$errors = [];
foreach ($sanitized as $groupName => $fields) {
// Verificar que el grupo existe en schema
if (!isset($schema[$groupName])) {
$errors[$groupName] = "Unknown group: {$groupName}";
continue;
}
// Validar cada campo del grupo
if (is_array($fields)) {
foreach ($fields as $key => $value) {
if (!isset($schema[$groupName][$key])) {
$errors["{$groupName}.{$key}"] = "Unknown field: {$groupName}.{$key}";
}
// Validaciones adicionales pueden agregarse aquí
// Por ejemplo, validar tipos, rangos, formatos, etc.
}
}
}
if (!empty($errors)) {
return ValidationResult::failure($errors);
}
return ValidationResult::success($sanitized);
}
/**
* Sanitizar datos recursivamente
*
* Usa funciones de WordPress según el tipo de dato
*
* @param array $data Datos a sanitizar
* @param string $componentName Nombre del componente
* @return array Datos sanitizados
*/
public function sanitize(array $data, string $componentName): array
{
$sanitized = [];
foreach ($data as $key => $value) {
if (is_array($value)) {
// Recursivo para arrays anidados
$sanitized[$key] = $this->sanitizeValue($value);
} else {
$sanitized[$key] = $this->sanitizeValue($value);
}
}
return $sanitized;
}
/**
* Sanitizar un valor individual
*
* @param mixed $value
* @return mixed
*/
private function sanitizeValue(mixed $value): mixed
{
if (is_array($value)) {
$sanitized = [];
foreach ($value as $k => $v) {
$sanitized[$k] = $this->sanitizeValue($v);
}
return $sanitized;
}
if (is_bool($value)) {
return (bool) $value;
}
if (is_numeric($value)) {
return is_float($value) ? (float) $value : (int) $value;
}
if (is_string($value) && filter_var($value, FILTER_VALIDATE_URL)) {
return esc_url_raw($value);
}
if (is_string($value)) {
return sanitize_text_field($value);
}
return $value;
}
/**
* Validar una URL
*
* @param string $url
* @return bool
*/
public function isValidUrl(string $url): bool
{
return filter_var($url, FILTER_VALIDATE_URL) !== false;
}
/**
* Validar un color hexadecimal
*
* @param string $color
* @return bool
*/
public function isValidColor(string $color): bool
{
return preg_match('/^#[0-9A-F]{6}$/i', $color) === 1;
}
/**
* Validar nombre de componente
*
* @param string $name
* @return bool
*/
public function isValidComponentName(string $name): bool
{
// Solo letras minúsculas, números y guiones bajos
return preg_match('/^[a-z0-9_]+$/', $name) === 1;
}
}