ViewStorage.php 15.6 KB
Newer Older
1
<?php
2 3 4

/**
 * @file
5
 * Definition of Drupal\views\ViewStorage.
6 7 8 9
 */

namespace Drupal\views;

10
use Drupal\config\ConfigEntityBase;
11

12
/**
13
 * Defines a ViewStorage configuration entity class.
14
 */
15
class ViewStorage extends ConfigEntityBase implements ViewStorageInterface {
16 17 18 19 20 21 22 23 24 25

  /**
   * Provide direct access to the UUID.
   *
   * @todo Change usage of this to the uuid() method.
   *
   * @var string
   */
  public $uuid;

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
  /**
   * The name of the base table this view will use.
   *
   * @var string
   */
  public $base_table = 'node';

  /**
   * The name of the view.
   *
   * @var string
   */
  public $name = '';

  /**
   * The description of the view, which is used only in the interface.
   *
   * @var string
   */
  public $description = '';

  /**
   * The "tags" of a view.
   *
   * The tags are stored as a single string, though it is used as multiple tags
   * for example in the views overview.
   *
   * @var string
   */
  public $tag = '';

  /**
   * The human readable name of the view.
   *
   * @var string
   */
  public $human_name = '';

  /**
   * The core version the view was created for.
   *
   * @var int
   */
  public $core = DRUPAL_CORE_COMPATIBILITY;

  /**
   * The views API version this view was created by.
   *
   * @var string
   */
  public $api_version = VIEWS_API_VERSION;

  /**
   * Stores all display handlers of this view.
   *
   * An array containing Drupal\views\Plugin\views\display\DisplayPluginBase
   * objects.
   *
   * @var array
   */
  public $display;

  /**
   * The name of the base field to use.
   *
   * @var string
   */
  public $base_field = 'nid';

  /**
   * Returns whether the view's status is disabled or not.
   *
   * This value is used for exported view, to provide some default views which
   * aren't enabled.
   *
   * @var bool
   */
  public $disabled = FALSE;

  /**
106 107 108
   * Stores a reference to the executable version of this view.
   *
   * @var Drupal\views\ViewExecutable
109 110 111
   */
  public $executable;

112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
  /**
   * A copy of the original entity.
   *
   * @todo This should be moved to Drupal\Core\Entity\Entity.
   *
   * @var Drupal\Core\Entity\EntityInterface
   */
  public $original;

  /**
   * Stores the executable version of this view.
   *
   * @param Drupal\views\ViewExecutable $executable
   *   The executable version of this view.
   */
  public function setExecutable(ViewExecutable $executable) {
128 129 130
    $this->executable = $executable;
  }

131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
  /**
   * Initializes the display.
   *
   * @todo Inspect calls to this and attempt to clean up.
   *
   * @param bool $reset
   *   If the display should be reset. Defaults to FALSE.
   *
   * @see Drupal\views\ViewExecutable::initDisplay()
   */
  public function initDisplay($reset = FALSE) {
    if (!isset($this->executable)) {
      $this->setExecutable(new ViewExecutable($this));
    }
    $this->executable->initDisplay($reset);
  }

  /**
   * Implements the magic __call() method.
   *
   * @todo Remove this once all calls are changed to use executable directly.
   */
  public function __call($name, $arguments) {
    if (method_exists($this->executable, $name)) {
155 156 157
      return call_user_func_array(array($this->executable, $name), $arguments);
    }
  }
158

159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
  /**
   * Implements the magic __get() method.
   *
   * @todo Remove this once all calls are changed to use executable directly.
   */
  public function &__get($name) {
    if (property_exists($this->executable, $name)) {
      return $this->executable->{$name};
    }
    if (property_exists($this, $name)) {
      return $this->{$name};
    }
  }

  /**
   * Implements the magic __set() method.
   *
   * @todo Remove this once all calls are changed to use executable directly.
   */
  public function __set($name, $value) {
    if (property_exists($this, $name)) {
      $this->{$name} = $value;
    }
    elseif (property_exists($this->executable, $name)) {
      $this->executable->{$name} = $value;
    }
  }

damiankloip's avatar
damiankloip committed
187
  /**
188
   * Overrides Drupal\Core\Entity\EntityInterface::id().
damiankloip's avatar
damiankloip committed
189 190 191 192 193
   */
  public function id() {
    return $this->name;
  }

194 195 196 197 198
  /**
   * Implements Drupal\views\ViewStorageInterface::enable().
   */
  public function enable() {
    $this->disabled = FALSE;
199
    $this->save();
200 201 202 203 204 205 206
  }

