diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php index e3150e3e5fe0305a3df3c1498bbdc9dc4e4034c4..eadd0b06830f7b050716fab71b5efaf155ce53c2 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php +++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php @@ -128,7 +128,7 @@ function get_base_table() { $relationships = $this->view->display_handler->getOption('relationships'); if (!empty($relationships[$this->options['relationship']])) { $options = $relationships[$this->options['relationship']]; - $data = views_fetch_data($options['table']); + $data = drupal_container()->get('views.views_data')->get($options['table']); $this->base_table = $data[$options['field']]['relationship']['base']; } } diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/relationship/EntityReverse.php b/core/modules/field/lib/Drupal/field/Plugin/views/relationship/EntityReverse.php index bc9abf365d08708340afad49597c8f8ff25827ad..223c68353bcffa351880bd67e46d4034b9ab1820 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/views/relationship/EntityReverse.php +++ b/core/modules/field/lib/Drupal/field/Plugin/views/relationship/EntityReverse.php @@ -40,7 +40,7 @@ public function query() { $this->ensureMyTable(); // First, relate our base table to the current base table to the // field, using the base table's id field to the field's column. - $views_data = views_fetch_data($this->table); + $views_data = drupal_container()->get('views.views_data')->get($this->table); $left_field = $views_data['table']['base']['field']; $first = array( diff --git a/core/modules/field/lib/Drupal/field/Tests/Views/ApiDataTest.php b/core/modules/field/lib/Drupal/field/Tests/Views/ApiDataTest.php index 6056996388818c34d25c0401f7adbc97b3acd6d7..00c48d9dd3831cc59115cc0a657c38423a1fb5c0 100644 --- a/core/modules/field/lib/Drupal/field/Tests/Views/ApiDataTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/Views/ApiDataTest.php @@ -71,9 +71,6 @@ function setUp() { ); $this->nodes[] = $this->drupalCreateNode($edit); } - - // Reset views data cache. - $this->clearViewsCaches(); } /** @@ -82,7 +79,7 @@ function setUp() { * We check data structure for both node and node revision tables. */ function testViewsData() { - $data = views_fetch_data(); + $data = drupal_container()->get('views.views_data')->get(); // Check the table and the joins of the first field. // Attached to node only. diff --git a/core/modules/field/lib/Drupal/field/Tests/Views/FieldTestBase.php b/core/modules/field/lib/Drupal/field/Tests/Views/FieldTestBase.php index d63272ae41f760cb70d911e9e9fdb1834cc380c5..c0f500b7c643b9dec3dffcfe603aa26f08454ab2 100644 --- a/core/modules/field/lib/Drupal/field/Tests/Views/FieldTestBase.php +++ b/core/modules/field/lib/Drupal/field/Tests/Views/FieldTestBase.php @@ -74,14 +74,4 @@ function setUpInstances($bundle = 'page') { } } - /** - * Clear all views caches and static caches which are required for the patch. - */ - function clearViewsCaches() { - // Reset views data cache. - drupal_static_reset('_views_fetch_data_cache'); - drupal_static_reset('_views_fetch_data_recursion_protected'); - drupal_static_reset('_views_fetch_data_fully_loaded'); - } - } diff --git a/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php b/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php index caacce247fe511ac76a923d70afe6d9d6ed6ea5c..3f5aea2f43ef39cb5771f1202bea817cedb36bbe 100644 --- a/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php @@ -52,8 +52,6 @@ protected function setUp() { $this->setUpInstances(); - $this->clearViewsCaches(); - // Create some nodes. $this->nodes = array(); for ($i = 0; $i < 3; $i++) { diff --git a/core/modules/views/includes/cache.inc b/core/modules/views/includes/cache.inc deleted file mode 100644 index 135787ffb5173726e9db036d50edec4f3056b50a..0000000000000000000000000000000000000000 --- a/core/modules/views/includes/cache.inc +++ /dev/null @@ -1,158 +0,0 @@ -<?php - -/** - * @file - * Load Views' data so that it knows what is available to build queries from. - */ - -/** - * Fetch Views' data from the cache. - * - * $param string|null $table - * (optional) The name of the table for which to fetch Views' data. If - * NULL, data for all tables will be retrieved - * @param bool $reset - * (optional) Whether to rebuild the cache. Defaults to FALSE. - * - * @return array - * An associative array of views data for the given table. If $table is - * NULL, the array will be keyed by table name, with each key corresponding - * to the data array for that table. - * - * @see hook_views_data() - */ -function _views_fetch_data($table = NULL, $reset = FALSE) { - $cache = &drupal_static(__FUNCTION__ . '_cache'); - $recursion_protection = &drupal_static(__FUNCTION__ . '_recursion_protected'); - $fully_loaded = &drupal_static(__FUNCTION__ . '_fully_loaded'); - if ($reset) { - $cache = NULL; - $fully_loaded = FALSE; - } - if ($table) { - if (!isset($cache[$table])) { - $cid = 'views_data:' . $table; - $data = views_cache_get($cid, TRUE); - if (!empty($data->data)) { - $cache[$table] = $data->data; - } - else { - // No cache entry, rebuild. - $cache = _views_fetch_data_build(); - $fully_loaded = TRUE; - } - } - if (isset($cache[$table])) { - return $cache[$table]; - } - } - else { - if (!$fully_loaded) { - $data = views_cache_get('views_data', TRUE); - if (!empty($data->data)) { - $cache = $data->data; - } - - if (empty($cache)) { - $cache = _views_fetch_data_build(); - } - $fully_loaded = TRUE; - } - return $cache; - } - // Return an empty array if there is no match. - return array(); -} - -/** - * Build, set the views data cache if empty and return the views data. - * - * @return array - * The views_data of all tables. - */ -function _views_fetch_data_build() { - $cache = module_invoke_all('views_data'); - foreach (module_implements('views_data_alter') as $module) { - $function = $module . '_views_data_alter'; - $function($cache); - } - _views_data_process_entity_types($cache); - - // Keep a record with all data. - views_cache_set('views_data', $cache, TRUE); - // Save data in seperate cache entries. - foreach ($cache as $key => $data) { - $cid = 'views_data:' . $key; - views_cache_set($cid, $data, TRUE); - } - return $cache; -} - -/** - * Links tables having an 'entity type' specified to the respective generic entity-type tables. - */ -function _views_data_process_entity_types(&$data) { - foreach ($data as $table_name => $table_info) { - // Add in a join from the entity-table if an entity-type is given. - if (!empty($table_info['table']['entity type'])) { - $entity_table = 'views_entity_' . $table_info['table']['entity type']; - - $data[$entity_table]['table']['join'][$table_name] = array( - 'left_table' => $table_name, - ); - $data[$entity_table]['table']['entity type'] = $table_info['table']['entity type']; - // Copy over the default table group if we have none yet. - if (!empty($table_info['table']['group']) && empty($data[$entity_table]['table']['group'])) { - $data[$entity_table]['table']['group'] = $table_info['table']['group']; - } - } - } -} - -/** - * Set a cached item in the views cache. - * - * This is just a convenience wrapper around cache_set(). - * - * @param $cid - * The cache ID of the data to store. - * @param $data - * The data to store in the cache. Complex data types will be automatically serialized before insertion. - * Strings will be stored as plain text and not serialized. - * @param $use_language - * If TRUE, the data will be cached specific to the currently active language. - */ -function views_cache_set($cid, $data, $use_language = FALSE) { - if (config('views.settings')->get('skip_cache')) { - return; - } - if ($use_language) { - $cid .= ':' . language(LANGUAGE_TYPE_INTERFACE)->langcode; - } - - cache('views_info')->set($cid, $data); -} - -/** - * Return data from the persistent views cache. - * - * This is just a convenience wrapper around cache_get(). - * - * @param int $cid - * The cache ID of the data to retrieve. - * @param bool $use_language - * If TRUE, the data will be requested specific to the currently active language. - * - * @return stdClass|bool - * The cache or FALSE on failure. - */ -function views_cache_get($cid, $use_language = FALSE) { - if (config('views.settings')->get('skip_cache')) { - return FALSE; - } - if ($use_language) { - $cid .= ':' . language(LANGUAGE_TYPE_INTERFACE)->langcode; - } - - return cache('views_info')->get($cid); -} diff --git a/core/modules/views/lib/Drupal/views/Plugin/Derivative/DefaultWizardDeriver.php b/core/modules/views/lib/Drupal/views/Plugin/Derivative/DefaultWizardDeriver.php index f0ac7b45739ffeb98a2bb62660158d3b48af9e40..aae73e4aca93823ca30228afd79605834ec007c9 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/Derivative/DefaultWizardDeriver.php +++ b/core/modules/views/lib/Drupal/views/Plugin/Derivative/DefaultWizardDeriver.php @@ -37,8 +37,9 @@ public function getDerivativeDefinition($derivative_id, array $base_plugin_defin public function getDerivativeDefinitions(array $base_plugin_definition) { $base_tables = array_keys(views_fetch_base_tables()); $this->derivatives = array(); + $views_data = drupal_container()->get('views.views_data'); foreach ($base_tables as $table) { - $views_info = views_fetch_data($table); + $views_info = $views_data->get($table); if (empty($views_info['table']['wizard_id'])) { $this->derivatives[$table] = array( 'id' => 'standard', diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php index 579e71dda4435ad03954a172ab8fc9856c130204..31601fd74c23bc17cf34ec56cbafa6f8a02b9a75 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php @@ -770,7 +770,7 @@ public static function getTimezone() { * @return Drupal\views\Plugin\views\join\JoinPluginBase */ public static function getTableJoin($table, $base_table) { - $data = views_fetch_data($table); + $data = drupal_container()->get('views.views_data')->get($table); if (isset($data['table']['join'][$base_table])) { $join_info = $data['table']['join'][$base_table]; if (!empty($join_info['join_id'])) { @@ -815,10 +815,10 @@ public function getEntityType() { // If the user has configured a relationship on the handler take that into // account. if (!empty($this->options['relationship']) && $this->options['relationship'] != 'none') { - $views_data = views_fetch_data($this->view->relationship->table); + $views_data = drupal_container()->get('views.views_data')->get($this->view->relationship->table); } else { - $views_data = views_fetch_data($this->view->storage->get('base_table')); + $views_data = drupal_container()->get('views.views_data')->get($this->view->storage->get('base_table')); } if (isset($views_data['table']['entity type'])) { diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php index 50a0eb7e63e883782a28968107b96a264bbac331..fa8207d6e9d35d1d6e71ebff3cd448a357b9150c 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php @@ -127,7 +127,6 @@ public function initDisplay(ViewExecutable $view, array &$display, array &$optio unset($options['defaults']); } - views_include('cache'); // Cache for unpackOptions, but not if we are in the ui. static $unpack_options = array(); if (empty($view->editing)) { @@ -799,7 +798,7 @@ public function getPlugin($type) { // Query plugins allow specifying a specific query class per base table. if ($type == 'query') { - $views_data = views_fetch_data($this->view->storage->get('base_table')); + $views_data = drupal_container()->get('views.views_data')->get($this->view->storage->get('base_table')); $name = isset($views_data['table']['base']['query_id']) ? $views_data['table']['base']['query_id'] : 'views_query'; } diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/query/Sql.php b/core/modules/views/lib/Drupal/views/Plugin/views/query/Sql.php index 8d0c5855ab346ccacdf298aa19ac30e2210c488d..12b97956c9cb1e9a725b0b53fde7de5aa1a1f83a 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/query/Sql.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/query/Sql.php @@ -1444,7 +1444,7 @@ function execute(ViewExecutable $view) { $count_query->addMetaData('view', $view); if (empty($this->options['disable_sql_rewrite'])) { - $base_table_data = views_fetch_data($this->view->storage->get('base_table')); + $base_table_data = drupal_container()->get('views.views_data')->get($this->view->storage->get('base_table')); if (isset($base_table_data['table']['base']['access query tag'])) { $access_tag = $base_table_data['table']['base']['access query tag']; $query->addTag($access_tag); @@ -1542,7 +1542,8 @@ function execute(ViewExecutable $view) { function get_entity_tables() { // Start with the base table. $entity_tables = array(); - $base_table_data = views_fetch_data($this->view->storage->get('base_table')); + $views_data = drupal_container()->get('views.views_data'); + $base_table_data = $views_data->get($this->view->storage->get('base_table')); if (isset($base_table_data['table']['entity type'])) { $entity_tables[$this->view->storage->get('base_table')] = array( 'base' => $this->view->storage->get('base_table'), @@ -1553,7 +1554,7 @@ function get_entity_tables() { } // Include all relationships. foreach ($this->view->relationship as $relationship_id => $relationship) { - $table_data = views_fetch_data($relationship->definition['base']); + $table_data = $views_data->get($relationship->definition['base']); if (isset($table_data['table']['entity type'])) { $entity_tables[$relationship->alias] = array( 'base' => $relationship->definition['base'], diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php b/core/modules/views/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php index f3a1f4d3616d158a2c64f3e9926f2c9e2ea44d59..0b085c6eed3cf241ba47c94fe6c374062fb5befd 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php @@ -93,7 +93,7 @@ public function buildOptionsForm(&$form, &$form_state) { foreach ($sorts as $sort_id => $sort) { $sort_options[$sort_id] = "$sort[group]: $sort[title]"; } - $base_table_data = views_fetch_data($this->definition['base']); + $base_table_data = drupal_container()->get('views.views_data')->get($this->definition['base']); $form['subquery_sort'] = array( '#type' => 'select', @@ -219,7 +219,7 @@ function left_query($options) { $temp_view->args[] = '**CORRELATED**'; // Add the base table ID field. - $views_data = views_fetch_data($this->definition['base']); + $views_data = drupal_container()->get('views.views_data')->get($this->definition['base']); $base_field = $views_data['table']['base']['field']; $temp_view->addItem('default', 'field', $this->definition['base'], $this->definition['field']); @@ -341,7 +341,7 @@ function condition_namespace($string) { */ public function query() { // Figure out what base table this relationship brings to the party. - $table_data = views_fetch_data($this->definition['base']); + $table_data = drupal_container()->get('views.views_data')->get($this->definition['base']); $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field']; $this->ensureMyTable(); diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/relationship/RelationshipPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/relationship/RelationshipPluginBase.php index 47b16d4933820b461335f0a17b81b0cc9e1f030b..e2e814c090653b7ff6505a88847ca2535b60762c 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/relationship/RelationshipPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/relationship/RelationshipPluginBase.php @@ -119,7 +119,7 @@ public function buildOptionsForm(&$form, &$form_state) { */ public function query() { // Figure out what base table this relationship brings to the party. - $table_data = views_fetch_data($this->definition['base']); + $table_data = drupal_container()->get('views.views_data')->get($this->definition['base']); $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field']; $this->ensureMyTable(); diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/row/RowPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/row/RowPluginBase.php index 23ab931a4f5a727a5f98b90caf473187dc1706c7..25f546e06103b69b51b2e1aa668ce185e2c34dbd 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/row/RowPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/row/RowPluginBase.php @@ -73,7 +73,7 @@ public function buildOptionsForm(&$form, &$form_state) { $relationship_handler = views_get_handler($relationship['table'], $relationship['field'], 'relationship'); // If this relationship is valid for this type, add it to the list. - $data = views_fetch_data($relationship['table']); + $data = drupal_container()->get('views.views_data')->get($relationship['table']); $base = $data[$relationship['field']]['relationship']['base']; if ($base == $this->base_table) { $relationship_handler->init($executable, $relationship); diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php index 37c00096dfcfb0df37c1130ecc8a16821ecdfb50..c977e84d9e8fb962ed8cd7bf038c65a66f762ebc 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php @@ -755,7 +755,7 @@ protected function default_display_options() { // Add a least one field so the view validates and the user has a preview. // The base field can provide a default in its base settings; otherwise, // choose the first field with a field handler. - $data = views_fetch_data($this->base_table); + $data = drupal_container()->get('views.views_data')->get($this->base_table); if (isset($data['table']['base']['defaults']['field'])) { $field = $data['table']['base']['defaults']['field']; } @@ -836,7 +836,7 @@ protected function default_display_filters_user(array $form, array &$form_state) } } } - $table_data = views_fetch_data($table); + $table_data = drupal_container()->get('views.views_data')->get($table); // If the 'in' operator is being used, map the values to an array. $handler = $table_data[$bundle_key]['filter']['id']; $handler_definition = drupal_container()->get('plugin.manager.views.filter')->getDefinition($handler); @@ -922,7 +922,7 @@ protected function default_display_sorts_user($form, $form_state) { // created from node, but the wizard type is another base table, make // sure it is not added. This usually don't happen if you have js // enabled. - $data = views_fetch_data($table); + $data = drupal_container()->get('views.views_data')->get($table); if (isset($data[$column]['sort'])) { $sorts[$column] = array( 'id' => $column, diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/HandlerAllTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/HandlerAllTest.php index 85861cd28e2d5e2d544414079bf589fabe02e954..7be896aadc218d8fed8d86c2aa0104c0cc0897c0 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Handler/HandlerAllTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Handler/HandlerAllTest.php @@ -53,7 +53,7 @@ public static function getInfo() { */ public function testHandlers() { $object_types = array_keys(ViewExecutable::viewsHandlerTypes()); - foreach (views_fetch_data() as $base_table => $info) { + foreach (drupal_container()->get('views.views_data')->get() as $base_table => $info) { if (!isset($info['table']['base'])) { continue; } diff --git a/core/modules/views/lib/Drupal/views/Tests/ModuleTest.php b/core/modules/views/lib/Drupal/views/Tests/ModuleTest.php index 9034e7507c32963af34c9bb49fdb4969ecf94f49..5ecedec301331a430a2e7ca767b4453d15d9e1f9 100644 --- a/core/modules/views/lib/Drupal/views/Tests/ModuleTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/ModuleTest.php @@ -219,7 +219,7 @@ protected function formatViewOptions(array $views = array()) { * Ensure that a certain handler is a instance of a certain table/field. */ function assertInstanceHandler($handler, $table, $field, $id) { - $table_data = views_fetch_data($table); + $table_data = drupal_container()->get('views.views_data')->get($table); $field_data = $table_data[$field][$id]; $this->assertEqual($field_data['id'], $handler->getPluginId()); diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewsDataTest.php b/core/modules/views/lib/Drupal/views/Tests/ViewsDataTest.php index d86bd81d0eb1c8db8ad85aebd88286abc459be44..031a9496f1a18e049019646a461d4e166954a674 100644 --- a/core/modules/views/lib/Drupal/views/Tests/ViewsDataTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/ViewsDataTest.php @@ -31,16 +31,12 @@ public function testViewsFetchData() { $table_name = 'views_test_data'; $expected_data = $this->viewsData(); - $data = views_fetch_data($table_name); + $data = drupal_container()->get('views.views_data')->get($table_name); $this->assertEqual($data, $expected_data[$table_name], 'Make sure fetching views data by table works as expected.'); - $data = views_fetch_data(); + $data = drupal_container()->get('views.views_data')->get(); $this->assertTrue(isset($data[$table_name]), 'Make sure the views_test_data info appears in the total views data.'); $this->assertEqual($data[$table_name], $expected_data[$table_name], 'Make sure the views_test_data has the expected values.'); - - $data = views_fetch_data(NULL, TRUE); - $this->assertTrue(isset($data[$table_name]), 'Make sure the views_fetch_data appears in the total views data with reset = TRUE.'); - $this->assertEqual($data[$table_name], $expected_data[$table_name], 'Make sure the views_test_data has the expected values.'); } /** diff --git a/core/modules/views/lib/Drupal/views/ViewExecutable.php b/core/modules/views/lib/Drupal/views/ViewExecutable.php index d5aef7d8bf406a479c821e59dc727d0bda4e686c..25a47ac1d6879408734a69d942765d7aeaeced15 100644 --- a/core/modules/views/lib/Drupal/views/ViewExecutable.php +++ b/core/modules/views/lib/Drupal/views/ViewExecutable.php @@ -946,7 +946,7 @@ public function initQuery() { } // Create and initialize the query object. - $views_data = views_fetch_data($this->storage->get('base_table')); + $views_data = drupal_container()->get('views.views_data')->get($this->storage->get('base_table')); $this->storage->set('base_field', !empty($views_data['table']['base']['field']) ? $views_data['table']['base']['field'] : ''); if (!empty($views_data['table']['base']['database'])) { $this->base_database = $views_data['table']['base']['database']; diff --git a/core/modules/views/lib/Drupal/views/ViewsBundle.php b/core/modules/views/lib/Drupal/views/ViewsBundle.php index 5b32a706e238323021735c3768f46c0871e8bec6..544b8c3e88055ecfccd829cbec008cfd4f64d1d7 100644 --- a/core/modules/views/lib/Drupal/views/ViewsBundle.php +++ b/core/modules/views/lib/Drupal/views/ViewsBundle.php @@ -9,6 +9,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; +use Symfony\Component\DependencyInjection\Reference; use Drupal\views\ViewExecutable; /** @@ -24,6 +25,16 @@ public function build(ContainerBuilder $container) { $container->register("plugin.manager.views.$type", 'Drupal\views\Plugin\ViewsPluginManager') ->addArgument($type); } + + $container + ->register('cache.views_info', 'Drupal\Core\Cache\CacheBackendInterface') + ->setFactoryClass('Drupal\Core\Cache\CacheFactory') + ->setFactoryMethod('get') + ->addArgument('views_info'); + + $container->register('views.views_data', 'Drupal\views\ViewsDataCache') + ->addArgument(new Reference('cache.views_info')) + ->addArgument(new Reference('config.factory')); } } diff --git a/core/modules/views/lib/Drupal/views/ViewsDataCache.php b/core/modules/views/lib/Drupal/views/ViewsDataCache.php new file mode 100644 index 0000000000000000000000000000000000000000..4df7ff5a55c309ac416fc89eb32b5783ff2929c3 --- /dev/null +++ b/core/modules/views/lib/Drupal/views/ViewsDataCache.php @@ -0,0 +1,219 @@ +<?php + +/** + * @file + * Contains \Drupal\views\ViewsDataCache. + */ + +namespace Drupal\views; + +use Drupal\Core\Config\ConfigFactory; +use Drupal\Core\Cache\CacheBackendInterface; + +/** + * Class to manage and lazy load cached views data. + */ +class ViewsDataCache { + + /** + * The base cache ID to use. + * + * @var string + */ + protected $baseCid = 'views_data'; + + /** + * The cache backend to use. + * + * @var \Drupal\Core\Cache\CacheBackendInterface + */ + protected $cacheBackend; + + /** + * Storage for the data itself. + * + * @var array + */ + protected $storage = array(); + + /** + * The configuration factory object. + * + * @var \Drupal\Core\Config\ConfigFactory + */ + protected $config; + + /** + * The current language code. + * + * @var string + */ + protected $langcode; + + /** + * Whether the data has been fully loaded in this request. + * + * @var bool + */ + protected $fullyLoaded = FALSE; + + /** + * Whether or not to skip data caching and rebuild data each time. + * + * @var bool + */ + protected $skipCache; + + /** + * Whether the cache should be rebuilt. This is set when getData() is called. + * + * @var bool + */ + protected $rebuildCache; + + public function __construct(CacheBackendInterface $cache_backend, ConfigFactory $config) { + $this->config = $config; + $this->cacheBackend = $cache_backend; + + $this->langcode = language(LANGUAGE_TYPE_INTERFACE)->langcode; + $this->skipCache = $this->config->get('views.settings')->get('skip_cache'); + } + + /** + * Gets cached data for a particular key, or rebuilds if necessary. + * + * @param string|null $key + * The key of the cache entry to retrieve. Defaults to NULL. + * + * @return array $data + * The cached data. + */ + public function get($key = NULL) { + if ($key) { + if (!isset($this->storage[$key])) { + $cid = $this->baseCid . ':' . $key; + $data = $this->cacheGet($cid); + if (!empty($data->data)) { + $this->storage[$key] = $data->data; + } + else { + // No cache entry, rebuild. + $this->storage = $this->getData(); + $this->fullyLoaded = TRUE; + } + } + if (isset($this->storage[$key])) { + return $this->storage[$key]; + } + } + else { + if (!$this->fullyLoaded) { + $data = $this->cacheGet($this->baseCid); + if (!empty($data->data)) { + $this->storage = $data->data; + } + else { + $this->storage = $this->getData(); + } + $this->fullyLoaded = TRUE; + } + } + + return $this->storage; + } + + /** + * Sets the data in the cache backend for a cache key. + * + * @param string $key + * The cache key to set. + * @param mixed $value + * The value to set for this key. + */ + public function set($key, $value) { + if ($this->skipCache) { + return FALSE; + } + + $key .= ':' . $this->langcode; + + $this->cacheBackend->set($key, $value); + } + + /** + * Gets data from the cache backend. + * + * @param string $cid + * The cache ID to return. + * + * @return mixed + * The cached data, if any. This will immediately return FALSE if the + * $skipCache property is TRUE. + */ + protected function cacheGet($cid) { + if ($this->skipCache) { + return FALSE; + } + + $cid .= ':' . $this->langcode; + + return $this->cacheBackend->get($cid); + } + + /** + * Gets all data invoked by hook_views_data(). + * + * @return array + * An array of all data. + */ + protected function getData() { + $data = module_invoke_all('views_data'); + drupal_alter('views_data', $data); + + $this->processEntityTypes($data); + + $this->rebuildCache = TRUE; + + return $data; + } + + /** + * Links tables with 'entity type' to respective generic entity-type tables. + * + * @param array $data + * The array of data to alter entity data for, passed by reference. + */ + protected function processEntityTypes(array &$data) { + foreach ($data as $table_name => $table_info) { + // Add in a join from the entity-table if an entity-type is given. + if (!empty($table_info['table']['entity type'])) { + $entity_table = 'views_entity_' . $table_info['table']['entity type']; + + $data[$entity_table]['table']['join'][$table_name] = array( + 'left_table' => $table_name, + ); + $data[$entity_table]['table']['entity type'] = $table_info['table']['entity type']; + // Copy over the default table group if we have none yet. + if (!empty($table_info['table']['group']) && empty($data[$entity_table]['table']['group'])) { + $data[$entity_table]['table']['group'] = $table_info['table']['group']; + } + } + } + } + + /** + * Destructs the ViewDataCache object. + */ + public function __destruct() { + if ($this->rebuildCache && !empty($this->storage)) { + // Keep a record with all data. + $this->set($this->baseCid, $this->storage); + // Save data in seperate cache entries. + foreach ($this->storage as $table => $data) { + $cid = $this->baseCid . ':' . $table; + $this->set($cid, $data); + } + } + } + +} diff --git a/core/modules/views/views.api.php b/core/modules/views/views.api.php index 5906e76bdea73d033586d5f07884231684e7b2f9..6e9dae8cb15c0acc7878d8334fbd7dc372c65cb9 100644 --- a/core/modules/views/views.api.php +++ b/core/modules/views/views.api.php @@ -101,7 +101,7 @@ * Describe data tables (or the equivalent) to Views. * * The data described with this hook is fetched and retrieved by - * views_fetch_data(). + * drupal_container()->get('views.views_data')->get(). * * @return array * An associative array describing the data structure. Primary key is the diff --git a/core/modules/views/views.module b/core/modules/views/views.module index 514a78a6c48a2e33890edecaaf6f8f2932620654..1783f164a8f6b93ae8f0761784c06fb2e5e8383d 100644 --- a/core/modules/views/views.module +++ b/core/modules/views/views.module @@ -614,7 +614,6 @@ function views_contextual_links_view_alter(&$element, $items) { */ function views_block_info() { // Try to avoid instantiating all the views just to get the blocks info. - views_include('cache'); $cache = views_cache_get('views_block_items', TRUE); if ($cache && is_array($cache->data)) { return $cache->data; @@ -1154,8 +1153,8 @@ function views_library_info() { function views_get_handler($table, $field, $type, $override = NULL) { // Get the plugin manager for this type. $manager = drupal_container()->get("plugin.manager.views.$type"); + $data = drupal_container()->get('views.views_data')->get($table); - $data = views_fetch_data($table); if (isset($data[$field][$type])) { $definition = $data[$field][$type]; foreach (array('group', 'title', 'title short', 'help', 'real field', 'real table') as $key) { @@ -1193,27 +1192,6 @@ function views_get_handler($table, $field, $type, $override = NULL) { return $manager->createInstance('broken'); } -/** - * Fetch Views' data from the cache - * - * $param string|null $table - * (optional) The name of the table for which to fetch Views' data. If - * NULL, data for all tables will be retrieved - * @param bool $reset - * (optional) Whether to rebuild the cache. Defaults to FALSE. - * - * @return array - * An associative array of views data for the given table. If $table is - * NULL, the array will be keyed by table name, with each key corresponding - * to the data array for that table. - * - * @see hook_views_data() - */ -function views_fetch_data($table = NULL, $reset = FALSE) { - views_include('cache'); - return _views_fetch_data($table, $reset); -} - /** * Fetch a list of all base tables available * @@ -1224,7 +1202,7 @@ function views_fetch_base_tables() { static $base_tables = array(); if (empty($base_tables)) { $tables = array(); - $data = views_fetch_data(); + $data = drupal_container()->get('views.views_data')->get(); foreach ($data as $table => $info) { if (!empty($info['table']['base'])) { $tables[$table] = array( @@ -2208,3 +2186,51 @@ function views_config_import_delete($name, $new_config, $old_config) { entity_delete($view); return TRUE; } + +/** + * Set a cached item in the views cache. + * + * This is just a convenience wrapper around cache_set(). + * + * @param $cid + * The cache ID of the data to store. + * @param $data + * The data to store in the cache. Complex data types will be automatically serialized before insertion. + * Strings will be stored as plain text and not serialized. + * @param $use_language + * If TRUE, the data will be cached specific to the currently active language. + */ +function views_cache_set($cid, $data, $use_language = FALSE) { + if (config('views.settings')->get('skip_cache')) { + return; + } + if ($use_language) { + $cid .= ':' . language(LANGUAGE_TYPE_INTERFACE)->langcode; + } + + cache('views_info')->set($cid, $data); +} + +/** + * Return data from the persistent views cache. + * + * This is just a convenience wrapper around cache_get(). + * + * @param int $cid + * The cache ID of the data to retrieve. + * @param bool $use_language + * If TRUE, the data will be requested specific to the currently active language. + * + * @return stdClass|bool + * The cache or FALSE on failure. + */ +function views_cache_get($cid, $use_language = FALSE) { + if (config('views.settings')->get('skip_cache')) { + return FALSE; + } + if ($use_language) { + $cid .= ':' . language(LANGUAGE_TYPE_INTERFACE)->langcode; + } + + return cache('views_info')->get($cid); +} diff --git a/core/modules/views/views_ui/admin.inc b/core/modules/views/views_ui/admin.inc index 65d2e8a585d686d6b7493364e63ef35cf0bd5e42..80a0e1f7230852ec8243915229a95a5bc19b9be9 100644 --- a/core/modules/views/views_ui/admin.inc +++ b/core/modules/views/views_ui/admin.inc @@ -1441,7 +1441,7 @@ function views_ui_config_item_form($form, &$form_state) { } // If this relationship is valid for this type, add it to the list. - $data = views_fetch_data($relationship['table']); + $data = drupal_container()->get('views.views_data')->get($relationship['table']); $base = $data[$relationship['field']]['relationship']['base']; $base_fields = views_fetch_fields($base, $form_state['type'], $executable->display_handler->useGroupBy()); if (isset($base_fields[$item['table'] . '.' . $item['field']])) { @@ -2156,7 +2156,7 @@ function _views_sort_types($a, $b) { function views_fetch_fields($base, $type, $grouping = FALSE, $sub_type = NULL) { static $fields = array(); if (empty($fields)) { - $data = views_fetch_data(); + $data = drupal_container()->get('views.views_data')->get(); $start = microtime(TRUE); // This constructs this ginormous multi dimensional array to // collect the important data about fields. In the end, @@ -2288,6 +2288,7 @@ function views_ui_form_button_was_clicked($element, &$form_state) { */ function views_ui_field_list() { $views = views_get_all_views(); + $data = drupal_container()->get('views.views_data'); // Fetch all fieldapi fields which are used in views // Therefore search in all views, displays and handler-types. @@ -2300,12 +2301,12 @@ function views_ui_field_list() { if ($executable->setDisplay($display_id)) { foreach ($handler_types as $type => $info) { foreach ($executable->getItems($type, $display_id) as $item) { - $data = views_fetch_data($item['table']); - if (isset($data[$item['field']]) && isset($data[$item['field']][$type]) - && $data = $data[$item['field']][$type]) { + $table_data = $data->get($item['table']); + if (isset($table_data[$item['field']]) && isset($table_data[$item['field']][$type]) + && $field_data = $table_data[$item['field']][$type]) { // The final check that we have a fieldapi field now. - if (isset($data['field_name'])) { - $fields[$data['field_name']][$view->get('name')] = $view->get('name'); + if (isset($field_data['field_name'])) { + $fields[$field_data['field_name']][$view->get('name')] = $view->get('name'); } } }