#!/usr/bin/env php === OUTPUT ARCHITECTURE AUDIT === Test 1: Checking for echo statements outside templates... Test 2: Checking for print statements... Test 3: Checking for var_dump() calls... ✓ PASS: No var_dump() calls found Test 4: Checking for print_r() calls... Test 5: Checking for die() calls... ✓ PASS: No die() calls found Test 6: Checking for exit() calls... Test 7: Verifying Public/index.php as single output point... ✓ PASS: Public/index.php contains output statements (as expected) ✓ PASS: Public/index.php calls orchestrate() or handle() Test 8: Checking error_log() usage for error handling... ✓ PASS: Found error_log() usage for error handling: /home/memorize/public_html/App/Cron.php:225: error_log("Cron Fatal Error: " . $e->getMessage()); /home/memorize/public_html/App/Routes/Controllers/PublicNotifyController.php:70: error_log("Failed to fetch full scripture text for reference '{$reference}': " . $e->getMessage()); /home/memorize/public_html/App/Routes/Controllers/SchedulesController.php:350: error_log("Warning: Failed to update study position for study_id {$schedule['study_id']} while updating schedule_id {$scheduleId}: " . $studyResult->getError()); /home/memorize/public_html/App/Routes/Controllers/StudiesController.php:394: error_log("[Send Now] Processing request for study ID: {$studyId}"); /home/memorize/public_html/App/Routes/Controllers/StudiesController.php:399: error_log("[Send Now] No active schedule found for study ID: {$studyId}"); /home/memorize/public_html/App/Routes/Controllers/StudiesController.php:403: error_log("[Send Now] Found active schedule ID: {$schedule['id']} (status: {$schedule['status']}) for study ID: {$studyId}"); /home/memorize/public_html/App/Routes/Controllers/StudiesController.php:408: error_log("[Send Now] No active notification found for schedule ID: {$schedule['id']}"); /home/memorize/public_html/App/Routes/Controllers/StudiesController.php:412: error_log("[Send Now] Found notification ID: {$notification['id']} (status: {$notification['status']}, due: {$notification['due']})"); /home/memorize/public_html/App/Routes/Controllers/StudiesController.php:417: error_log("[Send Now] Failed to update notification {$notification['id']}: " . ($result->getError() ?? 'Unknown error')); /home/memorize/public_html/App/Routes/Controllers/StudiesController.php:424: error_log("[Send Now] Successfully updated notification {$notification['id']} due time to: {$newDueTime}"); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:20: error_log('DEBUG editMenu() START'); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:30: error_log('DEBUG editMenu - User interface level: ' . ($user['interface'] ?? 'MISSING')); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:53: error_log('DEBUG editMenu - Current menuOverrides keys: ' . $overrideKeys); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:71: error_log('DEBUG editMenu - User does not qualify for menu customization'); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:73: error_log('DEBUG editMenu - Menu overrides exist but are marked invalid; skipping initialization'); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:75: error_log('DEBUG editMenu - No menu for level ' . $userInterfaceLevel . ', initializing...'); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:78: error_log('DEBUG editMenu - Loading menu.json from: ' . $menusPath); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:81: error_log('DEBUG editMenu - ERROR: menu.json NOT FOUND at ' . $menusPath); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:85: error_log('DEBUG editMenu - menu.json loaded, keys: ' . implode(', ', array_map('strval', array_keys($menusData)))); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:88: error_log('DEBUG editMenu - Looking for interface level name: ' . $levelName); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:93: error_log('DEBUG editMenu - Copied menu to overrides, count: ' . count($overrideData[$levelName])); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:99: error_log('DEBUG editMenu - Updated user config'); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:103: error_log('DEBUG editMenu - Persisted to database'); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:105: error_log('DEBUG editMenu - ERROR: Failed to persist to database: ' . $saveResult->getError()); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:108: error_log('DEBUG editMenu - ERROR: Level name "' . $levelName . '" not found in menu.json'); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:113: error_log('DEBUG editMenu - Menu already exists for level ' . $userInterfaceLevel . ', count: ' . $existingCount); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:121: error_log('DEBUG editMenu - Final currentMenu count: ' . count($currentMenu)); /home/memorize/public_html/App/Routes/Controllers/MenuCustomizationController.php:122: error_log('DEBUG editMenu END'); /home/memorize/public_html/App/App.php:148: error_log('SignalWire not configured: ' . $e->getMessage()); /home/memorize/public_html/App/Cron/StudyProcessor.php:50: error_log($msg); /home/memorize/public_html/App/Cron/NotificationProcessor.php:135: error_log($msg); /home/memorize/public_html/App/Cron/CronLogging.php:51: error_log("Failed to touch cron heartbeat file: " . $e->getMessage()); /home/memorize/public_html/App/Cron/ScheduleProcessor.php:67: error_log($msg); /home/memorize/public_html/App/Logic/Helpers/TimeFormatHelper.php:262: error_log("Failed to format friendly next delivery time: " . $e->getMessage()); /home/memorize/public_html/App/Logic/Helpers/TimeFormatHelper.php:443: error_log("Failed to format friendly next session time: " . $e->getMessage()); /home/memorize/public_html/App/Logic/Middleware/CsrfProtection.php:241: error_log("CSRF validation failed - IP: {$ip}, Method: {$method}, URI: {$uri}"); /home/memorize/public_html/App/Logic/Middleware/ErrorHandler.php:124: error_log($logMessage); /home/memorize/public_html/App/Logic/Middleware/ErrorHandler.php:125: error_log('Context: ' . json_encode($context)); /home/memorize/public_html/App/Logic/Middleware/ErrorHandler.php:126: error_log('Trace: ' . $e->getTraceAsString()); /home/memorize/public_html/App/Logic/Middleware/ErrorHandler.php:148: error_log($logMessage); /home/memorize/public_html/App/Logic/Middleware/ErrorHandler.php:165: error_log($logMessage); /home/memorize/public_html/App/Logic/Middleware/ErrorHandler.php:306: error_log('Failed to create log directory: ' . $logDirectory); /home/memorize/public_html/App/Logic/Middleware/ErrorHandler.php:316: error_log('Failed to write to log file: ' . $logFile); /home/memorize/public_html/App/Logic/Services/NotificationService.php:31: error_log("Attempting to send SMS notification #{$notificationId}"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:34: error_log("SMS delivery failed for notification #{$notificationId}: SignalWireClient not initialized"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:40: error_log("SMS delivery failed for notification #{$notificationId}: Invalid user ID"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:47: error_log("SMS delivery failed for notification #{$notificationId}: User #{$userId} not found"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:53: error_log("SMS delivery failed for notification #{$notificationId}: User #{$userId} has no phone number"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:60: error_log("SMS delivery failed for notification #{$notificationId}: User #{$userId} phone not validated"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:66: error_log("Routing notification #{$notificationId} to SMS handler. Phone: {$maskedPhone}"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:82: error_log("Message preview: " . mb_substr($smsBody, 0, 50) . "..."); /home/memorize/public_html/App/Logic/Services/NotificationService.php:87: error_log("SMS notification #{$notificationId} sent successfully. SID: " . ($result['messageId'] ?? 'N/A')); /home/memorize/public_html/App/Logic/Services/NotificationService.php:90: error_log("SMS notification #{$notificationId} failed: " . ($result['error'] ?? 'Unknown error')); /home/memorize/public_html/App/Logic/Services/NotificationService.php:103: error_log("Processing notifications for schedule ID: {$scheduleId}"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:110: error_log("Schedule not found for ID: {$scheduleId}"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:118: error_log("Study not found for schedule ID: {$scheduleId}"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:126: error_log("User not found for schedule ID: {$scheduleId}"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:131: error_log("Schedule Notification Details:"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:132: error_log(" - Schedule ID: {$scheduleId}"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:133: error_log(" - Study: {$study['title']} ({$study['type']})"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:134: error_log(" - User ID: {$user['id']}"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:135: error_log(" - Pattern: {$schedule['schedule']}"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:136: error_log(" - Current Progress: {$schedule['position']}/{$schedule['total']}"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:148: error_log("Error processing schedule notifications for schedule ID {$scheduleId}: " . $e->getMessage()); /home/memorize/public_html/App/Logic/Services/NotificationService.php:550: error_log("[NotificationService::setDueToNow] Notification #{$id} not found"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:554: error_log("[NotificationService::setDueToNow] Current due time for notification #{$id}: " . ($notification['due'] ?? 'null')); /home/memorize/public_html/App/Logic/Services/NotificationService.php:560: error_log("[NotificationService::setDueToNow] Database update failed for notification #{$id}"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:564: error_log("[NotificationService::setDueToNow] Database update successful for notification #{$id}"); /home/memorize/public_html/App/Logic/Services/NotificationService.php:568: error_log("[NotificationService::setDueToNow] New due time for notification #{$id}: " . ($updatedNotification['due'] ?? 'null')); /home/memorize/public_html/App/Logic/Services/NotificationService.php:572: error_log("[NotificationService::setDueToNow] Failed to retrieve updated notification #{$id}"); /home/memorize/public_html/App/Logic/Services/UserService.php:279: error_log('Failed to delete user: ' . $e->getMessage()); /home/memorize/public_html/App/Logic/Services/UserService.php:641: error_log('Failed to update login time for user ' . $userId . ': ' . $e->getMessage()); /home/memorize/public_html/App/Logic/Services/UserService.php:811: error_log('Failed to send verification email for user ' . $userId . ': ' . $emailResult->getError()); /home/memorize/public_html/App/Logic/Services/EmailService.php:42: error_log('Failed to initialize email service: ' . $e->getMessage() . '. Email functionality will be disabled.'); /home/memorize/public_html/App/Logic/Services/EmailService.php:61: error_log('Email service not initialized. Cannot send email.'); /home/memorize/public_html/App/Logic/Services/EmailService.php:94: error_log('Email service not initialized. Cannot send notification email.'); /home/memorize/public_html/App/Logic/Services/EmailService.php:125: error_log('Email service not initialized. Cannot send login link email.'); /home/memorize/public_html/App/Logic/Services/EmailService.php:160: error_log('Email service not initialized. Cannot send validation email.'); /home/memorize/public_html/App/Logic/Services/EmailService.php:197: error_log('Email service not initialized. Cannot send password reset email.'); /home/memorize/public_html/App/Logic/Services/StudyService.php:338: error_log("Failed to populate topical totals for topic {$topicId}: " . $e->getMessage()); /home/memorize/public_html/App/Logic/Services/StudyService.php:387: error_log("Failed to populate reference totals for '{$reference}': " . $e->getMessage()); /home/memorize/public_html/App/Logic/Services/StudyService.php:446: error_log("Failed to check user interface level for user {$userId}: " . $e->getMessage()); /home/memorize/public_html/App/Logic/Services/StudyService.php:478: error_log("Auto-schedule creation: Successfully calculated next run for study {$studyId}: {$upcomingTimestamp}"); /home/memorize/public_html/App/Logic/Services/StudyService.php:480: error_log("Auto-schedule creation: API returned no next_run timestamp for study {$studyId}. Will be calculated by cron."); /home/memorize/public_html/App/Logic/Services/StudyService.php:484: error_log("Auto-schedule creation: API failed for study {$studyId}: " . $e->getMessage() . ". Schedule created with NULL upcoming for cron to calculate."); /home/memorize/public_html/App/Logic/Services/StudyService.php:501: error_log("Auto-created active schedule for focused user study: Study ID {$studyId}, Schedule Pattern: {$pattern}, Total: {$studyTotal}, Upcoming: " . ($upcomingTimestamp ?? 'NULL')); /home/memorize/public_html/App/Logic/Services/StudyService.php:504: error_log("Failed to auto-create schedule for focused user study {$studyId}: " . $e->getMessage() . ". Study creation continues."); /home/memorize/public_html/App/Logic/Services/StudyService.php:706: error_log('Study reset: ' . json_encode([ /home/memorize/public_html/App/Logic/Services/StudyService.php:714: error_log('Study reset failed: ' . $e->getMessage()); /home/memorize/public_html/App/Data/Clients/SignalWireClient.php:379: error_log($message . ' phone=' . $context['phone'] . ' error=' . ($context['error'] ?? '')); /home/memorize/public_html/App/Data/Clients/SignalWireClient.php:388: if (function_exists('error_log')) { /home/memorize/public_html/App/Data/Clients/SignalWireClient.php:389: error_log('[INFO] ' . $message . ' ' . json_encode($context)); /home/memorize/public_html/App/Data/Clients/SignalWireClient.php:399: if (function_exists('error_log')) { /home/memorize/public_html/App/Data/Clients/SignalWireClient.php:400: error_log('[DEBUG] ' . $message . ' ' . json_encode($context)); /home/memorize/public_html/App/Data/Clients/ScheduleApiClient.php:46: error_log("ScheduleApiClient: Calling /validate with pattern='{$pattern}', timezone='{$timezone}'"); /home/memorize/public_html/App/Data/Clients/ScheduleApiClient.php:55: error_log("ScheduleApiClient: Raw API response: " . json_encode($response)); /home/memorize/public_html/App/Data/Clients/ScheduleApiClient.php:59: error_log("ScheduleApiClient: API request failed - no response received"); /home/memorize/public_html/App/Data/Clients/ScheduleApiClient.php:64: error_log("ScheduleApiClient: API request failed - invalid response format"); /home/memorize/public_html/App/Data/Clients/ScheduleApiClient.php:71: error_log("ScheduleApiClient: API error response: {$errorMsg}"); /home/memorize/public_html/App/Data/Clients/ScheduleApiClient.php:86: error_log("ScheduleApiClient: API response missing next_run_dates in both top-level and result-wrapped formats"); /home/memorize/public_html/App/Data/Clients/ScheduleApiClient.php:94: error_log("ScheduleApiClient: Missing timestamp in first next_run_date"); /home/memorize/public_html/App/Data/Clients/ScheduleApiClient.php:108: error_log("ScheduleApiClient: Converted ISO8601 '{$iso8601}' to UTC '{$datetimeString}'"); /home/memorize/public_html/App/Data/Clients/ScheduleApiClient.php:116: error_log("ScheduleApiClient: Fallback conversion of timestamp {$timestamp} to UTC '{$datetimeString}'"); /home/memorize/public_html/App/Data/Clients/ScheduleApiClient.php:123: error_log("ScheduleApiClient: Successfully parsed response from {$responseSource} format, next_run: {$datetimeString} ({$diffMinutes} minutes from now)"); /home/memorize/public_html/App/Data/Clients/ScheduleApiClient.php:138: error_log("ScheduleApiClient: Failed to calculate next run for pattern '{$pattern}' in timezone '{$timezone}': " . $e->getMessage()); /home/memorize/public_html/App/Data/Repositories/NotificationRepository.php:442: error_log("[NotificationRepository::setDueToNow] Updated notification #{$id}, rows affected: {$rowCount}"); /home/memorize/public_html/App/Data/Repositories/NotificationRepository.php:444: error_log("[NotificationRepository::setDueToNow] Failed to update notification #{$id}"); /home/memorize/public_html/App/Presentation/Partials/MenuPartial.php:42: error_log("WARNING: Theme '{$theme}' not found, falling back to '{$defaultTheme}'"); /home/memorize/public_html/App/Presentation/Partials/MenuPartial.php:46: error_log("ERROR: Default theme '{$defaultTheme}' not found in {$themeDir}"); /home/memorize/public_html/App/Presentation/Partials/NotificationsPartial.php:25: error_log("WARNING: Theme '{$theme}' not found, falling back to '{$defaultTheme}'"); /home/memorize/public_html/App/Presentation/Partials/NotificationsPartial.php:29: error_log("ERROR: Default theme '{$defaultTheme}' not found in {$themeDir}"); /home/memorize/public_html/App/Presentation/Partials/HeaderPartial.php:24: error_log("WARNING: Theme '{$theme}' not found, falling back to '{$defaultTheme}'"); /home/memorize/public_html/App/Presentation/Partials/HeaderPartial.php:28: error_log("ERROR: Default theme '{$defaultTheme}' not found in {$themeDir}"); /home/memorize/public_html/App/Presentation/Partials/FooterPartial.php:28: error_log("WARNING: Theme '{$theme}' not found, falling back to '{$defaultTheme}'"); /home/memorize/public_html/App/Presentation/Partials/FooterPartial.php:32: error_log("ERROR: Default theme '{$defaultTheme}' not found in {$themeDir}"); /home/memorize/public_html/App/Presentation/Presenter.php:70: error_log("WARNING: Theme '{$theme}' not found, falling back to 'ml'"); /home/memorize/public_html/App/Presentation/Presenter.php:181: error_log('SIMPLE DEBUG: About to render template: ' . $resolvedTemplate); /home/memorize/public_html/App/Presentation/Presenter.php:182: error_log('SIMPLE DEBUG: Templates path: ' . $this->templatesPath); /home/memorize/public_html/App/Presentation/Presenter.php:185: error_log('SIMPLE DEBUG: Looking for template at: ' . $templateFile . ', exists=' . (file_exists($templateFile) ? 'yes' : 'no')); /home/memorize/public_html/App/Presentation/Presenter.php:189: error_log('SIMPLE DEBUG: Presenter rendered body, length=' . strlen($body) . ', first 200 chars=' . substr($body, 0, 200)); /home/memorize/public_html/App/Presentation/Presenter.php:193: error_log('SIMPLE DEBUG: About to render layout with body length=' . strlen($layoutData['body'])); Test 9: Verifying Services return data only... Test 10: Verifying Controllers return data only... ✓ PASS: All 11 controllers return data only Test 11: Verifying Repositories return data only... ✓ PASS: All 8 repositories return data only ============================================================ AUDIT SUMMARY ============================================================ ✗✗✗ VIOLATIONS FOUND ✗✗✗ 1. Found echo statements outside templates: /home/memorize/public_html/App/Cron.php:244: echo "Cron completed\n"; /home/memorize/public_html/App/Logic/Helpers/Result.php:162: * @example if (!$result->isSuccess()) { echo $result->getError(); } /home/memorize/public_html/App/Logic/Services/NotificationService.php:145: echo "Processing schedule notifications for schedule ID: {$scheduleId}\n"; /home/memorize/public_html/App/Presentation/Admin/users.php:74: echo $interfaces[$user['interface'] ?? 0] ?? $user['interface']; /home/memorize/public_html/App/Presentation/page-show.php:2: /home/memorize/public_html/App/Presentation/Public/notify.php:33:
= htmlspecialchars(print_r($debug['request'], true)) ?>/home/memorize/public_html/App/Presentation/error-show.php:21:
= htmlspecialchars(print_r($debug['trace'], true)) ?>4. Found exit() calls: /home/memorize/public_html/App/Cron.php:203: exit("Cron already running or lock error\n"); 5. Service has direct output: NotificationService.php