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