๐ง Fix Stuck Analysis";
echo "";
try {
$auth = new Auth();
if (!$auth->isLoggedIn()) {
die("
โ Please log in first
");
}
$db = Database::getInstance();
// Get action parameter
$action = $_GET['action'] ?? '';
if ($action) {
handleAction($action, $db);
} else {
diagnoseIssue($db);
}
} catch (Exception $e) {
echo "โ Error: " . htmlspecialchars($e->getMessage()) . "
";
}
function diagnoseIssue($db) {
echo "";
echo "
๐ Diagnosing Stuck Analysis ";
// Check current state
$stateQuery = $db->query("SELECT * FROM optimization_analysis_state ORDER BY id DESC LIMIT 1");
$state = $stateQuery ? $stateQuery->fetch_assoc() : null;
if ($state) {
echo "
Analysis marked as running: " . ($state['is_running'] ? 'โ
Yes' : 'โ No') . "
";
echo "
Should pause: " . ($state['should_pause'] ? 'โ ๏ธ Yes' : 'โ
No') . "
";
echo "
Started at: " . ($state['started_at'] ?? 'Never') . "
";
echo "
Last updated: " . ($state['last_updated'] ?? 'Never') . "
";
}
// Check recent activity
$recentQuery = $db->query("
SELECT COUNT(*) as count, MAX(updated_at) as last_update
FROM panel_directives
WHERE llm_checked = 1
AND updated_at > DATE_SUB(NOW(), INTERVAL 10 MINUTE)
");
$recent = $recentQuery->fetch_assoc();
echo "
Recent activity (10 min): " . $recent['count'] . " combinations
";
echo "
Last activity: " . ($recent['last_update'] ?? 'None') . "
";
// Check total progress
$progressQuery = $db->query("
SELECT
COUNT(*) as total,
SUM(llm_checked) as processed,
SUM(CASE WHEN llm_checked = 1 AND is_impossible = 1 THEN 1 ELSE 0 END) as impossible
FROM panel_directives
");
$progress = $progressQuery->fetch_assoc();
echo "
Total progress: {$progress['processed']} / {$progress['total']} combinations
";
echo "
Impossible found: {$progress['impossible']}
";
echo "
";
// Check log files
echo "";
echo "
๐ Log File Analysis ";
$logFiles = [
'optimization_analysis.log',
'enhanced_optimization.log',
'error_log'
];
foreach ($logFiles as $logFile) {
if (file_exists($logFile)) {
$size = filesize($logFile);
$modified = date('Y-m-d H:i:s', filemtime($logFile));
echo "
โ
$logFile exists (Size: " . number_format($size) . " bytes, Modified: $modified)
";
if ($size > 0) {
echo "
View $logFile ";
}
} else {
echo "
โ ๏ธ $logFile not found
";
}
}
echo "
";
// Identify likely issues
echo "";
echo "
๐จ Likely Issues ";
$issues = identifyIssues($db, $state, $recent);
foreach ($issues as $issue) {
echo "
{$issue['icon']} {$issue['message']}
";
}
echo "
";
// Provide solutions
echo "";
// Add JavaScript for log viewing
echo "";
}
function identifyIssues($db, $state, $recent) {
$issues = [];
// Check if truly stuck
if ($state && $state['is_running'] && $recent['count'] == 0) {
$issues[] = [
'type' => 'error',
'icon' => '๐จ',
'message' => 'Background process is marked as running but no recent activity detected'
];
}
// Check if process file exists
if (!file_exists('enhanced_process_optimization.php') && !file_exists('process_optimization_analysis.php')) {
$issues[] = [
'type' => 'error',
'icon' => 'โ',
'message' => 'No background process file found'
];
}
// Check PHP exec capability
if (!function_exists('exec')) {
$issues[] = [
'type' => 'error',
'icon' => '๐ซ',
'message' => 'PHP exec() function is disabled - background processes cannot run'
];
}
// Check if GptHelper is available
try {
if (!class_exists('GptHelper')) {
require_once 'includes/GptHelper.php';
}
if (!class_exists('GptHelper')) {
$issues[] = [
'type' => 'error',
'icon' => '๐ค',
'message' => 'GptHelper class not found - GPT requests will fail'
];
}
} catch (Exception $e) {
$issues[] = [
'type' => 'error',
'icon' => '๐ค',
'message' => 'GptHelper error: ' . $e->getMessage()
];
}
// Check OpenAI API key
if (!defined('OPENAI_API_KEY') || empty(OPENAI_API_KEY)) {
$issues[] = [
'type' => 'error',
'icon' => '๐',
'message' => 'OpenAI API key not configured'
];
}
// Check for combinations to process
$pendingQuery = $db->query("SELECT COUNT(*) as count FROM panel_directives WHERE llm_checked = 0");
$pending = $pendingQuery->fetch_assoc()['count'];
if ($pending == 0) {
$issues[] = [
'type' => 'warning',
'icon' => 'โ
',
'message' => 'All combinations have been processed - analysis is complete!'
];
}
// If no major issues found
if (empty($issues) && $recent['count'] == 0) {
$issues[] = [
'type' => 'warning',
'icon' => '๐ค',
'message' => 'Background process may have crashed silently or hit memory/time limits'
];
}
return $issues;
}
function handleAction($action, $db) {
switch ($action) {
case 'stop_and_restart':
stopAndRestart($db);
break;
case 'manual_process':
manualProcess($db);
break;
case 'foreground_test':
foregroundTest($db);
break;
case 'reset_state':
resetState($db);
break;
case 'check_permissions':
checkPermissions();
break;
case 'view_log':
viewLog($_GET['file'] ?? '');
exit;
default:
echo "โ Unknown action: $action
";
}
echo "โ Back to Diagnosis ";
}
function stopAndRestart($db) {
echo "๐ Stop & Restart Analysis ";
try {
// Stop current analysis
$db->query("UPDATE optimization_analysis_state SET is_running = 0, should_pause = 0 WHERE is_running = 1");
echo "โ
Stopped current analysis
";
sleep(2);
// Get current stats
$totalQuery = $db->query("SELECT COUNT(*) as count FROM panel_directives");
$totalCombinations = $totalQuery->fetch_assoc()['count'];
$processedQuery = $db->query("SELECT COUNT(*) as count FROM panel_directives WHERE llm_checked = 1");
$processedCount = $processedQuery->fetch_assoc()['count'];
// Start new analysis
$stmt = $db->prepare("INSERT INTO optimization_analysis_state
(total_combinations, processed_combinations, is_running, started_at, should_pause)
VALUES (?, ?, 1, NOW(), 0)");
$stmt->bind_param('ii', $totalCombinations, $processedCount);
if ($stmt->execute()) {
echo "โ
Created new analysis state
";
// Try to start background process
$processFile = file_exists('enhanced_process_optimization.php') ?
'enhanced_process_optimization.php' :
'process_optimization_analysis.php';
if (function_exists('exec')) {
$command = "php " . __DIR__ . "/$processFile > /dev/null 2>&1 &";
exec($command);
echo "โ
Started background process: $processFile
";
} else {
echo "โ Cannot start background process - exec() disabled
";
echo "๐ก Try 'Manual Processing' instead
";
}
} else {
echo "โ Failed to create analysis state
";
}
} catch (Exception $e) {
echo "โ Error: " . htmlspecialchars($e->getMessage()) . "
";
}
}
function manualProcess($db) {
echo "๐ง Manual Processing (Foreground) ";
echo "This will process combinations manually in the browser. Keep this page open.
";
try {
// Load GptHelper
if (!class_exists('GptHelper')) {
require_once 'includes/GptHelper.php';
}
if (!class_exists('GptHelper')) {
throw new Exception("GptHelper class not found");
}
echo "โ
GptHelper loaded
";
// Get a small batch to process
$batchSize = 5;
$query = $db->query("
SELECT id, attribute1_id, attribute2_id, choice1, choice2, attribute1_name, attribute2_name
FROM panel_directives
WHERE llm_checked = 0
ORDER BY id ASC
LIMIT $batchSize
");
if (!$query || $query->num_rows == 0) {
echo "โ ๏ธ No combinations to process
";
return;
}
echo "๐ Processing " . $query->num_rows . " combinations...
";
$successCount = 0;
$errorCount = 0;
while ($combination = $query->fetch_assoc()) {
echo "";
echo "Processing: {$combination['attribute1_name']}={$combination['choice1']} + {$combination['attribute2_name']}={$combination['choice2']}";
try {
$result = processCombination($combination, $db);
if ($result['success']) {
$successCount++;
$status = $result['is_impossible'] ? 'IMPOSSIBLE' : 'POSSIBLE';
echo " โ $status ";
} else {
$errorCount++;
echo " โ ERROR: {$result['error']} ";
}
} catch (Exception $e) {
$errorCount++;
echo " โ EXCEPTION: " . htmlspecialchars($e->getMessage()) . " ";
}
echo "
";
flush();
// Small delay to prevent overwhelming the API
sleep(1);
}
echo "โ
Manual processing complete: $successCount success, $errorCount errors
";
if ($successCount > 0) {
echo "๐ก Manual processing is working. You can continue with 'Foreground Test' for more.
";
}
} catch (Exception $e) {
echo "โ Error: " . htmlspecialchars($e->getMessage()) . "
";
}
}
function processCombination($combination, $db) {
try {
$prompt = sprintf(
"Analyze this demographic combination:\n\n%s = %s\n%s = %s\n\nIs this combination logically possible in real-world demographics? Respond with 'POSSIBLE' or 'IMPOSSIBLE' followed by a brief reason.",
$combination['attribute1_name'],
$combination['choice1'],
$combination['attribute2_name'],
$combination['choice2']
);
$messages = [
[
'role' => 'system',
'content' => 'You are an expert demographic analyst. Analyze if the given combination is logically possible.'
],
[
'role' => 'user',
'content' => $prompt
]
];
$response = GptHelper::makeRequest($messages, 'gpt-4', 0.1);
if (!$response['success']) {
throw new Exception("GPT request failed: " . $response['error']);
}
$content = trim($response['response']);
$isImpossible = stripos($content, 'IMPOSSIBLE') === 0 ? 1 : 0;
// Extract reasoning
$reasoning = trim(str_ireplace(['POSSIBLE', 'IMPOSSIBLE'], '', $content));
if (empty($reasoning)) {
$reasoning = $content;
}
// Update database
$stmt = $db->prepare("UPDATE panel_directives SET
llm_checked = 1,
is_impossible = ?,
llm_reasoning = ?,
updated_at = NOW()
WHERE id = ?");
$stmt->bind_param('isi', $isImpossible, $reasoning, $combination['id']);
if (!$stmt->execute()) {
throw new Exception("Database update failed");
}
return [
'success' => true,
'is_impossible' => $isImpossible,
'reasoning' => $reasoning
];
} catch (Exception $e) {
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
function foregroundTest($db) {
echo "๐งช Foreground Processing Test ";
echo "โ ๏ธ This will run continuous processing in your browser. Keep this tab open and active.
";
echo "Processing will continue until you close this page or all combinations are done.
";
echo " ";
// Add auto-refresh and processing script
echo "Starting...
";
echo "
";
echo "
";
echo "";
}
function resetState($db) {
echo "๐ Reset Analysis State ";
try {
// Stop and reset analysis state
$db->query("UPDATE optimization_analysis_state SET is_running = 0, should_pause = 0, completed_at = NOW()");
echo "โ
Analysis state reset
";
// Optionally reset progress (uncomment if needed)
// $db->query("UPDATE panel_directives SET llm_checked = 0, is_impossible = 0, llm_reasoning = NULL WHERE llm_checked = 1");
// echo "โ
Progress reset (all combinations marked as unprocessed)
";
echo "You can now start a fresh analysis from the OptimAIze page
";
} catch (Exception $e) {
echo "โ Error: " . htmlspecialchars($e->getMessage()) . "
";
}
}
function checkPermissions() {
echo "๐ File Permissions Check ";
$files = [
'enhanced_process_optimization.php',
'process_optimization_analysis.php',
'includes/GptHelper.php',
'includes/config.php'
];
foreach ($files as $file) {
if (file_exists($file)) {
$perms = substr(sprintf('%o', fileperms($file)), -4);
$readable = is_readable($file) ? 'โ
' : 'โ';
$executable = is_executable($file) ? 'โ
' : 'โ';
echo "$file: Permissions $perms | Readable $readable | Executable $executable
";
} else {
echo "โ $file: Not found
";
}
}
// Check directory permissions
$writeable = is_writable('.') ? 'โ
' : 'โ';
echo "Current directory writable: $writeable
";
}
function viewLog($filename) {
if (!in_array($filename, ['optimization_analysis.log', 'enhanced_optimization.log', 'error_log'])) {
echo "Invalid log file";
return;
}
if (!file_exists($filename)) {
echo "Log file not found: $filename";
return;
}
$content = file_get_contents($filename);
echo htmlspecialchars($content);
}
// Handle AJAX batch processing
if (isset($_GET['action']) && $_GET['action'] === 'process_batch') {
header('Content-Type: application/json');
try {
if (!class_exists('GptHelper')) {
require_once 'includes/GptHelper.php';
}
$batchSize = 3;
$query = $db->query("
SELECT id, attribute1_id, attribute2_id, choice1, choice2, attribute1_name, attribute2_name
FROM panel_directives
WHERE llm_checked = 0
ORDER BY id ASC
LIMIT $batchSize
");
$combinations = [];
$processed = 0;
$errors = 0;
if ($query && $query->num_rows > 0) {
while ($combination = $query->fetch_assoc()) {
$result = processCombination($combination, $db);
$combinations[] = [
'combination' => "{$combination['attribute1_name']}={$combination['choice1']} + {$combination['attribute2_name']}={$combination['choice2']}",
'result' => $result['success'] ? ($result['is_impossible'] ? 'IMPOSSIBLE' : 'POSSIBLE') : 'ERROR'
];
if ($result['success']) {
$processed++;
} else {
$errors++;
}
}
}
// Check if more combinations exist
$remainingQuery = $db->query("SELECT COUNT(*) as count FROM panel_directives WHERE llm_checked = 0");
$hasMore = $remainingQuery->fetch_assoc()['count'] > 0;
echo json_encode([
'success' => true,
'processed' => $processed,
'errors' => $errors,
'combinations' => $combinations,
'has_more' => $hasMore
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
exit;
}
?>