maison_alexandra/www/system-brs-core/library/cMail/cMail.php

459 lines
16 KiB
PHP

<?php
namespace BRSystems\Core\Library\cMail;
use BRSystems\Core\Cms\CmsMailEngine\CmsMailEngine;
use BRSystems\Core\Library\cJSON\cJSON;
use Swift_Attachment;
use Swift_Mailer;
use Swift_Message;
use Swift_SendmailTransport;
use Swift_SmtpTransport;
use Swift_Transport;
/**
* Mail module
*
* @category LIB mail
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @since Version 1.1
*
*
* EXAMPLE:
* $mm = new cMail();
* $mm->addMail('burkkanc@gmail.com', cMail::MAIL_8_AUCTION_PICKUP_REMINDER, $this->langId, array('Prod-name' => 'XXXLS-10992'), true, 3);
*
*/
class cMail
{
private cMailModule $module;
CONST PWD = 'pwd';
CONST PORT = 'port';
CONST LOGIN = 'login';
CONST SERVER = 'server';
CONST SENDER = 'SENDER';
CONST ENCRYPTION = 'encryption';
CONST REWRITE_SENDER_NAME_TO = 'RW_NAME';
CONST SEND_READ_REC_TO = 'readReceiptTo';
CONST MAIL_SERVER_DEFAULT = '1';
const CC_SHOP_OWNER = 'cc_shop_owner'; // TODO: šo jāuzseto pareizu
/* MAIL SERVER CONSTANTS */
static array $SERVER_CFG = [
self::MAIL_SERVER_DEFAULT => [
self::LOGIN => 'info@maisonalexandra.lv',
self::PWD => 'dkq2fecDqy8J43m!@',
self::PORT => 465,
self::ENCRYPTION => 'ssl',
self::SERVER => 'smtppro.zoho.eu',
self::SENDER => 'info@maisonalexandra.lv',
self::SEND_READ_REC_TO => 'info@maisonalexandra.lv',
self::REWRITE_SENDER_NAME_TO => 'Maison Alexandra',
],
];
const MAIL_REQUEST_KEY = 'MAISONALEXANDRA-A94A8FE5CCB19BA61C4C0873D391E987982FBBD3';
CONST MAIL_REQUEST_PROCESS_ID = 'maisonalexandra_mailer';
CONST MAIL_TRACKING_STR = '[%TRACKING_IMG%]';
CONST EHLO_SERVER = 'www.maisonalexandra.lv'; // Send hello message to check server availability
// Main mail templates
const MAIL_1_ACCOUNT_ACTIVATION = 'Mail 1'; // User account activation (User registration complete email)
const MAIL_2_PASSWORD_RECOVERY = 'Mail 2'; // Password recovery email
const MAIL_3_SUBSCRIPTION_MAIL = 'Mail 3'; // Newsletter mail
const MAIL_4_SYSTEM_NOTICES_MAIL = 'Mail 4'; // System notices mail
const MAIL_5_ORDER_CONFIRMATION = 'Mail 5'; // Order confirmation mail
const MAIL_6_ORDER_RECEIPT = 'Mail 6'; // Order receipt mail
const MAIL_16_SYSTEM_NEW_MAILS = 'Mail 16'; // System news
public function __construct()
{
include_once 'cMail.classModule.php';
$this->module = new cMailModule();
}
/**
* Function to insert new mail into ned table
*
* @category LIB mail
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @param string $to - mail owner
* @param string|bool $toCC - mail cc owner
* @param string $sMailSrvType - mail server to use
* @param string $template - mail template constant
* @param int $lang - mail language
* @param array $rdata - mail replace template data varibles k => v
* @param string $attachment - attachment file
* @param bool $send - send mail now
* @param int $priority - mail priority enum 1-3
* @param string|bool $marker - mail tracking marker to check specific data
* @return bool|int -
*/
public function addMail($to, $toCC = false, $sMailSrvType = self::MAIL_SERVER_DEFAULT, $template, $lang, $rdata = array(), $attachment = '', $send = false, $priority = 1, $marker = false){
// Check mail server
if(!isset(self::$SERVER_CFG[$sMailSrvType])) cJSON::sendError(array('msg' => "Passed mail server does'nt exist!"));
// Get mail template
if(strlen($to) && $mailData = $this->module->getTemplateByType($template, $lang)){
$replace = array();
$replaceData = array();
if(count($rdata)){
foreach ($rdata as $k=>$v) {
if($v && is_array($v)){
$this->composeArrayDataReplace($k, $v, $mailData['mail_data']);
}else{
$replaceData[] = $v;
$replace[] = $k;
}
}
}
// Replace constants
$mailData['mail_data'] = str_replace($replace, $replaceData, $mailData['mail_data']);
if($mailData['mail_data']){
// Add outgoing mail
$mail = array(
'mail_server_type' => $sMailSrvType,
'mail_lang_id' => $lang,
'mail_template_id' => $mailData['template_id'],
'mail_owner' => $to,
'mail_owner_cc' => $toCC,
'mail_sender' => self::$SERVER_CFG[$sMailSrvType][self::SENDER],
'mail_title' => $mailData['mail_title'],
'mail_content' => $mailData['mail_data'],
'mail_attachment' => $attachment,
'mail_inserted' => time(),
'mail_modified' => time(),
'mail_priority' => $priority,
'mail_send_atempt' => 0,
'mail_marker' => $marker,
);
// Check send mail flag
if(defined('SEND_MAILS') && !SEND_MAILS) $send = false;
// Add mail to outgoing list
$mId = $this->module->insOutgoingMail($mail);
// Send mail immediately
if ($send && $mId) {
$SSL = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443 ? 's' : '');
exec("screen -A -m -d -S " . self::MAIL_REQUEST_PROCESS_ID . " curl 'http{$SSL}://{$_SERVER['HTTP_HOST']}/cron/ctp:" . self::MAIL_REQUEST_KEY . "/ct:send/id:{$mId}'");
}
return $mId;
}
}
return false;
}
/**
* Function to insert new mail into ned table
*
* @category LIB mail
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @param string $to - mail owner
* @param string|bool $toCC - mail cc owner
* @param string $sMailSrvType - mail server to use
* @param array $mailData - mail data
* @param int $lang - mail language
* @param array $rdata - mail replace template data varibles k => v
* @param string $attachment - attachment file
* @param bool $send - send mail now
* @param int $priority - mail priority enum 1-3
* @param string|bool $marker - mail tracking marker to check specific data
* @return bool true/false
*/
public function addMailT($to, $toCC = false, $sMailSrvType = self::MAIL_SERVER_DEFAULT, $mailData = array(), $lang, $rdata = array(), $attachment = '', $send = false, $priority = 1, $marker = false){
// Check mail server
if(!isset(self::$SERVER_CFG[$sMailSrvType])) cJSON::sendError(array('msg' => "Passed mail server does'nt exist!"));
// Get mail template
if(strlen($to) && !empty($mailData)){
$replace = array();
$replaceData = array();
if(count($rdata)){
foreach ($rdata as $k=>$v) {
if($v && is_array($v)){
$this->composeArrayDataReplace($k, $v, $mailData['mail_data']);
}else{
$replaceData[] = $v;
$replace[] = $k;
}
}
}
// Replace constants
$mailData['mail_data'] = str_replace($replace, $replaceData, $mailData['mail_data']);
if($mailData['mail_data']){
// Add outgoing mail
$mail = array(
'mail_server_type' => $sMailSrvType,
'mail_lang_id' => $lang,
'mail_template_id' => $mailData['template_id'],
'mail_owner' => $to,
'mail_owner_cc' => $toCC,
'mail_sender' => self::$SERVER_CFG[$sMailSrvType][self::SENDER],
'mail_title' => $mailData['mail_title'],
'mail_content' => $mailData['mail_data'],
'mail_attachment' => $attachment,
'mail_inserted' => time(),
'mail_modified' => time(),
'mail_priority' => $priority,
'mail_send_atempt' => 0,
'mail_marker' => $marker,
);
// Check send mail flag
if(defined('SEND_MAILS') && !SEND_MAILS) $send = false;
// Add mail to outgoing list
$mId = $this->module->insOutgoingMail($mail);
// Send mail immediately
if ($send && $mId) {
$SSL = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443 ? 's' : '');
exec("screen -A -m -d -S " . self::MAIL_REQUEST_PROCESS_ID . " curl 'http{$SSL}://{$_SERVER['HTTP_HOST']}/cron/ctp:" . self::MAIL_REQUEST_KEY . "/ct:send/id:{$mId}'");
}
return true;
}
}
return false;
}
/**
* Function to send mail
*
* @category LIB mail
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @param array|null $mailData - mail configuration data
* @returns mixed
*/
public function sendMail(array $mailData = null)
{
if(is_null($mailData)) return false;
if (!isset(self::$SERVER_CFG[$mailData['mail_server_type']])) {
cJSON::sendError(array('msg' => "Passed mail server does'nt exist!"));
}
// Check send mail flag
if(defined('SEND_MAILS') && !SEND_MAILS || !defined('SEND_MAILS')) cJSON::sendError('Outgoing E-Mails are DISABLED!!!');
$mailCfg = self::$SERVER_CFG[$mailData['mail_server_type']];
// Create SwiftMail instance
$oMailer = new Swift_Mailer($this->getSwiftMailerTransport($mailCfg));
// Analyse & prepare data
$senderTitle = (strlen($mailCfg[self::REWRITE_SENDER_NAME_TO]) ? $mailCfg[self::REWRITE_SENDER_NAME_TO] : $this->getDomainName($mailData['mail_sender']));
$mailData['mail_owner_title'] = (!isset($mailData['mail_owner_title']) ? $mailData['mail_owner_title'] = $mailData['mail_owner'] : $mailData['mail_owner_title']);
$mailData['mail_owner_cc_title'] = (!isset($mailData['mail_owner_cc_title']) ? $mailData['mail_owner_cc_title'] = $mailData['mail_owner_cc'] : $mailData['mail_owner_cc_title']);
// Strip left constants
$this->stripLeftDataVariableInMailContent($mailData['mail_content']);
// Create a message
$oMessage = (new Swift_Message($mailData['mail_title']))
->setReplyTo([$mailData['mail_sender'] => $senderTitle])
->setFrom([$mailData['mail_sender'] => $senderTitle])
->setTo([$mailData['mail_owner'] => $mailData['mail_owner_title']])
->setBody($mailData['mail_content'], 'text/html');
// Check for plain message
if(isset($mailData['plain_text']) && $mailData['plain_text'])
$oMessage->addPart('My amazing body in plain text', 'text/plain');
// Add cc if specified
if(!empty($mailData['mail_owner_cc']))
$oMessage->setCc([$mailData['mail_owner_cc'] => $mailData['mail_owner_cc_title']]);
// Ask for a delivery receipt from the recipient to be sent to
if(isset($mailCfg[self::SEND_READ_REC_TO]))
$oMessage->setReadReceiptTo($mailCfg[self::SEND_READ_REC_TO]);
// Create the attachment
if(!empty($mailData['mail_attachment']))
$oMessage->attach(Swift_Attachment::fromPath($mailData['mail_attachment']));
// Send the message
return $oMailer->send($oMessage);
}
/**
* Function to get Swift Mail transport
*
* @category LIB mail
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @param array $mailCfg - mail configuration data
* @returns Swift_Transport
*/
private function getSwiftMailerTransport(array $mailCfg): Swift_Transport
{
if (!defined('SEND_MAIL_SERVER')) define('SEND_MAIL_SERVER', 'MAILHOG');
switch (SEND_MAIL_SERVER) {
case 'SMTP':
$oTransport = new Swift_SmtpTransport(
$mailCfg[self::SERVER],
$mailCfg[self::PORT],
$mailCfg[self::ENCRYPTION]
);
$oTransport->setUsername($mailCfg[self::LOGIN])->setPassword($mailCfg[self::PWD]);
break;
case 'MAILHOG':
default:
$sendMailCommand = (defined('SEND_MAIL_COMMAND_PATH') ? SEND_MAIL_COMMAND_PATH : ini_get('sendmail_path'));
$oTransport = new Swift_SendmailTransport($sendMailCommand);
break;
}
return $oTransport;
}
/**
* Function to get mail firs name
*
* @category LIB mail
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @param string $email - provided email
* @return bool or email name
*/
public static function getMailName($email){
if($email){
$ch = explode('@', $email);
if(count($ch)>1){
return $ch[0];
}
}
return false;
}
/**
* Function to get mail domain name
*
* @category LIB mail
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @param string $email - provided email
* @return bool or email name
*/
public static function getDomainName($email){
if($email){
$ch = explode('@', $email);
if(count($ch)>1){
return $ch[1];
}
}
return false;
}
/**
* Function to check if mail with pattern has been sent or prepared
*
* @category LIB mail
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @param string $email - provided email
* @param string $pattern - pattern key to check
* @param mixed $timeFrame - time frame to search mail for
* @return bool or email name
*/
public function isMailSent($email, $pattern, $timeFrame = false){
// Setup base timeframe
if(!$timeFrame || !is_array($timeFrame)){
$timeFrame = ($timeFrame > 0 ? $timeFrame : 24*60*60);
$timeFrame = array(
'from' => time() - $timeFrame,
'till' => time()
);
}
if($id = $this->module->isMailSent($email, $pattern, $timeFrame)){
return true;
}
return false;
}
/**
* Function to strip unused constants in mail
*
* @category APP pubPPR
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @param string $sMailData - mail data to check
* @returns void
*/
public static function stripLeftDataVariableInMailContent(&$sMailData) {
$sMailData = preg_replace('/(\[%[\w\d\n\t_ \|\-]*%\])/i', ' ', $sMailData);
}
/**
* Function to replace data array - like table based on key & class to search and dublicate
*
* @category APP pubPPR
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @param string $tag - tag in htm to search
* @param array $cfg - config array with data to compose
* @param string $mailData - mail data in which to search
* @returns bool true
*/
public function composeArrayDataReplace($tag, $cfg, &$mailData) {
if($tag && @$cfg['class'] && count($cfg['data'])){
// Search for replica row in mail data
$tlen = strlen("</{$tag}>");
$start = strpos($mailData, '<' . $tag . ' class="' . $cfg['class']);
$end = strpos($mailData, "</{$tag}>", $start);
// Extract string to multiple & replace with key
$sStr = substr($mailData, $start, $end-$start+$tlen);
$mailData = str_replace($sStr, '{ROW_DATA}', $mailData);
// Setup replacement keys
$tableData = "";
foreach ($cfg['data'] as $item) {
$replace = array();
$replaceData = array();
if($item && is_array($item)){
foreach ($item as $k=>$v) {
$replaceData[] = $v;
$replace[] = $k;
}
$tableData .= $t = str_replace($replace, $replaceData, $sStr);
}
}
// Replace constants
$mailData = str_replace('{ROW_DATA}', $tableData, $mailData);
}
}
}