Update to Drupal 8.0.3. For more information, see https://www.drupal.org/drupal-8.0.3-release-notes

This commit is contained in:
Pantheon Automation 2016-02-03 14:56:31 -08:00 committed by Greg Anderson
parent 10f9f7fbde
commit 9db4fae9a7
202 changed files with 3806 additions and 760 deletions

View file

@ -12,6 +12,8 @@ use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\EventSubscriber\AjaxResponseSubscriber;
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Path\CurrentPathStack;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\RenderContext;
@ -161,7 +163,15 @@ class ViewAjaxController implements ContainerInjectionInterface {
// Overwrite the destination.
// @see the redirect.destination service.
$origin_destination = $path;
$query = UrlHelper::buildQuery($request->query->all());
// Remove some special parameters you never want to have part of the
// destination query.
$used_query_parameters = $request->query->all();
// @todo Remove this parsing once these are removed from the request in
// https://www.drupal.org/node/2504709.
unset($used_query_parameters[FormBuilderInterface::AJAX_FORM_REQUEST], $used_query_parameters[MainContentViewSubscriber::WRAPPER_FORMAT], $used_query_parameters['ajax_page_state']);
$query = UrlHelper::buildQuery($used_query_parameters);
if ($query != '') {
$origin_destination .= '?' . $query;
}

View file

@ -236,7 +236,7 @@ class ManyToOneHelper {
$join = $this->getJoin();
$join->type = 'LEFT';
$join->extra = array();
$join->extra_type = 'OR';
$join->extraOperator = 'OR';
foreach ($this->handler->value as $value) {
$join->extra[] = array(
'field' => $this->handler->realField,
@ -311,10 +311,21 @@ class ManyToOneHelper {
$placeholder = $this->placeholder();
if (count($this->handler->value) > 1) {
$placeholder .= '[]';
$this->handler->query->addWhereExpression(0, "$field $operator($placeholder)", array($placeholder => $value));
if ($operator == 'IS NULL') {
$this->handler->query->addWhereExpression(0, "$field $operator");
}
else {
$this->handler->query->addWhereExpression(0, "$field $operator($placeholder)", array($placeholder => $value));
}
}
else {
$this->handler->query->addWhereExpression(0, "$field $operator $placeholder", array($placeholder => $value));
if ($operator == 'IS NULL') {
$this->handler->query->addWhereExpression(0, "$field $operator");
}
else {
$this->handler->query->addWhereExpression(0, "$field $operator $placeholder", array($placeholder => $value));
}
}
}
}

View file

@ -2335,13 +2335,17 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
'#cache_properties' => ['#view_id', '#view_display_show_admin_links', '#view_display_plugin_id'],
];
// When something passes $cache = FALSE, they're asking us not to create our
// own render cache for it. However, we still need to include certain pieces
// of cacheability metadata (e.g.: cache contexts), so they can bubble up.
// Thus, we add the cacheability metadata first, then modify / remove the
// cache keys depending on the $cache argument.
$this->applyDisplayCachablityMetadata($this->view->element);
if ($cache) {
$this->view->element['#cache'] += ['keys' => []];
// Places like \Drupal\views\ViewExecutable::setCurrentPage() set up an
// additional cache context.
$this->view->element['#cache']['keys'] = array_merge(['views', 'display', $this->view->element['#name'], $this->view->element['#display_id']], $this->view->element['#cache']['keys']);
$this->applyDisplayCachablityMetadata($this->view->element);
}
else {
// Remove the cache keys, to ensure render caching is not triggered. We

View file

@ -138,7 +138,8 @@ class EntityReference extends DisplayPluginBase {
foreach ($style_options['options']['search_fields'] as $field_id) {
if (!empty($field_id)) {
// Get the table and field names for the checked field.
$field_alias = $this->view->query->addField($this->view->field[$field_id]->table, $field_id);
$field_handler = $this->view->field[$field_id];
$field_alias = $this->view->query->addField($field_handler->table, $field_handler->realField);
$field = $this->view->query->fields[$field_alias];
// Add an OR condition for the field.
$conditions->condition($field['table'] . '.' . $field['field'], $value, 'LIKE');

View file

@ -22,6 +22,7 @@ use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\Element;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\views\FieldAPIHandlerTrait;
use Drupal\views\Entity\Render\EntityFieldRenderer;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
@ -820,9 +821,10 @@ class Field extends FieldPluginBase implements CacheableDependencyInterface, Mul
'settings' => $this->options['settings'],
'label' => 'hidden',
];
$build_list = $this->createEntityForGroupBy($this->getEntity($values), $values)
->{$this->definition['field_name']}
->view($display);
// Some bundles might not have a specific field, in which case the faked
// entity doesn't have it either.
$entity = $this->createEntityForGroupBy($this->getEntity($values), $values);
$build_list = isset($entity->{$this->definition['field_name']}) ? $entity->{$this->definition['field_name']}->view($display) : NULL;
}
if (!$build_list) {
@ -932,8 +934,10 @@ class Field extends FieldPluginBase implements CacheableDependencyInterface, Mul
if (is_object($raw)) {
$property = $raw->get($id);
if (!empty($property)) {
$tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($property->getValue());
// Check if TypedDataInterface is implemented so we know how to render
// the item as a string.
if (!empty($property) && $property instanceof TypedDataInterface) {
$tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($property->getString());
}
else {
// Make sure that empty values are replaced as well.
@ -1002,8 +1006,17 @@ class Field extends FieldPluginBase implements CacheableDependencyInterface, Mul
* {@inheritdoc}
*/
public function getValue(ResultRow $values, $field = NULL) {
$entity = $this->getEntity($values);
// Some bundles might not have a specific field, in which case the entity
// (potentially a fake one) doesn't have it either.
/** @var \Drupal\Core\Field\FieldItemListInterface $field_item_list */
$field_item_list = $this->getEntity($values)->{$this->definition['field_name']};
$field_item_list = isset($entity->{$this->definition['field_name']}) ? $entity->{$this->definition['field_name']} : NULL;
if (!isset($field_item_list)) {
// There isn't anything we can do without a valid field.
return NULL;
}
$field_item_definition = $field_item_list->getFieldDefinition();
if ($field_item_definition->getFieldStorageDefinition()->getCardinality() == 1) {

View file

@ -482,9 +482,17 @@ abstract class StylePluginBase extends PluginBase {
* grouping.
*
* @param $sets
* Array containing the grouping sets to render.
* An array keyed by group content containing the grouping sets to render.
* Each set contains the following associative array:
* - group: The group content.
* - level: The hierarchical level of the grouping.
* - rows: The result rows to be rendered in this group..
* @param $level
* Integer indicating the hierarchical level of the grouping.
* (deprecated) This is no longer used and will be removed in Drupal 9. The
* 'level' key in $sets is used to indicate the hierarchical level of the
* grouping.
*
* @todo Remove the $level parameter in https://www.drupal.org/node/2633890.
*
* @return string
* Rendered output of given grouping sets.
@ -493,16 +501,16 @@ abstract class StylePluginBase extends PluginBase {
$output = array();
$theme_functions = $this->view->buildThemeFunctions($this->groupingTheme);
foreach ($sets as $set) {
$level = isset($set['level']) ? $set['level'] : 0;
$row = reset($set['rows']);
// Render as a grouping set.
if (is_array($row) && isset($row['group'])) {
$output[] = array(
$single_output = array(
'#theme' => $theme_functions,
'#view' => $this->view,
'#grouping' => $this->options['grouping'][$level],
'#grouping_level' => $level,
'#rows' => $set['rows'],
'#title' => $set['group'],
);
}
// Render as a record set.
@ -515,10 +523,11 @@ abstract class StylePluginBase extends PluginBase {
}
$single_output = $this->renderRowGroup($set['rows']);
$single_output['#grouping_level'] = $level;
$single_output['#title'] = $set['group'];
$output[] = $single_output;
}
$single_output['#grouping_level'] = $level;
$single_output['#title'] = $set['group'];
$output[] = $single_output;
}
unset($this->view->row_index);
return $output;
@ -546,9 +555,11 @@ abstract class StylePluginBase extends PluginBase {
* array(
* 'grouping_field_1:grouping_1' => array(
* 'group' => 'grouping_field_1:content_1',
* 'level' => 0,
* 'rows' => array(
* 'grouping_field_2:grouping_a' => array(
* 'group' => 'grouping_field_2:content_a',
* 'level' => 1,
* 'rows' => array(
* $row_index_1 => $row_1,
* $row_index_2 => $row_2,
@ -580,7 +591,7 @@ abstract class StylePluginBase extends PluginBase {
// hierarchically positioned set where the current row belongs to.
// While iterating, parent groups, that do not exist yet, are added.
$set = &$sets;
foreach ($groupings as $info) {
foreach ($groupings as $level => $info) {
$field = $info['field'];
$rendered = isset($info['rendered']) ? $info['rendered'] : $group_rendered;
$rendered_strip = isset($info['rendered_strip']) ? $info['rendered_strip'] : FALSE;
@ -613,6 +624,7 @@ abstract class StylePluginBase extends PluginBase {
// Create the group if it does not exist yet.
if (empty($set[$grouping])) {
$set[$grouping]['group'] = $group_content;
$set[$grouping]['level'] = $level;
$set[$grouping]['rows'] = array();
}

View file

@ -84,4 +84,15 @@ class CacheWebTest extends PluginTestBase {
$this->assertCacheTags($cache_tags);
}
/**
* Tests that a display without caching still contains the cache metadata.
*/
public function testDisplayWithoutCacheStillBubblesMetadata() {
$view = Views::getView('test_display');
$uncached_block = $view->buildRenderable('block_1', [], FALSE);
$cached_block = $view->buildRenderable('block_1', [], TRUE);
$this->assertEqual($uncached_block['#cache']['contexts'], $cached_block['#cache']['contexts'], 'Cache contexts are the same when you render the view cached and uncached.');
}
}

View file

@ -0,0 +1,134 @@
<?php
/**
* @file
* Contains \Drupal\views\Tests\Plugin\DisplayEntityReferenceTest.
*/
namespace Drupal\views\Tests\Plugin;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\views\Views;
/**
* Tests the entity reference display plugin.
*
* @group views
*
* @see \Drupal\views\Plugin\views\display\EntityReference
*/
class DisplayEntityReferenceTest extends PluginTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array('test_display_entity_reference');
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('entity_test', 'field', 'views_ui');
/**
* The used field name in the test.
*
* @var string
*/
protected $fieldName;
/**
* The field storage.
*
* @var \Drupal\field\Entity\FieldStorageConfig
*/
protected $fieldStorage;
/**
* The field config.
*
* @var \Drupal\field\Entity\FieldConfig
*/
protected $field;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->drupalLogin($this->drupalCreateUser(array('administer views')));
// Create the text field.
$this->fieldName = 'field_test_entity_ref_display';
$this->fieldStorage = FieldStorageConfig::create([
'field_name' => $this->fieldName,
'entity_type' => 'entity_test',
'type' => 'text',
]);
$this->fieldStorage->save();
// Create an instance of the text field on the content type.
$this->field = FieldConfig::create([
'field_storage' => $this->fieldStorage,
'bundle' => 'entity_test',
]);
$this->field->save();
// Create some entities to search. Add a common string to the name and
// the text field in two entities so we can test that we can search in both.
for ($i = 0; $i < 5; $i++) {
EntityTest::create([
'bundle' => 'entity_test',
'name' => 'name' . $i,
$this->fieldName => 'text',
])->save();
EntityTest::create([
'bundle' => 'entity_test',
'name' => 'name',
$this->fieldName => 'text' . $i,
])->save();
}
}
/**
* Tests the entity reference display plugin.
*/
public function testEntityReferenceDisplay() {
// Add the new field to the fields.
$this->drupalPostForm('admin/structure/views/nojs/add-handler/test_display_entity_reference/default/field', ['name[entity_test__' . $this->fieldName . '.' . $this->fieldName . ']' => TRUE], t('Add and configure fields'));
$this->drupalPostForm(NULL, [], t('Apply'));
// Test that the right fields are shown on the display settings form.
$this->drupalGet('admin/structure/views/nojs/display/test_display_entity_reference/entity_reference_1/style_options');
$this->assertText('Test entity: Name');
$this->assertText('Test entity: ' . $this->field->label());
// Add the new field to the search fields.
$this->drupalPostForm(NULL, ['style_options[search_fields][' . $this->fieldName . ']' => $this->fieldName], t('Apply'));
$this->drupalPostForm(NULL, [], t('Save'));
$view = Views::getView('test_display_entity_reference');
$view->setDisplay('entity_reference_1');
// Add the required settings to test a search operation.
$options = [
'match' => '1',
'match_operator' => 'CONTAINS',
'limit' => 0,
'ids' => NULL,
];
$view->display_handler->setOption('entity_reference_options', $options);
$this->executeView($view);
// Test that we have searched in both fields.
$this->assertEqual(count($view->result), 2, 'Search returned two rows');
}
}

View file

@ -149,8 +149,10 @@ class StyleTest extends ViewTestBase {
$expected = array();
$expected['Job: Singer'] = array();
$expected['Job: Singer']['group'] = 'Job: Singer';
$expected['Job: Singer']['level'] = 0;
$expected['Job: Singer']['rows']['Age: 25'] = array();
$expected['Job: Singer']['rows']['Age: 25']['group'] = 'Age: 25';
$expected['Job: Singer']['rows']['Age: 25']['level'] = 1;
$expected['Job: Singer']['rows']['Age: 25']['rows'][0] = new ResultRow(['index' => 0]);
$expected['Job: Singer']['rows']['Age: 25']['rows'][0]->views_test_data_name = 'John';
$expected['Job: Singer']['rows']['Age: 25']['rows'][0]->views_test_data_job = 'Singer';
@ -158,6 +160,7 @@ class StyleTest extends ViewTestBase {
$expected['Job: Singer']['rows']['Age: 25']['rows'][0]->views_test_data_id = '1';
$expected['Job: Singer']['rows']['Age: 27'] = array();
$expected['Job: Singer']['rows']['Age: 27']['group'] = 'Age: 27';
$expected['Job: Singer']['rows']['Age: 27']['level'] = 1;
$expected['Job: Singer']['rows']['Age: 27']['rows'][1] = new ResultRow(['index' => 1]);
$expected['Job: Singer']['rows']['Age: 27']['rows'][1]->views_test_data_name = 'George';
$expected['Job: Singer']['rows']['Age: 27']['rows'][1]->views_test_data_job = 'Singer';
@ -165,8 +168,10 @@ class StyleTest extends ViewTestBase {
$expected['Job: Singer']['rows']['Age: 27']['rows'][1]->views_test_data_id = '2';
$expected['Job: Drummer'] = array();
$expected['Job: Drummer']['group'] = 'Job: Drummer';
$expected['Job: Drummer']['level'] = 0;
$expected['Job: Drummer']['rows']['Age: 28'] = array();
$expected['Job: Drummer']['rows']['Age: 28']['group'] = 'Age: 28';
$expected['Job: Drummer']['rows']['Age: 28']['level'] = 1;
$expected['Job: Drummer']['rows']['Age: 28']['rows'][2] = new ResultRow(['index' => 2]);
$expected['Job: Drummer']['rows']['Age: 28']['rows'][2]->views_test_data_name = 'Ringo';
$expected['Job: Drummer']['rows']['Age: 28']['rows'][2]->views_test_data_job = 'Drummer';

View file

@ -25,7 +25,7 @@ class QueryGroupByTest extends ViewKernelTestBase {
*
* @var array
*/
public static $testViews = array('test_group_by_in_filters', 'test_aggregate_count', 'test_group_by_count', 'test_group_by_count_multicardinality');
public static $testViews = array('test_group_by_in_filters', 'test_aggregate_count', 'test_group_by_count', 'test_group_by_count_multicardinality', 'test_group_by_field_not_within_bundle');
/**
* Modules to enable.
@ -292,4 +292,48 @@ class QueryGroupByTest extends ViewKernelTestBase {
$this->assertEqual('6', $view->getStyle()->getField(5, 'field_test'));
}
/**
* Tests groupby with a field not existing on some bundle.
*/
public function testGroupByWithFieldsNotExistingOnBundle() {
$field_storage = FieldStorageConfig::create([
'type' => 'integer',
'field_name' => 'field_test',
'cardinality' => 4,
'entity_type' => 'entity_test_mul',
]);
$field_storage->save();
$field = FieldConfig::create([
'field_name' => 'field_test',
'entity_type' => 'entity_test_mul',
'bundle' => 'entity_test_mul',
]);
$field->save();
$entities = [];
$entity = EntityTestMul::create([
'field_test' => [1],
'type' => 'entity_test_mul',
]);
$entity->save();
$entities[] = $entity;
$entity = EntityTestMul::create([
'type' => 'entity_test_mul2',
]);
$entity->save();
$entities[] = $entity;
$view = Views::getView('test_group_by_field_not_within_bundle');
$this->executeView($view);
$this->assertEqual(2, count($view->result));
// The first result is coming from entity_test_mul2, so no field could be
// rendered.
$this->assertEqual('', $view->getStyle()->getField(0, 'field_test'));
// The second result is coming from entity_test_mul, so its field value
// could be rendered.
$this->assertEqual('1', $view->getStyle()->getField(1, 'field_test'));
}
}

View file

@ -0,0 +1,80 @@
<?php
/**
* @file
* Contains \Drupal\views\Tests\RenderCacheWebTest.
*/
namespace Drupal\views\Tests;
use Drupal\node\Entity\Node;
/**
* Tests render caching of blocks provided by views.
*
* @group views
*/
class RenderCacheWebTest extends ViewTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['node', 'block'];
/**
* {@inheritdoc}
*/
public static $testViews = ['node_id_argument'];
/**
* The created nodes.
*
* @var \Drupal\node\NodeInterface[]
*/
protected $nodes;
/**
* {@inheritdoc}
*/
protected function setUp($import_test_views = TRUE) {
parent::setUp($import_test_views);
$node_type = $this->drupalCreateContentType(['type' => 'test_type']);
$node = Node::create([
'title' => 'test title 1',
'type' => $node_type->id(),
]);
$node->save();
$this->nodes[] = $node;
$node = Node::create([
'title' => 'test title 2',
'type' => $node_type->id(),
]);
$node->save();
$this->nodes[] = $node;
$this->placeBlock('views_block:node_id_argument-block_1', ['region' => 'header']);
}
/**
* Tests rendering caching of a views block with arguments.
*/
public function testEmptyView() {
$this->drupalGet('<front>');
$this->assertEqual([], $this->cssSelect('div.region-header div.views-field-title'));
$this->drupalGet($this->nodes[0]->toUrl());
$result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span;
$this->assertEqual('test title 1', $result);
$this->drupalGet($this->nodes[1]->toUrl());
$result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span;
$this->assertEqual('test title 2', $result);
$this->drupalGet($this->nodes[0]->toUrl());
$result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span;
$this->assertEqual('test title 1', $result);
}
}

View file

@ -77,4 +77,23 @@ class TokenReplaceTest extends ViewKernelTestBase {
}
}
/**
* Tests core token replacements generated from a view without results.
*/
function testTokenReplacementNoResults() {
$token_handler = \Drupal::token();
$view = Views::getView('test_tokens');
$view->setDisplay('page_2');
$this->executeView($view);
$expected = array(
'[view:page-count]' => '1',
);
foreach ($expected as $token => $expected_output) {
$output = $token_handler->replace($token, array('view' => $view));
$this->assertIdentical($output, $expected_output, format_string('Token %token replaced correctly.', array('%token' => $token)));
}
}
}

View file

@ -0,0 +1,215 @@
langcode: en
status: true
dependencies:
module:
- node
- user
id: node_id_argument
label: node_id_argument
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: some
options:
items_per_page: 5
offset: 0
style:
type: default
row:
type: fields
fields:
title:
id: title
table: node_field_data
field: title
settings:
link_to_entity: false
plugin_id: field
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: true
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: string
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
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
title: node_id_argument
header: { }
footer: { }
empty: { }
relationships: { }
arguments:
nid:
id: nid
table: node_field_data
field: nid
relationship: none
group_type: group
admin_label: ''
default_action: default
exception:
value: all
title_enable: false
title: All
title_enable: false
title: ''
default_argument_type: node
default_argument_options: { }
default_argument_skip_url: false
summary_options:
base_path: ''
count: true
items_per_page: 25
override: false
summary:
sort_order: asc
number_of_records: 0
format: default_summary
specify_validation: false
validate:
type: none
fail: 'not found'
validate_options: { }
break_phrase: false
not: false
entity_type: node
entity_field: nid
plugin_id: node_nid
display_extenders: { }
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- 'user.node_grants:view'
- user.permissions
tags: { }
block_1:
display_plugin: block
id: block_1
display_title: Block
position: 1
display_options:
display_extenders: { }
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- 'user.node_grants:view'
- user.permissions
tags: { }

View file

@ -0,0 +1,50 @@
langcode: en
status: true
dependencies: { }
id: test_display_entity_reference
module: views
description: ''
tag: ''
base_table: entity_test
base_field: id
core: '8'
display:
default:
display_options:
access:
type: none
cache:
type: tag
fields:
name:
id: name
table: entity_test
field: name
plugin_id: field
entity_type: entity_test
entity_field: name
style:
type: html_list
display_plugin: default
display_title: Master
id: default
position: 0
entity_reference_1:
display_plugin: entity_reference
id: entity_reference_1
display_title: 'Entity Reference'
position: 1
display_options:
display_extenders: { }
style:
type: entity_reference
options:
search_fields:
name: name
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- 'user.node_grants:view'
tags: { }

View file

@ -0,0 +1,61 @@
langcode: en
status: true
dependencies: { }
id: test_group_by_field_not_within_bundle
label: ''
module: views
description: ''
tag: ''
base_table: entity_test_mul_property_data
base_field: id
core: '8'
display:
default:
display_options:
access:
type: none
cache:
type: tag
exposed_form:
type: basic
fields:
field_test:
alter:
alter_text: false
ellipsis: true
html: false
make_link: false
strip_tags: false
trim: false
word_boundary: true
group_type: group
group_column: value
empty_zero: false
field: field_test
hide_empty: false
id: field_test
table: entity_test_mul__field_test
entity_type: entity_test_mul
entity_field: field_test
plugin_id: field
sorts:
field_test_value:
table: entity_test_mul__field_test
field: field_test_value
id: field_test_value
entity_type: entity_test_mul
entity_field: field_test
group_type: group
order: ASC
plugin_id: standard
group_by: true
pager:
type: some
style:
type: default
row:
type: fields
display_plugin: default
display_title: Master
id: default
position: 0

View file

@ -57,3 +57,23 @@ display:
type: views_query
options: { }
path: test_tokens
page_2:
id: page_2
display_title: Page
display_plugin: page
position: 2
display_options:
defaults:
filters: false
query:
type: views_query
options: { }
filters:
name:
field: name
id: test_filter
table: views_test_data
plugin_id: string
operator: '='
value: 'not an existing name'
path: test_tokens_empty

View file

@ -185,6 +185,10 @@ class ViewAjaxControllerTest extends UnitTestCase {
$request = new Request();
$request->request->set('view_name', 'test_view');
$request->request->set('view_display_id', 'page_1');
$request->request->set('view_path', '/test-page');
$request->request->set('_wrapper_format', 'ajax');
$request->request->set('ajax_page_state', 'drupal.settings[]');
$request->request->set('type', 'article');
list($view, $executable) = $this->setupValidMocks();
@ -205,6 +209,10 @@ class ViewAjaxControllerTest extends UnitTestCase {
$executable->displayHandlers = $display_collection;
$this->redirectDestination->expects($this->atLeastOnce())
->method('set')
->with('/test-page?type=article');
$response = $this->viewAjaxController->ajaxView($request);
$this->assertTrue($response instanceof ViewAjaxResponse);

View file

@ -138,8 +138,8 @@ class EntityViewsDataTest extends UnitTestCase {
// Add a description field to the fields supplied by the EntityTest
// classes. This example comes from the taxonomy Term entity.
$base_fields['description'] = BaseFieldDefinition::create('text_long')
->setLabel(t('Description'))
->setDescription(t('A description of the term.'))
->setLabel('Description')
->setDescription('A description of the term.')
->setTranslatable(TRUE)
->setDisplayOptions('view', array(
'label' => 'hidden',
@ -155,8 +155,8 @@ class EntityViewsDataTest extends UnitTestCase {
// Add a URL field; this example is from the Comment entity.
$base_fields['homepage'] = BaseFieldDefinition::create('uri')
->setLabel(t('Homepage'))
->setDescription(t("The comment author's home page address."))
->setLabel('Homepage')
->setDescription("The comment author's home page address.")
->setTranslatable(TRUE)
->setSetting('max_length', 255);
@ -409,8 +409,8 @@ class EntityViewsDataTest extends UnitTestCase {
$base_field_definitions = $this->setupBaseFields(EntityTest::baseFieldDefinitions($this->baseEntityType));
$user_base_field_definitions = [
'uid' => BaseFieldDefinition::create('integer')
->setLabel(t('ID'))
->setDescription(t('The ID of the user entity.'))
->setLabel('ID')
->setDescription('The ID of the user entity.')
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE)
];
@ -498,8 +498,8 @@ class EntityViewsDataTest extends UnitTestCase {
$base_field_definitions = $this->setupBaseFields($base_field_definitions);
$user_base_field_definitions = [
'uid' => BaseFieldDefinition::create('integer')
->setLabel(t('ID'))
->setDescription(t('The ID of the user entity.'))
->setLabel('ID')
->setDescription('The ID of the user entity.')
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE)
];
@ -621,8 +621,8 @@ class EntityViewsDataTest extends UnitTestCase {
$base_field_definitions = $this->setupBaseFields(EntityTestMulRev::baseFieldDefinitions($this->baseEntityType));
$user_base_field_definitions = [
'uid' => BaseFieldDefinition::create('integer')
->setLabel(t('ID'))
->setDescription(t('The ID of the user entity.'))
->setLabel('ID')
->setDescription('The ID of the user entity.')
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE)
];
@ -970,10 +970,11 @@ class TestEntityType extends EntityType {
}
namespace {
namespace Drupal\entity_test\Entity {
if (!function_exists('t')) {
function t($string, array $args = []) {
return strtr($string, $args);
}
}
}

View file

@ -124,7 +124,7 @@ function views_tokens($type, $tokens, array $data, array $options, BubbleableMet
case 'page-count':
// If there are no items per page, set this to 1 for the division.
$per_page = $view->getItemsPerPage() ?: 1;
$replacements[$original] = (int) ceil(count($view->result) / $per_page);
$replacements[$original] = max(1, (int) ceil(count($view->result) / $per_page));
break;
}
}