Newer
Older
Damian Lee
committed
<?php
/**
* @file
* Definition of Drupal\views\Entity\View.
namespace Drupal\views\Entity;
Dries Buytaert
committed
use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\Core\Entity\EntityStorageControllerInterface;
Dries Buytaert
committed
use Drupal\views\Views;
use Drupal\views_ui\ViewUI;
Angie Byron
committed
use Drupal\views\ViewStorageInterface;
use Drupal\views\ViewExecutable;
Angie Byron
committed
* Defines a View configuration entity class.
*
Alex Pott
committed
* @ConfigEntityType(
Angie Byron
committed
* id = "view",
* label = @Translation("View"),
* controllers = {
* "access" = "Drupal\views\ViewAccessController"
* },
* admin_permission = "administer views",
Angie Byron
committed
* entity_keys = {
Angie Byron
committed
* "id" = "id",
Angie Byron
committed
* "label" = "label",
* "status" = "status"
Angie Byron
committed
* }
* )
Angie Byron
committed
class View extends ConfigEntityBase implements ViewStorageInterface {
Tim Plunkett
committed
Daniel Wehner
committed
/**
* The name of the base table this view will use.
*
* @var string
*/
protected $base_table = 'node';
Daniel Wehner
committed
/**
Angie Byron
committed
* The unique ID of the view.
Daniel Wehner
committed
*
* @var string
*/
Angie Byron
committed
public $id = NULL;
Daniel Wehner
committed
Angie Byron
committed
/**
* The label of the view.
*/
protected $label;
Daniel Wehner
committed
/**
* The description of the view, which is used only in the interface.
*
* @var string
*/
protected $description = '';
Daniel Wehner
committed
/**
* 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
*/
protected $tag = '';
Daniel Wehner
committed
/**
* The core version the view was created for.
*
* @var int
*/
catch
committed
protected $core = \Drupal::CORE_COMPATIBILITY;
Daniel Wehner
committed
/**
* Stores all display handlers of this view.
*
* An array containing Drupal\views\Plugin\views\display\DisplayPluginBase
* objects.
*
* @var array
*/
Angie Byron
committed
protected $display = array();
Daniel Wehner
committed
/**
* The name of the base field to use.
*
* @var string
*/
protected $base_field = 'nid';
Daniel Wehner
committed
Tim Plunkett
committed
/**
* Stores a reference to the executable version of this view.
Tim Plunkett
committed
*
Alex Pott
committed
* @var \Drupal\views\ViewExecutable
Tim Plunkett
committed
*/
protected $executable;
Tim Plunkett
committed
Damian Lee
committed
/**
* The module implementing this view.
*
* @var string
*/
protected $module = 'views';
Damian Lee
committed
Tim Plunkett
committed
/**
Alex Pott
committed
* Gets an executable instance for this view.
*
* @return \Drupal\views\ViewExecutable
* A view executable instance.
Tim Plunkett
committed
*/
Alex Pott
committed
public function getExecutable() {
// Ensure that an executable View is available.
Alex Pott
committed
if (!isset($this->executable)) {
$this->executable = Views::executableFactory()->get($this);
Tim Plunkett
committed
}
Alex Pott
committed
return $this->executable;
Damian Lee
committed
}
/**
* Overrides Drupal\Core\Config\Entity\ConfigEntityBase::createDuplicate().
*/
public function createDuplicate() {
$duplicate = parent::createDuplicate();
unset($duplicate->executable);
return $duplicate;
}
Daniel Wehner
committed
/**
Angie Byron
committed
* Overrides \Drupal\Core\Entity\Entity::label().
Daniel Wehner
committed
*
Angie Byron
committed
* When a certain view doesn't have a label return the ID.
Daniel Wehner
committed
*/
public function label() {
Angie Byron
committed
if (!$label = $this->get('label')) {
$label = $this->id();
Daniel Wehner
committed
}
Angie Byron
committed
return $label;
Daniel Wehner
committed
}
Tim Plunkett
committed
* Adds a new display handler to the view, automatically creating an ID.
Tim Plunkett
committed
* @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.
public function addDisplay($plugin_id = 'page', $title = NULL, $id = NULL) {
if (empty($plugin_id)) {
return FALSE;
}
Dries Buytaert
committed
$plugin = Views::pluginManager('display')->getDefinition($plugin_id);
if (empty($plugin)) {
$plugin['title'] = t('Broken');
}
if (empty($id)) {
$id = $this->generateDisplayId($plugin_id);
Tim Plunkett
committed
// Generate a unique human-readable name by inspecting the counter at the
// end of the previous display ID, e.g., 'page_1'.
if ($id !== 'default') {
preg_match("/[0-9]+/", $id, $count);
$count = $count[0];
}
else {
$count = '';
}
if (empty($title)) {
Tim Plunkett
committed
// If there is no title provided, use the plugin title, and if there are
// multiple displays, append the count.
$title = $plugin['title'];
if ($count > 1) {
Tim Plunkett
committed
$title .= ' ' . $count;
}
}
}
$display_options = array(
'display_plugin' => $plugin_id,
'id' => $id,
'display_title' => $title,
Alex Pott
committed
'position' => count($this->display),
'provider' => $plugin['provider'],
Daniel Wehner
committed
'display_options' => array(),
Daniel Wehner
committed
// Add the display options to the view.
$this->display[$id] = $display_options;
return $id;
}
/**
Tim Plunkett
committed
* Generates a display ID of a certain plugin type.
Tim Plunkett
committed
* @param string $plugin_id
* Which plugin should be used for the new display ID.
protected function generateDisplayId($plugin_id) {
// 'default' is singular and is unique, so just go with 'default'
// for it. For all others, start counting.
Tim Plunkett
committed
if ($plugin_id == 'default') {
return 'default';
}
Tim Plunkett
committed
// Initial ID.
$id = $plugin_id . '_1';
$count = 1;
// Loop through IDs based upon our style plugin name until
// we find one that is unused.
while (!empty($this->display[$id])) {
Tim Plunkett
committed
$id = $plugin_id . '_' . ++$count;
}
return $id;
}
Angie Byron
committed
/**
* {@inheritdoc}
Angie Byron
committed
*/
public function &getDisplay($display_id) {
return $this->display[$display_id];
}
Dries Buytaert
committed
/**
Angie Byron
committed
* {@inheritdoc}
Dries Buytaert
committed
*/
Angie Byron
committed
public function toArray() {
Dries Buytaert
committed
$names = array(
'base_field',
'base_table',
'core',
'description',
'status',
Dries Buytaert
committed
'display',
Angie Byron
committed
'label',
Dries Buytaert
committed
'module',
Angie Byron
committed
'id',
Dries Buytaert
committed
'tag',
'uuid',
'langcode',
'dependencies',
Dries Buytaert
committed
);
$properties = array();
foreach ($names as $name) {
$properties[$name] = $this->get($name);
}
return $properties;
}
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/**
* {@inheritdoc}
*/
public function calculateDependencies() {
parent::calculateDependencies();
// Ensure that the view is dependant on the module that implements the view.
$this->addDependency('module', $this->module);
// Ensure that the view is dependant on the module that provides the schema
// for the base table.
$schema = drupal_get_schema($this->base_table);
if ($this->module != $schema['module']) {
$this->addDependency('module', $schema['module']);
}
$handler_types = array();
foreach (ViewExecutable::viewsHandlerTypes() as $type) {
$handler_types[] = $type['plural'];
}
foreach ($this->get('display') as $display) {
foreach ($handler_types as $handler_type) {
if (!empty($display['display_options'][$handler_type])) {
foreach ($display['display_options'][$handler_type] as $handler) {
if (isset($handler['provider']) && empty($handler['optional'])) {
$this->addDependency('module', $handler['provider']);
}
}
}
}
}
return $this->dependencies;
}
/**
* {@inheritdoc}
*/
public function postSave(EntityStorageControllerInterface $storage_controller, $update = TRUE) {
Angie Byron
committed
parent::postSave($storage_controller, $update);
Dries Buytaert
committed
// Clear cache tags for this view.
// @todo Remove if views implements a view_builder controller.
$id = $this->id();
Cache::deleteTags(array('view' => array($id => $id)));
views_invalidate_cache();
}
/**
* {@inheritdoc}
Alex Pott
committed
*/
public static function postLoad(EntityStorageControllerInterface $storage_controller, array &$entities) {
parent::postLoad($storage_controller, $entities);
foreach ($entities as $entity) {
$entity->mergeDefaultDisplaysOptions();
}
}
/**
* {@inheritdoc}
*/
public static function preCreate(EntityStorageControllerInterface $storage_controller, array &$values) {
Angie Byron
committed
parent::preCreate($storage_controller, $values);
// If there is no information about displays available add at least the
// default display.
$values += array(
'display' => array(
'default' => array(
'display_plugin' => 'default',
'id' => 'default',
'display_title' => 'Master',
'position' => 0,
'display_options' => array(),
),
)
);
}
/**
* {@inheritdoc}
*/
public function postCreate(EntityStorageControllerInterface $storage_controller) {
Angie Byron
committed
parent::postCreate($storage_controller);
$this->mergeDefaultDisplaysOptions();
}
Dries Buytaert
committed
/**
* {@inheritdoc}
*/
public static function postDelete(EntityStorageControllerInterface $storage_controller, array $entities) {
Angie Byron
committed
parent::postDelete($storage_controller, $entities);
Dries Buytaert
committed
$tempstore = \Drupal::service('user.tempstore')->get('views');
Dries Buytaert
committed
$tags = array();
Dries Buytaert
committed
foreach ($entities as $entity) {
Dries Buytaert
committed
$id = $entity->id();
$tempstore->delete($id);
$tags['view'][$id] = $id;
Dries Buytaert
committed
}
Dries Buytaert
committed
// Clear cache tags for these views.
// @todo Remove if views implements a view_builder controller.
Cache::deleteTags($tags);
Dries Buytaert
committed
}
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
/**
* {@inheritdoc}
*/
public function mergeDefaultDisplaysOptions() {
$displays = array();
foreach ($this->get('display') as $key => $options) {
$options += array(
'display_options' => array(),
'display_plugin' => NULL,
'id' => NULL,
'display_title' => '',
'position' => NULL,
);
// Add the defaults for the display.
$displays[$key] = $options;
}
// Sort the displays.
uasort($displays, function ($display1, $display2) {
if ($display1['position'] != $display2['position']) {
return $display1['position'] < $display2['position'] ? -1 : 1;
}
return 0;
});
$this->set('display', $displays);
}