MDNodaHelpers/src/NodaMailChecker.php

111 lines
3.2 KiB
PHP

<?PHP
/**
* Contains a class for checking the validity of mail addresses and their
* hostnames, cached through the central noda DB.
*
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
*/
declare(strict_types = 1);
/**
* Contains static functions for checking the validity of mail addresses.
*/
final class NodaMailChecker {
/**
* Splits a mail address and returns the hostname.
*
* @param string $mail_address Mail address.
*
* @return string
*/
public static function getDomainFromMailAddress(string $mail_address):string {
$mail_address = MD_STD_IN::sanitize_email($mail_address);
$addressParts = explode('@', $mail_address);
if (empty($addressParts[1])) {
throw new MDInvalidEmail("Failed to get mail domain");
}
$domain = $addressParts[1];
if (str_contains($domain, '.') === false) {
throw new MDInvalidEmail("Failed to find a dot in the mail domain");
}
return $domain;
}
/**
* Checks if a mail hostname is accessible.
*
* @param string $mail_domain Hostname of the mail address.
*
* @return string
*/
public static function validateMailDomainAccessibility(string $mail_domain):string {
$mxRecords = [];
getmxrr($mail_domain, $mxRecords);
$mxRecords = array_diff($mxRecords, ['0.0.0.0', '', null]);
if (empty($mxRecords)) return "";
return MD_STD_IN::sanitize_text(implode(',', $mxRecords));
}
/**
* Checks if a mail hostname is accessible.
*
* @param MDMysqli $mysqli DB connection.
* @param string $mail_domain Hostname of the mail address.
*
* @return boolean
*/
public static function validateMailDomainAccessibilityCached(MDMysqli $mysqli, string $mail_domain):bool {
$result = $mysqli->query_by_stmt("SELECT `valid`, `hostname`
FROM `" . DATABASENAME_NODA . "`.`misc_mail_hostname_validity`
WHERE `hostname` = ?", "s", $mail_domain);
if ($cur = $result->fetch_row()) {
$result->close();
return (bool)$cur[0];
}
$result->close();
$target_hostnames = self::validateMailDomainAccessibility($mail_domain);
$validity = !empty($target_hostnames);
$insertStmt = $mysqli->do_prepare("INSERT
INTO `" . DATABASENAME_NODA . "`.`misc_mail_hostname_validity`
(`hostname`, `valid`, `resolved_hostnames`)
VALUES
(?, ?, ?)");
$insertStmt->bind_param("sis", $mail_domain, $validity, $target_hostnames);
$insertStmt->execute();
$insertStmt->close();
return $validity;
}
/**
* Checks a mail address for the validity of its hostname.
*
* @param MDMysqli $mysqli DB connection.
* @param string $mail_address Hostname of the mail address.
*
* @return boolean
*/
public static function validateMailByDomainAccessibilityCached(MDMysqli $mysqli, string $mail_address):bool {
$domain = self::getDomainFromMailAddress($mail_address);
return self::validateMailDomainAccessibilityCached($mysqli, $domain);
}
}