continue with emaill impl.

This commit is contained in:
Dennis Eichhorn 2020-07-29 20:56:22 +02:00
parent fc39d6d452
commit 86d3c10b05
3 changed files with 232 additions and 48 deletions

View File

@ -104,6 +104,14 @@ abstract class EmailAbstract
*/
protected string $endOfLine = "\r\n";
/**
* OAuth
*
* @var OAuth
* @since 1.0.0
*/
protected $oauth = null;
/**
* Construct
*
@ -227,8 +235,6 @@ abstract class EmailAbstract
|| $this->submitType === SubmitType::MAIL
) {
$this->endOfLine = $this->submitType === SubmitType::SMTP || !\stripos(\PHP_OS, 'WIN') === 0 ? \PHP_EOL : "\r\n";
return;
} elseif ($this->submitType === SubmitType::SENDMAIL) {
$this->endOfLine = \PHP_EOL;
$path = \ini_get('sendmail_path');
@ -256,6 +262,34 @@ abstract class EmailAbstract
if (empty($mail->getTo())) {
return false;
}
$this->preSend($mail);
$this->postSend($mail);
return true;
}
private function preSend(Mail $mail) : bool
{
$this->endOfLine = $this->submitType === SubmitType::SMTP
|| ($this->submitType === SubmitType::MAIL && \stripos(\PHP_OS, 'WIN') === 0)
? "\r\n" : \PHP_EOL;
$this->setMessageType();
if($this->submitType === SubmitType::MAIL) {
$this->header .= 'to: ' . $this->addrAppend('to', $this->to);
$this->header .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->subject)));
}
return true;
}
private function postSend(Mail $mail) : bool
{
return true;
}
/**
@ -620,4 +654,18 @@ abstract class EmailAbstract
return \imap_fetchheader($this->con, $id);
}
/**
* Set the OAuth connection
*
* @param OAuth $oauth OAuth
*
* @return void
*
* @since 1.0.0
*/
public function setOAuth($oauth) : void
{
$this->oauth = $oauth;
}
}

View File

@ -40,12 +40,4 @@ class Imap extends EmailAbstract
return parent::connect($user, $pass);
}
/**
* {@inheritdoc}
*/
public function send() : bool
{
}
}

View File

