Mercurial > hg > isophonics-drupal-site
diff core/modules/views_ui/src/ViewFormBase.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | af1871eacc83 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/modules/views_ui/src/ViewFormBase.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,170 @@ +<?php + +namespace Drupal\views_ui; + +use Drupal\Core\Entity\EntityForm; +use Drupal\Core\Form\FormStateInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; + +/** + * Base form for Views forms. + */ +abstract class ViewFormBase extends EntityForm { + + /** + * The name of the display used by the form. + * + * @var string + */ + protected $displayID; + + /** + * {@inheritdoc} + */ + public function init(FormStateInterface $form_state) { + parent::init($form_state); + + // @todo Remove the need for this. + $form_state->loadInclude('views_ui', 'inc', 'admin'); + $form_state->set('view', $this->entity); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state, $display_id = NULL) { + if (isset($display_id) && $form_state->has('display_id') && ($display_id !== $form_state->get('display_id'))) { + throw new \InvalidArgumentException('Mismatch between $form_state->get(\'display_id\') and $display_id.'); + } + $this->displayID = $form_state->has('display_id') ? $form_state->get('display_id') : $display_id; + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + protected function prepareEntity() { + // Determine the displays available for editing. + if ($tabs = $this->getDisplayTabs($this->entity)) { + if (empty($this->displayID)) { + // If a display isn't specified, use the first one after sorting by + // #weight. + uasort($tabs, 'Drupal\Component\Utility\SortArray::sortByWeightProperty'); + foreach ($tabs as $id => $tab) { + if (!isset($tab['#access']) || $tab['#access']) { + $this->displayID = $id; + break; + } + } + } + // If a display is specified, but we don't have access to it, return + // an access denied page. + if ($this->displayID && !isset($tabs[$this->displayID])) { + throw new NotFoundHttpException(); + } + elseif ($this->displayID && (isset($tabs[$this->displayID]['#access']) && !$tabs[$this->displayID]['#access'])) { + throw new AccessDeniedHttpException(); + } + + } + elseif ($this->displayID) { + throw new NotFoundHttpException(); + } + } + + /** + * Adds tabs for navigating across Displays when editing a View. + * + * This function can be called from hook_menu_local_tasks_alter() to implement + * these tabs as secondary local tasks, or it can be called from elsewhere if + * having them as secondary local tasks isn't desired. The caller is responsible + * for setting the active tab's #active property to TRUE. + * + * @param $display_id + * The display_id which is edited on the current request. + */ + public function getDisplayTabs(ViewUI $view) { + $executable = $view->getExecutable(); + $executable->initDisplay(); + $display_id = $this->displayID; + $tabs = []; + + // Create a tab for each display. + foreach ($view->get('display') as $id => $display) { + // Get an instance of the display plugin, to make sure it will work in the + // UI. + $display_plugin = $executable->displayHandlers->get($id); + if (empty($display_plugin)) { + continue; + } + + $tabs[$id] = [ + '#theme' => 'menu_local_task', + '#weight' => $display['position'], + '#link' => [ + 'title' => $this->getDisplayLabel($view, $id), + 'localized_options' => [], + 'url' => $view->urlInfo('edit-display-form')->setRouteParameter('display_id', $id), + ], + ]; + if (!empty($display['deleted'])) { + $tabs[$id]['#link']['localized_options']['attributes']['class'][] = 'views-display-deleted-link'; + } + if (isset($display['display_options']['enabled']) && !$display['display_options']['enabled']) { + $tabs[$id]['#link']['localized_options']['attributes']['class'][] = 'views-display-disabled-link'; + } + } + + // If the default display isn't supposed to be shown, don't display its tab, unless it's the only display. + if ((!$this->isDefaultDisplayShown($view) && $display_id != 'default') && count($tabs) > 1) { + $tabs['default']['#access'] = FALSE; + } + + // Mark the display tab as red to show validation errors. + $errors = $executable->validate(); + foreach ($view->get('display') as $id => $display) { + if (!empty($errors[$id])) { + // Always show the tab. + $tabs[$id]['#access'] = TRUE; + // Add a class to mark the error and a title to make a hover tip. + $tabs[$id]['#link']['localized_options']['attributes']['class'][] = 'error'; + $tabs[$id]['#link']['localized_options']['attributes']['title'] = $this->t('This display has one or more validation errors.'); + } + } + + return $tabs; + } + + /** + * Controls whether or not the default display should have its own tab on edit. + */ + public function isDefaultDisplayShown(ViewUI $view) { + // Always show the default display for advanced users who prefer that mode. + $advanced_mode = \Drupal::config('views.settings')->get('ui.show.master_display'); + // For other users, show the default display only if there are no others, and + // hide it if there's at least one "real" display. + $additional_displays = (count($view->getExecutable()->displayHandlers) == 1); + + return $advanced_mode || $additional_displays; + } + + /** + * Placeholder function for overriding $display['display_title']. + * + * @todo Remove this function once editing the display title is possible. + */ + public function getDisplayLabel(ViewUI $view, $display_id, $check_changed = TRUE) { + $display = $view->get('display'); + $title = $display_id == 'default' ? $this->t('Master') : $display[$display_id]['display_title']; + $title = views_ui_truncate($title, 25); + + if ($check_changed && !empty($view->changed_display[$display_id])) { + $changed = '*'; + $title = $title . $changed; + } + + return $title; + } + +}