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:
@@ -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;
|
||||||
|
|||||||
@@ -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)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user