smart_date-3.1.0-beta1/modules/smart_date_recur/src/Form/SmartDateOverrideForm.php
modules/smart_date_recur/src/Form/SmartDateOverrideForm.php
<?php namespace Drupal\smart_date_recur\Form; use Drupal\Core\Ajax\AjaxResponse; use Drupal\Core\Ajax\PrependCommand; use Drupal\Core\Ajax\RemoveCommand; use Drupal\Core\Ajax\ReplaceCommand; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\DependencyInjection\ClassResolverInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\RendererInterface; use Drupal\Core\Url; use Drupal\field\Entity\FieldConfig; use Drupal\smart_date\Plugin\Field\FieldWidget\SmartDateWidgetBase; use Drupal\smart_date_recur\Controller\Instances; use Drupal\smart_date_recur\Entity\SmartDateOverride; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Form controller for Smart Date Recur instance override edit forms. * * @ingroup smart_date_recur */ class SmartDateOverrideForm extends FormBase { /** * The class resolver service. * * @var \Drupal\Core\DependencyInjection\ClassResolverInterface */ protected $classResolver; /** * Definition of form entity type manager service. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * Drupal\Core\Render\RendererInterface definition. * * @var Drupal\Core\Render\RendererInterface */ protected $renderer; /** * {@inheritdoc} */ public function __construct(EntityTypeManagerInterface $entityTypeManager, RendererInterface $renderer, ClassResolverInterface $classResolver) { $this->entityTypeManager = $entityTypeManager; $this->renderer = $renderer; $this->classResolver = $classResolver; } /** * {@inheritdoc} * * @param \Symfony\Component\DependencyInjection\ContainerInterface $container * The Drupal service container. * * @return static */ public static function create(ContainerInterface $container) { return new static( $container->get('entity_type.manager'), $container->get('renderer'), $container->get('class_resolver'), ); } /** * {@inheritdoc} */ public function getFormId() { return 'smart_date_override_form'; } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $rrule = NULL, $index = NULL, $ajax = FALSE) { // @todo Show some kind of entity summary? Title at least? $instances = $rrule?->getRuleInstances(); if ($ajax) { $form['#prefix'] = '<div id="manage-instances">'; $form['#suffix'] = '</div>'; } // Get field config. $field_config = FieldConfig::loadByName( $rrule->get('entity_type')->getString(), $rrule->get('bundle')->getString(), $rrule->get('field_name')->getString() ); $defaults = $field_config?->getDefaultValueLiteral()[0]; $values = []; if ($instances && $index) { $values['start'] = DrupalDateTime::createFromTimestamp($instances[$index]['value']); $values['end'] = DrupalDateTime::createFromTimestamp($instances[$index]['end_value']); $values['duration'] = ($instances[$index]['end_value'] - $instances[$index]['value']) / 60; } $element = [ 'value' => [ '#type' => 'datetime', ], ]; SmartDateWidgetBase::createWidget($element, $values, $defaults); // Add the wrapper class for the Smart Date field so JS and CSS apply. $element['#attributes']['class'][] = 'smartdate--widget'; $form['override'] = $element; $form['#attached']['library'][] = 'smart_date/smart_date'; // Pass in values to identify the override. $form['rrule'] = [ '#type' => 'hidden', '#value' => $rrule->id(), ]; $form['rrule_index'] = [ '#type' => 'hidden', '#value' => $index, ]; if ($instances && $index && !empty($instances[$index]['oid'])) { $form['oid'] = [ '#type' => 'hidden', '#value' => $instances[$index]['oid'], ]; } if ($ajax) { $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save'), '#button_type' => 'primary', '#ajax' => [ 'callback' => '::ajaxSubmit', ], ]; $cancelurl = new Url('smart_date_recur.instances', [ 'rrule' => (int) $rrule->id(), 'modal' => TRUE, ]); $form['ajaxcancel'] = [ '#type' => 'link', '#title' => $this->t('Cancel'), '#attributes' => [ 'class' => [ 'button', 'use-ajax', ], ], '#url' => $cancelurl, '#cache' => [ 'contexts' => [ 'url.query_args:destination', ], ], ]; } else { $form['actions']['#type'] = 'actions'; $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save'), '#button_type' => 'primary', ]; } return $form; } /** * {@inheritdoc} */ public function validateForm(array &$form, FormStateInterface $form_state) { // @todo check that end > start. // @todo check that values != default. } /** * Ajax submit function. * * @param array $form * The render array of the form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The form state to submit. * * @return \Drupal\Core\Ajax\AjaxResponse * The return value of the AJAX submission. * * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException */ public function ajaxSubmit(array &$form, FormStateInterface $form_state) { $response = new AjaxResponse(); $status_messages = ['#type' => 'status_messages']; $messages = $this->renderer->renderRoot($status_messages); if (!empty($messages)) { $response->addCommand(new RemoveCommand('.messages-list')); $response->addCommand(new PrependCommand('#manage-instances', $messages)); return $response; } $form_state->disableRedirect(); /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager */ $entityTypeManager = $this->entityTypeManager; /** @var \Drupal\smart_date_recur\Entity\SmartDateRule $rrule */ $rrule = $entityTypeManager->getStorage('smart_date_rule')->load($form_state->getValue('rrule')); /** @var \Drupal\smart_date_recur\Controller\Instances $instanceController */ $instanceController = $this->classResolver->getInstanceFromDefinition(Instances::class); $instanceController->setSmartDateRule($rrule); $instanceController->setUseAjax(TRUE); $response = new AjaxResponse(); $response->addCommand(new ReplaceCommand('#manage-instances', $instanceController->listInstancesOutput())); return $response; } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->override($form_state); if (!isset($form['ajaxcancel'])) { /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager */ $entityTypeManager = $this->entityTypeManager; /** @var \Drupal\smart_date_recur\Entity\SmartDateRule $rrule */ $rrule = $entityTypeManager->getStorage('smart_date_rule')->load($form_state->getValue('rrule')); /** @var \Drupal\smart_date_recur\Controller\Instances $instanceController */ $instanceController = $this->classResolver->getInstanceFromDefinition(Instances::class); // Force refresh of parent entity. $instanceController->applyChanges($rrule); // Output message about operation performed, if not using AJAX. $this->messenger()->addMessage($this->t('The instance has been rescheduled.')); } // Redirect to rrule instance listing. $form_state->setRedirect('smart_date_recur.instances', ['rrule' => $form_state->getValue('rrule')]); } /** * Create or updating an override entity, this means overriding one rule item. * * @param \Drupal\Core\Form\FormStateInterface $form_state * The provided form values. * * @throws \Drupal\Core\Entity\EntityStorageException */ protected function override(FormStateInterface $form_state) { if (!empty($form_state->getValue('oid'))) { // Existing override, so retrieve and update values. $override = SmartDateOverride::load($form_state->getValue('oid')); // Only the values, end_value, and duration are changeable. $override ->set('value', $form_state->getValue('value')->getTimestamp()); $override ->set('end_value', $form_state->getValue('end_value')->getTimestamp()); $override ->set('duration', $form_state->getValue('duration')); } else { $values = [ 'rrule' => $form_state->getValue('rrule'), 'rrule_index' => $form_state->getValue('rrule_index'), 'value' => $form_state->getValue('value')->getTimestamp(), 'end_value' => $form_state->getValue('end_value')->getTimestamp(), 'duration' => $form_state->getValue('duration'), ]; // New override, so construct object. $override = SmartDateOverride::create($values); } $override->save(); } }