=')) { echo "Hinweis: Ab PHP 8.4 ist imap kein Bestandteil von PHP mehr. Entweder den\n" . "PHP-Handler dieses Vhosts auf 8.3 stellen oder den Abruf ueber eine reine\n" . "TLS-Verbindung laufen lassen (siehe Test unten).\n"; } echo "\n=== Einstellungen (env.local.php) ===\n"; $host = app_env('PAYPAL_IMAP_HOST'); $user = app_env('PAYPAL_IMAP_USER'); $pass = app_env('PAYPAL_IMAP_PASS'); $port = (int) app_env('PAYPAL_IMAP_PORT', '993'); $flags = (string) app_env('PAYPAL_IMAP_FLAGS', '/imap/ssl'); $mailbox = (string) app_env('PAYPAL_IMAP_MAILBOX', 'INBOX'); imap_check_line('PAYPAL_INBOX_BASE', (string) (app_env('PAYPAL_INBOX_BASE') ?? '(nicht gesetzt)')); imap_check_line('PAYPAL_IMAP_HOST', (string) ($host ?? '(nicht gesetzt)')); imap_check_line('PAYPAL_IMAP_PORT', (string) $port); imap_check_line('PAYPAL_IMAP_FLAGS', $flags); imap_check_line('PAYPAL_IMAP_USER', (string) ($user ?? '(nicht gesetzt)')); // Das Passwort selbst gehoert nicht in ein Protokoll, das per Mail // verschickt oder weitergereicht wird - nur die Laenge als Tippfehler-Probe. imap_check_line('PAYPAL_IMAP_PASS', $pass === null ? '(nicht gesetzt)' : 'gesetzt (' . strlen($pass) . ' Zeichen)'); imap_check_line('PAYPAL_IMAP_MAILBOX', $mailbox); if ($host === null || $user === null || $pass === null) { echo "\nOhne Host, Benutzer und Passwort ist kein Verbindungstest moeglich.\n"; exit(1); } /** * Liest die Antwort bis zur Zeile mit dem gesuchten Tag. * * @return array{ok: bool, lines: list} */ function imap_check_read($sock, string $tag): array { $lines = []; while (($line = fgets($sock)) !== false) { $line = rtrim($line, "\r\n"); $lines[] = $line; if (str_starts_with($line, $tag . ' ')) { return ['ok' => str_starts_with($line, $tag . ' OK'), 'lines' => $lines]; } } return ['ok' => false, 'lines' => $lines]; } function imap_check_send($sock, string $tag, string $command): array { fwrite($sock, $tag . ' ' . $command . "\r\n"); return imap_check_read($sock, $tag); } echo "\n=== Verbindungstest ohne imap-Erweiterung (nur lesend) ===\n"; // Port 993 = TLS von Anfang an; alles andere (typisch 143) = STARTTLS. $implizitesTls = $port === 993 || str_contains($flags, '/ssl'); $adresse = ($implizitesTls ? 'ssl://' : 'tcp://') . $host . ':' . $port; imap_check_line('Verbindung', $adresse . ($implizitesTls ? ' (TLS sofort)' : ' (STARTTLS)')); $fehlerNr = 0; $fehlerText = ''; $sock = @stream_socket_client($adresse, $fehlerNr, $fehlerText, 15); if ($sock === false) { echo "FEHLER: Verbindung nicht moeglich ({$fehlerNr}: {$fehlerText})\n"; echo "Moegliche Ursachen: Host/Port falsch, ausgehende Verbindungen gesperrt,\n" . "oder TLS-Zertifikat nicht akzeptiert.\n"; exit(1); } stream_set_timeout($sock, 15); $greeting = rtrim((string) fgets($sock), "\r\n"); imap_check_line('Begruessung', $greeting !== '' ? $greeting : '(keine)'); if (!$implizitesTls) { $start = imap_check_send($sock, 'a0', 'STARTTLS'); if (!$start['ok'] || !@stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { echo "FEHLER: STARTTLS fehlgeschlagen - ohne Verschluesselung wird nicht angemeldet.\n"; exit(1); } imap_check_line('STARTTLS', 'ok'); } // Anfuehrungszeichen und Backslashes im Passwort maskieren (IMAP-Quoting). $quote = static fn(string $wert): string => '"' . str_replace(['\\', '"'], ['\\\\', '\\"'], $wert) . '"'; $login = imap_check_send($sock, 'a1', 'LOGIN ' . $quote($user) . ' ' . $quote($pass)); if (!$login['ok']) { echo "FEHLER: Anmeldung abgelehnt.\n"; echo ' Antwort: ' . end($login['lines']) . "\n"; fwrite($sock, "a9 LOGOUT\r\n"); fclose($sock); exit(1); } imap_check_line('Anmeldung', 'ok'); // EXAMINE statt SELECT: oeffnet das Postfach ausdruecklich nur lesend. $examine = imap_check_send($sock, 'a2', 'EXAMINE ' . $quote($mailbox)); if (!$examine['ok']) { echo "FEHLER: Postfach '{$mailbox}' nicht zu oeffnen.\n"; echo ' Antwort: ' . end($examine['lines']) . "\n"; fwrite($sock, "a9 LOGOUT\r\n"); fclose($sock); exit(1); } $gesamt = 0; foreach ($examine['lines'] as $line) { if (preg_match('/^\* (\d+) EXISTS/', $line, $m)) { $gesamt = (int) $m[1]; } } imap_check_line('Postfach', $mailbox . ' geoeffnet'); imap_check_line('Mails gesamt', (string) $gesamt); $search = imap_check_send($sock, 'a3', 'SEARCH UNSEEN'); $ungelesen = 0; foreach ($search['lines'] as $line) { if (str_starts_with($line, '* SEARCH')) { $ids = trim(substr($line, strlen('* SEARCH'))); $ungelesen = $ids === '' ? 0 : count(preg_split('/\s+/', $ids) ?: []); } } imap_check_line('davon ungelesen', (string) $ungelesen); fwrite($sock, "a9 LOGOUT\r\n"); fclose($sock); echo "\nErgebnis: Postfach erreichbar und Zugangsdaten gueltig.\n"; if (function_exists('imap_open')) { echo "Die imap-Erweiterung ist vorhanden - scripts/fetch-paypal-payments.php\n" . "laeuft ohne weitere Aenderung. Naechster Schritt: derselbe Task mit --dry-run.\n"; } else { echo "Die imap-Erweiterung fehlt, das Postfach ist aber ueber die reine\n" . "TLS-Verbindung erreichbar - ein Abruf ohne Erweiterung ist also moeglich.\n"; }