Adresse => SMTP-Code der Ablehnung */ public array $abgelehnt = []; /** @var string[] Adressen, die RCPT angenommen hat */ public array $angenommen = []; /** true, wenn DATA angenommen wurde (die angenommenen Empfaenger haben die Mail). */ public bool $datenAngenommen = false; /** SMTP-Code der DATA-Antwort, wenn sie scheiterte ('' = keine Antwort). */ public string $datenCode = ''; public function zuruecksetzen(): void { $this->mailGestartet = false; $this->abgelehnt = []; $this->angenommen = []; $this->datenAngenommen = false; $this->datenCode = ''; } /** Host der letzten Verbindung (ohne ssl://), fuer den Wechsel auf die andere Annahmestelle. */ public string $host = ''; public function connect($host, $port = null, $timeout = 30, $options = []) { $this->zuruecksetzen(); $this->host = strtolower((string) preg_replace('#^[a-z]+://#i', '', (string) $host)); $ok = parent::connect($host, $port, $timeout, $options); // Verbindungsaufbau und Begruessung mit kurzem Limit (Ausfall schnell erkennen), Antworten danach mit // langem: Eine leere DATA-Antwort nach 8 s waere "voruebergehend", die Mail ginge doppelt raus. $this->Timeout = self::ANTWORT_S; return $ok; } public function mail($from) { $this->zuruecksetzen(); $this->mailGestartet = true; return parent::mail($from); } public function recipient($address, $dsn = '') { $ok = parent::recipient($address, $dsn); if ($ok) { $this->angenommen[] = strtolower((string) $address); } else { $this->abgelehnt[strtolower((string) $address)] = (string) ($this->getError()['smtp_code'] ?? ''); } return $ok; } public function data($msg_data) { $ok = parent::data($msg_data); $this->datenAngenommen = (bool) $ok; if (!$ok) { $this->datenCode = (string) ($this->getError()['smtp_code'] ?? ''); } return $ok; } /** * Ergebnis je Empfaenger nach einem Fehler, null wenn die Mail gar nicht bis * zu den Empfaengern kam (Anmeldung, MAIL FROM, Fehler vor dem Versand). * * @return array{zugestellt: bool, vorueber: string[], dauerhaft: string[]}|null */ public function auswertung(): ?array { if (!$this->mailGestartet || (!$this->abgelehnt && !$this->angenommen)) { return null; } $vorueber = $dauerhaft = []; foreach ($this->abgelehnt as $adresse => $code) { if ($code !== '' && $code[0] === '5') { $dauerhaft[] = $adresse; } else { $vorueber[] = $adresse; } } // DATA gescheitert: auch die angenommenen Empfaenger haben die Mail nicht. if (!$this->datenAngenommen && $this->angenommen) { if ($this->datenCode !== '' && $this->datenCode[0] === '5') { array_push($dauerhaft, ...$this->angenommen); } else { array_push($vorueber, ...$this->angenommen); } } if (!$vorueber && !$dauerhaft) { return null; } return ['zugestellt' => $this->datenAngenommen, 'vorueber' => $vorueber, 'dauerhaft' => $dauerhaft]; } }