Backup of db before drupal security update
[yaffs-website] / web / core / modules / views_ui / src / Controller / ViewsUIController.php
1 <?php
2
3 namespace Drupal\views_ui\Controller;
4
5 use Drupal\Core\Controller\ControllerBase;
6 use Drupal\Core\Url;
7 use Drupal\views\ViewExecutable;
8 use Drupal\views\ViewEntityInterface;
9 use Drupal\views\Views;
10 use Drupal\views_ui\ViewUI;
11 use Drupal\views\ViewsData;
12 use Symfony\Component\DependencyInjection\ContainerInterface;
13 use Symfony\Component\HttpFoundation\Request;
14 use Symfony\Component\HttpFoundation\JsonResponse;
15 use Drupal\Core\Ajax\AjaxResponse;
16 use Drupal\Core\Ajax\ReplaceCommand;
17 use Drupal\Component\Utility\Html;
18
19 /**
20  * Returns responses for Views UI routes.
21  */
22 class ViewsUIController extends ControllerBase {
23
24   /**
25    * Stores the Views data cache object.
26    *
27    * @var \Drupal\views\ViewsData
28    */
29   protected $viewsData;
30
31   /**
32    * Constructs a new \Drupal\views_ui\Controller\ViewsUIController object.
33    *
34    * @param \Drupal\views\ViewsData $views_data
35    *   The Views data cache object.
36    */
37   public function __construct(ViewsData $views_data) {
38     $this->viewsData = $views_data;
39   }
40
41   /**
42    * {@inheritdoc}
43    */
44   public static function create(ContainerInterface $container) {
45     return new static(
46       $container->get('views.views_data')
47     );
48   }
49
50   /**
51    * Lists all instances of fields on any views.
52    *
53    * @return array
54    *   The Views fields report page.
55    */
56   public function reportFields() {
57     $views = $this->entityManager()->getStorage('view')->loadMultiple();
58
59     // Fetch all fieldapi fields which are used in views
60     // Therefore search in all views, displays and handler-types.
61     $fields = [];
62     $handler_types = ViewExecutable::getHandlerTypes();
63     foreach ($views as $view) {
64       $executable = $view->getExecutable();
65       $executable->initDisplay();
66       foreach ($executable->displayHandlers as $display_id => $display) {
67         if ($executable->setDisplay($display_id)) {
68           foreach ($handler_types as $type => $info) {
69             foreach ($executable->getHandlers($type, $display_id) as $item) {
70               $table_data = $this->viewsData->get($item['table']);
71               if (isset($table_data[$item['field']]) && isset($table_data[$item['field']][$type])
72                 && $field_data = $table_data[$item['field']][$type]) {
73                 // The final check that we have a fieldapi field now.
74                 if (isset($field_data['field_name'])) {
75                   $fields[$field_data['field_name']][$view->id()] = $view->id();
76                 }
77               }
78             }
79           }
80         }
81       }
82     }
83
84     $header = [t('Field name'), t('Used in')];
85     $rows = [];
86     foreach ($fields as $field_name => $views) {
87       $rows[$field_name]['data'][0]['data']['#plain_text'] = $field_name;
88       foreach ($views as $view) {
89         $rows[$field_name]['data'][1][] = $this->l($view, new Url('entity.view.edit_form', ['view' => $view]));
90       }
91       $item_list = [
92         '#theme' => 'item_list',
93         '#items' => $rows[$field_name]['data'][1],
94         '#context' => ['list_style' => 'comma-list'],
95       ];
96       $rows[$field_name]['data'][1] = ['data' => $item_list];
97     }
98
99     // Sort rows by field name.
100     ksort($rows);
101     $output = [
102       '#type' => 'table',
103       '#header' => $header,
104       '#rows' => $rows,
105       '#empty' => t('No fields have been used in views yet.'),
106     ];
107
108     return $output;
109   }
110
111   /**
112    * Lists all plugins and what enabled Views use them.
113    *
114    * @return array
115    *   The Views plugins report page.
116    */
117   public function reportPlugins() {
118     $rows = Views::pluginList();
119     foreach ($rows as &$row) {
120       $views = [];
121       // Link each view name to the view itself.
122       foreach ($row['views'] as $row_name => $view) {
123         $views[] = $this->l($view, new Url('entity.view.edit_form', ['view' => $view]));
124       }
125       unset($row['views']);
126       $row['views']['data'] = [
127         '#theme' => 'item_list',
128         '#items' => $views,
129         '#context' => ['list_style' => 'comma-list'],
130       ];
131     }
132
133     // Sort rows by field name.
134     ksort($rows);
135     return [
136       '#type' => 'table',
137       '#header' => [t('Type'), t('Name'), t('Provided by'), t('Used in')],
138       '#rows' => $rows,
139       '#empty' => t('There are no enabled views.'),
140     ];
141   }
142
143   /**
144    * Calls a method on a view and reloads the listing page.
145    *
146    * @param \Drupal\views\ViewEntityInterface $view
147    *   The view being acted upon.
148    * @param string $op
149    *   The operation to perform, e.g., 'enable' or 'disable'.
150    * @param \Symfony\Component\HttpFoundation\Request $request
151    *   The current request.
152    *
153    * @return \Drupal\Core\Ajax\AjaxResponse|\Symfony\Component\HttpFoundation\RedirectResponse
154    *   Either returns a rebuilt listing page as an AJAX response, or redirects
155    *   back to the listing page.
156    */
157   public function ajaxOperation(ViewEntityInterface $view, $op, Request $request) {
158     // Perform the operation.
159     $view->$op()->save();
160
161     // If the request is via AJAX, return the rendered list as JSON.
162     if ($request->request->get('js')) {
163       $list = $this->entityManager()->getListBuilder('view')->render();
164       $response = new AjaxResponse();
165       $response->addCommand(new ReplaceCommand('#views-entity-list', $list));
166       return $response;
167     }
168
169     // Otherwise, redirect back to the page.
170     return $this->redirect('entity.view.collection');
171   }
172
173   /**
174    * Menu callback for Views tag autocompletion.
175    *
176    * Like other autocomplete functions, this function inspects the 'q' query
177    * parameter for the string to use to search for suggestions.
178    *
179    * @return \Symfony\Component\HttpFoundation\JsonResponse
180    *   A JSON response containing the autocomplete suggestions for Views tags.
181    */
182   public function autocompleteTag(Request $request) {
183     $matches = [];
184     $string = $request->query->get('q');
185     // Get matches from default views.
186     $views = $this->entityManager()->getStorage('view')->loadMultiple();
187     // Keep track of previously processed tags so they can be skipped.
188     $tags = [];
189     foreach ($views as $view) {
190       $tag = $view->get('tag');
191       if ($tag && !in_array($tag, $tags)) {
192         $tags[] = $tag;
193         if (strpos($tag, $string) === 0) {
194           $matches[] = ['value' => $tag, 'label' => Html::escape($tag)];
195           if (count($matches) >= 10) {
196             break;
197           }
198         }
199       }
200     }
201
202     return new JsonResponse($matches);
203   }
204
205   /**
206    * Returns the form to edit a view.
207    *
208    * @param \Drupal\views_ui\ViewUI $view
209    *   The view to be edited.
210    * @param string|null $display_id
211    *   (optional) The display ID being edited. Defaults to NULL, which will load
212    *   the first available display.
213    *
214    * @return array
215    *   An array containing the Views edit and preview forms.
216    */
217   public function edit(ViewUI $view, $display_id = NULL) {
218     $name = $view->label();
219     $data = $this->viewsData->get($view->get('base_table'));
220
221     if (isset($data['table']['base']['title'])) {
222       $name .= ' (' . $data['table']['base']['title'] . ')';
223     }
224     $build['#title'] = $name;
225
226     $build['edit'] = $this->entityFormBuilder()->getForm($view, 'edit', ['display_id' => $display_id]);
227     $build['preview'] = $this->entityFormBuilder()->getForm($view, 'preview', ['display_id' => $display_id]);
228     return $build;
229   }
230
231 }