refactor: reorganize project structure for better maintainability
- Move 45 debug/test files from root to organized scripts/ directories - Secure public/ directory by removing debug files (security improvement) - Create structured scripts organization: • scripts/debug/ (20 files) - Framework debugging tools • scripts/test/ (18 files) - Test and validation scripts • scripts/maintenance/ (5 files) - Maintenance utilities • scripts/dev/ (2 files) - Development tools Security improvements: - Removed all debug/test files from public/ directory - Only production files remain: index.php, health.php Root directory cleanup: - Reduced from 47 to 2 PHP files in root - Only essential production files: console.php, worker.php This improves: ✅ Security (no debug code in public/) ✅ Organization (clear separation of concerns) ✅ Maintainability (easy to find and manage scripts) ✅ Professional structure (clean root directory)
This commit is contained in:
78
scripts/debug/debug-container.php
Normal file
78
scripts/debug/debug-container.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Attributes\Route;
|
||||
use App\Framework\Core\AppBootstrapper;
|
||||
use App\Framework\Discovery\Results\DiscoveryRegistry;
|
||||
use App\Framework\Performance\EnhancedPerformanceCollector;
|
||||
use App\Framework\DateTime\SystemClock;
|
||||
use App\Framework\DateTime\SystemHighResolutionClock;
|
||||
use App\Framework\Performance\MemoryMonitor;
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
require __DIR__ . '/src/Framework/Debug/helpers.php';
|
||||
|
||||
echo "DEBUG: Starting container debug\n";
|
||||
|
||||
// Create dependencies for enhanced performance collector
|
||||
$basePath = __DIR__;
|
||||
$clock = new SystemClock();
|
||||
$highResClock = new SystemHighResolutionClock();
|
||||
$memoryMonitor = new MemoryMonitor();
|
||||
$collector = new EnhancedPerformanceCollector($clock, $highResClock, $memoryMonitor, enabled: true);
|
||||
|
||||
echo "DEBUG: About to create AppBootstrapper\n";
|
||||
$bootstrapper = new AppBootstrapper($basePath, $collector, $memoryMonitor);
|
||||
|
||||
echo "DEBUG: About to bootstrap web app\n";
|
||||
$app = $bootstrapper->bootstrapWeb();
|
||||
|
||||
echo "DEBUG: Web app bootstrapped successfully\n";
|
||||
|
||||
// Get container from the app
|
||||
$reflection = new ReflectionObject($app);
|
||||
$containerProperty = $reflection->getProperty('container');
|
||||
$containerProperty->setAccessible(true);
|
||||
$container = $containerProperty->getValue($app);
|
||||
|
||||
echo "DEBUG: Got container from app\n";
|
||||
|
||||
// Check if DiscoveryRegistry is available
|
||||
if ($container->has(DiscoveryRegistry::class)) {
|
||||
echo "DEBUG: DiscoveryRegistry is available in container\n";
|
||||
$registry = $container->get(DiscoveryRegistry::class);
|
||||
|
||||
$routeCount = $registry->attributes->getCount(Route::class);
|
||||
echo "DEBUG: Found $routeCount route attributes in registry\n";
|
||||
|
||||
if ($routeCount > 0) {
|
||||
$routes = $registry->attributes->get(Route::class);
|
||||
echo "DEBUG: First few routes:\n";
|
||||
foreach (array_slice($routes, 0, 3) as $i => $route) {
|
||||
echo " Route $i: " . $route->className->getFullyQualified() . "::" . $route->methodName?->toString() . "\n";
|
||||
}
|
||||
|
||||
// Look for the home route specifically
|
||||
echo "DEBUG: Looking for home route (/)\n";
|
||||
$homeFound = false;
|
||||
foreach ($routes as $route) {
|
||||
$instance = $route->createAttributeInstance();
|
||||
if ($instance instanceof \App\Framework\Attributes\Route && $instance->path === '/') {
|
||||
echo " HOME ROUTE FOUND: " . $route->className->getFullyQualified() . "::" . $route->methodName?->toString() . " -> " . $instance->path . "\n";
|
||||
$homeFound = true;
|
||||
}
|
||||
}
|
||||
if (!$homeFound) {
|
||||
echo " HOME ROUTE NOT FOUND in discovery results\n";
|
||||
}
|
||||
} else {
|
||||
echo "DEBUG: No routes found in registry\n";
|
||||
}
|
||||
|
||||
echo "DEBUG: Total discovery items: " . count($registry) . "\n";
|
||||
} else {
|
||||
echo "DEBUG: DiscoveryRegistry is NOT available in container\n";
|
||||
}
|
||||
|
||||
echo "DEBUG: Debug complete\n";
|
||||
87
scripts/debug/debug-contexts.php
Normal file
87
scripts/debug/debug-contexts.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Attributes\Route;
|
||||
use App\Framework\Core\AppBootstrapper;
|
||||
use App\Framework\Discovery\Results\DiscoveryRegistry;
|
||||
use App\Framework\Performance\EnhancedPerformanceCollector;
|
||||
use App\Framework\DateTime\SystemClock;
|
||||
use App\Framework\DateTime\SystemHighResolutionClock;
|
||||
use App\Framework\Performance\MemoryMonitor;
|
||||
use App\Framework\DI\Initializer;
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
require __DIR__ . '/src/Framework/Debug/helpers.php';
|
||||
|
||||
echo "DEBUG: Starting context analysis\n";
|
||||
|
||||
// Create dependencies for enhanced performance collector
|
||||
$basePath = __DIR__;
|
||||
$clock = new SystemClock();
|
||||
$highResClock = new SystemHighResolutionClock();
|
||||
$memoryMonitor = new MemoryMonitor();
|
||||
$collector = new EnhancedPerformanceCollector($clock, $highResClock, $memoryMonitor, enabled: true);
|
||||
|
||||
echo "DEBUG: About to create AppBootstrapper\n";
|
||||
$bootstrapper = new AppBootstrapper($basePath, $collector, $memoryMonitor);
|
||||
|
||||
echo "DEBUG: About to bootstrap web app\n";
|
||||
$app = $bootstrapper->bootstrapWeb();
|
||||
|
||||
echo "DEBUG: Web app bootstrapped successfully\n";
|
||||
|
||||
// Get container from the app
|
||||
$reflection = new ReflectionObject($app);
|
||||
$containerProperty = $reflection->getProperty('container');
|
||||
$containerProperty->setAccessible(true);
|
||||
$container = $containerProperty->getValue($app);
|
||||
|
||||
echo "DEBUG: Got container from app\n";
|
||||
|
||||
// Check if DiscoveryRegistry is available
|
||||
if ($container->has(DiscoveryRegistry::class)) {
|
||||
echo "DEBUG: DiscoveryRegistry is available in container\n";
|
||||
$registry = $container->get(DiscoveryRegistry::class);
|
||||
|
||||
$initializerCount = $registry->attributes->getCount(Initializer::class);
|
||||
echo "DEBUG: Found $initializerCount initializer attributes in registry\n";
|
||||
|
||||
if ($initializerCount > 0) {
|
||||
$initializers = $registry->attributes->get(Initializer::class);
|
||||
echo "DEBUG: Looking for router-related initializers\n";
|
||||
|
||||
foreach ($initializers as $initializer) {
|
||||
$className = $initializer->className->getFullyQualified();
|
||||
|
||||
if (str_contains($className, 'Router') || str_contains($className, 'Route')) {
|
||||
echo " ROUTER INITIALIZER: $className\n";
|
||||
|
||||
// Get the attribute instance to see the contexts
|
||||
$attributeInstance = $initializer->createAttributeInstance();
|
||||
if ($attributeInstance instanceof \App\Framework\DI\Initializer) {
|
||||
$contexts = $attributeInstance->contexts;
|
||||
if (empty($contexts)) {
|
||||
echo " CONTEXTS: ALL (no restrictions)\n";
|
||||
} else {
|
||||
$contextNames = array_map(function($ctx) {
|
||||
return $ctx instanceof \App\Framework\Context\ContextType ? $ctx->name : (string)$ctx;
|
||||
}, $contexts);
|
||||
echo " CONTEXTS: " . implode(', ', $contextNames) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Check additionalData for debugging
|
||||
if (isset($initializer->additionalData['contexts'])) {
|
||||
echo " STORED CONTEXTS: " . print_r($initializer->additionalData['contexts'], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
echo "DEBUG: No initializers found in registry\n";
|
||||
}
|
||||
} else {
|
||||
echo "DEBUG: DiscoveryRegistry is NOT available in container\n";
|
||||
}
|
||||
|
||||
echo "DEBUG: Context analysis complete\n";
|
||||
94
scripts/debug/debug_console_init.php
Normal file
94
scripts/debug/debug_console_init.php
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use App\Framework\Core\AppBootstrapper;
|
||||
use App\Framework\Performance\EnhancedPerformanceCollector;
|
||||
use App\Framework\DateTime\SystemClock;
|
||||
use App\Framework\DateTime\SystemHighResolutionClock;
|
||||
use App\Framework\Performance\MemoryMonitor;
|
||||
use App\Framework\Discovery\Results\DiscoveryRegistry;
|
||||
use App\Framework\Console\ConsoleApplication;
|
||||
|
||||
try {
|
||||
echo "1. Creating performance collector..." . PHP_EOL;
|
||||
$clock = new SystemClock();
|
||||
$highResClock = new SystemHighResolutionClock();
|
||||
$memoryMonitor = new MemoryMonitor();
|
||||
$collector = new EnhancedPerformanceCollector($clock, $highResClock, $memoryMonitor, enabled: false);
|
||||
|
||||
echo "2. Creating bootstrapper..." . PHP_EOL;
|
||||
$bootstrapper = new AppBootstrapper(__DIR__, $collector, $memoryMonitor);
|
||||
|
||||
echo "3. Bootstrapping console..." . PHP_EOL;
|
||||
$consoleApp = $bootstrapper->bootstrapConsole();
|
||||
|
||||
echo "4. Getting container from console app..." . PHP_EOL;
|
||||
$reflection = new ReflectionClass($consoleApp);
|
||||
$containerProperty = $reflection->getProperty('container');
|
||||
$containerProperty->setAccessible(true);
|
||||
$container = $containerProperty->getValue($consoleApp);
|
||||
|
||||
echo "5. Checking if DiscoveryRegistry is in container..." . PHP_EOL;
|
||||
$hasDiscoveryRegistry = $container->has(DiscoveryRegistry::class);
|
||||
echo " DiscoveryRegistry available: " . ($hasDiscoveryRegistry ? 'YES' : 'NO') . PHP_EOL;
|
||||
|
||||
if ($hasDiscoveryRegistry) {
|
||||
echo "6. Getting DiscoveryRegistry..." . PHP_EOL;
|
||||
$discoveryRegistry = $container->get(DiscoveryRegistry::class);
|
||||
echo " DiscoveryRegistry type: " . get_class($discoveryRegistry) . PHP_EOL;
|
||||
echo " Total attributes: " . $discoveryRegistry->attributes->count() . PHP_EOL;
|
||||
|
||||
// Show all discovered attribute types
|
||||
$allTypes = $discoveryRegistry->attributes->getAllTypes();
|
||||
echo " All discovered attribute types: " . implode(', ', $allTypes) . PHP_EOL;
|
||||
|
||||
$commands = $discoveryRegistry->attributes->get(\App\Framework\Console\ConsoleCommand::class);
|
||||
echo " ConsoleCommand attributes: " . count($commands) . PHP_EOL;
|
||||
|
||||
if (count($commands) > 0) {
|
||||
foreach (array_slice($commands, 0, 5) as $discovered) {
|
||||
$methodName = $discovered->methodName ? $discovered->methodName->toString() : '__invoke';
|
||||
echo " - " . $discovered->className->getFullyQualified() . "::" . $methodName . PHP_EOL;
|
||||
$command = $discovered->createAttributeInstance();
|
||||
echo " Command: " . $command->name . PHP_EOL;
|
||||
}
|
||||
} else {
|
||||
echo " No ConsoleCommand attributes found!" . PHP_EOL;
|
||||
echo " This suggests ConsoleCommandMapper is not included or working properly" . PHP_EOL;
|
||||
}
|
||||
} else {
|
||||
echo "6. DiscoveryRegistry NOT found in container!" . PHP_EOL;
|
||||
}
|
||||
|
||||
echo "7. Checking ConsoleApplication's command registry..." . PHP_EOL;
|
||||
$registryProperty = $reflection->getProperty('commandRegistry');
|
||||
$registryProperty->setAccessible(true);
|
||||
$commandRegistry = $registryProperty->getValue($consoleApp);
|
||||
|
||||
if ($commandRegistry === null) {
|
||||
echo " CommandRegistry is NULL!" . PHP_EOL;
|
||||
echo " This means initializeCommandRegistry was never called or failed" . PHP_EOL;
|
||||
} else {
|
||||
echo " CommandRegistry type: " . get_class($commandRegistry) . PHP_EOL;
|
||||
|
||||
// Try to get the command list from the registry
|
||||
$commandRegistryReflection = new ReflectionClass($commandRegistry);
|
||||
$commandListProperty = $commandRegistryReflection->getProperty('commandList');
|
||||
$commandListProperty->setAccessible(true);
|
||||
$commandList = $commandListProperty->getValue($commandRegistry);
|
||||
|
||||
if ($commandList === null) {
|
||||
echo " CommandList is NULL in CommandRegistry!" . PHP_EOL;
|
||||
} else {
|
||||
echo " CommandList type: " . get_class($commandList) . PHP_EOL;
|
||||
echo " Command count: " . $commandList->count() . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "Error: " . $e->getMessage() . PHP_EOL;
|
||||
echo "Stack trace: " . $e->getTraceAsString() . PHP_EOL;
|
||||
}
|
||||
57
scripts/debug/debug_initializers.php
Normal file
57
scripts/debug/debug_initializers.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use App\Framework\Core\AppBootstrapper;
|
||||
use App\Framework\Performance\EnhancedPerformanceCollector;
|
||||
use App\Framework\DateTime\SystemClock;
|
||||
use App\Framework\DateTime\SystemHighResolutionClock;
|
||||
use App\Framework\Performance\MemoryMonitor;
|
||||
|
||||
echo "Testing Queue Initializer Discovery...\n\n";
|
||||
|
||||
try {
|
||||
// Create dependencies for enhanced performance collector
|
||||
$clock = new SystemClock();
|
||||
$highResClock = new SystemHighResolutionClock();
|
||||
$memoryMonitor = new MemoryMonitor();
|
||||
$collector = new EnhancedPerformanceCollector($clock, $highResClock, $memoryMonitor, enabled: false);
|
||||
|
||||
// Bootstrap the framework
|
||||
$bootstrapper = new AppBootstrapper(__DIR__, $collector, $memoryMonitor);
|
||||
$container = $bootstrapper->bootstrapWorker();
|
||||
|
||||
echo "Framework bootstrapped successfully.\n";
|
||||
|
||||
// Check if Queue services are available
|
||||
$services = [
|
||||
'App\Framework\Queue\Interfaces\DistributedLockInterface',
|
||||
'App\Framework\Queue\Services\WorkerRegistry',
|
||||
'App\Framework\Queue\Services\JobDistributionService',
|
||||
'App\Framework\Queue\Services\WorkerHealthCheckService',
|
||||
'App\Framework\Queue\Services\FailoverRecoveryService',
|
||||
'App\Framework\Queue\Contracts\JobProgressTrackerInterface',
|
||||
'App\Framework\Queue\Contracts\DeadLetterQueueInterface',
|
||||
'App\Framework\Queue\Services\JobMetricsManagerInterface',
|
||||
'App\Framework\Queue\Contracts\JobDependencyManagerInterface'
|
||||
];
|
||||
|
||||
echo "\nChecking Queue service registrations:\n";
|
||||
echo str_repeat("=", 50) . "\n";
|
||||
|
||||
foreach ($services as $service) {
|
||||
if ($container->has($service)) {
|
||||
echo "✅ {$service} - REGISTERED\n";
|
||||
} else {
|
||||
echo "❌ {$service} - NOT REGISTERED\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "\nTotal container bindings: " . count($container->getBindings()) . "\n";
|
||||
|
||||
} catch (Throwable $e) {
|
||||
echo "Error: " . $e->getMessage() . "\n";
|
||||
echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n";
|
||||
}
|
||||
263
scripts/debug/debug_live_tui.php
Normal file
263
scripts/debug/debug_live_tui.php
Normal file
@@ -0,0 +1,263 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
// Live debug version of TUI that shows what's happening
|
||||
use App\Framework\Console\Components\TuiState;
|
||||
use App\Framework\Console\Components\TuiInputHandler;
|
||||
use App\Framework\Console\Components\TuiCommandExecutor;
|
||||
use App\Framework\Console\Components\TuiRenderer;
|
||||
use App\Framework\Console\CommandHistory;
|
||||
use App\Framework\Console\CommandGroupRegistry;
|
||||
use App\Framework\Console\SimpleWorkflowExecutor;
|
||||
use App\Framework\Console\TuiView;
|
||||
use App\Framework\Console\TuiKeyCode;
|
||||
use App\Framework\Console\ConsoleOutput;
|
||||
use App\Framework\Console\ConsoleColor;
|
||||
use App\Framework\Console\Screen\ScreenManager;
|
||||
use App\Framework\Console\Screen\ScreenControlCode;
|
||||
use App\Framework\Console\Screen\CursorControlCode;
|
||||
use App\Framework\Discovery\Results\DiscoveryRegistry;
|
||||
use App\Framework\DI\Container;
|
||||
|
||||
echo "Live TUI Debug Session\n";
|
||||
echo "======================\n\n";
|
||||
|
||||
// Check TTY
|
||||
if (!posix_isatty(STDIN)) {
|
||||
echo "❌ Requires TTY. Run with: docker exec -it php php debug_live_tui.php\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo "✓ TTY available\n";
|
||||
|
||||
// Check PHPStorm
|
||||
$isPhpStorm = getenv('TERMINAL_EMULATOR') === 'JetBrains-JediTerm';
|
||||
echo "✓ PHPStorm detected: " . ($isPhpStorm ? "YES" : "NO") . "\n\n";
|
||||
|
||||
try {
|
||||
// Create minimal dependencies
|
||||
$container = new \App\Framework\DI\DefaultContainer();
|
||||
|
||||
$discoveryRegistry = new class implements DiscoveryRegistry {
|
||||
public function interfaces() {
|
||||
return new class { public function get(string $interface) { return []; } };
|
||||
}
|
||||
public function attributes() {
|
||||
return new class { public function get(string $attributeClass) { return []; } };
|
||||
}
|
||||
};
|
||||
|
||||
// Debug command executor
|
||||
$debugExecutor = new class implements TuiCommandExecutor {
|
||||
public function executeSelectedCommand(object $command): void {
|
||||
echo "\n🚀 EXECUTE: Selected command\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function executeCommand(string $commandName): void {
|
||||
echo "\n🚀 EXECUTE: $commandName\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function validateSelectedCommand(object $command): void {
|
||||
echo "\n✓ VALIDATE: Selected command\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function validateCommand(string $commandName): void {
|
||||
echo "\n✓ VALIDATE: $commandName\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function showSelectedCommandHelp(object $command): void {
|
||||
echo "\n📚 HELP: Selected command\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function showCommandHelp(string $commandName): void {
|
||||
echo "\n📚 HELP: $commandName\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function showAllCommandsHelp(): void {
|
||||
echo "\n📚 HELP: All commands\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function startInteractiveForm(object $command, \App\Framework\Console\Components\TuiState $state): void {
|
||||
echo "\n📝 FORM: Start interactive form\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function findCommandObject(string $commandName): ?object {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
$workflowExecutor = new class implements SimpleWorkflowExecutor {
|
||||
public function executeWorkflow(array $workflow, \App\Framework\Console\Components\TuiState $state): void {
|
||||
echo "\n🔄 WORKFLOW: Execute\n";
|
||||
sleep(1);
|
||||
}
|
||||
};
|
||||
|
||||
// Create output with debug info
|
||||
$output = new class extends ConsoleOutput {
|
||||
public function writeLine(string $line = '', ?ConsoleColor $color = null): void {
|
||||
// Show debug info for navigation updates
|
||||
if (str_contains($line, '▶')) {
|
||||
echo "\n[DEBUG] Navigation update detected: $line\n";
|
||||
}
|
||||
parent::writeLine($line, $color);
|
||||
}
|
||||
};
|
||||
|
||||
$output->screen = new ScreenManager($output);
|
||||
|
||||
// Custom TUI state with debug
|
||||
$debugState = new class extends TuiState {
|
||||
public function setSelectedCategory(int $index): void {
|
||||
$oldIndex = $this->getSelectedCategory();
|
||||
parent::setSelectedCategory($index);
|
||||
$newIndex = $this->getSelectedCategory();
|
||||
echo "\n[DEBUG] Category changed: $oldIndex → $newIndex\n";
|
||||
}
|
||||
|
||||
public function navigateUp(): void {
|
||||
echo "\n[DEBUG] navigateUp() called\n";
|
||||
$before = $this->getSelectedCategory();
|
||||
parent::navigateUp();
|
||||
$after = $this->getSelectedCategory();
|
||||
echo "[DEBUG] navigateUp result: $before → $after\n";
|
||||
}
|
||||
|
||||
public function navigateDown(): void {
|
||||
echo "\n[DEBUG] navigateDown() called\n";
|
||||
$before = $this->getSelectedCategory();
|
||||
parent::navigateDown();
|
||||
$after = $this->getSelectedCategory();
|
||||
echo "[DEBUG] navigateDown result: $before → $after\n";
|
||||
}
|
||||
};
|
||||
|
||||
// Custom input handler with debug
|
||||
$debugInputHandler = new class($debugExecutor) extends TuiInputHandler {
|
||||
public function handleInput(string $key, \App\Framework\Console\Components\TuiState $state, \App\Framework\Console\CommandHistory $history): void {
|
||||
$keyHex = bin2hex($key);
|
||||
$keyDesc = match($key) {
|
||||
"\033[A" => "ARROW_UP",
|
||||
"\033[B" => "ARROW_DOWN",
|
||||
"\033[C" => "ARROW_RIGHT",
|
||||
"\033[D" => "ARROW_LEFT",
|
||||
"\n" => "ENTER",
|
||||
" " => "SPACE",
|
||||
"\033" => "ESC",
|
||||
'q' => "Q",
|
||||
default => "OTHER($key)"
|
||||
};
|
||||
|
||||
echo "\n[DEBUG] INPUT: '$keyDesc' (hex: $keyHex) in view: " . $state->getCurrentView()->name . "\n";
|
||||
|
||||
parent::handleInput($key, $state, $history);
|
||||
|
||||
echo "[DEBUG] After input - Selected: " . $state->getSelectedCategory() . "\n";
|
||||
}
|
||||
};
|
||||
|
||||
$state = $debugState;
|
||||
$history = new CommandHistory();
|
||||
$inputHandler = $debugInputHandler;
|
||||
$renderer = new TuiRenderer($output);
|
||||
$groupRegistry = new CommandGroupRegistry($discoveryRegistry);
|
||||
|
||||
// Add test categories
|
||||
$testCategories = [
|
||||
['name' => 'Testing', 'description' => 'Test commands', 'icon' => '🧪', 'commands' => []],
|
||||
['name' => 'Demo', 'description' => 'Demo commands', 'icon' => '🎮', 'commands' => []],
|
||||
['name' => 'Generator', 'description' => 'Code generation', 'icon' => '⚙️', 'commands' => []],
|
||||
['name' => 'General', 'description' => 'General commands', 'icon' => '📂', 'commands' => []]
|
||||
];
|
||||
|
||||
$state->setCategories($testCategories);
|
||||
$state->setCurrentView(TuiView::CATEGORIES);
|
||||
$state->setRunning(true);
|
||||
|
||||
echo "✓ Debug TUI components ready\n";
|
||||
echo "Categories: " . count($testCategories) . "\n";
|
||||
echo "Selected: " . $state->getSelectedCategory() . "\n\n";
|
||||
|
||||
// Save terminal settings
|
||||
$originalSettings = trim(shell_exec('stty -g') ?: '');
|
||||
|
||||
// Set up terminal
|
||||
if ($isPhpStorm) {
|
||||
shell_exec('stty raw -echo min 1 time 0 2>/dev/null');
|
||||
} else {
|
||||
shell_exec('stty -icanon -echo 2>/dev/null');
|
||||
}
|
||||
|
||||
// Hide cursor
|
||||
echo CursorControlCode::HIDE->format();
|
||||
|
||||
echo "🚀 LIVE DEBUG TUI STARTED\n";
|
||||
echo "Use arrow keys to test navigation.\n";
|
||||
echo "Press 'q' to quit.\n";
|
||||
echo "All navigation events will be logged below.\n\n";
|
||||
|
||||
// Simple TUI loop with debug
|
||||
while ($state->isRunning()) {
|
||||
// Clear and render
|
||||
echo ScreenControlCode::CLEAR_ALL->format();
|
||||
echo CursorControlCode::POSITION->format(1, 1);
|
||||
|
||||
// Render current state
|
||||
$renderer->render($state, $history);
|
||||
|
||||
// Show debug info at bottom
|
||||
echo "\n" . str_repeat('=', 60) . "\n";
|
||||
echo "DEBUG INFO:\n";
|
||||
echo "Selected Category: " . $state->getSelectedCategory() . "\n";
|
||||
echo "Current View: " . $state->getCurrentView()->name . "\n";
|
||||
$category = $state->getCurrentCategory();
|
||||
echo "Category Name: " . ($category ? $category['name'] : 'NULL') . "\n";
|
||||
echo "Press arrow keys to test navigation...\n";
|
||||
|
||||
// Read input with PHPStorm-compatible method
|
||||
$key = fgetc(STDIN);
|
||||
if ($key === false) continue;
|
||||
|
||||
if ($key === "\033") {
|
||||
$sequence = $key;
|
||||
stream_set_blocking(STDIN, false);
|
||||
$next = fgetc(STDIN);
|
||||
if ($next === false) {
|
||||
usleep(10000);
|
||||
$next = fgetc(STDIN);
|
||||
}
|
||||
if ($next !== false) {
|
||||
$sequence .= $next;
|
||||
if ($next === '[') {
|
||||
$third = fgetc(STDIN);
|
||||
if ($third === false) {
|
||||
usleep(10000);
|
||||
$third = fgetc(STDIN);
|
||||
}
|
||||
if ($third !== false) {
|
||||
$sequence .= $third;
|
||||
}
|
||||
}
|
||||
}
|
||||
stream_set_blocking(STDIN, true);
|
||||
$key = $sequence;
|
||||
}
|
||||
|
||||
if ($key === 'q' || $key === 'Q') {
|
||||
$state->setRunning(false);
|
||||
break;
|
||||
}
|
||||
|
||||
// Process input
|
||||
$inputHandler->handleInput($key, $state, $history);
|
||||
}
|
||||
|
||||
} finally {
|
||||
// Restore terminal
|
||||
echo CursorControlCode::SHOW->format();
|
||||
if (!empty($originalSettings)) {
|
||||
shell_exec("stty $originalSettings 2>/dev/null");
|
||||
}
|
||||
echo "\n✓ Debug TUI session ended\n";
|
||||
}
|
||||
99
scripts/debug/debug_make_console.php
Normal file
99
scripts/debug/debug_make_console.php
Normal file
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use App\Framework\Core\AppBootstrapper;
|
||||
use App\Framework\Performance\EnhancedPerformanceCollector;
|
||||
use App\Framework\DateTime\SystemClock;
|
||||
use App\Framework\DateTime\SystemHighResolutionClock;
|
||||
use App\Framework\Performance\MemoryMonitor;
|
||||
use App\Framework\Discovery\Results\DiscoveryRegistry;
|
||||
use App\Framework\Console\ConsoleCommand;
|
||||
use App\Framework\Context\ExecutionContext;
|
||||
|
||||
echo "=== Debug: Make Console Issue ===" . PHP_EOL;
|
||||
echo "Current environment:" . PHP_EOL;
|
||||
echo " TERM: " . ($_SERVER['TERM'] ?? 'not set') . PHP_EOL;
|
||||
echo " STDIN: " . (stream_isatty(STDIN) ? 'TTY' : 'not TTY') . PHP_EOL;
|
||||
echo " STDOUT: " . (stream_isatty(STDOUT) ? 'TTY' : 'not TTY') . PHP_EOL;
|
||||
echo " argv[0]: " . ($_SERVER['argv'][0] ?? 'not set') . PHP_EOL;
|
||||
echo " Command line: " . implode(' ', $_SERVER['argv'] ?? []) . PHP_EOL;
|
||||
|
||||
try {
|
||||
echo "1. Creating components..." . PHP_EOL;
|
||||
$clock = new SystemClock();
|
||||
$highResClock = new SystemHighResolutionClock();
|
||||
$memoryMonitor = new MemoryMonitor();
|
||||
$collector = new EnhancedPerformanceCollector($clock, $highResClock, $memoryMonitor, enabled: false);
|
||||
$bootstrapper = new AppBootstrapper(__DIR__, $collector, $memoryMonitor);
|
||||
|
||||
echo "2. Detecting execution context..." . PHP_EOL;
|
||||
$context = ExecutionContext::detect();
|
||||
echo " Context type: " . $context->getType()->value . PHP_EOL;
|
||||
|
||||
echo "3. Bootstrapping console..." . PHP_EOL;
|
||||
$consoleApp = $bootstrapper->bootstrapConsole();
|
||||
|
||||
echo "4. Getting container..." . PHP_EOL;
|
||||
$reflection = new ReflectionClass($consoleApp);
|
||||
$containerProperty = $reflection->getProperty('container');
|
||||
$containerProperty->setAccessible(true);
|
||||
$container = $containerProperty->getValue($consoleApp);
|
||||
|
||||
echo "5. Checking DiscoveryRegistry..." . PHP_EOL;
|
||||
if ($container->has(DiscoveryRegistry::class)) {
|
||||
$discoveryRegistry = $container->get(DiscoveryRegistry::class);
|
||||
$commands = $discoveryRegistry->attributes->get(ConsoleCommand::class);
|
||||
echo " ConsoleCommand attributes: " . count($commands) . PHP_EOL;
|
||||
|
||||
if (count($commands) > 0) {
|
||||
echo " First 3 commands:" . PHP_EOL;
|
||||
foreach (array_slice($commands, 0, 3) as $discovered) {
|
||||
$command = $discovered->createAttributeInstance();
|
||||
echo " - " . $command->name . PHP_EOL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
echo " DiscoveryRegistry NOT found!" . PHP_EOL;
|
||||
}
|
||||
|
||||
echo "6. Checking CommandRegistry..." . PHP_EOL;
|
||||
$registryProperty = $reflection->getProperty('commandRegistry');
|
||||
$registryProperty->setAccessible(true);
|
||||
$commandRegistry = $registryProperty->getValue($consoleApp);
|
||||
|
||||
if ($commandRegistry) {
|
||||
$commandRegistryReflection = new ReflectionClass($commandRegistry);
|
||||
$commandListProperty = $commandRegistryReflection->getProperty('commandList');
|
||||
$commandListProperty->setAccessible(true);
|
||||
$commandList = $commandListProperty->getValue($commandRegistry);
|
||||
|
||||
if ($commandList) {
|
||||
echo " CommandList count: " . $commandList->count() . PHP_EOL;
|
||||
} else {
|
||||
echo " CommandList is NULL!" . PHP_EOL;
|
||||
}
|
||||
} else {
|
||||
echo " CommandRegistry is NULL!" . PHP_EOL;
|
||||
}
|
||||
|
||||
echo "7. Cache key analysis..." . PHP_EOL;
|
||||
$pathProvider = $container->get(\App\Framework\Core\PathProvider::class);
|
||||
$currentContext = ExecutionContext::detect();
|
||||
$contextString = $currentContext->getType()->value;
|
||||
$defaultPaths = [$pathProvider->getSourcePath()];
|
||||
|
||||
echo " Context: " . $contextString . PHP_EOL;
|
||||
echo " Paths: " . implode(', ', $defaultPaths) . PHP_EOL;
|
||||
|
||||
// Generate cache key as it would be done in DiscoveryServiceBootstrapper
|
||||
$pathsHash = md5(implode('|', $defaultPaths));
|
||||
$cacheKey = "discovery:full_{$pathsHash}_{$contextString}";
|
||||
echo " Expected cache key: " . $cacheKey . PHP_EOL;
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "Error: " . $e->getMessage() . PHP_EOL;
|
||||
echo "Stack trace: " . $e->getTraceAsString() . PHP_EOL;
|
||||
}
|
||||
40
scripts/debug/debug_mapper_config.php
Normal file
40
scripts/debug/debug_mapper_config.php
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use App\Framework\Console\ConsoleCommandMapper;
|
||||
use App\Framework\Console\ConsoleCommand;
|
||||
use App\Framework\Console\DemoCommand;
|
||||
use App\Framework\Reflection\WrappedReflectionMethod;
|
||||
|
||||
echo "Testing ConsoleCommandMapper..." . PHP_EOL;
|
||||
|
||||
try {
|
||||
$mapper = new ConsoleCommandMapper();
|
||||
|
||||
// Test the mapper configuration
|
||||
echo "Mapper attribute class: " . $mapper->getAttributeClass() . PHP_EOL;
|
||||
echo "ConsoleCommand class: " . ConsoleCommand::class . PHP_EOL;
|
||||
echo "Classes match: " . ($mapper->getAttributeClass() === ConsoleCommand::class ? 'YES' : 'NO') . PHP_EOL;
|
||||
|
||||
// Test with a real method
|
||||
$reflector = new ReflectionClass(DemoCommand::class);
|
||||
$method = $reflector->getMethod('hello');
|
||||
$attributes = $method->getAttributes(ConsoleCommand::class);
|
||||
|
||||
if (!empty($attributes)) {
|
||||
$attribute = $attributes[0]->newInstance();
|
||||
echo "Attribute found: " . $attribute->name . PHP_EOL;
|
||||
|
||||
// This would require complex setup, just test the basic mapping
|
||||
echo "Basic mapper test passed!" . PHP_EOL;
|
||||
} else {
|
||||
echo "No attributes found on hello method!" . PHP_EOL;
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "Error: " . $e->getMessage() . PHP_EOL;
|
||||
echo "Trace: " . $e->getTraceAsString() . PHP_EOL;
|
||||
}
|
||||
167
scripts/debug/debug_navigation.php
Normal file
167
scripts/debug/debug_navigation.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
// Debug navigation issue
|
||||
use App\Framework\Console\Components\TuiState;
|
||||
use App\Framework\Console\Components\TuiInputHandler;
|
||||
use App\Framework\Console\Components\TuiCommandExecutor;
|
||||
use App\Framework\Console\CommandHistory;
|
||||
use App\Framework\Console\TuiView;
|
||||
use App\Framework\Console\TuiKeyCode;
|
||||
|
||||
echo "Debugging TUI Navigation Issue...\n";
|
||||
echo "=================================\n\n";
|
||||
|
||||
try {
|
||||
// Create mock executor
|
||||
$mockExecutor = new class implements \App\Framework\Console\Components\TuiCommandExecutor {
|
||||
public function executeSelectedCommand(object $command): void {
|
||||
echo "Mock: Execute command\n";
|
||||
}
|
||||
public function executeCommand(string $commandName): void {
|
||||
echo "Mock: Execute command: $commandName\n";
|
||||
}
|
||||
public function validateSelectedCommand(object $command): void {
|
||||
echo "Mock: Validate command\n";
|
||||
}
|
||||
public function validateCommand(string $commandName): void {
|
||||
echo "Mock: Validate command: $commandName\n";
|
||||
}
|
||||
public function showSelectedCommandHelp(object $command): void {
|
||||
echo "Mock: Show help\n";
|
||||
}
|
||||
public function showCommandHelp(string $commandName): void {
|
||||
echo "Mock: Show help: $commandName\n";
|
||||
}
|
||||
public function showAllCommandsHelp(): void {
|
||||
echo "Mock: Show all commands help\n";
|
||||
}
|
||||
public function startInteractiveForm(object $command, \App\Framework\Console\Components\TuiState $state): void {
|
||||
echo "Mock: Start form\n";
|
||||
}
|
||||
public function findCommandObject(string $commandName): ?object {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
$state = new TuiState();
|
||||
$history = new CommandHistory();
|
||||
$inputHandler = new TuiInputHandler($mockExecutor);
|
||||
|
||||
// Setup realistic test categories like in real TUI
|
||||
$categories = [
|
||||
0 => [
|
||||
'name' => 'Database',
|
||||
'description' => 'Database commands',
|
||||
'icon' => '🗄️',
|
||||
'commands' => [],
|
||||
'priority' => 100
|
||||
],
|
||||
1 => [
|
||||
'name' => 'Cache',
|
||||
'description' => 'Cache commands',
|
||||
'icon' => '⚡',
|
||||
'commands' => [],
|
||||
'priority' => 90
|
||||
],
|
||||
2 => [
|
||||
'name' => 'Testing',
|
||||
'description' => 'Testing commands',
|
||||
'icon' => '🧪',
|
||||
'commands' => [],
|
||||
'priority' => 80
|
||||
],
|
||||
3 => [
|
||||
'name' => 'MCP',
|
||||
'description' => 'MCP commands',
|
||||
'icon' => '🤖',
|
||||
'commands' => [],
|
||||
'priority' => 70
|
||||
]
|
||||
];
|
||||
|
||||
$state->setCategories($categories);
|
||||
$state->setCurrentView(TuiView::CATEGORIES);
|
||||
$state->setRunning(true);
|
||||
|
||||
echo "✓ Initial Setup:\n";
|
||||
echo " Categories: " . count($categories) . "\n";
|
||||
echo " Current View: " . $state->getCurrentView()->name . "\n";
|
||||
echo " Selected Category: " . $state->getSelectedCategory() . "\n";
|
||||
echo " Category Name: '{$categories[$state->getSelectedCategory()]['name']}'\n\n";
|
||||
|
||||
// Test step-by-step navigation
|
||||
echo "🔍 Testing Navigation Step-by-Step:\n\n";
|
||||
|
||||
// Test 1: Arrow Down
|
||||
echo "Test 1: Arrow DOWN\n";
|
||||
echo " Before: Category {$state->getSelectedCategory()} ('{$categories[$state->getSelectedCategory()]['name']}')\n";
|
||||
echo " Input Key: '" . TuiKeyCode::ARROW_DOWN->value . "' (hex: " . bin2hex(TuiKeyCode::ARROW_DOWN->value) . ")\n";
|
||||
|
||||
$inputHandler->handleInput(TuiKeyCode::ARROW_DOWN->value, $state, $history);
|
||||
|
||||
echo " After: Category {$state->getSelectedCategory()} ('{$categories[$state->getSelectedCategory()]['name']}')\n";
|
||||
echo " ✓ Expected: Should move from Database (0) to Cache (1)\n\n";
|
||||
|
||||
// Test 2: Arrow Down again
|
||||
echo "Test 2: Arrow DOWN again\n";
|
||||
echo " Before: Category {$state->getSelectedCategory()} ('{$categories[$state->getSelectedCategory()]['name']}')\n";
|
||||
|
||||
$inputHandler->handleInput(TuiKeyCode::ARROW_DOWN->value, $state, $history);
|
||||
|
||||
echo " After: Category {$state->getSelectedCategory()} ('{$categories[$state->getSelectedCategory()]['name']}')\n";
|
||||
echo " ✓ Expected: Should move from Cache (1) to Testing (2)\n\n";
|
||||
|
||||
// Test 3: Arrow Up
|
||||
echo "Test 3: Arrow UP\n";
|
||||
echo " Before: Category {$state->getSelectedCategory()} ('{$categories[$state->getSelectedCategory()]['name']}')\n";
|
||||
|
||||
$inputHandler->handleInput(TuiKeyCode::ARROW_UP->value, $state, $history);
|
||||
|
||||
echo " After: Category {$state->getSelectedCategory()} ('{$categories[$state->getSelectedCategory()]['name']}')\n";
|
||||
echo " ✓ Expected: Should move from Testing (2) to Cache (1)\n\n";
|
||||
|
||||
// Test 4: Boundary testing - go to end
|
||||
echo "Test 4: Go to last category and test boundary\n";
|
||||
$state->setSelectedCategory(3); // MCP
|
||||
echo " Set to: Category {$state->getSelectedCategory()} ('{$categories[$state->getSelectedCategory()]['name']}')\n";
|
||||
|
||||
$inputHandler->handleInput(TuiKeyCode::ARROW_DOWN->value, $state, $history);
|
||||
|
||||
echo " After Arrow DOWN: Category {$state->getSelectedCategory()} ('{$categories[$state->getSelectedCategory()]['name']}')\n";
|
||||
echo " ✓ Expected: Should stay at MCP (3) - boundary protection\n\n";
|
||||
|
||||
// Test 5: Boundary testing - go to beginning
|
||||
echo "Test 5: Go to first category and test boundary\n";
|
||||
$state->setSelectedCategory(0); // Database
|
||||
echo " Set to: Category {$state->getSelectedCategory()} ('{$categories[$state->getSelectedCategory()]['name']}')\n";
|
||||
|
||||
$inputHandler->handleInput(TuiKeyCode::ARROW_UP->value, $state, $history);
|
||||
|
||||
echo " After Arrow UP: Category {$state->getSelectedCategory()} ('{$categories[$state->getSelectedCategory()]['name']}')\n";
|
||||
echo " ✓ Expected: Should stay at Database (0) - boundary protection\n\n";
|
||||
|
||||
// Debug the TuiState navigation methods directly
|
||||
echo "🔍 Testing TuiState Navigation Methods Directly:\n\n";
|
||||
|
||||
echo "Direct TuiState Testing:\n";
|
||||
$state->setSelectedCategory(1); // Cache
|
||||
echo " Set to: {$state->getSelectedCategory()}\n";
|
||||
|
||||
echo " Calling navigateDown()...\n";
|
||||
$state->navigateDown();
|
||||
echo " Result: {$state->getSelectedCategory()}\n";
|
||||
|
||||
echo " Calling navigateUp()...\n";
|
||||
$state->navigateUp();
|
||||
echo " Result: {$state->getSelectedCategory()}\n\n";
|
||||
|
||||
echo "✅ Navigation Debug Test COMPLETED\n";
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
echo "\n❌ Navigation Debug Test FAILED:\n";
|
||||
echo "Error: " . $e->getMessage() . "\n";
|
||||
echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n";
|
||||
echo "\nStack trace:\n" . $e->getTraceAsString() . "\n";
|
||||
}
|
||||
80
scripts/debug/debug_navigation_issue.php
Normal file
80
scripts/debug/debug_navigation_issue.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
// Debug das TUI Navigation Problem
|
||||
use App\Framework\Console\Components\TuiState;
|
||||
use App\Framework\Console\TuiView;
|
||||
use App\Framework\Console\CommandGroupRegistry;
|
||||
use App\Framework\Discovery\Results\DiscoveryRegistry;
|
||||
|
||||
echo "=== TUI NAVIGATION DEBUG ===\n";
|
||||
|
||||
try {
|
||||
// Mock Discovery Registry
|
||||
$discoveryRegistry = new class implements DiscoveryRegistry {
|
||||
public function interfaces() {
|
||||
return new class {
|
||||
public function get(string $interface) { return []; }
|
||||
};
|
||||
}
|
||||
public function attributes() {
|
||||
return new class {
|
||||
public function get(string $attributeClass) { return []; }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
$groupRegistry = new CommandGroupRegistry($discoveryRegistry);
|
||||
$categories = $groupRegistry->getOrganizedCommands();
|
||||
|
||||
echo "📊 Categories loaded: " . count($categories) . "\n";
|
||||
foreach ($categories as $index => $category) {
|
||||
echo " [$index] {$category['name']} - Commands: " . count($category['commands']) . "\n";
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
// Test TuiState Navigation
|
||||
$state = new TuiState();
|
||||
$state->setCategories($categories);
|
||||
$state->setCurrentView(TuiView::CATEGORIES);
|
||||
|
||||
echo "🔍 Initial TUI State:\n";
|
||||
echo " Selected Category: " . $state->getSelectedCategory() . "\n";
|
||||
echo " Current View: " . $state->getCurrentView()->name . "\n";
|
||||
echo " Current Category: " . ($state->getCurrentCategory()['name'] ?? 'NULL') . "\n";
|
||||
echo "\n";
|
||||
|
||||
// Test Navigation Up/Down
|
||||
echo "🧪 Testing Navigation:\n";
|
||||
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
echo "Step $i - Before navigateDown(): " . $state->getSelectedCategory() . "\n";
|
||||
$state->navigateDown();
|
||||
echo "Step $i - After navigateDown(): " . $state->getSelectedCategory() . "\n";
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
echo "Step $i - Before navigateUp(): " . $state->getSelectedCategory() . "\n";
|
||||
$state->navigateUp();
|
||||
echo "Step $i - After navigateUp(): " . $state->getSelectedCategory() . "\n";
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
|
||||
// Test Category Bounds
|
||||
echo "🎯 Testing Bounds:\n";
|
||||
$state->setSelectedCategory(99);
|
||||
echo "Set to 99, actual: " . $state->getSelectedCategory() . "\n";
|
||||
$state->setSelectedCategory(-5);
|
||||
echo "Set to -5, actual: " . $state->getSelectedCategory() . "\n";
|
||||
|
||||
echo "\n✅ Navigation logic test completed\n";
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
echo "❌ ERROR: " . $e->getMessage() . "\n";
|
||||
echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n";
|
||||
echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
|
||||
}
|
||||
171
scripts/debug/debug_real_tui.php
Normal file
171
scripts/debug/debug_real_tui.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
// Debug real TUI execution
|
||||
use App\Framework\Console\Components\ConsoleTUI;
|
||||
use App\Framework\Console\Components\TuiState;
|
||||
use App\Framework\Console\Components\TuiInputHandler;
|
||||
use App\Framework\Console\Components\TuiCommandExecutor;
|
||||
use App\Framework\Console\Components\TuiRenderer;
|
||||
use App\Framework\Console\CommandHistory;
|
||||
use App\Framework\Console\CommandGroupRegistry;
|
||||
use App\Framework\Console\SimpleWorkflowExecutor;
|
||||
use App\Framework\Console\ConsoleOutput;
|
||||
use App\Framework\Console\Screen\ScreenManager;
|
||||
use App\Framework\Discovery\Results\DiscoveryRegistry;
|
||||
use App\Framework\DI\Container;
|
||||
|
||||
echo "Debug Real TUI Execution\n";
|
||||
echo "========================\n\n";
|
||||
|
||||
// Check TTY first
|
||||
if (!posix_isatty(STDIN)) {
|
||||
echo "❌ This test requires a TTY terminal.\n";
|
||||
echo "Run with: docker exec -it php php debug_real_tui.php\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo "✓ TTY detected\n";
|
||||
|
||||
// Check stty
|
||||
if (!function_exists('shell_exec') || shell_exec('which stty') === null) {
|
||||
echo "❌ stty not available\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo "✓ stty available\n\n";
|
||||
|
||||
try {
|
||||
// Create minimal dependencies
|
||||
$container = new \App\Framework\DI\DefaultContainer();
|
||||
|
||||
// Create a minimal discovery registry
|
||||
$discoveryRegistry = new class implements DiscoveryRegistry {
|
||||
public function interfaces() {
|
||||
return new class {
|
||||
public function get(string $interface) { return []; }
|
||||
};
|
||||
}
|
||||
public function attributes() {
|
||||
return new class {
|
||||
public function get(string $attributeClass) { return []; }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Create mock command executor
|
||||
$mockExecutor = new class implements TuiCommandExecutor {
|
||||
public function executeSelectedCommand(object $command): void {
|
||||
echo "\n🚀 Mock: Execute command\n";
|
||||
}
|
||||
public function executeCommand(string $commandName): void {
|
||||
echo "\n🚀 Mock: Execute command: $commandName\n";
|
||||
}
|
||||
public function validateSelectedCommand(object $command): void {
|
||||
echo "\n✓ Mock: Validate command\n";
|
||||
}
|
||||
public function validateCommand(string $commandName): void {
|
||||
echo "\n✓ Mock: Validate command: $commandName\n";
|
||||
}
|
||||
public function showSelectedCommandHelp(object $command): void {
|
||||
echo "\n📚 Mock: Show help\n";
|
||||
}
|
||||
public function showCommandHelp(string $commandName): void {
|
||||
echo "\n📚 Mock: Show help: $commandName\n";
|
||||
}
|
||||
public function showAllCommandsHelp(): void {
|
||||
echo "\n📚 Mock: Show all commands help\n";
|
||||
}
|
||||
public function startInteractiveForm(object $command, \App\Framework\Console\Components\TuiState $state): void {
|
||||
echo "\n📝 Mock: Start form\n";
|
||||
}
|
||||
public function findCommandObject(string $commandName): ?object {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// Create workflow executor
|
||||
$workflowExecutor = new class implements SimpleWorkflowExecutor {
|
||||
public function executeWorkflow(array $workflow, \App\Framework\Console\Components\TuiState $state): void {
|
||||
echo "\n🔄 Mock: Execute workflow\n";
|
||||
}
|
||||
};
|
||||
|
||||
// Create components
|
||||
$output = new ConsoleOutput();
|
||||
$output->screen = new ScreenManager($output);
|
||||
|
||||
$state = new TuiState();
|
||||
$history = new CommandHistory();
|
||||
$inputHandler = new TuiInputHandler($mockExecutor);
|
||||
$renderer = new TuiRenderer($output);
|
||||
$groupRegistry = new CommandGroupRegistry($discoveryRegistry);
|
||||
|
||||
echo "✓ Components created\n";
|
||||
|
||||
// Test categories loading
|
||||
$categories = $groupRegistry->getOrganizedCommands();
|
||||
echo "✓ Categories loaded: " . count($categories) . "\n";
|
||||
|
||||
if (empty($categories)) {
|
||||
// Add test categories since discovery is empty
|
||||
$testCategories = [
|
||||
[
|
||||
'name' => 'Testing',
|
||||
'description' => 'Test commands',
|
||||
'icon' => '🧪',
|
||||
'priority' => 0,
|
||||
'commands' => []
|
||||
],
|
||||
[
|
||||
'name' => 'Demo',
|
||||
'description' => 'Demo commands',
|
||||
'icon' => '🎮',
|
||||
'priority' => 0,
|
||||
'commands' => []
|
||||
],
|
||||
[
|
||||
'name' => 'General',
|
||||
'description' => 'General commands',
|
||||
'icon' => '📂',
|
||||
'priority' => 0,
|
||||
'commands' => []
|
||||
]
|
||||
];
|
||||
$state->setCategories($testCategories);
|
||||
echo "✓ Test categories added: " . count($testCategories) . "\n";
|
||||
} else {
|
||||
$state->setCategories($categories);
|
||||
}
|
||||
|
||||
// Create TUI
|
||||
$tui = new ConsoleTUI(
|
||||
$output,
|
||||
$container,
|
||||
$discoveryRegistry,
|
||||
$state,
|
||||
$renderer,
|
||||
$inputHandler,
|
||||
$mockExecutor,
|
||||
$history,
|
||||
$groupRegistry,
|
||||
$workflowExecutor
|
||||
);
|
||||
|
||||
echo "✓ TUI created\n\n";
|
||||
|
||||
echo "🚀 Starting TUI...\n";
|
||||
echo "Use arrow keys to navigate, 'q' to quit.\n";
|
||||
echo "This will show if the TUI actually responds to input.\n\n";
|
||||
|
||||
// Start TUI
|
||||
$exitCode = $tui->run();
|
||||
|
||||
echo "\n✓ TUI exited with code: " . $exitCode->value . "\n";
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
echo "\n❌ ERROR: " . $e->getMessage() . "\n";
|
||||
echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n";
|
||||
echo "\nStack trace:\n" . $e->getTraceAsString() . "\n";
|
||||
}
|
||||
56
scripts/debug/debug_routes.php
Normal file
56
scripts/debug/debug_routes.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
require '/var/www/html/vendor/autoload.php';
|
||||
|
||||
use App\Framework\Discovery\DiscoveryServiceBootstrapper;
|
||||
use App\Framework\DI\DefaultContainer;
|
||||
use App\Framework\Attributes\Route;
|
||||
|
||||
try {
|
||||
echo "=== Route Discovery Diagnostic ===\n";
|
||||
|
||||
$container = new DefaultContainer();
|
||||
$bootStrapper = new DiscoveryServiceBootstrapper();
|
||||
$bootStrapper->initialize($container);
|
||||
|
||||
$registry = $container->get('App\Framework\Discovery\Results\DiscoveryRegistry');
|
||||
$routes = $registry->attributes->get(Route::class);
|
||||
|
||||
echo "Total routes found: " . count($routes) . "\n\n";
|
||||
|
||||
$adminRoutes = [];
|
||||
foreach ($routes as $route) {
|
||||
$path = $route->additionalData['path'] ?? '';
|
||||
if (str_contains($path, 'admin')) {
|
||||
$adminRoutes[] = [
|
||||
'path' => $path,
|
||||
'controller' => $route->className->getFullyQualified(),
|
||||
'method' => $route->methodName?->toString() ?? 'unknown'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
echo "Admin routes found:\n";
|
||||
foreach ($adminRoutes as $route) {
|
||||
echo " Path: {$route['path']}\n";
|
||||
echo " Controller: {$route['controller']}\n";
|
||||
echo " Method: {$route['method']}\n";
|
||||
echo " ---\n";
|
||||
}
|
||||
|
||||
// Check specifically for ShowRoutes
|
||||
echo "\nLooking for ShowRoutes controller:\n";
|
||||
foreach ($routes as $route) {
|
||||
if (str_contains($route->className->getFullyQualified(), 'ShowRoutes')) {
|
||||
echo "Found ShowRoutes route:\n";
|
||||
echo " Path: " . ($route->additionalData['path'] ?? 'unknown') . "\n";
|
||||
echo " Controller: " . $route->className->getFullyQualified() . "\n";
|
||||
echo " Method: " . ($route->methodName?->toString() ?? 'unknown') . "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "Error: " . $e->getMessage() . "\n";
|
||||
echo "Stack trace: " . $e->getTraceAsString() . "\n";
|
||||
}
|
||||
34
scripts/debug/debug_template_renderer.php
Normal file
34
scripts/debug/debug_template_renderer.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use App\Framework\Core\Application;
|
||||
use App\Framework\View\TemplateRenderer;
|
||||
|
||||
try {
|
||||
$app = new Application();
|
||||
$container = $app->getContainer();
|
||||
|
||||
$templateRenderer = $container->get(TemplateRenderer::class);
|
||||
|
||||
echo "TemplateRenderer class: " . get_class($templateRenderer) . "\n";
|
||||
echo "TemplateRenderer instance of TemplateRenderer: " . ($templateRenderer instanceof TemplateRenderer ? 'YES' : 'NO') . "\n";
|
||||
|
||||
if (method_exists($templateRenderer, 'render')) {
|
||||
echo "Has render method: YES\n";
|
||||
} else {
|
||||
echo "Has render method: NO\n";
|
||||
}
|
||||
|
||||
// Check if it's the Engine class we expect
|
||||
if (get_class($templateRenderer) === 'App\Framework\View\Engine') {
|
||||
echo "Is Engine class: YES\n";
|
||||
} else {
|
||||
echo "Is Engine class: NO\n";
|
||||
echo "Actual class: " . get_class($templateRenderer) . "\n";
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "Error: " . $e->getMessage() . "\n";
|
||||
echo "Trace: " . $e->getTraceAsString() . "\n";
|
||||
}
|
||||
219
scripts/debug/debug_tui_navigation_logic.php
Normal file
219
scripts/debug/debug_tui_navigation_logic.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
// Debug TUI navigation logic specifically
|
||||
use App\Framework\Console\Components\TuiState;
|
||||
use App\Framework\Console\Components\TuiInputHandler;
|
||||
use App\Framework\Console\Components\TuiCommandExecutor;
|
||||
use App\Framework\Console\CommandHistory;
|
||||
use App\Framework\Console\CommandGroupRegistry;
|
||||
use App\Framework\Console\TuiView;
|
||||
use App\Framework\Console\TuiKeyCode;
|
||||
use App\Framework\Discovery\Results\DiscoveryRegistry;
|
||||
|
||||
echo "Debug TUI Navigation Logic\n";
|
||||
echo "==========================\n\n";
|
||||
|
||||
try {
|
||||
// Create discovery registry that returns real-looking data
|
||||
$discoveryRegistry = new class implements DiscoveryRegistry {
|
||||
public function interfaces() {
|
||||
return new class {
|
||||
public function get(string $interface) { return []; }
|
||||
};
|
||||
}
|
||||
public function attributes() {
|
||||
return new class {
|
||||
public function get(string $attributeClass) { return []; }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Create mock executor with debug output
|
||||
$mockExecutor = new class implements TuiCommandExecutor {
|
||||
public function executeSelectedCommand(object $command): void {
|
||||
echo "\n🚀 Mock: Execute command\n";
|
||||
}
|
||||
public function executeCommand(string $commandName): void {
|
||||
echo "\n🚀 Mock: Execute command: $commandName\n";
|
||||
}
|
||||
public function validateSelectedCommand(object $command): void {
|
||||
echo "\n✓ Mock: Validate command\n";
|
||||
}
|
||||
public function validateCommand(string $commandName): void {
|
||||
echo "\n✓ Mock: Validate command: $commandName\n";
|
||||
}
|
||||
public function showSelectedCommandHelp(object $command): void {
|
||||
echo "\n📚 Mock: Show help\n";
|
||||
}
|
||||
public function showCommandHelp(string $commandName): void {
|
||||
echo "\n📚 Mock: Show help: $commandName\n";
|
||||
}
|
||||
public function showAllCommandsHelp(): void {
|
||||
echo "\n📚 Mock: Show all commands help\n";
|
||||
}
|
||||
public function startInteractiveForm(object $command, \App\Framework\Console\Components\TuiState $state): void {
|
||||
echo "\n📝 Mock: Start form\n";
|
||||
}
|
||||
public function findCommandObject(string $commandName): ?object {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// Create components
|
||||
$state = new TuiState();
|
||||
$history = new CommandHistory();
|
||||
$inputHandler = new TuiInputHandler($mockExecutor);
|
||||
$groupRegistry = new CommandGroupRegistry($discoveryRegistry);
|
||||
|
||||
echo "✓ Components created\n";
|
||||
|
||||
// Since discovery is empty, let's manually create categories like the real TUI
|
||||
$testCategories = [
|
||||
[
|
||||
'name' => 'Testing',
|
||||
'description' => 'Test commands',
|
||||
'icon' => '🧪',
|
||||
'priority' => 0,
|
||||
'commands' => []
|
||||
],
|
||||
[
|
||||
'name' => 'Demo',
|
||||
'description' => 'Demo commands',
|
||||
'icon' => '🎮',
|
||||
'priority' => 0,
|
||||
'commands' => []
|
||||
],
|
||||
[
|
||||
'name' => 'Generator',
|
||||
'description' => 'Code generation',
|
||||
'icon' => '⚙️',
|
||||
'priority' => 0,
|
||||
'commands' => []
|
||||
],
|
||||
[
|
||||
'name' => 'General',
|
||||
'description' => 'General commands',
|
||||
'icon' => '📂',
|
||||
'priority' => 0,
|
||||
'commands' => []
|
||||
]
|
||||
];
|
||||
|
||||
echo "📊 Test Categories:\n";
|
||||
foreach ($testCategories as $index => $category) {
|
||||
echo " [$index] {$category['icon']} {$category['name']} - {$category['description']}\n";
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
// Setup TUI state
|
||||
$state->setCategories($testCategories);
|
||||
$state->setCurrentView(TuiView::CATEGORIES);
|
||||
$state->setRunning(true);
|
||||
|
||||
echo "✓ TUI State initialized:\n";
|
||||
echo " Categories: " . count($testCategories) . "\n";
|
||||
echo " Current View: " . $state->getCurrentView()->name . "\n";
|
||||
echo " Selected Category: " . $state->getSelectedCategory() . "\n";
|
||||
|
||||
$currentCategory = $state->getCurrentCategory();
|
||||
if ($currentCategory) {
|
||||
echo " Current Category: '{$currentCategory['name']}'\n";
|
||||
} else {
|
||||
echo " ❌ ERROR: getCurrentCategory() returned NULL!\n";
|
||||
echo " This would cause navigation to fail!\n";
|
||||
}
|
||||
|
||||
echo "\n=== STEP-BY-STEP NAVIGATION DEBUG ===\n\n";
|
||||
|
||||
function debugState($state, $step) {
|
||||
echo "Step $step State:\n";
|
||||
echo " - Selected Index: " . $state->getSelectedCategory() . "\n";
|
||||
echo " - Current View: " . $state->getCurrentView()->name . "\n";
|
||||
|
||||
$category = $state->getCurrentCategory();
|
||||
if ($category) {
|
||||
echo " - Current Category: '{$category['name']}'\n";
|
||||
} else {
|
||||
echo " - ❌ Current Category: NULL\n";
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
// Initial state
|
||||
debugState($state, "Initial");
|
||||
|
||||
// Test 1: Direct TuiState navigation
|
||||
echo "🔍 Test 1: Direct TuiState navigation\n";
|
||||
echo "Calling \$state->navigateDown()...\n";
|
||||
$state->navigateDown();
|
||||
debugState($state, "After navigateDown()");
|
||||
|
||||
echo "Calling \$state->navigateUp()...\n";
|
||||
$state->navigateUp();
|
||||
debugState($state, "After navigateUp()");
|
||||
|
||||
// Test 2: TuiInputHandler navigation
|
||||
echo "🔍 Test 2: TuiInputHandler with Arrow Keys\n";
|
||||
|
||||
echo "Simulating ARROW_DOWN input...\n";
|
||||
echo "Key code: '" . TuiKeyCode::ARROW_DOWN->value . "' (hex: " . bin2hex(TuiKeyCode::ARROW_DOWN->value) . ")\n";
|
||||
|
||||
$beforeIndex = $state->getSelectedCategory();
|
||||
$inputHandler->handleInput(TuiKeyCode::ARROW_DOWN->value, $state, $history);
|
||||
$afterIndex = $state->getSelectedCategory();
|
||||
|
||||
echo "Before: $beforeIndex, After: $afterIndex\n";
|
||||
echo "Changed: " . ($beforeIndex !== $afterIndex ? "YES ✓" : "NO ❌") . "\n";
|
||||
debugState($state, "After ARROW_DOWN");
|
||||
|
||||
echo "Simulating ARROW_UP input...\n";
|
||||
echo "Key code: '" . TuiKeyCode::ARROW_UP->value . "' (hex: " . bin2hex(TuiKeyCode::ARROW_UP->value) . ")\n";
|
||||
|
||||
$beforeIndex = $state->getSelectedCategory();
|
||||
$inputHandler->handleInput(TuiKeyCode::ARROW_UP->value, $state, $history);
|
||||
$afterIndex = $state->getSelectedCategory();
|
||||
|
||||
echo "Before: $beforeIndex, After: $afterIndex\n";
|
||||
echo "Changed: " . ($beforeIndex !== $afterIndex ? "YES ✓" : "NO ❌") . "\n";
|
||||
debugState($state, "After ARROW_UP");
|
||||
|
||||
// Test 3: Check bounds
|
||||
echo "🔍 Test 3: Boundary testing\n";
|
||||
|
||||
// Go to last category
|
||||
$lastIndex = count($testCategories) - 1;
|
||||
$state->setSelectedCategory($lastIndex);
|
||||
echo "Set to last category ($lastIndex)\n";
|
||||
debugState($state, "Set to last");
|
||||
|
||||
echo "Try to go beyond last (ARROW_DOWN)...\n";
|
||||
$beforeIndex = $state->getSelectedCategory();
|
||||
$inputHandler->handleInput(TuiKeyCode::ARROW_DOWN->value, $state, $history);
|
||||
$afterIndex = $state->getSelectedCategory();
|
||||
|
||||
echo "Before: $beforeIndex, After: $afterIndex\n";
|
||||
echo "Boundary protected: " . ($beforeIndex === $afterIndex ? "YES ✓" : "NO ❌") . "\n";
|
||||
|
||||
// Test 4: Check TuiInputHandler logic
|
||||
echo "\n🔍 Test 4: Debug TuiInputHandler logic\n";
|
||||
|
||||
// Let's trace what happens in handleInput
|
||||
echo "Current view check: " . $state->getCurrentView()->name . "\n";
|
||||
echo "Is CATEGORIES view: " . ($state->getCurrentView() === TuiView::CATEGORIES ? "YES" : "NO") . "\n";
|
||||
|
||||
if ($state->getCurrentView() === TuiView::CATEGORIES) {
|
||||
echo "✓ View is correct for category navigation\n";
|
||||
} else {
|
||||
echo "❌ View is not CATEGORIES - navigation won't work!\n";
|
||||
}
|
||||
|
||||
echo "\n✅ NAVIGATION DEBUG COMPLETED\n";
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
echo "\n❌ DEBUG FAILED:\n";
|
||||
echo "Error: " . $e->getMessage() . "\n";
|
||||
echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n";
|
||||
echo "\nStack trace:\n" . $e->getTraceAsString() . "\n";
|
||||
}
|
||||
27
scripts/debug/env-check.php
Normal file
27
scripts/debug/env-check.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
// Simple production test endpoint
|
||||
declare(strict_types=1);
|
||||
|
||||
// Load environment
|
||||
$envFile = __DIR__ . '/../.env';
|
||||
if (file_exists($envFile)) {
|
||||
$lines = file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
foreach ($lines as $line) {
|
||||
if (strpos($line, '#') === 0) continue;
|
||||
if (strpos($line, '=') !== false) {
|
||||
[$key, $value] = explode('=', $line, 2);
|
||||
$_ENV[trim($key)] = trim($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
echo json_encode([
|
||||
'status' => 'production-test',
|
||||
'app_env' => $_ENV['APP_ENV'] ?? 'not-set',
|
||||
'app_debug' => $_ENV['APP_DEBUG'] ?? 'not-set',
|
||||
'analytics_track_performance' => $_ENV['ANALYTICS_TRACK_PERFORMANCE'] ?? 'not-set',
|
||||
'xdebug_mode' => $_ENV['XDEBUG_MODE'] ?? 'not-set',
|
||||
'timestamp' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
62
scripts/debug/env-force-check.php
Normal file
62
scripts/debug/env-force-check.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
// Force production environment test by reading .env directly
|
||||
declare(strict_types=1);
|
||||
|
||||
// Load environment from .env file (override container env)
|
||||
$envFile = __DIR__ . '/../.env';
|
||||
if (file_exists($envFile)) {
|
||||
$lines = file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
foreach ($lines as $line) {
|
||||
if (strpos($line, '#') === 0) continue;
|
||||
if (strpos($line, '=') !== false) {
|
||||
[$key, $value] = explode('=', $line, 2);
|
||||
$key = trim($key);
|
||||
$value = trim($value);
|
||||
|
||||
// Override environment
|
||||
$_ENV[$key] = $value;
|
||||
putenv("$key=$value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$tests = [
|
||||
'environment' => [
|
||||
'app_env_file' => $_ENV['APP_ENV'] ?? 'not-set',
|
||||
'app_debug_file' => $_ENV['APP_DEBUG'] ?? 'not-set',
|
||||
'app_env_server' => $_SERVER['APP_ENV'] ?? 'not-set',
|
||||
'app_debug_server' => $_SERVER['APP_DEBUG'] ?? 'not-set',
|
||||
'status' => ($_ENV['APP_ENV'] ?? '') === 'production' && ($_ENV['APP_DEBUG'] ?? '') === 'false' ? 'PASS' : 'FAIL'
|
||||
],
|
||||
'performance_debug' => [
|
||||
'analytics_track_performance' => $_ENV['ANALYTICS_TRACK_PERFORMANCE'] ?? 'not-set',
|
||||
'status' => (strpos($_ENV['ANALYTICS_TRACK_PERFORMANCE'] ?? '', 'false') !== false) ? 'PASS' : 'FAIL'
|
||||
],
|
||||
'xdebug' => [
|
||||
'xdebug_mode' => $_ENV['XDEBUG_MODE'] ?? 'not-set',
|
||||
'status' => ($_ENV['XDEBUG_MODE'] ?? '') === 'off' ? 'PASS' : 'FAIL'
|
||||
],
|
||||
'files' => [
|
||||
'env_file_exists' => file_exists($envFile) ? 'PASS' : 'FAIL',
|
||||
'env_backup_created' => glob(__DIR__ . '/../.env.backup.*') ? 'PASS' : 'FAIL'
|
||||
]
|
||||
];
|
||||
|
||||
// Calculate overall status
|
||||
$overall_status = 'PASS';
|
||||
foreach ($tests as $category => $test) {
|
||||
if (isset($test['status']) && $test['status'] === 'FAIL') {
|
||||
$overall_status = 'FAIL';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'deployment_status' => $overall_status,
|
||||
'timestamp' => date('Y-m-d H:i:s'),
|
||||
'note' => 'Reading production config from .env file (container env vars need rebuild)',
|
||||
'tests' => $tests
|
||||
], JSON_PRETTY_PRINT);
|
||||
?>
|
||||
57
scripts/debug/framework-components.php
Normal file
57
scripts/debug/framework-components.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
// Enable error reporting
|
||||
ini_set('display_errors', '1');
|
||||
ini_set('log_errors', '1');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
echo "🧪 Framework Debug Check\n";
|
||||
echo "======================\n\n";
|
||||
|
||||
try {
|
||||
echo "1. ✅ Basic PHP OK (Version: " . PHP_VERSION . ")\n";
|
||||
|
||||
echo "2. Testing Autoloader...\n";
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
echo " ✅ Autoloader loaded\n";
|
||||
|
||||
echo "3. Testing Basic Classes...\n";
|
||||
$testClasses = [
|
||||
'App\\Framework\\Core\\Application',
|
||||
'App\\Framework\\Core\\AppBootstrapper',
|
||||
'App\\Framework\\Http\\HttpRequest',
|
||||
'App\\Framework\\Http\\Method',
|
||||
];
|
||||
|
||||
foreach ($testClasses as $class) {
|
||||
if (class_exists($class)) {
|
||||
echo " ✅ $class: EXISTS\n";
|
||||
} else {
|
||||
echo " ❌ $class: MISSING\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "4. Testing DateTime Components...\n";
|
||||
$clock = new App\Framework\DateTime\SystemClock();
|
||||
echo " ✅ SystemClock: " . $clock->now()->format('Y-m-d H:i:s') . "\n";
|
||||
|
||||
echo "5. Testing Memory Monitor...\n";
|
||||
$memoryMonitor = new App\Framework\Performance\MemoryMonitor();
|
||||
echo " ✅ MemoryMonitor: Current usage " . number_format(memory_get_usage(true) / 1024 / 1024, 2) . " MB\n";
|
||||
|
||||
echo "\n🎉 Basic framework components working!\n";
|
||||
echo "The issue is likely in the Discovery System during bootstrap.\n";
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "\n❌ ERROR: " . $e->getMessage() . "\n";
|
||||
echo "Class: " . get_class($e) . "\n";
|
||||
echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n";
|
||||
echo "\nStack Trace:\n" . $e->getTraceAsString() . "\n";
|
||||
} catch (Error $e) {
|
||||
echo "\n❌ FATAL ERROR: " . $e->getMessage() . "\n";
|
||||
echo "Class: " . get_class($e) . "\n";
|
||||
echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n";
|
||||
echo "\nStack Trace:\n" . $e->getTraceAsString() . "\n";
|
||||
}
|
||||
53
scripts/debug/minimal-bootstrap.php
Normal file
53
scripts/debug/minimal-bootstrap.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Minimal framework test without discovery system
|
||||
*/
|
||||
|
||||
ini_set('display_errors', '1');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
try {
|
||||
echo "🌐 Minimal Framework Test\n";
|
||||
echo "========================\n\n";
|
||||
|
||||
// Test basic framework components without discovery
|
||||
$pathProvider = new App\Framework\Core\PathProvider(__DIR__ . '/..');
|
||||
$clock = new App\Framework\DateTime\SystemClock();
|
||||
$memoryMonitor = new App\Framework\Performance\MemoryMonitor();
|
||||
|
||||
echo "✅ PathProvider: " . $pathProvider->getBasePath() . "\n";
|
||||
echo "✅ Clock: " . $clock->now()->format('Y-m-d H:i:s') . "\n";
|
||||
echo "✅ Memory: " . number_format(memory_get_usage(true) / 1024 / 1024, 2) . " MB\n";
|
||||
|
||||
// Test HTTP Request parsing
|
||||
$method = App\Framework\Http\Method::GET;
|
||||
echo "✅ HTTP Method: " . $method->value . "\n";
|
||||
|
||||
// Simple HTTP response
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
|
||||
echo "\n📦 Framework Status:\n";
|
||||
echo " • Basic components: ✅ Working\n";
|
||||
echo " • Discovery system: 🚧 Needs optimization\n";
|
||||
echo " • Performance: ⚡ {$memoryMonitor->getPeakMemoryUsageMb()}MB peak\n";
|
||||
|
||||
echo "\n🎯 Next Steps:\n";
|
||||
echo " 1. Optimize discovery system for large codebase\n";
|
||||
echo " 2. Implement lazy loading for Framework components\n";
|
||||
echo " 3. Add performance monitoring\n";
|
||||
echo " 4. Test with production cache settings\n";
|
||||
|
||||
} catch (Throwable $e) {
|
||||
echo "❌ ERROR: " . $e->getMessage() . "\n";
|
||||
echo " File: " . $e->getFile() . ":" . $e->getLine() . "\n";
|
||||
echo " Class: " . get_class($e) . "\n";
|
||||
|
||||
if (method_exists($e, 'getContext')) {
|
||||
echo " Context: " . json_encode($e->getContext()) . "\n";
|
||||
}
|
||||
}
|
||||
50
scripts/debug/security-validation.php
Normal file
50
scripts/debug/security-validation.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
// Security test endpoint for production deployment validation
|
||||
declare(strict_types=1);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$tests = [
|
||||
'environment' => [
|
||||
'app_env' => $_ENV['APP_ENV'] ?? 'not-set',
|
||||
'app_debug' => $_ENV['APP_DEBUG'] ?? 'not-set',
|
||||
'status' => ($_ENV['APP_ENV'] ?? '') === 'production' && ($_ENV['APP_DEBUG'] ?? '') === 'false' ? 'PASS' : 'FAIL'
|
||||
],
|
||||
'performance_debug' => [
|
||||
'analytics_track_performance' => $_ENV['ANALYTICS_TRACK_PERFORMANCE'] ?? 'not-set',
|
||||
'status' => (strpos($_ENV['ANALYTICS_TRACK_PERFORMANCE'] ?? '', 'false') !== false) ? 'PASS' : 'FAIL'
|
||||
],
|
||||
'xdebug' => [
|
||||
'xdebug_mode' => $_ENV['XDEBUG_MODE'] ?? 'not-set',
|
||||
'status' => ($_ENV['XDEBUG_MODE'] ?? '') === 'off' ? 'PASS' : 'FAIL'
|
||||
],
|
||||
'security_headers' => [
|
||||
'https_only' => isset($_SERVER['HTTPS']) ? 'PASS' : 'FAIL',
|
||||
'user_agent_required' => !empty($_SERVER['HTTP_USER_AGENT']) ? 'PASS' : 'FAIL'
|
||||
]
|
||||
];
|
||||
|
||||
// Calculate overall status
|
||||
$overall_status = 'PASS';
|
||||
foreach ($tests as $category => $test) {
|
||||
if (isset($test['status']) && $test['status'] === 'FAIL') {
|
||||
$overall_status = 'FAIL';
|
||||
break;
|
||||
}
|
||||
if (is_array($test)) {
|
||||
foreach ($test as $key => $value) {
|
||||
if ($key === 'status' || !is_string($value)) continue;
|
||||
if ($value === 'FAIL') {
|
||||
$overall_status = 'FAIL';
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'overall_status' => $overall_status,
|
||||
'timestamp' => date('Y-m-d H:i:s'),
|
||||
'tests' => $tests
|
||||
], JSON_PRETTY_PRINT);
|
||||
?>
|
||||
5
scripts/debug/simple-test.php
Normal file
5
scripts/debug/simple-test.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
ini_set('display_errors',1);
|
||||
ini_set('display_startup_errors',1);
|
||||
error_reporting(E_ALL);
|
||||
echo 'DEBUG '.date('Y-m-d H:i:s');
|
||||
253
scripts/debug/simple_debug_tui.php
Normal file
253
scripts/debug/simple_debug_tui.php
Normal file
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
// Simple debug TUI without complex dependencies
|
||||
use App\Framework\Console\Components\TuiState;
|
||||
use App\Framework\Console\Components\TuiInputHandler;
|
||||
use App\Framework\Console\Components\TuiCommandExecutor;
|
||||
use App\Framework\Console\CommandHistory;
|
||||
use App\Framework\Console\TuiView;
|
||||
use App\Framework\Console\TuiKeyCode;
|
||||
use App\Framework\Console\ConsoleColor;
|
||||
use App\Framework\Console\Screen\ScreenControlCode;
|
||||
use App\Framework\Console\Screen\CursorControlCode;
|
||||
|
||||
echo "Simple TUI Debug Session\n";
|
||||
echo "========================\n\n";
|
||||
|
||||
// Check TTY
|
||||
if (!posix_isatty(STDIN)) {
|
||||
echo "❌ Requires TTY. Run with: docker exec -it php php simple_debug_tui.php\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo "✓ TTY available\n";
|
||||
|
||||
// Check PHPStorm
|
||||
$isPhpStorm = getenv('TERMINAL_EMULATOR') === 'JetBrains-JediTerm';
|
||||
echo "✓ PHPStorm detected: " . ($isPhpStorm ? "YES" : "NO") . "\n\n";
|
||||
|
||||
try {
|
||||
// Debug command executor
|
||||
$debugExecutor = new class implements TuiCommandExecutor {
|
||||
public function executeSelectedCommand(object $command): void {
|
||||
echo "\n🚀 EXECUTE: Selected command\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function executeCommand(string $commandName): void {
|
||||
echo "\n🚀 EXECUTE: $commandName\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function validateSelectedCommand(object $command): void {
|
||||
echo "\n✓ VALIDATE: Selected command\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function validateCommand(string $commandName): void {
|
||||
echo "\n✓ VALIDATE: $commandName\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function showSelectedCommandHelp(object $command): void {
|
||||
echo "\n📚 HELP: Selected command\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function showCommandHelp(string $commandName): void {
|
||||
echo "\n📚 HELP: $commandName\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function showAllCommandsHelp(): void {
|
||||
echo "\n📚 HELP: All commands\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function startInteractiveForm(object $command, \App\Framework\Console\Components\TuiState $state): void {
|
||||
echo "\n📝 FORM: Start interactive form\n";
|
||||
sleep(1);
|
||||
}
|
||||
public function findCommandObject(string $commandName): ?object {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// Custom TUI state with debug
|
||||
$debugState = new class extends TuiState {
|
||||
public function setSelectedCategory(int $index): void {
|
||||
$oldIndex = $this->getSelectedCategory();
|
||||
parent::setSelectedCategory($index);
|
||||
$newIndex = $this->getSelectedCategory();
|
||||
echo "\n[DEBUG] Category index: $oldIndex → $newIndex\n";
|
||||
flush();
|
||||
}
|
||||
|
||||
public function navigateUp(): void {
|
||||
echo "\n[DEBUG] ⬆️ navigateUp() called\n";
|
||||
flush();
|
||||
$before = $this->getSelectedCategory();
|
||||
parent::navigateUp();
|
||||
$after = $this->getSelectedCategory();
|
||||
echo "[DEBUG] ⬆️ Result: $before → $after\n";
|
||||
flush();
|
||||
}
|
||||
|
||||
public function navigateDown(): void {
|
||||
echo "\n[DEBUG] ⬇️ navigateDown() called\n";
|
||||
flush();
|
||||
$before = $this->getSelectedCategory();
|
||||
parent::navigateDown();
|
||||
$after = $this->getSelectedCategory();
|
||||
echo "[DEBUG] ⬇️ Result: $before → $after\n";
|
||||
flush();
|
||||
}
|
||||
};
|
||||
|
||||
// Custom input handler with debug
|
||||
$debugInputHandler = new class($debugExecutor) extends TuiInputHandler {
|
||||
public function handleInput(string $key, \App\Framework\Console\Components\TuiState $state, \App\Framework\Console\CommandHistory $history): void {
|
||||
$keyHex = bin2hex($key);
|
||||
$keyDesc = match($key) {
|
||||
"\033[A" => "ARROW_UP",
|
||||
"\033[B" => "ARROW_DOWN",
|
||||
"\033[C" => "ARROW_RIGHT",
|
||||
"\033[D" => "ARROW_LEFT",
|
||||
"\n" => "ENTER",
|
||||
" " => "SPACE",
|
||||
"\033" => "ESC",
|
||||
'q', 'Q' => "QUIT",
|
||||
default => "OTHER('$key')"
|
||||
};
|
||||
|
||||
echo "\n[INPUT] 🎯 Key: $keyDesc (hex: $keyHex)\n";
|
||||
echo "[INPUT] 📍 Current view: " . $state->getCurrentView()->name . "\n";
|
||||
echo "[INPUT] 📍 Current category: " . $state->getSelectedCategory() . "\n";
|
||||
flush();
|
||||
|
||||
parent::handleInput($key, $state, $history);
|
||||
|
||||
echo "[INPUT] ✅ After processing - Category: " . $state->getSelectedCategory() . "\n";
|
||||
flush();
|
||||
}
|
||||
};
|
||||
|
||||
$state = $debugState;
|
||||
$history = new CommandHistory();
|
||||
$inputHandler = $debugInputHandler;
|
||||
|
||||
// Add test categories
|
||||
$testCategories = [
|
||||
['name' => 'Testing', 'description' => 'Test commands', 'icon' => '🧪', 'commands' => []],
|
||||
['name' => 'Demo', 'description' => 'Demo commands', 'icon' => '🎮', 'commands' => []],
|
||||
['name' => 'Generator', 'description' => 'Code generation', 'icon' => '⚙️', 'commands' => []],
|
||||
['name' => 'General', 'description' => 'General commands', 'icon' => '📂', 'commands' => []]
|
||||
];
|
||||
|
||||
$state->setCategories($testCategories);
|
||||
$state->setCurrentView(TuiView::CATEGORIES);
|
||||
$state->setRunning(true);
|
||||
|
||||
echo "✓ Debug TUI ready\n";
|
||||
echo "Categories: " . count($testCategories) . "\n";
|
||||
echo "Selected: " . $state->getSelectedCategory() . "\n\n";
|
||||
|
||||
// Save terminal settings
|
||||
$originalSettings = trim(shell_exec('stty -g') ?: '');
|
||||
|
||||
echo "Setting up terminal for PHPStorm...\n";
|
||||
|
||||
// Set up terminal
|
||||
if ($isPhpStorm) {
|
||||
shell_exec('stty raw -echo min 1 time 0 2>/dev/null');
|
||||
} else {
|
||||
shell_exec('stty -icanon -echo 2>/dev/null');
|
||||
}
|
||||
|
||||
echo "✓ Terminal configured\n\n";
|
||||
|
||||
echo "🚀 SIMPLE DEBUG TUI\n";
|
||||
echo "==================\n\n";
|
||||
|
||||
function renderSimpleMenu($categories, $selectedIndex) {
|
||||
echo "Categories:\n";
|
||||
foreach ($categories as $index => $category) {
|
||||
$indicator = $index === $selectedIndex ? '▶️' : ' ';
|
||||
echo "$indicator {$category['icon']} {$category['name']}\n";
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function readKeyPHPStorm() {
|
||||
$key = fgetc(STDIN);
|
||||
if ($key === false) return '';
|
||||
|
||||
if ($key === "\033") {
|
||||
$sequence = $key;
|
||||
stream_set_blocking(STDIN, false);
|
||||
|
||||
$next = fgetc(STDIN);
|
||||
if ($next === false) {
|
||||
usleep(10000);
|
||||
$next = fgetc(STDIN);
|
||||
}
|
||||
|
||||
if ($next !== false) {
|
||||
$sequence .= $next;
|
||||
if ($next === '[') {
|
||||
$third = fgetc(STDIN);
|
||||
if ($third === false) {
|
||||
usleep(10000);
|
||||
$third = fgetc(STDIN);
|
||||
}
|
||||
if ($third !== false) {
|
||||
$sequence .= $third;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stream_set_blocking(STDIN, true);
|
||||
return $sequence;
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
// Simple debug loop
|
||||
echo "Use ↑/↓ arrow keys to navigate. Press 'q' to quit.\n\n";
|
||||
|
||||
while ($state->isRunning()) {
|
||||
// Render current state
|
||||
renderSimpleMenu($testCategories, $state->getSelectedCategory());
|
||||
|
||||
echo "Debug Info:\n";
|
||||
echo "- Selected Index: " . $state->getSelectedCategory() . "\n";
|
||||
echo "- Current View: " . $state->getCurrentView()->name . "\n";
|
||||
$category = $state->getCurrentCategory();
|
||||
echo "- Category Name: " . ($category ? $category['name'] : 'NULL') . "\n";
|
||||
echo "\nPress arrow keys...\n";
|
||||
echo str_repeat('=', 40) . "\n";
|
||||
|
||||
// Read input
|
||||
$key = readKeyPHPStorm();
|
||||
|
||||
if ($key === 'q' || $key === 'Q') {
|
||||
echo "\n[QUIT] Stopping TUI...\n";
|
||||
$state->setRunning(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($key !== '') {
|
||||
// Clear screen for next render
|
||||
echo ScreenControlCode::CLEAR_ALL->format();
|
||||
echo CursorControlCode::POSITION->format(1, 1);
|
||||
|
||||
// Process input with full debug output
|
||||
$inputHandler->handleInput($key, $state, $history);
|
||||
|
||||
echo "\n" . str_repeat('-', 40) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
// Restore terminal
|
||||
if (!empty($originalSettings)) {
|
||||
shell_exec("stty $originalSettings 2>/dev/null");
|
||||
}
|
||||
echo "\n✅ Simple Debug TUI ended\n";
|
||||
}
|
||||
Reference in New Issue
Block a user