arch-8.x-1.x-dev/modules/order/src/OrderMail/Form/MailForm.php
modules/order/src/OrderMail/Form/MailForm.php
<?php
namespace Drupal\arch_order\OrderMail\Form;
use Drupal\arch_order\OrderMail\OrderMailInterface;
use Drupal\arch_order\OrderMail\OrderMailManagerInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Messenger\Messenger;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\file\FileUsage\FileUsageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Mail form.
*
* @package Drupal\arch_order\Form
*/
class MailForm extends FormBase {
/**
* Mail manager service.
*
* @var \Drupal\arch_order\OrderMail\OrderMailManagerInterface
*/
protected $mailManager;
/**
* Language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* The messenger.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* Renderer service.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $renderer;
/**
* Available site language list.
*
* @var \Drupal\Core\Language\LanguageInterface[]
*/
private $languageList;
/**
* Site default language.
*
* @var \Drupal\Core\Language\LanguageInterface
*/
private $defaultLanguage;
/**
* Entity repository service.
*
* @var \Drupal\Core\Entity\EntityRepositoryInterface
*/
protected $entityRepository;
/**
* File usage service.
*
* @var \Drupal\file\FileUsage\FileUsageInterface
*/
protected $fileUsage;
/**
* Module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* MailForm constructor.
*
* @param \Drupal\arch_order\OrderMail\OrderMailManagerInterface $mail_manager
* Mail manager service.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* Language manager.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger.
* @param \Drupal\Core\Render\RendererInterface $renderer
* Renderer service.
* @param \Drupal\Core\Entity\EntityRepositoryInterface $entityRepository
* Entity repository service.
* @param \Drupal\file\FileUsage\FileUsageInterface $fileUsage
* File usage service.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
* Module handler.
*/
public function __construct(
OrderMailManagerInterface $mail_manager,
LanguageManagerInterface $language_manager,
MessengerInterface $messenger,
RendererInterface $renderer,
EntityRepositoryInterface $entityRepository,
FileUsageInterface $fileUsage,
ModuleHandlerInterface $moduleHandler,
) {
$this->mailManager = $mail_manager;
$this->languageManager = $language_manager;
$this->messenger = $messenger;
$this->renderer = $renderer;
$this->languageList = $this->languageManager->getLanguages();
$this->defaultLanguage = $this->languageManager->getDefaultLanguage();
$this->entityRepository = $entityRepository;
$this->fileUsage = $fileUsage;
$this->moduleHandler = $moduleHandler;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('arch_order_mail'),
$container->get('language_manager'),
$container->get('messenger'),
$container->get('renderer'),
$container->get('entity.repository'),
$container->get('file.usage'),
$container->get('module_handler')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'arch_order_mail';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, $plugin_id = NULL, $lang_code = NULL) {
if (!$plugin_id) {
throw new NotFoundHttpException();
}
if (isset($lang_code)) {
$lang_code = strtolower(trim($lang_code));
if (!isset($this->languageList[$lang_code])) {
throw new NotFoundHttpException();
}
}
$mail = $this->mailManager->get($plugin_id);
if (!$mail) {
throw new NotFoundHttpException();
}
if ($lang_code && !$mail->translationIsExists($lang_code)) {
throw new NotFoundHttpException();
}
$languageList = [];
foreach ($this->languageList as $lang) {
if ($mail && $lang->getId() !== $lang_code && $mail->translationIsExists($lang->getId())) {
continue;
}
$languageList[$lang->getId()] = $lang->getName();
}
if (empty($languageList)) {
$message = $this->t(
'Translation is already available in all languages.',
[],
['context' => 'arch_order_mail']
);
$this->messenger->addMessage($message, Messenger::TYPE_WARNING);
return $this->redirect('arch_order_mail.view', ['plugin_id' => $plugin_id]);
}
$token_tree = [
'#theme' => 'token_tree_link',
'#token_types' => ['order'],
];
$form['plugin_id'] = [
'#type' => 'hidden',
'#value' => $plugin_id,
];
$form['lang_code'] = [
'#type' => 'select',
'#title' => $this->t('Language'),
'#options' => $languageList,
'#default_value' => $lang_code ? $lang_code : $this->defaultLanguage->getId(),
'#attributes' => $lang_code ? ['disabled' => 'disabled'] : [],
];
$form['subject'] = [
'#type' => 'textfield',
'#title' => $this->t('Subject'),
'#maxlength' => 255,
'#default_value' => $mail ? $mail->getSubject($lang_code) : '',
'#required' => TRUE,
];
$form['body'] = [
'#type' => 'text_format',
'#title' => $this->t('Body'),
'#default_value' => $mail ? $mail->getBody($lang_code)['value'] : '',
'#required' => TRUE,
'#format' => 'basic_html',
'#allowed_formats' => ['basic_html'],
'#description' => $this->t(
'This field supports tokens. @browse_tokens_link',
['@browse_tokens_link' => $this->renderer->render($token_tree)]
),
];
$form['actions'] = [
'#type' => 'actions',
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Save'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
// No validation.
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$pluginId = $form_state->getValue('plugin_id');
$langcode = $form_state->getValue('lang_code');
$subject = $form_state->getValue('subject');
$body = $form_state->getValue('body');
// Makes it safe for DB and prevent unnecessary newlines.
$body['value'] = preg_replace('/\s\s+/', '', $body['value']);
$mail = $this->mailManager->get($pluginId);
if (!$mail) {
throw new NotFoundHttpException();
}
$mail->setTranslation($langcode, $subject, $body);
$this->handleManagedFiles($body, $mail, $form_state);
$message = $this->t(
'@language translation have been saved.',
['@language' => $this->languageManager->getLanguage($langcode)->getName()],
['context' => 'arch_order_mail']
);
$this->messenger->addMessage($message);
$form_state->setRedirect('arch_order_mail.view', ['plugin_id' => $pluginId]);
}
/**
* Handles managed files.
*
* @param array $body
* Array of body field. Keys are 'value', 'format'.
* @param \Drupal\arch_order\OrderMail\OrderMailInterface $orderMail
* Loaded order mail plugin currently editing.
* @param \Drupal\Core\Form\FormStateInterface $formState
* Form state data.
*/
protected function handleManagedFiles(array $body, OrderMailInterface $orderMail, FormStateInterface $formState) {
if (!$this->moduleHandler->moduleExists('editor')) {
return;
}
$module = 'arch_order';
$type = 'order_mail';
$plugin_id = $formState->getValue('plugin_id');
$translation_langcode = $formState->getValue('lang_code');
$id = substr($translation_langcode . '__' . $plugin_id, 0, 64);
try {
$original_uuids = _editor_parse_file_uuids($orderMail->getBody($translation_langcode)['value']);
$uuids = _editor_parse_file_uuids($body['value']);
// Adds new files.
foreach ($uuids as $uuid) {
if ($file = $this->entityRepository->loadEntityByUuid('file', $uuid)) {
/** @var \Drupal\file\FileInterface $file */
if ($file->isTemporary()) {
$file->setPermanent();
$file->save();
}
$usages = $this->fileUsage->listUsage($file);
if (!isset($usages[$module][$type][$id])) {
$this->fileUsage->add($file, $module, $type, $id);
}
}
}
// Deletes possibly removed image(s) from file_usage table.
$removed_files = array_diff($original_uuids, $uuids);
foreach ($removed_files as $uuid) {
if ($file = $this->entityRepository->loadEntityByUuid('file', $uuid)) {
$this->fileUsage->delete($file, $module, $type, $id, 1);
}
}
}
catch (\Exception $e) {
$this->messenger->addWarning($this->t('Failed to set image to permanent.'));
}
}
}
