You are here

private function FormManglerService::addRabbitHoleOptionsToForm in Rabbit Hole 8

Same name and namespace in other branches
  1. 2.x src/FormManglerService.php \Drupal\rabbit_hole\FormManglerService::addRabbitHoleOptionsToForm()

Common functionality for adding rabbit hole options to forms.

Parameters

array $attach: The form that the Rabbit Hole form should be attached to.

string $entity_type_id: The string ID of the entity type for the form, e.g. 'node'.

object $entity: The entity that we're adding the form to, e.g. a node. This should be defined even in the case of bundles since it is used to determine bundle and entity type.

\Drupal\Core\Form\FormStateInterface $form_state: Form state object.

string $form_id: Form ID.

Throws

\Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException

\Drupal\Component\Plugin\Exception\PluginNotFoundException

2 calls to FormManglerService::addRabbitHoleOptionsToForm()
FormManglerService::addRabbitHoleOptionsToEntityForm in src/FormManglerService.php
Form structure for the Rabbit Hole configuration.
FormManglerService::addRabbitHoleOptionsToGlobalForm in src/FormManglerService.php
Add rabbit hole options to an entity type's global configuration form.

File

src/FormManglerService.php, line 159

Class

FormManglerService
Provides necessary form alterations.

Namespace

Drupal\rabbit_hole

Code

