459 lines
16 KiB
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_LORETA_LV = '1';
|
|
|
|
const CC_SHOP_OWNER = 'cc_shop_owner'; // TODO: šo jāuzseto pareizu
|
|
|
|
/* MAIL SERVER CONSTANTS */
|
|
static array $SERVER_CFG = [
|
|
self::MAIL_SERVER_LORETA_LV => [
|
|
self::LOGIN => 'info@elixirvault.lv',
|
|
self::PWD => 'dkq2fecDqy8J43m!@',
|
|
self::PORT => 465,
|
|
self::ENCRYPTION => 'ssl',
|
|
self::SERVER => 'smtppro.zoho.eu',
|
|
|
|
self::SENDER => 'info@elixirvault.lv',
|
|
self::SEND_READ_REC_TO => 'info@elixirvault.lv',
|
|
self::REWRITE_SENDER_NAME_TO => 'ELIXIR VAULT',
|
|
],
|
|
];
|
|
|
|
const MAIL_REQUEST_KEY = 'LORETA-A94A8FE5CCB19BA61C4C0873D391E987982FBBD3';
|
|
CONST MAIL_REQUEST_PROCESS_ID = 'loreta_mailer';
|
|
CONST MAIL_TRACKING_STR = '[%TRACKING_IMG%]';
|
|
CONST EHLO_SERVER = 'www.elixirvault.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_LORETA_LV, $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_LORETA_LV, $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);
|
|
}
|
|
}
|
|
}
|