diff --git a/core/modules/block_content/src/Tests/BlockContentListViewsTest.php b/core/modules/block_content/src/Tests/BlockContentListViewsTest.php index ba84f2b..2740bd3 100644 --- a/core/modules/block_content/src/Tests/BlockContentListViewsTest.php +++ b/core/modules/block_content/src/Tests/BlockContentListViewsTest.php @@ -62,6 +62,7 @@ public function testListing() { $edit = array(); $edit['info[0][value]'] = $label; $edit['body[0][value]'] = $this->randomMachineName(16); + $this->verbose = TRUE; $this->drupalPostForm(NULL, $edit, t('Save')); // Confirm that once the user returns to the listing, the text of the label diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index ad82046..5cb50fb 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -211,6 +211,29 @@ function comment_node_links_alter(array &$node_links, NodeInterface $node, array } /** + * Implements hook_ENTITY_TYPE_view. + */ +function comment_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode, $langcode) { + /** @var \Drupal\comment\CommentManagerInterface $comment_manager */ + $comment_manager = \Drupal::service('comment.manager'); + $fields = $comment_manager->getFields($entity->getEntityTypeId()); + foreach ($fields as $field_name => $detail) { + if ($view_mode == 'rss' && $display->getComponent('links') && $entity->get($field_name)->status) { + // Add a comments RSS element which is a URL to the comments of this + // entity. + $options = array( + 'fragment' => 'comments', + 'absolute' => TRUE, + ); + $entity->rss_elements[] = array( + 'key' => 'comments', + 'value' => $entity->url('canonical', $options), + ); + } + } +} + +/** * Implements hook_ENTITY_TYPE_view_alter() for node entities. */ function comment_node_view_alter(array &$build, EntityInterface $node, EntityViewDisplayInterface $display) { diff --git a/core/modules/comment/src/CommentLinkBuilder.php b/core/modules/comment/src/CommentLinkBuilder.php index 951a69f..0597d72 100644 --- a/core/modules/comment/src/CommentLinkBuilder.php +++ b/core/modules/comment/src/CommentLinkBuilder.php @@ -89,19 +89,7 @@ public function buildCommentedEntityLinks(FieldableEntityInterface $entity, arra if ($commenting_status != CommentItemInterface::HIDDEN) { // Entity has commenting status open or closed. $field_definition = $entity->getFieldDefinition($field_name); - if ($view_mode == 'rss') { - // Add a comments RSS element which is a URL to the comments of this - // entity. - $options = array( - 'fragment' => 'comments', - 'absolute' => TRUE, - ); - $entity->rss_elements[] = array( - 'key' => 'comments', - 'value' => $entity->url('canonical', $options), - ); - } - elseif ($view_mode == 'teaser') { + if ($view_mode == 'teaser') { // Teaser view: display the number of comments that have been posted, // or a link to add new comments if the user has permission, the // entity is open to new comments, and there currently are none. diff --git a/core/modules/comment/src/Plugin/views/row/Rss.php b/core/modules/comment/src/Plugin/views/row/Rss.php index 329d743..3002765 100644 --- a/core/modules/comment/src/Plugin/views/row/Rss.php +++ b/core/modules/comment/src/Plugin/views/row/Rss.php @@ -123,7 +123,7 @@ public function render($row) { $item->title = $comment->label(); $item->link = $comment->link; // Provide a reference so that the render call in - // template_preprocess_views_view_row_rss() can still it. + // template_preprocess_views_view_row_rss() can still access it. $item->elements = &$comment->rss_elements; $item->cid = $comment->id(); diff --git a/core/modules/comment/src/Tests/CommentRssTest.php b/core/modules/comment/src/Tests/CommentRssTest.php index 03a4e9b..b146e65 100644 --- a/core/modules/comment/src/Tests/CommentRssTest.php +++ b/core/modules/comment/src/Tests/CommentRssTest.php @@ -8,6 +8,7 @@ namespace Drupal\comment\Tests; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; +use Drupal\Core\Entity\Entity\EntityViewDisplay; use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait; /** @@ -27,6 +28,23 @@ class CommentRssTest extends CommentTestBase { public static $modules = array('views'); /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + // Setup the rss view display. + EntityViewDisplay::create([ + 'status' => TRUE, + 'targetEntityType' => 'node', + 'bundle' => 'article', + 'mode' => 'rss', + 'content' => ['links' => ['weight' => 100]], + ])->save(); + } + + + /** * Tests comments as part of an RSS feed. */ function testCommentRss() { @@ -36,13 +54,14 @@ function testCommentRss() { $this->drupalGet('rss.xml'); $this->assertCacheTags([ - 'config:views.view.frontpage', 'node:1', 'node_list', + 'config:views.view.frontpage', 'node:1', 'node_list', 'node_view', 'user:3', ]); $this->assertCacheContexts([ 'languages:language_interface', 'theme', 'user.node_grants:view', 'user.permissions', + 'timezone', ]); $raw = '' . $this->node->url('canonical', array('fragment' => 'comments', 'absolute' => TRUE)) . ''; diff --git a/core/modules/node/src/Plugin/views/row/Rss.php b/core/modules/node/src/Plugin/views/row/Rss.php index f93719f..72127fe 100644 --- a/core/modules/node/src/Plugin/views/row/Rss.php +++ b/core/modules/node/src/Plugin/views/row/Rss.php @@ -180,6 +180,8 @@ public function render($row) { $item->description = $description_build; $item->title = $node->label(); $item->link = $node->link; + // Provide a reference so that the render call in + // template_preprocess_views_view_row_rss() can still access it. $item->elements = &$node->rss_elements; $item->nid = $node->id(); $build = array( diff --git a/core/modules/node/src/Tests/Views/FrontPageTest.php b/core/modules/node/src/Tests/Views/FrontPageTest.php index 934eed3..b7e041b 100644 --- a/core/modules/node/src/Tests/Views/FrontPageTest.php +++ b/core/modules/node/src/Tests/Views/FrontPageTest.php @@ -291,6 +291,7 @@ protected function assertFrontPageViewCacheTags($do_assert_views_caches) { 'timezone', ]); + $this->pass('First page'); // First page. $first_page_result_cache_tags = [ 'config:views.view.frontpage', @@ -313,10 +314,10 @@ protected function assertFrontPageViewCacheTags($do_assert_views_caches) { 'user:0', ]); $view->setDisplay('page_1'); - $view->setCurrentPage(0, TRUE); + $view->setCurrentPage(0); $this->assertViewsCacheTags( $view, - NULL, + $first_page_result_cache_tags, $do_assert_views_caches, $first_page_output_cache_tags ); @@ -327,6 +328,7 @@ protected function assertFrontPageViewCacheTags($do_assert_views_caches) { ); // Second page. + $this->pass('second page'); $this->assertPageCacheContextsAndTags(Url::fromRoute('view.frontpage.page_1', [], ['query' => ['page' => 1]]), $cache_contexts, [ // The cache tags for the listed nodes. 'node:1', diff --git a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php index f0a7b75..69d78c6 100644 --- a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php +++ b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php @@ -219,7 +219,7 @@ public function testResponseFormatConfiguration() { $this->drupalGet('test/serialize/field', array(), array('Accept: application/xml')); $this->assertResponse(200, 'A 200 response was returned when XML was requested'); $headers = $this->drupalGetHeaders(); - $this->assertEqual($headers['content-type'], 'text/xml', 'The header Content-type is correct.'); + $this->assertTrue(strpos($headers['content-type'], 'text/xml') !== FALSE, 'The header Content-type is correct.'); // Should return a 406. $this->drupalGet('test/serialize/field', array(), array('Accept: application/html')); $this->assertResponse(406, 'A 406 response was returned when HTML was requested.'); diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php index 2e8702b..7739409 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -2597,6 +2597,7 @@ protected function prepareRequestForGenerator($clean_urls = TRUE, $override_serv $server = array_merge($server, $override_server_vars); $request = Request::create($request_path, 'GET', array(), array(), array(), $server); + $request->server->set('REQUEST_TIME', REQUEST_TIME); $this->container->get('request_stack')->push($request); // The request context is normally set by the router_listener from within diff --git a/core/modules/views/src/Plugin/views/cache/CachePluginBase.php b/core/modules/views/src/Plugin/views/cache/CachePluginBase.php index 66d8987..bd9b74e 100644 --- a/core/modules/views/src/Plugin/views/cache/CachePluginBase.php +++ b/core/modules/views/src/Plugin/views/cache/CachePluginBase.php @@ -191,7 +191,7 @@ public function cacheSet($type) { 'total_rows' => isset($this->view->total_rows) ? $this->view->total_rows : 0, 'current_page' => $this->view->getCurrentPage(), ); - $expire = ($this->cacheSetMaxAge($type) === Cache::PERMANENT) ? Cache::PERMANENT : (int) $this->view->getRequest()->server->get('SERVER_TIME') + $this->cacheSetMaxAge($type); + $expire = ($this->cacheSetMaxAge($type) === Cache::PERMANENT) ? Cache::PERMANENT : (int) $this->view->getRequest()->server->get('REQUEST_TIME') + $this->cacheSetMaxAge($type); \Drupal::cache($this->resultsBin)->set($this->generateResultsKey(), $data, $expire, $this->getCacheTags()); break; } diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php index cc0984a..7726989 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php @@ -2130,14 +2130,9 @@ public function render() { '#view' => $this->view, '#pre_render' => [[$this, 'elementPreRender']], '#rows' => $rows, - // Assigned by reference so anything added in $element['#attached'] will - // be available on the view. - '#attached' => &$this->view->element['#attached'], - '#cache' => &$this->view->element['#cache'], - '#post_render_cache' => &$this->view->element['#post_render_cache'], ); - $this->renderSetCacheData($element); + $this->renderSetCacheData($this->view->element); return $element; } diff --git a/core/modules/views/src/Tests/AssertViewsCacheTagsTrait.php b/core/modules/views/src/Tests/AssertViewsCacheTagsTrait.php index de37c44..b450ae0 100644 --- a/core/modules/views/src/Tests/AssertViewsCacheTagsTrait.php +++ b/core/modules/views/src/Tests/AssertViewsCacheTagsTrait.php @@ -82,7 +82,8 @@ protected function assertViewsCacheTags(ViewExecutable $view, $expected_results_ $this->pass('Checking Views render cache item cache tags.'); - $original['#cache'] += ['contexts' => $this->container->getParameter('renderer.config')['required_cache_contexts']]; + $original['#cache'] += ['contexts' => []]; + $original['#cache']['contexts'] = Cache::mergeContexts($original['#cache']['contexts'], $this->container->getParameter('renderer.config')['required_cache_contexts']); $render_cache_item = $render_cache->get($original); if ($views_caching_is_enabled === TRUE) { diff --git a/core/modules/views/src/Tests/Plugin/CacheTagTest.php b/core/modules/views/src/Tests/Plugin/CacheTagTest.php index d0e358d..219857f 100644 --- a/core/modules/views/src/Tests/Plugin/CacheTagTest.php +++ b/core/modules/views/src/Tests/Plugin/CacheTagTest.php @@ -7,7 +7,7 @@ namespace Drupal\views\Tests\Plugin; -use Drupal\views\Plugin\views\display\DisplayPluginBase; +use Drupal\Core\Cache\Cache; use Drupal\views\ViewExecutable; use Drupal\views\Views; @@ -109,10 +109,11 @@ protected function setUp() { protected function getRenderCache(ViewExecutable $view) { /** @var \Drupal\Core\Render\RenderCacheInterface $render_cache */ $render_cache = \Drupal::service('render_cache'); - $cache_element = DisplayPluginBase::buildBasicRenderable($view->id(), $view->current_display); - $cache_element['#cache'] += ['contexts' => $this->container->getParameter('renderer.config')['required_cache_contexts']]; + $view->element = ['#cache' => []]; + $build = $view->buildRenderable(); + $build['#cache']['contexts'] = Cache::mergeContexts($build['#cache']['contexts'], $this->container->getParameter('renderer.config')['required_cache_contexts']); - return $render_cache->get($cache_element); + return $render_cache->get($build); } /** diff --git a/core/modules/views/src/Tests/Plugin/CacheTest.php b/core/modules/views/src/Tests/Plugin/CacheTest.php index 8d31f07..8db3e94 100644 --- a/core/modules/views/src/Tests/Plugin/CacheTest.php +++ b/core/modules/views/src/Tests/Plugin/CacheTest.php @@ -46,7 +46,7 @@ protected function setUp($import_test_views = TRUE) { $this->installEntitySchema('user'); // Setup the current time properly. - \Drupal::request()->server->set('SERVER_TIME', time()); + \Drupal::request()->server->set('REQUEST_TIME', time()); } /** diff --git a/core/modules/views/src/Tests/ViewAjaxTest.php b/core/modules/views/src/Tests/ViewAjaxTest.php index bb4c76c..35b5518 100644 --- a/core/modules/views/src/Tests/ViewAjaxTest.php +++ b/core/modules/views/src/Tests/ViewAjaxTest.php @@ -54,11 +54,14 @@ public function testAjaxView() { $response = $this->drupalPost('views/ajax', 'application/vnd.drupal-ajax', $post); $data = Json::decode($response); + $this->assertTrue(isset($data[0]['settings']['views']['ajaxViews'])); + $this->assertEqual($data[1]['command'], 'add_css'); + // Ensure that the view insert command is part of the result. - $this->assertEqual($data[1]['command'], 'insert'); - $this->assertTrue(strpos($data[1]['selector'], '.js-view-dom-id-') === 0); + $this->assertEqual($data[2]['command'], 'insert'); + $this->assertTrue(strpos($data[2]['selector'], '.js-view-dom-id-') === 0); - $this->setRawContent($data[1]['data']); + $this->setRawContent($data[2]['data']); $result = $this->xpath('//div[contains(@class, "views-row")]'); $this->assertEqual(count($result), 2, 'Ensure that two items are rendered in the HTML.'); } diff --git a/core/modules/views/src/ViewExecutable.php b/core/modules/views/src/ViewExecutable.php index b99e842..d5d2781 100644 --- a/core/modules/views/src/ViewExecutable.php +++ b/core/modules/views/src/ViewExecutable.php @@ -511,7 +511,11 @@ public function addCacheContext($cache_context) { public function setCurrentPage($page) { $this->current_page = $page; - $this->element['#cache']['keys'][] = 'page:' . $page; + // Calls like ::unserialize() might setup a $page might call this method + // without a proper $page. + if ($page) { + $this->element['#cache']['keys'][] = 'page:' . $page; + } // If the pager is already initialized, pass it through to the pager. if (!empty($this->pager)) { @@ -2379,7 +2383,7 @@ public function unserialize($serialized) { $this->setDisplay($current_display); $this->setArguments($args); - $this->setCurrentPage($current_page, TRUE); + $this->setCurrentPage($current_page); $this->setExposedInput($exposed_input); $this->exposed_data = $exposed_data; $this->exposed_raw_input = $exposed_raw_input;