annotate core/modules/views_ui/src/ViewFormBase.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\views_ui;
Chris@0 4
Chris@0 5 use Drupal\Core\Entity\EntityForm;
Chris@0 6 use Drupal\Core\Form\FormStateInterface;
Chris@0 7 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
Chris@0 8 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
Chris@0 9
Chris@0 10 /**
Chris@0 11 * Base form for Views forms.
Chris@0 12 */
Chris@0 13 abstract class ViewFormBase extends EntityForm {
Chris@0 14
Chris@0 15 /**
Chris@0 16 * The name of the display used by the form.
Chris@0 17 *
Chris@0 18 * @var string
Chris@0 19 */
Chris@0 20 protected $displayID;
Chris@0 21
Chris@0 22 /**
Chris@0 23 * {@inheritdoc}
Chris@0 24 */
Chris@0 25 public function init(FormStateInterface $form_state) {
Chris@0 26 parent::init($form_state);
Chris@0 27
Chris@0 28 // @todo Remove the need for this.
Chris@0 29 $form_state->loadInclude('views_ui', 'inc', 'admin');
Chris@0 30 $form_state->set('view', $this->entity);
Chris@0 31 }
Chris@0 32
Chris@0 33 /**
Chris@0 34 * {@inheritdoc}
Chris@0 35 */
Chris@0 36 public function buildForm(array $form, FormStateInterface $form_state, $display_id = NULL) {
Chris@0 37 if (isset($display_id) && $form_state->has('display_id') && ($display_id !== $form_state->get('display_id'))) {
Chris@0 38 throw new \InvalidArgumentException('Mismatch between $form_state->get(\'display_id\') and $display_id.');
Chris@0 39 }
Chris@0 40 $this->displayID = $form_state->has('display_id') ? $form_state->get('display_id') : $display_id;
Chris@0 41 return parent::buildForm($form, $form_state);
Chris@0 42 }
Chris@0 43
Chris@0 44 /**
Chris@0 45 * {@inheritdoc}
Chris@0 46 */
Chris@0 47 protected function prepareEntity() {
Chris@0 48 // Determine the displays available for editing.
Chris@0 49 if ($tabs = $this->getDisplayTabs($this->entity)) {
Chris@0 50 if (empty($this->displayID)) {
Chris@0 51 // If a display isn't specified, use the first one after sorting by
Chris@0 52 // #weight.
Chris@0 53 uasort($tabs, 'Drupal\Component\Utility\SortArray::sortByWeightProperty');
Chris@0 54 foreach ($tabs as $id => $tab) {
Chris@0 55 if (!isset($tab['#access']) || $tab['#access']) {
Chris@0 56 $this->displayID = $id;
Chris@0 57 break;
Chris@0 58 }
Chris@0 59 }
Chris@0 60 }
Chris@0 61 // If a display is specified, but we don't have access to it, return
Chris@0 62 // an access denied page.
Chris@0 63 if ($this->displayID && !isset($tabs[$this->displayID])) {
Chris@0 64 throw new NotFoundHttpException();
Chris@0 65 }
Chris@0 66 elseif ($this->displayID && (isset($tabs[$this->displayID]['#access']) && !$tabs[$this->displayID]['#access'])) {
Chris@0 67 throw new AccessDeniedHttpException();
Chris@0 68 }
Chris@0 69
Chris@0 70 }
Chris@0 71 elseif ($this->displayID) {
Chris@0 72 throw new NotFoundHttpException();
Chris@0 73 }
Chris@0 74 }
Chris@0 75
Chris@0 76 /**
Chris@0 77 * Adds tabs for navigating across Displays when editing a View.
Chris@0 78 *
Chris@0 79 * This function can be called from hook_menu_local_tasks_alter() to implement
Chris@0 80 * these tabs as secondary local tasks, or it can be called from elsewhere if
Chris@0 81 * having them as secondary local tasks isn't desired. The caller is responsible
Chris@0 82 * for setting the active tab's #active property to TRUE.
Chris@0 83 *
Chris@0 84 * @param $display_id
Chris@0 85 * The display_id which is edited on the current request.
Chris@0 86 */
Chris@0 87 public function getDisplayTabs(ViewUI $view) {
Chris@0 88 $executable = $view->getExecutable();
Chris@0 89 $executable->initDisplay();
Chris@0 90 $display_id = $this->displayID;
Chris@0 91 $tabs = [];
Chris@0 92
Chris@0 93 // Create a tab for each display.
Chris@0 94 foreach ($view->get('display') as $id => $display) {
Chris@0 95 // Get an instance of the display plugin, to make sure it will work in the
Chris@0 96 // UI.
Chris@0 97 $display_plugin = $executable->displayHandlers->get($id);
Chris@0 98 if (empty($display_plugin)) {
Chris@0 99 continue;
Chris@0 100 }
Chris@0 101
Chris@0 102 $tabs[$id] = [
Chris@0 103 '#theme' => 'menu_local_task',
Chris@0 104 '#weight' => $display['position'],
Chris@0 105 '#link' => [
Chris@0 106 'title' => $this->getDisplayLabel($view, $id),
Chris@0 107 'localized_options' => [],
Chris@18 108 'url' => $view->toUrl('edit-display-form')->setRouteParameter('display_id', $id),
Chris@0 109 ],
Chris@0 110 ];
Chris@0 111 if (!empty($display['deleted'])) {
Chris@0 112 $tabs[$id]['#link']['localized_options']['attributes']['class'][] = 'views-display-deleted-link';
Chris@0 113 }
Chris@0 114 if (isset($display['display_options']['enabled']) && !$display['display_options']['enabled']) {
Chris@0 115 $tabs[$id]['#link']['localized_options']['attributes']['class'][] = 'views-display-disabled-link';
Chris@0 116 }
Chris@0 117 }
Chris@0 118
Chris@0 119 // If the default display isn't supposed to be shown, don't display its tab, unless it's the only display.
Chris@0 120 if ((!$this->isDefaultDisplayShown($view) && $display_id != 'default') && count($tabs) > 1) {
Chris@0 121 $tabs['default']['#access'] = FALSE;
Chris@0 122 }
Chris@0 123
Chris@0 124 // Mark the display tab as red to show validation errors.
Chris@0 125 $errors = $executable->validate();
Chris@0 126 foreach ($view->get('display') as $id => $display) {
Chris@0 127 if (!empty($errors[$id])) {
Chris@0 128 // Always show the tab.
Chris@0 129 $tabs[$id]['#access'] = TRUE;
Chris@0 130 // Add a class to mark the error and a title to make a hover tip.
Chris@0 131 $tabs[$id]['#link']['localized_options']['attributes']['class'][] = 'error';
Chris@0 132 $tabs[$id]['#link']['localized_options']['attributes']['title'] = $this->t('This display has one or more validation errors.');
Chris@0 133 }
Chris@0 134 }
Chris@0 135
Chris@0 136 return $tabs;
Chris@0 137 }
Chris@0 138
Chris@0 139 /**
Chris@0 140 * Controls whether or not the default display should have its own tab on edit.
Chris@0 141 */
Chris@0 142 public function isDefaultDisplayShown(ViewUI $view) {
Chris@0 143 // Always show the default display for advanced users who prefer that mode.
Chris@0 144 $advanced_mode = \Drupal::config('views.settings')->get('ui.show.master_display');
Chris@0 145 // For other users, show the default display only if there are no others, and
Chris@0 146 // hide it if there's at least one "real" display.
Chris@0 147 $additional_displays = (count($view->getExecutable()->displayHandlers) == 1);
Chris@0 148
Chris@0 149 return $advanced_mode || $additional_displays;
Chris@0 150 }
Chris@0 151
Chris@0 152 /**
Chris@0 153 * Placeholder function for overriding $display['display_title'].
Chris@0 154 *
Chris@0 155 * @todo Remove this function once editing the display title is possible.
Chris@0 156 */
Chris@0 157 public function getDisplayLabel(ViewUI $view, $display_id, $check_changed = TRUE) {
Chris@0 158 $display = $view->get('display');
Chris@0 159 $title = $display_id == 'default' ? $this->t('Master') : $display[$display_id]['display_title'];
Chris@0 160 $title = views_ui_truncate($title, 25);
Chris@0 161
Chris@0 162 if ($check_changed && !empty($view->changed_display[$display_id])) {
Chris@0 163 $changed = '*';
Chris@0 164 $title = $title . $changed;
Chris@0 165 }
Chris@0 166
Chris@0 167 return $title;
Chris@0 168 }
Chris@0 169
Chris@0 170 }