annotate core/modules/views_ui/src/ViewUI.php @ 0:c75dbcec494b

Initial commit from drush-created site
author Chris Cannam
date Thu, 05 Jul 2018 14:24:15 +0000
parents
children a9cd425dd02b
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\Component\Utility\Html;
Chris@0 6 use Drupal\Component\Utility\Timer;
Chris@0 7 use Drupal\Core\EventSubscriber\AjaxResponseSubscriber;
Chris@0 8 use Drupal\Core\Form\FormStateInterface;
Chris@0 9 use Drupal\views\Views;
Chris@0 10 use Drupal\Core\Entity\EntityStorageInterface;
Chris@0 11 use Drupal\views\ViewExecutable;
Chris@0 12 use Drupal\Core\Database\Database;
Chris@0 13 use Drupal\Core\Session\AccountInterface;
Chris@0 14 use Drupal\views\Plugin\views\query\Sql;
Chris@0 15 use Drupal\views\Entity\View;
Chris@0 16 use Drupal\views\ViewEntityInterface;
Chris@0 17 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
Chris@0 18 use Symfony\Component\HttpFoundation\ParameterBag;
Chris@0 19 use Symfony\Component\HttpFoundation\Request;
Chris@0 20
Chris@0 21 /**
Chris@0 22 * Stores UI related temporary settings.
Chris@0 23 */
Chris@0 24 class ViewUI implements ViewEntityInterface {
Chris@0 25
Chris@0 26 /**
Chris@0 27 * Indicates if a view is currently being edited.
Chris@0 28 *
Chris@0 29 * @var bool
Chris@0 30 */
Chris@0 31 public $editing = FALSE;
Chris@0 32
Chris@0 33 /**
Chris@0 34 * Stores an array of displays that have been changed.
Chris@0 35 *
Chris@0 36 * @var array
Chris@0 37 */
Chris@0 38 public $changed_display;
Chris@0 39
Chris@0 40 /**
Chris@0 41 * How long the view takes to render in microseconds.
Chris@0 42 *
Chris@0 43 * @var float
Chris@0 44 */
Chris@0 45 public $render_time;
Chris@0 46
Chris@0 47 /**
Chris@0 48 * If this view is locked for editing.
Chris@0 49 *
Chris@0 50 * If this view is locked it will contain the result of
Chris@0 51 * \Drupal\Core\TempStore\SharedTempStore::getMetadata(). Which can be a stdClass or
Chris@0 52 * NULL.
Chris@0 53 *
Chris@0 54 * @var stdClass
Chris@0 55 */
Chris@0 56 public $lock;
Chris@0 57
Chris@0 58 /**
Chris@0 59 * If this view has been changed.
Chris@0 60 *
Chris@0 61 * @var bool
Chris@0 62 */
Chris@0 63 public $changed;
Chris@0 64
Chris@0 65 /**
Chris@0 66 * Stores options temporarily while editing.
Chris@0 67 *
Chris@0 68 * @var array
Chris@0 69 */
Chris@0 70 public $temporary_options;
Chris@0 71
Chris@0 72 /**
Chris@0 73 * Stores a stack of UI forms to display.
Chris@0 74 *
Chris@0 75 * @var array
Chris@0 76 */
Chris@0 77 public $stack;
Chris@0 78
Chris@0 79 /**
Chris@0 80 * Is the view run in a context of the preview in the admin interface.
Chris@0 81 *
Chris@0 82 * @var bool
Chris@0 83 */
Chris@0 84 public $live_preview;
Chris@0 85
Chris@0 86 public $renderPreview = FALSE;
Chris@0 87
Chris@0 88 /**
Chris@0 89 * The View storage object.
Chris@0 90 *
Chris@0 91 * @var \Drupal\views\ViewEntityInterface
Chris@0 92 */
Chris@0 93 protected $storage;
Chris@0 94
Chris@0 95 /**
Chris@0 96 * Stores a list of database queries run beside the main one from views.
Chris@0 97 *
Chris@0 98 * @var array
Chris@0 99 *
Chris@0 100 * @see \Drupal\Core\Database\Log
Chris@0 101 */
Chris@0 102 protected $additionalQueries;
Chris@0 103
Chris@0 104 /**
Chris@0 105 * Contains an array of form keys and their respective classes.
Chris@0 106 *
Chris@0 107 * @var array
Chris@0 108 */
Chris@0 109 public static $forms = [
Chris@0 110 'add-handler' => '\Drupal\views_ui\Form\Ajax\AddItem',
Chris@0 111 'analyze' => '\Drupal\views_ui\Form\Ajax\Analyze',
Chris@0 112 'handler' => '\Drupal\views_ui\Form\Ajax\ConfigHandler',
Chris@0 113 'handler-extra' => '\Drupal\views_ui\Form\Ajax\ConfigHandlerExtra',
Chris@0 114 'handler-group' => '\Drupal\views_ui\Form\Ajax\ConfigHandlerGroup',
Chris@0 115 'display' => '\Drupal\views_ui\Form\Ajax\Display',
Chris@0 116 'edit-details' => '\Drupal\views_ui\Form\Ajax\EditDetails',
Chris@0 117 'rearrange' => '\Drupal\views_ui\Form\Ajax\Rearrange',
Chris@0 118 'rearrange-filter' => '\Drupal\views_ui\Form\Ajax\RearrangeFilter',
Chris@0 119 'reorder-displays' => '\Drupal\views_ui\Form\Ajax\ReorderDisplays',
Chris@0 120 ];
Chris@0 121
Chris@0 122 /**
Chris@0 123 * Whether the config is being created, updated or deleted through the
Chris@0 124 * import process.
Chris@0 125 *
Chris@0 126 * @var bool
Chris@0 127 */
Chris@0 128 private $isSyncing = FALSE;
Chris@0 129
Chris@0 130 /**
Chris@0 131 * Whether the config is being deleted through the uninstall process.
Chris@0 132 *
Chris@0 133 * @var bool
Chris@0 134 */
Chris@0 135 private $isUninstalling = FALSE;
Chris@0 136
Chris@0 137 /**
Chris@0 138 * Constructs a View UI object.
Chris@0 139 *
Chris@0 140 * @param \Drupal\views\ViewEntityInterface $storage
Chris@0 141 * The View storage object to wrap.
Chris@0 142 */
Chris@0 143 public function __construct(ViewEntityInterface $storage) {
Chris@0 144 $this->entityType = 'view';
Chris@0 145 $this->storage = $storage;
Chris@0 146 }
Chris@0 147
Chris@0 148 /**
Chris@0 149 * {@inheritdoc}
Chris@0 150 */
Chris@0 151 public function get($property_name, $langcode = NULL) {
Chris@0 152 if (property_exists($this->storage, $property_name)) {
Chris@0 153 return $this->storage->get($property_name, $langcode);
Chris@0 154 }
Chris@0 155
Chris@0 156 return isset($this->{$property_name}) ? $this->{$property_name} : NULL;
Chris@0 157 }
Chris@0 158
Chris@0 159 /**
Chris@0 160 * {@inheritdoc}
Chris@0 161 */
Chris@0 162 public function setStatus($status) {
Chris@0 163 return $this->storage->setStatus($status);
Chris@0 164 }
Chris@0 165
Chris@0 166 /**
Chris@0 167 * {@inheritdoc}
Chris@0 168 */
Chris@0 169 public function set($property_name, $value, $notify = TRUE) {
Chris@0 170 if (property_exists($this->storage, $property_name)) {
Chris@0 171 $this->storage->set($property_name, $value);
Chris@0 172 }
Chris@0 173 else {
Chris@0 174 $this->{$property_name} = $value;
Chris@0 175 }
Chris@0 176 }
Chris@0 177
Chris@0 178 /**
Chris@0 179 * {@inheritdoc}
Chris@0 180 */
Chris@0 181 public function setSyncing($syncing) {
Chris@0 182 $this->isSyncing = $syncing;
Chris@0 183 }
Chris@0 184
Chris@0 185 /**
Chris@0 186 * {@inheritdoc}
Chris@0 187 */
Chris@0 188 public function setUninstalling($isUninstalling) {
Chris@0 189 $this->isUninstalling = $isUninstalling;
Chris@0 190 }
Chris@0 191
Chris@0 192 /**
Chris@0 193 * {@inheritdoc}
Chris@0 194 */
Chris@0 195 public function isSyncing() {
Chris@0 196 return $this->isSyncing;
Chris@0 197 }
Chris@0 198
Chris@0 199 /**
Chris@0 200 * {@inheritdoc}
Chris@0 201 */
Chris@0 202 public function isUninstalling() {
Chris@0 203 return $this->isUninstalling;
Chris@0 204 }
Chris@0 205
Chris@0 206 /**
Chris@0 207 * Basic submit handler applicable to all 'standard' forms.
Chris@0 208 *
Chris@0 209 * This submit handler determines whether the user wants the submitted changes
Chris@0 210 * to apply to the default display or to the current display, and dispatches
Chris@0 211 * control appropriately.
Chris@0 212 */
Chris@0 213 public function standardSubmit($form, FormStateInterface $form_state) {
Chris@0 214 // Determine whether the values the user entered are intended to apply to
Chris@0 215 // the current display or the default display.
Chris@0 216
Chris@0 217 list($was_defaulted, $is_defaulted, $revert) = $this->getOverrideValues($form, $form_state);
Chris@0 218
Chris@0 219 // Based on the user's choice in the display dropdown, determine which display
Chris@0 220 // these changes apply to.
Chris@0 221 $display_id = $form_state->get('display_id');
Chris@0 222 if ($revert) {
Chris@0 223 // If it's revert just change the override and return.
Chris@0 224 $display = &$this->getExecutable()->displayHandlers->get($display_id);
Chris@0 225 $display->optionsOverride($form, $form_state);
Chris@0 226
Chris@0 227 // Don't execute the normal submit handling but still store the changed view into cache.
Chris@0 228 $this->cacheSet();
Chris@0 229 return;
Chris@0 230 }
Chris@0 231 elseif ($was_defaulted === $is_defaulted) {
Chris@0 232 // We're not changing which display these form values apply to.
Chris@0 233 // Run the regular submit handler for this form.
Chris@0 234 }
Chris@0 235 elseif ($was_defaulted && !$is_defaulted) {
Chris@0 236 // We were using the default display's values, but we're now overriding
Chris@0 237 // the default display and saving values specific to this display.
Chris@0 238 $display = &$this->getExecutable()->displayHandlers->get($display_id);
Chris@0 239 // optionsOverride toggles the override of this section.
Chris@0 240 $display->optionsOverride($form, $form_state);
Chris@0 241 $display->submitOptionsForm($form, $form_state);
Chris@0 242 }
Chris@0 243 elseif (!$was_defaulted && $is_defaulted) {
Chris@0 244 // We used to have an override for this display, but the user now wants
Chris@0 245 // to go back to the default display.
Chris@0 246 // Overwrite the default display with the current form values, and make
Chris@0 247 // the current display use the new default values.
Chris@0 248 $display = &$this->getExecutable()->displayHandlers->get($display_id);
Chris@0 249 // optionsOverride toggles the override of this section.
Chris@0 250 $display->optionsOverride($form, $form_state);
Chris@0 251 $display->submitOptionsForm($form, $form_state);
Chris@0 252 }
Chris@0 253
Chris@0 254 $submit_handler = [$form_state->getFormObject(), 'submitForm'];
Chris@0 255 call_user_func_array($submit_handler, [&$form, $form_state]);
Chris@0 256 }
Chris@0 257
Chris@0 258 /**
Chris@0 259 * Submit handler for cancel button
Chris@0 260 */
Chris@0 261 public function standardCancel($form, FormStateInterface $form_state) {
Chris@0 262 if (!empty($this->changed) && isset($this->form_cache)) {
Chris@0 263 unset($this->form_cache);
Chris@0 264 $this->cacheSet();
Chris@0 265 }
Chris@0 266
Chris@0 267 $form_state->setRedirectUrl($this->urlInfo('edit-form'));
Chris@0 268 }
Chris@0 269
Chris@0 270 /**
Chris@0 271 * Provide a standard set of Apply/Cancel/OK buttons for the forms. Also provide
Chris@0 272 * a hidden op operator because the forms plugin doesn't seem to properly
Chris@0 273 * provide which button was clicked.
Chris@0 274 *
Chris@0 275 * TODO: Is the hidden op operator still here somewhere, or is that part of the
Chris@0 276 * docblock outdated?
Chris@0 277 */
Chris@0 278 public function getStandardButtons(&$form, FormStateInterface $form_state, $form_id, $name = NULL) {
Chris@0 279 $form['actions'] = [
Chris@0 280 '#type' => 'actions',
Chris@0 281 ];
Chris@0 282
Chris@0 283 if (empty($name)) {
Chris@0 284 $name = t('Apply');
Chris@0 285 if (!empty($this->stack) && count($this->stack) > 1) {
Chris@0 286 $name = t('Apply and continue');
Chris@0 287 }
Chris@0 288 $names = [t('Apply'), t('Apply and continue')];
Chris@0 289 }
Chris@0 290
Chris@0 291 // Forms that are purely informational set an ok_button flag, so we know not
Chris@0 292 // to create an "Apply" button for them.
Chris@0 293 if (!$form_state->get('ok_button')) {
Chris@0 294 $form['actions']['submit'] = [
Chris@0 295 '#type' => 'submit',
Chris@0 296 '#value' => $name,
Chris@0 297 '#id' => 'edit-submit-' . Html::getUniqueId($form_id),
Chris@0 298 // The regular submit handler ($form_id . '_submit') does not apply if
Chris@0 299 // we're updating the default display. It does apply if we're updating
Chris@0 300 // the current display. Since we have no way of knowing at this point
Chris@0 301 // which display the user wants to update, views_ui_standard_submit will
Chris@0 302 // take care of running the regular submit handler as appropriate.
Chris@0 303 '#submit' => [[$this, 'standardSubmit']],
Chris@0 304 '#button_type' => 'primary',
Chris@0 305 ];
Chris@0 306 // Form API button click detection requires the button's #value to be the
Chris@0 307 // same between the form build of the initial page request, and the
Chris@0 308 // initial form build of the request processing the form submission.
Chris@0 309 // Ideally, the button's #value shouldn't change until the form rebuild
Chris@0 310 // step. However, \Drupal\views_ui\Form\Ajax\ViewsFormBase::getForm()
Chris@0 311 // implements a different multistep form workflow than the Form API does,
Chris@0 312 // and adjusts $view->stack prior to form processing, so we compensate by
Chris@0 313 // extending button click detection code to support any of the possible
Chris@0 314 // button labels.
Chris@0 315 if (isset($names)) {
Chris@0 316 $form['actions']['submit']['#values'] = $names;
Chris@0 317 $form['actions']['submit']['#process'] = array_merge(['views_ui_form_button_was_clicked'], \Drupal::service('element_info')->getInfoProperty($form['actions']['submit']['#type'], '#process', []));
Chris@0 318 }
Chris@0 319 // If a validation handler exists for the form, assign it to this button.
Chris@0 320 $form['actions']['submit']['#validate'][] = [$form_state->getFormObject(), 'validateForm'];
Chris@0 321 }
Chris@0 322
Chris@0 323 // Create a "Cancel" button. For purely informational forms, label it "OK".
Chris@0 324 $cancel_submit = function_exists($form_id . '_cancel') ? $form_id . '_cancel' : [$this, 'standardCancel'];
Chris@0 325 $form['actions']['cancel'] = [
Chris@0 326 '#type' => 'submit',
Chris@0 327 '#value' => !$form_state->get('ok_button') ? t('Cancel') : t('Ok'),
Chris@0 328 '#submit' => [$cancel_submit],
Chris@0 329 '#validate' => [],
Chris@0 330 '#limit_validation_errors' => [],
Chris@0 331 ];
Chris@0 332
Chris@0 333 // Compatibility, to be removed later: // TODO: When is "later"?
Chris@0 334 // We used to set these items on the form, but now we want them on the $form_state:
Chris@0 335 if (isset($form['#title'])) {
Chris@0 336 $form_state->set('title', $form['#title']);
Chris@0 337 }
Chris@0 338 if (isset($form['#section'])) {
Chris@0 339 $form_state->set('#section', $form['#section']);
Chris@0 340 }
Chris@0 341 // Finally, we never want these cached -- our object cache does that for us.
Chris@0 342 $form['#no_cache'] = TRUE;
Chris@0 343 }
Chris@0 344
Chris@0 345 /**
Chris@0 346 * Return the was_defaulted, is_defaulted and revert state of a form.
Chris@0 347 */
Chris@0 348 public function getOverrideValues($form, FormStateInterface $form_state) {
Chris@0 349 // Make sure the dropdown exists in the first place.
Chris@0 350 if ($form_state->hasValue(['override', 'dropdown'])) {
Chris@0 351 // #default_value is used to determine whether it was the default value or not.
Chris@0 352 // So the available options are: $display, 'default' and 'default_revert', not 'defaults'.
Chris@0 353 $was_defaulted = ($form['override']['dropdown']['#default_value'] === 'defaults');
Chris@0 354 $dropdown = $form_state->getValue(['override', 'dropdown']);
Chris@0 355 $is_defaulted = ($dropdown === 'default');
Chris@0 356 $revert = ($dropdown === 'default_revert');
Chris@0 357
Chris@0 358 if ($was_defaulted !== $is_defaulted && isset($form['#section'])) {
Chris@0 359 // We're changing which display these values apply to.
Chris@0 360 // Update the #section so it knows what to mark changed.
Chris@0 361 $form['#section'] = str_replace('default-', $form_state->get('display_id') . '-', $form['#section']);
Chris@0 362 }
Chris@0 363 }
Chris@0 364 else {
Chris@0 365 // The user didn't get the dropdown for overriding the default display.
Chris@0 366 $was_defaulted = FALSE;
Chris@0 367 $is_defaulted = FALSE;
Chris@0 368 $revert = FALSE;
Chris@0 369 }
Chris@0 370
Chris@0 371 return [$was_defaulted, $is_defaulted, $revert];
Chris@0 372 }
Chris@0 373
Chris@0 374 /**
Chris@0 375 * Add another form to the stack; clicking 'apply' will go to this form
Chris@0 376 * rather than closing the ajax popup.
Chris@0 377 */
Chris@0 378 public function addFormToStack($key, $display_id, $type, $id = NULL, $top = FALSE, $rebuild_keys = FALSE) {
Chris@0 379 // Reset the cache of IDs. Drupal rather aggressively prevents ID
Chris@0 380 // duplication but this causes it to remember IDs that are no longer even
Chris@0 381 // being used.
Chris@0 382 Html::resetSeenIds();
Chris@0 383
Chris@0 384 if (empty($this->stack)) {
Chris@0 385 $this->stack = [];
Chris@0 386 }
Chris@0 387
Chris@0 388 $stack = [implode('-', array_filter([$key, $this->id(), $display_id, $type, $id])), $key, $display_id, $type, $id];
Chris@0 389 // If we're being asked to add this form to the bottom of the stack, no
Chris@0 390 // special logic is required. Our work is equally easy if we were asked to add
Chris@0 391 // to the top of the stack, but there's nothing in it yet.
Chris@0 392 if (!$top || empty($this->stack)) {
Chris@0 393 $this->stack[] = $stack;
Chris@0 394 }
Chris@0 395 // If we're adding to the top of an existing stack, we have to maintain the
Chris@0 396 // existing integer keys, so they can be used for the "2 of 3" progress
Chris@0 397 // indicator (which will now read "2 of 4").
Chris@0 398 else {
Chris@0 399 $keys = array_keys($this->stack);
Chris@0 400 $first = current($keys);
Chris@0 401 $last = end($keys);
Chris@0 402 for ($i = $last; $i >= $first; $i--) {
Chris@0 403 if (!isset($this->stack[$i])) {
Chris@0 404 continue;
Chris@0 405 }
Chris@0 406 // Move form number $i to the next position in the stack.
Chris@0 407 $this->stack[$i + 1] = $this->stack[$i];
Chris@0 408 unset($this->stack[$i]);
Chris@0 409 }
Chris@0 410 // Now that the previously $first slot is free, move the new form into it.
Chris@0 411 $this->stack[$first] = $stack;
Chris@0 412 ksort($this->stack);
Chris@0 413
Chris@0 414 // Start the keys from 0 again, if requested.
Chris@0 415 if ($rebuild_keys) {
Chris@0 416 $this->stack = array_values($this->stack);
Chris@0 417 }
Chris@0 418 }
Chris@0 419 }
Chris@0 420
Chris@0 421 /**
Chris@0 422 * Submit handler for adding new item(s) to a view.
Chris@0 423 */
Chris@0 424 public function submitItemAdd($form, FormStateInterface $form_state) {
Chris@0 425 $type = $form_state->get('type');
Chris@0 426 $types = ViewExecutable::getHandlerTypes();
Chris@0 427 $section = $types[$type]['plural'];
Chris@0 428 $display_id = $form_state->get('display_id');
Chris@0 429
Chris@0 430 // Handle the override select.
Chris@0 431 list($was_defaulted, $is_defaulted) = $this->getOverrideValues($form, $form_state);
Chris@0 432 if ($was_defaulted && !$is_defaulted) {
Chris@0 433 // We were using the default display's values, but we're now overriding
Chris@0 434 // the default display and saving values specific to this display.
Chris@0 435 $display = &$this->getExecutable()->displayHandlers->get($display_id);
Chris@0 436 // setOverride toggles the override of this section.
Chris@0 437 $display->setOverride($section);
Chris@0 438 }
Chris@0 439 elseif (!$was_defaulted && $is_defaulted) {
Chris@0 440 // We used to have an override for this display, but the user now wants
Chris@0 441 // to go back to the default display.
Chris@0 442 // Overwrite the default display with the current form values, and make
Chris@0 443 // the current display use the new default values.
Chris@0 444 $display = &$this->getExecutable()->displayHandlers->get($display_id);
Chris@0 445 // optionsOverride toggles the override of this section.
Chris@0 446 $display->setOverride($section);
Chris@0 447 }
Chris@0 448
Chris@0 449 if (!$form_state->isValueEmpty('name') && is_array($form_state->getValue('name'))) {
Chris@0 450 // Loop through each of the items that were checked and add them to the view.
Chris@0 451 foreach (array_keys(array_filter($form_state->getValue('name'))) as $field) {
Chris@0 452 list($table, $field) = explode('.', $field, 2);
Chris@0 453
Chris@0 454 if ($cut = strpos($field, '$')) {
Chris@0 455 $field = substr($field, 0, $cut);
Chris@0 456 }
Chris@0 457 $id = $this->getExecutable()->addHandler($display_id, $type, $table, $field);
Chris@0 458
Chris@0 459 // check to see if we have group by settings
Chris@0 460 $key = $type;
Chris@0 461 // Footer,header and empty text have a different internal handler type(area).
Chris@0 462 if (isset($types[$type]['type'])) {
Chris@0 463 $key = $types[$type]['type'];
Chris@0 464 }
Chris@0 465 $item = [
Chris@0 466 'table' => $table,
Chris@0 467 'field' => $field,
Chris@0 468 ];
Chris@0 469 $handler = Views::handlerManager($key)->getHandler($item);
Chris@0 470 if ($this->getExecutable()->displayHandlers->get('default')->useGroupBy() && $handler->usesGroupBy()) {
Chris@0 471 $this->addFormToStack('handler-group', $display_id, $type, $id);
Chris@0 472 }
Chris@0 473
Chris@0 474 // check to see if this type has settings, if so add the settings form first
Chris@0 475 if ($handler && $handler->hasExtraOptions()) {
Chris@0 476 $this->addFormToStack('handler-extra', $display_id, $type, $id);
Chris@0 477 }
Chris@0 478 // Then add the form to the stack
Chris@0 479 $this->addFormToStack('handler', $display_id, $type, $id);
Chris@0 480 }
Chris@0 481 }
Chris@0 482
Chris@0 483 if (isset($this->form_cache)) {
Chris@0 484 unset($this->form_cache);
Chris@0 485 }
Chris@0 486
Chris@0 487 // Store in cache
Chris@0 488 $this->cacheSet();
Chris@0 489 }
Chris@0 490
Chris@0 491 /**
Chris@0 492 * Set up query capturing.
Chris@0 493 *
Chris@0 494 * \Drupal\Core\Database\Database stores the queries that it runs, if logging
Chris@0 495 * is enabled.
Chris@0 496 *
Chris@0 497 * @see ViewUI::endQueryCapture()
Chris@0 498 */
Chris@0 499 public function startQueryCapture() {
Chris@0 500 Database::startLog('views');
Chris@0 501 }
Chris@0 502
Chris@0 503 /**
Chris@0 504 * Add the list of queries run during render to buildinfo.
Chris@0 505 *
Chris@0 506 * @see ViewUI::startQueryCapture()
Chris@0 507 */
Chris@0 508 public function endQueryCapture() {
Chris@0 509 $queries = Database::getLog('views');
Chris@0 510
Chris@0 511 $this->additionalQueries = $queries;
Chris@0 512 }
Chris@0 513
Chris@0 514 public function renderPreview($display_id, $args = []) {
Chris@0 515 // Save the current path so it can be restored before returning from this function.
Chris@0 516 $request_stack = \Drupal::requestStack();
Chris@0 517 $current_request = $request_stack->getCurrentRequest();
Chris@0 518 $executable = $this->getExecutable();
Chris@0 519
Chris@0 520 // Determine where the query and performance statistics should be output.
Chris@0 521 $config = \Drupal::config('views.settings');
Chris@0 522 $show_query = $config->get('ui.show.sql_query.enabled');
Chris@0 523 $show_info = $config->get('ui.show.preview_information');
Chris@0 524 $show_location = $config->get('ui.show.sql_query.where');
Chris@0 525
Chris@0 526 $show_stats = $config->get('ui.show.performance_statistics');
Chris@0 527 if ($show_stats) {
Chris@0 528 $show_stats = $config->get('ui.show.sql_query.where');
Chris@0 529 }
Chris@0 530
Chris@0 531 $combined = $show_query && $show_stats;
Chris@0 532
Chris@0 533 $rows = ['query' => [], 'statistics' => []];
Chris@0 534
Chris@0 535 $errors = $executable->validate();
Chris@0 536 $executable->destroy();
Chris@0 537 if (empty($errors)) {
Chris@0 538 $this->ajax = TRUE;
Chris@0 539 $executable->live_preview = TRUE;
Chris@0 540
Chris@0 541 // AJAX happens via HTTP POST but everything expects exposed data to
Chris@0 542 // be in GET. Copy stuff but remove ajax-framework specific keys.
Chris@0 543 // If we're clicking on links in a preview, though, we could actually
Chris@0 544 // have some input in the query parameters, so we merge request() and
Chris@0 545 // query() to ensure we get it all.
Chris@0 546 $exposed_input = array_merge(\Drupal::request()->request->all(), \Drupal::request()->query->all());
Chris@0 547 foreach (['view_name', 'view_display_id', 'view_args', 'view_path', 'view_dom_id', 'pager_element', 'view_base_path', AjaxResponseSubscriber::AJAX_REQUEST_PARAMETER, 'ajax_page_state', 'form_id', 'form_build_id', 'form_token'] as $key) {
Chris@0 548 if (isset($exposed_input[$key])) {
Chris@0 549 unset($exposed_input[$key]);
Chris@0 550 }
Chris@0 551 }
Chris@0 552 $executable->setExposedInput($exposed_input);
Chris@0 553
Chris@0 554 if (!$executable->setDisplay($display_id)) {
Chris@0 555 return [
Chris@0 556 '#markup' => t('Invalid display id @display', ['@display' => $display_id]),
Chris@0 557 ];
Chris@0 558 }
Chris@0 559
Chris@0 560 $executable->setArguments($args);
Chris@0 561
Chris@0 562 // Store the current view URL for later use:
Chris@0 563 if ($executable->hasUrl() && $executable->display_handler->getOption('path')) {
Chris@0 564 $path = $executable->getUrl();
Chris@0 565 }
Chris@0 566
Chris@0 567 // Make view links come back to preview.
Chris@0 568
Chris@0 569 // Also override the current path so we get the pager, and make sure the
Chris@0 570 // Request object gets all of the proper values from $_SERVER.
Chris@0 571 $request = Request::createFromGlobals();
Chris@0 572 $request->attributes->set(RouteObjectInterface::ROUTE_NAME, 'entity.view.preview_form');
Chris@0 573 $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, \Drupal::service('router.route_provider')->getRouteByName('entity.view.preview_form'));
Chris@0 574 $request->attributes->set('view', $this->storage);
Chris@0 575 $request->attributes->set('display_id', $display_id);
Chris@0 576 $raw_parameters = new ParameterBag();
Chris@0 577 $raw_parameters->set('view', $this->id());
Chris@0 578 $raw_parameters->set('display_id', $display_id);
Chris@0 579 $request->attributes->set('_raw_variables', $raw_parameters);
Chris@0 580
Chris@0 581 foreach ($args as $key => $arg) {
Chris@0 582 $request->attributes->set('arg_' . $key, $arg);
Chris@0 583 }
Chris@0 584 $request_stack->push($request);
Chris@0 585
Chris@0 586 // Suppress contextual links of entities within the result set during a
Chris@0 587 // Preview.
Chris@0 588 // @todo We'll want to add contextual links specific to editing the View, so
Chris@0 589 // the suppression may need to be moved deeper into the Preview pipeline.
Chris@0 590 views_ui_contextual_links_suppress_push();
Chris@0 591
Chris@0 592 $show_additional_queries = $config->get('ui.show.additional_queries');
Chris@0 593
Chris@0 594 Timer::start('entity.view.preview_form');
Chris@0 595
Chris@0 596 if ($show_additional_queries) {
Chris@0 597 $this->startQueryCapture();
Chris@0 598 }
Chris@0 599
Chris@0 600 // Execute/get the view preview.
Chris@0 601 $preview = $executable->preview($display_id, $args);
Chris@0 602
Chris@0 603 if ($show_additional_queries) {
Chris@0 604 $this->endQueryCapture();
Chris@0 605 }
Chris@0 606
Chris@0 607 $this->render_time = Timer::stop('entity.view.preview_form')['time'];
Chris@0 608
Chris@0 609 views_ui_contextual_links_suppress_pop();
Chris@0 610
Chris@0 611 // Prepare the query information and statistics to show either above or
Chris@0 612 // below the view preview.
Chris@0 613 // Initialise the empty rows arrays so we can safely merge them later.
Chris@0 614 $rows['query'] = [];
Chris@0 615 $rows['statistics'] = [];
Chris@0 616 if ($show_info || $show_query || $show_stats) {
Chris@0 617 // Get information from the preview for display.
Chris@0 618 if (!empty($executable->build_info['query'])) {
Chris@0 619 if ($show_query) {
Chris@0 620 $query_string = $executable->build_info['query'];
Chris@0 621 // Only the sql default class has a method getArguments.
Chris@0 622 $quoted = [];
Chris@0 623
Chris@0 624 if ($executable->query instanceof Sql) {
Chris@0 625 $quoted = $query_string->getArguments();
Chris@0 626 $connection = Database::getConnection();
Chris@0 627 foreach ($quoted as $key => $val) {
Chris@0 628 if (is_array($val)) {
Chris@0 629 $quoted[$key] = implode(', ', array_map([$connection, 'quote'], $val));
Chris@0 630 }
Chris@0 631 else {
Chris@0 632 $quoted[$key] = $connection->quote($val);
Chris@0 633 }
Chris@0 634 }
Chris@0 635 }
Chris@0 636 $rows['query'][] = [
Chris@0 637 [
Chris@0 638 'data' => [
Chris@0 639 '#type' => 'inline_template',
Chris@0 640 '#template' => "<strong>{% trans 'Query' %}</strong>",
Chris@0 641 ],
Chris@0 642 ],
Chris@0 643 [
Chris@0 644 'data' => [
Chris@0 645 '#type' => 'inline_template',
Chris@0 646 '#template' => '<pre>{{ query }}</pre>',
Chris@0 647 '#context' => ['query' => strtr($query_string, $quoted)],
Chris@0 648 ],
Chris@0 649 ],
Chris@0 650 ];
Chris@0 651 if (!empty($this->additionalQueries)) {
Chris@0 652 $queries[] = [
Chris@0 653 '#prefix' => '<strong>',
Chris@0 654 '#markup' => t('These queries were run during view rendering:'),
Chris@0 655 '#suffix' => '</strong>',
Chris@0 656 ];
Chris@0 657 foreach ($this->additionalQueries as $query) {
Chris@0 658 $query_string = strtr($query['query'], $query['args']);
Chris@0 659 $queries[] = [
Chris@0 660 '#prefix' => "\n",
Chris@0 661 '#markup' => t('[@time ms] @query', ['@time' => round($query['time'] * 100000, 1) / 100000.0, '@query' => $query_string]),
Chris@0 662 ];
Chris@0 663 }
Chris@0 664
Chris@0 665 $rows['query'][] = [
Chris@0 666 [
Chris@0 667 'data' => [
Chris@0 668 '#type' => 'inline_template',
Chris@0 669 '#template' => "<strong>{% trans 'Other queries' %}</strong>",
Chris@0 670 ],
Chris@0 671 ],
Chris@0 672 [
Chris@0 673 'data' => [
Chris@0 674 '#prefix' => '<pre>',
Chris@0 675 'queries' => $queries,
Chris@0 676 '#suffix' => '</pre>',
Chris@0 677 ],
Chris@0 678 ],
Chris@0 679 ];
Chris@0 680 }
Chris@0 681 }
Chris@0 682 if ($show_info) {
Chris@0 683 $rows['query'][] = [
Chris@0 684 [
Chris@0 685 'data' => [
Chris@0 686 '#type' => 'inline_template',
Chris@0 687 '#template' => "<strong>{% trans 'Title' %}</strong>",
Chris@0 688 ],
Chris@0 689 ],
Chris@0 690 [
Chris@0 691 'data' => [
Chris@0 692 '#markup' => $executable->getTitle(),
Chris@0 693 ],
Chris@0 694 ],
Chris@0 695 ];
Chris@0 696 if (isset($path)) {
Chris@0 697 // @todo Views should expect and store a leading /. See:
Chris@0 698 // https://www.drupal.org/node/2423913
Chris@0 699 $path = \Drupal::l($path->toString(), $path);
Chris@0 700 }
Chris@0 701 else {
Chris@0 702 $path = t('This display has no path.');
Chris@0 703 }
Chris@0 704 $rows['query'][] = [
Chris@0 705 [
Chris@0 706 'data' => [
Chris@0 707 '#prefix' => '<strong>',
Chris@0 708 '#markup' => t('Path'),
Chris@0 709 '#suffix' => '</strong>',
Chris@0 710 ],
Chris@0 711 ],
Chris@0 712 [
Chris@0 713 'data' => [
Chris@0 714 '#markup' => $path,
Chris@0 715 ],
Chris@0 716 ]
Chris@0 717 ];
Chris@0 718 }
Chris@0 719 if ($show_stats) {
Chris@0 720 $rows['statistics'][] = [
Chris@0 721 [
Chris@0 722 'data' => [
Chris@0 723 '#type' => 'inline_template',
Chris@0 724 '#template' => "<strong>{% trans 'Query build time' %}</strong>",
Chris@0 725 ],
Chris@0 726 ],
Chris@0 727 t('@time ms', ['@time' => intval($executable->build_time * 100000) / 100]),
Chris@0 728 ];
Chris@0 729
Chris@0 730 $rows['statistics'][] = [
Chris@0 731 [
Chris@0 732 'data' => [
Chris@0 733 '#type' => 'inline_template',
Chris@0 734 '#template' => "<strong>{% trans 'Query execute time' %}</strong>",
Chris@0 735 ],
Chris@0 736 ],
Chris@0 737 t('@time ms', ['@time' => intval($executable->execute_time * 100000) / 100]),
Chris@0 738 ];
Chris@0 739
Chris@0 740 $rows['statistics'][] = [
Chris@0 741 [
Chris@0 742 'data' => [
Chris@0 743 '#type' => 'inline_template',
Chris@0 744 '#template' => "<strong>{% trans 'View render time' %}</strong>",
Chris@0 745 ],
Chris@0 746 ],
Chris@0 747 t('@time ms', ['@time' => intval($this->render_time * 100) / 100]),
Chris@0 748 ];
Chris@0 749 }
Chris@0 750 \Drupal::moduleHandler()->alter('views_preview_info', $rows, $executable);
Chris@0 751 }
Chris@0 752 else {
Chris@0 753 // No query was run. Display that information in place of either the
Chris@0 754 // query or the performance statistics, whichever comes first.
Chris@0 755 if ($combined || ($show_location === 'above')) {
Chris@0 756 $rows['query'][] = [
Chris@0 757 [
Chris@0 758 'data' => [
Chris@0 759 '#prefix' => '<strong>',
Chris@0 760 '#markup' => t('Query'),
Chris@0 761 '#suffix' => '</strong>',
Chris@0 762 ],
Chris@0 763 ],
Chris@0 764 [
Chris@0 765 'data' => [
Chris@0 766 '#markup' => t('No query was run'),
Chris@0 767 ],
Chris@0 768 ],
Chris@0 769 ];
Chris@0 770 }
Chris@0 771 else {
Chris@0 772 $rows['statistics'][] = [
Chris@0 773 [
Chris@0 774 'data' => [
Chris@0 775 '#prefix' => '<strong>',
Chris@0 776 '#markup' => t('Query'),
Chris@0 777 '#suffix' => '</strong>',
Chris@0 778 ],
Chris@0 779 ],
Chris@0 780 [
Chris@0 781 'data' => [
Chris@0 782 '#markup' => t('No query was run'),
Chris@0 783 ],
Chris@0 784 ],
Chris@0 785 ];
Chris@0 786 }
Chris@0 787 }
Chris@0 788 }
Chris@0 789 }
Chris@0 790 else {
Chris@0 791 foreach ($errors as $display_errors) {
Chris@0 792 foreach ($display_errors as $error) {
Chris@0 793 drupal_set_message($error, 'error');
Chris@0 794 }
Chris@0 795 }
Chris@0 796 $preview = ['#markup' => t('Unable to preview due to validation errors.')];
Chris@0 797 }
Chris@0 798
Chris@0 799 // Assemble the preview, the query info, and the query statistics in the
Chris@0 800 // requested order.
Chris@0 801 $table = [
Chris@0 802 '#type' => 'table',
Chris@0 803 '#prefix' => '<div class="views-query-info">',
Chris@0 804 '#suffix' => '</div>',
Chris@0 805 '#rows' => array_merge($rows['query'], $rows['statistics']),
Chris@0 806 ];
Chris@0 807
Chris@0 808 if ($show_location == 'above') {
Chris@0 809 $output = [
Chris@0 810 'table' => $table,
Chris@0 811 'preview' => $preview,
Chris@0 812 ];
Chris@0 813 }
Chris@0 814 else {
Chris@0 815 $output = [
Chris@0 816 'preview' => $preview,
Chris@0 817 'table' => $table,
Chris@0 818 ];
Chris@0 819 }
Chris@0 820
Chris@0 821 // Ensure that we just remove an additional request we pushed earlier.
Chris@0 822 // This could happen if $errors was not empty.
Chris@0 823 if ($request_stack->getCurrentRequest() != $current_request) {
Chris@0 824 $request_stack->pop();
Chris@0 825 }
Chris@0 826 return $output;
Chris@0 827 }
Chris@0 828
Chris@0 829 /**
Chris@0 830 * Get the user's current progress through the form stack.
Chris@0 831 *
Chris@0 832 * @return
Chris@0 833 * FALSE if the user is not currently in a multiple-form stack. Otherwise,
Chris@0 834 * an associative array with the following keys:
Chris@0 835 * - current: The number of the current form on the stack.
Chris@0 836 * - total: The total number of forms originally on the stack.
Chris@0 837 */
Chris@0 838 public function getFormProgress() {
Chris@0 839 $progress = FALSE;
Chris@0 840 if (!empty($this->stack)) {
Chris@0 841 // The forms on the stack have integer keys that don't change as the forms
Chris@0 842 // are completed, so we can see which ones are still left.
Chris@0 843 $keys = array_keys($this->stack);
Chris@0 844 // Add 1 to the array keys for the benefit of humans, who start counting
Chris@0 845 // from 1 and not 0.
Chris@0 846 $current = reset($keys) + 1;
Chris@0 847 $total = end($keys) + 1;
Chris@0 848 if ($total > 1) {
Chris@0 849 $progress = [];
Chris@0 850 $progress['current'] = $current;
Chris@0 851 $progress['total'] = $total;
Chris@0 852 }
Chris@0 853 }
Chris@0 854 return $progress;
Chris@0 855 }
Chris@0 856
Chris@0 857 /**
Chris@0 858 * Sets a cached view object in the shared tempstore.
Chris@0 859 */
Chris@0 860 public function cacheSet() {
Chris@0 861 if ($this->isLocked()) {
Chris@0 862 drupal_set_message(t('Changes cannot be made to a locked view.'), 'error');
Chris@0 863 return;
Chris@0 864 }
Chris@0 865
Chris@0 866 // Let any future object know that this view has changed.
Chris@0 867 $this->changed = TRUE;
Chris@0 868
Chris@0 869 $executable = $this->getExecutable();
Chris@0 870 if (isset($executable->current_display)) {
Chris@0 871 // Add the knowledge of the changed display, too.
Chris@0 872 $this->changed_display[$executable->current_display] = TRUE;
Chris@0 873 $executable->current_display = NULL;
Chris@0 874 }
Chris@0 875
Chris@0 876 // Unset handlers. We don't want to write these into the cache.
Chris@0 877 $executable->display_handler = NULL;
Chris@0 878 $executable->default_display = NULL;
Chris@0 879 $executable->query = NULL;
Chris@0 880 $executable->displayHandlers = NULL;
Chris@0 881 \Drupal::service('tempstore.shared')->get('views')->set($this->id(), $this);
Chris@0 882 }
Chris@0 883
Chris@0 884 /**
Chris@0 885 * Returns whether the current view is locked.
Chris@0 886 *
Chris@0 887 * @return bool
Chris@0 888 * TRUE if the view is locked, FALSE otherwise.
Chris@0 889 */
Chris@0 890 public function isLocked() {
Chris@0 891 return is_object($this->lock) && ($this->lock->owner != \Drupal::currentUser()->id());
Chris@0 892 }
Chris@0 893
Chris@0 894 /**
Chris@0 895 * Passes through all unknown calls onto the storage object.
Chris@0 896 */
Chris@0 897 public function __call($method, $args) {
Chris@0 898 return call_user_func_array([$this->storage, $method], $args);
Chris@0 899 }
Chris@0 900
Chris@0 901 /**
Chris@0 902 * {@inheritdoc}
Chris@0 903 */
Chris@0 904 public function &getDisplay($display_id) {
Chris@0 905 return $this->storage->getDisplay($display_id);
Chris@0 906 }
Chris@0 907
Chris@0 908 /**
Chris@0 909 * {@inheritdoc}
Chris@0 910 */
Chris@0 911 public function id() {
Chris@0 912 return $this->storage->id();
Chris@0 913 }
Chris@0 914
Chris@0 915 /**
Chris@0 916 * {@inheritdoc}
Chris@0 917 */
Chris@0 918 public function uuid() {
Chris@0 919 return $this->storage->uuid();
Chris@0 920 }
Chris@0 921
Chris@0 922 /**
Chris@0 923 * {@inheritdoc}
Chris@0 924 */
Chris@0 925 public function isNew() {
Chris@0 926 return $this->storage->isNew();
Chris@0 927 }
Chris@0 928
Chris@0 929 /**
Chris@0 930 * {@inheritdoc}
Chris@0 931 */
Chris@0 932 public function getEntityTypeId() {
Chris@0 933 return $this->storage->getEntityTypeId();
Chris@0 934 }
Chris@0 935
Chris@0 936 /**
Chris@0 937 * {@inheritdoc}
Chris@0 938 */
Chris@0 939 public function bundle() {
Chris@0 940 return $this->storage->bundle();
Chris@0 941 }
Chris@0 942
Chris@0 943 /**
Chris@0 944 * {@inheritdoc}
Chris@0 945 */
Chris@0 946 public function getEntityType() {
Chris@0 947 return $this->storage->getEntityType();
Chris@0 948 }
Chris@0 949
Chris@0 950 /**
Chris@0 951 * {@inheritdoc}
Chris@0 952 */
Chris@0 953 public function createDuplicate() {
Chris@0 954 return $this->storage->createDuplicate();
Chris@0 955 }
Chris@0 956
Chris@0 957 /**
Chris@0 958 * {@inheritdoc}
Chris@0 959 */
Chris@0 960 public static function load($id) {
Chris@0 961 return View::load($id);
Chris@0 962 }
Chris@0 963
Chris@0 964 /**
Chris@0 965 * {@inheritdoc}
Chris@0 966 */
Chris@0 967 public static function loadMultiple(array $ids = NULL) {
Chris@0 968 return View::loadMultiple($ids);
Chris@0 969 }
Chris@0 970
Chris@0 971 /**
Chris@0 972 * {@inheritdoc}
Chris@0 973 */
Chris@0 974 public static function create(array $values = []) {
Chris@0 975 return View::create($values);
Chris@0 976 }
Chris@0 977
Chris@0 978 /**
Chris@0 979 * {@inheritdoc}
Chris@0 980 */
Chris@0 981 public function delete() {
Chris@0 982 return $this->storage->delete();
Chris@0 983 }
Chris@0 984
Chris@0 985 /**
Chris@0 986 * {@inheritdoc}
Chris@0 987 */
Chris@0 988 public function save() {
Chris@0 989 return $this->storage->save();
Chris@0 990 }
Chris@0 991
Chris@0 992 /**
Chris@0 993 * {@inheritdoc}
Chris@0 994 */
Chris@0 995 public function urlInfo($rel = 'edit-form', array $options = []) {
Chris@0 996 return $this->storage->urlInfo($rel, $options);
Chris@0 997 }
Chris@0 998
Chris@0 999 /**
Chris@0 1000 * {@inheritdoc}
Chris@0 1001 */
Chris@0 1002 public function toUrl($rel = 'edit-form', array $options = []) {
Chris@0 1003 return $this->storage->toUrl($rel, $options);
Chris@0 1004 }
Chris@0 1005
Chris@0 1006 /**
Chris@0 1007 * {@inheritdoc}
Chris@0 1008 */
Chris@0 1009 public function link($text = NULL, $rel = 'edit-form', array $options = []) {
Chris@0 1010 return $this->storage->link($text, $rel, $options);
Chris@0 1011 }
Chris@0 1012
Chris@0 1013 /**
Chris@0 1014 * {@inheritdoc}
Chris@0 1015 */
Chris@0 1016 public function toLink($text = NULL, $rel = 'edit-form', array $options = []) {
Chris@0 1017 return $this->storage->toLink($text, $rel, $options);
Chris@0 1018 }
Chris@0 1019
Chris@0 1020 /**
Chris@0 1021 * {@inheritdoc}
Chris@0 1022 */
Chris@0 1023 public function label() {
Chris@0 1024 return $this->storage->label();
Chris@0 1025 }
Chris@0 1026
Chris@0 1027 /**
Chris@0 1028 * {@inheritdoc}
Chris@0 1029 */
Chris@0 1030 public function enforceIsNew($value = TRUE) {
Chris@0 1031 return $this->storage->enforceIsNew($value);
Chris@0 1032 }
Chris@0 1033
Chris@0 1034 /**
Chris@0 1035 * {@inheritdoc}
Chris@0 1036 */
Chris@0 1037 public function toArray() {
Chris@0 1038 return $this->storage->toArray();
Chris@0 1039 }
Chris@0 1040
Chris@0 1041 /**
Chris@0 1042 * {@inheritdoc}
Chris@0 1043 */
Chris@0 1044 public function language() {
Chris@0 1045 return $this->storage->language();
Chris@0 1046 }
Chris@0 1047
Chris@0 1048 /**
Chris@0 1049 * {@inheritdoc}
Chris@0 1050 */
Chris@0 1051 public function access($operation = 'view', AccountInterface $account = NULL, $return_as_object = FALSE) {
Chris@0 1052 return $this->storage->access($operation, $account, $return_as_object);
Chris@0 1053 }
Chris@0 1054
Chris@0 1055 /**
Chris@0 1056 * {@inheritdoc}
Chris@0 1057 */
Chris@0 1058 public function enable() {
Chris@0 1059 return $this->storage->enable();
Chris@0 1060 }
Chris@0 1061
Chris@0 1062 /**
Chris@0 1063 * {@inheritdoc}
Chris@0 1064 */
Chris@0 1065 public function disable() {
Chris@0 1066 return $this->storage->disable();
Chris@0 1067 }
Chris@0 1068
Chris@0 1069 /**
Chris@0 1070 * {@inheritdoc}
Chris@0 1071 */
Chris@0 1072 public function status() {
Chris@0 1073 return $this->storage->status();
Chris@0 1074 }
Chris@0 1075
Chris@0 1076 /**
Chris@0 1077 * {@inheritdoc}
Chris@0 1078 */
Chris@0 1079 public function getOriginalId() {
Chris@0 1080 return $this->storage->getOriginalId();
Chris@0 1081 }
Chris@0 1082
Chris@0 1083 /**
Chris@0 1084 * {@inheritdoc}
Chris@0 1085 */
Chris@0 1086 public function setOriginalId($id) {
Chris@0 1087 return $this->storage->setOriginalId($id);
Chris@0 1088 }
Chris@0 1089
Chris@0 1090 /**
Chris@0 1091 * {@inheritdoc}
Chris@0 1092 */
Chris@0 1093 public function preSave(EntityStorageInterface $storage) {
Chris@0 1094 $this->storage->presave($storage);
Chris@0 1095 }
Chris@0 1096
Chris@0 1097 /**
Chris@0 1098 * {@inheritdoc}
Chris@0 1099 */
Chris@0 1100 public function postSave(EntityStorageInterface $storage, $update = TRUE) {
Chris@0 1101 $this->storage->postSave($storage, $update);
Chris@0 1102 }
Chris@0 1103
Chris@0 1104 /**
Chris@0 1105 * {@inheritdoc}
Chris@0 1106 */
Chris@0 1107 public static function preCreate(EntityStorageInterface $storage, array &$values) {
Chris@0 1108 }
Chris@0 1109
Chris@0 1110 /**
Chris@0 1111 * {@inheritdoc}
Chris@0 1112 */
Chris@0 1113 public function postCreate(EntityStorageInterface $storage) {
Chris@0 1114 $this->storage->postCreate($storage);
Chris@0 1115 }
Chris@0 1116
Chris@0 1117 /**
Chris@0 1118 * {@inheritdoc}
Chris@0 1119 */
Chris@0 1120 public static function preDelete(EntityStorageInterface $storage, array $entities) {
Chris@0 1121 }
Chris@0 1122
Chris@0 1123 /**
Chris@0 1124 * {@inheritdoc}
Chris@0 1125 */
Chris@0 1126 public static function postDelete(EntityStorageInterface $storage, array $entities) {
Chris@0 1127 }
Chris@0 1128
Chris@0 1129 /**
Chris@0 1130 * {@inheritdoc}
Chris@0 1131 */
Chris@0 1132 public static function postLoad(EntityStorageInterface $storage, array &$entities) {
Chris@0 1133 }
Chris@0 1134
Chris@0 1135 /**
Chris@0 1136 * {@inheritdoc}
Chris@0 1137 */
Chris@0 1138 public function getExecutable() {
Chris@0 1139 return $this->storage->getExecutable();
Chris@0 1140 }
Chris@0 1141
Chris@0 1142 /**
Chris@0 1143 * {@inheritdoc}
Chris@0 1144 */
Chris@0 1145 public function duplicateDisplayAsType($old_display_id, $new_display_type) {
Chris@0 1146 return $this->storage->duplicateDisplayAsType($old_display_id, $new_display_type);
Chris@0 1147 }
Chris@0 1148
Chris@0 1149 /**
Chris@0 1150 * {@inheritdoc}
Chris@0 1151 */
Chris@0 1152 public function mergeDefaultDisplaysOptions() {
Chris@0 1153 $this->storage->mergeDefaultDisplaysOptions();
Chris@0 1154 }
Chris@0 1155
Chris@0 1156 /**
Chris@0 1157 * {@inheritdoc}
Chris@0 1158 */
Chris@0 1159 public function uriRelationships() {
Chris@0 1160 return $this->storage->uriRelationships();
Chris@0 1161 }
Chris@0 1162
Chris@0 1163 /**
Chris@0 1164 * {@inheritdoc}
Chris@0 1165 */
Chris@0 1166 public function referencedEntities() {
Chris@0 1167 return $this->storage->referencedEntities();
Chris@0 1168 }
Chris@0 1169
Chris@0 1170 /**
Chris@0 1171 * {@inheritdoc}
Chris@0 1172 */
Chris@0 1173 public function url($rel = 'edit-form', $options = []) {
Chris@0 1174 return $this->storage->url($rel, $options);
Chris@0 1175 }
Chris@0 1176
Chris@0 1177 /**
Chris@0 1178 * {@inheritdoc}
Chris@0 1179 */
Chris@0 1180 public function hasLinkTemplate($key) {
Chris@0 1181 return $this->storage->hasLinkTemplate($key);
Chris@0 1182 }
Chris@0 1183
Chris@0 1184 /**
Chris@0 1185 * {@inheritdoc}
Chris@0 1186 */
Chris@0 1187 public function calculateDependencies() {
Chris@0 1188 $this->storage->calculateDependencies();
Chris@0 1189 return $this;
Chris@0 1190 }
Chris@0 1191
Chris@0 1192 /**
Chris@0 1193 * {@inheritdoc}
Chris@0 1194 */
Chris@0 1195 public function getConfigDependencyKey() {
Chris@0 1196 return $this->storage->getConfigDependencyKey();
Chris@0 1197 }
Chris@0 1198
Chris@0 1199 /**
Chris@0 1200 * {@inheritdoc}
Chris@0 1201 */
Chris@0 1202 public function getConfigDependencyName() {
Chris@0 1203 return $this->storage->getConfigDependencyName();
Chris@0 1204 }
Chris@0 1205
Chris@0 1206 /**
Chris@0 1207 * {@inheritdoc}
Chris@0 1208 */
Chris@0 1209 public function getConfigTarget() {
Chris@0 1210 return $this->storage->getConfigTarget();
Chris@0 1211 }
Chris@0 1212
Chris@0 1213 /**
Chris@0 1214 * {@inheritdoc}
Chris@0 1215 */
Chris@0 1216 public function onDependencyRemoval(array $dependencies) {
Chris@0 1217 return $this->storage->onDependencyRemoval($dependencies);
Chris@0 1218 }
Chris@0 1219
Chris@0 1220 /**
Chris@0 1221 * {@inheritdoc}
Chris@0 1222 */
Chris@0 1223 public function getDependencies() {
Chris@0 1224 return $this->storage->getDependencies();
Chris@0 1225 }
Chris@0 1226
Chris@0 1227 /**
Chris@0 1228 * {@inheritdoc}
Chris@0 1229 */
Chris@0 1230 public function getCacheContexts() {
Chris@0 1231 return $this->storage->getCacheContexts();
Chris@0 1232 }
Chris@0 1233
Chris@0 1234 /**
Chris@0 1235 * {@inheritdoc}
Chris@0 1236 */
Chris@0 1237 public function getCacheTags() {
Chris@0 1238 return $this->storage->getCacheTags();
Chris@0 1239 }
Chris@0 1240
Chris@0 1241 /**
Chris@0 1242 * {@inheritdoc}
Chris@0 1243 */
Chris@0 1244 public function getCacheMaxAge() {
Chris@0 1245 return $this->storage->getCacheMaxAge();
Chris@0 1246 }
Chris@0 1247
Chris@0 1248 /**
Chris@0 1249 * {@inheritdoc}
Chris@0 1250 */
Chris@0 1251 public function getTypedData() {
Chris@0 1252 $this->storage->getTypedData();
Chris@0 1253 }
Chris@0 1254
Chris@0 1255 /**
Chris@0 1256 * {@inheritdoc}
Chris@0 1257 */
Chris@0 1258 public function addDisplay($plugin_id = 'page', $title = NULL, $id = NULL) {
Chris@0 1259 return $this->storage->addDisplay($plugin_id, $title, $id);
Chris@0 1260 }
Chris@0 1261
Chris@0 1262 /**
Chris@0 1263 * {@inheritdoc}
Chris@0 1264 */
Chris@0 1265 public function isInstallable() {
Chris@0 1266 return $this->storage->isInstallable();
Chris@0 1267 }
Chris@0 1268
Chris@0 1269 /**
Chris@0 1270 * {@inheritdoc}
Chris@0 1271 */
Chris@0 1272 public function setThirdPartySetting($module, $key, $value) {
Chris@0 1273 return $this->storage->setThirdPartySetting($module, $key, $value);
Chris@0 1274 }
Chris@0 1275
Chris@0 1276 /**
Chris@0 1277 * {@inheritdoc}
Chris@0 1278 */
Chris@0 1279 public function getThirdPartySetting($module, $key, $default = NULL) {
Chris@0 1280 return $this->storage->getThirdPartySetting($module, $key, $default);
Chris@0 1281 }
Chris@0 1282
Chris@0 1283 /**
Chris@0 1284 * {@inheritdoc}
Chris@0 1285 */
Chris@0 1286 public function getThirdPartySettings($module) {
Chris@0 1287 return $this->storage->getThirdPartySettings($module);
Chris@0 1288 }
Chris@0 1289
Chris@0 1290 /**
Chris@0 1291 * {@inheritdoc}
Chris@0 1292 */
Chris@0 1293 public function unsetThirdPartySetting($module, $key) {
Chris@0 1294 return $this->storage->unsetThirdPartySetting($module, $key);
Chris@0 1295 }
Chris@0 1296
Chris@0 1297 /**
Chris@0 1298 * {@inheritdoc}
Chris@0 1299 */
Chris@0 1300 public function getThirdPartyProviders() {
Chris@0 1301 return $this->storage->getThirdPartyProviders();
Chris@0 1302 }
Chris@0 1303
Chris@0 1304 /**
Chris@0 1305 * {@inheritdoc}
Chris@0 1306 */
Chris@0 1307 public function trustData() {
Chris@0 1308 return $this->storage->trustData();
Chris@0 1309 }
Chris@0 1310
Chris@0 1311 /**
Chris@0 1312 * {@inheritdoc}
Chris@0 1313 */
Chris@0 1314 public function hasTrustedData() {
Chris@0 1315 return $this->storage->hasTrustedData();
Chris@0 1316 }
Chris@0 1317
Chris@0 1318 /**
Chris@0 1319 * {@inheritdoc}
Chris@0 1320 */
Chris@0 1321 public function addCacheableDependency($other_object) {
Chris@0 1322 $this->storage->addCacheableDependency($other_object);
Chris@0 1323 return $this;
Chris@0 1324 }
Chris@0 1325
Chris@0 1326 /**
Chris@0 1327 * {@inheritdoc}
Chris@0 1328 */
Chris@0 1329 public function addCacheContexts(array $cache_contexts) {
Chris@0 1330 return $this->storage->addCacheContexts($cache_contexts);
Chris@0 1331 }
Chris@0 1332
Chris@0 1333 /**
Chris@0 1334 * {@inheritdoc}
Chris@0 1335 */
Chris@0 1336 public function mergeCacheMaxAge($max_age) {
Chris@0 1337 return $this->storage->mergeCacheMaxAge($max_age);
Chris@0 1338 }
Chris@0 1339
Chris@0 1340 /**
Chris@0 1341 * {@inheritdoc}
Chris@0 1342 */
Chris@0 1343 public function getCacheTagsToInvalidate() {
Chris@0 1344 return $this->storage->getCacheTagsToInvalidate();
Chris@0 1345 }
Chris@0 1346
Chris@0 1347 /**
Chris@0 1348 * {@inheritdoc}
Chris@0 1349 */
Chris@0 1350 public function addCacheTags(array $cache_tags) {
Chris@0 1351 return $this->storage->addCacheTags($cache_tags);
Chris@0 1352 }
Chris@0 1353
Chris@0 1354 }