  /**
   * Implements Drupal\views\ViewStorageInterface::disable().
   */
  public function disable() {
    $this->disabled = TRUE;
207
    $this->save();
208 209 210 211 212 213 214 215 216
  }

  /**
   * Implements Drupal\views\ViewStorageInterface::isEnabled().
   */
  public function isEnabled() {
    return !$this->disabled;
  }

217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
  /**
   * Return the human readable name for a view.
   *
   * When a certain view doesn't have a human readable name return the machine readable name.
   */
  public function getHumanName() {
    if (!empty($this->human_name)) {
      $human_name = $this->human_name;
    }
    else {
      $human_name = $this->name;
    }
    return $human_name;
  }

232
  /**
233
   * Adds a new display handler to the view, automatically creating an ID.
234
   *
235 236 237 238 239 240 241 242 243 244 245 246
   * @param string $plugin_id
   *   (optional) The plugin type from the Views plugin annotation. Defaults to
   *   'page'.
   * @param string $title
   *   (optional) The title of the display. Defaults to NULL.
   * @param string $id
   *   (optional) The ID to use, e.g., 'default', 'page_1', 'block_2'. Defaults
   *   to NULL.
   *
   * @return string|false
   *   The key to the display in $view->display, or FALSE if no plugin ID was
   *   provided.
247
   */
248
  public function addDisplay($plugin_id = 'page', $title = NULL, $id = NULL) {
249
    if (empty($plugin_id)) {
250 251 252
      return FALSE;
    }

253
    $plugin = views_get_plugin_definition('display', $plugin_id);
254 255 256 257 258
    if (empty($plugin)) {
      $plugin['title'] = t('Broken');
    }

    if (empty($id)) {
259
      $id = $this->generateDisplayId($plugin_id);
260

261 262
      // Generate a unique human-readable name by inspecting the counter at the
      // end of the previous display ID, e.g., 'page_1'.
263 264 265 266 267 268 269 270 271
      if ($id !== 'default') {
        preg_match("/[0-9]+/", $id, $count);
        $count = $count[0];
      }
      else {
        $count = '';
      }

      if (empty($title)) {
272 273 274
        // If there is no title provided, use the plugin title, and if there are
        // multiple displays, append the count.
        $title = $plugin['title'];
275
        if ($count > 1) {
276
          $title .= ' ' . $count;
277 278 279 280
        }
      }
    }

281
    $display_options = array(
282
      'display_plugin' => $plugin_id,
283 284 285 286
      'id' => $id,
      'display_title' => $title,
    );

287
    // Create the new display object
288
    $display = new ViewDisplay($display_options);
289 290 291 292 293 294 295

    // Add the new display object to the view.
    $this->display[$id] = $display;
    return $id;
  }

  /**
296
   * Generates a display ID of a certain plugin type.
297
   *
298 299
   * @param string $plugin_id
   *   Which plugin should be used for the new display ID.
300
   */
301
  protected function generateDisplayId($plugin_id) {
302 303
    // 'default' is singular and is unique, so just go with 'default'
    // for it. For all others, start counting.
304
    if ($plugin_id == 'default') {
305 306
      return 'default';
    }
307 308
    // Initial ID.
    $id = $plugin_id . '_1';
309 310 311 312 313
    $count = 1;

    // Loop through IDs based upon our style plugin name until
    // we find one that is unused.
    while (!empty($this->display[$id])) {
314
      $id = $plugin_id . '_' . ++$count;
315 316 317 318 319 320
    }

    return $id;
  }

