292 lines
8.9 KiB
PHP
292 lines
8.9 KiB
PHP
<?php
|
|
|
|
/*
|
|
* Create email class
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace CoreLibs\Create;
|
|
|
|
/**
|
|
* sending simple text emails
|
|
*/
|
|
class Email
|
|
{
|
|
/** @var array<string> allowed list for encodings that can do KV folding */
|
|
private static array $encoding_kv_allowed = [
|
|
'UTF-8',
|
|
'EUC-JP',
|
|
'SJIS',
|
|
'SJIS-win',
|
|
'ISO-2022-JP',
|
|
'ISO-2022-JP-MS',
|
|
'JIS',
|
|
'JIS-ms',
|
|
];
|
|
/** @var string normaly this does not need to be changed */
|
|
private static string $mb_convert_kana_mode = 'KV';
|
|
|
|
/**
|
|
* create mime encoded email part for to/from emails.
|
|
* If encoding is not UTF-8 it will convert the email name to target encoding
|
|
* FROM UTF-8
|
|
* Source data is ALWAYS seen as utf-8
|
|
*
|
|
* @param string $email E-Mail address
|
|
* @param string $email_name Name for the email address, in UTF-8, if not set, empty
|
|
* @param string $encoding Encoding, if not set UTF-8
|
|
* @param bool $kv_folding If set to true and a valid encoding, do KV folding
|
|
* @return string Correctly encoded and build email string
|
|
*/
|
|
public static function encodeEmailName(
|
|
string $email,
|
|
string $email_name = '',
|
|
string $encoding = 'UTF-8',
|
|
bool $kv_folding = false
|
|
): string {
|
|
if (empty($email_name)) {
|
|
return $email;
|
|
}
|
|
// if encoding is not UTF-8 then we convert
|
|
if ($encoding != 'UTF-8') {
|
|
$email_name = mb_convert_encoding($email_name, $encoding, 'UTF-8');
|
|
}
|
|
$email_name =
|
|
mb_encode_mimeheader(
|
|
in_array($encoding, self::$encoding_kv_allowed) && $kv_folding ?
|
|
mb_convert_kana(
|
|
$email_name,
|
|
self::$mb_convert_kana_mode,
|
|
$encoding
|
|
) :
|
|
$email_name,
|
|
$encoding
|
|
);
|
|
return '"' . $email_name . '" '
|
|
. '<' . (string)$email . '>';
|
|
}
|
|
|
|
/**
|
|
* Subject/Body replace sub function
|
|
*
|
|
* @param string $subject Subject string, in UTF-8
|
|
* @param string $body Body string, in UTF-8
|
|
* @param array<string,string> $replace Replace the array as key -> value, in UTF-8
|
|
* @param string $encoding Encoding for subject encode mime header
|
|
* @param bool $kv_folding If set to true and a valid encoding,
|
|
* do KV folding
|
|
* @return array<string> Pos 0: Subject, Pos 1: Body
|
|
*/
|
|
private static function replaceContent(
|
|
string $subject,
|
|
string $body,
|
|
array $replace,
|
|
string $encoding,
|
|
bool $kv_folding
|
|
): array {
|
|
foreach (['subject', 'body'] as $element) {
|
|
$$element = str_replace(
|
|
array_map(
|
|
function ($key) {
|
|
return '{' . $key . '}';
|
|
},
|
|
array_keys($replace)
|
|
),
|
|
array_values($replace),
|
|
$$element
|
|
);
|
|
}
|
|
// if encoding is NOT UTF-8 convert to target
|
|
if ($encoding != 'UTF-8') {
|
|
$subject = mb_convert_encoding($subject, $encoding, 'UTF-8');
|
|
$body = mb_convert_encoding($body, $encoding, 'UTF-8');
|
|
}
|
|
// we need to encodde the subject
|
|
$subject = mb_encode_mimeheader(
|
|
in_array($encoding, self::$encoding_kv_allowed) && $kv_folding ?
|
|
// for any non UTF-8 encoding convert kana
|
|
mb_convert_kana(
|
|
$subject,
|
|
self::$mb_convert_kana_mode,
|
|
$encoding
|
|
) :
|
|
$subject,
|
|
$encoding
|
|
);
|
|
return [$subject, $body];
|
|
}
|
|
|
|
/**
|
|
* Send plain text email with possible to replace subject/body data
|
|
* either global or per to email set.
|
|
* replace to tags are in {} in the subject or body
|
|
*
|
|
* @param string $subject Mail subject, mandatory, in UTF-8
|
|
* @param string $body Mail body, mandatory, in UTF-8
|
|
* @param string $from_email From email, mandatory
|
|
* @param string $from_name From email name, in UTF-8
|
|
* if empty '' then not set
|
|
* @param array<mixed> $send_to_emails to email or array for email/replace
|
|
* If array: name/email/replace[key,value]
|
|
* name and replace must be in UTF-8
|
|
* At least one must be set
|
|
* @param array<string,string> $replace_content Subject/Body replace as
|
|
* search -> replace, in UTF-8
|
|
* @param string $encoding E-Mail encoding, default UTF-8
|
|
* @param bool $kv_folding If set to true and a valid encoding,
|
|
* do KV folding
|
|
* @param bool $test test flag, default off
|
|
* @param \CoreLibs\Logging\Logging|null $log Logging class,
|
|
* only used if test flag is true
|
|
* @return int 2 test only, no sent
|
|
* 1 for ok,
|
|
* 0 for send not ok
|
|
* -1 for nothing set (emails, subject, body)
|
|
* -2 for empty to list
|
|
* -3 encoding target not valid or not installed
|
|
*/
|
|
public static function sendEmail(
|
|
string $subject,
|
|
string $body,
|
|
string $from_email,
|
|
string $from_name,
|
|
array $send_to_emails,
|
|
array $replace_content = [],
|
|
string $encoding = 'UTF-8',
|
|
bool $kv_folding = false,
|
|
bool $test = false,
|
|
?\CoreLibs\Logging\Logging $log = null
|
|
): int {
|
|
/** @var array<string> */
|
|
$to_emails = [];
|
|
/** @var array<string,array<string,string>> */
|
|
$to_replace = [];
|
|
/** @var string */
|
|
$out_subject = $subject;
|
|
/** @var string */
|
|
$out_body = $body;
|
|
// check basic set
|
|
if (empty($subject) || empty($body) || empty($from_email)) {
|
|
return -1;
|
|
}
|
|
if (
|
|
$encoding != 'UTF-8' &&
|
|
!in_array($encoding, mb_list_encodings())
|
|
) {
|
|
return -3;
|
|
}
|
|
// if not one valid to, abort
|
|
foreach ($send_to_emails as $to_email) {
|
|
// to_email can be string, then only to email
|
|
// else expect 'email' & 'name'
|
|
if (
|
|
is_array($to_email) &&
|
|
isset($to_email['email'])
|
|
) {
|
|
$_to_email = self::encodeEmailName(
|
|
$to_email['email'],
|
|
$to_email['name'] ?? '',
|
|
$encoding,
|
|
$kv_folding
|
|
);
|
|
$to_emails[] = $_to_email;
|
|
// if we have to replacement, this override replace content
|
|
if (isset($to_email['replace']) && count($to_email['replace'])) {
|
|
// merge with original replace content,
|
|
// to data will override original data
|
|
$to_replace[$_to_email] = array_merge(
|
|
$replace_content,
|
|
$to_email['replace']
|
|
);
|
|
}
|
|
} elseif (is_string($to_email)) {
|
|
$to_emails[] = $to_email;
|
|
}
|
|
}
|
|
if (!count($to_emails)) {
|
|
return -2;
|
|
}
|
|
|
|
// the email headers needed
|
|
$headers = [
|
|
'From' => self::encodeEmailName($from_email, $from_name, $encoding),
|
|
'Content-type' => "text/plain; charset=" . $encoding,
|
|
'MIME-Version' => "1.0",
|
|
];
|
|
|
|
// if we have a replace string, we need to do replace run
|
|
// only if there is no dedicated to replace
|
|
// also run replace if there is nothing to replace at all
|
|
// this will mime encode the subject
|
|
if (!count($to_replace)) {
|
|
list($out_subject, $out_body) = self::replaceContent(
|
|
$subject,
|
|
$body,
|
|
$replace_content,
|
|
$encoding,
|
|
$kv_folding
|
|
);
|
|
}
|
|
|
|
$mail_delivery_status = 1;
|
|
// send the email
|
|
foreach ($to_emails as $to_email) {
|
|
// default mail status is success
|
|
$mail_status = true;
|
|
// if there is a to replace, if not use the original replace content
|
|
if (count($to_replace)) {
|
|
$_replace = [];
|
|
if (!empty($to_replace[$to_email])) {
|
|
$_replace = $to_replace[$to_email];
|
|
} elseif (count($replace_content)) {
|
|
$_replace = $replace_content;
|
|
}
|
|
if (count($_replace)) {
|
|
list($out_subject, $out_body) = self::replaceContent(
|
|
$subject,
|
|
$body,
|
|
$_replace,
|
|
$encoding,
|
|
$kv_folding
|
|
);
|
|
}
|
|
}
|
|
// if we are in test mode, do not send an email and set status to 2
|
|
if ($test === false) {
|
|
$mail_status = mail($to_email, $out_subject, $out_body, $headers);
|
|
} else {
|
|
$mail_delivery_status = 2;
|
|
}
|
|
// log if an log instance exists
|
|
if ($log instanceof \CoreLibs\Logging\Logging) {
|
|
// build debug strings: convert to UTF-8 if not utf-8
|
|
$log->debug('SEND EMAIL', 'HEADERS: ' . \CoreLibs\Debug\Support::prAr($headers) . ', '
|
|
. 'ENCODING: ' . $encoding . ', '
|
|
. 'KV FOLDING: ' . \CoreLibs\Debug\Support::prBl($kv_folding) . ', '
|
|
. 'TO: ' . $to_email . ', '
|
|
. 'SUBJECT: ' . $out_subject . ', '
|
|
. 'BODY: ' . ($encoding == 'UTF-8' ?
|
|
$out_body :
|
|
mb_convert_encoding($out_body, 'UTF-8', $encoding)));
|
|
$log->debug('SEND EMAIL JSON', json_encode([
|
|
'encoding' => $encoding,
|
|
'kv_folding' => $kv_folding,
|
|
'header' => $headers,
|
|
'to' => $to_email,
|
|
'subject' => $out_subject,
|
|
'body' => ($encoding == 'UTF-8' ?
|
|
$out_body :
|
|
mb_convert_encoding($out_body, 'UTF-8', $encoding))
|
|
]) ?: '{}');
|
|
}
|
|
if (!$mail_status) {
|
|
$mail_delivery_status = 0;
|
|
}
|
|
}
|
|
return $mail_delivery_status;
|
|
}
|
|
}
|
|
|
|
// __END__
|