171 lines
6.4 KiB
PHP
171 lines
6.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Esun\ContactPopup\Controller\Index;
|
|
|
|
use Esun\ContactPopup\Model\Submission;
|
|
use Esun\ContactPopup\Model\SubmissionFactory;
|
|
use Magento\Contact\Model\ConfigInterface;
|
|
use Magento\Contact\Model\MailInterface;
|
|
use Magento\Framework\App\Action\HttpPostActionInterface;
|
|
use Magento\Framework\App\RequestInterface;
|
|
use Magento\Framework\Controller\Result\Json;
|
|
use Magento\Framework\Controller\Result\JsonFactory;
|
|
use Magento\Framework\DataObject;
|
|
use Magento\Framework\Escaper;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
class Post implements HttpPostActionInterface
|
|
{
|
|
private const ALLOWED_CATEGORIES = [
|
|
'Product',
|
|
'Technical support',
|
|
'Cooperation',
|
|
'Other',
|
|
];
|
|
|
|
public function __construct(
|
|
private readonly RequestInterface $request,
|
|
private readonly JsonFactory $jsonFactory,
|
|
private readonly ConfigInterface $contactsConfig,
|
|
private readonly MailInterface $mail,
|
|
private readonly SubmissionFactory $submissionFactory,
|
|
private readonly Escaper $escaper,
|
|
private readonly LoggerInterface $logger
|
|
) {
|
|
}
|
|
|
|
public function execute(): Json
|
|
{
|
|
$result = $this->jsonFactory->create();
|
|
|
|
try {
|
|
$data = $this->validateRequest();
|
|
$submission = $this->saveSubmission($data);
|
|
} catch (\Magento\Framework\Exception\LocalizedException $exception) {
|
|
return $this->errorResult($result, $exception->getMessage(), 422);
|
|
} catch (\Throwable $exception) {
|
|
$this->logger->critical($exception);
|
|
return $this->errorResult($result, __('Unable to save your message. Please try again later.'), 500);
|
|
}
|
|
|
|
$this->sendMail($submission, $data);
|
|
|
|
return $result->setData([
|
|
'success' => true,
|
|
'message' => (string)__('Thanks for contacting us. We will respond to you as soon as possible.'),
|
|
]);
|
|
}
|
|
|
|
private function validateRequest(): array
|
|
{
|
|
$company = trim((string)$this->request->getParam('company', ''));
|
|
$category = trim((string)$this->request->getParam('question_category', ''));
|
|
$name = trim((string)$this->request->getParam('name', ''));
|
|
$email = trim((string)$this->request->getParam('email', ''));
|
|
$country = trim((string)$this->request->getParam('country', ''));
|
|
$details = trim((string)$this->request->getParam('details', ''));
|
|
|
|
if (trim((string)$this->request->getParam('hideit', '')) !== '') {
|
|
throw new \Magento\Framework\Exception\LocalizedException(__('Unable to submit the form.'));
|
|
}
|
|
if (!in_array($category, self::ALLOWED_CATEGORIES, true)) {
|
|
throw new \Magento\Framework\Exception\LocalizedException(__('Select a question category.'));
|
|
}
|
|
if ($name === '') {
|
|
throw new \Magento\Framework\Exception\LocalizedException(__('Enter your name.'));
|
|
}
|
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
throw new \Magento\Framework\Exception\LocalizedException(__('Enter a valid email address.'));
|
|
}
|
|
if ($country === '') {
|
|
throw new \Magento\Framework\Exception\LocalizedException(__('Enter your country.'));
|
|
}
|
|
if ($details === '') {
|
|
throw new \Magento\Framework\Exception\LocalizedException(__('Enter the details.'));
|
|
}
|
|
if (
|
|
mb_strlen($company) > 255 || mb_strlen($name) > 255 ||
|
|
mb_strlen($email) > 255 || mb_strlen($country) > 255
|
|
) {
|
|
throw new \Magento\Framework\Exception\LocalizedException(__('One or more fields are too long.'));
|
|
}
|
|
if (mb_strlen($details) > 5000) {
|
|
throw new \Magento\Framework\Exception\LocalizedException(__('The details must not exceed 5000 characters.'));
|
|
}
|
|
|
|
return compact('company', 'category', 'name', 'email', 'country', 'details');
|
|
}
|
|
|
|
private function saveSubmission(array $data): Submission
|
|
{
|
|
$submission = $this->submissionFactory->create();
|
|
$submission->setData([
|
|
'company' => $data['company'],
|
|
'question_category' => $data['category'],
|
|
'name' => $data['name'],
|
|
'email' => $data['email'],
|
|
'country' => $data['country'],
|
|
'details' => $data['details'],
|
|
'mail_status' => 'pending',
|
|
]);
|
|
$submission->save();
|
|
return $submission;
|
|
}
|
|
|
|
private function sendMail(Submission $submission, array $data): void
|
|
{
|
|
if (!$this->contactsConfig->isEnabled()) {
|
|
$submission->setData('mail_status', 'disabled')->save();
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$this->mail->send($data['email'], ['data' => new DataObject($this->buildMailData($data))]);
|
|
$submission->setData('mail_status', 'sent')->setData('mail_error', null)->save();
|
|
} catch (\Throwable $exception) {
|
|
$this->logger->critical($exception);
|
|
try {
|
|
$submission->setData('mail_status', 'failed')
|
|
->setData('mail_error', mb_substr($exception->getMessage(), 0, 2000))
|
|
->save();
|
|
} catch (\Throwable $saveException) {
|
|
$this->logger->critical($saveException);
|
|
}
|
|
}
|
|
}
|
|
|
|
private function buildMailData(array $data): array
|
|
{
|
|
$message = [
|
|
$this->mailLine(__('Company Name'), $data['company'] !== '' ? $data['company'] : '-'),
|
|
$this->mailLine(__('Question Category'), $data['category']),
|
|
$this->mailLine(__('Country'), $data['country']),
|
|
'',
|
|
$this->escaper->escapeHtml((string)__('Details')) . ':<br>' .
|
|
nl2br($this->escaper->escapeHtml($data['details']), false),
|
|
];
|
|
|
|
return [
|
|
'name' => $data['name'],
|
|
'email' => $data['email'],
|
|
'telephone' => '',
|
|
'comment' => implode('<br>', $message),
|
|
];
|
|
}
|
|
|
|
private function mailLine(\Stringable|string $label, string $value): string
|
|
{
|
|
return $this->escaper->escapeHtml((string)$label) . ': ' . $this->escaper->escapeHtml($value);
|
|
}
|
|
|
|
private function errorResult(Json $result, \Stringable|string $message, int $statusCode): Json
|
|
{
|
|
$result->setHttpResponseCode($statusCode);
|
|
return $result->setData([
|
|
'success' => false,
|
|
'message' => (string)$message,
|
|
]);
|
|
}
|
|
}
|