  /**
321
   * Generates a unique ID for an handler instance.
322
   *
323 324
   * These handler instances are typically fields, filters, sort criteria, or
   * arguments.
325
   *
326 327 328 329
   * @param string $requested_id
   *   The requested ID for the handler instance.
   * @param array $existing_items
   *   An array of existing handler instancess, keyed by their IDs.
330
   *
331 332 333 334 335
   * @return string
   *   A unique ID. This will be equal to $requested_id if no handler instance
   *   with that ID already exists. Otherwise, it will be appended with an
   *   integer to make it unique, e.g., "{$requested_id}_1",
   *   "{$requested_id}_2", etc.
336
   */
337
  public static function generateItemId($requested_id, $existing_items) {
338 339 340 341 342 343 344 345 346
    $count = 0;
    $id = $requested_id;
    while (!empty($existing_items[$id])) {
      $id = $requested_id . '_' . ++$count;
    }
    return $id;
  }

  /**
347 348 349 350 351 352 353 354 355 356 357 358
   * Creates a new display and a display handler for it.
   *
   * @param string $plugin_id
   *   (optional) The plugin type from the Views plugin annotation. Defaults to
   *   'page'.
   * @param string $title
   *   (optional) The title of the display. Defaults to NULL.
   * @param string $id
   *   (optional) The ID to use, e.g., 'default', 'page_1', 'block_2'. Defaults
   *   to NULL.
   *
   * @return Drupal\views\Plugin\views\display\DisplayPluginBase
359 360
   *   A reference to the new handler object.
   */
361 362
  public function &newDisplay($plugin_id = 'page', $title = NULL, $id = NULL) {
    $id = $this->addDisplay($plugin_id, $title, $id);
363

364
    // Create a handler.
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
    $this->display[$id]->handler = views_get_plugin('display', $this->display[$id]->display_plugin);
    if (empty($this->display[$id]->handler)) {
      // provide a 'default' handler as an emergency. This won't work well but
      // it will keep things from crashing.
      $this->display[$id]->handler = views_get_plugin('display', 'default');
    }

    if (!empty($this->display[$id]->handler)) {
      // Initialize the new display handler with data.
      $this->display[$id]->handler->init($this, $this->display[$id]);
      // If this is NOT the default display handler, let it know which is
      if ($id != 'default') {
        $this->display[$id]->handler->default_display = &$this->display['default']->handler;
      }
    }

    return $this->display[$id]->handler;
  }

384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
  /**
   * Gets a list of displays included in the view.
   *
   * @return array
   *   An array of display types that this view includes.
   */
  function getDisplaysList() {
    $this->initDisplay();

    $displays = array();
    foreach ($this->display as $display) {
      if (!empty($display->handler->definition['admin'])) {
        $displays[$display->handler->definition['admin']] = TRUE;
      }
    }

    ksort($displays);
    return array_keys($displays);
  }

  /**
   * Gets a list of paths assigned to the view.
   *
   * @return array
   *   An array of paths for this view.
   */
  public function getPaths() {
    $all_paths = array();
    if (empty($this->display)) {
      $all_paths[] = t('Edit this view to add a display.');
    }
    else {
      $this->initDisplay();   // Make sure all the handlers are set up
      foreach ($this->display as $display) {
        if (!empty($display->handler) && $display->handler->hasPath()) {
          $path = $display->handler->getOption('path');
          if ($this->isEnabled() && strpos($path, '%') === FALSE) {
            $all_paths[] = l('/' . $path, $path);
          }
          else {
            $all_paths[] = check_plain('/' . $path);
          }
        }
      }
    }

    return array_unique($all_paths);
  }

433
  /**
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
   * Adds an instance of a handler to the view.
   *
   * Items may be fields, filters, sort criteria, or arguments.
   *
   * @param string $display_id
   *   The machine name of the display.
   * @param string $type
   *   The type of handler being added.
   * @param string $table
   *   The name of the table this handler is from.
   * @param string $field
   *   The name of the field this handler is from.
   * @param array $options
   *   (optional) Extra options for this instance. Defaults to an empty array.
   * @param string $id
   *   (optional) A unique ID for this handler instance. Defaults to NULL, in
   *   which case one will be generated.
451
   *
452 453
   * @return string
   *   The unique ID for this handler instance.
454
   */
455
  public function addItem($display_id, $type, $table, $field, $options = array(), $id = NULL) {
456
    $types = ViewExecutable::viewsHandlerTypes();
457
    $this->setDisplay($display_id);
458

459
    $fields = $this->display[$display_id]->handler->getOption($types[$type]['plural']);
460 461

    if (empty($id)) {
462
      $id = $this->generateItemId($field, $fields);
463 464
    }

465 466 467 468 469 470 471
    // If the desired type is not found, use the original value directly.
    $handler_type = !empty($types[$type]['type']) ? $types[$type]['type'] : $type;

    // @todo This variable is never used.
    $handler = views_get_handler($table, $field, $handler_type);

    $fields[$id] = array(
472 473 474 475 476
      'id' => $id,
      'table' => $table,
      'field' => $field,
    ) + $options;

477
    $this->display[$display_id]->handler->setOption($types[$type]['plural'], $fields);
478 479 480 481 482

    return $id;
  }

