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