class ConfigHandler

Same name and namespace in other branches
  1. 11.x core/modules/views_ui/src/Form/Ajax/ConfigHandler.php \Drupal\views_ui\Form\Ajax\ConfigHandler
  2. 10 core/modules/views_ui/src/Form/Ajax/ConfigHandler.php \Drupal\views_ui\Form\Ajax\ConfigHandler
  3. 9 core/modules/views_ui/src/Form/Ajax/ConfigHandler.php \Drupal\views_ui\Form\Ajax\ConfigHandler
  4. 8.9.x core/modules/views_ui/src/Form/Ajax/ConfigHandler.php \Drupal\views_ui\Form\Ajax\ConfigHandler

Provides a form for configuring an item in the Views UI.

@internal

Hierarchy

Expanded class hierarchy of ConfigHandler

File

core/modules/views_ui/src/Form/Ajax/ConfigHandler.php, line 16

Namespace

Drupal\views_ui\Form\Ajax
View source
class ConfigHandler extends ViewsFormBase {
  
  /**
   * Constructs a new ConfigHandler object.
   */
  public function __construct($type = NULL, $id = NULL) {
    $this->setType($type);
    $this->setID($id);
  }
  
  /**
   * {@inheritdoc}
   */
  public function getFormKey() {
    return 'handler';
  }
  
