Files
ave-cms-alt/functions/func.mail.php
2025-10-11 17:17:12 +05:00

353 lines
14 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* AVE.cms
*
* @package AVE.cms
* @version 3.x
* @filesource
* @copyright © 2007-2014 AVE.cms, http://www.ave-cms.ru
*
* @license GPL v.2
*/
// ----------------------------------------------------------------------
// БЛОК SYMFONY MAILER: Подключение и использование пространств имен
// ----------------------------------------------------------------------
// Подключаем Composer Autoload
require_once BASE_DIR . '/lib/SymfonyMailer/vendor/autoload.php';
// Импорт необходимых классов Symfony Mailer
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Address;
// ----------------------------------------------------------------------
/**
* Отправка e-Mail
*
* @param string $to - email получателя
* @param string $body - текст сообщения
* @param string $subject - тема сообщения
* @param string $from_email - e-mail отправителя
* @param string $from_name - имя отправителя
* @param string $type - содержимое (html или text)
* @param array $attach - пути файлов вложений
* @param bool $saveattach - сохранять вложения после отправки в ATTACH_DIR?
* @param bool $signature - добавлять подпись из общих настроек?
*/
if (! function_exists('send_mail'))
{
function send_mail($to='', $body='', $subject='', $from_email='', $from_name='', $type='text', $attach=array(), $saveattach=true, $signature=true)
{
unset($transport, $message, $mailer);
$to = str_nospace($to);
$from_email = str_nospace($from_email);
// Определяем тип письма
$type = ((strtolower($type) == 'html' || strtolower($type) == 'text/html') ? 'text/html' : 'text/plain');
// Добавляем подпись, если просили
if ($signature)
{
if ($type == 'text/html')
{
$signature = '<br><br>' . nl2br(get_settings('mail_signature'));
}
else
{
$signature = "\r\n\r\n" . get_settings('mail_signature');
}
}
else $signature = '';
// Составляем тело письма
$body = stripslashes($body) . $signature;
if ($type == 'text/html')
{
$body = str_replace(array("\t","\r","\n"),'',$body);
$body = str_replace(array(' ','> <'),array(' ','><'),$body);
}
// ----------------------------------------------------
// БЛОК SYMFONY MAILER: Инициализация и настройка письма
// ----------------------------------------------------
$message = new Email();
$message->getHeaders()->addTextHeader('X-Mailer', 'AVE.cms Symfony Mailer');
$message->subject($subject);
// Отправитель
$message->from(new Address($from_email, $from_name));
// Получатель (разбиваем строку $to на массив адресов)
$to_addresses = array_map('trim', explode(',', $to));
$message->to(...$to_addresses);
// Тело письма
if ($type == 'text/html') {
$message->html($body);
$message->text(strip_tags($body)); // AltBody
} else {
$message->text($body);
}
// ----------------------------------------------------
// БЛОК SYMFONY MAILER: Прикрепление вложений
// ----------------------------------------------------
if ($attach)
{
foreach ($attach as $attach_file)
{
$file_path = trim($attach_file);
if ($file_path && file_exists($file_path)) {
$message->attachFromPath($file_path);
}
}
}
// ----------------------------------------------------
// БЛОК SYMFONY MAILER: Формирование DSN
// ----------------------------------------------------
$transport_dsn = '';
$mail_type = get_settings('mail_type');
switch ($mail_type) {
// Резервный DSN (если выбрано что-то неизвестное)
default:
$transport_dsn = 'native://default';
break;
// МЕТОД 'mail' (Самый простой и надежный)
case 'mail':
// DSN 'sendmail://default' использует внутреннюю, стабильную функцию PHP mail().
$transport_dsn = 'sendmail://default';
break;
// 2. МЕТОД 'sendmail' (Использует путь из настроек, но только если он работает, проверяйте на VDS командой # systemctl status sendmail)
case 'sendmail':
$path = get_settings('mail_sendmail_path'); // Берем путь из настроек
// DSN для прямого вызова исполняемого файла
$transport_dsn = 'sendmail://default?command=' . urlencode($path);
break;
case 'smtp':
// --- ОПТИМИЗАЦИЯ: Получаем дешифрованные настройки одним вызовом ---
// Пароль уже ДЕШИФРОВАН функцией get_settings()
$settings = get_settings();
$host = stripslashes($settings['mail_host']);
$port = (int)$settings['mail_port'];
$user = stripslashes($settings['mail_smtp_login']);
$pass = stripslashes($settings['mail_smtp_pass']);
// Получаем значение шифрования
$encrypt_setting = strtolower(stripslashes($settings['mail_smtp_encrypt']));
$scheme = 'smtp';
$encryption = '';
$extra_params = '';
// 1. Определяем тип шифрования и необходимость отключения проверки
if (str_contains($encrypt_setting, 'insecure')) {
// Если выбрано *_insecure, отключаем проверку
$extra_params = '&verify_peer=0';
// Извлекаем чистый тип шифрования (tls или ssl)
$encryption = str_replace('_insecure', '', $encrypt_setting);
} elseif ($encrypt_setting === 'tls' || $encrypt_setting === 'ssl') {
// Если выбрано обычное шифрование, включаем его (проверка peer=1 по умолчанию)
$encryption = $encrypt_setting;
}
// 2. Формируем DSN в зависимости от наличия шифрования
if ($encryption) {
// Если есть шифрование (tls или ssl), добавляем его и доп. параметры
$transport_dsn = sprintf('%s://%s:%s@%s:%d?encryption=%s%s',
$scheme,
urlencode($user),
urlencode($pass), // Здесь используется ДЕШИФРОВАННЫЙ пароль
$host,
$port,
$encryption, // 'tls' или 'ssl'
$extra_params // '' или '&verify_peer=0'
);
} else {
// Без шифрования (когда выбрано "Нет")
$transport_dsn = sprintf('smtp://%s:%s@%s:%d',
urlencode($user),
urlencode($pass), // Здесь используется ДЕШИФРОВАННЫЙ пароль
$host,
$port ?: 25 // Порт 25 по умолчанию
);
}
break;
}
// Сохраняем вложения в ATTACH_DIR, если просили
if ($attach && $saveattach)
{
$attach_dir = BASE_DIR . '/tmp/' . ATTACH_DIR . '/';
foreach ($attach as $file_path)
{
if ($file_path && file_exists($file_path))
{
$file_name = basename($file_path);
$file_name = str_replace(' ','',mb_strtolower(trim($file_name)));
if (file_exists($attach_dir . $file_name))
{
$file_name = rand(1000, 9999) . '_' . $file_name;
}
$file_path_new = $attach_dir . $file_name;
if (!@move_uploaded_file($file_path,$file_path_new))
{
copy($file_path,$file_path_new);
}
}
}
}
// ----------------------------------------------------
// БЛОК SYMFONY MAILER: Отправка и обработка ошибок
// ----------------------------------------------------
try {
// 1. Создаем транспорт из DSN
$transport = Transport::fromDsn($transport_dsn);
// 2. Создаем почтальона (Mailer)
$mailer = new Mailer($transport);
// 3. Отправляем сообщение
$mailer->send($message);
return true; // Успех
} catch (TransportExceptionInterface $e) {
// Записываем специфические ошибки Symfony Mailer в лог
reportLog('Не удалось отправить письма. Symfony Mailer Transport Error: ' . $e->getMessage());
return false; // Неудача
} catch (\Exception $e) {
// Общая ошибка (на всякий случай)
reportLog('Не удалось отправить письма. Symfony Mailer Fatal Error: ' . $e->getMessage());
return false;
}
// ----------------------------------------------------
// КОНЕЦ БЛОКА SYMFONY MAILER
// ----------------------------------------------------
}
}
if ( ! function_exists('safe_mailto'))
{
function safe_mailto($email, $title = '', $attributes = '')
{
$title = (string) $title;
if ($title == "")
{
$title = $email;
}
for ($i = 0; $i < 16; $i++)
{
$x[] = substr('<a href="mailto:', $i, 1);
}
for ($i = 0; $i < strlen($email); $i++)
{
$x[] = "|".ord(substr($email, $i, 1));
}
$x[] = '"';
if ($attributes != '')
{
if (is_array($attributes))
{
foreach ($attributes as $key => $val)
{
$x[] = ' '.$key.'="';
for ($i = 0; $i < strlen($val); $i++)
{
$x[] = "|".ord(substr($val, $i, 1));
}
$x[] = '"';
}
}
else
{
for ($i = 0; $i < strlen($attributes); $i++)
{
$x[] = substr($attributes, $i, 1);
}
}
}
$x[] = '>';
$temp = array();
for ($i = 0; $i < strlen($title); $i++)
{
$ordinal = ord($title[$i]);
if ($ordinal < 128)
{
$x[] = "|".$ordinal;
}
else
{
if (count($temp) == 0)
{
$count = ($ordinal < 224) ? 2 : 3;
}
$temp[] = $ordinal;
if (count($temp) == $count)
{
$number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);
$x[] = "|".$number;
$count = 1;
$temp = array();
}
}
}
$x[] = '<'; $x[] = '/'; $x[] = 'a'; $x[] = '>';
$x = array_reverse($x);
ob_start();
?><script type="text/javascript">
//<![CDATA[
var l=new Array();
<?php
$i = 0;
foreach ($x as $val){ ?>l[<?php echo $i++; ?>]='<?php echo $val; ?>';<?php } ?>
for (var i = l.length-1; i >= 0; i=i-1){
if
(l[i].substring(0, 1) == '|') document.write("&#"+unescape(l[i].substring(1))+";");
else
document.write(unescape(l[i]));}
//]]>
</script><?php
$buffer = ob_get_contents();
ob_end_clean();
return $buffer;
}
}
?>