COMPLETADO: Fase 1 de la migración a Clean Architecture + POO ## Estructura de Carpetas - ✓ Estructura completa de 4 capas (Domain, Application, Infrastructure, Presentation) - ✓ Carpetas de Use Cases (SaveComponent, GetComponent, DeleteComponent, SyncSchema) - ✓ Estructura de tests (Unit, Integration, E2E) - ✓ Carpetas de schemas y templates ## Composer y Autoloading - ✓ PSR-4 autoloading configurado para ROITheme namespace - ✓ Autoloader optimizado regenerado ## DI Container - ✓ DIContainer implementado con patrón Singleton - ✓ Métodos set(), get(), has() para gestión de servicios - ✓ Getters específicos para ComponentRepository, ValidationService, CacheService - ✓ Placeholders que serán implementados en Fase 5 - ✓ Prevención de clonación y deserialización ## Interfaces - ✓ ComponentRepositoryInterface (Domain) - ✓ ValidationServiceInterface (Application) - ✓ CacheServiceInterface (Application) - ✓ Component entity placeholder (Domain) ## Bootstrap - ✓ functions.php actualizado con carga de Composer autoloader - ✓ Inicialización del DIContainer - ✓ Helper function roi_container() disponible globalmente ## Tests - ✓ 10 tests unitarios para DIContainer (100% cobertura) - ✓ Total: 13 tests unitarios, 28 assertions - ✓ Suite de tests pasando correctamente ## Validación - ✓ Script de validación automatizado (48/48 checks pasados) - ✓ 100% de validaciones exitosas La arquitectura base está lista para la Fase 2. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
294 lines
8.8 KiB
PHP
294 lines
8.8 KiB
PHP
<?php
|
|
/**
|
|
* Validation Script for Phase 1
|
|
*
|
|
* Validates that all Phase 1 tasks have been completed successfully.
|
|
*
|
|
* @package ROITheme
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
class Phase1Validator
|
|
{
|
|
private int $totalChecks = 0;
|
|
private int $passedChecks = 0;
|
|
private array $errors = [];
|
|
|
|
public function run(): void
|
|
{
|
|
echo "\n";
|
|
echo "========================================\n";
|
|
echo " VALIDACIÓN DE FASE 1 - ROI THEME \n";
|
|
echo "========================================\n\n";
|
|
|
|
$this->checkFolderStructure();
|
|
$this->checkComposerAutoloader();
|
|
$this->checkDIContainer();
|
|
$this->checkInterfaces();
|
|
$this->checkBootstrap();
|
|
$this->checkTests();
|
|
|
|
$this->printResults();
|
|
}
|
|
|
|
private function check(string $description, callable $test): void
|
|
{
|
|
$this->totalChecks++;
|
|
|
|
try {
|
|
$result = $test();
|
|
|
|
if ($result) {
|
|
echo "✓ {$description}\n";
|
|
$this->passedChecks++;
|
|
} else {
|
|
echo "✗ {$description}\n";
|
|
$this->errors[] = $description;
|
|
}
|
|
} catch (Exception $e) {
|
|
echo "✗ {$description} (Error: {$e->getMessage()})\n";
|
|
$this->errors[] = $description . ': ' . $e->getMessage();
|
|
}
|
|
}
|
|
|
|
private function checkFolderStructure(): void
|
|
{
|
|
echo "Validando estructura de carpetas...\n";
|
|
|
|
$requiredDirs = [
|
|
'src/Domain/Component',
|
|
'src/Domain/Component/ValueObjects',
|
|
'src/Domain/Component/Exceptions',
|
|
'src/Domain/Shared/ValueObjects',
|
|
'src/Application/UseCases/SaveComponent',
|
|
'src/Application/UseCases/GetComponent',
|
|
'src/Application/UseCases/DeleteComponent',
|
|
'src/Application/UseCases/SyncSchema',
|
|
'src/Application/DTO',
|
|
'src/Application/Contracts',
|
|
'src/Infrastructure/Persistence/WordPress/Repositories',
|
|
'src/Infrastructure/API/WordPress',
|
|
'src/Infrastructure/Services',
|
|
'src/Infrastructure/DI',
|
|
'src/Infrastructure/Facades',
|
|
'src/Infrastructure/Presentation/Public/Renderers',
|
|
'src/Infrastructure/Presentation/Admin/FormBuilders',
|
|
'src/Infrastructure/UI/Assets',
|
|
'src/Infrastructure/UI/Views',
|
|
'tests/Unit/Domain/Component',
|
|
'tests/Unit/Application/UseCases',
|
|
'tests/Unit/Infrastructure/Persistence',
|
|
'tests/Unit/Infrastructure/Services',
|
|
'tests/Integration',
|
|
'tests/E2E',
|
|
'schemas',
|
|
'templates/admin',
|
|
'templates/public',
|
|
];
|
|
|
|
foreach ($requiredDirs as $dir) {
|
|
$this->check(
|
|
"Carpeta {$dir} existe",
|
|
fn() => is_dir(__DIR__ . '/../' . $dir)
|
|
);
|
|
}
|
|
|
|
echo "\n";
|
|
}
|
|
|
|
private function checkComposerAutoloader(): void
|
|
{
|
|
echo "Validando Composer y autoloader...\n";
|
|
|
|
$this->check(
|
|
'composer.json existe',
|
|
fn() => file_exists(__DIR__ . '/../composer.json')
|
|
);
|
|
|
|
$this->check(
|
|
'vendor/autoload.php existe',
|
|
fn() => file_exists(__DIR__ . '/../vendor/autoload.php')
|
|
);
|
|
|
|
$this->check(
|
|
'PSR-4 autoloading configurado',
|
|
function () {
|
|
$composer = json_decode(file_get_contents(__DIR__ . '/../composer.json'), true);
|
|
return isset($composer['autoload']['psr-4']['ROITheme\\']);
|
|
}
|
|
);
|
|
|
|
echo "\n";
|
|
}
|
|
|
|
private function checkDIContainer(): void
|
|
{
|
|
echo "Validando DI Container...\n";
|
|
|
|
require_once __DIR__ . '/../vendor/autoload.php';
|
|
|
|
$this->check(
|
|
'DIContainer class existe',
|
|
fn() => class_exists('ROITheme\Infrastructure\DI\DIContainer')
|
|
);
|
|
|
|
$this->check(
|
|
'DIContainer es singleton',
|
|
function () {
|
|
$instance1 = \ROITheme\Infrastructure\DI\DIContainer::getInstance();
|
|
$instance2 = \ROITheme\Infrastructure\DI\DIContainer::getInstance();
|
|
return $instance1 === $instance2;
|
|
}
|
|
);
|
|
|
|
$this->check(
|
|
'DIContainer tiene método set()',
|
|
fn() => method_exists('ROITheme\Infrastructure\DI\DIContainer', 'set')
|
|
);
|
|
|
|
$this->check(
|
|
'DIContainer tiene método get()',
|
|
fn() => method_exists('ROITheme\Infrastructure\DI\DIContainer', 'get')
|
|
);
|
|
|
|
$this->check(
|
|
'DIContainer tiene método has()',
|
|
fn() => method_exists('ROITheme\Infrastructure\DI\DIContainer', 'has')
|
|
);
|
|
|
|
$this->check(
|
|
'DIContainer tiene métodos de servicio',
|
|
function () {
|
|
return method_exists('ROITheme\Infrastructure\DI\DIContainer', 'getComponentRepository')
|
|
&& method_exists('ROITheme\Infrastructure\DI\DIContainer', 'getValidationService')
|
|
&& method_exists('ROITheme\Infrastructure\DI\DIContainer', 'getCacheService');
|
|
}
|
|
);
|
|
|
|
echo "\n";
|
|
}
|
|
|
|
private function checkInterfaces(): void
|
|
{
|
|
echo "Validando interfaces...\n";
|
|
|
|
$this->check(
|
|
'ComponentRepositoryInterface existe',
|
|
fn() => interface_exists('ROITheme\Domain\Component\ComponentRepositoryInterface')
|
|
);
|
|
|
|
$this->check(
|
|
'ValidationServiceInterface existe',
|
|
fn() => interface_exists('ROITheme\Application\Contracts\ValidationServiceInterface')
|
|
);
|
|
|
|
$this->check(
|
|
'CacheServiceInterface existe',
|
|
fn() => interface_exists('ROITheme\Application\Contracts\CacheServiceInterface')
|
|
);
|
|
|
|
$this->check(
|
|
'Component entity existe',
|
|
fn() => class_exists('ROITheme\Domain\Component\Component')
|
|
);
|
|
|
|
echo "\n";
|
|
}
|
|
|
|
private function checkBootstrap(): void
|
|
{
|
|
echo "Validando bootstrap en functions.php...\n";
|
|
|
|
$functionsContent = file_get_contents(__DIR__ . '/../functions.php');
|
|
|
|
$this->check(
|
|
'functions.php existe',
|
|
fn() => file_exists(__DIR__ . '/../functions.php')
|
|
);
|
|
|
|
$this->check(
|
|
'functions.php carga Composer autoloader',
|
|
fn() => strpos($functionsContent, "require_once __DIR__ . '/vendor/autoload.php'") !== false
|
|
);
|
|
|
|
$this->check(
|
|
'functions.php importa DIContainer',
|
|
fn() => strpos($functionsContent, 'use ROITheme\Infrastructure\DI\DIContainer') !== false
|
|
);
|
|
|
|
$this->check(
|
|
'functions.php define roi_container()',
|
|
fn() => strpos($functionsContent, 'function roi_container()') !== false
|
|
);
|
|
|
|
echo "\n";
|
|
}
|
|
|
|
private function checkTests(): void
|
|
{
|
|
echo "Validando tests unitarios...\n";
|
|
|
|
$this->check(
|
|
'phpunit.xml configurado',
|
|
fn() => file_exists(__DIR__ . '/../phpunit.xml')
|
|
);
|
|
|
|
$this->check(
|
|
'DIContainerTest existe',
|
|
fn() => file_exists(__DIR__ . '/../tests/Unit/Infrastructure/DI/DIContainerTest.php')
|
|
);
|
|
|
|
// Run PHPUnit tests
|
|
$baseDir = dirname(__DIR__);
|
|
$phpunitPath = $baseDir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'phpunit';
|
|
|
|
// For Windows compatibility
|
|
if (PHP_OS_FAMILY === 'Windows') {
|
|
$command = "cd /d \"$baseDir\" && \"$phpunitPath\" --testsuite Unit 2>&1";
|
|
} else {
|
|
$command = "cd \"$baseDir\" && \"$phpunitPath\" --testsuite Unit 2>&1";
|
|
}
|
|
|
|
exec($command, $output, $returnCode);
|
|
|
|
$this->check(
|
|
'Tests unitarios pasan',
|
|
fn() => $returnCode === 0
|
|
);
|
|
|
|
echo "\n";
|
|
}
|
|
|
|
private function printResults(): void
|
|
{
|
|
echo "========================================\n";
|
|
echo " RESULTADOS DE VALIDACIÓN\n";
|
|
echo "========================================\n\n";
|
|
|
|
$percentage = $this->totalChecks > 0
|
|
? round(($this->passedChecks / $this->totalChecks) * 100, 2)
|
|
: 0;
|
|
|
|
echo "Checks pasados: {$this->passedChecks}/{$this->totalChecks} ({$percentage}%)\n\n";
|
|
|
|
if (count($this->errors) > 0) {
|
|
echo "ERRORES ENCONTRADOS:\n";
|
|
foreach ($this->errors as $error) {
|
|
echo " - {$error}\n";
|
|
}
|
|
echo "\n";
|
|
exit(1);
|
|
} else {
|
|
echo "✓ ¡FASE 1 COMPLETADA EXITOSAMENTE!\n\n";
|
|
echo "Todas las validaciones pasaron correctamente.\n";
|
|
echo "La arquitectura base está lista para la Fase 2.\n\n";
|
|
exit(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Run validation
|
|
$validator = new Phase1Validator();
|
|
$validator->run();
|