Update to Drupal 8.1.5. For more information, see https://www.drupal.org/project/drupal/releases/8.1.5
This commit is contained in:
parent
13b6ca7cc2
commit
38ba7c357d
342 changed files with 7814 additions and 1534 deletions
|
@ -34,6 +34,12 @@ views.display.page:
|
|||
weight:
|
||||
type: integer
|
||||
label: 'Weight'
|
||||
enabled:
|
||||
type: boolean
|
||||
label: 'Enabled'
|
||||
expanded:
|
||||
type: boolean
|
||||
label: 'Expanded'
|
||||
menu_name:
|
||||
type: string
|
||||
label: 'Menu name'
|
||||
|
|
|
@ -104,7 +104,7 @@ class ViewAjaxController implements ContainerInjectionInterface {
|
|||
* The current request object.
|
||||
*
|
||||
* @return \Drupal\views\Ajax\ViewAjaxResponse
|
||||
* The view response as ajax response.
|
||||
* The view response as ajax response.
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
|
||||
* Thrown when the view was not found.
|
||||
|
|
|
@ -57,6 +57,13 @@ class EntityViewsData implements EntityHandlerInterface, EntityViewsDataInterfac
|
|||
*/
|
||||
protected $fieldStorageDefinitions;
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* Constructs an EntityViewsData object.
|
||||
*
|
||||
|
@ -112,6 +119,7 @@ class EntityViewsData implements EntityHandlerInterface, EntityViewsDataInterfac
|
|||
$data = [];
|
||||
|
||||
$base_table = $this->entityType->getBaseTable() ?: $this->entityType->id();
|
||||
$views_revision_base_table = NULL;
|
||||
$revisionable = $this->entityType->isRevisionable();
|
||||
$base_field = $this->entityType->getKey('id');
|
||||
|
||||
|
@ -235,6 +243,7 @@ class EntityViewsData implements EntityHandlerInterface, EntityViewsDataInterfac
|
|||
// Load all typed data definitions of all fields. This should cover each of
|
||||
// the entity base, revision, data tables.
|
||||
$field_definitions = $this->entityManager->getBaseFieldDefinitions($this->entityType->id());
|
||||
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
|
||||
if ($table_mapping = $this->storage->getTableMapping($field_definitions)) {
|
||||
// Fetch all fields that can appear in both the base table and the data
|
||||
// table.
|
||||
|
@ -257,6 +266,36 @@ class EntityViewsData implements EntityHandlerInterface, EntityViewsDataInterfac
|
|||
$this->mapFieldDefinition($table, $field_name, $field_definitions[$field_name], $table_mapping, $data[$table]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($field_definitions as $field_definition) {
|
||||
if ($table_mapping->requiresDedicatedTableStorage($field_definition->getFieldStorageDefinition())) {
|
||||
$table = $table_mapping->getDedicatedDataTableName($field_definition->getFieldStorageDefinition());
|
||||
|
||||
$data[$table]['table']['group'] = $this->entityType->getLabel();
|
||||
$data[$table]['table']['provider'] = $this->entityType->getProvider();
|
||||
$data[$table]['table']['join'][$views_base_table] = [
|
||||
'left_field' => $base_field,
|
||||
'field' => 'entity_id',
|
||||
'extra' => [
|
||||
['field' => 'deleted', 'value' => 0, 'numeric' => TRUE],
|
||||
],
|
||||
];
|
||||
|
||||
if ($revisionable) {
|
||||
$revision_table = $table_mapping->getDedicatedRevisionTableName($field_definition->getFieldStorageDefinition());
|
||||
|
||||
$data[$revision_table]['table']['group'] = $this->t('@entity_type revision', ['@entity_type' => $this->entityType->getLabel()]);
|
||||
$data[$revision_table]['table']['provider'] = $this->entityType->getProvider();
|
||||
$data[$revision_table]['table']['join'][$views_revision_base_table] = [
|
||||
'left_field' => $revision_field,
|
||||
'field' => 'entity_id',
|
||||
'extra' => [
|
||||
['field' => 'deleted', 'value' => 0, 'numeric' => TRUE],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the entity type key to each table generated.
|
||||
|
|
|
@ -26,7 +26,6 @@ class ViewsMenuLink extends MenuLinkBase implements ContainerFactoryPluginInterf
|
|||
'enabled' => 1,
|
||||
'title' => 1,
|
||||
'description' => 1,
|
||||
'metadata' => 1,
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -140,9 +139,9 @@ class ViewsMenuLink extends MenuLinkBase implements ContainerFactoryPluginInterf
|
|||
$display = &$view->storage->getDisplay($view->current_display);
|
||||
// Just save the title to the original view.
|
||||
$changed = FALSE;
|
||||
foreach ($new_definition_values as $key => $new_definition_value) {
|
||||
if (isset($display['display_options']['menu'][$key]) && $display['display_options']['menu'][$key] != $new_definition_values[$key]) {
|
||||
$display['display_options']['menu'][$key] = $new_definition_values[$key];
|
||||
foreach ($overrides as $key => $new_definition_value) {
|
||||
if (empty($display['display_options']['menu'][$key]) || $display['display_options']['menu'][$key] != $new_definition_value) {
|
||||
$display['display_options']['menu'][$key] = $new_definition_value;
|
||||
$changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ class ViewsHandlerManager extends DefaultPluginManager implements FallbackPlugin
|
|||
|
||||
if (isset($data[$field][$this->handlerType])) {
|
||||
$definition = $data[$field][$this->handlerType];
|
||||
foreach (array('group', 'title', 'title short', 'help', 'real field', 'real table', 'entity type', 'entity field') as $key) {
|
||||
foreach (array('group', 'title', 'title short', 'label', 'help', 'real field', 'real table', 'entity type', 'entity field') as $key) {
|
||||
if (!isset($definition[$key])) {
|
||||
// First check the field level.
|
||||
if (!empty($data[$field][$key])) {
|
||||
|
|
|
@ -816,4 +816,19 @@ abstract class HandlerBase extends PluginBase implements ViewsHandlerInterface {
|
|||
$view->cacheSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates options stored on the handler
|
||||
*
|
||||
* @param array $options
|
||||
* The options stored in the handler
|
||||
* @param array $form_state_options
|
||||
* The newly submitted form state options.
|
||||
*
|
||||
* @return array
|
||||
* The new options
|
||||
*/
|
||||
public function submitFormCalculateOptions(array $options, array $form_state_options) {
|
||||
return $form_state_options + $options;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -336,7 +336,7 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
|
|||
* @param $tokens
|
||||
* Array of token => replacement_value items.
|
||||
*
|
||||
* @return String
|
||||
* @return string
|
||||
*/
|
||||
protected function viewsTokenReplace($text, $tokens) {
|
||||
if (!strlen($text)) {
|
||||
|
@ -373,7 +373,8 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
|
|||
assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/\', $top) === 1', 'Tokens need to be valid Twig variables.');
|
||||
$token_array = array(array_pop($parts) => $replacement);
|
||||
foreach (array_reverse($parts) as $key) {
|
||||
assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/\', $key) === 1', 'Tokens need to be valid Twig variables.');
|
||||
// The key could also be numeric (array index) so allow that.
|
||||
assert('is_numeric($key) || (preg_match(\'/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/\', $key) === 1)', 'Tokens need to be valid Twig variables.');
|
||||
$token_array = array($key => $token_array);
|
||||
}
|
||||
if (!isset($twig_tokens[$top])) {
|
||||
|
|
|
@ -568,7 +568,7 @@ interface DisplayPluginInterface {
|
|||
* Renders the exposed form as block.
|
||||
*
|
||||
* @return string|null
|
||||
* The rendered exposed form as string or NULL otherwise.
|
||||
* The rendered exposed form as string or NULL otherwise.
|
||||
*/
|
||||
public function viewExposedFormBlocks();
|
||||
|
||||
|
|
|
@ -124,6 +124,7 @@ class Page extends PathPluginBase {
|
|||
'title' => array('default' => ''),
|
||||
'description' => array('default' => ''),
|
||||
'weight' => array('default' => 0),
|
||||
'enabled' => array('default' => TRUE),
|
||||
'menu_name' => array('default' => 'main'),
|
||||
'parent' => array('default' => ''),
|
||||
'context' => array('default' => ''),
|
||||
|
|
|
@ -322,6 +322,8 @@ abstract class PathPluginBase extends DisplayPluginBase implements DisplayRouter
|
|||
$links[$menu_link_id]['title'] = $menu['title'];
|
||||
$links[$menu_link_id]['description'] = $menu['description'];
|
||||
$links[$menu_link_id]['parent'] = $menu['parent'];
|
||||
$links[$menu_link_id]['enabled'] = $menu['enabled'];
|
||||
$links[$menu_link_id]['expanded'] = $menu['expanded'];
|
||||
|
||||
if (isset($menu['weight'])) {
|
||||
$links[$menu_link_id]['weight'] = intval($menu['weight']);
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
namespace Drupal\views\Plugin\views\field;
|
||||
|
||||
use Drupal\Core\Entity\EntityMalformedException;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\Exception\UndefinedLinkTemplateException;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\views\ResultRow;
|
||||
use Drupal\views\ViewExecutable;
|
||||
|
@ -105,8 +107,16 @@ class EntityLabel extends FieldPluginBase {
|
|||
$entity = $this->loadedReferencers[$type][$value];
|
||||
|
||||
if (!empty($this->options['link_to_entity'])) {
|
||||
$this->options['alter']['make_link'] = TRUE;
|
||||
$this->options['alter']['url'] = $entity->urlInfo();
|
||||
try {
|
||||
$this->options['alter']['url'] = $entity->toUrl();
|
||||
$this->options['alter']['make_link'] = TRUE;
|
||||
}
|
||||
catch (UndefinedLinkTemplateException $e) {
|
||||
$this->options['alter']['make_link'] = FALSE;
|
||||
}
|
||||
catch (EntityMalformedException $e) {
|
||||
$this->options['alter']['make_link'] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->sanitizeValue($entity->label());
|
||||
|
|
|
@ -472,7 +472,8 @@ class Field extends FieldPluginBase implements CacheableDependencyInterface, Mul
|
|||
|
||||
// Get the settings form.
|
||||
$settings_form = array('#value' => array());
|
||||
if ($formatter = $this->getFormatterInstance()) {
|
||||
$format = isset($form_state->getUserInput()['options']['type']) ? $form_state->getUserInput()['options']['type'] : $this->options['type'];
|
||||
if ($formatter = $this->getFormatterInstance($format)) {
|
||||
$settings_form = $formatter->settingsForm($form, $form_state);
|
||||
// Convert field UI selector states to work in the Views field form.
|
||||
FormHelper::rewriteStatesSelector($settings_form, "fields[{$field->getName()}][settings_edit_form]", 'options');
|
||||
|
@ -480,6 +481,21 @@ class Field extends FieldPluginBase implements CacheableDependencyInterface, Mul
|
|||
$form['settings'] = $settings_form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitFormCalculateOptions(array $options, array $form_state_options) {
|
||||
// When we change the formatter type we don't want to keep any of the
|
||||
// previous configured formatter settings, as there might be schema
|
||||
// conflict.
|
||||
unset($options['settings']);
|
||||
$options = $form_state_options + $options;
|
||||
if (!isset($options['settings'])) {
|
||||
$options['settings'] = [];
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide options for multiple value fields.
|
||||
*/
|
||||
|
@ -937,13 +953,16 @@ class Field extends FieldPluginBase implements CacheableDependencyInterface, Mul
|
|||
* @return \Drupal\Core\Field\FormatterInterface|null
|
||||
* The field formatter instance.
|
||||
*/
|
||||
protected function getFormatterInstance() {
|
||||
$settings = $this->options['settings'] + $this->formatterPluginManager->getDefaultSettings($this->options['type']);
|
||||
protected function getFormatterInstance($format = NULL) {
|
||||
if (!isset($format)) {
|
||||
$format = $this->options['type'];
|
||||
}
|
||||
$settings = $this->options['settings'] + $this->formatterPluginManager->getDefaultSettings($format);
|
||||
|
||||
$options = [
|
||||
'field_definition' => $this->getFieldDefinition(),
|
||||
'configuration' => [
|
||||
'type' => $this->options['type'],
|
||||
'type' => $format,
|
||||
'settings' => $settings,
|
||||
'label' => '',
|
||||
'weight' => 0,
|
||||
|
|
|
@ -140,7 +140,7 @@ interface FieldHandlerInterface extends ViewsHandlerInterface {
|
|||
* by in the style settings.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if this field handler is groupable, otherwise FALSE.
|
||||
* TRUE if this field handler is groupable, otherwise FALSE.
|
||||
*/
|
||||
public function useStringGroupBy();
|
||||
|
||||
|
@ -215,7 +215,7 @@ interface FieldHandlerInterface extends ViewsHandlerInterface {
|
|||
* Whether or not to use empty() to check the value.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the value is considered empty, FALSE otherwise.
|
||||
* TRUE if the value is considered empty, FALSE otherwise.
|
||||
*/
|
||||
public function isValueEmpty($value, $empty_zero, $no_skip_empty = TRUE);
|
||||
|
||||
|
|
|
@ -93,9 +93,14 @@ class BooleanOperator extends FilterPluginBase {
|
|||
parent::init($view, $display, $options);
|
||||
|
||||
$this->value_value = $this->t('True');
|
||||
|
||||
if (isset($this->definition['label'])) {
|
||||
$this->value_value = $this->definition['label'];
|
||||
}
|
||||
elseif (isset($this->definition['title'])) {
|
||||
$this->value_value = $this->definition['title'];
|
||||
}
|
||||
|
||||
if (isset($this->definition['accept null'])) {
|
||||
$this->accept_null = (bool) $this->definition['accept null'];
|
||||
}
|
||||
|
|
|
@ -303,24 +303,18 @@ class JoinPluginBase extends PluginBase implements JoinPluginInterface {
|
|||
if (is_array($info['value']) && count($info['value']) == 1) {
|
||||
$info['value'] = array_shift($info['value']);
|
||||
}
|
||||
|
||||
if (is_array($info['value'])) {
|
||||
// With an array of values, we need multiple placeholders and the
|
||||
// 'IN' operator is implicit.
|
||||
$local_arguments = array();
|
||||
foreach ($info['value'] as $value) {
|
||||
$placeholder_i = ':views_join_condition_' . $select_query->nextPlaceholder();
|
||||
$local_arguments[$placeholder_i] = $value;
|
||||
}
|
||||
|
||||
// We use an SA-CORE-2014-005 conformant placeholder for our array
|
||||
// of values. Also, note that the 'IN' operator is implicit.
|
||||
// @see https://www.drupal.org/node/2401615.
|
||||
$operator = !empty($info['operator']) ? $info['operator'] : 'IN';
|
||||
$placeholder = '( ' . implode(', ', array_keys($local_arguments)) . ' )';
|
||||
$arguments += $local_arguments;
|
||||
$placeholder = ':views_join_condition_' . $select_query->nextPlaceholder() . '[]';
|
||||
$placeholder_sql = "( $placeholder )";
|
||||
}
|
||||
else {
|
||||
// With a single value, the '=' operator is implicit.
|
||||
$operator = !empty($info['operator']) ? $info['operator'] : '=';
|
||||
$placeholder = ':views_join_condition_' . $select_query->nextPlaceholder();
|
||||
$placeholder = $placeholder_sql = ':views_join_condition_' . $select_query->nextPlaceholder();
|
||||
}
|
||||
// Set 'field' as join table field if available or set 'left field' as
|
||||
// join table field is not set.
|
||||
|
@ -329,7 +323,7 @@ class JoinPluginBase extends PluginBase implements JoinPluginInterface {
|
|||
// Allow the value to be set either with the 'value' element or
|
||||
// with 'left_field'.
|
||||
if (isset($info['left_field'])) {
|
||||
$placeholder = "$left[alias].$info[left_field]";
|
||||
$placeholder_sql = "$left[alias].$info[left_field]";
|
||||
}
|
||||
else {
|
||||
$arguments[$placeholder] = $info['value'];
|
||||
|
@ -340,7 +334,8 @@ class JoinPluginBase extends PluginBase implements JoinPluginInterface {
|
|||
$join_table_field = "$left[alias].$info[left_field]";
|
||||
$arguments[$placeholder] = $info['value'];
|
||||
}
|
||||
$extras[] = "$join_table_field $operator $placeholder";
|
||||
// Render out the SQL fragment with parameters.
|
||||
$extras[] = "$join_table_field $operator $placeholder_sql";
|
||||
}
|
||||
|
||||
if ($extras) {
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace Drupal\views\Plugin\views\query;
|
|||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\Core\Database\DatabaseExceptionWrapper;
|
||||
|
@ -13,6 +14,7 @@ use Drupal\views\Plugin\views\HandlerBase;
|
|||
use Drupal\views\ResultRow;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Views;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Views query plugin for an SQL query.
|
||||
|
@ -106,6 +108,40 @@ class Sql extends QueryPluginBase {
|
|||
*/
|
||||
protected $noDistinct;
|
||||
|
||||
/**
|
||||
* The entity type manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
|
||||
*/
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* Constructs a Sql object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||
* The entity type manager.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
}
|
||||
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity_type.manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -1482,63 +1518,97 @@ class Sql extends QueryPluginBase {
|
|||
foreach ($entity_information as $info) {
|
||||
$entity_type = $info['entity_type'];
|
||||
if (!isset($entity_types[$entity_type])) {
|
||||
$entity_types[$entity_type] = \Drupal::entityManager()->getDefinition($entity_type);
|
||||
$entity_types[$entity_type] = $this->entityTypeManager->getDefinition($entity_type);
|
||||
}
|
||||
}
|
||||
|
||||
// Assemble a list of entities to load.
|
||||
$ids_by_type = array();
|
||||
$entity_ids_by_type = [];
|
||||
$revision_ids_by_type = [];
|
||||
foreach ($entity_information as $info) {
|
||||
$relationship_id = $info['relationship_id'];
|
||||
$entity_type = $info['entity_type'];
|
||||
/** @var \Drupal\Core\Entity\EntityTypeInterface $entity_info */
|
||||
$entity_info = $entity_types[$entity_type];
|
||||
$id_key = !$info['revision'] ? $entity_info->getKey('id') : $entity_info->getKey('revision');
|
||||
$revision = $info['revision'];
|
||||
$id_key = !$revision ? $entity_info->getKey('id') : $entity_info->getKey('revision');
|
||||
$id_alias = $this->getFieldAlias($info['alias'], $id_key);
|
||||
|
||||
foreach ($results as $index => $result) {
|
||||
// Store the entity id if it was found.
|
||||
if (isset($result->{$id_alias}) && $result->{$id_alias} != '') {
|
||||
$ids_by_type[$entity_type][$index][$relationship_id] = $result->$id_alias;
|
||||
if ($revision) {
|
||||
$revision_ids_by_type[$entity_type][$index][$relationship_id] = $result->$id_alias;
|
||||
}
|
||||
else {
|
||||
$entity_ids_by_type[$entity_type][$index][$relationship_id] = $result->$id_alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load all entities and assign them to the correct result row.
|
||||
foreach ($ids_by_type as $entity_type => $ids) {
|
||||
foreach ($entity_ids_by_type as $entity_type => $ids) {
|
||||
$entity_storage = $this->entityTypeManager->getStorage($entity_type);
|
||||
$flat_ids = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveArrayIterator($ids)), FALSE);
|
||||
|
||||
// Drupal core currently has no way to load multiple revisions. Sad.
|
||||
if (isset($entity_information[$entity_type]['revision']) && $entity_information[$entity_type]['revision'] === TRUE) {
|
||||
$entities = array();
|
||||
foreach ($flat_ids as $revision_id) {
|
||||
$entity = entity_revision_load($entity_type, $revision_id);
|
||||
if ($entity) {
|
||||
$entities[$revision_id] = $entity;
|
||||
}
|
||||
$entities = $entity_storage->loadMultiple(array_unique($flat_ids));
|
||||
$results = $this->_assignEntitiesToResult($ids, $entities, $results);
|
||||
}
|
||||
|
||||
// Now load all revisions.
|
||||
foreach ($revision_ids_by_type as $entity_type => $revision_ids) {
|
||||
$entity_storage = $this->entityTypeManager->getStorage($entity_type);
|
||||
$entities = [];
|
||||
|
||||
foreach ($revision_ids as $index => $revision_id_by_relationship) {
|
||||
foreach ($revision_id_by_relationship as $revision => $revision_id) {
|
||||
// Drupal core currently has no way to load multiple revisions.
|
||||
$entity = $entity_storage->loadRevision($revision_id);
|
||||
$entities[$revision_id] = $entity;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$entities = entity_load_multiple($entity_type, $flat_ids);
|
||||
}
|
||||
|
||||
foreach ($ids as $index => $relationships) {
|
||||
foreach ($relationships as $relationship_id => $entity_id) {
|
||||
if (isset($entities[$entity_id])) {
|
||||
$entity = $entities[$entity_id];
|
||||
}
|
||||
else {
|
||||
$entity = NULL;
|
||||
}
|
||||
$results = $this->_assignEntitiesToResult($revision_ids, $entities, $results);
|
||||
}
|
||||
}
|
||||
|
||||
if ($relationship_id == 'none') {
|
||||
$results[$index]->_entity = $entity;
|
||||
}
|
||||
else {
|
||||
$results[$index]->_relationship_entities[$relationship_id] = $entity;
|
||||
}
|
||||
/**
|
||||
* Sets entities onto the view result row objects.
|
||||
*
|
||||
* This method takes into account the relationship in which the entity was
|
||||
* needed in the first place.
|
||||
*
|
||||
* @param mixed[][] $ids
|
||||
* A two dimensional array of identifiers (entity ID / revision ID) keyed by
|
||||
* relationship.
|
||||
* @param \Drupal\Core\Entity\EntityInterface[] $entities
|
||||
* An array of entities keyed by their identified (entity ID / revision ID).
|
||||
* @param \Drupal\views\ResultRow[] $results
|
||||
* The entire views result.
|
||||
*
|
||||
* @return \Drupal\views\ResultRow[]
|
||||
* The changed views results.
|
||||
*/
|
||||
protected function _assignEntitiesToResult($ids, array $entities, array $results) {
|
||||
foreach ($ids as $index => $relationships) {
|
||||
foreach ($relationships as $relationship_id => $id) {
|
||||
if (isset($entities[$id])) {
|
||||
$entity = $entities[$id];
|
||||
}
|
||||
else {
|
||||
$entity = NULL;
|
||||
}
|
||||
|
||||
if ($relationship_id == 'none') {
|
||||
$results[$index]->_entity = $entity;
|
||||
}
|
||||
else {
|
||||
$results[$index]->_relationship_entities[$relationship_id] = $entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -152,7 +152,7 @@ class DisplayPageWebTest extends PluginTestBase {
|
|||
* @param string $path
|
||||
* Path that will be set as the view page display path.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* Assertion result.
|
||||
*/
|
||||
public function assertPagePath($path) {
|
||||
|
|
|
@ -136,7 +136,7 @@ class NumericFormatPluralTest extends ViewTestBase {
|
|||
* Creates and saves a test file.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityInterface
|
||||
* A file entity.
|
||||
* A file entity.
|
||||
*/
|
||||
protected function createFile() {
|
||||
// Create a new file entity.
|
||||
|
|
|
@ -2374,7 +2374,7 @@ class ViewExecutable implements \Serializable {
|
|||
* Returns whether admin links should be rendered on the view.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if admin links should be rendered, else FALSE.
|
||||
* TRUE if admin links should be rendered, else FALSE.
|
||||
*/
|
||||
public function getShowAdminLinks() {
|
||||
if (!isset($this->showAdminLinks)) {
|
||||
|
|
|
@ -295,8 +295,8 @@ class Views {
|
|||
* If TRUE, the list of views is sorted ascending.
|
||||
*
|
||||
* @return array
|
||||
* an associative array for use in select.
|
||||
* - key: view name and display id separated by ':', or the view name only
|
||||
* An associative array for use in select.
|
||||
* - key: view name and display id separated by ':', or the view name only.
|
||||
*/
|
||||
public static function getViewsAsOptions($views_only = FALSE, $filter = 'all', $exclude_view = NULL, $optgroup = FALSE, $sort = FALSE) {
|
||||
|
||||
|
|
|
@ -0,0 +1,346 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
- user
|
||||
id: base_and_revision
|
||||
label: base_and_revision
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: node_field_revision
|
||||
base_field: vid
|
||||
core: 8.x
|
||||
display:
|
||||
default:
|
||||
display_plugin: default
|
||||
id: default
|
||||
display_title: Master
|
||||
position: 0
|
||||
display_options:
|
||||
access:
|
||||
type: perm
|
||||
options:
|
||||
perm: 'view all revisions'
|
||||
cache:
|
||||
type: none
|
||||
options: { }
|
||||
query:
|
||||
type: views_query
|
||||
options:
|
||||
disable_sql_rewrite: false
|
||||
distinct: false
|
||||
replica: false
|
||||
query_comment: ''
|
||||
query_tags: { }
|
||||
exposed_form:
|
||||
type: basic
|
||||
options:
|
||||
submit_button: Apply
|
||||
reset_button: false
|
||||
reset_button_label: Reset
|
||||
exposed_sorts_label: 'Sort by'
|
||||
expose_sort_order: true
|
||||
sort_asc_label: Asc
|
||||
sort_desc_label: Desc
|
||||
pager:
|
||||
type: mini
|
||||
options:
|
||||
items_per_page: 10
|
||||
offset: 0
|
||||
id: 0
|
||||
total_pages: null
|
||||
expose:
|
||||
items_per_page: false
|
||||
items_per_page_label: 'Items per page'
|
||||
items_per_page_options: '5, 10, 25, 50'
|
||||
items_per_page_options_all: false
|
||||
items_per_page_options_all_label: '- All -'
|
||||
offset: false
|
||||
offset_label: Offset
|
||||
tags:
|
||||
previous: ‹‹
|
||||
next: ››
|
||||
style:
|
||||
type: default
|
||||
options:
|
||||
grouping: { }
|
||||
row_class: ''
|
||||
default_row_class: true
|
||||
uses_fields: false
|
||||
row:
|
||||
type: fields
|
||||
options:
|
||||
inline: { }
|
||||
separator: ''
|
||||
hide_empty: false
|
||||
default_field_elements: true
|
||||
fields:
|
||||
nid:
|
||||
id: nid
|
||||
table: node_field_revision
|
||||
field: nid
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
label: ''
|
||||
exclude: false
|
||||
alter:
|
||||
alter_text: false
|
||||
text: ''
|
||||
make_link: false
|
||||
path: ''
|
||||
absolute: false
|
||||
external: false
|
||||
replace_spaces: false
|
||||
path_case: none
|
||||
trim_whitespace: false
|
||||
alt: ''
|
||||
rel: ''
|
||||
link_class: ''
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
target: ''
|
||||
nl2br: false
|
||||
max_length: 0
|
||||
word_boundary: true
|
||||
ellipsis: true
|
||||
more_link: false
|
||||
more_link_text: ''
|
||||
more_link_path: ''
|
||||
strip_tags: false
|
||||
trim: false
|
||||
preserve_tags: ''
|
||||
html: false
|
||||
element_type: ''
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: false
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
click_sort_column: value
|
||||
type: number_integer
|
||||
settings:
|
||||
thousand_separator: ''
|
||||
prefix_suffix: true
|
||||
group_column: value
|
||||
group_columns: { }
|
||||
group_rows: true
|
||||
delta_limit: 0
|
||||
delta_offset: 0
|
||||
delta_reversed: false
|
||||
delta_first_last: false
|
||||
multi_type: separator
|
||||
separator: ', '
|
||||
field_api_classes: false
|
||||
entity_type: node
|
||||
entity_field: nid
|
||||
plugin_id: field
|
||||
vid:
|
||||
id: vid
|
||||
table: node_field_revision
|
||||
field: vid
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
label: ''
|
||||
exclude: false
|
||||
alter:
|
||||
alter_text: false
|
||||
text: ''
|
||||
make_link: false
|
||||
path: ''
|
||||
absolute: false
|
||||
external: false
|
||||
replace_spaces: false
|
||||
path_case: none
|
||||
trim_whitespace: false
|
||||
alt: ''
|
||||
rel: ''
|
||||
link_class: ''
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
target: ''
|
||||
nl2br: false
|
||||
max_length: 0
|
||||
word_boundary: true
|
||||
ellipsis: true
|
||||
more_link: false
|
||||
more_link_text: ''
|
||||
more_link_path: ''
|
||||
strip_tags: false
|
||||
trim: false
|
||||
preserve_tags: ''
|
||||
html: false
|
||||
element_type: ''
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: false
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
click_sort_column: value
|
||||
type: number_integer
|
||||
settings:
|
||||
thousand_separator: ''
|
||||
prefix_suffix: true
|
||||
group_column: value
|
||||
group_columns: { }
|
||||
group_rows: true
|
||||
delta_limit: 0
|
||||
delta_offset: 0
|
||||
delta_reversed: false
|
||||
delta_first_last: false
|
||||
multi_type: separator
|
||||
separator: ', '
|
||||
field_api_classes: false
|
||||
entity_type: node
|
||||
entity_field: vid
|
||||
plugin_id: field
|
||||
vid_1:
|
||||
id: vid_1
|
||||
table: node_field_data
|
||||
field: vid
|
||||
relationship: nid
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
label: ''
|
||||
exclude: false
|
||||
alter:
|
||||
alter_text: false
|
||||
text: ''
|
||||
make_link: false
|
||||
path: ''
|
||||
absolute: false
|
||||
external: false
|
||||
replace_spaces: false
|
||||
path_case: none
|
||||
trim_whitespace: false
|
||||
alt: ''
|
||||
rel: ''
|
||||
link_class: ''
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
target: ''
|
||||
nl2br: false
|
||||
max_length: 0
|
||||
word_boundary: true
|
||||
ellipsis: true
|
||||
more_link: false
|
||||
more_link_text: ''
|
||||
more_link_path: ''
|
||||
strip_tags: false
|
||||
trim: false
|
||||
preserve_tags: ''
|
||||
html: false
|
||||
element_type: ''
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: false
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
click_sort_column: value
|
||||
type: number_integer
|
||||
settings:
|
||||
thousand_separator: ''
|
||||
prefix_suffix: true
|
||||
group_column: value
|
||||
group_columns: { }
|
||||
group_rows: true
|
||||
delta_limit: 0
|
||||
delta_offset: 0
|
||||
delta_reversed: false
|
||||
delta_first_last: false
|
||||
multi_type: separator
|
||||
separator: ', '
|
||||
field_api_classes: false
|
||||
entity_type: node
|
||||
entity_field: vid
|
||||
plugin_id: field
|
||||
filters:
|
||||
vid:
|
||||
id: vid
|
||||
table: node_field_revision
|
||||
field: vid
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
operator: '='
|
||||
value:
|
||||
min: ''
|
||||
max: ''
|
||||
value: '3'
|
||||
group: 1
|
||||
exposed: false
|
||||
expose:
|
||||
operator_id: ''
|
||||
label: ''
|
||||
description: ''
|
||||
use_operator: false
|
||||
operator: ''
|
||||
identifier: ''
|
||||
required: false
|
||||
remember: false
|
||||
multiple: false
|
||||
remember_roles:
|
||||
authenticated: authenticated
|
||||
is_grouped: false
|
||||
group_info:
|
||||
label: ''
|
||||
description: ''
|
||||
identifier: ''
|
||||
optional: true
|
||||
widget: select
|
||||
multiple: false
|
||||
remember: false
|
||||
default_group: All
|
||||
default_group_multiple: { }
|
||||
group_items: { }
|
||||
entity_type: node
|
||||
entity_field: vid
|
||||
plugin_id: numeric
|
||||
sorts: { }
|
||||
header: { }
|
||||
footer: { }
|
||||
empty: { }
|
||||
relationships:
|
||||
nid:
|
||||
id: nid
|
||||
table: node_field_revision
|
||||
field: nid
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: Node
|
||||
required: false
|
||||
entity_type: node
|
||||
entity_field: nid
|
||||
plugin_id: standard
|
||||
arguments: { }
|
||||
display_extenders: { }
|
||||
rendering_language: en
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_interface'
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
tags: { }
|
|
@ -0,0 +1,45 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- entity_test
|
||||
id: test_entity_multivalue_basefield
|
||||
label: ''
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: entity_test_multivalue_basefield
|
||||
base_field: id
|
||||
core: '8'
|
||||
display:
|
||||
default:
|
||||
display_plugin: default
|
||||
id: default
|
||||
display_title: Master
|
||||
position: 0
|
||||
display_options:
|
||||
fields:
|
||||
id:
|
||||
id: id
|
||||
table: entity_test_multivalue_basefield
|
||||
field: nid
|
||||
relationship: none
|
||||
plugin_id: field
|
||||
entity_type: entity_test_multivalue_basefield
|
||||
entity_field: id
|
||||
name:
|
||||
id: name
|
||||
table: entity_test_multivalue_basefield__name
|
||||
field: name
|
||||
plugin_id: field
|
||||
entity_type: entity_test_multivalue_basefield
|
||||
entity_field: name
|
||||
defaults:
|
||||
fields: false
|
||||
filters: false
|
||||
sorts:
|
||||
id:
|
||||
id: id
|
||||
table: entity_test_multivalue_basefield
|
||||
field: id
|
||||
order: asc
|
|
@ -0,0 +1,188 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.body
|
||||
module:
|
||||
- node
|
||||
- text
|
||||
- user
|
||||
id: test_field_body
|
||||
label: test_field_body
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: node_field_data
|
||||
base_field: nid
|
||||
core: 8.x
|
||||
display:
|
||||
default:
|
||||
display_plugin: default
|
||||
id: default
|
||||
display_title: Master
|
||||
position: 0
|
||||
display_options:
|
||||
access:
|
||||
type: perm
|
||||
options:
|
||||
perm: 'access content'
|
||||
cache:
|
||||
type: tag
|
||||
options: { }
|
||||
query:
|
||||
type: views_query
|
||||
options:
|
||||
disable_sql_rewrite: false
|
||||
distinct: false
|
||||
replica: false
|
||||
query_comment: ''
|
||||
query_tags: { }
|
||||
exposed_form:
|
||||
type: basic
|
||||
options:
|
||||
submit_button: Apply
|
||||
reset_button: false
|
||||
reset_button_label: Reset
|
||||
exposed_sorts_label: 'Sort by'
|
||||
expose_sort_order: true
|
||||
sort_asc_label: Asc
|
||||
sort_desc_label: Desc
|
||||
pager:
|
||||
type: mini
|
||||
options:
|
||||
items_per_page: 10
|
||||
offset: 0
|
||||
id: 0
|
||||
total_pages: null
|
||||
expose:
|
||||
items_per_page: false
|
||||
items_per_page_label: 'Items per page'
|
||||
items_per_page_options: '5, 10, 25, 50'
|
||||
items_per_page_options_all: false
|
||||
items_per_page_options_all_label: '- All -'
|
||||
offset: false
|
||||
offset_label: Offset
|
||||
tags:
|
||||
previous: ‹‹
|
||||
next: ››
|
||||
style:
|
||||
type: default
|
||||
options:
|
||||
grouping: { }
|
||||
row_class: ''
|
||||
default_row_class: true
|
||||
uses_fields: false
|
||||
row:
|
||||
type: fields
|
||||
options:
|
||||
inline: { }
|
||||
separator: ''
|
||||
hide_empty: false
|
||||
default_field_elements: true
|
||||
fields:
|
||||
body:
|
||||
id: body
|
||||
table: node__body
|
||||
field: body
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: 'Body field'
|
||||
label: ''
|
||||
exclude: false
|
||||
alter:
|
||||
alter_text: false
|
||||
text: ''
|
||||
make_link: false
|
||||
path: ''
|
||||
absolute: false
|
||||
external: false
|
||||
replace_spaces: false
|
||||
path_case: none
|
||||
trim_whitespace: false
|
||||
alt: ''
|
||||
rel: ''
|
||||
link_class: ''
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
target: ''
|
||||
nl2br: false
|
||||
max_length: 0
|
||||
word_boundary: true
|
||||
ellipsis: true
|
||||
more_link: false
|
||||
more_link_text: ''
|
||||
more_link_path: ''
|
||||
strip_tags: false
|
||||
trim: false
|
||||
preserve_tags: ''
|
||||
html: false
|
||||
element_type: ''
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: false
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
click_sort_column: value
|
||||
type: text_default
|
||||
settings: { }
|
||||
group_column: value
|
||||
group_columns: { }
|
||||
group_rows: true
|
||||
delta_limit: 0
|
||||
delta_offset: 0
|
||||
delta_reversed: false
|
||||
delta_first_last: false
|
||||
multi_type: separator
|
||||
separator: ', '
|
||||
field_api_classes: false
|
||||
plugin_id: field
|
||||
filters:
|
||||
status:
|
||||
value: true
|
||||
table: node_field_data
|
||||
field: status
|
||||
plugin_id: boolean
|
||||
entity_type: node
|
||||
entity_field: status
|
||||
id: status
|
||||
expose:
|
||||
operator: ''
|
||||
group: 1
|
||||
sorts:
|
||||
created:
|
||||
id: created
|
||||
table: node_field_data
|
||||
field: created
|
||||
order: DESC
|
||||
entity_type: node
|
||||
entity_field: created
|
||||
plugin_id: date
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
exposed: false
|
||||
expose:
|
||||
label: ''
|
||||
granularity: second
|
||||
header: { }
|
||||
footer: { }
|
||||
empty: { }
|
||||
relationships: { }
|
||||
arguments: { }
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
tags:
|
||||
- 'config:field.storage.node.body'
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\views\FunctionalJavascript\Plugin\views\Handler;
|
||||
|
||||
use Drupal\config\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
|
||||
/**
|
||||
* Tests the field field handler UI.
|
||||
*
|
||||
* @group views
|
||||
*/
|
||||
class FieldTest extends JavascriptTestBase {
|
||||
use SchemaCheckTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'views', 'views_ui', 'views_test_config'];
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_field_body'];
|
||||
|
||||
/**
|
||||
* The account.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
ViewTestData::createTestViews(get_class($this), ['views_test_config']);
|
||||
|
||||
// Disable automatic live preview to make the sequence of calls clearer.
|
||||
\Drupal::configFactory()->getEditable('views.settings')->set('ui.always_live_preview', FALSE)->save();
|
||||
|
||||
$this->account = $this->drupalCreateUser(['administer views']);
|
||||
$this->drupalLogin($this->account);
|
||||
|
||||
NodeType::create([
|
||||
'type' => 'page',
|
||||
])->save();
|
||||
|
||||
FieldConfig::create([
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'body',
|
||||
'bundle' => 'page',
|
||||
])->save();
|
||||
}
|
||||
|
||||
public function testFormatterChanging() {
|
||||
$web_assert = $this->assertSession();
|
||||
$url = '/admin/structure/views/view/test_field_body';
|
||||
$this->drupalGet($url);
|
||||
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$page->clickLink('Body field');
|
||||
$web_assert->assertWaitOnAjaxRequest();
|
||||
|
||||
$page->fillField('options[type]', 'text_trimmed');
|
||||
// Add a value to the trim_length setting.
|
||||
$web_assert->assertWaitOnAjaxRequest();
|
||||
$page->fillField('options[settings][trim_length]', '700');
|
||||
$apply_button = $page->find('css', '.views-ui-dialog button.button--primary');
|
||||
$this->assertTrue(!empty($apply_button));
|
||||
$apply_button->press();
|
||||
$web_assert->assertWaitOnAjaxRequest();
|
||||
|
||||
// Save the page.
|
||||
$save_button = $page->find('css', '#edit-actions-submit');
|
||||
$save_button->press();
|
||||
|
||||
// Set the body field back to 'default' and test that the trim_length
|
||||
// settings are not in the config.
|
||||
$this->drupalGet($url);
|
||||
$page->clickLink('Body field');
|
||||
$web_assert->assertWaitOnAjaxRequest();
|
||||
|
||||
$page->fillField('options[type]', 'text_default');
|
||||
$web_assert->assertWaitOnAjaxRequest();
|
||||
$apply_button = $page->find('css', '.views-ui-dialog button.button--primary');
|
||||
$apply_button->press();
|
||||
$web_assert->assertWaitOnAjaxRequest();
|
||||
|
||||
// Save the page.
|
||||
$save_button = $page->find('css', '#edit-actions-submit');
|
||||
$save_button->press();
|
||||
|
||||
$this->assertConfigSchemaByName('views.view.test_field_body');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\views\Kernel\Entity;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTestMultiValueBasefield;
|
||||
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests entity views with multivalue base fields.
|
||||
*
|
||||
* @group views
|
||||
*/
|
||||
class EntityViewsWithMultivalueBasefieldTest extends ViewsKernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['entity_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $testViews = ['test_entity_multivalue_basefield'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
$this->installEntitySchema('entity_test_multivalue_basefield');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests entity views with multivalue base fields.
|
||||
*/
|
||||
public function testView() {
|
||||
EntityTestMultiValueBasefield::create([
|
||||
'name' => 'test',
|
||||
])->save();
|
||||
EntityTestMultiValueBasefield::create([
|
||||
'name' => ['test2', 'test3'],
|
||||
])->save();
|
||||
|
||||
$view = Views::getView('test_entity_multivalue_basefield');
|
||||
$view->execute();
|
||||
$this->assertIdenticalResultset($view, [
|
||||
['name' => ['test']],
|
||||
['name' => ['test2', 'test3']],
|
||||
], ['name' => 'name']);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\views\Kernel\Plugin\Display;
|
||||
|
||||
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
|
||||
|
||||
/**
|
||||
* Menu link test.
|
||||
*
|
||||
* @group views
|
||||
*/
|
||||
class ViewsMenuLinkTest extends ViewsKernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'menu_ui',
|
||||
'user',
|
||||
'views'
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $testViews = ['test_page_display_menu'];
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManger;
|
||||
|
||||
/**
|
||||
* The menu link manager.
|
||||
*
|
||||
* @var \Drupal\Core\Menu\MenuLinkManagerInterface
|
||||
*/
|
||||
protected $menuLinkManager;
|
||||
|
||||
/**
|
||||
* The menu link overrides.
|
||||
*
|
||||
* @var \Drupal\Core\Menu\StaticMenuLinkOverridesInterface
|
||||
*/
|
||||
protected $menuLinkOverrides;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
$this->entityManger = $this->container->get('entity.manager');
|
||||
$this->menuLinkManager = $this->container->get('plugin.manager.menu.link');
|
||||
$this->menuLinkOverrides = $this->container->get('menu_link.static.overrides');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test views internal menu link options.
|
||||
*/
|
||||
public function testMenuLinkOverrides() {
|
||||
// Link from views module.
|
||||
$views_link = $this->menuLinkManager->getDefinition('views_view:views.test_page_display_menu.page_3');
|
||||
$this->assertTrue($views_link['enabled'], 'Menu link is enabled.');
|
||||
$this->assertFalse($views_link['expanded'], 'Menu link is not expanded.');
|
||||
$views_link['enabled'] = 0;
|
||||
$views_link['expanded'] = 1;
|
||||
$this->menuLinkManager->updateDefinition($views_link['id'], $views_link);
|
||||
$views_link = $this->menuLinkManager->getDefinition($views_link['id']);
|
||||
$this->assertFalse($views_link['enabled'], 'Menu link is disabled.');
|
||||
$this->assertTrue($views_link['expanded'], 'Menu link is expanded.');
|
||||
$this->menuLinkManager->rebuild();
|
||||
$this->assertFalse($views_link['enabled'], 'Menu link is disabled.');
|
||||
$this->assertTrue($views_link['expanded'], 'Menu link is expanded.');
|
||||
|
||||
// Link from user module.
|
||||
$user_link = $this->menuLinkManager->getDefinition('user.page');
|
||||
$this->assertTrue($user_link['enabled'], 'Menu link is enabled.');
|
||||
$user_link['enabled'] = 0;
|
||||
$views_link['expanded'] = 1;
|
||||
$this->menuLinkManager->updateDefinition($user_link['id'], $user_link);
|
||||
$this->assertFalse($user_link['enabled'], 'Menu link is disabled.');
|
||||
$this->menuLinkManager->rebuild();
|
||||
$this->assertFalse($user_link['enabled'], 'Menu link is disabled.');
|
||||
|
||||
$this->menuLinkOverrides->reload();
|
||||
|
||||
$views_link = $this->menuLinkManager->getDefinition('views_view:views.test_page_display_menu.page_3');
|
||||
$this->assertFalse($views_link['enabled'], 'Menu link is disabled.');
|
||||
$this->assertTrue($views_link['expanded'], 'Menu link is expanded.');
|
||||
|
||||
$user_link = $this->menuLinkManager->getDefinition('user.page');
|
||||
$this->assertFalse($user_link['enabled'], 'Menu link is disabled.');
|
||||
}
|
||||
|
||||
}
|
|
@ -172,7 +172,8 @@ class JoinTest extends RelationshipJoinTestBase {
|
|||
$join_info = $tables['users4'];
|
||||
$this->assertTrue(strpos($join_info['condition'], "views_test_data.uid = users4.uid") !== FALSE, 'Make sure the join condition appears in the query.');
|
||||
$this->assertTrue(strpos($join_info['condition'], "users4.name = :views_join_condition_2") !== FALSE, 'Make sure the first extra join condition appears in the query.');
|
||||
$this->assertTrue(strpos($join_info['condition'], "users4.name IN ( :views_join_condition_3, :views_join_condition_4, :views_join_condition_5 )") !== FALSE, 'The IN condition for the join is properly formed.');
|
||||
$this->assertTrue(strpos($join_info['condition'], "users4.name IN ( :views_join_condition_3[] )") !== FALSE, 'The IN condition for the join is properly formed.');
|
||||
$this->assertEqual($join_info['arguments'][':views_join_condition_3[]'], array($random_name_2, $random_name_3, $random_name_4), 'Make sure the IN arguments are still part of an array.');
|
||||
|
||||
// Test that all the conditions are properly built.
|
||||
$configuration['extra'] = array(
|
||||
|
@ -197,8 +198,8 @@ class JoinTest extends RelationshipJoinTestBase {
|
|||
$tables = $query->getTables();
|
||||
$join_info = $tables['users5'];
|
||||
$this->assertTrue(strpos($join_info['condition'], "views_test_data.uid = users5.uid") !== FALSE, 'Make sure the join condition appears in the query.');
|
||||
$this->assertTrue(strpos($join_info['condition'], "users5.langcode = :views_join_condition_6") !== FALSE, 'Make sure the first extra join condition appears in the query.');
|
||||
$this->assertTrue(strpos($join_info['condition'], "views_test_data.status = :views_join_condition_7") !== FALSE, 'Make sure the second extra join condition appears in the query.');
|
||||
$this->assertTrue(strpos($join_info['condition'], "users5.langcode = :views_join_condition_4") !== FALSE, 'Make sure the first extra join condition appears in the query.');
|
||||
$this->assertTrue(strpos($join_info['condition'], "views_test_data.status = :views_join_condition_5") !== FALSE, 'Make sure the second extra join condition appears in the query.');
|
||||
$this->assertTrue(strpos($join_info['condition'], "users5.name = views_test_data.name") !== FALSE, 'Make sure the third extra join condition appears in the query.');
|
||||
$this->assertEqual(array_values($join_info['arguments']), array('en', 0), 'Make sure the arguments are in the right order');
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
* Contains \Drupal\views\Tests\Plugin\PluginBaseTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Tests\Plugin;
|
||||
namespace Drupal\Tests\views\Kernel\Plugin;
|
||||
|
||||
use Drupal\Core\Render\RenderContext;
|
||||
use Drupal\Core\Render\Markup;
|
||||
use Drupal\simpletest\KernelTestBase;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\views\Plugin\views\PluginBase;
|
||||
|
||||
/**
|
||||
|
@ -55,6 +55,16 @@ class PluginBaseTest extends KernelTestBase {
|
|||
});
|
||||
|
||||
$this->assertIdentical($result, 'first comes before second');
|
||||
|
||||
// Test tokens with numeric indexes.
|
||||
$text = '{{ argument.0.first }} comes before {{ argument.1.second }}';
|
||||
$tokens = ['{{ argument.0.first }}' => 'first', '{{ argument.1.second }}' => 'second'];
|
||||
|
||||
$result = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($text, $tokens) {
|
||||
return $this->testPluginBase->viewsTokenReplace($text, $tokens);
|
||||
});
|
||||
|
||||
$this->assertIdentical($result, 'first comes before second');
|
||||
}
|
||||
|
||||
/**
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\views\Kernel\Plugin;
|
||||
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests the loading of entities and entity revisions.
|
||||
*
|
||||
* @group views
|
||||
*
|
||||
* @see \Drupal\views\Plugin\views\query\Sql
|
||||
*/
|
||||
class SqlEntityLoadingTest extends ViewsKernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'user'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $testViews = ['base_and_revision'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installEntitySchema('user');
|
||||
$this->installSchema('node', 'node_access');
|
||||
}
|
||||
|
||||
public function testViewWithNonDefaultForwardRevision() {
|
||||
$node_type = NodeType::create([
|
||||
'type' => 'page',
|
||||
]);
|
||||
$node_type->save();
|
||||
|
||||
$node = Node::create([
|
||||
'type' => 'page',
|
||||
'title' => 'test title',
|
||||
]);
|
||||
$node->save();
|
||||
|
||||
// Creates the first revision, which is set as default.
|
||||
$revision = clone $node;
|
||||
$revision->setNewRevision(TRUE);
|
||||
$revision->isDefaultRevision(TRUE);
|
||||
$revision->save();
|
||||
|
||||
// Creates the second revision, which is not set as default.
|
||||
$revision2 = clone $node;
|
||||
$revision2->setNewRevision(TRUE);
|
||||
$revision2->isDefaultRevision(FALSE);
|
||||
$revision2->save();
|
||||
|
||||
$view = Views::getView('base_and_revision');
|
||||
$view->execute();
|
||||
|
||||
$expected = [
|
||||
[
|
||||
'nid' => $node->id(),
|
||||
// The default revision ID.
|
||||
'vid_1' => $revision->getRevisionId(),
|
||||
// THe latest revision ID.
|
||||
'vid' => $revision2->getRevisionId(),
|
||||
],
|
||||
];
|
||||
$this->assertIdenticalResultset($view, $expected, [
|
||||
'node_field_data_node_field_revision_nid' => 'nid',
|
||||
'vid_1' => 'vid_1',
|
||||
'vid' => 'vid',
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
|
@ -11,7 +11,7 @@ use Drupal\views\Tests\ViewTestData;
|
|||
/**
|
||||
* Defines a base class for Views kernel testing.
|
||||
*/
|
||||
class ViewsKernelTestBase extends KernelTestBase {
|
||||
abstract class ViewsKernelTestBase extends KernelTestBase {
|
||||
|
||||
use ViewResultAssertionTrait;
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ use Drupal\Core\Config\Entity\ConfigEntityType;
|
|||
use Drupal\Core\Entity\ContentEntityType;
|
||||
use Drupal\Core\Entity\EntityType;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Entity\Sql\DefaultTableMapping;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
|
||||
use Drupal\Core\Field\Plugin\Field\FieldType\IntegerItem;
|
||||
|
@ -160,6 +161,12 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
->setTranslatable(TRUE)
|
||||
->setSetting('max_length', 255);
|
||||
|
||||
// A base field with cardinality > 1
|
||||
$base_fields['string'] = BaseFieldDefinition::create('string')
|
||||
->setLabel('Strong')
|
||||
->setTranslatable(TRUE)
|
||||
->setCardinality(2);
|
||||
|
||||
foreach ($base_fields as $name => $base_field) {
|
||||
$base_field->setName($name);
|
||||
}
|
||||
|
@ -376,6 +383,10 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
$homepage_field_storage_definition->expects($this->any())
|
||||
->method('getSchema')
|
||||
->willReturn(UriItem::schema($homepage_field_storage_definition));
|
||||
$string_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
|
||||
$string_field_storage_definition->expects($this->any())
|
||||
->method('getSchema')
|
||||
->willReturn(StringItem::schema($string_field_storage_definition));
|
||||
|
||||
// Setup the user_id entity reference field.
|
||||
$this->entityManager->expects($this->any())
|
||||
|
@ -411,6 +422,7 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
'name' => $name_field_storage_definition,
|
||||
'description' => $description_field_storage_definition,
|
||||
'homepage' => $homepage_field_storage_definition,
|
||||
'string' => $string_field_storage_definition,
|
||||
'user_id' => $user_id_field_storage_definition,
|
||||
'revision_id' => $revision_id_field_storage_definition,
|
||||
]);
|
||||
|
@ -435,10 +447,12 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
['entity_test', $base_field_definitions],
|
||||
]));
|
||||
// Setup the table mapping.
|
||||
$table_mapping = $this->getMock('Drupal\Core\Entity\Sql\TableMappingInterface');
|
||||
$table_mapping = $this->getMockBuilder(DefaultTableMapping::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getTableNames')
|
||||
->willReturn(['entity_test']);
|
||||
->willReturn(['entity_test', 'entity_test__string']);
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getColumnNames')
|
||||
->willReturnMap([
|
||||
|
@ -450,12 +464,26 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
['description', ['value' => 'description__value', 'format' => 'description__format']],
|
||||
['homepage', ['value' => 'homepage']],
|
||||
['user_id', ['target_id' => 'user_id']],
|
||||
['string', ['value' => 'value']],
|
||||
]);
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getFieldNames')
|
||||
->willReturnMap([
|
||||
['entity_test', ['id', 'uuid', 'type', 'langcode', 'name', 'description', 'homepage', 'user_id']]
|
||||
['entity_test', ['id', 'uuid', 'type', 'langcode', 'name', 'description', 'homepage', 'user_id']],
|
||||
['entity_test__string', ['string']],
|
||||
]);
|
||||
$table_mapping->expects($this->any())
|
||||
->method('requiresDedicatedTableStorage')
|
||||
->willReturnCallback(function (BaseFieldDefinition $base_field) {
|
||||
return $base_field->getName() === 'string';
|
||||
});
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getDedicatedDataTableName')
|
||||
->willReturnCallback(function (BaseFieldDefinition $base_field) {
|
||||
if ($base_field->getName() === 'string') {
|
||||
return 'entity_test__string';
|
||||
}
|
||||
});
|
||||
|
||||
$this->entityStorage->expects($this->once())
|
||||
->method('getTableMapping')
|
||||
|
@ -492,6 +520,18 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
$relationship = $data['entity_test']['user_id']['relationship'];
|
||||
$this->assertEquals('users_field_data', $relationship['base']);
|
||||
$this->assertEquals('uid', $relationship['base field']);
|
||||
|
||||
$this->assertStringField($data['entity_test__string']['string']);
|
||||
$this->assertField($data['entity_test__string']['string'], 'string');
|
||||
$this->assertEquals([
|
||||
'left_field' => 'id',
|
||||
'field' => 'entity_id',
|
||||
'extra' => [[
|
||||
'field' => 'deleted',
|
||||
'value' => 0,
|
||||
'numeric' => TRUE,
|
||||
]],
|
||||
], $data['entity_test__string']['table']['join']['entity_test']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -529,10 +569,12 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
$this->viewsData->setEntityType($entity_type);
|
||||
|
||||
// Setup the table mapping.
|
||||
$table_mapping = $this->getMock('Drupal\Core\Entity\Sql\TableMappingInterface');
|
||||
$table_mapping = $this->getMockBuilder(DefaultTableMapping::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getTableNames')
|
||||
->willReturn(['entity_test_mul', 'entity_test_mul_property_data']);
|
||||
->willReturn(['entity_test_mul', 'entity_test_mul_property_data', 'entity_test_mul__string']);
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getColumnNames')
|
||||
->willReturnMap([
|
||||
|
@ -544,12 +586,14 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
['description', ['value' => 'description__value', 'format' => 'description__format']],
|
||||
['homepage', ['value' => 'homepage']],
|
||||
['user_id', ['target_id' => 'user_id']],
|
||||
['string', ['value' => 'value']],
|
||||
]);
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getFieldNames')
|
||||
->willReturnMap([
|
||||
['entity_test_mul', ['uuid']],
|
||||
['entity_test_mul_property_data', ['id', 'type', 'langcode', 'name', 'description', 'homepage', 'user_id']],
|
||||
['entity_test_mul__string', ['string']],
|
||||
]);
|
||||
|
||||
$table_mapping->expects($this->any())
|
||||
|
@ -560,6 +604,18 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
}
|
||||
return 'entity_test_mul_property_data';
|
||||
});
|
||||
$table_mapping->expects($this->any())
|
||||
->method('requiresDedicatedTableStorage')
|
||||
->willReturnCallback(function (BaseFieldDefinition $base_field) {
|
||||
return $base_field->getName() === 'string';
|
||||
});
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getDedicatedDataTableName')
|
||||
->willReturnCallback(function (BaseFieldDefinition $base_field) {
|
||||
if ($base_field->getName() === 'string') {
|
||||
return 'entity_test_mul__string';
|
||||
}
|
||||
});
|
||||
|
||||
$this->entityStorage->expects($this->once())
|
||||
->method('getTableMapping')
|
||||
|
@ -619,6 +675,18 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
$relationship = $data['entity_test_mul_property_data']['user_id']['relationship'];
|
||||
$this->assertEquals('users_field_data', $relationship['base']);
|
||||
$this->assertEquals('uid', $relationship['base field']);
|
||||
|
||||
$this->assertStringField($data['entity_test_mul__string']['string']);
|
||||
$this->assertField($data['entity_test_mul__string']['string'], 'string');
|
||||
$this->assertEquals([
|
||||
'left_field' => 'id',
|
||||
'field' => 'entity_id',
|
||||
'extra' => [[
|
||||
'field' => 'deleted',
|
||||
'value' => 0,
|
||||
'numeric' => TRUE,
|
||||
]],
|
||||
], $data['entity_test_mul__string']['table']['join']['entity_test_mul']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -650,10 +718,12 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
$this->viewsData->setEntityType($entity_type);
|
||||
|
||||
// Setup the table mapping.
|
||||
$table_mapping = $this->getMock('Drupal\Core\Entity\Sql\TableMappingInterface');
|
||||
$table_mapping = $this->getMockBuilder(DefaultTableMapping::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getTableNames')
|
||||
->willReturn(['entity_test_mulrev', 'entity_test_mulrev_revision', 'entity_test_mulrev_property_data', 'entity_test_mulrev_property_revision']);
|
||||
->willReturn(['entity_test_mulrev', 'entity_test_mulrev_revision', 'entity_test_mulrev_property_data', 'entity_test_mulrev_property_revision', 'entity_test_mulrev__string', 'entity_test_mulrev_revision__string']);
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getColumnNames')
|
||||
->willReturnMap([
|
||||
|
@ -666,6 +736,7 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
['homepage', ['value' => 'homepage']],
|
||||
['user_id', ['target_id' => 'user_id']],
|
||||
['revision_id', ['value' => 'id']],
|
||||
['string', ['value' => 'value']],
|
||||
]);
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getFieldNames')
|
||||
|
@ -674,7 +745,29 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
['entity_test_mulrev_revision', ['id', 'revision_id', 'langcode']],
|
||||
['entity_test_mulrev_property_data', ['id', 'revision_id', 'langcode', 'name', 'description', 'homepage', 'user_id']],
|
||||
['entity_test_mulrev_property_revision', ['id', 'revision_id', 'langcode', 'name', 'description', 'homepage', 'user_id']],
|
||||
['entity_test_mulrev__string', ['string']],
|
||||
['entity_test_mulrev_revision__string', ['string']],
|
||||
]);
|
||||
$table_mapping->expects($this->any())
|
||||
->method('requiresDedicatedTableStorage')
|
||||
->willReturnCallback(function (BaseFieldDefinition $base_field) {
|
||||
return $base_field->getName() === 'string';
|
||||
});
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getDedicatedDataTableName')
|
||||
->willReturnCallback(function (BaseFieldDefinition $base_field) {
|
||||
if ($base_field->getName() === 'string') {
|
||||
return 'entity_test_mulrev__string';
|
||||
}
|
||||
});
|
||||
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getDedicatedRevisionTableName')
|
||||
->willReturnCallback(function (BaseFieldDefinition $base_field) {
|
||||
if ($base_field->getName() === 'string') {
|
||||
return 'entity_test_mulrev_revision__string';
|
||||
}
|
||||
});
|
||||
|
||||
$table_mapping->expects($this->any())
|
||||
->method('getFieldTableName')
|
||||
|
@ -767,6 +860,30 @@ class EntityViewsDataTest extends UnitTestCase {
|
|||
$relationship = $data['entity_test_mulrev_property_revision']['user_id']['relationship'];
|
||||
$this->assertEquals('users_field_data', $relationship['base']);
|
||||
$this->assertEquals('uid', $relationship['base field']);
|
||||
|
||||
$this->assertStringField($data['entity_test_mulrev__string']['string']);
|
||||
$this->assertField($data['entity_test_mulrev__string']['string'], 'string');
|
||||
$this->assertEquals([
|
||||
'left_field' => 'id',
|
||||
'field' => 'entity_id',
|
||||
'extra' => [[
|
||||
'field' => 'deleted',
|
||||
'value' => 0,
|
||||
'numeric' => TRUE,
|
||||
]],
|
||||
], $data['entity_test_mulrev__string']['table']['join']['entity_test_mulrev_property_data']);
|
||||
|
||||
$this->assertStringField($data['entity_test_mulrev_revision__string']['string']);
|
||||
$this->assertField($data['entity_test_mulrev_revision__string']['string'], 'string');
|
||||
$this->assertEquals([
|
||||
'left_field' => 'revision_id',
|
||||
'field' => 'entity_id',
|
||||
'extra' => [[
|
||||
'field' => 'deleted',
|
||||
'value' => 0,
|
||||
'numeric' => TRUE,
|
||||
]],
|
||||
], $data['entity_test_mulrev_revision__string']['table']['join']['entity_test_mulrev_property_revision']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,9 +2,18 @@
|
|||
|
||||
namespace Drupal\Tests\views\Unit\Plugin\query;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\EntityType;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\views\Plugin\views\query\Sql;
|
||||
use Drupal\views\Plugin\views\relationship\RelationshipPluginBase;
|
||||
use Drupal\views\ResultRow;
|
||||
use Drupal\views\ViewEntityInterface;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\ViewsData;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\views\Plugin\views\query\Sql
|
||||
|
@ -19,8 +28,9 @@ class SqlTest extends UnitTestCase {
|
|||
*/
|
||||
public function testGetCacheTags() {
|
||||
$view = $this->prophesize('Drupal\views\ViewExecutable')->reveal();
|
||||
$entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
|
||||
|
||||
$query = new Sql([], 'sql', []);
|
||||
$query = new Sql([], 'sql', [], $entity_type_manager->reveal());
|
||||
$query->view = $view;
|
||||
|
||||
$result = [];
|
||||
|
@ -64,8 +74,9 @@ class SqlTest extends UnitTestCase {
|
|||
*/
|
||||
public function testGetCacheMaxAge() {
|
||||
$view = $this->prophesize('Drupal\views\ViewExecutable')->reveal();
|
||||
$entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
|
||||
|
||||
$query = new Sql([], 'sql', []);
|
||||
$query = new Sql([], 'sql', [], $entity_type_manager->reveal());
|
||||
$query->view = $view;
|
||||
|
||||
$view->result = [];
|
||||
|
@ -98,4 +109,427 @@ class SqlTest extends UnitTestCase {
|
|||
$this->assertEquals(10, $query->getCacheMaxAge());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the views data in the container.
|
||||
*
|
||||
* @param \Drupal\views\ViewsData $views_data
|
||||
* The views data.
|
||||
*/
|
||||
protected function setupViewsData(ViewsData $views_data) {
|
||||
$container = \Drupal::hasContainer() ? \Drupal::getContainer() : new ContainerBuilder();
|
||||
$container->set('views.views_data', $views_data);
|
||||
\Drupal::setContainer($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the entity type manager in the container.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||
* The entity type manager.
|
||||
*/
|
||||
protected function setupEntityTypeManager(EntityTypeManagerInterface $entity_type_manager) {
|
||||
$container = \Drupal::hasContainer() ? \Drupal::getContainer() : new ContainerBuilder();
|
||||
$container->set('entity_type.manager', $entity_type_manager);
|
||||
$container->set('entity.manager', $entity_type_manager);
|
||||
\Drupal::setContainer($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up some test entity types and corresponding views data.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface[][] $entities_by_type
|
||||
* Test entities keyed by entity type and entity ID.
|
||||
* @param \Drupal\Core\Entity\EntityInterface[][] $entities_by_type
|
||||
* Test entities keyed by entity type and revision ID.
|
||||
*
|
||||
* @return \Prophecy\Prophecy\ObjectProphecy
|
||||
*/
|
||||
protected function setupEntityTypes($entities_by_type = [], $entity_revisions_by_type = []) {
|
||||
$entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
|
||||
$entity_type0 = new EntityType([
|
||||
'label' => 'First',
|
||||
'id' => 'first',
|
||||
'base_table' => 'entity_first',
|
||||
'revision_table' => 'entity_first__revision',
|
||||
'entity_keys' => [
|
||||
'id' => 'id',
|
||||
'revision' => 'vid',
|
||||
],
|
||||
]);
|
||||
$entity_type1 = new EntityType([
|
||||
'label' => 'second',
|
||||
'id' => 'second',
|
||||
'base_table' => 'entity_second',
|
||||
'revision_table' => 'entity_second__revision',
|
||||
'entity_keys' => [
|
||||
'id' => 'id',
|
||||
'revision' => 'vid',
|
||||
],
|
||||
]);
|
||||
|
||||
$entity_type_manager->getDefinitions()->willReturn([
|
||||
'first' => $entity_type0,
|
||||
'second' => $entity_type1,
|
||||
'base_table' => 'entity_second',
|
||||
]);
|
||||
|
||||
$entity_type_manager->getDefinition('first')->willReturn($entity_type0);
|
||||
$entity_type_manager->getDefinition('second')->willReturn($entity_type1);
|
||||
|
||||
// Setup the views data corresponding to the entity types.
|
||||
$views_data = $this->prophesize(ViewsData::class);
|
||||
$views_data->get('entity_first')->willReturn([
|
||||
'table' => [
|
||||
'entity type' => 'first',
|
||||
'entity revision' => FALSE,
|
||||
],
|
||||
]);
|
||||
$views_data->get('entity_first__revision')->willReturn([
|
||||
'table' => [
|
||||
'entity type' => 'first',
|
||||
'entity revision' => TRUE,
|
||||
],
|
||||
]);
|
||||
$views_data->get('entity_second')->willReturn([
|
||||
'table' => [
|
||||
'entity type' => 'second',
|
||||
'entity revision' => FALSE,
|
||||
],
|
||||
]);
|
||||
$views_data->get('entity_second__revision')->willReturn([
|
||||
'table' => [
|
||||
'entity type' => 'second',
|
||||
'entity revision' => TRUE,
|
||||
],
|
||||
]);
|
||||
$this->setupViewsData($views_data->reveal());
|
||||
|
||||
// Setup the loading of entities and entity revisions.
|
||||
$entity_storages = [
|
||||
'first' => $this->prophesize(EntityStorageInterface::class),
|
||||
'second' => $this->prophesize(EntityStorageInterface::class),
|
||||
];
|
||||
|
||||
foreach ($entities_by_type as $entity_type_id => $entities) {
|
||||
foreach ($entities as $entity_id => $entity) {
|
||||
$entity_storages[$entity_type_id]->load($entity_id)->willReturn($entity);
|
||||
}
|
||||
$entity_storages[$entity_type_id]->loadMultiple(array_keys($entities))->willReturn($entities);
|
||||
}
|
||||
|
||||
foreach ($entity_revisions_by_type as $entity_type_id => $entity_revisions) {
|
||||
foreach ($entity_revisions as $revision_id => $revision) {
|
||||
$entity_storages[$entity_type_id]->loadRevision($revision_id)->willReturn($revision);
|
||||
}
|
||||
}
|
||||
|
||||
$entity_type_manager->getStorage('first')->willReturn($entity_storages['first']);
|
||||
$entity_type_manager->getStorage('second')->willReturn($entity_storages['second']);
|
||||
|
||||
$this->setupEntityTypeManager($entity_type_manager->reveal());
|
||||
|
||||
return $entity_type_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::loadEntities
|
||||
* @covers ::_assignEntitiesToResult
|
||||
*/
|
||||
public function testLoadEntitiesWithEmptyResult() {
|
||||
$view = $this->prophesize('Drupal\views\ViewExecutable')->reveal();
|
||||
$view_entity = $this->prophesize(ViewEntityInterface::class);
|
||||
$view_entity->get('base_table')->willReturn('entity_first');
|
||||
$view_entity->get('base_field')->willReturn('id');
|
||||
$view->storage = $view_entity->reveal();
|
||||
|
||||
$entity_type_manager = $this->setupEntityTypes();
|
||||
|
||||
$query = new Sql([], 'sql', [], $entity_type_manager->reveal());
|
||||
$query->view = $view;
|
||||
|
||||
$result = [];
|
||||
$query->addField('entity_first', 'id', 'id');
|
||||
$query->loadEntities($result);
|
||||
$this->assertEmpty($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::loadEntities
|
||||
* @covers ::_assignEntitiesToResult
|
||||
*/
|
||||
public function testLoadEntitiesWithNoRelationshipAndNoRevision() {
|
||||
$view = $this->prophesize('Drupal\views\ViewExecutable')->reveal();
|
||||
$view_entity = $this->prophesize(ViewEntityInterface::class);
|
||||
$view_entity->get('base_table')->willReturn('entity_first');
|
||||
$view_entity->get('base_field')->willReturn('id');
|
||||
$view->storage = $view_entity->reveal();
|
||||
|
||||
$entities = [
|
||||
'first' => [
|
||||
1 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
2 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
],
|
||||
];
|
||||
$entity_type_manager = $this->setupEntityTypes($entities);
|
||||
|
||||
$query = new Sql([], 'sql', [], $entity_type_manager->reveal());
|
||||
$query->view = $view;
|
||||
|
||||
$result = [];
|
||||
$result[] = new ResultRow([
|
||||
'id' => 1,
|
||||
]);
|
||||
// Note: Let the same entity be returned multiple times, for example to
|
||||
// support the translation usecase.
|
||||
$result[] = new ResultRow([
|
||||
'id' => 2,
|
||||
]);
|
||||
$result[] = new ResultRow([
|
||||
'id' => 2,
|
||||
]);
|
||||
|
||||
$query->addField('entity_first', 'id', 'id');
|
||||
$query->loadEntities($result);
|
||||
|
||||
$this->assertSame($entities['first'][1], $result[0]->_entity);
|
||||
$this->assertSame($entities['first'][2], $result[1]->_entity);
|
||||
$this->assertSame($entities['first'][2], $result[2]->_entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a view with a relationship.
|
||||
*/
|
||||
protected function setupViewWithRelationships(ViewExecutable $view, $base = 'entity_second') {
|
||||
// We don't use prophecy, because prophecy enforces methods.
|
||||
$relationship = $this->getMockBuilder(RelationshipPluginBase::class)->disableOriginalConstructor()->getMock();
|
||||
$relationship->definition['base'] = $base;
|
||||
$relationship->tableAlias = $base;
|
||||
$relationship->alias = $base;
|
||||
|
||||
$view->relationship[$base] = $relationship;
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::loadEntities
|
||||
* @covers ::_assignEntitiesToResult
|
||||
*/
|
||||
public function testLoadEntitiesWithRelationship() {
|
||||
// We don't use prophecy, because prophecy enforces methods.
|
||||
$view = $this->getMockBuilder(ViewExecutable::class)->disableOriginalConstructor()->getMock();
|
||||
$this->setupViewWithRelationships($view);
|
||||
|
||||
$view_entity = $this->prophesize(ViewEntityInterface::class);
|
||||
$view_entity->get('base_table')->willReturn('entity_first');
|
||||
$view_entity->get('base_field')->willReturn('id');
|
||||
$view->storage = $view_entity->reveal();
|
||||
|
||||
$entities = [
|
||||
'first' => [
|
||||
1 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
2 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
],
|
||||
'second' => [
|
||||
11 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
12 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
],
|
||||
];
|
||||
$entity_type_manager = $this->setupEntityTypes($entities);
|
||||
|
||||
$query = new Sql([], 'sql', [], $entity_type_manager->reveal());
|
||||
$query->view = $view;
|
||||
|
||||
$result = [];
|
||||
$result[] = new ResultRow([
|
||||
'id' => 1,
|
||||
'entity_second__id' => 11,
|
||||
]);
|
||||
// Provide an explicit NULL value, to test the case of a non required
|
||||
// relationship.
|
||||
$result[] = new ResultRow([
|
||||
'id' => 2,
|
||||
'entity_second__id' => NULL,
|
||||
]);
|
||||
$result[] = new ResultRow([
|
||||
'id' => 2,
|
||||
'entity_second__id' => 12,
|
||||
]);
|
||||
|
||||
$query->addField('entity_first', 'id', 'id');
|
||||
$query->addField('entity_second', 'id', 'entity_second__id');
|
||||
$query->loadEntities($result);
|
||||
|
||||
$this->assertSame($entities['first'][1], $result[0]->_entity);
|
||||
$this->assertSame($entities['first'][2], $result[1]->_entity);
|
||||
$this->assertSame($entities['first'][2], $result[2]->_entity);
|
||||
|
||||
$this->assertSame($entities['second'][11], $result[0]->_relationship_entities['entity_second']);
|
||||
$this->assertEquals([], $result[1]->_relationship_entities);
|
||||
$this->assertSame($entities['second'][12], $result[2]->_relationship_entities['entity_second']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::loadEntities
|
||||
* @covers ::_assignEntitiesToResult
|
||||
*/
|
||||
public function testLoadEntitiesWithRevision() {
|
||||
// We don't use prophecy, because prophecy enforces methods.
|
||||
$view = $this->getMockBuilder(ViewExecutable::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$view_entity = $this->prophesize(ViewEntityInterface::class);
|
||||
$view_entity->get('base_table')->willReturn('entity_first__revision');
|
||||
$view_entity->get('base_field')->willReturn('vid');
|
||||
$view->storage = $view_entity->reveal();
|
||||
|
||||
$entity_revisions = [
|
||||
'first' => [
|
||||
1 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
3 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
],
|
||||
];
|
||||
$entity_type_manager = $this->setupEntityTypes([], $entity_revisions);
|
||||
|
||||
$query = new Sql([], 'sql', [], $entity_type_manager->reveal());
|
||||
$query->view = $view;
|
||||
|
||||
$result = [];
|
||||
$result[] = new ResultRow([
|
||||
'vid' => 1,
|
||||
]);
|
||||
$result[] = new ResultRow([
|
||||
'vid' => 1,
|
||||
]);
|
||||
$result[] = new ResultRow([
|
||||
'vid' => 3,
|
||||
]);
|
||||
|
||||
$query->addField('entity_first__revision', 'vid', 'vid');
|
||||
$query->loadEntities($result);
|
||||
|
||||
$this->assertSame($entity_revisions['first'][1], $result[0]->_entity);
|
||||
$this->assertSame($entity_revisions['first'][1], $result[1]->_entity);
|
||||
$this->assertSame($entity_revisions['first'][3], $result[2]->_entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::loadEntities
|
||||
* @covers ::_assignEntitiesToResult
|
||||
*/
|
||||
public function testLoadEntitiesWithRevisionOfSameEntityType() {
|
||||
// We don't use prophecy, because prophecy enforces methods.
|
||||
$view = $this->getMockBuilder(ViewExecutable::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->setupViewWithRelationships($view, 'entity_first__revision');
|
||||
|
||||
$view_entity = $this->prophesize(ViewEntityInterface::class);
|
||||
$view_entity->get('base_table')->willReturn('entity_first');
|
||||
$view_entity->get('base_field')->willReturn('id');
|
||||
$view->storage = $view_entity->reveal();
|
||||
|
||||
$entity = [
|
||||
'first' => [
|
||||
1 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
2 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
],
|
||||
];
|
||||
$entity_revisions = [
|
||||
'first' => [
|
||||
1 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
2 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
3 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
],
|
||||
];
|
||||
$entity_type_manager = $this->setupEntityTypes($entity, $entity_revisions);
|
||||
|
||||
$query = new Sql([], 'sql', [], $entity_type_manager->reveal());
|
||||
$query->view = $view;
|
||||
|
||||
$result = [];
|
||||
$result[] = new ResultRow([
|
||||
'id' => 1,
|
||||
'entity_first__revision__vid' => 1,
|
||||
]);
|
||||
$result[] = new ResultRow([
|
||||
'id' => 2,
|
||||
'entity_first__revision__vid' => 2,
|
||||
]);
|
||||
$result[] = new ResultRow([
|
||||
'id' => 2,
|
||||
'entity_first__revision__vid' => 3,
|
||||
]);
|
||||
|
||||
$query->addField('entity_first', 'id', 'id');
|
||||
$query->addField('entity_first__revision', 'vid', 'entity_first__revision__vid');
|
||||
$query->loadEntities($result);
|
||||
|
||||
$this->assertSame($entity['first'][1], $result[0]->_entity);
|
||||
$this->assertSame($entity['first'][2], $result[1]->_entity);
|
||||
$this->assertSame($entity['first'][2], $result[2]->_entity);
|
||||
$this->assertSame($entity_revisions['first'][1], $result[0]->_relationship_entities['entity_first__revision']);
|
||||
$this->assertSame($entity_revisions['first'][2], $result[1]->_relationship_entities['entity_first__revision']);
|
||||
$this->assertSame($entity_revisions['first'][3], $result[2]->_relationship_entities['entity_first__revision']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::loadEntities
|
||||
* @covers ::_assignEntitiesToResult
|
||||
*/
|
||||
public function testLoadEntitiesWithRelationshipAndRevision() {
|
||||
// We don't use prophecy, because prophecy enforces methods.
|
||||
$view = $this->getMockBuilder(ViewExecutable::class)->disableOriginalConstructor()->getMock();
|
||||
$this->setupViewWithRelationships($view);
|
||||
|
||||
$view_entity = $this->prophesize(ViewEntityInterface::class);
|
||||
$view_entity->get('base_table')->willReturn('entity_first__revision');
|
||||
$view_entity->get('base_field')->willReturn('vid');
|
||||
$view->storage = $view_entity->reveal();
|
||||
|
||||
$entities = [
|
||||
'second' => [
|
||||
11 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
12 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
],
|
||||
];
|
||||
$entity_revisions = [
|
||||
'first' => [
|
||||
1 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
3 => $this->prophesize(EntityInterface::class)->reveal(),
|
||||
],
|
||||
];
|
||||
$entity_type_manager = $this->setupEntityTypes($entities, $entity_revisions);
|
||||
|
||||
$query = new Sql([], 'sql', [], $entity_type_manager->reveal());
|
||||
$query->view = $view;
|
||||
|
||||
$result = [];
|
||||
$result[] = new ResultRow([
|
||||
'vid' => 1,
|
||||
'entity_second__id' => 11,
|
||||
]);
|
||||
// Provide an explicit NULL value, to test the case of a non required
|
||||
// relationship.
|
||||
$result[] = new ResultRow([
|
||||
'vid' => 1,
|
||||
'entity_second__id' => NULL,
|
||||
]);
|
||||
$result[] = new ResultRow([
|
||||
'vid' => 3,
|
||||
'entity_second__id' => 12,
|
||||
]);
|
||||
|
||||
$query->addField('entity_first__revision', 'vid', 'vid');
|
||||
$query->addField('entity_second', 'id', 'entity_second__id');
|
||||
$query->loadEntities($result);
|
||||
|
||||
$this->assertSame($entity_revisions['first'][1], $result[0]->_entity);
|
||||
$this->assertSame($entity_revisions['first'][1], $result[1]->_entity);
|
||||
$this->assertSame($entity_revisions['first'][3], $result[2]->_entity);
|
||||
|
||||
$this->assertSame($entities['second'][11], $result[0]->_relationship_entities['entity_second']);
|
||||
$this->assertEquals([], $result[1]->_relationship_entities);
|
||||
$this->assertSame($entities['second'][12], $result[2]->_relationship_entities['entity_second']);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -360,6 +360,35 @@ function views_update_8005() {
|
|||
// Empty update function to rebuild the views data.
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear caches due to updated entity views data.
|
||||
*/
|
||||
function views_update_8100() {
|
||||
// Empty update to cause a cache flush so that views data is rebuilt.
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default values for enabled/expanded flag on page displays.
|
||||
*/
|
||||
function views_update_8101() {
|
||||
$config_factory = \Drupal::configFactory();
|
||||
foreach ($config_factory->listAll('views.view.') as $view_config_name) {
|
||||
$view = $config_factory->getEditable($view_config_name);
|
||||
$save = FALSE;
|
||||
foreach ($view->get('display') as $display_id => $display) {
|
||||
if ($display['display_plugin'] == 'page') {
|
||||
$display['display_options']['menu']['enabled'] = TRUE;
|
||||
$display['display_options']['menu']['expanded'] = FALSE;
|
||||
$view->set("display.$display_id", $display);
|
||||
$save = TRUE;
|
||||
}
|
||||
}
|
||||
if ($save) {
|
||||
$view->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup updates-8.1.0".
|
||||
*/
|
||||
|
|
Reference in a new issue