  /**
   * {@inheritdoc}
   */
  public function getForm(ViewEntityInterface $view, $display_id, $js, $type = NULL, $id = NULL) {
    $this->setType($type);
    $this->setID($id);
    return parent::getForm($view, $display_id, $js);
  }
  
  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'views_ui_config_item_form';
  }
  
  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, ?Request $request = NULL) {
    /** @var \Drupal\views\Entity\View $view */
    $view = $form_state->get('view');
    $display_id = $form_state->get('display_id');
    $type = $form_state->get('type');
    $id = $form_state->get('id');
    $form = [
      'options' => [
        '#tree' => TRUE,
        '#theme_wrappers' => [
          'container',
        ],
        '#attributes' => [
          'class' => [
            'scroll',
          ],
          'data-drupal-views-scroll' => TRUE,
        ],
      ],
    ];
    $executable = $view->getExecutable();
    $save_ui_cache = FALSE;
    if (!$executable->setDisplay($display_id)) {
      $form['markup'] = [
        '#markup' => $this->t('Invalid display id @display', [
          '@display' => $display_id,
        ]),
      ];
      return $form;
    }
    $item = $executable->getHandler($display_id, $type, $id);
    if ($item) {
      $handler = $executable->display_handler
        ->getHandler($type, $id);
      if (empty($handler)) {
        $form['markup'] = [
          '#markup' => $this->t("Error: handler for @table > @field doesn't exist!", [
            '@table' => $item['table'],
            '@field' => $item['field'],
          ]),
        ];
      }
      else {
        $types = ViewExecutable::getHandlerTypes();
        $form['#title'] = $this->t('Configure @type: @item', [
          '@type' => $types[$type]['lstitle'],
          '@item' => $handler->adminLabel(),
        ]);
        // If this item can come from the default display, show a dropdown
        // that lets the user choose which display the changes should apply to.
        if ($executable->display_handler
          ->defaultableSections($types[$type]['plural'])) {
          $section = $types[$type]['plural'];
          $form_state->set('section', $section);
          $this->standardDisplayDropdown($form, $form_state, $section);
        }
        // A whole bunch of code to figure out what relationships are valid for
        // this item.
        $relationships = $executable->display_handler
          ->getOption('relationships');
        $relationship_options = [];
        foreach ($relationships as $relationship) {
          // Relationships can't link back to self. But also, due to ordering,
          // relationships can only link to prior relationships.
          if ($type == 'relationship' && $id == $relationship['id']) {
            break;

          }
          $relationship_handler = \Drupal::service('plugin.manager.views.relationship')->getHandler($relationship);
          // Ignore invalid/broken relationships.
          if (empty($relationship_handler)) {
            continue;
          }
          // If this relationship is valid for this type, add it to the list.
          $data = Views::viewsData()->get($relationship['table']);
          if (isset($data[$relationship['field']]['relationship']['base']) && $base = $data[$relationship['field']]['relationship']['base']) {
            $base_fields = Views::viewsDataHelper()->fetchFields($base, $type, $executable->display_handler
              ->useGroupBy());
            if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
              $relationship_handler->init($executable, $executable->display_handler, $relationship);
              $relationship_options[$relationship['id']] = $relationship_handler->adminLabel();
            }
          }
        }
        if (!empty($relationship_options)) {
          // Make sure the existing relationship is even valid. If not, force
          // it to none.
          $base_fields = Views::viewsDataHelper()->fetchFields($view->get('base_table'), $type, $executable->display_handler
            ->useGroupBy());
          if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
            $relationship_options = array_merge([
              'none' => $this->t('Do not use a relationship'),
            ], $relationship_options);
          }
          $rel = empty($item['relationship']) ? 'none' : $item['relationship'];
          if (empty($relationship_options[$rel])) {
            // Pick the first relationship.
            $rel = key($relationship_options);
            // We want this relationship option to get saved even if the user
            // skips submitting the form.
            $executable->setHandlerOption($display_id, $type, $id, 'relationship', $rel);
            $save_ui_cache = TRUE;
            // Re-initialize with new relationship.
            $item['relationship'] = $rel;
            $handler->init($executable, $executable->display_handler, $item);
          }
          $form['options']['relationship'] = [
            '#type' => 'select',
            '#title' => $this->t('Relationship'),
            '#options' => $relationship_options,
            '#default_value' => $rel,
            '#weight' => -500,
          ];
        }
        else {
          $form['options']['relationship'] = [
            '#type' => 'value',
            '#value' => 'none',
          ];
        }
        if (!empty($handler->definition['help'])) {
          $form['options']['form_description'] = [
            '#markup' => $handler->definition['help'],
            '#theme_wrappers' => [
              'container',
            ],
            '#attributes' => [
              'class' => [
                'js-form-item form-item description',
              ],
            ],
            '#weight' => -1000,
          ];
        }
        $form['#section'] = $display_id . '-' . $type . '-' . $id;
        // Get form from the handler.
        $handler->buildOptionsForm($form['options'], $form_state);
        $form_state->set('handler', $handler);
      }
      $name = $form_state->get('update_name');
      $view->getStandardButtons($form, $form_state, 'views_ui_config_item_form', $name);
      // Add a 'remove' button.
      $form['actions']['remove'] = [
        '#type' => 'submit',
        '#value' => $this->t('Remove'),
        '#submit' => [
          [
            $this,
            'remove',
          ],
        ],
        '#limit_validation_errors' => [
          [
            'override',
          ],
        ],
        '#button_type' => 'danger',
      ];
    }
    if ($save_ui_cache) {
      $view->cacheSet();
    }
    return $form;
  }
  
  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $form_state->get('handler')
      ->validateOptionsForm($form['options'], $form_state);
    if ($form_state->getErrors()) {
      // Trigger a form rerender so error messages are displayed correctly in
      // the AJAX modal.
      // @see \Drupal\views_ui\Form\Ajax\ViewsFormBase::ajaxFormWrapper()
      $form_state->set('rerender', TRUE);
    }
  }
  
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $view = $form_state->get('view');
    $display_id = $form_state->get('display_id');
    $id = $form_state->get('id');
    $handler = $form_state->get('handler');
    // Run it through the handler's submit function.
    $handler->submitOptionsForm($form['options'], $form_state);
    $item = $handler->options;
    $types = ViewExecutable::getHandlerTypes();
    // For footer/header $handler_type is area but $type is footer/header.
    // For all other handle types it's the same.
    $handler_type = $type = $form_state->get('type');
    if (!empty($types[$type]['type'])) {
      $handler_type = $types[$type]['type'];
    }
    $override = NULL;
    $executable = $view->getExecutable();
    if ($executable->display_handler
      ->useGroupBy() && !empty($item['group_type'])) {
      if (empty($executable->query)) {
        $executable->initQuery();
      }
      $aggregate = $executable->query
        ->getAggregationInfo();
      if (!empty($aggregate[$item['group_type']]['handler'][$type])) {
        $override = $aggregate[$item['group_type']]['handler'][$type];
      }
    }
    // Create a new handler and unpack the options from the form onto it. We
    // can use that for storage.
    $handler = \Drupal::service('views.plugin_managers')->get($handler_type)
      ->getHandler($item, $override);
    $handler->init($executable, $executable->display_handler, $item);
    // Add the incoming options to existing options because items using
    // the extra form may not have everything in the form here.
    $options = $handler->submitFormCalculateOptions($handler->options, $form_state->getValue('options', []));
    // This unpacks only options that are in the definition, ensuring random
    // extra stuff on the form is not sent through.
    $handler->unpackOptions($handler->options, $options, NULL, FALSE);
    // Store the item back on the view.
    $executable->setHandler($display_id, $type, $id, $handler->options);
    // Ensure any temporary options are removed.
    if (isset($view->temporary_options[$type][$id])) {
      unset($view->temporary_options[$type][$id]);
    }
    // Write to cache.
    $view->cacheSet();
  }
  
  /**
   * Submit handler for removing an item from a view.
   */
  public function remove(&$form, FormStateInterface $form_state) {
    $view = $form_state->get('view');
    $display_id = $form_state->get('display_id');
    $type = $form_state->get('type');
    $id = $form_state->get('id');
    // Store the item back on the view.
    [$was_defaulted, $is_defaulted] = $view->getOverrideValues($form, $form_state);
    $executable = $view->getExecutable();
    // If the display selection was changed toggle the override value.
    if ($was_defaulted != $is_defaulted) {
      $display =& $executable->displayHandlers
        ->get($display_id);
      $display->optionsOverride($form, $form_state);
    }
    $executable->removeHandler($display_id, $type, $id);
    // Write to cache.
    $view->cacheSet();
  }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
