refactor(validators): Add support for injection components

Injection components (like theme-settings) are special components that:
- Don't render visual HTML (inject code into wp_head/wp_footer)
- Don't need visibility group (always enabled)
- Don't need CSSGeneratorInterface (output user-provided CSS)
- Don't need getVisibilityClasses (not responsive visual elements)

- Update Phase01Validator to skip visibility check for injection components
- Update Phase03Validator to skip CSS/visibility validations for injection components

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2025-11-26 21:59:04 -06:00
parent 6dc052afa6
commit 7cc5f194e9
2 changed files with 54 additions and 13 deletions

View File

@@ -21,6 +21,16 @@ final class Phase01Validator implements PhaseValidatorInterface
'visual_effects', 'behavior', 'layout', 'links', 'icons', 'media', 'forms' 'visual_effects', 'behavior', 'layout', 'links', 'icons', 'media', 'forms'
]; ];
/**
* Componentes especiales que NO requieren grupo visibility
*
* Estos son componentes de inyeccion (no visuales) que:
* - NO renderizan HTML visual
* - Inyectan codigo en hooks (wp_head, wp_footer)
* - Siempre estan activos (controlados por campos vacios/llenos)
*/
private const INJECTION_COMPONENTS = ['theme-settings'];
public function validate(string $componentName, string $themePath): ValidationResult public function validate(string $componentName, string $themePath): ValidationResult
{ {
$result = new ValidationResult(); $result = new ValidationResult();
@@ -53,8 +63,8 @@ final class Phase01Validator implements PhaseValidatorInterface
$this->validateGroups($schema['groups'], $result); $this->validateGroups($schema['groups'], $result);
} }
// 5. Validar campos obligatorios de visibilidad // 5. Validar campos obligatorios de visibilidad (excepto componentes de inyeccion)
$this->validateVisibilityFields($schema, $result); $this->validateVisibilityFields($schema, $componentName, $result);
// Estadísticas // Estadísticas
$totalFields = $this->countTotalFields($schema); $totalFields = $this->countTotalFields($schema);
@@ -184,8 +194,14 @@ final class Phase01Validator implements PhaseValidatorInterface
} }
} }
private function validateVisibilityFields(array $schema, ValidationResult $result): void private function validateVisibilityFields(array $schema, string $componentName, ValidationResult $result): void
{ {
// Componentes de inyeccion no requieren grupo visibility
if (in_array($componentName, self::INJECTION_COMPONENTS, true)) {
$result->addInfo("✓ Componente de inyección '{$componentName}' - grupo visibility no requerido");
return;
}
if (!isset($schema['groups']['visibility'])) { if (!isset($schema['groups']['visibility'])) {
$result->addError("Grupo 'visibility' es obligatorio y no está presente"); $result->addError("Grupo 'visibility' es obligatorio y no está presente");
return; return;

View File

@@ -17,6 +17,17 @@ namespace ROITheme\Shared\Infrastructure\Validators;
*/ */
final class Phase03Validator implements PhaseValidatorInterface final class Phase03Validator implements PhaseValidatorInterface
{ {
/**
* Componentes especiales que NO requieren CSSGeneratorInterface ni getVisibilityClasses
*
* Estos son componentes de inyeccion (no visuales) que:
* - NO renderizan HTML visual
* - NO generan CSS dinamico (inyectan CSS del usuario tal cual)
* - NO necesitan clases de visibilidad responsive
* - Inyectan codigo en hooks (wp_head, wp_footer)
*/
private const INJECTION_COMPONENTS = ['theme-settings'];
public function validate(string $componentName, string $themePath): ValidationResult public function validate(string $componentName, string $themePath): ValidationResult
{ {
$result = new ValidationResult(); $result = new ValidationResult();
@@ -40,10 +51,19 @@ final class Phase03Validator implements PhaseValidatorInterface
// Validaciones // Validaciones
$this->validateNamespaceAndClass($content, $componentName, $result); $this->validateNamespaceAndClass($content, $componentName, $result);
$this->validateCSSGeneratorInjection($content, $result);
$this->validateRenderMethod($content, $result); // Validaciones especiales para componentes de inyeccion
$this->validateNoCSSHardcoded($content, $result); // CRÍTICO $isInjectionComponent = in_array($componentName, self::INJECTION_COMPONENTS, true);
$this->validateGetVisibilityClassesMethod($content, $result);
if ($isInjectionComponent) {
$result->addInfo("✓ Componente de inyección - validaciones CSS/visibility omitidas");
} else {
$this->validateCSSGeneratorInjection($content, $result);
$this->validateNoCSSHardcoded($content, $result); // CRÍTICO
$this->validateGetVisibilityClassesMethod($content, $result);
}
$this->validateRenderMethod($content, $componentName, $result);
$this->validateEscaping($content, $result); $this->validateEscaping($content, $result);
$this->validateNoDirectDatabaseAccess($content, $result); $this->validateNoDirectDatabaseAccess($content, $result);
@@ -112,7 +132,7 @@ final class Phase03Validator implements PhaseValidatorInterface
} }
} }
private function validateRenderMethod(string $content, ValidationResult $result): void private function validateRenderMethod(string $content, string $componentName, ValidationResult $result): void
{ {
// Verificar método render existe (aceptar Component object o array - Component es preferido) // Verificar método render existe (aceptar Component object o array - Component es preferido)
$hasComponentSignature = preg_match('/public\s+function\s+render\s*\(\s*Component\s+\$component\s*\)\s*:\s*string/', $content); $hasComponentSignature = preg_match('/public\s+function\s+render\s*\(\s*Component\s+\$component\s*\)\s*:\s*string/', $content);
@@ -124,12 +144,17 @@ final class Phase03Validator implements PhaseValidatorInterface
$result->addWarning("Método usa render(array \$data) - Considerar migrar a render(Component \$component) para type safety"); $result->addWarning("Método usa render(array \$data) - Considerar migrar a render(Component \$component) para type safety");
} }
// Verificar que valida is_enabled // Componentes de inyeccion no requieren validacion de visibility
$hasArrayValidation = preg_match('/\$data\s*\[\s*[\'"]visibility[\'"]\s*\]\s*\[\s*[\'"]is_enabled[\'"]\s*\]/', $content); $isInjectionComponent = in_array($componentName, self::INJECTION_COMPONENTS, true);
$hasComponentValidation = preg_match('/\$component->getVisibility\(\)->isEnabled\(\)/', $content);
if (!$hasArrayValidation && !$hasComponentValidation) { if (!$isInjectionComponent) {
$result->addWarning("Método render() debería validar visibilidad (is_enabled)"); // Verificar que valida is_enabled
$hasArrayValidation = preg_match('/\$data\s*\[\s*[\'"]visibility[\'"]\s*\]\s*\[\s*[\'"]is_enabled[\'"]\s*\]/', $content);
$hasComponentValidation = preg_match('/\$component->getVisibility\(\)->isEnabled\(\)/', $content);
if (!$hasArrayValidation && !$hasComponentValidation) {
$result->addWarning("Método render() debería validar visibilidad (is_enabled)");
}
} }
} }