View source
<?php
namespace Drupal\autosave_form\Form;
use Drupal\autosave_form\Ajax\OpenAutosaveDisabledDialog;
use Drupal\autosave_form\Storage\AutosaveEntityFormStorageInterface;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Entity\EntityChangedInterface;
use Drupal\Core\Entity\EntityFormInterface;
use Drupal\Core\Entity\EntityHandlerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class AutosaveEntityFormHandler implements AutosaveEntityFormHandlerInterface, EntityHandlerInterface {
use DependencySerializationTrait;
use AutosaveFormAlterTrait {
autosaveFormAjax as traitAutosaveFormAjax;
formAlter as traitFormAlter;
}
protected $entityTypeId;
protected $entityType;
protected $entityStorage;
protected $currentUser;
protected $autosaveEntityFormStorage;
protected $time;
protected $dateFormatter;
protected $configFactory;
protected $keyValueExpirableFactory;
protected $conflictEnabled;
public function __construct(EntityTypeInterface $entity_type, EntityTypeManagerInterface $entity_type_manager, AccountInterface $current_user, AutosaveEntityFormStorageInterface $autosave_entity_form_storage, TimeInterface $time, DateFormatterInterface $date_formatter, ConfigFactoryInterface $config_factory, KeyValueExpirableFactoryInterface $key_value_expirable_factory, ModuleHandlerInterface $module_handler) {
$this->entityTypeId = $entity_type
->id();
$this->entityType = $entity_type;
$this->entityStorage = $entity_type_manager
->getStorage($entity_type
->id());
$this->currentUser = $current_user;
$this->autosaveEntityFormStorage = $autosave_entity_form_storage;
$this->time = $time;
$this->dateFormatter = $date_formatter;
$this->configFactory = $config_factory;
$this->keyValueExpirableFactory = $key_value_expirable_factory;
$this->conflictEnabled = $module_handler
->moduleExists('conflict');
}
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
return new static($entity_type, $container
->get('entity_type.manager'), $container
->get('current_user'), $container
->get('autosave_form.entity_form_storage'), $container
->get('datetime.time'), $container
->get('date.formatter'), $container
->get('config.factory'), $container
->get('keyvalue.expirable'), $container
->get('module_handler'));
}
public function formAlter(array &$form, FormStateInterface $form_state) {
$this
->traitFormAlter($form, $form_state);
$form['#entity_builders'][] = [
static::class,
'entityFormEntityBuild',
];
}
public function autosaveFormAjax($form, FormStateInterface $form_state) {
$response = $this
->traitAutosaveFormAjax($form, $form_state);
$timestamp = $form_state
->getTemporaryValue('autosave_form_last_autosave_timestamp');
if ($timestamp == 'entity_saved_meanwhile') {
$input = $form_state
->getUserInput();
if (is_numeric($input['autosave_form_last_autosave_timestamp']) || empty($input['autosave_form_last_autosave_timestamp'])) {
$message = $this->configFactory
->get('autosave_form.messages')
->get('entity_saved_in_background_alert_message');
$options = [
'width' => 'auto',
'closeOnEscape' => FALSE,
];
$response
->addCommand(new OpenAutosaveDisabledDialog($this
->t('Autosave has been disabled'), $message, $options));
$response
->addCommand(new InvokeCommand('input[name="autosave_form_last_autosave_timestamp"]', 'attr', [
'value',
(string) $this
->t('Autosave is turned off.'),
]));
$attachments = [];
$attachments['drupalSettings']['autosaveForm']['autosaveFormRunning'] = FALSE;
$response
->addAttachments($attachments);
}
}
return $response;
}
public static function entityFormEntityBuild($entity_type, EntityInterface $entity, array $form, FormStateInterface $form_state) {
if ($autosave_form_session_id = static::getAutosaveFormSessionID($form_state)) {
$entity->{static::AUTOSAVE_SESSION_ID} = $autosave_form_session_id;
}
}
public function isAutosaveSubmitValid(FormStateInterface $form_state) {
list($form_id, $entity) = $this
->getFormIDandEntity($form_state);
if ($entity instanceof EntityChangedInterface) {
$changed_time = $entity
->getChangedTime();
$input = $form_state
->getUserInput();
$changed_form_value = isset($input['changed']) ? $input['changed'] : NULL;
$entity
->setChangedTime($changed_form_value ?: $changed_time);
if (!$this->conflictEnabled && ($unchanged = $this->entityStorage
->loadUnchanged($entity
->id())) && $unchanged
->getChangedTimeAcrossTranslations() > $entity
->getChangedTimeAcrossTranslations()) {
$form_state
->setTemporaryValue('autosave_form_last_autosave_timestamp', 'entity_saved_meanwhile');
return FALSE;
}
else {
$entity
->setChangedTime($changed_time);
}
}
return TRUE;
}
public function getLastAutosavedFormState(FormStateInterface $form_state, $autosave_form_session_id, $uid) {
list($form_id, $entity) = $this
->getFormIDandEntity($form_state);
return $this->autosaveEntityFormStorage
->getFormState($form_id, $entity
->getEntityTypeId(), $entity
->id(), $entity
->language()
->getId(), $uid, $autosave_form_session_id);
}
public function storeState(FormStateInterface $form_state, $autosave_form_session_id, $autosave_timestamp, $uid) {
list($form_id, $entity) = $this
->getFormIDandEntity($form_state);
$this->autosaveEntityFormStorage
->storeEntityAndFormState($form_id, $autosave_form_session_id, $entity
->getEntityTypeId(), $entity
->id(), $entity
->language()
->getId(), $uid, $autosave_timestamp, $entity, $form_state);
}
public function getLastAutosavedTimestamp(FormStateInterface $form_state, $uid) {
list($form_id, $entity) = $this
->getFormIDandEntity($form_state);
return $entity
->isNew() ? NULL : $this->autosaveEntityFormStorage
->getLastAutosavedStateTimestamp($form_id, $entity
->getEntityTypeId(), $entity
->id(), $entity
->language()
->getId(), $uid);
}
public function purgeCurrentAutosavedState(FormStateInterface $form_state, $uid) {
list($form_id, $entity) = $this
->getFormIDandEntity($form_state);
$this->autosaveEntityFormStorage
->purgeAutosavedEntityState($entity
->getEntityTypeId(), $entity
->id(), $this
->getAutosaveFormSessionID($form_state), $form_id, $entity
->language()
->getId(), $uid);
}
public function purgeAllAutosavedStates(FormStateInterface $form_state, $uid) {
list($form_id, $entity) = $this
->getFormIDandEntity($form_state);
$this->autosaveEntityFormStorage
->purgeAutosavedEntityState($entity
->getEntityTypeId(), $entity
->id(), NULL, $form_id, $entity
->language()
->getId(), $uid);
}
public function isAutosaveEnabled(FormStateInterface $form_state) {
list($form_id, $entity) = $this
->getFormIDandEntity($form_state);
$allowed = !$entity
->isNew() && !$this->currentUser
->isAnonymous();
return $allowed;
}
public static function getAutosaveSessionID(EntityInterface $entity) {
if (isset($entity->{static::AUTOSAVE_SESSION_ID})) {
return $entity->{static::AUTOSAVE_SESSION_ID};
}
else {
return NULL;
}
}
protected function getFormIDandEntity(FormStateInterface $form_state) {
$form_object = $form_state
->getFormObject();
$form_id = $form_object
->getFormId();
$entity = $form_object
->getEntity();
return [
$form_id,
$entity,
];
}
}