Update to Drupal 8.2.0. For more information, see https://www.drupal.org/project/drupal/releases/8.2.0

This commit is contained in:
Pantheon Automation 2016-10-06 15:16:20 -07:00 committed by Greg Anderson
parent 2f563ab520
commit f1c8716f57
1732 changed files with 52334 additions and 11780 deletions

View file

@ -106,7 +106,7 @@ display:
id: status
table: node_field_data
field: status
value: true
value: '1'
group: 0
expose:
operator: '0'

View file

@ -370,7 +370,7 @@ display:
group_type: group
admin_label: ''
operator: '='
value: true
value: '1'
group: 1
exposed: true
expose:

View file

@ -105,7 +105,7 @@ display:
operator: '='
relationship: none
table: node_field_data
value: true
value: '1'
plugin_id: boolean
entity_type: node
entity_field: promote
@ -116,7 +116,7 @@ display:
group: 1
id: status
table: node_field_data
value: true
value: '1'
plugin_id: boolean
entity_type: node
entity_field: status

View file

@ -6,7 +6,7 @@ node.settings:
mapping:
use_admin_theme:
type: boolean
label: 'Use admin theme when editing or creating content'
label: 'Use administration theme when editing or creating content'
node.type.*:
type: config_entity

View file

@ -11,6 +11,9 @@ process:
entity_type: 'constants/entity_type'
bundle: type
field_name: 'constants/field_name'
label:
plugin: default_value
default_value: 'Publishing status'
'default_value/0/value': 'options/status'
destination:
plugin: entity:base_field_override

View file

@ -492,8 +492,7 @@ function hook_node_links_alter(array &$links, NodeInterface $entity, array &$con
'#links' => array(
'node-report' => array(
'title' => t('Report'),
'href' => "node/{$entity->id()}/report",
'query' => array('token' => \Drupal::getContainer()->get('csrf_token')->get("node/{$entity->id()}/report")),
'url' => Url::fromRoute('node_test.report', ['node' => $entity->id()], ['query' => ['token' => \Drupal::getContainer()->get('csrf_token')->get("node/{$entity->id()}/report")]]),
),
),
);

View file

