annotate core/modules/views_ui/views_ui.module @ 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 /**
Chris@0 4 * @file
Chris@0 5 * Provide structure for the administrative interface to Views.
Chris@0 6 */
Chris@0 7
Chris@0 8 use Drupal\Core\Routing\RouteMatchInterface;
Chris@0 9 use Drupal\Core\Url;
Chris@0 10 use Drupal\views\ViewExecutable;
Chris@0 11 use Drupal\views\Analyzer;
Chris@0 12
Chris@0 13 /**
Chris@0 14 * Implements hook_help().
Chris@0 15 */
Chris@0 16 function views_ui_help($route_name, RouteMatchInterface $route_match) {
Chris@0 17 switch ($route_name) {
Chris@0 18 case 'help.page.views_ui':
Chris@0 19 $output = '';
Chris@0 20 $output .= '<h3>' . t('About') . '</h3>';
Chris@18 21 $output .= '<p>' . t('The Views UI module provides an interface for managing views for the <a href=":views">Views module</a>. For more information, see the <a href=":handbook">online documentation for the Views UI module</a>.', [':views' => Url::fromRoute('help.page', ['name' => 'views'])->toString(), ':handbook' => 'https://www.drupal.org/documentation/modules/views_ui']) . '</p>';
Chris@0 22 $output .= '<h3>' . t('Uses') . '</h3>';
Chris@0 23 $output .= '<dl>';
Chris@0 24 $output .= '<dt>' . t('Creating and managing views') . '</dt>';
Chris@18 25 $output .= '<dd>' . t('Views can be created from the <a href=":list">Views list page</a> by using the "Add view" action. Existing views can be managed from the <a href=":list">Views list page</a> by locating the view in the "Enabled" or "Disabled" list and selecting the desired operation action, for example "Edit".', [':list' => Url::fromRoute('entity.view.collection', ['name' => 'views_ui'])->toString()]) . '</dd>';
Chris@0 26 $output .= '<dt>' . t('Enabling and disabling views') . '<dt>';
Chris@18 27 $output .= '<dd>' . t('Views can be enabled or disabled from the <a href=":list">Views list page</a>. To enable a view, find the view within the "Disabled" list and select the "Enable" operation. To disable a view find the view within the "Enabled" list and select the "Disable" operation.', [':list' => Url::fromRoute('entity.view.collection', ['name' => 'views_ui'])->toString()]) . '</dd>';
Chris@0 28 $output .= '<dt>' . t('Exporting and importing views') . '</dt>';
Chris@18 29 $output .= '<dd>' . t('Views can be exported and imported as configuration files by using the <a href=":config">Configuration Manager module</a>.', [':config' => (\Drupal::moduleHandler()->moduleExists('config')) ? Url::fromRoute('help.page', ['name' => 'config'])->toString() : '#']) . '</dd>';
Chris@0 30 $output .= '</dl>';
Chris@0 31 return $output;
Chris@0 32 }
Chris@0 33 }
Chris@0 34
Chris@0 35 /**
Chris@0 36 * Implements hook_entity_type_build().
Chris@0 37 */
Chris@0 38 function views_ui_entity_type_build(array &$entity_types) {
Chris@0 39 /** @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */
Chris@0 40 $entity_types['view']
Chris@0 41 ->setFormClass('edit', 'Drupal\views_ui\ViewEditForm')
Chris@0 42 ->setFormClass('add', 'Drupal\views_ui\ViewAddForm')
Chris@0 43 ->setFormClass('preview', 'Drupal\views_ui\ViewPreviewForm')
Chris@0 44 ->setFormClass('duplicate', 'Drupal\views_ui\ViewDuplicateForm')
Chris@0 45 ->setFormClass('delete', 'Drupal\Core\Entity\EntityDeleteForm')
Chris@0 46 ->setFormClass('break_lock', 'Drupal\views_ui\Form\BreakLockForm')
Chris@0 47 ->setListBuilderClass('Drupal\views_ui\ViewListBuilder')
Chris@0 48 ->setLinkTemplate('edit-form', '/admin/structure/views/view/{view}')
Chris@0 49 ->setLinkTemplate('edit-display-form', '/admin/structure/views/view/{view}/edit/{display_id}')
Chris@0 50 ->setLinkTemplate('preview-form', '/admin/structure/views/view/{view}/preview/{display_id}')
Chris@0 51 ->setLinkTemplate('duplicate-form', '/admin/structure/views/view/{view}/duplicate')
Chris@0 52 ->setLinkTemplate('delete-form', '/admin/structure/views/view/{view}/delete')
Chris@0 53 ->setLinkTemplate('enable', '/admin/structure/views/view/{view}/enable')
Chris@0 54 ->setLinkTemplate('disable', '/admin/structure/views/view/{view}/disable')
Chris@0 55 ->setLinkTemplate('break-lock-form', '/admin/structure/views/view/{view}/break-lock')
Chris@0 56 ->setLinkTemplate('collection', '/admin/structure/views');
Chris@0 57 }
Chris@0 58
Chris@0 59 /**
Chris@0 60 * Implements hook_theme().
Chris@0 61 */
Chris@0 62 function views_ui_theme() {
Chris@0 63 return [
Chris@0 64 // edit a view
Chris@0 65 'views_ui_display_tab_setting' => [
Chris@0 66 'variables' => ['description' => '', 'link' => '', 'settings_links' => [], 'overridden' => FALSE, 'defaulted' => FALSE, 'description_separator' => TRUE, 'class' => []],
Chris@0 67 'file' => 'views_ui.theme.inc',
Chris@0 68 ],
Chris@0 69 'views_ui_display_tab_bucket' => [
Chris@0 70 'render element' => 'element',
Chris@0 71 'file' => 'views_ui.theme.inc',
Chris@0 72 ],
Chris@0 73 'views_ui_rearrange_filter_form' => [
Chris@0 74 'render element' => 'form',
Chris@0 75 'file' => 'views_ui.theme.inc',
Chris@0 76 ],
Chris@0 77 'views_ui_expose_filter_form' => [
Chris@0 78 'render element' => 'form',
Chris@0 79 'file' => 'views_ui.theme.inc',
Chris@0 80 ],
Chris@0 81
Chris@0 82 // Legacy theme hook for displaying views info.
Chris@0 83 'views_ui_view_info' => [
Chris@0 84 'variables' => ['view' => NULL, 'displays' => NULL],
Chris@0 85 'file' => 'views_ui.theme.inc',
Chris@0 86 ],
Chris@0 87
Chris@0 88 // List views.
Chris@0 89 'views_ui_views_listing_table' => [
Chris@0 90 'variables' => [
Chris@0 91 'headers' => NULL,
Chris@0 92 'rows' => NULL,
Chris@0 93 'attributes' => [],
Chris@0 94 ],
Chris@0 95 'file' => 'views_ui.theme.inc',
Chris@0 96 ],
Chris@0 97 'views_ui_view_displays_list' => [
Chris@0 98 'variables' => ['displays' => []],
Chris@0 99 ],
Chris@0 100
Chris@0 101 // Group of filters.
Chris@0 102 'views_ui_build_group_filter_form' => [
Chris@0 103 'render element' => 'form',
Chris@0 104 'file' => 'views_ui.theme.inc',
Chris@0 105 ],
Chris@0 106
Chris@0 107 // On behalf of a plugin
Chris@0 108 'views_ui_style_plugin_table' => [
Chris@0 109 'render element' => 'form',
Chris@0 110 'file' => 'views_ui.theme.inc',
Chris@0 111 ],
Chris@0 112
Chris@0 113 // When previewing a view.
Chris@0 114 'views_ui_view_preview_section' => [
Chris@0 115 'variables' => ['view' => NULL, 'section' => NULL, 'content' => NULL, 'links' => ''],
Chris@0 116 'file' => 'views_ui.theme.inc',
Chris@0 117 ],
Chris@0 118
Chris@0 119 // Generic container wrapper, to use instead of theme_container when an id
Chris@0 120 // is not desired.
Chris@0 121 'views_ui_container' => [
Chris@0 122 'variables' => ['children' => NULL, 'attributes' => []],
Chris@0 123 'file' => 'views_ui.theme.inc',
Chris@0 124 ],
Chris@0 125 ];
Chris@0 126 }
Chris@0 127
Chris@0 128 /**
Chris@0 129 * Implements hook_preprocess_HOOK() for views templates.
Chris@0 130 */
Chris@0 131 function views_ui_preprocess_views_view(&$variables) {
Chris@0 132 $view = $variables['view'];
Chris@0 133
Chris@0 134 // Render title for the admin preview.
Chris@0 135 if (!empty($view->live_preview)) {
Chris@0 136 $variables['title'] = [
Chris@17 137 '#markup' => $view->getTitle(),
Chris@0 138 ];
Chris@0 139 }
Chris@0 140
Chris@0 141 if (!empty($view->live_preview) && \Drupal::moduleHandler()->moduleExists('contextual')) {
Chris@0 142 $view->setShowAdminLinks(FALSE);
Chris@0 143 foreach (['title', 'header', 'exposed', 'rows', 'pager', 'more', 'footer', 'empty', 'attachment_after', 'attachment_before'] as $section) {
Chris@0 144 if (!empty($variables[$section])) {
Chris@0 145 $variables[$section] = [
Chris@0 146 '#theme' => 'views_ui_view_preview_section',
Chris@0 147 '#view' => $view,
Chris@0 148 '#section' => $section,
Chris@0 149 '#content' => $variables[$section],
Chris@0 150 '#theme_wrappers' => ['views_ui_container'],
Chris@0 151 '#attributes' => ['class' => ['contextual-region']],
Chris@0 152 ];
Chris@0 153 }
Chris@0 154 }
Chris@0 155 }
Chris@0 156 }
Chris@0 157
Chris@0 158 /**
Chris@12 159 * Implements hook_theme_suggestions_HOOK().
Chris@12 160 */
Chris@12 161 function views_ui_theme_suggestions_views_ui_view_preview_section(array $variables) {
Chris@12 162 return ['views_ui_view_preview_section__' . $variables['section']];
Chris@12 163 }
Chris@12 164
Chris@12 165 /**
Chris@0 166 * Returns contextual links for each handler of a certain section.
Chris@0 167 *
Chris@0 168 * @TODO
Chris@0 169 * Bring in relationships
Chris@0 170 * Refactor this function to use much stuff of views_ui_edit_form_get_bucket.
Chris@0 171 *
Chris@0 172 * @param $title
Chris@0 173 * Add a bolded title of this section.
Chris@0 174 */
Chris@0 175 function views_ui_view_preview_section_handler_links(ViewExecutable $view, $type, $title = FALSE) {
Chris@0 176 $display = $view->display_handler->display;
Chris@0 177 $handlers = $view->display_handler->getHandlers($type);
Chris@0 178 $links = [];
Chris@0 179
Chris@0 180 $types = ViewExecutable::getHandlerTypes();
Chris@0 181 if ($title) {
Chris@0 182 $links[$type . '-title'] = [
Chris@0 183 'title' => $types[$type]['title'],
Chris@0 184 ];
Chris@0 185 }
Chris@0 186
Chris@0 187 foreach ($handlers as $id => $handler) {
Chris@0 188 $field_name = $handler->adminLabel(TRUE);
Chris@0 189 $links[$type . '-edit-' . $id] = [
Chris@0 190 'title' => t('Edit @section', ['@section' => $field_name]),
Chris@0 191 'url' => Url::fromRoute('views_ui.form_handler', ['js' => 'nojs', 'view' => $view->storage->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id]),
Chris@0 192 'attributes' => ['class' => ['views-ajax-link']],
Chris@0 193 ];
Chris@0 194 }
Chris@0 195 $links[$type . '-add'] = [
Chris@0 196 'title' => t('Add new'),
Chris@0 197 'url' => Url::fromRoute('views_ui.form_add_handler', ['js' => 'nojs', 'view' => $view->storage->id(), 'display_id' => $display['id'], 'type' => $type]),
Chris@0 198 'attributes' => ['class' => ['views-ajax-link']],
Chris@0 199 ];
Chris@0 200
Chris@0 201 return $links;
Chris@0 202 }
Chris@0 203
Chris@0 204 /**
Chris@0 205 * Returns a link to editing a certain display setting.
Chris@0 206 */
Chris@0 207 function views_ui_view_preview_section_display_category_links(ViewExecutable $view, $type, $title) {
Chris@0 208 $display = $view->display_handler->display;
Chris@0 209 $links = [
Chris@0 210 $type . '-edit' => [
Chris@0 211 'title' => t('Edit @section', ['@section' => $title]),
Chris@0 212 'url' => Url::fromRoute('views_ui.form_display', ['js' => 'nojs', 'view' => $view->storage->id(), 'display_id' => $display['id'], 'type' => $type]),
Chris@0 213 'attributes' => ['class' => ['views-ajax-link']],
Chris@0 214 ],
Chris@0 215 ];
Chris@0 216
Chris@0 217 return $links;
Chris@0 218 }
Chris@0 219
Chris@0 220 /**
Chris@0 221 * Returns all contextual links for the main content part of the view.
Chris@0 222 */
Chris@0 223 function views_ui_view_preview_section_rows_links(ViewExecutable $view) {
Chris@0 224 $links = [];
Chris@0 225 $links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'filter', TRUE));
Chris@0 226 $links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'field', TRUE));
Chris@0 227 $links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'sort', TRUE));
Chris@0 228 $links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'argument', TRUE));
Chris@0 229 $links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'relationship', TRUE));
Chris@0 230
Chris@0 231 return $links;
Chris@0 232 }
Chris@0 233
Chris@0 234 /**
Chris@0 235 * Implements hook_views_plugins_display_alter().
Chris@0 236 */
Chris@0 237 function views_ui_views_plugins_display_alter(&$plugins) {
Chris@0 238 // Attach contextual links to each display plugin. The links will point to
Chris@0 239 // paths underneath "admin/structure/views/view/{$view->id()}" (i.e., paths
Chris@0 240 // for editing and performing other contextual actions on the view).
Chris@0 241 foreach ($plugins as &$display) {
Chris@0 242 $display['contextual links']['entity.view.edit_form'] = [
Chris@0 243 'route_name' => 'entity.view.edit_form',
Chris@0 244 'route_parameters_names' => ['view' => 'id'],
Chris@0 245 ];
Chris@0 246 }
Chris@0 247 }
Chris@0 248
Chris@0 249 /**
Chris@0 250 * Implements hook_contextual_links_view_alter().
Chris@0 251 */
Chris@0 252 function views_ui_contextual_links_view_alter(&$element, $items) {
Chris@0 253 // Remove contextual links from being rendered, when so desired, such as
Chris@0 254 // within a View preview.
Chris@0 255 if (views_ui_contextual_links_suppress()) {
Chris@0 256 $element['#links'] = [];
Chris@0 257 }
Chris@0 258 // Append the display ID to the Views UI edit links, so that clicking on the
Chris@0 259 // contextual link takes you directly to the correct display tab on the edit
Chris@0 260 // screen.
Chris@0 261 elseif (!empty($element['#links']['entityviewedit-form'])) {
Chris@0 262 $display_id = $items['entity.view.edit_form']['metadata']['display_id'];
Chris@0 263 $route_parameters = $element['#links']['entityviewedit-form']['url']->getRouteParameters() + ['display_id' => $display_id];
Chris@0 264 $element['#links']['entityviewedit-form']['url'] = Url::fromRoute('entity.view.edit_display_form', $route_parameters);
Chris@0 265 }
Chris@0 266 }
Chris@0 267
Chris@0 268 /**
Chris@0 269 * Sets a static variable for controlling whether contextual links are rendered.
Chris@0 270 *
Chris@0 271 * @see views_ui_contextual_links_view_alter()
Chris@0 272 */
Chris@0 273 function views_ui_contextual_links_suppress($set = NULL) {
Chris@0 274 $suppress = &drupal_static(__FUNCTION__);
Chris@0 275 if (isset($set)) {
Chris@0 276 $suppress = $set;
Chris@0 277 }
Chris@0 278 return $suppress;
Chris@0 279 }
Chris@0 280
Chris@0 281 /**
Chris@0 282 * Increments the views_ui_contextual_links_suppress() static variable.
Chris@0 283 *
Chris@0 284 * When this function is added to the #pre_render of an element, and
Chris@0 285 * 'views_ui_contextual_links_suppress_pop' is added to the #post_render of the
Chris@0 286 * same element, then all contextual links within the element and its
Chris@0 287 * descendants are suppressed from being rendered. This is used, for example,
Chris@0 288 * during a View preview, when it is not desired for nodes in the Views result
Chris@0 289 * to have contextual links.
Chris@0 290 *
Chris@0 291 * @see views_ui_contextual_links_suppress_pop()
Chris@0 292 */
Chris@0 293 function views_ui_contextual_links_suppress_push() {
Chris@0 294 views_ui_contextual_links_suppress(((int) views_ui_contextual_links_suppress()) + 1);
Chris@0 295 }
Chris@0 296
Chris@0 297 /**
Chris@0 298 * Decrements the views_ui_contextual_links_suppress() static variable.
Chris@0 299 *
Chris@0 300 * @see views_ui_contextual_links_suppress_push()
Chris@0 301 */
Chris@0 302 function views_ui_contextual_links_suppress_pop() {
Chris@0 303 views_ui_contextual_links_suppress(((int) views_ui_contextual_links_suppress()) - 1);
Chris@0 304 }
Chris@0 305
Chris@0 306 /**
Chris@0 307 * Implements hook_views_analyze().
Chris@0 308 *
Chris@0 309 * This is the basic views analysis that checks for very minimal problems.
Chris@0 310 * There are other analysis tools in core specific sections, such as
Chris@0 311 * node.views.inc as well.
Chris@0 312 */
Chris@0 313 function views_ui_views_analyze(ViewExecutable $view) {
Chris@0 314 $ret = [];
Chris@0 315 // Check for something other than the default display:
Chris@0 316 if (count($view->displayHandlers) < 2) {
Chris@0 317 $ret[] = Analyzer::formatMessage(t('This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display.'), 'warning');
Chris@0 318 }
Chris@0 319 // You can give a page display the same path as an alias existing in the
Chris@0 320 // system, so the alias will not work anymore. Report this to the user,
Chris@0 321 // because he probably wanted something else.
Chris@0 322 foreach ($view->displayHandlers as $display) {
Chris@0 323 if (empty($display)) {
Chris@0 324 continue;
Chris@0 325 }
Chris@0 326 if ($display->hasPath() && $path = $display->getOption('path')) {
Chris@0 327 $normal_path = \Drupal::service('path.alias_manager')->getPathByAlias($path);
Chris@0 328 if ($path != $normal_path) {
Chris@0 329 $ret[] = Analyzer::formatMessage(t('You have configured display %display with a path which is an path alias as well. This might lead to unwanted effects so better use an internal path.', ['%display' => $display->display['display_title']]), 'warning');
Chris@0 330 }
Chris@0 331 }
Chris@0 332 }
Chris@0 333
Chris@0 334 return $ret;
Chris@0 335 }
Chris@0 336
Chris@0 337 /**
Chris@0 338 * Truncate strings to a set length and provide a '...' if they truncated.
Chris@0 339 *
Chris@0 340 * This is often used in the UI to ensure long strings fit.
Chris@0 341 */
Chris@0 342 function views_ui_truncate($string, $length) {
Chris@17 343 if (mb_strlen($string) > $length) {
Chris@17 344 $string = mb_substr($string, 0, $length);
Chris@0 345 $string .= '...';
Chris@0 346 }
Chris@0 347
Chris@0 348 return $string;
Chris@0 349 }