Current File : /var/www/vinorea/src/Core/Domain/CustomerService/CommandHandler/AddOrderCustomerMessageHandler.php |
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
*/
namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\CommandHandler;
use Configuration;
use Customer;
use CustomerMessage;
use CustomerThread;
use Mail;
use Order;
use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml;
use PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Command\AddOrderCustomerMessageCommand;
use PrestaShop\PrestaShop\Core\Domain\CustomerMessage\CommandHandler\AddOrderCustomerMessageHandlerInterface;
use PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Exception\CannotSendEmailException;
use PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Exception\CustomerMessageConstraintException;
use PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Exception\CustomerMessageException;
use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderNotFoundException;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Tools;
class AddOrderCustomerMessageHandler implements AddOrderCustomerMessageHandlerInterface
{
/**
* @var int
*/
private $contextShopId;
/**
* @var int
*/
private $contextLanguageId;
/**
* @var int
*/
private $contextEmployeeId;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* @var ValidatorInterface
*/
private $validator;
/**
* @param TranslatorInterface $translator
* @param ValidatorInterface $validator
* @param int $contextShopId
* @param int $contextLanguageId
* @param int $contextEmployeeId
*/
public function __construct(
TranslatorInterface $translator,
ValidatorInterface $validator,
int $contextShopId,
int $contextLanguageId,
int $contextEmployeeId
) {
$this->contextShopId = $contextShopId;
$this->contextLanguageId = $contextLanguageId;
$this->contextEmployeeId = $contextEmployeeId;
$this->translator = $translator;
$this->validator = $validator;
}
/**
* {@inheritdoc}
*
* @throws CustomerMessageException
* @throws OrderNotFoundException
*/
public function handle(AddOrderCustomerMessageCommand $command): void
{
$this->assertIsValidMessage($command->getMessage());
$order = new Order($command->getOrderId()->getValue());
if (0 >= $order->id) {
throw new OrderNotFoundException($command->getOrderId(), "Order with id {$command->getOrderId()->getValue()} was not found");
}
$customer = new Customer($order->id_customer);
if (0 >= $customer->id) {
throw new CustomerMessageException("Associated order customer with id {$command->getOrderId()->getValue()} was not found", CustomerMessageException::ORDER_CUSTOMER_NOT_FOUND);
}
$customerServiceThreadId = CustomerThread::getIdCustomerThreadByEmailAndIdOrder(
$customer->email,
$order->id
);
if (!$customerServiceThreadId) {
try {
$customerServiceThreadId = $this->createCustomerMessageThread($order);
} catch (\PrestaShopException $e) {
throw new CustomerMessageException('An unexpected error occurred when creating customer message thread', 0, $e);
}
}
try {
$this->createMessage($customerServiceThreadId, $command);
} catch (\PrestaShopException $e) {
throw new CustomerMessageException('An unexpected error occurred when creating customer message', 0, $e);
}
$failedMailSentMessage = 'An unexpected error occurred when sending the email';
try {
$isSent = $this->sendMail($customer, $order, $command);
if (!$isSent) {
throw new CannotSendEmailException($failedMailSentMessage);
}
} catch (\PrestaShopException $e) {
throw new CannotSendEmailException($failedMailSentMessage, 0, $e);
}
}
/**
* @param string $message
*
* @throws CustomerMessageConstraintException
*/
private function assertIsValidMessage(string $message): void
{
$errors = $this->validator->validate($message, new CleanHtml());
if (0 !== \count($errors)) {
throw new CustomerMessageConstraintException(sprintf('Given message "%s" contains javascript events or script tags', $message), CustomerMessageConstraintException::INVALID_MESSAGE);
}
}
/**
* Creates customer message thread which groups customer message in an order group.
*
* @param Order $order
*
* @return int
*
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException
*/
private function createCustomerMessageThread(Order $order): int
{
$orderCustomer = new Customer($order->id_customer);
$customerThread = new CustomerThread();
$customerThread->id_contact = 0;
$customerThread->id_customer = (int) $order->id_customer;
$customerThread->id_shop = $this->contextShopId;
$customerThread->id_order = $order->id;
$customerThread->id_lang = $this->contextLanguageId;
$customerThread->email = $orderCustomer->email;
$customerThread->status = 'open';
$customerThread->token = Tools::passwdGen(12);
$customerThread->add();
return $customerThread->id;
}
/**
* Creates actual message.
*
* @param int $customerServiceThreadId
* @param AddOrderCustomerMessageCommand $command
*
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException
*/
private function createMessage(int $customerServiceThreadId, AddOrderCustomerMessageCommand $command): void
{
$customerMessage = new CustomerMessage();
$customerMessage->id_customer_thread = $customerServiceThreadId;
$customerMessage->id_employee = $this->contextEmployeeId;
$customerMessage->message = $command->getMessage();
$customerMessage->private = $command->isPrivate();
$customerMessage->add();
}
/**
* Sends email to customer
*
* @param Customer $customer
* @param Order $order
* @param AddOrderCustomerMessageCommand $command
*
* @return bool
*
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException
*/
private function sendMail(Customer $customer, Order $order, AddOrderCustomerMessageCommand $command): bool
{
if ($command->isPrivate()) {
return true;
}
$message = $command->getMessage();
if (Configuration::get('PS_MAIL_TYPE', null, null, $order->id_shop) != Mail::TYPE_TEXT) {
$message = Tools::nl2br(Tools::htmlentitiesUTF8($command->getMessage()));
}
$orderLanguage = $order->getAssociatedLanguage();
$varsTpl = [
'{lastname}' => $customer->lastname,
'{firstname}' => $customer->firstname,
'{id_order}' => $order->id,
'{order_name}' => $order->getUniqReference(),
'{message}' => $message,
];
return Mail::Send(
(int) $orderLanguage->getId(),
'order_merchant_comment',
$this->translator->trans(
'New message regarding your order',
[],
'Emails.Subject',
$orderLanguage->locale
),
$varsTpl,
$customer->email,
$customer->firstname . ' ' . $customer->lastname,
null,
null,
null,
null,
_PS_MAIL_DIR_,
true,
(int) $order->id_shop
);
}
}