You are here

public function ScheduledTransitionAddForm::form in Scheduled Transitions 8

Same name and namespace in other branches
  1. 2.x src/Form/Entity/ScheduledTransitionAddForm.php \Drupal\scheduled_transitions\Form\Entity\ScheduledTransitionAddForm::form()

Gets the actual form array to be built.

Overrides ContentEntityForm::form

See also

\Drupal\Core\Entity\EntityForm::processForm()

\Drupal\Core\Entity\EntityForm::afterBuild()

File

src/Form/Entity/ScheduledTransitionAddForm.php, line 119

Class

ScheduledTransitionAddForm
Scheduled transitions add form.

Namespace

Drupal\scheduled_transitions\Form\Entity

Code

public function form(array $form, FormStateInterface $form_state) : array {
  $account = $this
    ->currentUser();
  $form['scheduled_transitions']['#theme'] = 'scheduled_transitions_form_add';
  $entity = $this
    ->getEntity();
  $header = [];
  $header['revision_id'] = $this
    ->t('Revision');
  $header['state'] = $this
    ->t('State');
  if ($entity instanceof RevisionLogInterface) {
    $header['revision_time'] = $this
      ->t('Saved on');
    $header['revision_author'] = $this
      ->t('Saved by');
    $header['revision_log'] = $this
      ->t('Log');
  }
  $newMetaWrapperId = 'new-meta-wrapper';
  $input = $form_state
    ->getUserInput();
  $revisionOptions = $this
    ->getRevisionOptions($entity);

  // Use the selected option (if form is being rebuilt from AJAX), otherwise
  // select latest revision if it exists.
  $revision = $input['revision'] ?? (isset($revisionOptions[static::LATEST_REVISION]) ? static::LATEST_REVISION : NULL);
  $form['scheduled_transitions']['revision'] = [
    '#type' => 'tableselect',
    '#header' => $header,
    '#caption' => $this
      ->t('Select which revision you wish to move to a new state.'),
    '#options' => $revisionOptions,
    '#multiple' => FALSE,
    '#footer' => [
      [
        [
          'colspan' => count($header) + 1,
          'data' => [
            '#plain_text' => $this
              ->t('Revisions are ordered from newest to oldest.'),
          ],
        ],
      ],
    ],
    '#process' => [
      [
        Tableselect::class,
        'processTableselect',
      ],
      '::revisionProcess',
    ],
    '#new_meta_wrapper_id' => $newMetaWrapperId,
    '#default_value' => $revision,
  ];
  $form['scheduled_transitions']['new_meta'] = [
    '#type' => 'container',
    '#attributes' => [
      'class' => [
        'container-inline',
      ],
    ],
    '#prefix' => '<div id="' . $newMetaWrapperId . '">',
    '#suffix' => '</div>',
  ];
  $workflow = $this->moderationInformation
    ->getWorkflowForEntity($entity);
  $workflowPlugin = $workflow
    ->getTypePlugin();

  // Populate options with nothing.
  if (is_numeric($revision) && $revision > 0) {
    $entityStorage = $this->entityTypeManager
      ->getStorage($entity
      ->getEntityTypeId());
    $entityRevision = $entityStorage
      ->loadRevision($revision);
    $toTransitions = $this->stateTransitionValidation
      ->getValidTransitions($entityRevision, $this
      ->currentUser());
  }
  elseif (is_string($revision)) {

    // Show all transitions as we cannot be sure what will be available.
    // Cannot use getValidTransitions since it is only valid for the current
    // state of the entity passed to it:
    $toTransitions = array_filter($workflowPlugin
      ->getTransitions(), function (Transition $transition) use ($workflow, $account) {
      return $account
        ->hasPermission('use ' . $workflow
        ->id() . ' transition ' . $transition
        ->id());
    });
  }
  if (isset($toTransitions)) {
    $transitionOptions = [];
    foreach ($toTransitions as $toTransition) {
      $transitionOptions[$toTransition
        ->id()] = $toTransition
        ->label();
    }
    $form['scheduled_transitions']['new_meta']['transition_help']['#markup'] = $this
      ->t('<strong>Execute transition</strong>');
    $form['scheduled_transitions']['new_meta']['transition'] = [
      '#type' => 'select',
      '#options' => $transitionOptions,
      '#empty_option' => $this
        ->t('- Select -'),
      '#required' => TRUE,
    ];
    $form['scheduled_transitions']['new_meta']['on_help']['#markup'] = $this
      ->t('<strong>on date</strong>');
    $form['scheduled_transitions']['new_meta']['on'] = [
      '#type' => 'datetime',
      '#default_value' => new \DateTime(),
      '#required' => TRUE,
    ];
  }
  else {
    $form['scheduled_transitions']['new_meta']['transition_help']['#markup'] = $this
      ->t('Select a revision above');
  }
  $form['scheduled_transitions']['to_options'] = [
    '#type' => 'container',
  ];
  if (isset($toTransitions) && count($toTransitions) > 0) {

    // Its too difficult to have a checkbox with default TRUE with conditional
    // existence, as AJAX reloads, will sometimes show the checkbox as
    // unchecked. See https://www.drupal.org/project/drupal/issues/1100170.
    // Instead show this checkbox depending on value of other fields. The
    // checkbox will always be present therefore preserving its state.
    $conditions = [];
    foreach ($toTransitions as $transition) {
      if ($transition
        ->to()
        ->isDefaultRevisionState()) {
        $conditions[] = [
          ':input[name="transition"]' => [
            'value' => $transition
              ->id(),
          ],
        ];
      }
    }
    $form['scheduled_transitions']['to_options']['recreate_non_default_head'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Recreate pending revision'),
      '#description' => $this
        ->t('Before creating this revision, check if there is any pending work. If so then recreate it. Regardless of choice, revisions are safely retained in history, and can be reverted manually.'),
      '#default_value' => TRUE,
      '#states' => [
        'visible' => $conditions,
      ],
    ];
  }
  return $form;
}