summaryrefslogtreecommitdiffstatshomepage
path: root/core/modules/node/src
diff options
context:
space:
mode:
Diffstat (limited to 'core/modules/node/src')
-rw-r--r--core/modules/node/src/Controller/NodeController.php6
-rw-r--r--core/modules/node/src/Form/NodeForm.php45
-rw-r--r--core/modules/node/src/Form/NodeRevisionRevertForm.php2
-rw-r--r--core/modules/node/src/Hook/NodeHooks1.php4
-rw-r--r--core/modules/node/src/Hook/NodeTokensHooks.php2
-rw-r--r--core/modules/node/src/Hook/NodeViewsHooks.php2
-rw-r--r--core/modules/node/src/NodeAccessControlHandlerInterface.php2
-rw-r--r--core/modules/node/src/NodeGrantDatabaseStorage.php23
-rw-r--r--core/modules/node/src/NodeGrantDatabaseStorageInterface.php10
-rw-r--r--core/modules/node/src/NodeListBuilder.php2
-rw-r--r--core/modules/node/src/NodeTranslationHandler.php3
-rw-r--r--core/modules/node/src/Plugin/views/filter/Access.php2
-rw-r--r--core/modules/node/src/Plugin/views/wizard/Node.php2
13 files changed, 59 insertions, 46 deletions
diff --git a/core/modules/node/src/Controller/NodeController.php b/core/modules/node/src/Controller/NodeController.php
index 87c9586daee..d5a35f64285 100644
--- a/core/modules/node/src/Controller/NodeController.php
+++ b/core/modules/node/src/Controller/NodeController.php
@@ -196,10 +196,12 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
'username' => $this->renderer->renderInIsolation($username),
'message' => ['#markup' => $revision->revision_log->value, '#allowed_tags' => Xss::getHtmlTagList()],
],
+ // @todo Fix this properly in https://www.drupal.org/project/drupal/issues/3227637.
+ '#cache' => [
+ 'max-age' => 0,
+ ],
],
];
- // @todo Simplify once https://www.drupal.org/node/2334319 lands.
- $this->renderer->addCacheableDependency($column['data'], $username);
$row[] = $column;
if ($is_current_revision) {
diff --git a/core/modules/node/src/Form/NodeForm.php b/core/modules/node/src/Form/NodeForm.php
index d5afa396568..5498c94c497 100644
--- a/core/modules/node/src/Form/NodeForm.php
+++ b/core/modules/node/src/Form/NodeForm.php
@@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
+use Drupal\Core\Utility\Error;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -124,7 +125,7 @@ class NodeForm extends ContentEntityForm {
if ($this->operation == 'edit') {
$form['#title'] = $this->t('<em>Edit @type</em> @title', [
- '@type' => node_get_type_label($node),
+ '@type' => $node->getBundleEntity()->label(),
'@title' => $node->label(),
]);
}
@@ -163,7 +164,7 @@ class NodeForm extends ContentEntityForm {
$form['meta']['author'] = [
'#type' => 'item',
'#title' => $this->t('Author'),
- '#markup' => $node->getOwner()?->getAccountName(),
+ '#markup' => $node->getOwner()?->getDisplayName(),
'#wrapper_attributes' => ['class' => ['entity-meta__author']],
];
@@ -278,21 +279,22 @@ class NodeForm extends ContentEntityForm {
public function save(array $form, FormStateInterface $form_state) {
$node = $this->entity;
$insert = $node->isNew();
- $node->save();
- $node_link = $node->toLink($this->t('View'))->toString();
- $context = ['@type' => $node->getType(), '%title' => $node->label(), 'link' => $node_link];
- $t_args = ['@type' => node_get_type_label($node), '%title' => $node->toLink()->toString()];
-
- if ($insert) {
- $this->logger('content')->info('@type: added %title.', $context);
- $this->messenger()->addStatus($this->t('@type %title has been created.', $t_args));
- }
- else {
- $this->logger('content')->info('@type: updated %title.', $context);
- $this->messenger()->addStatus($this->t('@type %title has been updated.', $t_args));
- }
- if ($node->id()) {
+ try {
+ $node->save();
+ $node_link = $node->toLink($this->t('View'))->toString();
+ $context = ['@type' => $node->getType(), '%title' => $node->label(), 'link' => $node_link];
+ $t_args = ['@type' => $node->getBundleEntity()->label(), '%title' => $node->access('view') ? $node->toLink()->toString() : $node->label()];
+
+ if ($insert) {
+ $this->logger('content')->info('@type: added %title.', $context);
+ $this->messenger()->addStatus($this->t('@type %title has been created.', $t_args));
+ }
+ else {
+ $this->logger('content')->info('@type: updated %title.', $context);
+ $this->messenger()->addStatus($this->t('@type %title has been updated.', $t_args));
+ }
+
$form_state->setValue('nid', $node->id());
$form_state->set('nid', $node->id());
if ($node->access('view')) {
@@ -310,10 +312,15 @@ class NodeForm extends ContentEntityForm {
$store = $this->tempStoreFactory->get('node_preview');
$store->delete($node->uuid());
}
- else {
+ catch (\Exception $e) {
// In the unlikely case something went wrong on save, the node will be
- // rebuilt and node form redisplayed the same way as in preview.
- $this->messenger()->addError($this->t('The post could not be saved.'));
+ // rebuilt and node form redisplayed.
+ $this->messenger()->addError($this->t('The content could not be saved. Contact the site administrator if the problem persists.'));
+ // It's likely that this exception is an EntityStorageException in which
+ // case we won't have the actual backtrace available. Attempt to get the
+ // previous exception if available to include the backtrace.
+ $e = $e->getPrevious() ?: $e;
+ \Drupal::logger('node')->error('%type saving node form: @message in %function (line %line of %file) @backtrace_string.', Error::decodeException($e));
$form_state->setRebuild();
}
}
diff --git a/core/modules/node/src/Form/NodeRevisionRevertForm.php b/core/modules/node/src/Form/NodeRevisionRevertForm.php
index ffb58fb71fb..a1e04e2942d 100644
--- a/core/modules/node/src/Form/NodeRevisionRevertForm.php
+++ b/core/modules/node/src/Form/NodeRevisionRevertForm.php
@@ -136,7 +136,7 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
$this->logger('content')->info('@type: reverted %title revision %revision.', ['@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]);
$this->messenger()
->addStatus($this->t('@type %title has been reverted to the revision from %revision-date.', [
- '@type' => node_get_type_label($this->revision),
+ '@type' => $this->revision->getBundleEntity()->label(),
'%title' => $this->revision->label(),
'%revision-date' => $this->dateFormatter->format($original_revision_timestamp),
]));
diff --git a/core/modules/node/src/Hook/NodeHooks1.php b/core/modules/node/src/Hook/NodeHooks1.php
index 8e25f2eb066..e103717fb61 100644
--- a/core/modules/node/src/Hook/NodeHooks1.php
+++ b/core/modules/node/src/Hook/NodeHooks1.php
@@ -92,7 +92,7 @@ class NodeHooks1 {
case 'entity.entity_view_display.node.default':
case 'entity.entity_view_display.node.view_mode':
$type = $route_match->getParameter('node_type');
- return '<p>' . $this->t('Content items can be displayed using different view modes: Teaser, Full content, Print, RSS, etc. <em>Teaser</em> is a short format that is typically used in lists of multiple content items. <em>Full content</em> is typically used when the content is displayed on its own page.') . '</p>' . '<p>' . $this->t('Here, you can define which fields are shown and hidden when %type content is displayed in each view mode, and define how the fields are displayed in each view mode.', ['%type' => $type->label()]) . '</p>';
+ return '<p>' . $this->t('Content items can be displayed using different view modes: Teaser, Full content, Print, RSS, etc. <em>Teaser</em> is a short format that is typically used in lists of multiple content items. <em>Full content</em> is typically used when the content is displayed on its own page.') . '</p><p>' . $this->t('Here, you can define which fields are shown and hidden when %type content is displayed in each view mode, and define how the fields are displayed in each view mode.', ['%type' => $type->label()]) . '</p>';
case 'entity.node.version_history':
return '<p>' . $this->t('Revisions allow you to track differences between multiple versions of your content, and revert to older versions.') . '</p>';
@@ -219,7 +219,7 @@ class NodeHooks1 {
$ranking = [
'relevance' => [
'title' => $this->t('Keyword relevance'),
- // Average relevance values hover around 0.15
+ // Average relevance values hover around 0.15.
'score' => 'i.relevance',
],
'sticky' => [
diff --git a/core/modules/node/src/Hook/NodeTokensHooks.php b/core/modules/node/src/Hook/NodeTokensHooks.php
index 3d7f0b0adf4..a7a90347313 100644
--- a/core/modules/node/src/Hook/NodeTokensHooks.php
+++ b/core/modules/node/src/Hook/NodeTokensHooks.php
@@ -109,7 +109,7 @@ class NodeTokensHooks {
break;
case 'type-name':
- $type_name = node_get_type_label($node);
+ $type_name = $node->getBundleEntity()->label();
$replacements[$original] = $type_name;
break;
diff --git a/core/modules/node/src/Hook/NodeViewsHooks.php b/core/modules/node/src/Hook/NodeViewsHooks.php
index 477784c153d..8729f547c17 100644
--- a/core/modules/node/src/Hook/NodeViewsHooks.php
+++ b/core/modules/node/src/Hook/NodeViewsHooks.php
@@ -26,7 +26,7 @@ class NodeViewsHooks {
if ($view->storage->get('base_table') == 'node') {
foreach ($view->displayHandlers as $display) {
if (!$display->isDefaulted('access') || !$display->isDefaulted('filters')) {
- // Check for no access control
+ // Check for no access control.
$access = $display->getOption('access');
if (empty($access['type']) || $access['type'] == 'none') {
$anonymous_role = Role::load(RoleInterface::ANONYMOUS_ID);
diff --git a/core/modules/node/src/NodeAccessControlHandlerInterface.php b/core/modules/node/src/NodeAccessControlHandlerInterface.php
index 588391394ee..0d67cfb7bd6 100644
--- a/core/modules/node/src/NodeAccessControlHandlerInterface.php
+++ b/core/modules/node/src/NodeAccessControlHandlerInterface.php
@@ -30,6 +30,8 @@ interface NodeAccessControlHandlerInterface {
/**
* Creates the default node access grant entry on the grant storage.
+ *
+ * @see \Drupal\node\NodeGrantDatabaseStorageInterface::writeDefault()
*/
public function writeDefaultGrant();
diff --git a/core/modules/node/src/NodeGrantDatabaseStorage.php b/core/modules/node/src/NodeGrantDatabaseStorage.php
index eea6cc10012..fbaab21a211 100644
--- a/core/modules/node/src/NodeGrantDatabaseStorage.php
+++ b/core/modules/node/src/NodeGrantDatabaseStorage.php
@@ -112,6 +112,13 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
if (count($grants) > 0) {
$query->condition($grants);
}
+ if ($query->execute()->fetchField()) {
+ $access_result = AccessResult::allowed();
+ }
+ else {
+ $access_result = AccessResult::neutral();
+ }
+ $access_result->addCacheContexts(['user.node_grants:' . $operation]);
// Only the 'view' node grant can currently be cached; the others currently
// don't have any cacheability metadata. Hopefully, we can add that in the
@@ -119,20 +126,10 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
// cases. For now, this must remain marked as uncacheable, even when it is
// theoretically cacheable, because we don't have the necessary metadata to
// know it for a fact.
- $set_cacheability = function (AccessResult $access_result) use ($operation) {
- $access_result->addCacheContexts(['user.node_grants:' . $operation]);
- if ($operation !== 'view') {
- $access_result->setCacheMaxAge(0);
- }
- return $access_result;
- };
-
- if ($query->execute()->fetchField()) {
- return $set_cacheability(AccessResult::allowed());
- }
- else {
- return $set_cacheability(AccessResult::neutral());
+ if ($operation !== 'view') {
+ $access_result->setCacheMaxAge(0);
}
+ return $access_result;
}
/**
diff --git a/core/modules/node/src/NodeGrantDatabaseStorageInterface.php b/core/modules/node/src/NodeGrantDatabaseStorageInterface.php
index cce74476563..d343a2f350b 100644
--- a/core/modules/node/src/NodeGrantDatabaseStorageInterface.php
+++ b/core/modules/node/src/NodeGrantDatabaseStorageInterface.php
@@ -42,8 +42,8 @@ interface NodeGrantDatabaseStorageInterface {
* @param string $base_table
* The base table of the query.
*
- * @return int
- * Status of the access check.
+ * @return void
+ * No return value.
*/
public function alterQuery($query, array $tables, $operation, AccountInterface $account, $base_table);
@@ -83,6 +83,12 @@ interface NodeGrantDatabaseStorageInterface {
/**
* Creates the default node access grant entry.
+ *
+ * The default node access grant is a special grant added to the node_access
+ * table when no modules implement hook_node_grants. It grants view access
+ * to any published node.
+ *
+ * @see self::access()
*/
public function writeDefault();
diff --git a/core/modules/node/src/NodeListBuilder.php b/core/modules/node/src/NodeListBuilder.php
index 0fa80dee411..2b356eb2b34 100644
--- a/core/modules/node/src/NodeListBuilder.php
+++ b/core/modules/node/src/NodeListBuilder.php
@@ -95,7 +95,7 @@ class NodeListBuilder extends EntityListBuilder {
'#title' => $entity->label(),
'#url' => $entity->toUrl(),
];
- $row['type'] = node_get_type_label($entity);
+ $row['type'] = $entity->getBundleEntity()->label();
$row['author']['data'] = [
'#theme' => 'username',
'#account' => $entity->getOwner(),
diff --git a/core/modules/node/src/NodeTranslationHandler.php b/core/modules/node/src/NodeTranslationHandler.php
index 6c802440f37..88a3680a572 100644
--- a/core/modules/node/src/NodeTranslationHandler.php
+++ b/core/modules/node/src/NodeTranslationHandler.php
@@ -50,8 +50,7 @@ class NodeTranslationHandler extends ContentTranslationHandler {
* {@inheritdoc}
*/
protected function entityFormTitle(EntityInterface $entity) {
- $type_name = node_get_type_label($entity);
- return $this->t('<em>Edit @type</em> @title', ['@type' => $type_name, '@title' => $entity->label()]);
+ return $this->t('<em>Edit @type</em> @title', ['@type' => $entity->getBundleEntity()->label(), '@title' => $entity->label()]);
}
/**
diff --git a/core/modules/node/src/Plugin/views/filter/Access.php b/core/modules/node/src/Plugin/views/filter/Access.php
index 4934a2f2e63..4d579f687ce 100644
--- a/core/modules/node/src/Plugin/views/filter/Access.php
+++ b/core/modules/node/src/Plugin/views/filter/Access.php
@@ -36,7 +36,7 @@ class Access extends FilterPluginBase {
*/
public function query() {
$account = $this->view->getUser();
- if (!$account->hasPermission('bypass node access')) {
+ if (!$account->hasPermission('bypass node access') && $this->moduleHandler->hasImplementations('node_grants')) {
$table = $this->ensureMyTable();
$grants = $this->query->getConnection()->condition('OR');
foreach (node_access_grants('view', $account) as $realm => $gids) {
diff --git a/core/modules/node/src/Plugin/views/wizard/Node.php b/core/modules/node/src/Plugin/views/wizard/Node.php
index d66fa956f9a..bef4ddc8da5 100644
--- a/core/modules/node/src/Plugin/views/wizard/Node.php
+++ b/core/modules/node/src/Plugin/views/wizard/Node.php
@@ -92,7 +92,7 @@ class Node extends WizardPluginBase {
* {@inheritdoc}
*/
public function getAvailableSorts() {
- // You can't execute functions in properties, so override the method
+ // You can't execute functions in properties, so override the method.
return [
'node_field_data-title:ASC' => $this->t('Title'),
];