AutowiredInstanceTrait::createInstanceAutowired public static function Instantiates a new instance of the implementing class using autowiring.
AutowiredInstanceTrait::getAutowireArguments private static function Resolves arguments for a method using autowiring.
AutowireTrait::create public static function Instantiates a new instance of the implementing class using autowiring. 131
ConfigHandler::buildForm public function Form constructor. Overrides FormInterface::buildForm
ConfigHandler::getForm public function Creates a new instance of this form. Overrides ViewsFormBase::getForm
ConfigHandler::getFormId public function Returns a unique string identifying the form. Overrides FormInterface::getFormId
ConfigHandler::getFormKey public function Returns the key that represents this form. Overrides ViewsFormInterface::getFormKey
ConfigHandler::remove public function Submit handler for removing an item from a view.
ConfigHandler::submitForm public function Form submission handler. Overrides ViewsFormBase::submitForm
ConfigHandler::validateForm public function Form validation handler. Overrides ViewsFormBase::validateForm
ConfigHandler::__construct public function Constructs a new ConfigHandler object.
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 2
DependencySerializationTrait::__wakeup public function 2
FormBase::$configFactory protected property The config factory. 1
FormBase::$requestStack protected property The request stack. 1
FormBase::$routeMatch protected property The route match.
FormBase::config protected function Retrieves a configuration object.
FormBase::configFactory protected function Gets the config factory for this form. 1
FormBase::container private function Returns the service container.
FormBase::currentUser protected function Gets the current user. 2
FormBase::getRequest protected function Gets the request object. Overrides HtmxRequestInfoTrait::getRequest
FormBase::getRouteMatch protected function Gets the route match.
FormBase::logger protected function Gets the logger for a specific channel.
FormBase::redirect protected function Returns a redirect response object for the specified route.
FormBase::resetConfigFactory public function Resets the configuration factory.
FormBase::setConfigFactory public function Sets the config factory for this form.
FormBase::setRequestStack public function Sets the request stack object to use.
HtmxRequestInfoTrait::getHtmxCurrentUrl protected function Retrieves the URL of the requesting page from an HTMX request header.
HtmxRequestInfoTrait::getHtmxPrompt protected function Retrieves the prompt from an HTMX request header.
HtmxRequestInfoTrait::getHtmxTarget protected function Retrieves the target identifier from an HTMX request header.
HtmxRequestInfoTrait::getHtmxTrigger protected function Retrieves the trigger identifier from an HTMX request header.
HtmxRequestInfoTrait::getHtmxTriggerName protected function Retrieves the trigger name from an HTMX request header.
HtmxRequestInfoTrait::isHtmxBoosted protected function Determines if the request is boosted by HTMX.
HtmxRequestInfoTrait::isHtmxHistoryRestoration protected function Determines if if the request is for history restoration.
HtmxRequestInfoTrait::isHtmxRequest protected function Determines if the request is sent by HTMX.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 26
MessengerTrait::messenger public function Gets the messenger. 26
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 2
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 3
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language. 1
ViewsFormBase::$id protected property The ID of the item this form is manipulating.
ViewsFormBase::$type protected property The type of item this form is manipulating.
ViewsFormBase::ajaxFormWrapper protected function Wrapper for handling AJAX forms.
ViewsFormBase::getFormState public function Gets the form state for this form. Overrides ViewsFormInterface::getFormState 1
ViewsFormBase::setID protected function Sets the ID for this form.
ViewsFormBase::setType protected function Sets the type for this form.
ViewsFormHelperTrait::buildFormUrl protected function Creates the menu path for a standard AJAX form given the form state.
ViewsFormHelperTrait::formButtonWasClicked public static function The #process callback for a button.
ViewsFormHelperTrait::getConfigFactory protected function Returns the config factory service.
ViewsFormHelperTrait::standardDisplayDropdown protected function Adds an element to select either the default or the current display.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.