410 lines
12 KiB
PHP
410 lines
12 KiB
PHP
<?php
|
|
|
|
namespace KupShop\ContentBundle\View;
|
|
|
|
use KupShop\ComponentsBundle\View\ComponentsViewInterface;
|
|
use KupShop\ComponentsBundle\View\ComponentsViewTrait;
|
|
use KupShop\ContentBundle\Event\FormEvent;
|
|
use KupShop\ContentBundle\Util\Captcha;
|
|
use KupShop\ContentBundle\View\Exception\ValidationException;
|
|
use KupShop\KupShopBundle\Util\Mail\EmailCheck;
|
|
use KupShop\KupShopBundle\Util\StringUtil;
|
|
use KupShop\KupShopBundle\Views\Traits\RequestTrait;
|
|
use KupShop\KupShopBundle\Views\View;
|
|
use KupShop\OrderingBundle\Util\UserContent\UserContent;
|
|
use Query\Operator;
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
|
|
class ContactFormView extends View implements ComponentsViewInterface
|
|
{
|
|
use \DatabaseCommunication;
|
|
use RequestTrait;
|
|
use ComponentsViewTrait;
|
|
|
|
protected $formData = [];
|
|
protected $emailSent = false;
|
|
|
|
/** @var string Name of form to use - defined in config.modules.forms */
|
|
protected $formType = 'kontakt';
|
|
|
|
private $formConfig;
|
|
/**
|
|
* @var SessionInterface
|
|
*/
|
|
private $session;
|
|
|
|
/**
|
|
* @var EmailCheck
|
|
*/
|
|
private $emailCheck;
|
|
|
|
/**
|
|
* @var string Backward Compatibility for form templates without user messages
|
|
*/
|
|
protected $error;
|
|
|
|
/**
|
|
* @var bool Use.error for reporting error to template
|
|
*/
|
|
protected $compatibilityMode = false;
|
|
|
|
private $dispatcher;
|
|
|
|
protected UserContent $userContent;
|
|
|
|
public function __construct(SessionInterface $session, EventDispatcherInterface $dispatcher, EmailCheck $emailCheck, UserContent $userContent)
|
|
{
|
|
$this->session = $session;
|
|
$this->dispatcher = $dispatcher;
|
|
$this->emailCheck = $emailCheck;
|
|
$this->userContent = $userContent;
|
|
}
|
|
|
|
public function getConfig()
|
|
{
|
|
if (is_null($this->formConfig)) {
|
|
$config = $this->getDefaultConfig();
|
|
|
|
$this->formConfig = array_merge($config, $this->getCustomConfig());
|
|
}
|
|
|
|
return $this->formConfig;
|
|
}
|
|
|
|
public function getDefaultConfig()
|
|
{
|
|
$dbCfg = \Settings::getDefault();
|
|
|
|
return [
|
|
'title' => 'Kontaktní formulář',
|
|
'template' => 'form/contact.tpl',
|
|
'subject' => 'email/contact_subject.tpl',
|
|
'message' => 'email/contact_message.tpl',
|
|
'message_answer' => null,
|
|
'subject_answer' => null,
|
|
'email' => $dbCfg->order_shopkeeper_mail,
|
|
'required' => [
|
|
'email' => 'Email',
|
|
],
|
|
];
|
|
}
|
|
|
|
public function getCustomConfig()
|
|
{
|
|
$config = [];
|
|
if ($this->formType == 'dotaz-na-produkt') {
|
|
$config = [
|
|
'title' => 'Dotaz na produkt',
|
|
'template' => 'form/product_question.tpl',
|
|
'subject' => 'email/product_question_subject.tpl',
|
|
'message' => 'email/product_question.tpl',
|
|
'required' => [
|
|
'email' => 'Email',
|
|
'message' => 'Dotaz',
|
|
],
|
|
];
|
|
}
|
|
|
|
if ($this->formType == 'report-inappropriate-content') {
|
|
$config = [
|
|
'title' => 'Nahlásit závadný obsah',
|
|
'template' => 'form/report-inappropriate-content.tpl',
|
|
'subject' => 'email/report-inappropriate-content_subject.tpl',
|
|
'message' => 'email/report-inappropriate-content.tpl',
|
|
'message_answer' => 'email/report-inappropriate-content_answer.tpl',
|
|
'subject_answer' => 'email/report-inappropriate-content_subject_answer.tpl',
|
|
'required' => [
|
|
'reason' => 'Důvod',
|
|
],
|
|
];
|
|
}
|
|
|
|
$form = findModule('forms', $this->formType, []);
|
|
|
|
// TODO: Odstranit tohle az bude findModule skutecne vzdy vracet fallback
|
|
if (!is_array($form)) {
|
|
$form = [];
|
|
}
|
|
|
|
$config = array_merge($config, $form);
|
|
|
|
$translate_config = translate($this->formType, 'forms', true);
|
|
if (is_array($translate_config)) {
|
|
$config = array_merge($config, $translate_config);
|
|
}
|
|
|
|
return $config;
|
|
}
|
|
|
|
protected function getEmails()
|
|
{
|
|
$from = getVal('email', $this->getFormData());
|
|
$send_to = getVal('send_to', $this->getFormData());
|
|
$bcc = getVal('bcc', $this->getFormData());
|
|
|
|
if (!$from) {
|
|
throw new \Exception('ContactFormView: Undefined source email address');
|
|
}
|
|
|
|
if (is_callable($this->getConfig()['email'])) {
|
|
$email = $this->getConfig()['email']();
|
|
} else {
|
|
$email = $this->getConfig()['email'];
|
|
}
|
|
|
|
return [
|
|
'from' => $from,
|
|
'to' => ($send_to) ? $send_to : $email,
|
|
'bcc' => ($bcc) ? [$bcc] : (isset($this->getConfig()['bcc']) ? [$this->getConfig()['bcc']] : []),
|
|
];
|
|
}
|
|
|
|
public function getTitle()
|
|
{
|
|
return $this->getConfig()['title'];
|
|
}
|
|
|
|
/**
|
|
* @param array $errors
|
|
*
|
|
* @return int
|
|
*
|
|
* @throws ValidationException
|
|
*/
|
|
public function validate($data, $form, &$errors = [])
|
|
{
|
|
// Check required fields
|
|
$required = getVal('required', $form, []);
|
|
foreach ($required as $field => $display) {
|
|
if (empty($data[$field])) {
|
|
$errors[] = $display;
|
|
}
|
|
}
|
|
|
|
if (!empty($errors)) {
|
|
throw new ValidationException(translate('errorRequiredMissing', 'form').join(', ', $errors));
|
|
}
|
|
|
|
// Logged users does not require CAPTCHA validation
|
|
if (!\User::getCurrentUser()) {
|
|
Captcha::checkCaptcha($data);
|
|
}
|
|
|
|
$emails = $this->getEmails();
|
|
$emailsValidate = array_map(function ($email) { return StringUtil::unicode_trim($email); },
|
|
array_merge([$emails['from']],
|
|
explode(',', $emails['to']),
|
|
$emails['bcc']));
|
|
|
|
foreach ($emailsValidate as $email) {
|
|
if (!empty($email) && !$this->emailCheck->isEmailDomainValid($email)) {
|
|
throw new ValidationException(translate('errorInvalidEmail', 'form').htmlentities($email));
|
|
}
|
|
}
|
|
|
|
$this->dispatcher->dispatch(new FormEvent($this->formType, $data, $form), FormEvent::FORM_VALIDATE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
protected function getAttachments()
|
|
{
|
|
$attachments = [];
|
|
|
|
foreach ($_FILES as $file) {
|
|
if (is_array($file['name'])) {
|
|
foreach ($file['name'] as $index => $name) {
|
|
if (!empty($name)) {
|
|
$attachments[] = ['path' => $file['tmp_name'][$index], 'filename' => $name];
|
|
}
|
|
}
|
|
} else {
|
|
if (!empty($file['tmp_name'])) {
|
|
$attachments[] = ['path' => $file['tmp_name'], 'filename' => $file['name']];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $attachments;
|
|
}
|
|
|
|
protected function saveUser($from)
|
|
{
|
|
$form_fields = [
|
|
'figure' => 'N',
|
|
];
|
|
|
|
$confirmed = false;
|
|
if (!empty($this->formData['get_news']) && $this->formData['get_news'] == 'force') {
|
|
$this->formData['get_news'] = 'Y';
|
|
$confirmed = true;
|
|
}
|
|
|
|
$user_fields = [
|
|
'name', 'surname', 'phone', 'firm', 'ico', 'dic', 'street', 'city', 'zip', 'country',
|
|
'delivery_name', 'delivery_surname', 'delivery_firm', 'delivery_street', 'delivery_city', 'delivery_zip', 'delivery_country',
|
|
'get_news', 'custom_data', 'copy_email',
|
|
];
|
|
|
|
foreach ($user_fields as $field) {
|
|
$value = getVal($field, $this->formData);
|
|
if (!empty($value)) {
|
|
$form_fields[$field] = $value;
|
|
}
|
|
}
|
|
|
|
if (!empty($form_fields['custom_data'])) {
|
|
$form_fields['custom_data'] = json_encode($form_fields['custom_data']);
|
|
}
|
|
|
|
if (($form_fields['get_news'] ?? null) == 'Y' && $this->selectSQL('users', ['email' => $from, 'figure' => 'N'])->fetch()) {
|
|
$values = $form_fields;
|
|
unset($values['get_news']);
|
|
sqlQueryBuilder()->update('users')->directValues($values)->where(Operator::equals(['email' => $from]))->execute();
|
|
}
|
|
|
|
addUserEmail($from, [$this->getConfig()['title']], $form_fields, $confirmed);
|
|
}
|
|
|
|
public function getBodyVariables()
|
|
{
|
|
return [
|
|
'error' => $this->error,
|
|
'data' => $this->getFormData(),
|
|
'form' => $this->getConfig(),
|
|
'sent' => $this->emailSent,
|
|
] + parent::getBodyVariables();
|
|
}
|
|
|
|
private function sendEmail()
|
|
{
|
|
$config = $this->getConfig();
|
|
$smarty = $this->getSmarty();
|
|
|
|
$emails = $this->getEmails();
|
|
|
|
$get_news = getVal('get_news', $this->formData, 'N');
|
|
if ($get_news == 'Y' || $get_news == 'force') {
|
|
$this->saveUser($emails['from']);
|
|
}
|
|
|
|
$smarty->assign($this->getTemplateVariables());
|
|
|
|
$subject = trim($smarty->fetch($config['subject']));
|
|
$message = $smarty->fetch($config['message']);
|
|
|
|
$attachments = $this->getAttachments();
|
|
|
|
SendMail($emails['from'], $emails['to'], $subject, $message, 'text/html', $attachments, null, $emails['bcc']);
|
|
|
|
if (!empty($config['message_answer'])) {
|
|
$subject = $smarty->fetch($config['subject_answer']);
|
|
$message = $smarty->fetch($config['message_answer']);
|
|
SendMail($emails['to'], $emails['from'], $subject, $message, 'text/html');
|
|
}
|
|
|
|
$this->session->set('product_question', [
|
|
'email' => getVal('from', $emails),
|
|
'firstname' => getVal('name', $this->formData),
|
|
]);
|
|
}
|
|
|
|
public function submitForm()
|
|
{
|
|
$data = $this->getFormData();
|
|
$config = $this->getConfig();
|
|
|
|
try {
|
|
$this->validate($data, $config, $errorFields);
|
|
} catch (ValidationException $e) {
|
|
if ($this->compatibilityMode) {
|
|
$this->error = $e->getMessage();
|
|
} else {
|
|
$this->addErrorMessage($e->getMessage());
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
$this->dispatcher->dispatch(new FormEvent($this->formType, $data, $config), FormEvent::FORM_SUBMITTED);
|
|
|
|
$this->sendEmail();
|
|
|
|
// Mazání nahraných souborů přes uploader. Snad to nebude vadit nějakýmu emailu, že o ty data příjde moc brzy
|
|
// Případně se to uloží do session k form data
|
|
if ($data['user_content'] ?? false) {
|
|
$this->userContent->clearData($data['user_content']);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private function getFormData()
|
|
{
|
|
if ($this->emailSent) {
|
|
return $this->session->get("form-{$this->formType}");
|
|
}
|
|
|
|
return $this->formData;
|
|
}
|
|
|
|
public function getTemplate(): string
|
|
{
|
|
return $this->getConfig()['template'];
|
|
}
|
|
|
|
public function getShowInSearch(): bool
|
|
{
|
|
return empty($_GET) && empty($_POST);
|
|
}
|
|
|
|
/**
|
|
* @return ContactFormView
|
|
*/
|
|
public function setFormData($formData)
|
|
{
|
|
$this->formData = $formData;
|
|
|
|
if (!$this->emailSent) {
|
|
$this->session->set("form-{$this->formType}", $formData);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return ContactFormView
|
|
*/
|
|
public function setFormType($formType)
|
|
{
|
|
$this->formType = $formType;
|
|
|
|
if (!$this->getSmarty()->templateExists($this->getConfig()['template'])) {
|
|
throw new NotFoundHttpException('Form not found');
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param bool $emailSent
|
|
*
|
|
* @return ContactFormView
|
|
*/
|
|
public function setEmailSent($emailSent)
|
|
{
|
|
$this->emailSent = $emailSent;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setCompatibilityMode(bool $compatibilityMode): ContactFormView
|
|
{
|
|
$this->compatibilityMode = $compatibilityMode;
|
|
|
|
return $this;
|
|
}
|
|
}
|