updated core from 8.4 to 8.5 : bug with login_destination

This commit is contained in:
Bachir Soussi Chiadmi
2018-03-13 14:01:21 +01:00
parent 0d78da249b
commit e668535a4e
3486 changed files with 89604 additions and 33283 deletions
@@ -6,5 +6,5 @@ dependencies:
id: node_publish_action
label: 'Publish content'
type: node
plugin: node_publish_action
plugin: entity:publish_action:node
configuration: { }
@@ -6,5 +6,5 @@ dependencies:
id: node_save_action
label: 'Save content'
type: node
plugin: node_save_action
plugin: entity:save_action:node
configuration: { }
@@ -6,5 +6,5 @@ dependencies:
id: node_unpublish_action
label: 'Unpublish content'
type: node
plugin: node_unpublish_action
plugin: entity:unpublish_action:node
configuration: { }
@@ -28,7 +28,7 @@ display:
empty:
area_text_custom:
admin_label: ''
content: 'No front page content has been created yet.'
content: 'No front page content has been created yet.<br/>Follow the <a target="_blank" href="https://www.drupal.org/docs/user_guide/en/index.html">User Guide</a> to start building your site.'
empty: true
field: area_text_custom
group_type: group
@@ -62,14 +62,20 @@ action.configuration.node_promote_action:
type: action_configuration_default
label: 'Promote selected content from front page configuration'
# @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
# @see https://www.drupal.org/node/2919303
action.configuration.node_publish_action:
type: action_configuration_default
label: 'Publish selected content configuration'
# @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
# @see https://www.drupal.org/node/2919303
action.configuration.node_unpublish_action:
type: action_configuration_default
label: 'Unpublish selected content configuration'
# @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
# @see https://www.drupal.org/node/2919303
action.configuration.node_save_action:
type: action_configuration_default
label: 'Save content configuration'
+2 -2
View File
@@ -9,7 +9,7 @@
/* Narrow screens */
.layout-region {
box-sizing: border-box;
box-sizing: border-box;
}
/* Wide screens */
@@ -51,7 +51,7 @@
.layout-region-node-secondary .form-number,
.layout-region-node-secondary .form-color,
.layout-region-node-secondary textarea {
box-sizing: border-box;
box-sizing: border-box;
width: 100%;
max-width: 100%;
}
@@ -1,7 +1,9 @@
id: d6_node
label: Nodes
audit: true
migration_tags:
- Drupal 6
- Content
deriver: Drupal\node\Plugin\migrate\D6NodeDeriver
source:
plugin: d6_node
@@ -1,7 +1,9 @@
id: d6_node_revision
label: Node revisions
audit: true
migration_tags:
- Drupal 6
- Content
deriver: Drupal\node\Plugin\migrate\D6NodeDeriver
source:
plugin: d6_node_revision
@@ -2,6 +2,7 @@ id: d6_node_setting_promote
label: Node type 'promote' setting
migration_tags:
- Drupal 6
- Configuration
source:
plugin: d6_node_type
constants:
@@ -2,6 +2,7 @@ id: d6_node_setting_status
label: Node type 'status' setting
migration_tags:
- Drupal 6
- Configuration
source:
plugin: d6_node_type
constants:
@@ -2,6 +2,7 @@ id: d6_node_setting_sticky
label: Node type 'sticky' setting
migration_tags:
- Drupal 6
- Configuration
source:
plugin: d6_node_type
constants:
@@ -2,6 +2,7 @@ id: d6_node_settings
label: Node configuration
migration_tags:
- Drupal 6
- Configuration
source:
plugin: variable
variables:
@@ -2,11 +2,11 @@ id: d6_node_translation
label: Node translations
migration_tags:
- Drupal 6
- Content
deriver: Drupal\node\Plugin\migrate\D6NodeDeriver
source:
plugin: d6_node
translations: true
source_module: translation
process:
# If you are using this file to build a custom migration consider removing
# the nid field to allow incremental migrations.
@@ -2,6 +2,7 @@ id: d6_node_type
label: Node type configuration
migration_tags:
- Drupal 6
- Configuration
source:
plugin: d6_node_type
constants:
@@ -2,6 +2,7 @@ id: d6_view_modes
label: View modes
migration_tags:
- Drupal 6
- Configuration
source:
plugin: d6_view_mode
constants:
@@ -1,7 +1,9 @@
id: d7_node
label: Nodes
audit: true
migration_tags:
- Drupal 7
- Content
deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
source:
plugin: d7_node
@@ -1,7 +1,9 @@
id: d7_node_revision
label: Node revisions
audit: true
migration_tags:
- Drupal 7
- Content
deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
source:
plugin: d7_node_revision
@@ -2,6 +2,7 @@ id: d7_node_settings
label: Node configuration
migration_tags:
- Drupal 7
- Configuration
source:
plugin: variable
variables:
@@ -2,6 +2,7 @@ id: d7_node_title_label
label: Node title label
migration_tags:
- Drupal 7
- Configuration
source:
plugin: d7_node_type
constants:
@@ -3,11 +3,11 @@ label: Node translations
migration_tags:
- Drupal 7
- translation
- Content
deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
source:
plugin: d7_node
translations: true
source_module: translation
process:
# If you are using this file to build a custom migration consider removing
# the nid field to allow incremental migrations.
@@ -2,6 +2,7 @@ id: d7_node_type
label: Node type configuration
migration_tags:
- Drupal 7
- Configuration
source:
plugin: d7_node_type
constants:
+3 -3
View File
@@ -8,8 +8,8 @@ configure: entity.node_type.collection
dependencies:
- text
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
# Information added by Drupal.org packaging script on 2018-03-07
version: '8.5.0'
core: '8.x'
project: 'drupal'
datestamp: 1515021228
datestamp: 1520457825
+12
View File
@@ -255,3 +255,15 @@ function node_update_8400() {
$schema['fields']['realm']['description'] = 'The realm in which the user must possess the grant ID. Modules can define one or more realms by implementing hook_node_grants().';
Database::getConnection()->schema()->changeField('node_access', 'realm', 'realm', $schema['fields']['realm']);
}
/**
* Run a node access rebuild, if required.
*/
function node_update_8401() {
// Get the list of node access modules.
$modules = \Drupal::moduleHandler()->getImplementations('node_grants');
// If multilingual usage, then rebuild node access.
if (count($modules) > 0 && \Drupal::languageManager()->isMultilingual()) {
node_access_needs_rebuild(TRUE);
}
}
-2
View File
@@ -12,8 +12,6 @@ administer nodes:
restrict access: true
access content overview:
title: 'Access the Content overview page'
access content:
title: 'View published content'
view own unpublished content:
title: 'View own unpublished content'
view all revisions:
+1 -1
View File
@@ -30,7 +30,7 @@ services:
- { name: event_subscriber }
node_preview:
class: Drupal\node\ParamConverter\NodePreviewConverter
arguments: ['@user.private_tempstore']
arguments: ['@tempstore.private']
tags:
- { name: paramconverter }
lazy: true
@@ -173,6 +173,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
$rows = [];
$default_revision = $node->getRevisionId();
$current_revision_displayed = FALSE;
foreach ($this->getRevisionIds($node, $node_storage) as $vid) {
/** @var \Drupal\node\NodeInterface $revision */
@@ -187,11 +188,18 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
// Use revision link to link to revisions that are not active.
$date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short');
if ($vid != $node->getRevisionId()) {
// We treat also the latest translation-affecting revision as current
// revision, if it was the default revision, as its values for the
// current language will be the same of the current default revision in
// this case.
$is_current_revision = $vid == $default_revision || (!$current_revision_displayed && $revision->wasDefaultRevision());
if (!$is_current_revision) {
$link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid]));
}
else {
$link = $node->link($date);
$current_revision_displayed = TRUE;
}
$row = [];
@@ -210,7 +218,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
$this->renderer->addCacheableDependency($column['data'], $username);
$row[] = $column;
if ($vid == $default_revision) {
if ($is_current_revision) {
$row[] = [
'data' => [
'#prefix' => '<em>',
@@ -6,12 +6,14 @@ use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\user\PrivateTempStoreFactory;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Provides a node deletion confirmation form.
*
* @internal
*/
class DeleteMultiple extends ConfirmFormBase {
@@ -25,7 +27,7 @@ class DeleteMultiple extends ConfirmFormBase {
/**
* The tempstore factory.
*
* @var \Drupal\user\PrivateTempStoreFactory
* @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -34,12 +36,12 @@ class DeleteMultiple extends ConfirmFormBase {
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $manager;
protected $storage;
/**
* Constructs a DeleteMultiple form object.
*
* @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
* @param \Drupal\Core\Entity\EntityManagerInterface $manager
* The entity manager.
@@ -54,7 +56,7 @@ class DeleteMultiple extends ConfirmFormBase {
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('user.private_tempstore'),
$container->get('tempstore.private'),
$container->get('entity.manager')
);
}
@@ -6,6 +6,8 @@ use Drupal\Core\Entity\ContentEntityDeleteForm;
/**
* Provides a form for deleting a node.
*
* @internal
*/
class NodeDeleteForm extends ContentEntityDeleteForm {
@@ -12,6 +12,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Contains a form for switching the view mode of a node during preview.
*
* @internal
*/
class NodePreviewForm extends FormBase {
@@ -11,6 +11,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a form for reverting a node revision.
*
* @internal
*/
class NodeRevisionDeleteForm extends ConfirmFormBase {
@@ -13,6 +13,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a form for reverting a node revision.
*
* @internal
*/
class NodeRevisionRevertForm extends ConfirmFormBase {
@@ -26,7 +28,7 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
/**
* The node storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
* @var \Drupal\node\NodeStorageInterface
*/
protected $nodeStorage;
@@ -12,6 +12,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a form for reverting a node revision for a single translation.
*
* @internal
*/
class NodeRevisionRevertTranslationForm extends NodeRevisionRevertForm {
@@ -86,10 +88,15 @@ class NodeRevisionRevertTranslationForm extends NodeRevisionRevertForm {
$this->langcode = $langcode;
$form = parent::buildForm($form, $form_state, $node_revision);
// Unless untranslatable fields are configured to affect only the default
// translation, we need to ask the user whether they should be included in
// the revert process.
$default_translation_affected = $this->revision->isDefaultTranslationAffectedOnly();
$form['revert_untranslated_fields'] = [
'#type' => 'checkbox',
'#title' => $this->t('Revert content shared among translations'),
'#default_value' => FALSE,
'#default_value' => $default_translation_affected && $this->revision->getTranslation($this->langcode)->isDefaultTranslation(),
'#access' => !$default_translation_affected,
];
return $form;
@@ -99,24 +106,9 @@ class NodeRevisionRevertTranslationForm extends NodeRevisionRevertForm {
* {@inheritdoc}
*/
protected function prepareRevertedRevision(NodeInterface $revision, FormStateInterface $form_state) {
$revert_untranslated_fields = $form_state->getValue('revert_untranslated_fields');
/** @var \Drupal\node\NodeInterface $default_revision */
$latest_revision = $this->nodeStorage->load($revision->id());
$latest_revision_translation = $latest_revision->getTranslation($this->langcode);
$revision_translation = $revision->getTranslation($this->langcode);
foreach ($latest_revision_translation->getFieldDefinitions() as $field_name => $definition) {
if ($definition->isTranslatable() || $revert_untranslated_fields) {
$latest_revision_translation->set($field_name, $revision_translation->get($field_name)->getValue());
}
}
$latest_revision_translation->setNewRevision();
$latest_revision_translation->isDefaultRevision(TRUE);
return $latest_revision_translation;
$revert_untranslated_fields = (bool) $form_state->getValue('revert_untranslated_fields');
$translation = $revision->getTranslation($this->langcode);
return $this->nodeStorage->createRevision($translation, TRUE, $revert_untranslated_fields);
}
}
@@ -7,6 +7,8 @@ use Drupal\Core\Form\FormStateInterface;
/**
* Provides a form for content type deletion.
*
* @internal
*/
class NodeTypeDeleteConfirm extends EntityDeleteForm {
@@ -6,6 +6,11 @@ use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
/**
* Form for rebuilding permissions.
*
* @internal
*/
class RebuildPermissionsForm extends ConfirmFormBase {
/**
+6 -11
View File
@@ -8,18 +8,20 @@ use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\PrivateTempStoreFactory;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Form handler for the node edit forms.
*
* @internal
*/
class NodeForm extends ContentEntityForm {
/**
* The tempstore factory.
*
* @var \Drupal\user\PrivateTempStoreFactory
* @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -35,7 +37,7 @@ class NodeForm extends ContentEntityForm {
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
* @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The factory for the temp store object.
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
* The entity type bundle service.
@@ -56,7 +58,7 @@ class NodeForm extends ContentEntityForm {
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager'),
$container->get('user.private_tempstore'),
$container->get('tempstore.private'),
$container->get('entity_type.bundle.info'),
$container->get('datetime.time'),
$container->get('current_user')
@@ -142,13 +144,6 @@ class NodeForm extends ContentEntityForm {
'#wrapper_attributes' => ['class' => ['entity-meta__author']],
];
$form['footer'] = [
'#type' => 'container',
'#weight' => 99,
'#attributes' => [
'class' => ['node-form-footer']
]
];
$form['status']['#group'] = 'footer';
// Node author information for administrators.
@@ -211,6 +211,7 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
$query = $this->database->insert('node_access')->fields(['nid', 'langcode', 'fallback', 'realm', 'gid', 'grant_view', 'grant_update', 'grant_delete']);
// If we have defined a granted langcode, use it. But if not, add a grant
// for every language this node is translated to.
$fallback_langcode = $node->getUntranslated()->language()->getId();
foreach ($grants as $grant) {
if ($realm && $realm != $grant['realm']) {
continue;
@@ -227,7 +228,7 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
$grant['nid'] = $node->id();
$grant['langcode'] = $grant_langcode;
// The record with the original langcode is used as the fallback.
if ($grant['langcode'] == $node->language()->getId()) {
if ($grant['langcode'] == $fallback_langcode) {
$grant['fallback'] = 1;
}
else {
-20
View File
@@ -25,13 +25,6 @@ class NodeListBuilder extends EntityListBuilder {
*/
protected $dateFormatter;
/**
* The redirect destination service.
*
* @var \Drupal\Core\Routing\RedirectDestinationInterface
*/
protected $redirectDestination;
/**
* Constructs a new NodeListBuilder object.
*
@@ -128,17 +121,4 @@ class NodeListBuilder extends EntityListBuilder {
return $row + parent::buildRow($entity);
}
/**
* {@inheritdoc}
*/
protected function getDefaultOperations(EntityInterface $entity) {
$operations = parent::getDefaultOperations($entity);
$destination = $this->redirectDestination->getAsArray();
foreach ($operations as $key => $operation) {
$operations[$key]['query'] = $destination;
}
return $operations;
}
}
+2
View File
@@ -11,6 +11,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Form handler for node type forms.
*
* @internal
*/
class NodeTypeForm extends BundleEntityFormBase {
+9 -29
View File
@@ -2,10 +2,8 @@
namespace Drupal\node;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityViewBuilder;
use Drupal\node\Entity\Node;
/**
* View builder handler for nodes.
@@ -35,6 +33,7 @@ class NodeViewBuilder extends EntityViewBuilder {
$view_mode,
$entity->language()->getId(),
!empty($entity->in_preview),
$entity->isDefaultRevision() ? NULL : $entity->getLoadedRevisionId(),
],
],
];
@@ -78,11 +77,14 @@ class NodeViewBuilder extends EntityViewBuilder {
* The language in which the node entity is being viewed.
* @param bool $is_in_preview
* Whether the node is currently being previewed.
* @param $revision_id
* (optional) The identifier of the node revision to be loaded. If none
* is provided, the default revision will be loaded.
*
* @return array
* A renderable array representing the node links.
*/
public static function renderLinks($node_entity_id, $view_mode, $langcode, $is_in_preview) {
public static function renderLinks($node_entity_id, $view_mode, $langcode, $is_in_preview, $revision_id = NULL) {
$links = [
'#theme' => 'links__node',
'#pre_render' => ['drupal_pre_render_links'],
@@ -90,7 +92,10 @@ class NodeViewBuilder extends EntityViewBuilder {
];
if (!$is_in_preview) {
$entity = Node::load($node_entity_id)->getTranslation($langcode);
$storage = \Drupal::entityTypeManager()->getStorage('node');
/** @var \Drupal\node\NodeInterface $revision */
$revision = !isset($revision_id) ? $storage->load($node_entity_id) : $storage->loadRevision($revision_id);
$entity = $revision->getTranslation($langcode);
$links['node'] = static::buildLinks($entity, $view_mode);
// Allow other modules to alter the node links.
@@ -141,29 +146,4 @@ class NodeViewBuilder extends EntityViewBuilder {
];
}
/**
* {@inheritdoc}
*/
protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
/** @var \Drupal\node\NodeInterface $entity */
parent::alterBuild($build, $entity, $display, $view_mode);
if ($entity->id()) {
if ($entity->isDefaultRevision()) {
$build['#contextual_links']['node'] = [
'route_parameters' => ['node' => $entity->id()],
'metadata' => ['changed' => $entity->getChangedTime()],
];
}
else {
$build['#contextual_links']['node_revision'] = [
'route_parameters' => [
'node' => $entity->id(),
'node_revision' => $entity->getRevisionId(),
],
'metadata' => ['changed' => $entity->getChangedTime()],
];
}
}
}
}
-8
View File
@@ -58,14 +58,6 @@ class NodeViewsData extends EntityViewsData {
$data['node_field_data']['sticky']['filter']['type'] = 'yes-no';
$data['node_field_data']['sticky']['sort']['help'] = $this->t('Whether or not the content is sticky. To list sticky content first, set this to descending.');
$data['node']['path'] = [
'field' => [
'title' => $this->t('Path'),
'help' => $this->t('The aliased path to this content.'),
'id' => 'node_path',
],
];
$data['node']['node_bulk_form'] = [
'title' => $this->t('Node operations bulk form'),
'help' => $this->t('Add a form element that lets you run operations on multiple nodes.'),
@@ -2,7 +2,7 @@
namespace Drupal\node\ParamConverter;
use Drupal\user\PrivateTempStoreFactory;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\Routing\Route;
use Drupal\Core\ParamConverter\ParamConverterInterface;
@@ -14,14 +14,14 @@ class NodePreviewConverter implements ParamConverterInterface {
/**
* Stores the tempstore factory.
*
* @var \Drupal\user\PrivateTempStoreFactory
* @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
/**
* Constructs a new NodePreviewConverter.
*
* @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The factory for the temp store object.
*/
public function __construct(PrivateTempStoreFactory $temp_store_factory) {
@@ -5,7 +5,7 @@ namespace Drupal\node\Plugin\Action;
use Drupal\Core\Action\ActionBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\PrivateTempStoreFactory;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -23,7 +23,7 @@ class DeleteNode extends ActionBase implements ContainerFactoryPluginInterface {
/**
* The tempstore object.
*
* @var \Drupal\user\SharedTempStore
* @var \Drupal\Core\TempStore\SharedTempStore
*/
protected $tempStore;
@@ -43,7 +43,7 @@ class DeleteNode extends ActionBase implements ContainerFactoryPluginInterface {
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
* @param \Drupal\Core\Session\AccountInterface $current_user
* Current user.
@@ -63,7 +63,7 @@ class DeleteNode extends ActionBase implements ContainerFactoryPluginInterface {
$configuration,
$plugin_id,
$plugin_definition,
$container->get('user.private_tempstore'),
$container->get('tempstore.private'),
$container->get('current_user')
);
}
@@ -2,25 +2,32 @@
namespace Drupal\node\Plugin\Action;
use Drupal\Core\Field\FieldUpdateActionBase;
use Drupal\node\NodeInterface;
use Drupal\Core\Action\Plugin\Action\PublishAction;
use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Publishes a node.
*
* @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
* Use \Drupal\Core\Action\Plugin\Action\PublishAction instead.
*
* @see \Drupal\Core\Action\Plugin\Action\PublishAction
* @see https://www.drupal.org/node/2919303
*
* @Action(
* id = "node_publish_action",
* label = @Translation("Publish selected content"),
* type = "node"
* )
*/
class PublishNode extends FieldUpdateActionBase {
class PublishNode extends PublishAction {
/**
* {@inheritdoc}
*/
protected function getFieldsToUpdate() {
return ['status' => NodeInterface::PUBLISHED];
public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
@trigger_error(__NAMESPACE__ . '\PublishNode is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\PublishAction instead. See https://www.drupal.org/node/2919303.', E_USER_DEPRECATED);
}
}
@@ -2,36 +2,33 @@
namespace Drupal\node\Plugin\Action;
use Drupal\Core\Action\ActionBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Action\Plugin\Action\SaveAction;
use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Provides an action that can save any entity.
*
* @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
* Use \Drupal\Core\Action\Plugin\Action\SaveAction instead.
*
* @see \Drupal\Core\Action\Plugin\Action\SaveAction
* @see https://www.drupal.org/node/2919303
*
* @Action(
* id = "node_save_action",
* label = @Translation("Save content"),
* type = "node"
* )
*/
class SaveNode extends ActionBase {
class SaveNode extends SaveAction {
/**
* {@inheritdoc}
*/
public function execute($entity = NULL) {
// We need to change at least one value, otherwise the changed timestamp
// will not be updated.
$entity->changed = 0;
$entity->save();
}
/**
* {@inheritdoc}
*/
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
/** @var \Drupal\node\NodeInterface $object */
return $object->access('update', $account, $return_as_object);
public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, TimeInterface $time) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $time);
@trigger_error(__NAMESPACE__ . '\SaveNode is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\SaveAction instead. See https://www.drupal.org/node/2919303.', E_USER_DEPRECATED);
}
}
@@ -2,25 +2,32 @@
namespace Drupal\node\Plugin\Action;
use Drupal\Core\Field\FieldUpdateActionBase;
use Drupal\node\NodeInterface;
use Drupal\Core\Action\Plugin\Action\UnpublishAction;
use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Unpublishes a node.
*
* @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
* Use \Drupal\Core\Action\Plugin\Action\UnpublishAction instead.
*
* @see \Drupal\Core\Action\Plugin\Action\UnpublishAction
* @see https://www.drupal.org/node/2919303
*
* @Action(
* id = "node_unpublish_action",
* label = @Translation("Unpublish selected content"),
* type = "node"
* )
*/
class UnpublishNode extends FieldUpdateActionBase {
class UnpublishNode extends UnpublishAction {
/**
* {@inheritdoc}
*/
protected function getFieldsToUpdate() {
return ['status' => NodeInterface::NOT_PUBLISHED];
public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
@trigger_error(__NAMESPACE__ . '\UnpublishNode is deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\UnpublishAction instead. See https://www.drupal.org/node/2919303.', E_USER_DEPRECATED);
}
}
@@ -3,7 +3,6 @@
namespace Drupal\node\Plugin\EntityReferenceSelection;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\NodeInterface;
/**
@@ -19,15 +18,6 @@ use Drupal\node\NodeInterface;
*/
class NodeSelection extends DefaultSelection {
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$form['target_bundles']['#title'] = $this->t('Content types');
return $form;
}
/**
* {@inheritdoc}
*/
@@ -2,7 +2,7 @@
namespace Drupal\node\Plugin\views\field;
use Drupal\system\Plugin\views\field\BulkForm;
use Drupal\views\Plugin\views\field\BulkForm;
/**
* Defines a node operations bulk form element.
@@ -2,6 +2,8 @@
namespace Drupal\node\Plugin\views\field;
@trigger_error('Drupal\node\Plugin\views\field\Path is deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. Use @ViewsField("entity_link") with \'output_url_as_text\' set.', E_USER_DEPRECATED);
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\field\FieldPluginBase;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
@@ -14,6 +16,9 @@ use Drupal\views\ViewExecutable;
* @ingroup views_field_handlers
*
* @ViewsField("node_path")
*
* @deprecated in Drupal 8.5.x, will be removed before Drupal 9.0.0.
* Use @ViewsField("entity_link") with 'output_url_as_text' set.
*/
class Path extends FieldPluginBase {
@@ -27,20 +27,6 @@ class Node extends WizardPluginBase {
*/
protected $createdColumn = 'node_field_data-created';
/**
* Set default values for the filters.
*/
protected $filters = [
'status' => [
'value' => TRUE,
'table' => 'node_field_data',
'field' => 'status',
'plugin_id' => 'boolean',
'entity_type' => 'node',
'entity_field' => 'status',
]
];
/**
* Overrides Drupal\views\Plugin\views\wizard\WizardPluginBase::getAvailableSorts().
*
@@ -26,20 +26,6 @@ class NodeRevision extends WizardPluginBase {
*/
protected $createdColumn = 'changed';
/**
* Set default values for the filters.
*/
protected $filters = [
'status' => [
'value' => TRUE,
'table' => 'node_field_revision',
'field' => 'status',
'plugin_id' => 'boolean',
'entity_type' => 'node',
'entity_field' => 'status',
]
];
/**
* Overrides Drupal\views\Plugin\views\wizard\WizardPluginBase::rowStyleOptions().
*
@@ -64,6 +64,9 @@ class NodeRevisionsTest extends NodeTestBase {
$field = FieldConfig::create($field_definition);
$field->save();
// Enable translation for page nodes.
\Drupal::service('content_translation.manager')->setEnabled('node', 'page', TRUE);
// Create and log in user.
$web_user = $this->drupalCreateUser(
[
@@ -171,7 +171,7 @@ class PagePreviewTest extends NodeTestBase {
// Upload an image.
$test_image = current($this->drupalGetTestFiles('image', 39325));
$edit['files[field_image_0][]'] = drupal_realpath($test_image->uri);
$edit['files[field_image_0][]'] = \Drupal::service('file_system')->realpath($test_image->uri);
$this->drupalPostForm('node/add/page', $edit, t('Upload'));
// Add an alt tag and preview the node.
@@ -316,11 +316,13 @@ class PagePreviewTest extends NodeTestBase {
$this->assertUrl($node->toUrl());
$this->assertResponse(200);
/** @var \Drupal\Core\File\FileSystemInterface $file_system */
$file_system = \Drupal::service('file_system');
// Assert multiple items can be added and are not lost when previewing.
$test_image_1 = current($this->drupalGetTestFiles('image', 39325));
$edit_image_1['files[field_image_0][]'] = drupal_realpath($test_image_1->uri);
$edit_image_1['files[field_image_0][]'] = $file_system->realpath($test_image_1->uri);
$test_image_2 = current($this->drupalGetTestFiles('image', 39325));
$edit_image_2['files[field_image_1][]'] = drupal_realpath($test_image_2->uri);
$edit_image_2['files[field_image_1][]'] = $file_system->realpath($test_image_2->uri);
$edit['field_image[0][alt]'] = 'Alt 1';
$this->drupalPostForm('node/add/page', $edit_image_1, t('Upload'));
@@ -5,8 +5,8 @@ package: Testing
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
# Information added by Drupal.org packaging script on 2018-03-07
version: '8.5.0'
core: '8.x'
project: 'drupal'
datestamp: 1515021228
datestamp: 1520457825
@@ -5,8 +5,8 @@ package: Testing
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
# Information added by Drupal.org packaging script on 2018-03-07
version: '8.5.0'
core: '8.x'
project: 'drupal'
datestamp: 1515021228
datestamp: 1520457825
@@ -7,8 +7,8 @@ package: Testing
dependencies:
- options
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
# Information added by Drupal.org packaging script on 2018-03-07
version: '8.5.0'
core: '8.x'
project: 'drupal'
datestamp: 1515021228
datestamp: 1520457825
@@ -5,8 +5,8 @@ package: Testing
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
# Information added by Drupal.org packaging script on 2018-03-07
version: '8.5.0'
core: '8.x'
project: 'drupal'
datestamp: 1515021228
datestamp: 1520457825
@@ -5,8 +5,8 @@ description: 'Support module for node configuration tests.'
package: Testing
# version: VERSION
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
# Information added by Drupal.org packaging script on 2018-03-07
version: '8.5.0'
core: '8.x'
project: 'drupal'
datestamp: 1515021228
datestamp: 1520457825
@@ -5,8 +5,8 @@ package: Testing
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
# Information added by Drupal.org packaging script on 2018-03-07
version: '8.5.0'
core: '8.x'
project: 'drupal'
datestamp: 1515021228
datestamp: 1520457825
@@ -9,8 +9,8 @@ dependencies:
- views
- language
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
# Information added by Drupal.org packaging script on 2018-03-07
version: '8.5.0'
core: '8.x'
project: 'drupal'
datestamp: 1515021228
datestamp: 1520457825
@@ -5,8 +5,8 @@ package: Testing
# version: VERSION
# core: 8.x
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
# Information added by Drupal.org packaging script on 2018-03-07
version: '8.5.0'
core: '8.x'
project: 'drupal'
datestamp: 1515021228
datestamp: 1520457825
@@ -0,0 +1,131 @@
<?php
namespace Drupal\Tests\node\Functional;
use Drupal\language\Entity\ConfigurableLanguage;
/**
* Tests that the node_access system stores the proper fallback marker.
*
* @group node
*/
class NodeAccessLanguageFallbackTest extends NodeTestBase {
/**
* Enable language and a non-language-aware node access module.
*
* @var array
*/
public static $modules = ['language', 'node_access_test', 'content_translation'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// After enabling a node access module, the {node_access} table has to be
// rebuilt.
node_access_rebuild();
// Add Hungarian, Catalan, and Afrikaans.
ConfigurableLanguage::createFromLangcode('hu')->save();
ConfigurableLanguage::createFromLangcode('ca')->save();
ConfigurableLanguage::createFromLangcode('af')->save();
// Enable content translation for the current entity type.
\Drupal::service('content_translation.manager')->setEnabled('node', 'page', TRUE);
}
/**
* Tests node access fallback handling with multiple node languages.
*/
public function testNodeAccessLanguageFallback() {
// The node_access_test module allows nodes to be marked private. We need to
// ensure that system honors the fallback system of node access properly.
// Note that node_access_test_language is language-sensitive and does not
// apply to the fallback test.
// Create one node in Hungarian and marked as private.
$node = $this->drupalCreateNode([
'body' => [[]],
'langcode' => 'hu',
'private' => [['value' => 1]],
'status' => 1,
]);
// There should be one entry in node_access, with fallback set to hu.
$this->checkRecords(1, 'hu');
// Create a translation user.
$admin = $this->drupalCreateUser([
'bypass node access',
'administer nodes',
'translate any entity',
'administer content translation',
]);
$this->drupalLogin($admin);
$this->drupalGet('node/' . $node->id() . '/translations');
$this->assertSession()->statusCodeEquals(200);
// Create a Catalan translation through the UI.
$url_options = ['language' => \Drupal::languageManager()->getLanguage('ca')];
$this->drupalGet('node/' . $node->id() . '/translations/add/hu/ca', $url_options);
$this->assertSession()->statusCodeEquals(200);
// Save the form.
$this->getSession()->getPage()->pressButton('Save (this translation)');
$this->assertSession()->statusCodeEquals(200);
// Check the node access table.
$this->checkRecords(2, 'hu');
// Programmatically create a translation. This process lets us check that
// both forms and code behave in the same way.
$storage = \Drupal::entityTypeManager()->getStorage('node');
// Reload the node.
$node = $storage->load(1);
// Create an Afrikaans translation.
$translation = $node->addTranslation('af');
$translation->title->value = $this->randomString();
$translation->status = 1;
$node->save();
// Check the node access table.
$this->checkRecords(3, 'hu');
// For completeness, edit the Catalan version again.
$this->drupalGet('node/' . $node->id() . '/edit', $url_options);
$this->assertSession()->statusCodeEquals(200);
// Save the form.
$this->getSession()->getPage()->pressButton('Save (this translation)');
$this->assertSession()->statusCodeEquals(200);
// Check the node access table.
$this->checkRecords(3, 'hu');
}
/**
* Queries the node_access table and checks for proper storage.
*
* @param int $count
* The number of rows expected by the query (equal to the translation
* count).
* @param $langcode
* The expected language code set as the fallback property.
*/
public function checkRecords($count, $langcode = 'hu') {
$select = \Drupal::database()
->select('node_access', 'na')
->fields('na', ['nid', 'fallback', 'langcode', 'grant_view'])
->condition('na.realm', 'node_access_test', '=')
->condition('na.gid', 8888, '=');
$records = $select->execute()->fetchAll();
// Check that the expected record count is returned.
$this->assertEquals(count($records), $count);
// The fallback value is 'hu' and should be set to 1. For other languages,
// it should be set to 0. Casting to boolean lets us run that comparison.
foreach ($records as $record) {
$this->assertEquals((bool) $record->fallback, $record->langcode === $langcode);
}
}
}
@@ -2,7 +2,6 @@
namespace Drupal\Tests\node\Functional;
use Drupal\Component\Utility\Crypt;
use Drupal\Tests\BrowserTestBase;
use Drupal\system\Entity\Action;
@@ -30,7 +29,7 @@ class NodeActionsConfigurationTest extends BrowserTestBase {
// Make a POST request to admin/config/system/actions.
$edit = [];
$edit['action'] = Crypt::hashBase64('node_assign_owner_action');
$edit['action'] = 'node_assign_owner_action';
$this->drupalPostForm('admin/config/system/actions', $edit, t('Create'));
$this->assertResponse(200);
@@ -40,17 +39,17 @@ class NodeActionsConfigurationTest extends BrowserTestBase {
$edit['label'] = $action_label;
$edit['id'] = strtolower($action_label);
$edit['owner_uid'] = $user->id();
$this->drupalPostForm('admin/config/system/actions/add/' . Crypt::hashBase64('node_assign_owner_action'), $edit, t('Save'));
$this->drupalPostForm('admin/config/system/actions/add/node_assign_owner_action', $edit, t('Save'));
$this->assertResponse(200);
$action_id = $edit['id'];
// Make sure that the new action was saved properly.
$this->assertText(t('The action has been successfully saved.'), 'The node_assign_owner_action action has been successfully saved.');
$this->assertText($action_label, 'The label of the node_assign_owner_action action appears on the actions administration page after saving.');
// Make another POST request to the action edit page.
$this->clickLink(t('Configure'));
preg_match('|admin/config/system/actions/configure/(.+)|', $this->getUrl(), $matches);
$aid = $matches[1];
$edit = [];
$new_action_label = $this->randomMachineName();
$edit['label'] = $new_action_label;
@@ -68,7 +67,7 @@ class NodeActionsConfigurationTest extends BrowserTestBase {
$this->clickLink(t('Delete'));
$this->assertResponse(200);
$edit = [];
$this->drupalPostForm("admin/config/system/actions/configure/$aid/delete", $edit, t('Delete'));
$this->drupalPostForm(NULL, $edit, t('Delete'));
$this->assertResponse(200);
// Make sure that the action was actually deleted.
@@ -77,7 +76,7 @@ class NodeActionsConfigurationTest extends BrowserTestBase {
$this->assertResponse(200);
$this->assertNoText($new_action_label, 'The label for the node_assign_owner_action action does not appear on the actions administration page after deleting.');
$action = Action::load($aid);
$action = Action::load($action_id);
$this->assertFalse($action, 'The node_assign_owner_action action is not available after being deleted.');
}
@@ -0,0 +1,42 @@
<?php
namespace Drupal\Tests\node\Functional;
use Drupal\node\Entity\Node;
/**
* Tests views contextual links on nodes.
*
* @group node
*/
class NodeContextualLinksTest extends NodeTestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'contextual',
];
/**
* Tests contextual links.
*/
public function testNodeContextualLinks() {
// Create a node item.
$node = Node::create([
'type' => 'article',
'title' => 'Unnamed',
]);
$node->save();
$user = $this->drupalCreateUser([
'administer nodes',
'access contextual links',
]);
$this->drupalLogin($user);
$this->drupalGet('node/' . $node->id());
$this->assertSession()->elementAttributeContains('css', 'div[data-contextual-id]', 'data-contextual-id', 'node:node=' . $node->id() . ':');
}
}
@@ -160,10 +160,17 @@ class NodeRevisionsUiTest extends NodeTestBase {
$this->drupalGet('node/' . $node_id . '/revisions');
// Verify that the latest affected revision having been a default revision
// is displayed as the current one.
$this->assertNoLinkByHref('/node/' . $node_id . '/revisions/1/revert');
$elements = $this->xpath('//tr[contains(@class, "revision-current")]/td/a[1]');
// The site may be installed in a subdirectory, so check if the URL is
// contained in the retrieved one.
$this->assertContains('/node/1', current($elements)->getAttribute('href'));
// Verify that the default revision can be an older revision than the latest
// one.
// Assert that the revisions with translations changes are shown: 1 and 4.
$this->assertLinkByHref('/node/' . $node_id . '/revisions/1/revert');
// Assert that the revisions with translations changes are shown.
$this->assertLinkByHref('/node/' . $node_id . '/revisions/4/revert');
// Assert that the revisions without translations changes are filtered out:
@@ -21,13 +21,15 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
*/
protected $defaultCacheContexts = [
'languages:language_interface',
'session',
'theme',
'route',
'timezone',
'url.path.parent',
'url.query_args:_wrapper_format',
'user'
'user.roles',
// These two cache contexts are added by BigPipe.
'cookies:big_pipe_nojs',
'session.exists',
];
/**
@@ -45,16 +45,19 @@ class NodeRevisionWizardTest extends WizardTestBase {
$view['show[wizard_key]'] = 'node_revision';
$this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit'));
$view_storage_controller = \Drupal::entityManager()->getStorage('view');
/** @var \Drupal\views\Entity\View $view */
$view = $view_storage_controller->load($view['id']);
$view = Views::getView($view['id']);
$view->initHandlers();
$this->assertEqual($view->get('base_table'), 'node_field_revision');
$this->assertEqual($view->getBaseTables(), ['node_field_revision' => TRUE, '#global' => TRUE]);
$executable = Views::executableFactory()->get($view);
$this->executeView($executable);
// Check for the default filters.
$this->assertEqual($view->filter['status']->table, 'node_field_revision');
$this->assertEqual($view->filter['status']->field, 'status');
$this->assertTrue($view->filter['status']->value);
$this->assertIdenticalResultset($executable, [['vid' => 1], ['vid' => 3], ['vid' => 2], ['vid' => 4]],
$this->executeView($view);
$this->assertIdenticalResultset($view, [['vid' => 1], ['vid' => 3], ['vid' => 2], ['vid' => 4]],
['vid' => 'vid']);
}
@@ -58,12 +58,18 @@ class PathPluginTest extends NodeTestBase {
}
/**
* Tests the node path plugin.
* Tests the node path plugin functionality when converted to entity link.
*/
public function testPathPlugin() {
/** @var \Drupal\Core\Render\RendererInterface $renderer */
$renderer = $this->container->get('renderer');
$view = Views::getView('test_node_path_plugin');
// The configured deprecated node path plugin should be converted to the
// entity link plugin.
$field = $view->getHandler('page_1', 'field', 'path');
$this->assertEqual('entity_link', $field['plugin_id']);
$view->initDisplay();
$view->setDisplay('page_1');
$view->initStyle();
@@ -42,9 +42,7 @@ class MigrateNodeDeriverTest extends MigrateDrupal6TestBase {
// With content_translation, there should be translation migrations for
// each content type.
$this->enableModules(['language', 'content_translation']);
$migrations = $this->pluginManager->createInstances('d6_node_translation');
$this->assertArrayHasKey('d6_node_translation:story', $migrations,
"Node translation migrations exist after content_translation installed");
$this->assertTrue($this->container->get('plugin.manager.migration')->hasDefinition('d6_node_translation:story'), "Node translation migrations exist after content_translation installed");
}
}
@@ -11,38 +11,17 @@ use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
*/
class MigrateNodeDeriverTest extends MigrateDrupal7TestBase {
/**
* The migration plugin manager.
*
* @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface
*/
protected $pluginManager;
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->pluginManager = $this->container->get('plugin.manager.migration');
$this->moduleHandler = $this->container->get('module_handler');
}
public static $modules = ['node'];
/**
* Test node translation migrations with translation disabled.
*/
public function testNoTranslations() {
// Enabling node module for this test.
$this->enableModules(['node']);
// Without content_translation, there should be no translation migrations.
$migrations = $this->pluginManager->createInstances('d7_node_translation');
$this->assertTrue($this->moduleHandler->moduleExists('node'));
$migrations = $this->container->get('plugin.manager.migration')->createInstances('d7_node_translation');
$this->assertEmpty($migrations);
}
@@ -52,10 +31,8 @@ class MigrateNodeDeriverTest extends MigrateDrupal7TestBase {
public function testTranslations() {
// With content_translation, there should be translation migrations for
// each content type.
$this->enableModules(['language', 'content_translation', 'node', 'filter']);
$migrations = $this->pluginManager->createInstances('d7_node_translation');
$this->assertArrayHasKey('d7_node_translation:article', $migrations,
"Node translation migrations exist after content_translation installed");
$this->enableModules(['language', 'content_translation', 'filter']);
$this->assertTrue($this->container->get('plugin.manager.migration')->hasDefinition('d7_node_translation:article'), "Node translation migrations exist after content_translation installed");
}
}
@@ -0,0 +1,101 @@
<?php
namespace Drupal\Tests\node\Kernel;
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\user\Entity\User;
/**
* Tests the node view builder.
*
* @group node
*
* @coversDefaultClass \Drupal\node\NodeViewBuilder
*/
class NodeViewBuilderTest extends EntityKernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['node'];
/**
* The node storage.
*
* @var \Drupal\node\NodeStorageInterface
*/
protected $storage;
/**
* The node view builder.
*
* @var \Drupal\Core\Entity\EntityViewBuilderInterface
*/
protected $viewBuilder;
/**
* The renderer.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->storage = $this->entityManager->getStorage('node');
$this->viewBuilder = $this->entityManager->getViewBuilder('node');
$this->renderer = $this->container->get('renderer');
$type = NodeType::create([
'type' => 'article',
'name' => 'Article',
]);
$type->save();
$this->installSchema('node', 'node_access');
$this->installConfig(['system', 'node']);
}
/**
* Tests that node links are displayed correctly in pending revisions.
*
* @covers ::buildComponents
* @covers ::renderLinks
* @covers ::buildLinks
*/
public function testPendingRevisionLinks() {
$account = User::create([
'name' => $this->randomString(),
]);
$account->save();
$title = $this->randomMachineName();
$node = Node::create([
'type' => 'article',
'title' => $title,
'uid' => $account->id(),
]);
$node->save();
/** @var \Drupal\node\NodeInterface $pending_revision */
$pending_revision = $this->storage->createRevision($node, FALSE);
$draft_title = $title . ' draft';
$pending_revision->setTitle($draft_title);
$pending_revision->save();
$build = $this->viewBuilder->view($node, 'teaser');
$output = (string) $this->renderer->renderPlain($build);
$this->assertContains("title=\"$title\"", $output);
$build = $this->viewBuilder->view($pending_revision, 'teaser');
$output = (string) $this->renderer->renderPlain($build);
$this->assertContains("title=\"$draft_title\"", $output);
}
}