/** * Provide a list of views handler types used in a view, with some information * about them. * * @return array * An array of associative arrays containing: * - title: The title of the handler type. * - ltitle: The lowercase title of the handler type. * - stitle: A singular title of the handler type. * - lstitle: A singular lowercase title of the handler type. * - plural: Plural version of the handler type. * - (optional) type: The actual internal used handler type. This key is * just used for header,footer,empty to link to the internal type: area. */ public static function getHandlerTypes() { return Views::getHandlerTypes(); }
/** * {@inheritdoc} */ public function calculateCacheMetadata() { $cache_metadata = new CacheableMetadata(); // Iterate over ordinary views plugins. foreach (Views::getPluginTypes('plugin') as $plugin_type) { $plugin = $this->getPlugin($plugin_type); if ($plugin instanceof CacheableDependencyInterface) { $cache_metadata = $cache_metadata->merge(CacheableMetadata::createFromObject($plugin)); } } // Iterate over all handlers. Note that at least the argument handler will // need to ask all its subplugins. foreach (array_keys(Views::getHandlerTypes()) as $handler_type) { $handlers = $this->getHandlers($handler_type); foreach ($handlers as $handler) { if ($handler instanceof CacheableDependencyInterface) { $cache_metadata = $cache_metadata->merge(CacheableMetadata::createFromObject($handler)); } } } /** @var \Drupal\views\Plugin\views\cache\CachePluginBase $cache_plugin */ if ($cache_plugin = $this->getPlugin('cache')) { $cache_plugin->alterCacheMetadata($cache_metadata); } return $cache_metadata; }
/** * Applies a callable onto all handlers of all passed in views. * * @param \Drupal\views\Entity\View[] $all_views * All views entities. * @param callable $process * A callable which retrieves a handler config array. */ protected function processHandlers(array $all_views, callable $process) { foreach ($all_views as $view) { foreach (array_keys($view->get('display')) as $display_id) { $display =& $view->getDisplay($display_id); foreach (Views::getHandlerTypes() as $handler_type) { $handler_type = $handler_type['plural']; if (!isset($display['display_options'][$handler_type])) { continue; } foreach ($display['display_options'][$handler_type] as $id => &$handler_config) { $process($handler_config); if ($handler_config === NULL) { unset($display['display_options'][$handler_type][$id]); } } } } } }
/** * {@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 dependent on the module that provides the schema // for the base table. $schema = $this->drupalGetSchema($this->base_table); // @todo Entity base tables are no longer registered in hook_schema(). Once // we automate the views data for entity types add the entity type // type provider as a dependency. See https://drupal.org/node/1740492. if ($schema && $this->module != $schema['module']) { $this->addDependency('module', $schema['module']); } $handler_types = array(); foreach (Views::getHandlerTypes() as $type) { $handler_types[] = $type['plural']; } foreach ($this->get('display') as $display) { // Collect all dependencies of all handlers. foreach ($handler_types as $handler_type) { if (!empty($display['display_options'][$handler_type])) { foreach ($display['display_options'][$handler_type] as $handler) { // Add the provider as dependency. if (isset($handler['provider'])) { $this->addDependency('module', $handler['provider']); } // Add the additional dependencies from the handler configuration. if (!empty($handler['dependencies'])) { $this->addDependencies($handler['dependencies']); } } } } // Collect all dependencies of plugins. foreach (Views::getPluginTypes('plugin') as $plugin_type) { if (!empty($display['display_options'][$plugin_type]['options']['dependencies'])) { $this->addDependencies($display['display_options'][$plugin_type]['options']['dependencies']); } } } return $this->dependencies; }
/** * {@inheritdoc} */ public function calculateCacheMetadata() { $is_cacheable = TRUE; $cache_contexts = []; // Iterate over ordinary views plugins. foreach (Views::getPluginTypes('plugin') as $plugin_type) { $plugin = $this->getPlugin($plugin_type); if ($plugin instanceof CacheablePluginInterface) { $cache_contexts = array_merge($cache_contexts, $plugin->getCacheContexts()); $is_cacheable &= $plugin->isCacheable(); } else { $is_cacheable = FALSE; } } // Iterate over all handlers. Note that at least the argument handler will // need to ask all its subplugins. foreach (array_keys(Views::getHandlerTypes()) as $handler_type) { $handlers = $this->getHandlers($handler_type); foreach ($handlers as $handler) { if ($handler instanceof CacheablePluginInterface) { $cache_contexts = array_merge($cache_contexts, $handler->getCacheContexts()); $is_cacheable &= $handler->isCacheable(); } } } /** @var \Drupal\views\Plugin\views\cache\CachePluginBase $cache_plugin */ if ($cache_plugin = $this->getPlugin('cache')) { $cache_plugin->alterCacheMetadata($is_cacheable, $cache_contexts); } return [(bool) $is_cacheable, $cache_contexts]; }
/** * Update some views fields that were previously duplicated. */ function views_post_update_cleanup_duplicate_views_data() { $config_factory = \Drupal::configFactory(); $ids = []; $message = NULL; $data_tables = []; $base_tables = []; $revision_tables = []; $entities_by_table = []; $duplicate_fields = []; $handler_types = Views::getHandlerTypes(); /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */ $entity_type_manager = \Drupal::service('entity_type.manager'); // This will allow us to create an index of all entity types of the site. foreach ($entity_type_manager->getDefinitions() as $entity_type_id => $entity_type) { // Store the entity keyed by base table. If it has a data table, use that as // well. if ($data_table = $entity_type->getDataTable()) { $entities_by_table[$data_table] = $entity_type; } if ($base_table = $entity_type->getBaseTable()) { $entities_by_table[$base_table] = $entity_type; } // The following code basically contains the same kind of logic as // \Drupal\Core\Entity\Sql\SqlContentEntityStorage::initTableLayout() to // prefetch all tables (base, data, revision, and revision data). $base_tables[$entity_type_id] = $entity_type->getBaseTable() ?: $entity_type->id(); $revisionable = $entity_type->isRevisionable(); $revision_table = ''; if ($revisionable) { $revision_table = $entity_type->getRevisionTable() ?: $entity_type->id() . '_revision'; } $revision_tables[$entity_type_id] = $revision_table; $translatable = $entity_type->isTranslatable(); $data_table = ''; // For example the data table just exists, when the entity type is // translatable. if ($translatable) { $data_table = $entity_type->getDataTable() ?: $entity_type->id() . '_field_data'; } $data_tables[$entity_type_id] = $data_table; $duplicate_fields[$entity_type_id] = array_intersect_key($entity_type->getKeys(), array_flip(['id', 'revision', 'bundle'])); } foreach ($config_factory->listAll('views.view.') as $view_config_name) { $changed = FALSE; $view = $config_factory->getEditable($view_config_name); $displays = $view->get('display'); if (isset($entities_by_table[$view->get('base_table')])) { $entity_type = $entities_by_table[$view->get('base_table')]; $entity_type_id = $entity_type->id(); $data_table = $data_tables[$entity_type_id]; $base_table = $base_tables[$entity_type_id]; $revision_table = $revision_tables[$entity_type_id]; if ($data_table) { foreach ($displays as $display_name => &$display) { foreach ($handler_types as $handler_type) { if (!empty($display['display_options'][$handler_type['plural']])) { foreach ($display['display_options'][$handler_type['plural']] as $field_name => &$field) { $table = $field['table']; if (($table === $base_table || $table === $revision_table) && in_array($field_name, $duplicate_fields[$entity_type_id])) { $field['table'] = $data_table; $changed = TRUE; } } } } } } } if ($changed) { $view->set('display', $displays); $view->save(); $ids[] = $view->get('id'); } } if (!empty($ids)) { $message = new TranslatableMarkup('Updated tables for field handlers for views: @ids', ['@ids' => implode(', ', array_unique($ids))]); } return $message; }