@ -320,7 +320,7 @@ function node_type_load($name) {
* A Body field object.
*/
function node_add_body_field(NodeTypeInterface $type, $label = 'Body') {
// Add or remove the body field, as needed.
// Add or remove the body field, as needed.
$field_storage = FieldStorageConfig::loadByName('node', 'body');
$field = FieldConfig::loadByName('node', $type->id(), 'body');
if (empty($field)) {
@ -751,7 +751,7 @@ function node_get_recent($number = 10) {
// If not, restrict the query to published nodes.
$query->condition('status', NODE_PUBLISHED);
}
}
}
$nids = $query
->sort('changed', 'DESC')
->range(0, $number)

View file

@ -12,7 +12,6 @@ administer nodes:
restrict access: true
access content overview:
title: 'Access the Content overview page'
description: 'Get an overview of all content.'
access content:
title: 'View published content'
view own unpublished content:

View file

@ -172,9 +172,9 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
$delete_permission = (($account->hasPermission("delete $type revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $node->access('delete'));
$rows = array();
$latest_revision = TRUE;
$default_revision = $node->getRevisionId();
foreach ($this->_getRevisionIds($node, $node_storage) as $vid) {
foreach ($this->getRevisionIds($node, $node_storage) as $vid) {
/** @var \Drupal\node\NodeInterface $revision */
$revision = $node_storage->loadRevision($vid);
// Only show revisions that are affected by the language that is being
@ -182,7 +182,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) {
$username = [
'#theme' => 'username',
'#account' => $revision->getRevisionAuthor(),
'#account' => $revision->getRevisionUser(),
];
// Use revision link to link to revisions that are not active.
@ -210,7 +210,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
$this->renderer->addCacheableDependency($column['data'], $username);
$row[] = $column;
if ($latest_revision) {
if ($vid == $default_revision) {
$row[] = [
'data' => [
'#prefix' => '<em>',
@ -218,16 +218,17 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
'#suffix' => '</em>',
],
];
foreach ($row as &$current) {
$current['class'] = ['revision-current'];
}
$latest_revision = FALSE;
$rows[] = [
'data' => $row,
'class' => ['revision-current'],
];
}
else {
$links = [];
if ($revert_permission) {
$links['revert'] = [
'title' => $this->t('Revert'),
'title' => $vid < $node->getRevisionId() ? $this->t('Revert') : $this->t('Set as current revision'),
'url' => $has_translations ?
Url::fromRoute('node.revision_revert_translation_confirm', ['node' => $node->id(), 'node_revision' => $vid, 'langcode' => $langcode]) :
Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid]),
@ -247,9 +248,9 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
'#links' => $links,
],
];
}
$rows[] = $row;
$rows[] = $row;
}
}
}
@ -260,6 +261,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
'#attached' => array(
'library' => array('node/drupal.node.admin'),
),
'#attributes' => ['class' => 'node-revision-table'],
);
$build['pager'] = array('#type' => 'pager');
@ -283,7 +285,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
/**
* Gets a list of node revision IDs for a specific node.
*
* @param \Drupal\node\NodeInterface
* @param \Drupal\node\NodeInterface $node
* The node entity.
* @param \Drupal\node\NodeStorageInterface $node_storage
* The node storage handler.
@ -291,7 +293,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
* @return int[]
* Node revision IDs (in descending order).
*/
protected function _getRevisionIds(NodeInterface $node, NodeStorageInterface $node_storage) {
protected function getRevisionIds(NodeInterface $node, NodeStorageInterface $node_storage) {
$result = $node_storage->getQuery()
->allRevisions()
->condition($node->getEntityType()->getKey('id'), $node->id())

View file

@ -102,8 +102,8 @@ class Node extends ContentEntityBase implements NodeInterface {
// If no revision author has been set explicitly, make the node owner the
// revision author.
if (!$this->getRevisionAuthor()) {
$this->setRevisionAuthorId($this->getOwnerId());
if (!$this->getRevisionUser()) {
$this->setRevisionUserId($this->getOwnerId());
}
}
@ -178,13 +178,8 @@ class Node extends ContentEntityBase implements NodeInterface {
* {@inheritdoc}
*/
public function access($operation = 'view', AccountInterface $account = NULL, $return_as_object = FALSE) {
if ($operation == 'create') {
return parent::access($operation, $account, $return_as_object);
}
return \Drupal::entityManager()
->getAccessControlHandler($this->entityTypeId)
->access($this, $operation, $account, $return_as_object);
// This override exists to set the operation to the default value "view".
return parent::access($operation, $account, $return_as_object);
}
/**
@ -311,6 +306,13 @@ class Node extends ContentEntityBase implements NodeInterface {
* {@inheritdoc}
*/
public function getRevisionAuthor() {
return $this->getRevisionUser();
}
/**
* {@inheritdoc}
*/
public function getRevisionUser() {
return $this->get('revision_uid')->entity;
}
@ -318,7 +320,45 @@ class Node extends ContentEntityBase implements NodeInterface {
* {@inheritdoc}
*/
public function setRevisionAuthorId($uid) {
$this->set('revision_uid', $uid);
$this->setRevisionUserId($uid);
return $this;
}
/**
* {@inheritdoc}
*/
public function setRevisionUser(UserInterface $user) {
$this->set('revision_uid', $user);
return $this;
}
/**
* {@inheritdoc}
*/
public function getRevisionUserId() {
return $this->get('revision_uid')->entity->id();
}
/**
* {@inheritdoc}
*/
public function setRevisionUserId($user_id) {
$this->set('revision_uid', $user_id);
return $this;
}
/**
* {@inheritdoc}
*/
public function getRevisionLogMessage() {
return $this->get('revision_log')->value;
}
/**
* {@inheritdoc}
*/
public function setRevisionLogMessage($revision_log_message) {
$this->set('revision_log', $revision_log_message);
return $this;
}

View file

@ -83,7 +83,7 @@ class NodeType extends ConfigEntityBundleBase implements NodeTypeInterface {
*
* @var bool
*/
protected $new_revision = FALSE;
protected $new_revision = TRUE;
/**
* The preview mode.

View file

@ -3,7 +3,6 @@
namespace Drupal\node\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Form\FormBase;
@ -14,7 +13,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Contains a form for switching the view mode of a node during preview.
*/
class NodePreviewForm extends FormBase implements ContainerInjectionInterface {
class NodePreviewForm extends FormBase {
/**
* The entity manager service.

View file

@ -322,7 +322,7 @@ class NodeForm extends ContentEntityForm {
$node->setNewRevision();
// If a new revision is created, save the current user as revision author.
$node->setRevisionCreationTime(REQUEST_TIME);
$node->setRevisionAuthorId(\Drupal::currentUser()->id());
$node->setRevisionUserId(\Drupal::currentUser()->id());
}
else {
$node->setNewRevision(FALSE);
@ -356,7 +356,7 @@ class NodeForm extends ContentEntityForm {
$node->save();
$node_link = $node->link($this->t('View'));
$context = array('@type' => $node->getType(), '%title' => $node->label(), 'link' => $node_link);
$t_args = array('@type' => node_get_type_label($node), '%title' => $node->label());
$t_args = array('@type' => node_get_type_label($node), '%title' => $node->link($node->label()));
if ($insert) {
$this->logger('content')->notice('@type: added %title.', $context);

View file

@ -2,6 +2,7 @@
namespace Drupal\node;
use Drupal\Core\Entity\RevisionLogInterface;
use Drupal\user\EntityOwnerInterface;
use Drupal\Core\Entity\EntityChangedInterface;
use Drupal\Core\Entity\ContentEntityInterface;
@ -9,7 +10,7 @@ use Drupal\Core\Entity\ContentEntityInterface;
/**
* Provides an interface defining a node entity.
*/
interface NodeInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface {
interface NodeInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface, RevisionLogInterface {
/**
* Gets the node type.
@ -140,6 +141,9 @@ interface NodeInterface extends ContentEntityInterface, EntityChangedInterface,
*
* @return \Drupal\user\UserInterface
* The user entity for the revision author.
*
* @deprecated in Drupal 8.2.0, will be removed before Drupal 9.0.0. Use
* \Drupal\Core\Entity\RevisionLogInterface::getRevisionUser() instead.
*/
public function getRevisionAuthor();
@ -151,6 +155,9 @@ interface NodeInterface extends ContentEntityInterface, EntityChangedInterface,
*
* @return \Drupal\node\NodeInterface
* The called node entity.
*
* @deprecated in Drupal 8.2.0, will be removed before Drupal 9.0.0. Use
* \Drupal\Core\Entity\RevisionLogInterface::setRevisionUserId() instead.
*/
public function setRevisionAuthorId($uid);

View file

@ -14,7 +14,7 @@ interface NodeStorageInterface extends ContentEntityStorageInterface {
/**
* Gets a list of node revision IDs for a specific node.
*
* @param \Drupal\node\NodeInterface
* @param \Drupal\node\NodeInterface $node
* The node entity.
*
* @return int[]
@ -36,7 +36,7 @@ interface NodeStorageInterface extends ContentEntityStorageInterface {
/**
* Counts the number of revisions in the default language.
*
* @param \Drupal\node\NodeInterface
* @param \Drupal\node\NodeInterface $node
* The node entity.
*
* @return int

View file

@ -21,7 +21,6 @@ class NodeTypeAccessControlHandler extends EntityAccessControlHandler {
switch ($operation) {
case 'view':
return AccessResult::allowedIfHasPermission($account, 'access content');
break;
case 'delete':
if ($entity->isLocked()) {
@ -34,7 +33,7 @@ class NodeTypeAccessControlHandler extends EntityAccessControlHandler {
default:
return parent::checkAccess($entity, $operation, $account);
break;
}
}

View file

@ -261,7 +261,7 @@ class Node extends DrupalSqlBase {
/**
* Adapt our query for translations.
*
* @param \Drupal\Core\Database\Query\SelectInterface
* @param \Drupal\Core\Database\Query\SelectInterface $query
* The generated query.
*/
protected function handleTranslations(SelectInterface $query) {

View file

@ -39,7 +39,7 @@ class Vid extends NumericArgument {
* The plugin implementation definition.
* @param \Drupal\Core\Database\Connection $database
* Database Service Object.
* @param \Drupal\node\NodeStorageInterface
* @param \Drupal\node\NodeStorageInterface $node_storage
* The node storage.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database, NodeStorageInterface $node_storage) {

View file

@ -49,7 +49,7 @@ class Node extends WizardPluginBase {
public function getAvailableSorts() {
// You can't execute functions in properties, so override the method
return array(
'node_field_data-title:DESC' => $this->t('Title')
'node_field_data-title:ASC' => $this->t('Title')
);
}
@ -217,7 +217,7 @@ class Node extends WizardPluginBase {
// entities. If a particular entity type (i.e., bundle) has been
// selected above, then we only search for taxonomy fields associated
// with that bundle. Otherwise, we use all bundles.
$bundles = array_keys(entity_get_bundles($this->entityTypeId));
$bundles = array_keys($this->bundleInfoService->getBundleInfo($this->entityTypeId));
// Double check that this is a real bundle before using it (since above
// we added a dummy option 'all' to the bundle list on the form).
if (isset($selected_bundle) && in_array($selected_bundle, $bundles)) {

View file

@ -35,14 +35,14 @@ class MigrateNodeRevisionTest extends MigrateNodeTestBase {
$this->assertIdentical('Test title rev 2', $node->getTitle());
$this->assertIdentical('body test rev 2', $node->body->value);
$this->assertIdentical('teaser test rev 2', $node->body->summary);
$this->assertIdentical('2', $node->getRevisionAuthor()->id());
$this->assertIdentical('2', $node->getRevisionUser()->id());
$this->assertIdentical('modified rev 2', $node->revision_log->value);
$this->assertIdentical('1390095702', $node->getRevisionCreationTime());
$node = \Drupal::entityManager()->getStorage('node')->loadRevision(5);
$this->assertIdentical('1', $node->id());
$this->assertIdentical('body test rev 3', $node->body->value);
$this->assertIdentical('1', $node->getRevisionAuthor()->id());
$this->assertIdentical('1', $node->getRevisionUser()->id());
$this->assertIdentical('modified rev 3', $node->revision_log->value);
$this->assertIdentical('1390095703', $node->getRevisionCreationTime());
}

View file

@ -1,33 +0,0 @@
<?php
namespace Drupal\node\Tests;
/**
* Tests basic node_access functionality with hook_node_grants().
*
* This test just wraps the existing default permissions test while a module
* that implements hook_node_grants() is enabled.
*
* @see \Drupal\node\NodeGrantDatabaseStorage
*
* @group node
*/
class NodeAccessGrantsTest extends NodeAccessTest {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('node_access_test_empty');
/**
* Test operations not supported by node grants.
*/
function testUnsupportedOperation() {
$web_user = $this->drupalCreateUser(['access content']);
$node = $this->drupalCreateNode();
$this->assertNodeAccess(['random_operation' => FALSE], $node, $web_user);
}
}

View file

@ -254,9 +254,9 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
// Query with no language specified. The fallback (hu or und) will be used.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// Four nodes should be returned with public Hungarian translations or the
@ -269,10 +269,10 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
// Query with Hungarian (hu) specified.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addMetaData('langcode', 'hu')
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addMetaData('langcode', 'hu')
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// Three nodes should be returned (with public Hungarian translations).
@ -283,10 +283,10 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
// Query with Catalan (ca) specified.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addMetaData('langcode', 'ca')
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addMetaData('langcode', 'ca')
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// Three nodes should be returned (with public Catalan translations).
@ -297,10 +297,10 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
// Query with German (de) specified.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addMetaData('langcode', 'de')
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addMetaData('langcode', 'de')
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// There are no nodes with German translations, so no results are returned.
@ -309,9 +309,9 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
// Query the nodes table as admin user (full access) with the node access
// tag and no specific langcode.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $this->adminUser)
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $this->adminUser)
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// All nodes are returned.
@ -320,10 +320,10 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
// Query the nodes table as admin user (full access) with the node access
// tag and langcode de.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $this->adminUser)
->addMetaData('langcode', 'de')
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $this->adminUser)
->addMetaData('langcode', 'de')
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// Even though there is no German translation, all nodes are returned

View file

@ -195,9 +195,9 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
// Query with no language specified. The fallback (hu) will be used.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// Three nodes should be returned:
@ -211,10 +211,10 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
// Query with Hungarian (hu) specified.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addMetaData('langcode', 'hu')
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addMetaData('langcode', 'hu')
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// Two nodes should be returned: the node with both translations public, and
@ -225,10 +225,10 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
// Query with Catalan (ca) specified.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addMetaData('langcode', 'ca')
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addMetaData('langcode', 'ca')
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// Two nodes should be returned: the node with both translations public, and
@ -239,10 +239,10 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
// Query with German (de) specified.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addMetaData('langcode', 'de')
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $this->webUser)
->addMetaData('langcode', 'de')
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// There are no nodes with German translations, so no results are returned.
@ -251,9 +251,9 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
// Query the nodes table as admin user (full access) with the node access
// tag and no specific langcode.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $this->adminUser)
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $this->adminUser)
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// All nodes are returned.
@ -262,10 +262,10 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
// Query the nodes table as admin user (full access) with the node access
// tag and langcode de.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $this->adminUser)
->addMetaData('langcode', 'de')
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $this->adminUser)
->addMetaData('langcode', 'de')
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// Even though there is no German translation, all nodes are returned

View file

@ -204,9 +204,9 @@ class NodeAccessLanguageTest extends NodeTestBase {
// Query the nodes table as the web user with the node access tag and no
// specific langcode.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $web_user)
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $web_user)
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// The public node and no language node should be returned. Because no
@ -218,10 +218,10 @@ class NodeAccessLanguageTest extends NodeTestBase {
// Query the nodes table as the web user with the node access tag and
// langcode de.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $web_user)
->addMetaData('langcode', 'de')
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $web_user)
->addMetaData('langcode', 'de')
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// Because no nodes are created in German, no nodes are returned.
@ -230,9 +230,9 @@ class NodeAccessLanguageTest extends NodeTestBase {
// Query the nodes table as admin user (full access) with the node access
// tag and no specific langcode.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $admin_user)
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $admin_user)
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// All nodes are returned.
@ -241,10 +241,10 @@ class NodeAccessLanguageTest extends NodeTestBase {
// Query the nodes table as admin user (full access) with the node access
// tag and langcode de.
$select = db_select('node', 'n')
->fields('n', array('nid'))
->addMetaData('account', $admin_user)
->addMetaData('langcode', 'de')
->addTag('node_access');
->fields('n', array('nid'))
->addMetaData('account', $admin_user)
->addMetaData('langcode', 'de')
->addTag('node_access');
$nids = $select->execute()->fetchAllAssoc('nid');
// All nodes are returned because node access tag is not invoked when the

View file

@ -1,72 +0,0 @@
<?php
namespace Drupal\node\Tests;
use Drupal\user\RoleInterface;
/**
* Tests basic node_access functionality.
*
* Note that hook_node_access_records() is covered in another test class.
*
* @group node
* @todo Cover hook_node_access in a separate test class.
*/
class NodeAccessTest extends NodeTestBase {
protected function setUp() {
parent::setUp();
// Clear permissions for authenticated users.
$this->config('user.role.' . RoleInterface::AUTHENTICATED_ID)->set('permissions', array())->save();
}
/**
* Runs basic tests for node_access function.
*/
function testNodeAccess() {
// Ensures user without 'access content' permission can do nothing.
$web_user1 = $this->drupalCreateUser(array('create page content', 'edit any page content', 'delete any page content'));
$node1 = $this->drupalCreateNode(array('type' => 'page'));
$this->assertNodeCreateAccess($node1->bundle(), FALSE, $web_user1);
$this->assertNodeAccess(array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE), $node1, $web_user1);
// Ensures user with 'bypass node access' permission can do everything.
$web_user2 = $this->drupalCreateUser(array('bypass node access'));
$node2 = $this->drupalCreateNode(array('type' => 'page'));
$this->assertNodeCreateAccess($node2->bundle(), TRUE, $web_user2);
$this->assertNodeAccess(array('view' => TRUE, 'update' => TRUE, 'delete' => TRUE), $node2, $web_user2);
// User cannot 'view own unpublished content'.
$web_user3 = $this->drupalCreateUser(array('access content'));
$node3 = $this->drupalCreateNode(array('status' => 0, 'uid' => $web_user3->id()));
$this->assertNodeAccess(array('view' => FALSE), $node3, $web_user3);
// User cannot create content without permission.
$this->assertNodeCreateAccess($node3->bundle(), FALSE, $web_user3);
// User can 'view own unpublished content', but another user cannot.
$web_user4 = $this->drupalCreateUser(array('access content', 'view own unpublished content'));
$web_user5 = $this->drupalCreateUser(array('access content', 'view own unpublished content'));
$node4 = $this->drupalCreateNode(array('status' => 0, 'uid' => $web_user4->id()));
$this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE), $node4, $web_user4);
$this->assertNodeAccess(array('view' => FALSE), $node4, $web_user5);
// Tests the default access provided for a published node.
$node5 = $this->drupalCreateNode();
$this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE), $node5, $web_user3);
// Tests the "edit any BUNDLE" and "delete any BUNDLE" permissions.
$web_user6 = $this->drupalCreateUser(array('access content', 'edit any page content', 'delete any page content'));
$node6 = $this->drupalCreateNode(array('type' => 'page'));
$this->assertNodeAccess(array('view' => TRUE, 'update' => TRUE, 'delete' => TRUE), $node6, $web_user6);
// Tests the "edit own BUNDLE" and "delete own BUNDLE" permission.
$web_user7 = $this->drupalCreateUser(array('access content', 'edit own page content', 'delete own page content'));
// User should not be able to edit or delete nodes they do not own.
$this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE), $node6, $web_user7);
// User should be able to edit or delete nodes they own.
$node7 = $this->drupalCreateNode(array('type' => 'page', 'uid' => $web_user7->id()));
$this->assertNodeAccess(array('view' => TRUE, 'update' => TRUE, 'delete' => TRUE), $node7, $web_user7);
}
}

View file

@ -48,7 +48,11 @@ class NodeCreationTest extends NodeTestBase {
$this->drupalPostForm('node/add/page', $edit, t('Save'));
// Check that the Basic page has been created.
$this->assertRaw(t('@post %title has been created.', array('@post' => 'Basic page', '%title' => $edit['title[0][value]'])), 'Basic page created.');
$this->assertText(t('@post @title has been created.', array('@post' => 'Basic page', '@title' => $edit['title[0][value]'])), 'Basic page created.');
// Verify that the creation message contains a link to a node.
$view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', array(':href' => 'node/'));
$this->assert(isset($view_link), 'The message area contains a link to a node');
// Check that the node exists in the database.
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
@ -137,7 +141,11 @@ class NodeCreationTest extends NodeTestBase {
$this->assertText(t('Test page text'));
// Confirm that the node was created.
$this->assertRaw(t('@post %title has been created.', array('@post' => 'Basic page', '%title' => $edit['title[0][value]'])));
$this->assertText(t('@post @title has been created.', array('@post' => 'Basic page', '@title' => $edit['title[0][value]'])));
// Verify that the creation message contains a link to a node.
$view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', array(':href' => 'node/'));
$this->assert(isset($view_link), 'The message area contains a link to a node');
}
/**

View file

@ -110,7 +110,7 @@ class NodeEditFormTest extends NodeTestBase {
// made by different users.
$first_node_version = node_revision_load($node->getRevisionId());
$second_node_version = node_revision_load($revised_node->getRevisionId());
$this->assertNotIdentical($first_node_version->getRevisionAuthor()->id(), $second_node_version->getRevisionAuthor()->id(), 'Each revision has a distinct user.');
$this->assertNotIdentical($first_node_version->getRevisionUser()->id(), $second_node_version->getRevisionUser()->id(), 'Each revision has a distinct user.');
}
/**

View file

@ -119,7 +119,7 @@ class NodeFieldMultilingualTest extends WebTestBase {
// Check if node body is showed.
$this->drupalGet('node/' . $node->id());
$body = $this->xpath('//article[contains(concat(" ", normalize-space(@class), " "), :node-class)]//div[contains(concat(" ", normalize-space(@class), " "), :content-class)]/descendant::p', array(
$body = $this->xpath('//article[contains(concat(" ", normalize-space(@class), " "), :node-class)]//div[contains(concat(" ", normalize-space(@class), " "), :content-class)]/descendant::p', array(
':node-class' => ' node ',
':content-class' => 'node__content',
));

View file

@ -52,11 +52,13 @@ class NodeFormSaveChangedTimeTest extends WebTestBase {
* Test the changed time after API and FORM save without changes.
*/
public function testChangedTimeAfterSaveWithoutChanges() {
$node = entity_load('node', 1);
$storage = $this->container->get('entity_type.manager')->getStorage('node');
$storage->resetCache([1]);
$node = $storage->load(1);
$changed_timestamp = $node->getChangedTime();
$node->save();
$node = entity_load('node', 1, TRUE);
$storage->resetCache([1]);
$node = $storage->load(1);
$this->assertEqual($changed_timestamp, $node->getChangedTime(), "The entity's changed time wasn't updated after API save without changes.");
// Ensure different save timestamps.
@ -65,7 +67,8 @@ class NodeFormSaveChangedTimeTest extends WebTestBase {
// Save the node on the regular node edit form.
$this->drupalPostForm('node/1/edit', array(), t('Save'));
$node = entity_load('node', 1, TRUE);
$storage->resetCache([1]);
$node = $storage->load(1);
$this->assertNotEqual($changed_timestamp, $node->getChangedTime(), "The entity's changed time was updated after form save without changes.");
}

View file

@ -39,9 +39,9 @@ class NodeLoadMultipleTest extends NodeTestBase {
$this->assertText($node2->label(), 'Node title appears on the default listing.');
$this->assertNoText($node3->label(), 'Node title does not appear in the default listing.');
$this->assertNoText($node4->label(), 'Node title does not appear in the default listing.');
// Load nodes with only a condition. Nodes 3 and 4 will be loaded.
$nodes = entity_load_multiple_by_properties('node', array('promote' => 0));
$nodes = $this->container->get('entity_type.manager')->getStorage('node')
->loadByProperties(array('promote' => 0));
$this->assertEqual($node3->label(), $nodes[$node3->id()]->label(), 'Node was loaded.');
$this->assertEqual($node4->label(), $nodes[$node4->id()]->label(), 'Node was loaded.');
$count = count($nodes);

View file

@ -109,10 +109,10 @@ class NodeRevisionsTest extends NodeTestBase {
// Edit the 2nd revision with a different user.
if ($i == 1) {
$editor = $this->drupalCreateUser();
$node->setRevisionAuthorId($editor->id());
$node->setRevisionUserId($editor->id());
}
else {
$node->setRevisionAuthorId($web_user->id());
$node->setRevisionUserId($web_user->id());
}
$node->save();

View file

@ -121,4 +121,43 @@ class NodeRevisionsUiTest extends NodeTestBase {
$this->assertRaw($nodes[1]->link($date) . ' by ' . $editor . '<p class="revision-log">' . $revision_log . '</p>');
}
/**
* Checks the Revisions tab.
*/
public function testNodeRevisionsTabWithDefaultRevision() {
$this->drupalLogin($this->editor);
// Create the node.
$node = $this->drupalCreateNode();
$node->setNewRevision(TRUE);
$node->save();
$node->setNewRevision(TRUE);
$node->save();
$node->isDefaultRevision(FALSE);
$node->setNewRevision(TRUE);
$node->save();
$node->isDefaultRevision(FALSE);
$node->setNewRevision(TRUE);
$node->save();
$node_id = $node->id();
$this->drupalGet('node/' . $node_id . '/revisions');
// Verify that the default revision can be an older revision than the latest
// one.
$this->assertLinkByHref('/node/' . $node_id . '/revisions/5/revert');
$this->assertLinkByHref('/node/' . $node_id . '/revisions/4/revert');
$this->assertNoLinkByHref('/node/' . $node_id . '/revisions/3/revert');
$current_revision_row = $this->xpath("//table[contains(@class, :table_class)]//tbody//tr[3 and contains(@class, :class) and contains(., :text)]", [
':table_class' => 'node-revision-table',
':class' => 'revision-current',
':text' => 'Current revision',
]);
$this->assertEqual(count($current_revision_row), 1, 'The default revision can be a revision other than the latest one.');
$this->assertLinkByHref('/node/' . $node_id . '/revisions/2/revert');
$this->assertLinkByHref('/node/' . $node_id . '/revisions/1/revert');
}
}

View file

@ -83,7 +83,10 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
$default_langcode = $this->langcodes[0];
$values[$default_langcode] = array('title' => array(array('value' => $this->randomMachineName())));
$entity_id = $this->createEntity($values[$default_langcode], $default_langcode);
$entity = entity_load($this->entityTypeId, $entity_id, TRUE);
$storage = $this->container->get('entity_type.manager')
->getStorage($this->entityTypeId);
$storage->resetCache([$this->entityId]);
$entity = $storage->load($this->entityId);
// Add a content translation.
$langcode = 'fr';
@ -98,7 +101,8 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
], array('language' => $language));
$this->drupalPostForm($add_url, $this->getEditValues($values, $langcode), t('Save and unpublish (this translation)'));
$entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
$storage->resetCache([$this->entityId]);
$entity = $storage->load($this->entityId);
$translation = $entity->getTranslation($langcode);
// Make sure we unpublished the node correctly.
$this->assertFalse($this->manager->getTranslationMetadata($translation)->isPublished(), 'The translation has been correctly unpublished.');
@ -148,7 +152,10 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
* {@inheritdoc}
*/
protected function doTestPublishedStatus() {
$entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
$storage = $this->container->get('entity_type.manager')
->getStorage($this->entityTypeId);
$storage->resetCache([$this->entityId]);
$entity = $storage->load($this->entityId);
$languages = $this->container->get('language_manager')->getLanguages();
$actions = array(
@ -164,7 +171,8 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
$url = $entity->urlInfo('edit-form', $options);
$this->drupalPostForm($url, array(), $action . $this->getFormSubmitSuffix($entity, $langcode), $options);
}
$entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
$storage->resetCache([$this->entityId]);
$entity = $storage->load($this->entityId);
foreach ($this->langcodes as $langcode) {
// The node is created as unpublished thus we switch to the published
// status first.
@ -179,7 +187,10 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
* {@inheritdoc}
*/
protected function doTestAuthoringInfo() {
$entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
$storage = $this->container->get('entity_type.manager')
->getStorage($this->entityTypeId);
$storage->resetCache([$this->entityId]);
$entity = $storage->load($this->entityId);
$languages = $this->container->get('language_manager')->getLanguages();
$values = array();
@ -204,7 +215,8 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
$this->drupalPostForm($url, $edit, $this->getFormSubmitAction($entity, $langcode), $options);
}
$entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
$storage->resetCache([$this->entityId]);
$entity = $storage->load($this->entityId);
foreach ($this->langcodes as $langcode) {
$translation = $entity->getTranslation($langcode);
$metadata = $this->manager->getTranslationMetadata($translation);
@ -424,7 +436,10 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
* {@inheritdoc}
*/
protected function doTestTranslationEdit() {
$entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
$storage = $this->container->get('entity_type.manager')
->getStorage($this->entityTypeId);
$storage->resetCache([$this->entityId]);
$entity = $storage->load($this->entityId);
$languages = $this->container->get('language_manager')->getLanguages();
$type_name = node_get_type_label($entity);

View file

@ -87,7 +87,7 @@ class BulkFormAccessTest extends NodeTestBase {
'node_bulk_form[0]' => TRUE,
'action' => 'node_unpublish_action',
);
$this->drupalPostForm('test-node-bulk-form', $edit, t('Apply'));
$this->drupalPostForm('test-node-bulk-form', $edit, t('Apply to selected items'));
$this->assertRaw(SafeMarkup::format('No access to execute %action on the @entity_type_label %entity_label.', [
'%action' => 'Unpublish content',
'@entity_type_label' => 'Content',
@ -115,7 +115,11 @@ class BulkFormAccessTest extends NodeTestBase {
'node_bulk_form[0]' => TRUE,
'action' => 'node_unpublish_action',
);
$this->drupalPostForm('test-node-bulk-form', $edit, t('Apply'));
$this->drupalPostForm('test-node-bulk-form', $edit, t('Apply to selected items'));
// Test that the action message isn't shown.
$this->assertNoRaw(SafeMarkup::format('%action was applied to 1 item.', [
'%action' => 'Unpublish content',
]));
// Re-load the node and check the status.
$node = Node::load($node->id());
$this->assertTrue($node->isPublished(), 'The node is still published.');
@ -160,7 +164,7 @@ class BulkFormAccessTest extends NodeTestBase {
'node_bulk_form[1]' => TRUE,
'action' => 'node_delete_action',
);
$this->drupalPostForm('test-node-bulk-form', $edit, t('Apply'));
$this->drupalPostForm('test-node-bulk-form', $edit, t('Apply to selected items'));
$this->drupalPostForm(NULL, array(), t('Delete'));
// Ensure the private node still exists.
$private_node = Node::load($private_node->id());

View file

@ -105,7 +105,7 @@ class BulkFormTest extends NodeTestBase {
'node_bulk_form[0]' => TRUE,
'action' => 'node_unpublish_action',
);
$this->drupalPostForm(NULL, $edit, t('Apply'));
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
$node = $this->loadNode($node->id());
$this->assertFalse($node->isPublished(), 'Node has been unpublished');
$this->assertTrue($node->getTranslation('en-gb')->isPublished(), 'Node translation has not been unpublished');
@ -116,7 +116,7 @@ class BulkFormTest extends NodeTestBase {
'node_bulk_form[0]' => TRUE,
'action' => 'node_publish_action',
);
$this->drupalPostForm(NULL, $edit, t('Apply'));
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
$node = $this->loadNode($node->id());
$this->assertTrue($node->isPublished(), 'Node has been published again');
@ -128,7 +128,7 @@ class BulkFormTest extends NodeTestBase {
'node_bulk_form[0]' => TRUE,
'action' => 'node_make_sticky_action',
);
$this->drupalPostForm(NULL, $edit, t('Apply'));
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
$node = $this->loadNode($node->id());
$this->assertTrue($node->isSticky(), 'Node has been made sticky');
$this->assertFalse($node->getTranslation('en-gb')->isSticky(), 'Node translation has not been made sticky');
@ -139,7 +139,7 @@ class BulkFormTest extends NodeTestBase {
'node_bulk_form[0]' => TRUE,
'action' => 'node_make_unsticky_action',
);
$this->drupalPostForm(NULL, $edit, t('Apply'));
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
$node = $this->loadNode($node->id());
$this->assertFalse($node->isSticky(), 'Node is not sticky anymore');
@ -151,7 +151,7 @@ class BulkFormTest extends NodeTestBase {
'node_bulk_form[0]' => TRUE,
'action' => 'node_promote_action',
);
$this->drupalPostForm(NULL, $edit, t('Apply'));
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
$node = $this->loadNode($node->id());
$this->assertTrue($node->isPromoted(), 'Node has been promoted to the front page');
$this->assertFalse($node->getTranslation('en-gb')->isPromoted(), 'Node translation has not been promoted to the front page');
@ -162,7 +162,7 @@ class BulkFormTest extends NodeTestBase {
'node_bulk_form[0]' => TRUE,
'action' => 'node_unpromote_action',
);
$this->drupalPostForm(NULL, $edit, t('Apply'));
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
$node = $this->loadNode($node->id());
$this->assertFalse($node->isPromoted(), 'Node has been demoted');
@ -185,7 +185,7 @@ class BulkFormTest extends NodeTestBase {
'node_bulk_form[9]' => FALSE, // Node 5, British English, untranslated.
'action' => 'node_unpublish_action',
);
$this->drupalPostForm(NULL, $edit, t('Apply'));
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
$node = $this->loadNode(1);
$this->assertFalse($node->getTranslation('en')->isPublished(), '1: English translation has been unpublished');
$this->assertFalse($node->getTranslation('en-gb')->isPublished(), '1: British English translation has been unpublished');
@ -226,7 +226,7 @@ class BulkFormTest extends NodeTestBase {
'node_bulk_form[9]' => FALSE, // Node 5, British English, untranslated.
'action' => 'node_delete_action',
);
$this->drupalPostForm(NULL, $edit, t('Apply'));
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
$label = $this->loadNode(1)->label();
$this->assertText("$label (Original translation) - The following content translations will be deleted:");

View file

@ -2,7 +2,7 @@ type: default
name: Default
description: 'Default description.'
help: ''
new_revision: false
new_revision: true
display_submitted: true
preview_mode: 1
status: true

View file

@ -91,7 +91,7 @@ display:
plugin_id: field
filters:
status:
value: true
value: '1'
table: node_field_data
field: status
id: status
@ -177,7 +177,7 @@ display:
filter_groups: false
filters:
status:
value: true
value: '1'
table: node_field_data
field: status
id: status
@ -244,7 +244,7 @@ display:
filter_groups: false
filters:
status:
value: true
value: '1'
table: node_field_data
field: status
id: status
@ -311,7 +311,7 @@ display:
filter_groups: false
filters:
status:
value: true
value: '1'
table: node_field_data
field: status
id: status

View file

@ -166,7 +166,7 @@ display:
type: language
filters:
status:
value: true
value: '1'
table: node_field_data
field: status
id: status

View file

@ -123,7 +123,7 @@ display:
plugin_id: node_path
filters:
status:
value: true
value: '1'
table: node_field_data
field: status
plugin_id: boolean

View file

@ -29,7 +29,7 @@ display:
group: 1
id: status
table: node_field_data
value: true
value: '1'
plugin_id: boolean
entity_type: node
entity_field: status

View file

@ -123,7 +123,7 @@ display:
entity_field: nid
filters:
status:
value: true
value: '1'
table: node_field_data
field: status
id: status

View file

@ -0,0 +1,32 @@
<?php
namespace Drupal\Tests\node\Kernel\Migrate\d6;
use Drupal\Core\Field\Entity\BaseFieldOverride;
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
/**
* @group migrate_drupal_6
*/
class MigrateNodeSettingStatusTest extends MigrateDrupal6TestBase {
public static $modules = ['node', 'text'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(['node']);
$this->executeMigration('d6_node_type');
$this->executeMigration('d6_node_setting_status');
}
/**
* Tests migration of the publishing status checkbox's settings.
*/
public function testMigration() {
$this->assertIdentical('Publishing status', BaseFieldOverride::load('node.article.status')->label());
}
}

View file

@ -51,7 +51,7 @@ class MigrateNodeTest extends MigrateNodeTestBase {
/** @var \Drupal\node\NodeInterface $node_revision */
$node_revision = \Drupal::entityManager()->getStorage('node')->loadRevision(1);
$this->assertIdentical('Test title', $node_revision->getTitle());
$this->assertIdentical('1', $node_revision->getRevisionAuthor()->id(), 'Node revision has the correct user');
$this->assertIdentical('1', $node_revision->getRevisionUser()->id(), 'Node revision has the correct user');
// This is empty on the first revision.
$this->assertIdentical(NULL, $node_revision->revision_log->value);
$this->assertIdentical('This is a shared text field', $node->field_test->value);

View file

@ -111,7 +111,7 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
$revision = \Drupal::entityManager()->getStorage('node')->loadRevision($id);
$this->assertTrue($revision instanceof NodeInterface);
$this->assertIdentical($title, $revision->getTitle());
$this->assertIdentical($uid, $revision->getRevisionAuthor()->id());
$this->assertIdentical($uid, $revision->getRevisionUser()->id());
$this->assertIdentical($log, $revision->revision_log->value);
$this->assertIdentical($timestamp, $revision->getRevisionCreationTime());
}

View file

@ -0,0 +1,262 @@
<?php
namespace Drupal\Tests\node\Kernel;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Session\AccountInterface;
use Drupal\KernelTests\KernelTestBase;
use Drupal\node\NodeInterface;
use Drupal\simpletest\ContentTypeCreationTrait;
use Drupal\simpletest\NodeCreationTrait;
use Drupal\simpletest\UserCreationTrait;
use Drupal\user\RoleInterface;
/**
* Tests basic node_access functionality.
*
* @group node
*/
class NodeAccessTest extends KernelTestBase {
use NodeCreationTrait {
getNodeByTitle as drupalGetNodeByTitle;
createNode as drupalCreateNode;
}
use UserCreationTrait {
createUser as drupalCreateUser;
createRole as drupalCreateRole;
createAdminRole as drupalCreateAdminRole;
}
use ContentTypeCreationTrait {
createContentType as drupalCreateContentType;
}
/**
* {@inheritdoc}
*/
public static $modules = [
'node',
'datetime',
'user',
'system',
'filter',
'field',
'text',
];
/**
* Access handler.
*
* @var \Drupal\Core\Entity\EntityAccessControlHandlerInterface
*/
protected $accessHandler;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installSchema('system', 'sequences');
$this->installSchema('node', 'node_access');
$this->installEntitySchema('user');
$this->installEntitySchema('node');
$this->installConfig('filter');
$this->installConfig('node');
$this->accessHandler = $this->container->get('entity_type.manager')
->getAccessControlHandler('node');
// Clear permissions for authenticated users.
$this->config('user.role.' . RoleInterface::AUTHENTICATED_ID)
->set('permissions', [])
->save();
// Create user 1 who has special permissions.
$this->drupalCreateUser();
// Create a node type.
$this->drupalCreateContentType(array(
'type' => 'page',
'name' => 'Basic page',
'display_submitted' => FALSE,
));
}
/**
* Runs basic tests for node_access function.
*/
public function testNodeAccess() {
// Ensures user without 'access content' permission can do nothing.
$web_user1 = $this->drupalCreateUser([
'create page content',
'edit any page content',
'delete any page content',
]);
$node1 = $this->drupalCreateNode(['type' => 'page']);
$this->assertNodeCreateAccess($node1->bundle(), FALSE, $web_user1);
$this->assertNodeAccess([
'view' => FALSE,
'update' => FALSE,
'delete' => FALSE,
], $node1, $web_user1);
// Ensures user with 'bypass node access' permission can do everything.
$web_user2 = $this->drupalCreateUser(['bypass node access']);
$node2 = $this->drupalCreateNode(['type' => 'page']);
$this->assertNodeCreateAccess($node2->bundle(), TRUE, $web_user2);
$this->assertNodeAccess([
'view' => TRUE,
'update' => TRUE,
'delete' => TRUE,
], $node2, $web_user2);
// User cannot 'view own unpublished content'.
$web_user3 = $this->drupalCreateUser(['access content']);
$node3 = $this->drupalCreateNode([
'status' => 0,
'uid' => $web_user3->id(),
]);
$this->assertNodeAccess(['view' => FALSE], $node3, $web_user3);
// User cannot create content without permission.
$this->assertNodeCreateAccess($node3->bundle(), FALSE, $web_user3);
// User can 'view own unpublished content', but another user cannot.
$web_user4 = $this->drupalCreateUser([
'access content',
'view own unpublished content',
]);
$web_user5 = $this->drupalCreateUser([
'access content',
'view own unpublished content',
]);
$node4 = $this->drupalCreateNode([
'status' => 0,
'uid' => $web_user4->id(),
]);
$this->assertNodeAccess([
'view' => TRUE,
'update' => FALSE,
], $node4, $web_user4);
$this->assertNodeAccess(['view' => FALSE], $node4, $web_user5);
// Tests the default access provided for a published node.
$node5 = $this->drupalCreateNode();
$this->assertNodeAccess([
'view' => TRUE,
'update' => FALSE,
'delete' => FALSE,
], $node5, $web_user3);
// Tests the "edit any BUNDLE" and "delete any BUNDLE" permissions.
$web_user6 = $this->drupalCreateUser([
'access content',
'edit any page content',
'delete any page content',
]);
$node6 = $this->drupalCreateNode(['type' => 'page']);
$this->assertNodeAccess([
'view' => TRUE,
'update' => TRUE,
'delete' => TRUE,
], $node6, $web_user6);
// Tests the "edit own BUNDLE" and "delete own BUNDLE" permission.
$web_user7 = $this->drupalCreateUser([
'access content',
'edit own page content',
'delete own page content',
]);
// User should not be able to edit or delete nodes they do not own.
$this->assertNodeAccess([
'view' => TRUE,
'update' => FALSE,
'delete' => FALSE,
], $node6, $web_user7);
// User should be able to edit or delete nodes they own.
$node7 = $this->drupalCreateNode([
'type' => 'page',
'uid' => $web_user7->id(),
]);
$this->assertNodeAccess([
'view' => TRUE,
'update' => TRUE,
'delete' => TRUE,
], $node7, $web_user7);
}
/**
* Test operations not supported by node grants.
*/
public function testUnsupportedOperation() {
$this->enableModules(['node_access_test_empty']);
$web_user = $this->drupalCreateUser(['access content']);
$node = $this->drupalCreateNode();
$this->assertNodeAccess(['random_operation' => FALSE], $node, $web_user);
}
/**
* Asserts that node access correctly grants or denies access.
*
* @param array $ops
* An associative array of the expected node access grants for the node
* and account, with each key as the name of an operation (e.g. 'view',
* 'delete') and each value a Boolean indicating whether access to that
* operation should be granted.
* @param \Drupal\node\NodeInterface $node
* The node object to check.
* @param \Drupal\Core\Session\AccountInterface $account
* The user account for which to check access.
*/
public function assertNodeAccess(array $ops, NodeInterface $node, AccountInterface $account) {
foreach ($ops as $op => $result) {
$this->assertEquals($result, $this->accessHandler->access($node, $op, $account), $this->nodeAccessAssertMessage($op, $result, $node->language()
->getId()));
}
}
/**
* Asserts that node create access correctly grants or denies access.
*
* @param string $bundle
* The node bundle to check access to.
* @param bool $result
* Whether access should be granted or not.
* @param \Drupal\Core\Session\AccountInterface $account
* The user account for which to check access.
* @param string|null $langcode
* (optional) The language code indicating which translation of the node
* to check. If NULL, the untranslated (fallback) access is checked.
*/
public function assertNodeCreateAccess($bundle, $result, AccountInterface $account, $langcode = NULL) {
$this->assertEquals($result, $this->accessHandler->createAccess($bundle, $account, [
'langcode' => $langcode,
]), $this->nodeAccessAssertMessage('create', $result, $langcode));
}
/**
* Constructs an assert message to display which node access was tested.
*
* @param string $operation
* The operation to check access for.
* @param bool $result
* Whether access should be granted or not.
* @param string|null $langcode
* (optional) The language code indicating which translation of the node
* to check. If NULL, the untranslated (fallback) access is checked.
*
* @return string
* An assert message string which contains information in plain English
* about the node access permission test that was performed.
*/
public function nodeAccessAssertMessage($operation, $result, $langcode = NULL) {
return new FormattableMarkup(
'Node access returns @result with operation %op, language code %langcode.',
[
'@result' => $result ? 'true' : 'false',
'%op' => $operation,
'%langcode' => !empty($langcode) ? $langcode : 'empty',
]
);
}
}