first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

360
admin/emails.php Normal file
View File

@@ -0,0 +1,360 @@
<?php
use KupShop\KupShopBundle\Config;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Email\EmailGroupTypeEnum;
use KupShop\KupShopBundle\Email\OrderMessageEmail;
use KupShop\KupShopBundle\Email\UserMessagesInterface;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Mail\Email;
use KupShop\KupShopBundle\Util\Mail\EmailLocator;
use KupShop\KupShopBundle\Util\Mail\EmailSender;
use KupShop\KupShopBundle\Util\Mail\SMSSender;
use KupShop\OrderingBundle\Util\Attachment\AttachmentLocator;
use KupShop\ReturnsBundle\Util\ReturnsUtil;
use Symfony\Component\Mime\Exception\RfcComplianceException;
$main_class = 'AdminEmails';
class AdminEmails extends Window
{
protected $template = 'window/emails.tpl';
private $languageContext;
public function __construct()
{
$this->languageContext = ServiceContainer::getService(LanguageContext::class);
}
public function hasRights($name = null)
{
switch ($name) {
case self::RIGHT_DUPLICATE:
case self::RIGHT_DELETE:
return false;
default:
return true;
}
}
public function get_vars()
{
$vars = parent::get_vars();
$settings = Settings::createFromDB();
$pageVars['data'] = [
'order_send_received_mail' => $settings->order_send_received_mail,
'order_send_status_mail' => $settings->order_send_status_mail,
'order_send_to_shopkeeper' => $settings->order_send_to_shopkeeper,
'order_shopkeeper_mail' => $settings->order_shopkeeper_mail,
'default_email' => $settings->order_shopkeeper_mail,
'smtp' => $settings->smtp ?? [],
'email_default_signature' => $settings->email_default_signature ?? [],
'email_allowed_recipient_domains' => $settings->email_allowed_recipient_domains ?? '',
];
/** @var Email $email */
$email = ServiceContainer::getService(Email::class);
$pageVars['email'] = $email;
/** @var SMSSender $smsSender */
$smsSender = ServiceContainer::getService(SMSSender::class);
$pageVars['SMSSenderBackend'] = $smsSender->getBackend();
// Get email groups from enum, so we can display them in right order
array_map(function ($enum) use (&$pageVars) {
$pageVars['emails_messages'][$enum->value] = ['doNotShow' => true];
}, EmailGroupTypeEnum::cases());
$default_emails = [];
foreach ($email->getDefaultTypes() as $type) {
$emailService = $email->getServiceByType($type);
if ($emailService::getGroup() == EmailGroupTypeEnum::HIDDEN->value) {
continue;
}
if ($emailService instanceof UserMessagesInterface) {
// Fetch UserMessage types for group
$pageVars['messages_types'][$emailService::getGroup()] = $emailService::getType();
$pageVars['emails_messages'][$emailService::getGroup()] = $emailService->getMessages($this->languageContext->getDefaultId());
foreach ($pageVars['emails_messages'][$emailService::getGroup()] as &$message) {
$message['attachments'] = $this->prepareAttachments($message['attachments']);
}
continue;
}
$default_emails[$emailService::getGroup()][$type] = $emailService->getEmailTemplate($this->languageContext->getDefaultId());
$default_emails[$emailService::getGroup()][$type]['isAnswer'] = $emailService->isAnswer ?? null;
if (empty($default_emails[$emailService::getGroup()][$type]['id'])) {
$default_emails[$emailService::getGroup()][$type]['id'] = rand(-100, -200);
}
$default_emails[$emailService::getGroup()][$type]['name'] = $emailService::getName();
$default_emails[$emailService::getGroup()][$type]['attachments'] = $this->prepareAttachments($default_emails[$emailService::getGroup()][$type]['attachments']);
$default_emails[$emailService::getGroup()][$type]['default_template'] = $emailService->getDefaultEmail();
$default_emails[$emailService::getGroup()][$type]['attachmentsGroup'] = $emailService::getGroup();
}
// Sort groups by desired order
$sorted_default_emails = array_merge(array_flip([
EmailGroupTypeEnum::ORDER->value,
EmailGroupTypeEnum::FORMS->value,
EmailGroupTypeEnum::RETURN->value,
EmailGroupTypeEnum::RECLAMATION->value,
EmailGroupTypeEnum::OTHER->value,
]), $default_emails);
// Filter empty groups
$pageVars['emails'] = array_intersect_key($sorted_default_emails, $default_emails);
if (!empty($pageVars['emails'][EmailGroupTypeEnum::OTHER->value][Email::TYPE_BASIC_TEMPLATE]['email'])) {
$pageVars['data']['default_email'] = $pageVars['emails'][EmailGroupTypeEnum::OTHER->value][Email::TYPE_BASIC_TEMPLATE]['email'];
}
$pageVars['statuses'] = [
// -100 - hardcoded non existing status for storno, so it can be selected
'order' => Config::get()['Order']['Status']['global'] + ['-100' => 'storno'],
];
if (findModule(\Modules::RETURNS)) {
$pageVars['statuses']['return'] = ServiceContainer::getService(ReturnsUtil::class)->getStatuses();
}
// attachments
$attachmentLocator = ServiceContainer::getService(AttachmentLocator::class);
$pageVars['attachments'] = $attachmentLocator->getAttachments('ALL');
$vars['body'] = $pageVars;
return $vars;
}
private function prepareAttachments($attachments)
{
if (!empty($attachments)) {
return json_decode($attachments, true);
}
return [];
}
public function handle()
{
$this->tryRights('EDIT');
$data = getVal('data');
$Submit = getVal('Submit');
$acn = getVal('acn');
if (!empty($data) && !empty($Submit)) {
$ErrStr = $this->saveSettings($data);
redirect('launch.php?s=emails.php&acn=edit&flap='.getVal('flap').'&ErrStr='.$ErrStr);
} elseif (str_starts_with($acn ?? '', 'SendTestEmail_')) {
$this->sendTestEmail(str_replace('SendTestEmail_', '', $acn));
} else {
Base::handle();
}
}
public function handlePlaceholders()
{
$type = getVal('type');
$emailLocator = ServiceContainer::getService(EmailLocator::class);
$emailService = $emailLocator->getEmailService($type);
// TODO: HACK Bez testEmail padají applyPlaceholders, protože v nich lidi šahají na data (->getOrder()), který tam v tohle případě nejsou.
// TODO: HACK Proto volám testEmail, abych nasetoval nějaký testovací data a nepadalo to. Ale applyPlaceholders by nemělo záviset na datech.
$order_message = getVal('order_message');
if ($emailService instanceof OrderMessageEmail) {
$emailService->setOrderMessage($order_message);
}
$emailService->testEmail();
foreach ($emailLocator->getEmailRegisters() as $register) {
$register->applyPlaceholders($emailService);
}
$placeholders = $emailService::getPlaceholders();
foreach ($emailService->getEntityPlaceholders() as $placeholder) {
$placeholders[$emailService::getType()][$placeholder->code] = ['text' => $placeholder->description];
}
$smarty = createSmarty(true, true);
$smarty->assign([
'type' => $type,
'name' => $emailService::getName(),
'placeholders' => $placeholders,
]);
$smarty->display('window/emails.placeholders.tpl');
exit;
}
public function handleTest()
{
$type = getVal('type');
$emailLocator = ServiceContainer::getService(EmailLocator::class);
$emailService = $emailLocator->getEmailService($type);
$typeTestEmail = $emailService->getTestType();
$order_message = getVal('order_message');
if ($emailService instanceof OrderMessageEmail) {
$emailService->setOrderMessage($order_message);
}
if ($typeTestEmail && $entityID = getVal('entityID')) {
$emailService->setTestEntity($entityID);
}
try {
if ($type == 'BASIC_TEMPLATE') {
$message = ['body' => '<p>Testovací email.</p>', 'subject' => 'Testovací email'];
$message = $emailService->renderEmail($message);
$message['body'] = replacePlaceholders($message['body'], [], [$emailService, 'replacePlaceholdersItem']);
} else {
$message = $emailService->testEmail();
}
} catch (InvalidArgumentException $e) {
$this->returnError($e->getMessage());
}
$smarty = createSmarty(true, true);
$smarty->assign([
'type' => $type,
'typeTestEmail' => $typeTestEmail,
'entityID' => $entityID ?? '',
'email' => $message,
'order_message' => $order_message,
'placeholders' => $emailService::getPlaceholders() ?? '',
]);
$smarty->display('window/emails.preview.tpl');
exit;
}
public function sendTestEmail($id)
{
$this->saveSettings(getVal('data'));
$emailSender = ServiceContainer::getService(EmailSender::class);
try {
$email = Settings::getDefault()->order_shopkeeper_mail;
$testEmail = explode(',', getVal('data')['smtp'][$id]['allowed_senders']);
$testEmail = trim(reset($testEmail));
if (!$testEmail || $testEmail == '*') {
$testEmail = $email;
}
$message = $emailSender->createMessage($testEmail, $email, 'Testovací email', 'Testovací email pro kontrolu nastavení SMTP serveru.', 'text/html');
$emailSender->realSendMessage($message);
} catch (RfcComplianceException $e) {
$this->returnError('Nelze odeslat testovací e-mail. E-mailová adresa nemá správný formát');
} catch (Throwable $e) {
$error = $e->getMessage();
$this->returnError("Nelze odeslat testovací email: {$error}");
}
$this->returnOK('Testovací zpráva odeslána.');
}
protected function saveSettings($data)
{
$settings = Settings::createFromDB();
$edited = [];
$types = ['emails_messages'];
array_map(function ($enum) use (&$types) {
$types[] = $enum->value;
}, EmailGroupTypeEnum::cases());
foreach ($data as $type => $values) {
if (!in_array($type, $types)) {
continue;
}
foreach ($values as $id => $email) {
if ($id == 0) {
continue;
}
switch ($email['type']) {
case 'ORDER_CREATE':
$edited['order_send_received_mail'] = $email['enabled'];
break;
case 'ORDER_STATUS_CHANGE':
$edited['order_send_status_mail'] = $email['enabled'];
break;
case 'ORDER_CREATE_ADMIN':
$edited['order_send_to_shopkeeper'] = $email['enabled'];
break;
}
$email['order_status'] = $email['order_status'] == '' ? null : $email['order_status'];
$email['name'] = trim($email['name'] ?? '');
if (!empty($email['attachments'])) {
$email['attachments'] = json_encode($email['attachments']);
} else {
$email['attachments'] = null;
}
if (empty($email['body'])) {
continue;
}
/** @var Email $email */
$emailService = ServiceContainer::getService(Email::class);
$email['body'] = $emailService->stripEmail($email['body']);
if (!empty($email['delete'])) {
if ($email['system_msg'] != 'Y') {
$this->deleteSQL('emails', ['id' => $id]);
}
continue;
}
if ($email['type'] == \KupShop\KupShopBundle\Email\BaseEmail::getType() && empty($email['email'])) {
$email['email'] = $settings->order_shopkeeper_mail;
}
if ($id > 0) {
$this->updateSQL('emails', $email, ['id' => $id]);
} else {
$this->insertSQL('emails', $email, ['id']);
}
}
}
$edited['order_shopkeeper_mail'] = $data['order_shopkeeper_mail'];
$edited['bounce_email'] = $data['bounce_email'];
$edited['archive_email'] = $data['archive_email'];
$edited['email_allowed_recipient_domains'] = $data['email_allowed_recipient_domains'];
if (!empty($data['smtp'])) {
$edited['smtp'] = $data['smtp'];
}
if (!empty($data['email_default_signature'])) {
$edited['email_default_signature'] = $data['email_default_signature'];
}
$data['elninoEmailTemplates'] = array_filter($data['elninoEmailTemplates'] ?? [], function ($v) {
return $v['ticketState'] !== false && !empty($v['statuses']) && !empty($v['userMessage']) && empty($v['delete']);
});
if (!empty($data['elninoEmailTemplates'])) {
$data['elninoEmailTemplates'] = array_combine(range(1, count($data['elninoEmailTemplates'])), array_values($data['elninoEmailTemplates']));
}
$edited['elninoEmailTemplates'] = json_encode($data['elninoEmailTemplates']);
$settings->loadFromArray($edited);
if ($settings->saveToDB()) {
$ErrStr = $GLOBALS['txt_str']['status']['saved'];
} else {
$ErrStr = $GLOBALS['txt_str']['status']['scripterror'];
}
Settings::clearCache(true);
return $ErrStr;
}
}