Update to Drupal 8.0-dev-2015-11-17. Commits through da81cd220, Tue Nov 17 15:53:49 2015 +0000, Issue #2617224 by Wim Leers: Move around/fix some documentation.
This commit is contained in:
parent
4afb23bbd3
commit
7784f4c23d
929 changed files with 19798 additions and 5304 deletions
|
@ -1064,6 +1064,14 @@ function node_query_node_access_alter(AlterableInterface $query) {
|
|||
|
||||
// Update the query for the given storage method.
|
||||
\Drupal::service('node.grant_storage')->alterQuery($query, $tables, $op, $account, $base_table);
|
||||
|
||||
// Bubble the 'user.node_grants:$op' cache context to the current render
|
||||
// context.
|
||||
$renderer = \Drupal::service('renderer');
|
||||
if ($renderer->hasRenderContext()) {
|
||||
$build = ['#cache' => ['contexts' => ['user.node_grants:' . $op]]];
|
||||
$renderer->render($build);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,6 +47,7 @@ entity.node.version_history:
|
|||
_controller: '\Drupal\node\Controller\NodeController::revisionOverview'
|
||||
requirements:
|
||||
_access_node_revision: 'view'
|
||||
node: \d+
|
||||
options:
|
||||
_node_operation_route: TRUE
|
||||
|
||||
|
@ -57,6 +58,7 @@ entity.node.revision:
|
|||
_title_callback: '\Drupal\node\Controller\NodeController::revisionPageTitle'
|
||||
requirements:
|
||||
_access_node_revision: 'view'
|
||||
node: \d+
|
||||
|
||||
node.revision_revert_confirm:
|
||||
path: '/node/{node}/revisions/{node_revision}/revert'
|
||||
|
@ -65,6 +67,7 @@ node.revision_revert_confirm:
|
|||
_title: 'Revert to earlier revision'
|
||||
requirements:
|
||||
_access_node_revision: 'update'
|
||||
node: \d+
|
||||
options:
|
||||
_node_operation_route: TRUE
|
||||
|
||||
|
@ -75,6 +78,7 @@ node.revision_revert_translation_confirm:
|
|||
_title: 'Revert to earlier revision of a translation'
|
||||
requirements:
|
||||
_access_node_revision: 'update'
|
||||
node: \d+
|
||||
options:
|
||||
_node_operation_route: TRUE
|
||||
|
||||
|
@ -85,6 +89,7 @@ node.revision_delete_confirm:
|
|||
_title: 'Delete earlier revision'
|
||||
requirements:
|
||||
_access_node_revision: 'delete'
|
||||
node: \d+
|
||||
options:
|
||||
_node_operation_route: TRUE
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
|
|||
if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) {
|
||||
$username = [
|
||||
'#theme' => 'username',
|
||||
'#account' => $revision->uid->entity,
|
||||
'#account' => $revision->getRevisionAuthor(),
|
||||
];
|
||||
|
||||
// Use revision link to link to revisions that are not active.
|
||||
|
|
|
@ -27,6 +27,7 @@ class NodeRouteProvider implements EntityRouteProviderInterface {
|
|||
'_controller' => '\Drupal\node\Controller\NodeViewController::view',
|
||||
'_title_callback' => '\Drupal\node\Controller\NodeViewController::title',
|
||||
])
|
||||
->setRequirement('node', '\d+')
|
||||
->setRequirement('_entity_access', 'node.view');
|
||||
$route_collection->add('entity.node.canonical', $route);
|
||||
|
||||
|
@ -35,6 +36,7 @@ class NodeRouteProvider implements EntityRouteProviderInterface {
|
|||
'_entity_form' => 'node.delete',
|
||||
'_title' => 'Delete',
|
||||
])
|
||||
->setRequirement('node', '\d+')
|
||||
->setRequirement('_entity_access', 'node.delete')
|
||||
->setOption('_node_operation_route', TRUE);
|
||||
$route_collection->add('entity.node.delete_form', $route);
|
||||
|
@ -42,6 +44,7 @@ class NodeRouteProvider implements EntityRouteProviderInterface {
|
|||
$route = (new Route('/node/{node}/edit'))
|
||||
->setDefault('_entity_form', 'node.edit')
|
||||
->setRequirement('_entity_access', 'node.update')
|
||||
->setRequirement('node', '\d+')
|
||||
->setOption('_node_operation_route', TRUE);
|
||||
$route_collection->add('entity.node.edit_form', $route);
|
||||
|
||||
|
|
|
@ -48,4 +48,32 @@ class NodeSelection extends DefaultSelection {
|
|||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createNewEntity($entity_type_id, $bundle, $label, $uid) {
|
||||
$node = parent::createNewEntity($entity_type_id, $bundle, $label, $uid);
|
||||
|
||||
// In order to create a referenceable node, it needs to published.
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
$node->setPublished(TRUE);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateReferenceableNewEntities(array $entities) {
|
||||
$entities = parent::validateReferenceableNewEntities($entities);
|
||||
// Mirror the conditions checked in buildEntityQuery().
|
||||
if (!$this->currentUser->hasPermission('bypass node access') && !count($this->moduleHandler->getImplementations('node_grants'))) {
|
||||
$entities = array_filter($entities, function ($node) {
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
return $node->isPublished();
|
||||
});
|
||||
}
|
||||
return $entities;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -199,7 +199,9 @@ class Node extends WizardPluginBase {
|
|||
protected function buildFilters(&$form, FormStateInterface $form_state) {
|
||||
parent::buildFilters($form, $form_state);
|
||||
|
||||
$selected_bundle = static::getSelected($form_state, array('show', 'type'), 'all', $form['displays']['show']['type']);
|
||||
if (isset($form['displays']['show']['type'])) {
|
||||
$selected_bundle = static::getSelected($form_state, array('show', 'type'), 'all', $form['displays']['show']['type']);
|
||||
}
|
||||
|
||||
// Add the "tagged with" filter to the view.
|
||||
|
||||
|
|
48
core/modules/node/src/Tests/Migrate/MigrateNodeStubTest.php
Normal file
48
core/modules/node/src/Tests/Migrate/MigrateNodeStubTest.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\node\Tests\Migrate\MigrateNodeStubTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\Tests\Migrate;
|
||||
|
||||
use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
|
||||
use Drupal\migrate_drupal\Tests\StubTestTrait;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
/**
|
||||
* Test stub creation for nodes.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class MigrateNodeStubTest extends MigrateDrupalTestBase {
|
||||
|
||||
use StubTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('node');
|
||||
// Need at least one node type present.
|
||||
NodeType::create([
|
||||
'type' => 'testnodetype',
|
||||
'name' => 'Test node type',
|
||||
])->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests creation of node stubs.
|
||||
*/
|
||||
public function testStub() {
|
||||
$this->performStubTest('node');
|
||||
}
|
||||
|
||||
}
|
72
core/modules/node/src/Tests/NodeAccessAutoBubblingTest.php
Normal file
72
core/modules/node/src/Tests/NodeAccessAutoBubblingTest.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\node\Tests\NodeAccessAutoBubblingTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\Tests;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Tests the node access automatic cacheability bubbling logic.
|
||||
*
|
||||
* @group node
|
||||
* @group Cache
|
||||
* @group cacheability_safeguards
|
||||
*/
|
||||
class NodeAccessAutoBubblingTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node_access_test', 'node_access_test_auto_bubbling'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
node_access_rebuild();
|
||||
|
||||
// Create some content.
|
||||
$this->drupalCreateNode();
|
||||
$this->drupalCreateNode();
|
||||
$this->drupalCreateNode();
|
||||
$this->drupalCreateNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the node grants cache context is auto-added, only when needed.
|
||||
*
|
||||
* @see node_query_node_access_alter()
|
||||
*/
|
||||
public function testNodeAccessCacheabilitySafeguard() {
|
||||
$this->dumpHeaders = TRUE;
|
||||
|
||||
// The node grants cache context should be added automatically.
|
||||
$this->drupalGet(new Url('node_access_test_auto_bubbling'));
|
||||
$this->assertCacheContext('user.node_grants:view');
|
||||
|
||||
// The root user has the 'bypass node access' permission, which means the
|
||||
// node grants cache context is not necessary.
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->drupalGet(new Url('node_access_test_auto_bubbling'));
|
||||
$this->assertNoCacheContext('user.node_grants:view');
|
||||
$this->drupalLogout();
|
||||
|
||||
// Uninstall the module with the only hook_node_grants() implementation.
|
||||
$this->container->get('module_installer')->uninstall(['node_access_test']);
|
||||
$this->rebuildContainer();
|
||||
|
||||
// Because there are no node grants defined, there also is no need for the
|
||||
// node grants cache context to be bubbled.
|
||||
$this->drupalGet(new Url('node_access_test_auto_bubbling'));
|
||||
$this->assertNoCacheContext('user.node_grants:view');
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,19 @@ use Drupal\node\NodeInterface;
|
|||
* @group node
|
||||
*/
|
||||
class NodeRevisionsTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* An array of node revisions.
|
||||
*
|
||||
* @var \Drupal\node\NodeInterface[]
|
||||
*/
|
||||
protected $nodes;
|
||||
|
||||
/**
|
||||
* Revision log messages.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $revisionLogs;
|
||||
|
||||
/**
|
||||
|
@ -93,6 +105,16 @@ class NodeRevisionsTest extends NodeTestBase {
|
|||
);
|
||||
$node->untranslatable_string_field->value = $this->randomString();
|
||||
$node->setNewRevision();
|
||||
|
||||
// Edit the 2nd revision with a different user.
|
||||
if ($i == 1) {
|
||||
$editor = $this->drupalCreateUser();
|
||||
$node->setRevisionAuthorId($editor->id());
|
||||
}
|
||||
else {
|
||||
$node->setRevisionAuthorId($web_user->id());
|
||||
}
|
||||
|
||||
$node->save();
|
||||
|
||||
$node = Node::load($node->id()); // Make sure we get revision information.
|
||||
|
@ -123,6 +145,11 @@ class NodeRevisionsTest extends NodeTestBase {
|
|||
foreach ($logs as $revision_log) {
|
||||
$this->assertText($revision_log, 'Revision log message found.');
|
||||
}
|
||||
// Original author, and editor names should appear on revisions overview.
|
||||
$web_user = $nodes[0]->revision_uid->entity;
|
||||
$this->assertText(t('by @name', ['@name' => $web_user->getAccountName()]));
|
||||
$editor = $nodes[2]->revision_uid->entity;
|
||||
$this->assertText(t('by @name', ['@name' => $editor->getAccountName()]));
|
||||
|
||||
// Confirm that this is the default revision.
|
||||
$this->assertTrue($node->isDefaultRevision(), 'Third node revision is the default one.');
|
||||
|
|
|
@ -94,7 +94,8 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
|
|||
$language = ConfigurableLanguage::load($langcode);
|
||||
$values[$langcode] = array('title' => array(array('value' => $this->randomMachineName())));
|
||||
|
||||
$add_url = Url::fromRoute('content_translation.translation_add_' . $entity->getEntityTypeId(), [
|
||||
$entity_type_id = $entity->getEntityTypeId();
|
||||
$add_url = Url::fromRoute("entity.$entity_type_id.content_translation_add", [
|
||||
$entity->getEntityTypeId() => $entity->id(),
|
||||
'source' => $default_langcode,
|
||||
'target' => $langcode
|
||||
|
|
|
@ -218,6 +218,9 @@ class NodeTypeTest extends NodeTestBase {
|
|||
* Tests for when there are no content types defined.
|
||||
*/
|
||||
public function testNodeTypeNoContentType() {
|
||||
/** @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info */
|
||||
$bundle_info = \Drupal::service('entity_type.bundle.info');
|
||||
$this->assertEqual(2, count($bundle_info->getBundleInfo('node')), 'The bundle information service has 2 bundles for the Node entity type.');
|
||||
$web_user = $this->drupalCreateUser(['administer content types']);
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
|
@ -231,6 +234,9 @@ class NodeTypeTest extends NodeTestBase {
|
|||
$this->assertRaw(t('No content types available. <a href=":link">Add content type</a>.', [
|
||||
':link' => Url::fromRoute('node.type_add')->toString()
|
||||
]), 'Empty text when there are no content types in the system is correct.');
|
||||
|
||||
$bundle_info->clearCachedBundles();
|
||||
$this->assertEqual(0, count($bundle_info->getBundleInfo('node')), 'The bundle information service has 0 bundles for the Node entity type.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
name: 'Node module access automatic cacheability bubbling tests'
|
||||
type: module
|
||||
description: 'Support module for node permission testing. Provides a route which does a node access query without explicitly specifying the corresponding cache context.'
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
|
@ -0,0 +1,6 @@
|
|||
node_access_test_auto_bubbling:
|
||||
path: '/node_access_test_auto_bubbling'
|
||||
defaults:
|
||||
_controller: '\Drupal\node_access_test_auto_bubbling\Controller\NodeAccessTestAutoBubblingController::latest'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\node_access_test_auto_bubbling\Controller\NodeAccessTestAutoBubblingController.
|
||||
*/
|
||||
|
||||
namespace Drupal\node_access_test_auto_bubbling\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\Core\Entity\Query\QueryFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Returns a node ID listing.
|
||||
*/
|
||||
class NodeAccessTestAutoBubblingController extends ControllerBase implements ContainerInjectionInterface {
|
||||
|
||||
/**
|
||||
* The entity query factory service.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\Query\QueryFactory
|
||||
*/
|
||||
protected $entityQuery;
|
||||
|
||||
/**
|
||||
* Constructs a new NodeAccessTestAutoBubblingController.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\Query\QueryFactory $entity_query
|
||||
* The entity query factory.
|
||||
*/
|
||||
public function __construct(QueryFactory $entity_query) {
|
||||
$this->entityQuery = $entity_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.query')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists the three latest published node IDs.
|
||||
*
|
||||
* @return array
|
||||
* A render array.
|
||||
*/
|
||||
public function latest() {
|
||||
$nids = $this->entityQuery->get('node')
|
||||
->condition('status', NODE_PUBLISHED)
|
||||
->sort('created', 'DESC')
|
||||
->range(0, 3)
|
||||
->execute();
|
||||
return ['#markup' => $this->t('The three latest nodes are: @nids.', ['@nids' => implode(', ', $nids)])];
|
||||
}
|
||||
|
||||
}
|
Reference in a new issue