@ -20,6 +20,7 @@ declare(strict_types=1);
namespace phpOMS\Message\Mail;
use phpOMS\System\CharsetType;
use phpOMS\System\File\Local\File;
use phpOMS\System\MimeType;
use phpOMS\Utils\MbStringUtils;
@ -169,6 +170,14 @@ class Mail
*/
protected string $contentType = MimeType::M_TXT;
/**
* Character set
*
* @var string
* @since 1.0.0
*/
protected string $charset = CharsetType::ISO_8859_1;
/**
* Mail message type.
*
@ -236,8 +245,7 @@ class Mail
public function setBodyAlt(string $body) : void
{
$this->bodyAlt = $body;
$this->contentType = MimeType::M_ALT;
$this->setMessageType();
$this->contentType = empty($body) ? MimeType::M_TXT : MimeType::M_ALT;
}
/**
@ -293,7 +301,7 @@ class Mail
*/
public function setSubject(string $subject) : void
{
$this->subject = $subject;
$this->subject = \trim($subject);
}
/**
@ -429,13 +437,9 @@ class Mail
return false;
}
$info = [];
\preg_match('#^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^.\\\\/]+?)|))[\\\\/.]*$#m', $path, $info);
$filename = $info[2] ?? '';
$this->attachment[] = [
'path' => $path,
'filename' => $filename,
'filename' => \basename($path),
'name' => $name,
'encoding' => $encoding,
'type' => $type,
@ -444,8 +448,6 @@ class Mail
'id' => $name,
];
$this->setMessageType();
return true;
}
@ -456,8 +458,26 @@ class Mail
*
* @since 1.0.0
*/
public function addStringAttachment() : bool
{
public function addStringAttachment(
string $string,
string $filename,
string $encoding = EncodingType::E_BASE64,
string $type = '',
string $disposition = DispositionType::ATTACHMENT
) : bool {
$type = $type === '' ? MimeType::getByName('M_' . \strtoupper(File::extension($filename))) : $type;
$this->attachment[] = [
'path' => $string,
'filename' => $filename,
'name' => \basename($filename),
'encoding' => $encoding,
'type' => $type,
'string' => true,
'disposition' => $disposition,
'id' => 0,
];
return true;
}
@ -468,8 +488,32 @@ class Mail
*
* @since 1.0.0
*/
public function addEmbeddedImage() : bool
{
public function addEmbeddedImage(
string $path,
string $cid,
string $name = '',
string $encoding = EncodingType::E_BASE64,
string $type = '',
string $disposition = DispositionType::INLINE
) : bool {
if ((bool) \preg_match('#^[a-z]+://#i', $path)) {
return false;
}
$type = $type === '' ? MimeType::getByName('M_' . \strtoupper(File::extension($path))) : $type;
$filename = \basename($path);
$this->attachment[] = [
'path' => $path,
'filename' => $filename,
'name' => empty($name) ? $filename : $name,
'encoding' => $encoding,
'type' => $type,
'string' => false,
'disposition' => $disposition,
'id' => $cid,
];
return true;
}
@ -480,8 +524,27 @@ class Mail
*
* @since 1.0.0
*/
public function addStringEmbeddedImage() : bool
{
public function addStringEmbeddedImage(
string $string,
string $cid,
string $name = '',
string $encoding = EncodingType::E_BASE64,
string $type = '',
string $disposition = DispositionType::INLINE
) : bool {
$type = $type === '' ? MimeType::getByName('M_' . \strtoupper(File::extension($name))) : $type;
$this->attachment[] = [
'path' => $string,
'filename' => $name,
'name' => $name,
'encoding' => $encoding,
'type' => $type,
'string' => true,
'disposition' => $disposition,
'id' => $cid,
];
return true;
}
@ -517,9 +580,15 @@ class Mail
return null;
}
$domain = \substr($mail, ++$pos);
if (!((bool) \preg_match('/[\x80-\xFF]/', $domain))) {
return $mail;
}
$domain = \mb_convert_encoding($domain, 'UTF-8', $this->charset);
$normalized = \idn_to_ascii($mail);
return $normalized === false ? $mail : $normalized;
return $normalized === false ? $mail : \substr($domain, 0, $pos) . $normalized;
}
/**
@ -555,14 +624,20 @@ class Mail
if (\stripos($address, '<') === false) {
if (($address = $this->normalizeEmailAddress($address)) !== null) {
$addresses[$address] = '';
$addresses[] = [
'name' => '',
'address' => $address,
];
}
} else {
$parts = \explode('<', $address);
$address = \trim(\str_replace('>', '', $parts[1]));
if (($address = $this->normalizeEmailAddress($address)) !== null) {
$addresses[$address] = \trim(\str_replace(['"', '\''], '', $parts[0]));
$addresses[] = [
'name' => \trim(\str_replace(['"', '\''], '', $parts[0])),
'address' => $address,
];
}
}
}
@ -570,20 +645,6 @@ class Mail
return $addresses;
}
/**
* Check if text has none ascii characters
*
* @param string $text Text to check
*
* @return bool
*
* @since 1.0.0
*/
private function hasNoneASCII(string $text) : bool
{
return (bool) \preg_match('/[\x80-\xFF]/', $text);
}
/**
* Define the message type based on the content
*
@ -830,6 +891,10 @@ class Mail
*
* @param string $text Text to normalized
* @param string $lb Line break
*
* @return string
*
* @since 1.0.0
*/
private function normalizeText(string $text, string $lb = "\n") : string
{
@ -1089,7 +1154,7 @@ class Mail
$mime[] = '--' . $boundary . $this->endOfLine;
$mime[] = !empty($attach['name'])
? 'Content-Type: ' . $attach['type'] . '; name="' . $this->encodeHeader(\trim(\str_replace(["\r", "\n"], '', $attach['name']))) . '"' . $this->endOfLine
? 'Content-Type: ' . $attach['type'] . '; name=' . $this->quotedString($this->encodeHeader(\trim(\str_replace(["\r", "\n"], '', $attach['name'])))) . '"' . $this->endOfLine
: 'Content-Type: ' . $attach['type'] . $this->endOfLine;
if ($attach['encoding'] !== EncodingType::E_7BIT) {
@ -1104,8 +1169,8 @@ class Mail
$encodedName = $this->encodeHeader(\trim(\str_replace(["\r", "\n"], '', $attach['name'])));
// @todo: "" might be wrong for || condition
$mime[] = \preg_match('/[ ()<>@,;:"\/\[\]?=]/', $encodedName) || !empty($encodedName)
? 'Content-Disposition: ' . $attach['disposition'] . '; filename="' . $encodedName . '"' . $this->endOfLine
$mime[] = !empty($encodedName)
? 'Content-Disposition: ' . $attach['disposition'] . '; filename=' . $this->quotedString($encodedName) . $this->endOfLine
: 'Content-Disposition: ' . $attach['disposition'] . $this->endOfLine;
}
@ -1187,7 +1252,7 @@ class Mail
*/
private function encodeFile(string $path, string $encoding = EncodingType::E_BASE64) : string
{
if (!\is_readable($path)) {
if (!\is_readable($path) || (bool) \preg_match('#^[a-z]+://#i', $path)) {
return '';
}
@ -1241,6 +1306,20 @@ class Mail
return \substr($encoded, 0, -\strlen($lb));
}
/**
* Escape special strings
*
* @param string $text Text to escape
*
* @return string
*
* @since 1.0.0
*/
private function quotedString(string $text) : string
{
return \preg_match('/[ ()<>@,;:"\/\[\]?=]/', $text) === false ? $text : '"' . \str_replace('"', '\\"', $text) . '"';
}
/**
* Quoted encode
*
@ -1253,6 +1332,71 @@ class Mail
*/
private function encodeQ(string $text, int $context = HeaderContext::TEXT) : string
{
return '';
$pattern = '';
switch ($context) {
case HeaderContext::PHRASE:
$pattern = '^A-Za-z0-9!*+\/ -';
break;
case HeaderContext::COMMENT:
$pattern = '\(\)"';
case HeaderContext::TEXT:
default:
$pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
}
$matches = [];
$encoded = \str_replace(["\r", "\n"], '', $text);
if (\preg_match_all('/[{' . $pattern . '}]/', $encoded, $matches) !== false) {
$eqkey = \array_search('', $matches[0], true);
if ($eqkey !== false) {
unset($matches[0][$eqkey]);
\array_unshift($matches[0], '=');
}
$unique = \array_unique($matches[0]);
foreach ($unique as $char) {
$encoded = \str_replace($char, '=' . \sprintf('%02X', \ord($char)), $encoded);
}
}
return \str_replace(' ', '_', $encoded);
}
/**
* Set signing files
*
* @param string $certFile Certification file path
* @param string $keyFile Key file path
* @param string $keyPass Password for the key
*
* @return void
*
* @since 1.0.0
*/
public function sign(string $certFile, string $keyFile, string $keyPass) : void
{
$this->signCertFile = $certFile;
$this->signKeyFile = $keyFile;
$this->signKeyPass = $keyPass;
}
public function preSend() : void
{
$this->mimeHeader = '';
$this->mimeBody = $this->createBody();
// @todo: only if createBody impements sign / #tempheader = $this->header
$this->mimeHeader = $this->createHeader();
// set mime body
// set mime header
// ...
}
private function addrAppend(string $type, array $addr) : string
{
}
}