update drupal

This commit is contained in:
Tessier
2020-10-15 11:59:37 +02:00
parent ebb5db14b5
commit d8b9162932
558 changed files with 5954 additions and 4475 deletions
-74
View File
@@ -8,7 +8,6 @@
use Drupal\node\NodeInterface;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Access\AccessResult;
/**
* @addtogroup hooks
@@ -286,79 +285,6 @@ function hook_node_grants_alter(&$grants, \Drupal\Core\Session\AccountInterface
}
}
/**
* Controls access to a node.
*
* Modules may implement this hook if they want to have a say in whether or not
* a given user has access to perform a given operation on a node.
*
* The administrative account (user ID #1) always passes any access check, so
* this hook is not called in that case. Users with the "bypass node access"
* permission may always view and edit content through the administrative
* interface.
*
* The access to a node can be influenced in several ways:
* - To explicitly allow access, return an AccessResultInterface object with
* isAllowed() returning TRUE. Other modules can override this access by
* returning TRUE for isForbidden().
* - To explicitly forbid access, return an AccessResultInterface object with
* isForbidden() returning TRUE. Access will be forbidden even if your module
* (or another module) also returns TRUE for isNeutral() or isAllowed().
* - To neither allow nor explicitly forbid access, return an
* AccessResultInterface object with isNeutral() returning TRUE.
* - If your module does not return an AccessResultInterface object, neutral
* access will be assumed.
*
* Also note that this function isn't called for node listings (e.g., RSS feeds,
* the default home page at path 'node', a recent content block, etc.) See
* @link node_access Node access rights @endlink for a full explanation.
*
* @param \Drupal\node\NodeInterface|string $node
* Either a node entity or the machine name of the content type on which to
* perform the access check.
* @param string $op
* The operation to be performed. Possible values:
* - "create"
* - "delete"
* - "update"
* - "view"
* @param \Drupal\Core\Session\AccountInterface $account
* The user object to perform the access check operation on.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*
* @ingroup node_access
*/
function hook_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account) {
$type = $node->bundle();
switch ($op) {
case 'create':
return AccessResult::allowedIfHasPermission($account, 'create ' . $type . ' content');
case 'update':
if ($account->hasPermission('edit any ' . $type . ' content')) {
return AccessResult::allowed()->cachePerPermissions();
}
else {
return AccessResult::allowedIf($account->hasPermission('edit own ' . $type . ' content') && ($account->id() == $node->getOwnerId()))->cachePerPermissions()->cachePerUser()->addCacheableDependency($node);
}
case 'delete':
if ($account->hasPermission('delete any ' . $type . ' content')) {
return AccessResult::allowed()->cachePerPermissions();
}
else {
return AccessResult::allowedIf($account->hasPermission('delete own ' . $type . ' content') && ($account->id() == $node->getOwnerId()))->cachePerPermissions()->cachePerUser()->addCacheableDependency($node);
}
default:
// No opinion.
return AccessResult::neutral();
}
}
/**
* Act on a node being displayed as a search result.
*
+31 -26
View File
@@ -950,16 +950,16 @@ function node_form_system_themes_admin_form_submit($form, FormStateInterface $fo
* @{
* The node access system determines who can do what to which nodes.
*
* In determining access rights for a node, \Drupal\node\NodeAccessControlHandler
* first checks whether the user has the "bypass node access" permission. Such
* users have unrestricted access to all nodes. user 1 will always pass this
* check.
* In determining access rights for an existing node,
* \Drupal\node\NodeAccessControlHandler first checks whether the user has the
* "bypass node access" permission. Such users have unrestricted access to all
* nodes. user 1 will always pass this check.
*
* Next, all implementations of hook_node_access() will be called. Each
* implementation may explicitly allow, explicitly forbid, or ignore the access
* request. If at least one module says to forbid the request, it will be
* rejected. If no modules deny the request and at least one says to allow it,
* the request will be permitted.
* Next, all implementations of hook_ENTITY_TYPE_access() for node will
* be called. Each implementation may explicitly allow, explicitly forbid, or
* ignore the access request. If at least one module says to forbid the request,
* it will be rejected. If no modules deny the request and at least one says to
* allow it, the request will be permitted.
*
* If all modules ignore the access request, then the node_access table is used
* to determine access. All node access modules are queried using
@@ -972,40 +972,42 @@ function node_form_system_themes_admin_form_submit($form, FormStateInterface $fo
*
* In node listings (lists of nodes generated from a select query, such as the
* default home page at path 'node', an RSS feed, a recent content block, etc.),
* the process above is followed except that hook_node_access() is not called on
* each node for performance reasons and for proper functioning of the pager
* system. When adding a node listing to your module, be sure to use an entity
* query, which will add a tag of "node_access". This will allow modules dealing
* with node access to ensure only nodes to which the user has access are
* retrieved, through the use of hook_query_TAG_alter(). See the
* the process above is followed except that hook_ENTITY_TYPE_access() is not
* called on each node for performance reasons and for proper functioning of
* the pager system. When adding a node listing to your module, be sure to use
* an entity query, which will add a tag of "node_access". This will allow
* modules dealing with node access to ensure only nodes to which the user has
* access are retrieved, through the use of hook_query_TAG_alter(). See the
* @link entity_api Entity API topic @endlink for more information on entity
* queries. Tagging a query with "node_access" does not check the
* published/unpublished status of nodes, so the base query is responsible
* for ensuring that unpublished nodes are not displayed to inappropriate users.
*
* Note: Even a single module returning an AccessResultInterface object from
* hook_node_access() whose isForbidden() method equals TRUE will block access
* to the node. Therefore, implementers should take care to not deny access
* unless they really intend to. Unless a module wishes to actively forbid
* access it should return an AccessResultInterface object whose isAllowed() nor
* isForbidden() methods return TRUE, to allow other modules or the node_access
* table to control access.
* hook_ENTITY_TYPE_access() whose isForbidden() method equals TRUE will block
* access to the node. Therefore, implementers should take care to not deny
* access unless they really intend to. Unless a module wishes to actively
* forbid access it should return an AccessResultInterface object whose
* isAllowed() nor isForbidden() methods return TRUE, to allow other modules or
* the node_access table to control access.
*
* Note also that access to create nodes is handled by
* hook_ENTITY_TYPE_create_access().
*
* To see how to write a node access module of your own, see
* node_access_example.module.
*
* @see \Drupal\node\NodeAccessControlHandler
*/
/**
* Implements hook_node_access().
* Implements hook_ENTITY_TYPE_access().
*/
function node_node_access(NodeInterface $node, $op, AccountInterface $account) {
$type = $node->bundle();
$access = AccessResult::neutral();
// Note create access is handled by hook_ENTITY_TYPE_create_access().
switch ($op) {
case 'create':
$access = AccessResult::allowedIfHasPermission($account, 'create ' . $type . ' content');
case 'update':
$access = AccessResult::allowedIfHasPermission($account, 'edit any ' . $type . ' content');
if (!$access->isAllowed() && $account->hasPermission('edit own ' . $type . ' content')) {
@@ -1019,6 +1021,9 @@ function node_node_access(NodeInterface $node, $op, AccountInterface $account) {
$access = $access->orIf(AccessResult::allowedIf($account->id() == $node->getOwnerId()))->cachePerUser()->addCacheableDependency($node);
}
break;
default:
$access = AccessResult::neutral();
}
return $access;
+52
View File
@@ -0,0 +1,52 @@
<?php
/**
* @file
* Provide views data for node.module.
*/
use Drupal\user\RoleInterface;
use Drupal\views\ViewExecutable;
use Drupal\user\Entity\Role;
use Drupal\views\Analyzer;
/**
* Implements hook_views_analyze().
*/
function node_views_analyze(ViewExecutable $view) {
$ret = [];
// Check for something other than the default display:
if ($view->storage->get('base_table') == 'node') {
foreach ($view->displayHandlers as $display) {
if (!$display->isDefaulted('access') || !$display->isDefaulted('filters')) {
// check for no access control
$access = $display->getOption('access');
if (empty($access['type']) || $access['type'] == 'none') {
$anonymous_role = Role::load(RoleInterface::ANONYMOUS_ID);
$anonymous_has_access = $anonymous_role && $anonymous_role->hasPermission('access content');
$authenticated_role = Role::load(RoleInterface::AUTHENTICATED_ID);
$authenticated_has_access = $authenticated_role && $authenticated_role->hasPermission('access content');
if (!$anonymous_has_access || !$authenticated_has_access) {
$ret[] = Analyzer::formatMessage(t('Some roles lack permission to access content, but display %display has no access control.', ['%display' => $display->display['display_title']]), 'warning');
}
$filters = $display->getOption('filters');
foreach ($filters as $filter) {
if ($filter['table'] == 'node' && ($filter['field'] == 'status' || $filter['field'] == 'status_extra')) {
continue 2;
}
}
$ret[] = Analyzer::formatMessage(t('Display %display has no access control but does not contain a filter for published nodes.', ['%display' => $display->display['display_title']]), 'warning');
}
}
}
}
foreach ($view->displayHandlers as $display) {
if ($display->getPluginId() == 'page') {
if ($display->getOption('path') == 'node/%') {
$ret[] = Analyzer::formatMessage(t('Display %display has set node/% as path. This will not produce what you want. If you want to have multiple versions of the node view, use Layout Builder.', ['%display' => $display->display['display_title']]), 'warning');
}
}
}
return $ret;
}
@@ -5,9 +5,7 @@
* Provide views runtime hooks for node.module.
*/
use Drupal\user\RoleInterface;
use Drupal\views\ViewExecutable;
use Drupal\user\Entity\Role;
/**
* Implements hook_views_query_substitutions().
@@ -20,44 +18,3 @@ function node_views_query_substitutions(ViewExecutable $view) {
'***BYPASS_NODE_ACCESS***' => intval($account->hasPermission('bypass node access')),
];
}
/**
* Implements hook_views_analyze().
*/
function node_views_analyze(ViewExecutable $view) {
$ret = [];
// Check for something other than the default display:
if ($view->storage->get('base_table') == 'node') {
foreach ($view->displayHandlers as $display) {
if (!$display->isDefaulted('access') || !$display->isDefaulted('filters')) {
// check for no access control
$access = $display->getOption('access');
if (empty($access['type']) || $access['type'] == 'none') {
$anonymous_role = Role::load(RoleInterface::ANONYMOUS_ID);
$anonymous_has_access = $anonymous_role && $anonymous_role->hasPermission('access content');
$authenticated_role = Role::load(RoleInterface::AUTHENTICATED_ID);
$authenticated_has_access = $authenticated_role && $authenticated_role->hasPermission('access content');
if (!$anonymous_has_access || !$authenticated_has_access) {
$ret[] = Analyzer::formatMessage(t('Some roles lack permission to access content, but display %display has no access control.', ['%display' => $display->display['display_title']]), 'warning');
}
$filters = $display->getOption('filters');
foreach ($filters as $filter) {
if ($filter['table'] == 'node' && ($filter['field'] == 'status' || $filter['field'] == 'status_extra')) {
continue 2;
}
}
$ret[] = Analyzer::formatMessage(t('Display %display has no access control but does not contain a filter for published nodes.', ['%display' => $display->display['display_title']]), 'warning');
}
}
}
}
foreach ($view->displayHandlers as $display) {
if ($display->getPluginId() == 'page') {
if ($display->getOption('path') == 'node/%') {
$ret[] = Analyzer::formatMessage(t('Display %display has set node/% as path. This will not produce what you want. If you want to have multiple versions of the node view, use panels.', ['%display' => $display->display['display_title']]), 'warning');
}
}
}
return $ret;
}
@@ -368,7 +368,15 @@ display:
entity_type: node
entity_field: revision_uid
plugin_id: user_name
sorts: { }
sorts:
vid:
id: vid
table: node_field_revision
field: vid
order: ASC
plugin_id: field
entity_type: node
entity_field: vid
header: { }
footer: { }
empty: { }
@@ -0,0 +1,180 @@
langcode: en
status: true
dependencies:
module:
- node
- user
id: test_node_views_analyze
label: test_node_views_analyze
module: views
description: ''
tag: ''
base_table: node_field_data
base_field: nid
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
row:
type: 'entity:node'
options:
view_mode: teaser
fields:
title:
id: title
table: node_field_data
field: title
entity_type: node
entity_field: title
label: ''
alter:
alter_text: false
make_link: false
absolute: false
trim: false
word_boundary: false
ellipsis: false
strip_tags: false
html: false
hide_empty: false
empty_zero: false
settings:
link_to_entity: true
plugin_id: field
relationship: none
group_type: group
admin_label: ''
exclude: 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_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: '1'
table: node_field_data
field: status
plugin_id: boolean
entity_type: node
entity_field: status
id: status
expose:
operator: ''
operator_limit_selection: false
operator_list: { }
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: test_node_views_analyze
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: { }
page_1:
display_plugin: page
id: page_1
display_title: Page
position: 1
display_options:
display_extenders: { }
path: node/%
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url.query_args
- 'user.node_grants:view'
- user.permissions
tags: { }
@@ -82,7 +82,6 @@ class NodeAccessGrantsCacheContextTest extends NodeTestBase {
if ($uid > 0) {
$this->drupalLogin($this->userMapping[$uid]);
}
$this->pass('Asserting cache context for user ' . $uid . '.');
$this->assertIdentical($context, $this->container->get('cache_context.user.node_grants')->getContext('view'));
}
$this->drupalLogout();
@@ -111,7 +111,7 @@ class NodeCreationTest extends NodeTestBase {
$this->fail('Expected exception has not been thrown.');
}
catch (\Exception $e) {
$this->pass('Expected exception has been thrown.');
// Expected exception; just continue testing.
}
if (Database::getConnection()->supportsTransactions()) {
@@ -294,7 +294,9 @@ class NodeCreationTest extends NodeTestBase {
// PostgreSQL doesn't support bytea LIKE queries, so we need to unserialize
// first to check for the rollback exception message.
$matches = [];
$query = Database::getConnection()->query("SELECT wid, variables FROM {watchdog}");
$query = Database::getConnection()->select('watchdog', 'w')
->fields('w', ['wid', 'variables'])
->execute();
foreach ($query as $row) {
$variables = (array) unserialize($row->variables);
if (isset($variables['@message']) && $variables['@message'] === 'Test exception for rollback.') {
@@ -197,8 +197,13 @@ class NodeRevisionsTest extends NodeTestBase {
'%title' => $nodes[1]->label(),
]), 'Revision deleted.');
$connection = Database::getConnection();
$this->assertTrue($connection->query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid and vid = :vid', [':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()])->fetchField() == 0, 'Revision not found.');
$this->assertTrue($connection->query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid and vid = :vid', [':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()])->fetchField() == 0, 'Field revision not found.');
$nids = \Drupal::entityQuery('node')
->accessCheck(FALSE)
->allRevisions()
->condition('nid', $node->id())
->condition('vid', $nodes[1]->getRevisionId())
->execute();
$this->assertCount(0, $nids);
// Set the revision timestamp to an older date to make sure that the
// confirmation message correctly displays the stored revision date.
@@ -55,7 +55,6 @@ class NodeRevisionsUiBypassAccessTest extends NodeTestBase {
$this->drupalPlaceBlock('local_tasks_block');
$this->drupalLogin($this->editor);
$node_storage = $this->container->get('entity_type.manager')->getStorage('node');
// Set page revision setting 'create new revision'. This will mean new
// revisions are created by default when the node is edited.
@@ -371,7 +371,7 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
$this->doTestTranslations('node/' . $node->id(), $values);
// Test that the node page has the correct alternate hreflang links.
$this->doTestAlternateHreflangLinks($node->toUrl());
$this->doTestAlternateHreflangLinks($node);
}
/**
@@ -393,24 +393,35 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
/**
* Tests that the given path provides the correct alternate hreflang links.
*
* @param \Drupal\Core\Url $url
* The path to be tested.
* @param \Drupal\node\Entity\Node $node
* The node to be tested.
*/
protected function doTestAlternateHreflangLinks(Url $url) {
protected function doTestAlternateHreflangLinks(Node $node) {
$url = $node->toUrl();
$languages = $this->container->get('language_manager')->getLanguages();
$url->setAbsolute();
$urls = [];
$translations = [];
foreach ($this->langcodes as $langcode) {
$language_url = clone $url;
$urls[$langcode] = $language_url->setOption('language', $languages[$langcode]);
$translations[$langcode] = $node->getTranslation($langcode);
}
foreach ($this->langcodes as $langcode) {
$this->drupalGet($urls[$langcode]);
foreach ($urls as $alternate_langcode => $language_url) {
// Retrieve desired link elements from the HTML head.
$links = $this->xpath('head/link[@rel = "alternate" and @href = :href and @hreflang = :hreflang]',
[':href' => $language_url->toString(), ':hreflang' => $alternate_langcode]);
$this->assert(isset($links[0]), new FormattableMarkup('The %langcode node translation has the correct alternate hreflang link for %alternate_langcode: %link.', ['%langcode' => $langcode, '%alternate_langcode' => $alternate_langcode, '%link' => $url->toString()]));
// Skip unpublished translations.
if ($translations[$langcode]->isPublished()) {
$this->drupalGet($urls[$langcode]);
foreach ($urls as $alternate_langcode => $language_url) {
// Retrieve desired link elements from the HTML head.
$links = $this->xpath('head/link[@rel = "alternate" and @href = :href and @hreflang = :hreflang]',
[':href' => $language_url->toString(), ':hreflang' => $alternate_langcode]);
if ($translations[$alternate_langcode]->isPublished()) {
$this->assert(isset($links[0]), new FormattableMarkup('The %langcode node translation has the correct alternate hreflang link for %alternate_langcode: %link.', ['%langcode' => $langcode, '%alternate_langcode' => $alternate_langcode, '%link' => $url->toString()]));
}
else {
$this->assertFalse(isset($links[0]), new FormattableMarkup('The %langcode node translation has an hreflang link for unpublished %alternate_langcode translation: %link.', ['%langcode' => $langcode, '%alternate_langcode' => $alternate_langcode, '%link' => $url->toString()]));
}
}
}
}
}
@@ -2,7 +2,6 @@
namespace Drupal\Tests\node\Functional\Views;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\views\Views;
@@ -60,7 +59,6 @@ class BulkFormTest extends NodeTestBase {
'promote' => FALSE,
];
$node = $this->drupalCreateNode($values);
$this->pass(new FormattableMarkup('Node %title created with language %langcode.', ['%title' => $node->label(), '%langcode' => $node->language()->getId()]));
$this->nodes[] = $node;
}
@@ -71,7 +69,6 @@ class BulkFormTest extends NodeTestBase {
if (!$node->hasTranslation($langcode)) {
$title = $this->randomMachineName() . ' [' . $node->id() . ':' . $langcode . ']';
$translation = $node->addTranslation($langcode, ['title' => $title, 'promote' => FALSE]);
$this->pass(new FormattableMarkup('Translation %title created with language %langcode.', ['%title' => $translation->label(), '%langcode' => $translation->language()->getId()]));
}
}
$node->save();
@@ -82,7 +79,6 @@ class BulkFormTest extends NodeTestBase {
$langcode = 'en';
$title = $this->randomMachineName() . ' [' . $node->id() . ':' . $langcode . ']';
$translation = $node->addTranslation($langcode, ['title' => $title]);
$this->pass(new FormattableMarkup('Translation %title created with language %langcode.', ['%title' => $translation->label(), '%langcode' => $translation->language()->getId()]));
$node->save();
// Check that all created translations are selected by the test view.
@@ -187,7 +187,7 @@ class FrontPageTest extends ViewTestBase {
$this->drupalGet('node');
$this->assertSession()->statusCodeEquals(200);
// Check that the frontpage view was rendered.
$this->assertPattern('/class=".+view-frontpage/', 'Frontpage view was rendered');
$this->assertPattern('/class=".+view-frontpage/');
}
/**
@@ -304,7 +304,6 @@ class FrontPageTest extends ViewTestBase {
'timezone',
]);
$this->pass('First page');
// First page.
$first_page_result_cache_tags = [
'config:views.view.frontpage',
@@ -344,7 +343,6 @@ class FrontPageTest extends ViewTestBase {
);
// 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',
@@ -0,0 +1,47 @@
<?php
namespace Drupal\Tests\node\Functional\Views;
/**
* Tests node_views_analyze().
*
* @group node
*/
class NodeViewsAnalyzeTest extends NodeTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['views_ui', 'node_test_views'];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['test_node_views_analyze'];
/**
* Tests the implementation of node_views_analyze().
*/
public function testNodeViewsAnalyze() {
// Create user with permission to view analyze message on views_ui.
$admin_user = $this->createUser(['administer views']);
$this->drupalLogin($admin_user);
// Access to views analyze page.
$this->drupalGet('admin/structure/views/nojs/analyze/test_node_views_analyze/page_1');
// Should return 200 with correct permission.
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->responseContains('has set node/% as path. This will not produce what you want. If you want to have multiple versions of the node view, use Layout Builder.');
}
}
@@ -52,24 +52,24 @@ class MigrateNodeTest extends MigrateNodeTestBase {
$node = Node::load(1);
$this->assertIdentical('1', $node->id(), 'Node 1 loaded.');
$this->assertIdentical('und', $node->langcode->value);
$this->assertIdentical('test', $node->body->value);
$this->assertIdentical('test', $node->body->summary);
$this->assertIdentical('body test rev 3', $node->body->value);
$this->assertIdentical('teaser test rev 3', $node->body->summary);
$this->assertIdentical('filtered_html', $node->body->format);
$this->assertIdentical('story', $node->getType(), 'Node has the correct bundle.');
$this->assertIdentical('Test title', $node->getTitle(), 'Node has the correct title.');
$this->assertIdentical('Test title rev 3', $node->getTitle(), 'Node has the correct title.');
$this->assertIdentical('1390095702', $node->getCreatedTime(), 'Node has the correct created time.');
$this->assertIdentical(FALSE, $node->isSticky());
$this->assertIdentical('1', $node->getOwnerId());
$this->assertIdentical('1390095702', $node->getRevisionCreationTime());
$this->assertIdentical('1420861423', $node->getRevisionCreationTime());
/** @var \Drupal\node\NodeInterface $node_revision */
$node_revision = \Drupal::entityTypeManager()->getStorage('node')->loadRevision(1);
$this->assertIdentical('Test title', $node_revision->getTitle());
$this->assertIdentical('1', $node_revision->getRevisionUser()->id(), 'Node revision has the correct user');
$node_revision = \Drupal::entityTypeManager()->getStorage('node')->loadRevision(2001);
$this->assertIdentical('Test title rev 3', $node_revision->getTitle());
$this->assertIdentical('2', $node_revision->getRevisionUser()->id(), 'Node revision has the correct user');
$this->assertSame('1', $node_revision->id(), 'Node 1 loaded.');
$this->assertSame('1', $node_revision->getRevisionId(), 'Node 1 revision 1 loaded.');
$this->assertSame('2001', $node_revision->getRevisionId(), 'Node 1 revision 2001 loaded.');
// This is empty on the first revision.
$this->assertIdentical(NULL, $node_revision->revision_log->value);
$this->assertIdentical('modified rev 3', $node_revision->revision_log->value);
$this->assertIdentical('This is a shared text field', $node->field_test->value);
$this->assertIdentical('filtered_html', $node->field_test->format);
$this->assertIdentical('10', $node->field_test_two->value);
@@ -30,7 +30,11 @@ class NodeAccessRecordsTest extends NodeAccessTestBase {
// Check to see if grants added by node_test_node_access_records made it in.
$connection = Database::getConnection();
$records = $connection->query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node1->id()])->fetchAll();
$records = $connection->select('node_access', 'na')
->fields('na', ['realm', 'gid'])
->condition('nid', $node1->id())
->execute()
->fetchAll();
$this->assertCount(1, $records, 'Returned the correct number of rows.');
$this->assertEqual($records[0]->realm, 'test_article_realm', 'Grant with article_realm acquired for node without alteration.');
$this->assertEqual($records[0]->gid, 1, 'Grant with gid = 1 acquired for node without alteration.');
@@ -40,7 +44,11 @@ class NodeAccessRecordsTest extends NodeAccessTestBase {
$this->assertNotEmpty(Node::load($node2->id()), 'Unpromoted basic page node created.');
// Check to see if grants added by node_test_node_access_records made it in.
$records = $connection->query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node2->id()])->fetchAll();
$records = $connection->select('node_access', 'na')
->fields('na', ['realm', 'gid'])
->condition('nid', $node2->id())
->execute()
->fetchAll();
$this->assertCount(1, $records, 'Returned the correct number of rows.');
$this->assertEqual($records[0]->realm, 'test_page_realm', 'Grant with page_realm acquired for node without alteration.');
$this->assertEqual($records[0]->gid, 1, 'Grant with gid = 1 acquired for node without alteration.');
@@ -50,7 +58,11 @@ class NodeAccessRecordsTest extends NodeAccessTestBase {
$this->assertNotEmpty(Node::load($node3->id()), 'Unpromoted, unpublished basic page node created.');
// Check to see if grants added by node_test_node_access_records made it in.
$records = $connection->query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node3->id()])->fetchAll();
$records = $connection->select('node_access', 'na')
->fields('na', ['realm', 'gid'])
->condition('nid', $node3->id())
->execute()
->fetchAll();
$this->assertCount(1, $records, 'Returned the correct number of rows.');
$this->assertEqual($records[0]->realm, 'test_page_realm', 'Grant with page_realm acquired for node without alteration.');
$this->assertEqual($records[0]->gid, 1, 'Grant with gid = 1 acquired for node without alteration.');
@@ -61,7 +73,11 @@ class NodeAccessRecordsTest extends NodeAccessTestBase {
// Check to see if grant added by node_test_node_access_records was altered
// by node_test_node_access_records_alter.
$records = $connection->query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node4->id()])->fetchAll();
$records = $connection->select('node_access', 'na')
->fields('na', ['realm', 'gid'])
->condition('nid', $node4->id())
->execute()
->fetchAll();
$this->assertCount(1, $records, 'Returned the correct number of rows.');
$this->assertEqual($records[0]->realm, 'test_alter_realm', 'Altered grant with alter_realm acquired for node.');
$this->assertEqual($records[0]->gid, 2, 'Altered grant with gid = 2 acquired for node.');
@@ -80,7 +96,11 @@ class NodeAccessRecordsTest extends NodeAccessTestBase {
// Check that core does not grant access to an unpublished node when an
// empty $grants array is returned.
$node6 = $this->drupalCreateNode(['status' => 0, 'disable_node_access' => TRUE]);
$records = $connection->query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node6->id()])->fetchAll();
$records = $connection->select('node_access', 'na')
->fields('na', ['realm', 'gid'])
->condition('nid', $node6->id())
->execute()
->fetchAll();
$this->assertCount(0, $records, 'Returned no records for unpublished node.');
}