private function addRabbitHoleOptionsToForm(array &$attach, $entity_type_id, $entity, FormStateInterface $form_state, $form_id) {
  $entity_type = $this->entityTypeManager
    ->getStorage($entity_type_id)
    ->getEntityType();
  if ($entity === NULL) {
    $is_bundle_or_entity_type = TRUE;
  }
  else {
    $is_bundle_or_entity_type = $this
      ->isEntityBundle($entity);
  }
  $bundle_settings = NULL;
  $bundle = isset($entity) ? $entity
    ->bundle() : $entity_type_id;
  $action = NULL;
  $entity_plugin = $this->rhEntityPluginManager
    ->createInstanceByEntityType($is_bundle_or_entity_type && !empty($entity_type
    ->getBundleOf()) ? $entity_type
    ->getBundleOf() : $entity_type
    ->id());
  if ($is_bundle_or_entity_type) {
    if ($entity === NULL) {
      $bundle_settings = $this->rhBehaviorSettingsManager
        ->loadBehaviorSettingsAsConfig($entity_type
        ->id());
    }
    else {
      $bundle_settings = $this->rhBehaviorSettingsManager
        ->loadBehaviorSettingsAsConfig($entity_type
        ->id(), $entity
        ->id());
    }
    $action = $bundle_settings
      ->get('action');
  }
  else {

    // Attach extra submit for redirect in case of entity form.
    $submit_location = $entity_plugin
      ->getFormSubmitHandlerAttachLocations($attach, $form_state);
    $this
      ->attachFormSubmit($attach, $submit_location, [
      $this,
      'redirectToEntityEditForm',
    ]);
    $bundle_entity_type = $entity_type
      ->getBundleEntityType() ?: $entity_type
      ->id();
    $bundle_settings = $this->rhBehaviorSettingsManager
      ->loadBehaviorSettingsAsConfig($bundle_entity_type, $entity
      ->getEntityType()
      ->getBundleEntityType() ? $entity
      ->bundle() : NULL);

    // If the form is about to be attached to an entity,
    // but the bundle isn't allowed to be overridden, exit.
    if (!$bundle_settings
      ->get('allow_override')) {
      return;
    }
    $action = isset($entity->rh_action->value) ? $entity->rh_action->value : 'bundle_default';
  }

  // Get information about the entity.
  // TODO: Should be possible to get this as plural? Look into this.
  $entity_label = $entity_type
    ->getLabel();
  $bundle_info = isset($this->allBundleInfo[$entity_type
    ->id()]) ? $this->allBundleInfo[$entity_type
    ->id()] : NULL;

  // Get the label for the bundle. This won't be set when the user is creating
  // a new bundle. In that case, fallback to "this bundle".
  $bundle_label = NULL !== $bundle_info && NULL !== $bundle_info[$bundle]['label'] ? $bundle_info[$bundle]['label'] : $this
    ->t('this bundle');

  // Wrap everything in a fieldset.
  $form['rabbit_hole'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Rabbit Hole settings'),
    '#collapsed' => FALSE,
    '#collapsible' => TRUE,
    '#tree' => FALSE,
    '#weight' => 10,
    // TODO: Should probably handle group in a plugin - not sure if, e.g.,
    // files will work in the same way and even if they do later entities
    // might not.
    '#group' => $is_bundle_or_entity_type ? 'additional_settings' : 'advanced',
    '#attributes' => [
      'class' => [
        'rabbit-hole-settings-form',
      ],
    ],
  ];

  // Add the invoking module to the internal values.
  // TODO: This can probably be removed - check.
  $form['rabbit_hole']['rh_is_bundle'] = [
    '#type' => 'hidden',
    '#value' => $is_bundle_or_entity_type,
  ];
  $form['rabbit_hole']['rh_entity_type'] = [
    '#type' => 'hidden',
    '#value' => $entity_type
      ->id(),
  ];

  // Add override setting if we're editing a bundle.
  if ($is_bundle_or_entity_type) {
    $form['rabbit_hole']['rh_override'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Allow these settings to be overridden for individual entities'),
      '#default_value' => $bundle_settings
        ->get('allow_override'),
      '#description' => $this
        ->t('If this is checked, users with the %permission permission will be able to override these settings for individual entities.', [
        '%permission' => $this
          ->t('Administer Rabbit Hole settings for @entity_type', [
          '@entity_type' => $entity_label,
        ]),
      ]),
    ];
  }

  // Add action setting.
  $action_options = $this
    ->loadBehaviorOptions();
  if (!$is_bundle_or_entity_type) {

    // Add an option if we are editing an entity. This will allow us to use
    // the configuration for the bundle.
    $action_bundle = $bundle_settings
      ->get('action');
    $action_options = [
      self::RABBIT_HOLE_USE_DEFAULT => $this
        ->t('Global @bundle behavior (@setting)', [
        '@bundle' => strtolower($bundle_label),
        '@setting' => $action_options[$action_bundle],
      ]),
    ] + $action_options;
  }
  $form['rabbit_hole']['rh_action'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('Behavior'),
    '#options' => $action_options,
    '#default_value' => $action,
    '#description' => $this
      ->t('What should happen when someone tries to visit an entity page for @bundle?', [
      '@bundle' => strtolower($bundle_label),
    ]),
    '#attributes' => [
      'class' => [
        'rabbit-hole-action-setting',
      ],
    ],
  ];
  $this
    ->populateExtraBehaviorSections($form, $form_state, $form_id, $entity, $is_bundle_or_entity_type, $bundle_settings);

  // Attach the Rabbit Hole form to the main form, and add a custom validation
  // callback.
  $attach += $form;

  // TODO: Optionally provide a form validation handler (can we do this via
  // plugin?).
  //
  // If the implementing module provides a submit function for the bundle
  // form, we'll add it as a submit function for the attached form. We'll also
  // make sure that this won't be added for entity forms.
  //
  // TODO: This should probably be moved out into plugins based on entity
  // type.
  $is_global_form = isset($attach['#form_id']) && $attach['#form_id'] === $entity_plugin
    ->getGlobalConfigFormId();
  if ($is_global_form) {
    $submit_location = $entity_plugin
      ->getGlobalFormSubmitHandlerAttachLocations($attach, $form_state);
  }
  elseif ($is_bundle_or_entity_type) {
    $submit_location = $entity_plugin
      ->getBundleFormSubmitHandlerAttachLocations($attach, $form_state);
  }
  else {
    $submit_location = $entity_plugin
      ->getFormSubmitHandlerAttachLocations($attach, $form_state);
  }
  $this
    ->attachFormSubmit($attach, $submit_location, '_rabbit_hole_general_form_submit');

  // TODO: Optionally provide additional form submission handler (can we do
  // this via plugin?).
  // Add ability to validate user input before saving the data.
  $attach['rabbit_hole']['rabbit_hole']['redirect']['rh_redirect']['#element_validate'][] = [
    'Drupal\\rabbit_hole\\FormManglerService',
    'validateFormRedirect',
  ];
}