  /**
483 484 485 486 487 488 489 490 491 492
   * Gets an array of handler instances for the current display.
   *
   * @param string $type
   *   The type of handlers to retrieve.
   * @param string $display_id
   *   (optional) A specific display machine name to use. If NULL, the current
   *   display will be used.
   *
   * @return array
   *   An array of handler instances of a given type for this display.
493
   */
494
  public function getItems($type, $display_id = NULL) {
495
    $this->setDisplay($display_id);
496 497 498 499 500 501

    if (!isset($display_id)) {
      $display_id = $this->current_display;
    }

    // Get info about the types so we can get the right data.
502
    $types = ViewExecutable::viewsHandlerTypes();
503
    return $this->display[$display_id]->handler->getOption($types[$type]['plural']);
504 505 506
  }

  /**
507 508 509 510 511 512 513 514 515 516 517 518
   * Gets the configuration of a handler instance on a given display.
   *
   * @param string $display_id
   *   The machine name of the display.
   * @param string $type
   *   The type of handler to retrieve.
   * @param string $id
   *   The ID of the handler to retrieve.
   *
   * @return array|null
   *   Either the handler instance's configuration, or NULL if the handler is
   *   not used on the display.
519
   */
520
  public function getItem($display_id, $type, $id) {
521
    // Get info about the types so we can get the right data.
522
    $types = ViewExecutable::viewsHandlerTypes();
523
    // Initialize the display
524
    $this->setDisplay($display_id);
525 526

    // Get the existing configuration
527
    $fields = $this->display[$display_id]->handler->getOption($types[$type]['plural']);
528 529 530 531 532

    return isset($fields[$id]) ? $fields[$id] : NULL;
  }

  /**
533 534 535 536 537 538 539 540 541 542
   * Sets the configuration of a handler instance on a given display.
   *
   * @param string $display_id
   *   The machine name of the display.
   * @param string $type
   *   The type of handler being set.
   * @param string $id
   *   The ID of the handler being set.
   * @param array|null $item
   *   An array of configuration for a handler, or NULL to remove this instance.
543
   *
544
   * @see set_item_option()
545
   */
546
  public function setItem($display_id, $type, $id, $item) {
547
    // Get info about the types so we can get the right data.
548
    $types = ViewExecutable::viewsHandlerTypes();
549
    // Initialize the display.
550
    $this->setDisplay($display_id);
551

552
    // Get the existing configuration.
553
    $fields = $this->display[$display_id]->handler->getOption($types[$type]['plural']);
554 555 556 557 558 559 560 561
    if (isset($item)) {
      $fields[$id] = $item;
    }
    else {
      unset($fields[$id]);
    }

    // Store.
562
    $this->display[$display_id]->handler->setOption($types[$type]['plural'], $fields);
563 564 565
  }

  /**
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
   * Sets an option on a handler instance.
   *
   * Use this only if you have just 1 or 2 options to set; if you have many,
   * consider getting the handler instance, adding the options and using
   * set_item() directly.
   *
   * @param string $display_id
   *   The machine name of the display.
   * @param string $type
   *   The type of handler being set.
   * @param string $id
   *   The ID of the handler being set.
   * @param string $option
   *   The configuration key for the value being set.
   * @param mixed $value
   *   The value being set.
582
   *
583
   * @see set_item()
584
   */
585 586
  public function setItemOption($display_id, $type, $id, $option, $value) {
    $item = $this->getItem($display_id, $type, $id);
587
    $item[$option] = $value;
588
    $this->setItem($display_id, $type, $id, $item);
589
  }
590

591
}