upgrades core to 8.4.2
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @file
|
||||
* Javascript for the node content editing form.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
/**
|
||||
* Behaviors for setting summaries on content type form.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches summary behaviors on content type edit forms.
|
||||
*/
|
||||
Drupal.behaviors.contentTypes = {
|
||||
attach(context) {
|
||||
const $context = $(context);
|
||||
// Provide the vertical tab summaries.
|
||||
$context.find('#edit-submission').drupalSetSummary((context) => {
|
||||
const vals = [];
|
||||
vals.push(Drupal.checkPlain($(context).find('#edit-title-label').val()) || Drupal.t('Requires a title'));
|
||||
return vals.join(', ');
|
||||
});
|
||||
$context.find('#edit-workflow').drupalSetSummary((context) => {
|
||||
const vals = [];
|
||||
$(context).find('input[name^="options"]:checked').next('label').each(function () {
|
||||
vals.push(Drupal.checkPlain($(this).text()));
|
||||
});
|
||||
if (!$(context).find('#edit-options-status').is(':checked')) {
|
||||
vals.unshift(Drupal.t('Not published'));
|
||||
}
|
||||
return vals.join(', ');
|
||||
});
|
||||
$('#edit-language', context).drupalSetSummary((context) => {
|
||||
const vals = [];
|
||||
|
||||
vals.push($('.js-form-item-language-configuration-langcode select option:selected', context).text());
|
||||
|
||||
$('input:checked', context).next('label').each(function () {
|
||||
vals.push(Drupal.checkPlain($(this).text()));
|
||||
});
|
||||
|
||||
return vals.join(', ');
|
||||
});
|
||||
$context.find('#edit-display').drupalSetSummary((context) => {
|
||||
const vals = [];
|
||||
const $editContext = $(context);
|
||||
$editContext.find('input:checked').next('label').each(function () {
|
||||
vals.push(Drupal.checkPlain($(this).text()));
|
||||
});
|
||||
if (!$editContext.find('#edit-display-submitted').is(':checked')) {
|
||||
vals.unshift(Drupal.t("Don't display post information"));
|
||||
}
|
||||
return vals.join(', ');
|
||||
});
|
||||
},
|
||||
};
|
||||
}(jQuery, Drupal));
|
||||
@@ -1,24 +1,15 @@
|
||||
/**
|
||||
* @file
|
||||
* Javascript for the node content editing form.
|
||||
*/
|
||||
* DO NOT EDIT THIS FILE.
|
||||
* See the following change record for more information,
|
||||
* https://www.drupal.org/node/2815083
|
||||
* @preserve
|
||||
**/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Behaviors for setting summaries on content type form.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches summary behaviors on content type edit forms.
|
||||
*/
|
||||
Drupal.behaviors.contentTypes = {
|
||||
attach: function (context) {
|
||||
attach: function attach(context) {
|
||||
var $context = $(context);
|
||||
// Provide the vertical tab summaries.
|
||||
|
||||
$context.find('#edit-submission').drupalSetSummary(function (context) {
|
||||
var vals = [];
|
||||
vals.push(Drupal.checkPlain($(context).find('#edit-title-label').val()) || Drupal.t('Requires a title'));
|
||||
@@ -26,7 +17,7 @@
|
||||
});
|
||||
$context.find('#edit-workflow').drupalSetSummary(function (context) {
|
||||
var vals = [];
|
||||
$(context).find('input[name^="options"]:checked').parent().each(function () {
|
||||
$(context).find('input[name^="options"]:checked').next('label').each(function () {
|
||||
vals.push(Drupal.checkPlain($(this).text()));
|
||||
});
|
||||
if (!$(context).find('#edit-options-status').is(':checked')) {
|
||||
@@ -58,5 +49,4 @@
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
||||
})(jQuery, Drupal);
|
||||
@@ -6,6 +6,7 @@ source:
|
||||
plugin: variable
|
||||
variables:
|
||||
- node_admin_theme
|
||||
source_module: node
|
||||
process:
|
||||
use_admin_theme: node_admin_theme
|
||||
destination:
|
||||
|
||||
@@ -6,6 +6,7 @@ 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.
|
||||
@@ -41,6 +42,7 @@ process:
|
||||
destination:
|
||||
plugin: entity:node
|
||||
translations: true
|
||||
destination_module: content_translation
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d6_user
|
||||
@@ -52,4 +54,3 @@ migration_dependencies:
|
||||
- d6_field_instance_widget_settings
|
||||
- d6_field_formatter_settings
|
||||
- d6_upload_field_instance
|
||||
provider: migrate_drupal
|
||||
|
||||
@@ -35,3 +35,4 @@ migration_dependencies:
|
||||
- d7_node_type
|
||||
optional:
|
||||
- d7_field_instance
|
||||
- d7_comment_field_instance
|
||||
|
||||
@@ -6,6 +6,7 @@ source:
|
||||
plugin: variable
|
||||
variables:
|
||||
- node_admin_theme
|
||||
source_module: node
|
||||
process:
|
||||
use_admin_theme: node_admin_theme
|
||||
destination:
|
||||
|
||||
@@ -7,6 +7,7 @@ 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.
|
||||
@@ -32,6 +33,7 @@ destination:
|
||||
translations: true
|
||||
content_translation_update_definitions:
|
||||
- node
|
||||
destination_module: content_translation
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d7_user
|
||||
@@ -39,4 +41,3 @@ migration_dependencies:
|
||||
- language
|
||||
optional:
|
||||
- d7_field_instance
|
||||
provider: migrate_drupal
|
||||
|
||||
@@ -173,7 +173,7 @@ function _node_mass_update_batch_finished($success, $results, $operations) {
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $results,
|
||||
];
|
||||
$message .= drupal_render($item_list);
|
||||
$message .= \Drupal::service('renderer')->render($item_list);
|
||||
drupal_set_message($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ function hook_node_grants_alter(&$grants, \Drupal\Core\Session\AccountInterface
|
||||
* The user object to perform the access check operation on.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The access result.
|
||||
* The access result.
|
||||
*
|
||||
* @ingroup node_access
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @file
|
||||
* Defines Javascript behaviors for the node module.
|
||||
*/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
/**
|
||||
* Behaviors for tabs in the node edit form.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches summary behavior for tabs in the node edit form.
|
||||
*/
|
||||
Drupal.behaviors.nodeDetailsSummaries = {
|
||||
attach(context) {
|
||||
const $context = $(context);
|
||||
|
||||
$context.find('.node-form-author').drupalSetSummary((context) => {
|
||||
const $authorContext = $(context);
|
||||
const name = $authorContext.find('.field--name-uid input').val();
|
||||
const date = $authorContext.find('.field--name-created input').val();
|
||||
|
||||
if (name && date) {
|
||||
return Drupal.t('By @name on @date', { '@name': name, '@date': date });
|
||||
}
|
||||
else if (name) {
|
||||
return Drupal.t('By @name', { '@name': name });
|
||||
}
|
||||
else if (date) {
|
||||
return Drupal.t('Authored on @date', { '@date': date });
|
||||
}
|
||||
});
|
||||
|
||||
$context.find('.node-form-options').drupalSetSummary((context) => {
|
||||
const $optionsContext = $(context);
|
||||
const vals = [];
|
||||
|
||||
if ($optionsContext.find('input').is(':checked')) {
|
||||
$optionsContext.find('input:checked').next('label').each(function () {
|
||||
vals.push(Drupal.checkPlain($.trim($(this).text())));
|
||||
});
|
||||
return vals.join(', ');
|
||||
}
|
||||
|
||||
return Drupal.t('Not promoted');
|
||||
});
|
||||
},
|
||||
};
|
||||
}(jQuery, Drupal, drupalSettings));
|
||||
@@ -8,8 +8,8 @@ configure: entity.node_type.collection
|
||||
dependencies:
|
||||
- text
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -74,7 +74,7 @@ function node_schema() {
|
||||
'default' => 0,
|
||||
],
|
||||
'realm' => [
|
||||
'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.',
|
||||
'description' => 'The realm in which the user must possess the grant ID. Modules can define one or more realms by implementing hook_node_grants().',
|
||||
'type' => 'varchar_ascii',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
@@ -246,3 +246,12 @@ function node_update_8301() {
|
||||
$entity_type->set('entity_keys', $keys);
|
||||
$definition_update_manager->updateEntityType($entity_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix realm column description on the node_access table.
|
||||
*/
|
||||
function node_update_8400() {
|
||||
$schema = drupal_get_module_schema('node', 'node_access');
|
||||
$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']);
|
||||
}
|
||||
|
||||
+14
-27
@@ -1,22 +1,13 @@
|
||||
/**
|
||||
* @file
|
||||
* Defines Javascript behaviors for the node module.
|
||||
*/
|
||||
* DO NOT EDIT THIS FILE.
|
||||
* See the following change record for more information,
|
||||
* https://www.drupal.org/node/2815083
|
||||
* @preserve
|
||||
**/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Behaviors for tabs in the node edit form.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches summary behavior for tabs in the node edit form.
|
||||
*/
|
||||
Drupal.behaviors.nodeDetailsSummaries = {
|
||||
attach: function (context) {
|
||||
attach: function attach(context) {
|
||||
var $context = $(context);
|
||||
|
||||
$context.find('.node-form-author').drupalSetSummary(function (context) {
|
||||
@@ -25,13 +16,11 @@
|
||||
var date = $authorContext.find('.field--name-created input').val();
|
||||
|
||||
if (name && date) {
|
||||
return Drupal.t('By @name on @date', {'@name': name, '@date': date});
|
||||
}
|
||||
else if (name) {
|
||||
return Drupal.t('By @name', {'@name': name});
|
||||
}
|
||||
else if (date) {
|
||||
return Drupal.t('Authored on @date', {'@date': date});
|
||||
return Drupal.t('By @name on @date', { '@name': name, '@date': date });
|
||||
} else if (name) {
|
||||
return Drupal.t('By @name', { '@name': name });
|
||||
} else if (date) {
|
||||
return Drupal.t('Authored on @date', { '@date': date });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -45,11 +34,9 @@
|
||||
});
|
||||
return vals.join(', ');
|
||||
}
|
||||
else {
|
||||
return Drupal.t('Not promoted');
|
||||
}
|
||||
|
||||
return Drupal.t('Not promoted');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal, drupalSettings);
|
||||
})(jQuery, Drupal, drupalSettings);
|
||||
@@ -34,6 +34,8 @@ use Drupal\node\NodeTypeInterface;
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.x.
|
||||
* Use \Drupal\node\NodeInterface::NOT_PUBLISHED instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2316145
|
||||
*/
|
||||
const NODE_NOT_PUBLISHED = 0;
|
||||
|
||||
@@ -42,6 +44,8 @@ const NODE_NOT_PUBLISHED = 0;
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.x.
|
||||
* Use \Drupal\node\NodeInterface::PUBLISHED instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2316145
|
||||
*/
|
||||
const NODE_PUBLISHED = 1;
|
||||
|
||||
@@ -50,6 +54,8 @@ const NODE_PUBLISHED = 1;
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.x.
|
||||
* Use \Drupal\node\NodeInterface::NOT_PROMOTED instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2316145
|
||||
*/
|
||||
const NODE_NOT_PROMOTED = 0;
|
||||
|
||||
@@ -58,6 +64,8 @@ const NODE_NOT_PROMOTED = 0;
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.x.
|
||||
* Use \Drupal\node\NodeInterface::PROMOTED instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2316145
|
||||
*/
|
||||
const NODE_PROMOTED = 1;
|
||||
|
||||
@@ -66,6 +74,8 @@ const NODE_PROMOTED = 1;
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.x.
|
||||
* Use \Drupal\node\NodeInterface::NOT_STICKY instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2316145
|
||||
*/
|
||||
const NODE_NOT_STICKY = 0;
|
||||
|
||||
@@ -74,6 +84,8 @@ const NODE_NOT_STICKY = 0;
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.x.
|
||||
* Use \Drupal\node\NodeInterface::STICKY instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2316145
|
||||
*/
|
||||
const NODE_STICKY = 1;
|
||||
|
||||
@@ -593,9 +605,9 @@ function template_preprocess_node(&$variables) {
|
||||
$variables['node'] = $variables['elements']['#node'];
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
$node = $variables['node'];
|
||||
$variables['date'] = drupal_render($variables['elements']['created']);
|
||||
$variables['date'] = \Drupal::service('renderer')->render($variables['elements']['created']);
|
||||
unset($variables['elements']['created']);
|
||||
$variables['author_name'] = drupal_render($variables['elements']['uid']);
|
||||
$variables['author_name'] = \Drupal::service('renderer')->render($variables['elements']['uid']);
|
||||
unset($variables['elements']['uid']);
|
||||
|
||||
$variables['url'] = $node->url('canonical', [
|
||||
@@ -1099,7 +1111,7 @@ function node_query_node_access_alter(AlterableInterface $query) {
|
||||
// context.
|
||||
$request = \Drupal::requestStack()->getCurrentRequest();
|
||||
$renderer = \Drupal::service('renderer');
|
||||
if ($request->isMethodSafe() && $renderer->hasRenderContext()) {
|
||||
if ($request->isMethodCacheable() && $renderer->hasRenderContext()) {
|
||||
$build = ['#cache' => ['contexts' => ['user.node_grants:' . $op]]];
|
||||
$renderer->render($build);
|
||||
}
|
||||
|
||||
@@ -18,12 +18,13 @@ view own unpublished content:
|
||||
title: 'View own unpublished content'
|
||||
view all revisions:
|
||||
title: 'View all revisions'
|
||||
description: 'To view a revision, you also need permission to view the content item.'
|
||||
revert all revisions:
|
||||
title: 'Revert all revisions'
|
||||
description: 'Role requires permission <em>view revisions</em> and <em>edit rights</em> for nodes in question or <em>administer nodes</em>.'
|
||||
description: 'To revert a revision, you also need permission to edit the content item.'
|
||||
delete all revisions:
|
||||
title: 'Delete all revisions'
|
||||
description: 'Role requires permission to <em>view revisions</em> and <em>delete rights</em> for nodes in question or <em>administer nodes</em>.'
|
||||
description: 'To delete a revision, you also need permission to delete the content item.'
|
||||
|
||||
permission_callbacks:
|
||||
- \Drupal\node\NodePermissions::nodeTypePermissions
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Post update functions for Node.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
|
||||
/**
|
||||
* Load all form displays for nodes, add status with these settings, save.
|
||||
*/
|
||||
function node_post_update_configure_status_field_widget() {
|
||||
$query = \Drupal::entityQuery('entity_form_display')->condition('targetEntityType', 'node');
|
||||
$ids = $query->execute();
|
||||
$form_displays = EntityFormDisplay::loadMultiple($ids);
|
||||
|
||||
// Assign status settings for each 'node' target entity types with 'default'
|
||||
// form mode.
|
||||
foreach ($form_displays as $id => $form_display) {
|
||||
/** @var \Drupal\Core\Entity\Display\EntityDisplayInterface $form_display */
|
||||
$form_display->setComponent('status', [
|
||||
'type' => 'boolean_checkbox',
|
||||
'settings' => [
|
||||
'display_label' => TRUE,
|
||||
],
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* @file
|
||||
* Preview behaviors.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
/**
|
||||
* Disables all non-relevant links in node previews.
|
||||
*
|
||||
* Destroys links (except local fragment identifiers such as href="#frag") in
|
||||
* node previews to prevent users from leaving the page.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches confirmation prompt for clicking links in node preview mode.
|
||||
* @prop {Drupal~behaviorDetach} detach
|
||||
* Detaches confirmation prompt for clicking links in node preview mode.
|
||||
*/
|
||||
Drupal.behaviors.nodePreviewDestroyLinks = {
|
||||
attach(context) {
|
||||
function clickPreviewModal(event) {
|
||||
// Only confirm leaving previews when left-clicking and user is not
|
||||
// pressing the ALT, CTRL, META (Command key on the Macintosh keyboard)
|
||||
// or SHIFT key.
|
||||
if (event.button === 0 && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
|
||||
event.preventDefault();
|
||||
const $previewDialog = $(`<div>${Drupal.theme('nodePreviewModal')}</div>`).appendTo('body');
|
||||
Drupal.dialog($previewDialog, {
|
||||
title: Drupal.t('Leave preview?'),
|
||||
buttons: [
|
||||
{
|
||||
text: Drupal.t('Cancel'),
|
||||
click() {
|
||||
$(this).dialog('close');
|
||||
},
|
||||
}, {
|
||||
text: Drupal.t('Leave preview'),
|
||||
click() {
|
||||
window.top.location.href = event.target.href;
|
||||
},
|
||||
},
|
||||
],
|
||||
}).showModal();
|
||||
}
|
||||
}
|
||||
|
||||
const $preview = $(context).find('.content').once('node-preview');
|
||||
if ($(context).find('.node-preview-container').length) {
|
||||
$preview.on('click.preview', 'a:not([href^=#], #edit-backlink, #toolbar-administration a)', clickPreviewModal);
|
||||
}
|
||||
},
|
||||
detach(context, settings, trigger) {
|
||||
if (trigger === 'unload') {
|
||||
const $preview = $(context).find('.content').removeOnce('node-preview');
|
||||
if ($preview.length) {
|
||||
$preview.off('click.preview');
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Switch view mode.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches automatic submit on `formUpdated.preview` events.
|
||||
*/
|
||||
Drupal.behaviors.nodePreviewSwitchViewMode = {
|
||||
attach(context) {
|
||||
const $autosubmit = $(context).find('[data-drupal-autosubmit]').once('autosubmit');
|
||||
if ($autosubmit.length) {
|
||||
$autosubmit.on('formUpdated.preview', function () {
|
||||
$(this.form).trigger('submit');
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Theme function for node preview modal.
|
||||
*
|
||||
* @return {string}
|
||||
* Markup for the node preview modal.
|
||||
*/
|
||||
Drupal.theme.nodePreviewModal = function () {
|
||||
return `<p>${
|
||||
Drupal.t('Leaving the preview will cause unsaved changes to be lost. Are you sure you want to leave the preview?')
|
||||
}</p><small class="description">${
|
||||
Drupal.t('CTRL+Left click will prevent this dialog from showing and proceed to the clicked link.')}</small>`;
|
||||
};
|
||||
}(jQuery, Drupal));
|
||||
@@ -1,50 +1,30 @@
|
||||
/**
|
||||
* @file
|
||||
* Preview behaviors.
|
||||
*/
|
||||
* DO NOT EDIT THIS FILE.
|
||||
* See the following change record for more information,
|
||||
* https://www.drupal.org/node/2815083
|
||||
* @preserve
|
||||
**/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Disables all non-relevant links in node previews.
|
||||
*
|
||||
* Destroys links (except local fragment identifiers such as href="#frag") in
|
||||
* node previews to prevent users from leaving the page.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches confirmation prompt for clicking links in node preview mode.
|
||||
* @prop {Drupal~behaviorDetach} detach
|
||||
* Detaches confirmation prompt for clicking links in node preview mode.
|
||||
*/
|
||||
Drupal.behaviors.nodePreviewDestroyLinks = {
|
||||
attach: function (context) {
|
||||
|
||||
attach: function attach(context) {
|
||||
function clickPreviewModal(event) {
|
||||
// Only confirm leaving previews when left-clicking and user is not
|
||||
// pressing the ALT, CTRL, META (Command key on the Macintosh keyboard)
|
||||
// or SHIFT key.
|
||||
if (event.button === 0 && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
|
||||
event.preventDefault();
|
||||
var $previewDialog = $('<div>' + Drupal.theme('nodePreviewModal') + '</div>').appendTo('body');
|
||||
Drupal.dialog($previewDialog, {
|
||||
title: Drupal.t('Leave preview?'),
|
||||
buttons: [
|
||||
{
|
||||
text: Drupal.t('Cancel'),
|
||||
click: function () {
|
||||
$(this).dialog('close');
|
||||
}
|
||||
}, {
|
||||
text: Drupal.t('Leave preview'),
|
||||
click: function () {
|
||||
window.top.location.href = event.target.href;
|
||||
}
|
||||
buttons: [{
|
||||
text: Drupal.t('Cancel'),
|
||||
click: function click() {
|
||||
$(this).dialog('close');
|
||||
}
|
||||
]
|
||||
}, {
|
||||
text: Drupal.t('Leave preview'),
|
||||
click: function click() {
|
||||
window.top.location.href = event.target.href;
|
||||
}
|
||||
}]
|
||||
}).showModal();
|
||||
}
|
||||
}
|
||||
@@ -54,7 +34,7 @@
|
||||
$preview.on('click.preview', 'a:not([href^=#], #edit-backlink, #toolbar-administration a)', clickPreviewModal);
|
||||
}
|
||||
},
|
||||
detach: function (context, settings, trigger) {
|
||||
detach: function detach(context, settings, trigger) {
|
||||
if (trigger === 'unload') {
|
||||
var $preview = $(context).find('.content').removeOnce('node-preview');
|
||||
if ($preview.length) {
|
||||
@@ -64,16 +44,8 @@
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Switch view mode.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches automatic submit on `formUpdated.preview` events.
|
||||
*/
|
||||
Drupal.behaviors.nodePreviewSwitchViewMode = {
|
||||
attach: function (context) {
|
||||
attach: function attach(context) {
|
||||
var $autosubmit = $(context).find('[data-drupal-autosubmit]').once('autosubmit');
|
||||
if ($autosubmit.length) {
|
||||
$autosubmit.on('formUpdated.preview', function () {
|
||||
@@ -83,17 +55,7 @@
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Theme function for node preview modal.
|
||||
*
|
||||
* @return {string}
|
||||
* Markup for the node preview modal.
|
||||
*/
|
||||
Drupal.theme.nodePreviewModal = function () {
|
||||
return '<p>' +
|
||||
Drupal.t('Leaving the preview will cause unsaved changes to be lost. Are you sure you want to leave the preview?') +
|
||||
'</p><small class="description">' +
|
||||
Drupal.t('CTRL+Left click will prevent this dialog from showing and proceed to the clicked link.') + '</small>';
|
||||
return '<p>' + Drupal.t('Leaving the preview will cause unsaved changes to be lost. Are you sure you want to leave the preview?') + '</p><small class="description">' + Drupal.t('CTRL+Left click will prevent this dialog from showing and proceed to the clicked link.') + '</small>';
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
||||
})(jQuery, Drupal);
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
namespace Drupal\node\Entity;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityChangedTrait;
|
||||
use Drupal\Core\Entity\EntityPublishedTrait;
|
||||
use Drupal\Core\Entity\EditorialContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
@@ -61,6 +59,11 @@ use Drupal\user\UserInterface;
|
||||
* "published" = "status",
|
||||
* "uid" = "uid",
|
||||
* },
|
||||
* revision_metadata_keys = {
|
||||
* "revision_user" = "revision_uid",
|
||||
* "revision_created" = "revision_timestamp",
|
||||
* "revision_log_message" = "revision_log"
|
||||
* },
|
||||
* bundle_entity_type = "node_type",
|
||||
* field_ui_base_route = "entity.node_type.edit_form",
|
||||
* common_reference_target = TRUE,
|
||||
@@ -71,13 +74,11 @@ use Drupal\user\UserInterface;
|
||||
* "edit-form" = "/node/{node}/edit",
|
||||
* "version-history" = "/node/{node}/revisions",
|
||||
* "revision" = "/node/{node}/revisions/{node_revision}/view",
|
||||
* "create" = "/node",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class Node extends ContentEntityBase implements NodeInterface {
|
||||
|
||||
use EntityChangedTrait;
|
||||
use EntityPublishedTrait;
|
||||
class Node extends EditorialContentEntityBase implements NodeInterface {
|
||||
|
||||
/**
|
||||
* Whether the node is being previewed or not.
|
||||
@@ -278,21 +279,6 @@ class Node extends ContentEntityBase implements NodeInterface {
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRevisionCreationTime() {
|
||||
return $this->get('revision_timestamp')->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setRevisionCreationTime($timestamp) {
|
||||
$this->set('revision_timestamp', $timestamp);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -300,13 +286,6 @@ class Node extends ContentEntityBase implements NodeInterface {
|
||||
return $this->getRevisionUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRevisionUser() {
|
||||
return $this->get('revision_uid')->entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -315,50 +294,11 @@ class Node extends ContentEntityBase implements NodeInterface {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields = parent::baseFieldDefinitions($entity_type);
|
||||
$fields += static::publishedBaseFieldDefinitions($entity_type);
|
||||
|
||||
$fields['title'] = BaseFieldDefinition::create('string')
|
||||
->setLabel(t('Title'))
|
||||
@@ -400,6 +340,16 @@ class Node extends ContentEntityBase implements NodeInterface {
|
||||
])
|
||||
->setDisplayConfigurable('form', TRUE);
|
||||
|
||||
$fields['status']
|
||||
->setDisplayOptions('form', [
|
||||
'type' => 'boolean_checkbox',
|
||||
'settings' => [
|
||||
'display_label' => TRUE,
|
||||
],
|
||||
'weight' => 120,
|
||||
])
|
||||
->setDisplayConfigurable('form', TRUE);
|
||||
|
||||
$fields['created'] = BaseFieldDefinition::create('created')
|
||||
->setLabel(t('Authored on'))
|
||||
->setDescription(t('The time that the node was created.'))
|
||||
@@ -450,39 +400,6 @@ class Node extends ContentEntityBase implements NodeInterface {
|
||||
])
|
||||
->setDisplayConfigurable('form', TRUE);
|
||||
|
||||
$fields['revision_timestamp'] = BaseFieldDefinition::create('created')
|
||||
->setLabel(t('Revision timestamp'))
|
||||
->setDescription(t('The time that the current revision was created.'))
|
||||
->setQueryable(FALSE)
|
||||
->setRevisionable(TRUE);
|
||||
|
||||
$fields['revision_uid'] = BaseFieldDefinition::create('entity_reference')
|
||||
->setLabel(t('Revision user ID'))
|
||||
->setDescription(t('The user ID of the author of the current revision.'))
|
||||
->setSetting('target_type', 'user')
|
||||
->setQueryable(FALSE)
|
||||
->setRevisionable(TRUE);
|
||||
|
||||
$fields['revision_log'] = BaseFieldDefinition::create('string_long')
|
||||
->setLabel(t('Revision log message'))
|
||||
->setDescription(t('Briefly describe the changes you have made.'))
|
||||
->setRevisionable(TRUE)
|
||||
->setDefaultValue('')
|
||||
->setDisplayOptions('form', [
|
||||
'type' => 'string_textarea',
|
||||
'weight' => 25,
|
||||
'settings' => [
|
||||
'rows' => 4,
|
||||
],
|
||||
]);
|
||||
|
||||
$fields['revision_translation_affected'] = BaseFieldDefinition::create('boolean')
|
||||
->setLabel(t('Revision translation affected'))
|
||||
->setDescription(t('Indicates if the last edit of a translation belongs to current revision.'))
|
||||
->setReadOnly(TRUE)
|
||||
->setRevisionable(TRUE)
|
||||
->setTranslatable(TRUE);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class NodeRouteProvider implements EntityRouteProviderInterface {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRoutes( EntityTypeInterface $entity_type) {
|
||||
public function getRoutes(EntityTypeInterface $entity_type) {
|
||||
$route_collection = new RouteCollection();
|
||||
$route = (new Route('/node/{node}'))
|
||||
->addDefaults([
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\node\EventSubscriber;
|
||||
|
||||
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\ParamConverter\ParamNotConvertedException;
|
||||
use Drupal\Core\Routing\UrlGeneratorInterface;
|
||||
use Drupal\Core\State\StateInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
/**
|
||||
* Redirect node translations that have been consolidated by migration.
|
||||
*
|
||||
* If we migrated node translations from Drupal 6 or 7, these nodes are now
|
||||
* combined with their source language node. Since there still might be
|
||||
* references to the URLs of these now consolidated nodes, this service catches
|
||||
* the 404s and try to redirect them to the right node in the right language.
|
||||
*
|
||||
* The mapping of the old nids to the new ones is made by the
|
||||
* NodeTranslationMigrateSubscriber class during the migration and is stored
|
||||
* in the "node_translation_redirect" key/value collection.
|
||||
*
|
||||
* @see \Drupal\node\NodeServiceProvider
|
||||
* @see \Drupal\node\EventSubscriber\NodeTranslationMigrateSubscriber
|
||||
*/
|
||||
class NodeTranslationExceptionSubscriber implements EventSubscriberInterface {
|
||||
|
||||
/**
|
||||
* The key value factory.
|
||||
*
|
||||
* @var \Drupal\Core\KeyValueStore\KeyValueFactoryInterface
|
||||
*/
|
||||
protected $keyValue;
|
||||
|
||||
/**
|
||||
* The language manager.
|
||||
*
|
||||
* @var \Drupal\Core\Language\LanguageManagerInterface
|
||||
*/
|
||||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* The URL generator.
|
||||
*
|
||||
* @var \Drupal\Core\Routing\UrlGeneratorInterface
|
||||
*/
|
||||
protected $urlGenerator;
|
||||
|
||||
/**
|
||||
* The state service.
|
||||
*
|
||||
* @var \Drupal\Core\State\StateInterface
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* Constructs the NodeTranslationExceptionSubscriber.
|
||||
*
|
||||
* @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $key_value
|
||||
* The key value factory.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
* @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
|
||||
* The URL generator.
|
||||
* @param \Drupal\Core\State\StateInterface $state
|
||||
* The state service.
|
||||
*/
|
||||
public function __construct(KeyValueFactoryInterface $key_value, LanguageManagerInterface $language_manager, UrlGeneratorInterface $url_generator, StateInterface $state) {
|
||||
$this->keyValue = $key_value;
|
||||
$this->languageManager = $language_manager;
|
||||
$this->urlGenerator = $url_generator;
|
||||
$this->state = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects not found node translations using the key value collection.
|
||||
*
|
||||
* @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
|
||||
* The exception event.
|
||||
*/
|
||||
public function onException(GetResponseForExceptionEvent $event) {
|
||||
$exception = $event->getException();
|
||||
|
||||
// If this is not a 404, we don't need to check for a redirection.
|
||||
if (!($exception instanceof NotFoundHttpException)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$previous_exception = $exception->getPrevious();
|
||||
if ($previous_exception instanceof ParamNotConvertedException) {
|
||||
$route_name = $previous_exception->getRouteName();
|
||||
$parameters = $previous_exception->getRawParameters();
|
||||
if ($route_name === 'entity.node.canonical' && isset($parameters['node'])) {
|
||||
// If the node_translation_redirect state is not set, we don't need to check
|
||||
// for a redirection.
|
||||
if (!$this->state->get('node_translation_redirect')) {
|
||||
return;
|
||||
}
|
||||
$old_nid = $parameters['node'];
|
||||
$collection = $this->keyValue->get('node_translation_redirect');
|
||||
if ($old_nid && $value = $collection->get($old_nid)) {
|
||||
list($nid, $langcode) = $value;
|
||||
$language = $this->languageManager->getLanguage($langcode);
|
||||
$url = $this->urlGenerator->generateFromRoute('entity.node.canonical', ['node' => $nid], ['language' => $language]);
|
||||
$response = new RedirectResponse($url, 301);
|
||||
$event->setResponse($response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents() {
|
||||
$events = [];
|
||||
|
||||
$events[KernelEvents::EXCEPTION] = ['onException'];
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\node\EventSubscriber;
|
||||
|
||||
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
|
||||
use Drupal\Core\State\StateInterface;
|
||||
use Drupal\migrate\Event\EventBase;
|
||||
use Drupal\migrate\Event\MigrateEvents;
|
||||
use Drupal\migrate\Event\MigrateImportEvent;
|
||||
use Drupal\migrate\Event\MigratePostRowSaveEvent;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Creates a key value collection for migrated node translation redirections.
|
||||
*
|
||||
* If we are migrating node translations from Drupal 6 or 7, these nodes will be
|
||||
* combined with their source node. Since there still might be references to the
|
||||
* URLs of these now consolidated nodes, this service saves the mapping between
|
||||
* the old nids to the new ones to be able to redirect them to the right node in
|
||||
* the right language.
|
||||
*
|
||||
* The mapping is stored in the "node_translation_redirect" key/value collection
|
||||
* and the redirection is made by the NodeTranslationExceptionSubscriber class.
|
||||
*
|
||||
* @see \Drupal\node\NodeServiceProvider
|
||||
* @see \Drupal\node\EventSubscriber\NodeTranslationExceptionSubscriber
|
||||
*/
|
||||
class NodeTranslationMigrateSubscriber implements EventSubscriberInterface {
|
||||
|
||||
/**
|
||||
* The key value factory.
|
||||
*
|
||||
* @var \Drupal\Core\KeyValueStore\KeyValueFactoryInterface
|
||||
*/
|
||||
protected $keyValue;
|
||||
|
||||
/**
|
||||
* The state service.
|
||||
*
|
||||
* @var \Drupal\Core\State\StateInterface
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* Constructs the NodeTranslationMigrateSubscriber.
|
||||
*
|
||||
* @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $key_value
|
||||
* The key value factory.
|
||||
* @param \Drupal\Core\State\StateInterface $state
|
||||
* The state service.
|
||||
*/
|
||||
public function __construct(KeyValueFactoryInterface $key_value, StateInterface $state) {
|
||||
$this->keyValue = $key_value;
|
||||
$this->state = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to check if we are migrating translated nodes.
|
||||
*
|
||||
* @param \Drupal\migrate\Event\EventBase $event
|
||||
* The migrate event.
|
||||
*
|
||||
* @return bool
|
||||
* True if we are migrating translated nodes, false otherwise.
|
||||
*/
|
||||
protected function isNodeTranslationsMigration(EventBase $event) {
|
||||
$migration = $event->getMigration();
|
||||
$source_configuration = $migration->getSourceConfiguration();
|
||||
$destination_configuration = $migration->getDestinationConfiguration();
|
||||
return !empty($source_configuration['translations']) && $destination_configuration['plugin'] === 'entity:node';
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the old nid to the new one in the key value collection.
|
||||
*
|
||||
* @param \Drupal\migrate\Event\MigratePostRowSaveEvent $event
|
||||
* The migrate post row save event.
|
||||
*/
|
||||
public function onPostRowSave(MigratePostRowSaveEvent $event) {
|
||||
if ($this->isNodeTranslationsMigration($event)) {
|
||||
$row = $event->getRow();
|
||||
$source = $row->getSource();
|
||||
$destination = $row->getDestination();
|
||||
$collection = $this->keyValue->get('node_translation_redirect');
|
||||
$collection->set($source['nid'], [$destination['nid'], $destination['langcode']]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the node_translation_redirect state to enable the redirections.
|
||||
*
|
||||
* @param \Drupal\migrate\Event\MigrateImportEvent $event
|
||||
* The migrate import event.
|
||||
*/
|
||||
public function onPostImport(MigrateImportEvent $event) {
|
||||
if ($this->isNodeTranslationsMigration($event)) {
|
||||
$this->state->set('node_translation_redirect', TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents() {
|
||||
$events = [];
|
||||
|
||||
$events[MigrateEvents::POST_ROW_SAVE] = ['onPostRowSave'];
|
||||
$events[MigrateEvents::POST_IMPORT] = ['onPostImport'];
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\node\Form;
|
||||
|
||||
use Drupal\Component\Datetime\TimeInterface;
|
||||
use Drupal\Core\Datetime\DateFormatterInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
@@ -50,11 +51,13 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
|
||||
* The node storage.
|
||||
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
|
||||
* The date formatter service.
|
||||
* @param \Drupal\Component\Datetime\TimeInterface $time
|
||||
* The time service.
|
||||
*/
|
||||
public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter) {
|
||||
public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter, TimeInterface $time) {
|
||||
$this->nodeStorage = $node_storage;
|
||||
$this->dateFormatter = $date_formatter;
|
||||
$this->time = \Drupal::service('datetime.time');
|
||||
$this->time = $time;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +66,8 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getStorage('node'),
|
||||
$container->get('date.formatter')
|
||||
$container->get('date.formatter'),
|
||||
$container->get('datetime.time')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\node\Form;
|
||||
|
||||
use Drupal\Component\Datetime\TimeInterface;
|
||||
use Drupal\Core\Datetime\DateFormatterInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
@@ -37,9 +38,11 @@ class NodeRevisionRevertTranslationForm extends NodeRevisionRevertForm {
|
||||
* The date formatter service.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
* @param \Drupal\Component\Datetime\TimeInterface $time
|
||||
* The time service.
|
||||
*/
|
||||
public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter, LanguageManagerInterface $language_manager) {
|
||||
parent::__construct($node_storage, $date_formatter);
|
||||
public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter, LanguageManagerInterface $language_manager, TimeInterface $time) {
|
||||
parent::__construct($node_storage, $date_formatter, $time);
|
||||
$this->languageManager = $language_manager;
|
||||
}
|
||||
|
||||
@@ -50,7 +53,8 @@ class NodeRevisionRevertTranslationForm extends NodeRevisionRevertForm {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getStorage('node'),
|
||||
$container->get('date.formatter'),
|
||||
$container->get('language_manager')
|
||||
$container->get('language_manager'),
|
||||
$container->get('datetime.time')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ use Drupal\Core\Entity\ContentEntityForm;
|
||||
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 Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
@@ -22,6 +23,13 @@ class NodeForm extends ContentEntityForm {
|
||||
*/
|
||||
protected $tempStoreFactory;
|
||||
|
||||
/**
|
||||
* The Current User object.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* Constructs a NodeForm object.
|
||||
*
|
||||
@@ -33,10 +41,13 @@ class NodeForm extends ContentEntityForm {
|
||||
* The entity type bundle service.
|
||||
* @param \Drupal\Component\Datetime\TimeInterface $time
|
||||
* The time service.
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* The current user.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entity_manager, PrivateTempStoreFactory $temp_store_factory, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, TimeInterface $time = NULL) {
|
||||
public function __construct(EntityManagerInterface $entity_manager, PrivateTempStoreFactory $temp_store_factory, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, TimeInterface $time = NULL, AccountInterface $current_user) {
|
||||
parent::__construct($entity_manager, $entity_type_bundle_info, $time);
|
||||
$this->tempStoreFactory = $temp_store_factory;
|
||||
$this->currentUser = $current_user;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,7 +58,8 @@ class NodeForm extends ContentEntityForm {
|
||||
$container->get('entity.manager'),
|
||||
$container->get('user.private_tempstore'),
|
||||
$container->get('entity_type.bundle.info'),
|
||||
$container->get('datetime.time')
|
||||
$container->get('datetime.time'),
|
||||
$container->get('current_user')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -86,7 +98,10 @@ class NodeForm extends ContentEntityForm {
|
||||
$node = $this->entity;
|
||||
|
||||
if ($this->operation == 'edit') {
|
||||
$form['#title'] = $this->t('<em>Edit @type</em> @title', ['@type' => node_get_type_label($node), '@title' => $node->label()]);
|
||||
$form['#title'] = $this->t('<em>Edit @type</em> @title', [
|
||||
'@type' => node_get_type_label($node),
|
||||
'@title' => $node->label()
|
||||
]);
|
||||
}
|
||||
|
||||
// Changed must be sent to the client, for later overwrite error checking.
|
||||
@@ -99,6 +114,43 @@ class NodeForm extends ContentEntityForm {
|
||||
|
||||
$form['advanced']['#attributes']['class'][] = 'entity-meta';
|
||||
|
||||
$form['meta'] = [
|
||||
'#type' => 'details',
|
||||
'#group' => 'advanced',
|
||||
'#weight' => -10,
|
||||
'#title' => $this->t('Status'),
|
||||
'#attributes' => ['class' => ['entity-meta__header']],
|
||||
'#tree' => TRUE,
|
||||
'#access' => $this->currentUser->hasPermission('administer nodes'),
|
||||
];
|
||||
$form['meta']['published'] = [
|
||||
'#type' => 'item',
|
||||
'#markup' => $node->isPublished() ? $this->t('Published') : $this->t('Not published'),
|
||||
'#access' => !$node->isNew(),
|
||||
'#wrapper_attributes' => ['class' => ['entity-meta__title']],
|
||||
];
|
||||
$form['meta']['changed'] = [
|
||||
'#type' => 'item',
|
||||
'#title' => $this->t('Last saved'),
|
||||
'#markup' => !$node->isNew() ? format_date($node->getChangedTime(), 'short') : $this->t('Not saved yet'),
|
||||
'#wrapper_attributes' => ['class' => ['entity-meta__last-saved']],
|
||||
];
|
||||
$form['meta']['author'] = [
|
||||
'#type' => 'item',
|
||||
'#title' => $this->t('Author'),
|
||||
'#markup' => $node->getOwner()->getUsername(),
|
||||
'#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.
|
||||
$form['author'] = [
|
||||
'#type' => 'details',
|
||||
@@ -147,8 +199,6 @@ class NodeForm extends ContentEntityForm {
|
||||
|
||||
$form['#attached']['library'][] = 'node/form';
|
||||
|
||||
$form['#entity_builders']['update_status'] = '::updateStatus';
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
@@ -165,6 +215,9 @@ class NodeForm extends ContentEntityForm {
|
||||
* The current state of the form.
|
||||
*
|
||||
* @see \Drupal\node\NodeForm::form()
|
||||
*
|
||||
* @deprecated in Drupal 8.4.x, will be removed before Drupal 9.0.0.
|
||||
* The "Publish" button was removed.
|
||||
*/
|
||||
public function updateStatus($entity_type_id, NodeInterface $node, array $form, FormStateInterface $form_state) {
|
||||
$element = $form_state->getTriggeringElement();
|
||||
@@ -183,59 +236,6 @@ class NodeForm extends ContentEntityForm {
|
||||
|
||||
$element['submit']['#access'] = $preview_mode != DRUPAL_REQUIRED || $form_state->get('has_been_previewed');
|
||||
|
||||
// If saving is an option, privileged users get dedicated form submit
|
||||
// buttons to adjust the publishing status while saving in one go.
|
||||
// @todo This adjustment makes it close to impossible for contributed
|
||||
// modules to integrate with "the Save operation" of this form. Modules
|
||||
// need a way to plug themselves into 1) the ::submit() step, and
|
||||
// 2) the ::save() step, both decoupled from the pressed form button.
|
||||
if ($element['submit']['#access'] && \Drupal::currentUser()->hasPermission('administer nodes')) {
|
||||
// isNew | prev status » default & publish label & unpublish label
|
||||
// 1 | 1 » publish & Save and publish & Save as unpublished
|
||||
// 1 | 0 » unpublish & Save and publish & Save as unpublished
|
||||
// 0 | 1 » publish & Save and keep published & Save and unpublish
|
||||
// 0 | 0 » unpublish & Save and keep unpublished & Save and publish
|
||||
|
||||
// Add a "Publish" button.
|
||||
$element['publish'] = $element['submit'];
|
||||
// If the "Publish" button is clicked, we want to update the status to "published".
|
||||
$element['publish']['#published_status'] = TRUE;
|
||||
$element['publish']['#dropbutton'] = 'save';
|
||||
if ($node->isNew()) {
|
||||
$element['publish']['#value'] = t('Save and publish');
|
||||
}
|
||||
else {
|
||||
$element['publish']['#value'] = $node->isPublished() ? t('Save and keep published') : t('Save and publish');
|
||||
}
|
||||
$element['publish']['#weight'] = 0;
|
||||
|
||||
// Add a "Unpublish" button.
|
||||
$element['unpublish'] = $element['submit'];
|
||||
// If the "Unpublish" button is clicked, we want to update the status to "unpublished".
|
||||
$element['unpublish']['#published_status'] = FALSE;
|
||||
$element['unpublish']['#dropbutton'] = 'save';
|
||||
if ($node->isNew()) {
|
||||
$element['unpublish']['#value'] = t('Save as unpublished');
|
||||
}
|
||||
else {
|
||||
$element['unpublish']['#value'] = !$node->isPublished() ? t('Save and keep unpublished') : t('Save and unpublish');
|
||||
}
|
||||
$element['unpublish']['#weight'] = 10;
|
||||
|
||||
// If already published, the 'publish' button is primary.
|
||||
if ($node->isPublished()) {
|
||||
unset($element['unpublish']['#button_type']);
|
||||
}
|
||||
// Otherwise, the 'unpublish' button is primary and should come first.
|
||||
else {
|
||||
unset($element['publish']['#button_type']);
|
||||
$element['unpublish']['#weight'] = -10;
|
||||
}
|
||||
|
||||
// Remove the "Save" button.
|
||||
$element['submit']['#access'] = FALSE;
|
||||
}
|
||||
|
||||
$element['preview'] = [
|
||||
'#type' => 'submit',
|
||||
'#access' => $preview_mode != DRUPAL_DISABLED && ($node->access('create') || $node->access('update')),
|
||||
|
||||
@@ -138,7 +138,7 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
|
||||
|
||||
$grants = static::buildGrantsQueryCondition(node_access_grants('view', $account));
|
||||
|
||||
if (count($grants) > 0 ) {
|
||||
if (count($grants) > 0) {
|
||||
$query->condition($grants);
|
||||
}
|
||||
return $query->execute()->fetchField();
|
||||
|
||||
@@ -31,11 +31,11 @@ interface NodeGrantDatabaseStorageInterface {
|
||||
* @param array $tables
|
||||
* A list of tables that need to be part of the alter.
|
||||
* @param string $op
|
||||
* The operation to be performed on the node. Possible values are:
|
||||
* - "view"
|
||||
* - "update"
|
||||
* - "delete"
|
||||
* - "create"
|
||||
* The operation to be performed on the node. Possible values are:
|
||||
* - "view"
|
||||
* - "update"
|
||||
* - "delete"
|
||||
* - "create"
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* A user object representing the user for whom the operation is to be
|
||||
* performed.
|
||||
|
||||
@@ -110,7 +110,7 @@ class NodeListBuilder extends EntityListBuilder {
|
||||
$row['title']['data'] = [
|
||||
'#type' => 'link',
|
||||
'#title' => $entity->label(),
|
||||
'#suffix' => ' ' . drupal_render($mark),
|
||||
'#suffix' => ' ' . \Drupal::service('renderer')->render($mark),
|
||||
'#url' => $uri,
|
||||
];
|
||||
$row['type'] = node_get_type_label($entity);
|
||||
|
||||
@@ -62,14 +62,15 @@ class NodePermissions {
|
||||
],
|
||||
"view $type_id revisions" => [
|
||||
'title' => $this->t('%type_name: View revisions', $type_params),
|
||||
'description' => t('To view a revision, you also need permission to view the content item.'),
|
||||
],
|
||||
"revert $type_id revisions" => [
|
||||
'title' => $this->t('%type_name: Revert revisions', $type_params),
|
||||
'description' => t('Role requires permission <em>view revisions</em> and <em>edit rights</em> for nodes in question, or <em>administer nodes</em>.'),
|
||||
'description' => t('To revert a revision, you also need permission to edit the content item.'),
|
||||
],
|
||||
"delete $type_id revisions" => [
|
||||
'title' => $this->t('%type_name: Delete revisions', $type_params),
|
||||
'description' => $this->t('Role requires permission to <em>view revisions</em> and <em>delete rights</em> for nodes in question, or <em>administer nodes</em>.'),
|
||||
'description' => $this->t('To delete a revision, you also need permission to delete the content item.'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\node;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
|
||||
use Drupal\node\EventSubscriber\NodeTranslationExceptionSubscriber;
|
||||
use Drupal\node\EventSubscriber\NodeTranslationMigrateSubscriber;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Registers services in the container.
|
||||
*/
|
||||
class NodeServiceProvider implements ServiceProviderInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function register(ContainerBuilder $container) {
|
||||
// Register the node.node_translation_migrate service in the container if
|
||||
// the migrate and language modules are enabled.
|
||||
$modules = $container->getParameter('container.modules');
|
||||
if (isset($modules['migrate']) && isset($modules['language'])) {
|
||||
$container->register('node.node_translation_migrate', NodeTranslationMigrateSubscriber::class)
|
||||
->addTag('event_subscriber')
|
||||
->addArgument(new Reference('keyvalue'))
|
||||
->addArgument(new Reference('state'));
|
||||
}
|
||||
|
||||
// Register the node.node_translation_exception service in the container if
|
||||
// the language module is enabled.
|
||||
if (isset($modules['language'])) {
|
||||
$container->register('node.node_translation_exception', NodeTranslationExceptionSubscriber::class)
|
||||
->addTag('event_subscriber')
|
||||
->addArgument(new Reference('keyvalue'))
|
||||
->addArgument(new Reference('language_manager'))
|
||||
->addArgument(new Reference('url_generator'))
|
||||
->addArgument(new Reference('state'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,12 +29,14 @@ class NodeViewBuilder extends EntityViewBuilder {
|
||||
|
||||
if ($display->getComponent('links')) {
|
||||
$build[$id]['links'] = [
|
||||
'#lazy_builder' => [get_called_class() . '::renderLinks', [
|
||||
$entity->id(),
|
||||
$view_mode,
|
||||
$entity->language()->getId(),
|
||||
!empty($entity->in_preview),
|
||||
]],
|
||||
'#lazy_builder' => [
|
||||
get_called_class() . '::renderLinks', [
|
||||
$entity->id(),
|
||||
$view_mode,
|
||||
$entity->language()->getId(),
|
||||
!empty($entity->in_preview),
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Drupal\node\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Action\ActionBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Field\FieldUpdateActionBase;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Demotes a node.
|
||||
@@ -14,25 +14,13 @@ use Drupal\Core\Session\AccountInterface;
|
||||
* type = "node"
|
||||
* )
|
||||
*/
|
||||
class DemoteNode extends ActionBase {
|
||||
class DemoteNode extends FieldUpdateActionBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($entity = NULL) {
|
||||
$entity->setPromoted(FALSE);
|
||||
$entity->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
/** @var \Drupal\node\NodeInterface $object */
|
||||
$result = $object->access('update', $account, TRUE)
|
||||
->andIf($object->promote->access('edit', $account, TRUE));
|
||||
|
||||
return $return_as_object ? $result : $result->isAllowed();
|
||||
protected function getFieldsToUpdate() {
|
||||
return ['promote' => NodeInterface::NOT_PROMOTED];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Drupal\node\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Action\ActionBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Field\FieldUpdateActionBase;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Promotes a node.
|
||||
@@ -14,24 +14,13 @@ use Drupal\Core\Session\AccountInterface;
|
||||
* type = "node"
|
||||
* )
|
||||
*/
|
||||
class PromoteNode extends ActionBase {
|
||||
class PromoteNode extends FieldUpdateActionBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($entity = NULL) {
|
||||
$entity->setPromoted(TRUE);
|
||||
$entity->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
/** @var \Drupal\node\NodeInterface $object */
|
||||
$access = $object->access('update', $account, TRUE)
|
||||
->andif($object->promote->access('edit', $account, TRUE));
|
||||
return $return_as_object ? $access : $access->isAllowed();
|
||||
protected function getFieldsToUpdate() {
|
||||
return ['promote' => NodeInterface::PROMOTED];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Drupal\node\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Action\ActionBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Field\FieldUpdateActionBase;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Publishes a node.
|
||||
@@ -14,24 +14,13 @@ use Drupal\Core\Session\AccountInterface;
|
||||
* type = "node"
|
||||
* )
|
||||
*/
|
||||
class PublishNode extends ActionBase {
|
||||
class PublishNode extends FieldUpdateActionBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($entity = NULL) {
|
||||
$entity->setPublished()->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
/** @var \Drupal\node\NodeInterface $object */
|
||||
$result = $object->access('update', $account, TRUE)
|
||||
->andIf($object->status->access('edit', $account, TRUE));
|
||||
|
||||
return $return_as_object ? $result : $result->isAllowed();
|
||||
protected function getFieldsToUpdate() {
|
||||
return ['status' => NodeInterface::PUBLISHED];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Drupal\node\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Action\ActionBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Field\FieldUpdateActionBase;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Makes a node sticky.
|
||||
@@ -14,23 +14,13 @@ use Drupal\Core\Session\AccountInterface;
|
||||
* type = "node"
|
||||
* )
|
||||
*/
|
||||
class StickyNode extends ActionBase {
|
||||
class StickyNode extends FieldUpdateActionBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($entity = NULL) {
|
||||
$entity->setSticky(TRUE)->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
/** @var \Drupal\node\NodeInterface $object */
|
||||
$access = $object->access('update', $account, TRUE)
|
||||
->andif($object->sticky->access('edit', $account, TRUE));
|
||||
return $return_as_object ? $access : $access->isAllowed();
|
||||
protected function getFieldsToUpdate() {
|
||||
return ['sticky' => NodeInterface::STICKY];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class UnpublishByKeywordNode extends ConfigurableActionBase {
|
||||
public function execute($node = NULL) {
|
||||
foreach ($this->configuration['keywords'] as $keyword) {
|
||||
$elements = node_view(clone $node);
|
||||
if (strpos(drupal_render($elements), $keyword) !== FALSE || strpos($node->label(), $keyword) !== FALSE) {
|
||||
if (strpos(\Drupal::service('renderer')->render($elements), $keyword) !== FALSE || strpos($node->label(), $keyword) !== FALSE) {
|
||||
$node->setPublished(FALSE);
|
||||
$node->save();
|
||||
break;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Drupal\node\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Action\ActionBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Field\FieldUpdateActionBase;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Unpublishes a node.
|
||||
@@ -14,24 +14,13 @@ use Drupal\Core\Session\AccountInterface;
|
||||
* type = "node"
|
||||
* )
|
||||
*/
|
||||
class UnpublishNode extends ActionBase {
|
||||
class UnpublishNode extends FieldUpdateActionBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($entity = NULL) {
|
||||
$entity->setUnpublished()->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
/** @var \Drupal\node\NodeInterface $object */
|
||||
$access = $object->access('update', $account, TRUE)
|
||||
->andIf($object->status->access('edit', $account, TRUE));
|
||||
|
||||
return $return_as_object ? $access : $access->isAllowed();
|
||||
protected function getFieldsToUpdate() {
|
||||
return ['status' => NodeInterface::NOT_PUBLISHED];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Drupal\node\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Action\ActionBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Field\FieldUpdateActionBase;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Makes a node not sticky.
|
||||
@@ -14,24 +14,13 @@ use Drupal\Core\Session\AccountInterface;
|
||||
* type = "node"
|
||||
* )
|
||||
*/
|
||||
class UnstickyNode extends ActionBase {
|
||||
class UnstickyNode extends FieldUpdateActionBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($entity = NULL) {
|
||||
$entity->setSticky(FALSE)->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
/** @var \Drupal\node\NodeInterface $object */
|
||||
$access = $object->access('update', $account, TRUE)
|
||||
->andIf($object->sticky->access('edit', $account, TRUE));
|
||||
|
||||
return $return_as_object ? $access : $access->isAllowed();
|
||||
protected function getFieldsToUpdate() {
|
||||
return ['sticky' => NodeInterface::NOT_STICKY];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
static public function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
|
||||
@@ -141,6 +141,16 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
|
||||
$values['source']['node_type'] = $node_type;
|
||||
$values['destination']['default_bundle'] = $node_type;
|
||||
|
||||
// Comment status must be mapped to correct comment type.
|
||||
// Comment type migration creates a separate comment type for each
|
||||
// node type except for Forum which uses 'comment_forum'.
|
||||
$comment_type = 'comment_node_' . $node_type;
|
||||
if ($node_type == 'forum') {
|
||||
$comment_type = 'comment_forum';
|
||||
}
|
||||
$nested_key = $comment_type . '/0/status';
|
||||
$values['process'][$nested_key] = 'comment';
|
||||
|
||||
// If this migration is based on the d7_node_revision migration or
|
||||
// is for translations of nodes, it should explicitly depend on the
|
||||
// corresponding d7_node variant.
|
||||
|
||||
@@ -15,7 +15,9 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
* Drupal 6 node source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_node"
|
||||
* id = "d6_node",
|
||||
* source_module = "node"
|
||||
*
|
||||
* )
|
||||
*/
|
||||
class Node extends DrupalSqlBase {
|
||||
@@ -176,24 +178,24 @@ class Node extends DrupalSqlBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets CCK field values for a node.
|
||||
* Gets field values for a node.
|
||||
*
|
||||
* @param \Drupal\migrate\Row $node
|
||||
* The node.
|
||||
*
|
||||
* @return array
|
||||
* CCK field values, keyed by field name.
|
||||
* Field values, keyed by field name.
|
||||
*/
|
||||
protected function getFieldValues(Row $node) {
|
||||
$values = [];
|
||||
foreach ($this->getFieldInfo($node->getSourceProperty('type')) as $field => $info) {
|
||||
$values[$field] = $this->getCckData($info, $node);
|
||||
$values[$field] = $this->getFieldData($info, $node);
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets CCK field and instance definitions from the database.
|
||||
* Gets field and instance definitions from the database.
|
||||
*
|
||||
* @param string $node_type
|
||||
* The node type for which to get field info.
|
||||
@@ -205,14 +207,14 @@ class Node extends DrupalSqlBase {
|
||||
if (!isset($this->fieldInfo)) {
|
||||
$this->fieldInfo = [];
|
||||
|
||||
// Query the database directly for all CCK field info.
|
||||
// Query the database directly for all field info.
|
||||
$query = $this->select('content_node_field_instance', 'cnfi');
|
||||
$query->join('content_node_field', 'cnf', 'cnf.field_name = cnfi.field_name');
|
||||
$query->fields('cnfi');
|
||||
$query->fields('cnf');
|
||||
|
||||
foreach ($query->execute() as $field) {
|
||||
$this->fieldInfo[ $field['type_name'] ][ $field['field_name'] ] = $field;
|
||||
$this->fieldInfo[$field['type_name']][$field['field_name']] = $field;
|
||||
}
|
||||
|
||||
foreach ($this->fieldInfo as $type => $fields) {
|
||||
@@ -230,7 +232,7 @@ class Node extends DrupalSqlBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves raw CCK field data for a node.
|
||||
* Retrieves raw field data for a node.
|
||||
*
|
||||
* @param array $field
|
||||
* A field and instance definition from getFieldInfo().
|
||||
@@ -240,7 +242,7 @@ class Node extends DrupalSqlBase {
|
||||
* @return array
|
||||
* The field values, keyed by delta.
|
||||
*/
|
||||
protected function getCckData(array $field, Row $node) {
|
||||
protected function getFieldData(array $field, Row $node) {
|
||||
$field_table = 'content_' . $field['field_name'];
|
||||
$node_table = 'content_type_' . $node->getSourceProperty('type');
|
||||
|
||||
@@ -276,10 +278,9 @@ class Node extends DrupalSqlBase {
|
||||
|
||||
return $query
|
||||
// This call to isNotNull() is a kludge which relies on the convention
|
||||
// that CCK field schemas usually define their most important
|
||||
// column first. A better way would be to allow cckfield plugins to
|
||||
// alter the query directly before it's run, but this will do for
|
||||
// the time being.
|
||||
// that field schemas usually define their most important column first.
|
||||
// A better way would be to allow field plugins to alter the query
|
||||
// directly before it's run, but this will do for the time being.
|
||||
->isNotNull($field['field_name'] . '_' . $columns[0])
|
||||
->condition('nid', $node->getSourceProperty('nid'))
|
||||
->condition('vid', $node->getSourceProperty('vid'))
|
||||
@@ -291,6 +292,24 @@ class Node extends DrupalSqlBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves raw field data for a node.
|
||||
*
|
||||
* @deprecated in Drupal 8.2.x, to be removed in Drupal 9.0.x. Use
|
||||
* getFieldData() instead.
|
||||
*
|
||||
* @param array $field
|
||||
* A field and instance definition from getFieldInfo().
|
||||
* @param \Drupal\migrate\Row $node
|
||||
* The node.
|
||||
*
|
||||
* @return array
|
||||
* The field values, keyed by delta.
|
||||
*/
|
||||
protected function getCckData(array $field, Row $node) {
|
||||
return $this->getFieldData($field, $node);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\node\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
|
||||
/**
|
||||
* Drupal 6 node revision source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_node_revision"
|
||||
* id = "d6_node_revision",
|
||||
* source_module = "node"
|
||||
* )
|
||||
*/
|
||||
class NodeRevision extends Node {
|
||||
|
||||
@@ -9,7 +9,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
* Drupal 6 Node types source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_node_type"
|
||||
* id = "d6_node_type",
|
||||
* source_module = "node"
|
||||
* )
|
||||
*/
|
||||
class NodeType extends DrupalSqlBase {
|
||||
@@ -62,7 +63,7 @@ class NodeType extends DrupalSqlBase {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return [
|
||||
$fields = [
|
||||
'type' => $this->t('Machine name of the node type.'),
|
||||
'name' => $this->t('Human name of the node type.'),
|
||||
'module' => $this->t('The module providing the node type.'),
|
||||
@@ -78,6 +79,28 @@ class NodeType extends DrupalSqlBase {
|
||||
'orig_type' => $this->t('The original type.'),
|
||||
'teaser_length' => $this->t('Teaser length'),
|
||||
];
|
||||
if ($this->moduleExists('comment')) {
|
||||
$fields += $this->getCommentFields();
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fields containing comment settings for each node type.
|
||||
*
|
||||
* @return string[]
|
||||
* An associative array of field descriptions, keyed by field.
|
||||
*/
|
||||
protected function getCommentFields() {
|
||||
return [
|
||||
'comment' => $this->t('Default comment setting'),
|
||||
'comment_default_mode' => $this->t('Default display mode'),
|
||||
'comment_default_per_page' => $this->t('Default comments per page'),
|
||||
'comment_anonymous' => $this->t('Anonymous commenting'),
|
||||
'comment_subject_field' => $this->t('Comment subject field'),
|
||||
'comment_preview' => $this->t('Preview comment'),
|
||||
'comment_form_location' => $this->t('Location of comment submission form'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,6 +134,13 @@ class NodeType extends DrupalSqlBase {
|
||||
$row->setSourceProperty('available_menus', [$default_node_menu]);
|
||||
$row->setSourceProperty('parent', $default_node_menu . ':');
|
||||
}
|
||||
|
||||
if ($this->moduleExists('comment')) {
|
||||
foreach (array_keys($this->getCommentFields()) as $field) {
|
||||
$row->setSourceProperty($field, $this->variableGet($field . '_' . $type, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Drupal\node\Plugin\migrate\source\d6;
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_view_mode",
|
||||
* source_provider = "content"
|
||||
* source_module = "content"
|
||||
* )
|
||||
*/
|
||||
class ViewMode extends ViewModeBase {
|
||||
|
||||
@@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_node",
|
||||
* source_provider = "node"
|
||||
* source_module = "node"
|
||||
* )
|
||||
*/
|
||||
class Node extends FieldableEntity {
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Drupal\node\Plugin\migrate\source\d7;
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_node_revision",
|
||||
* source_provider = "node"
|
||||
* source_module = "node"
|
||||
* )
|
||||
*/
|
||||
class NodeRevision extends Node {
|
||||
|
||||
@@ -10,7 +10,7 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_node_type",
|
||||
* source_provider = "node"
|
||||
* source_module = "node"
|
||||
* )
|
||||
*/
|
||||
class NodeType extends DrupalSqlBase {
|
||||
@@ -54,6 +54,28 @@ class NodeType extends DrupalSqlBase {
|
||||
'orig_type' => $this->t('The original type.'),
|
||||
'teaser_length' => $this->t('Teaser length'),
|
||||
];
|
||||
if ($this->moduleExists('comment')) {
|
||||
$fields += $this->getCommentFields();
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fields containing comment settings for each node type.
|
||||
*
|
||||
* @return string[]
|
||||
* An associative array of field descriptions, keyed by field.
|
||||
*/
|
||||
protected function getCommentFields() {
|
||||
return [
|
||||
'comment' => $this->t('Default comment setting'),
|
||||
'comment_default_mode' => $this->t('Default display mode'),
|
||||
'comment_default_per_page' => $this->t('Default comments per page'),
|
||||
'comment_anonymous' => $this->t('Anonymous commenting'),
|
||||
'comment_subject_field' => $this->t('Comment subject field'),
|
||||
'comment_preview' => $this->t('Preview comment'),
|
||||
'comment_form_location' => $this->t('Location of comment submission form'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,6 +129,13 @@ class NodeType extends DrupalSqlBase {
|
||||
if ($parent = $this->variableGet('menu_parent_' . $type, NULL)) {
|
||||
$row->setSourceProperty('parent', $parent . ':');
|
||||
}
|
||||
|
||||
if ($this->moduleExists('comment')) {
|
||||
foreach (array_keys($this->getCommentFields()) as $field) {
|
||||
$row->setSourceProperty($field, $this->variableGet($field . '_' . $type, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ class Type extends StringArgument {
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $node_type_storage
|
||||
* The entity storage class.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityStorageInterface $node_type_storage) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\node\Plugin\views\filter;
|
||||
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\views\Plugin\views\filter\FilterPluginBase;
|
||||
|
||||
@@ -14,8 +15,8 @@ use Drupal\views\Plugin\views\filter\FilterPluginBase;
|
||||
*/
|
||||
class Access extends FilterPluginBase {
|
||||
|
||||
public function adminSummary() { }
|
||||
protected function operatorForm(&$form, FormStateInterface $form_state) { }
|
||||
public function adminSummary() {}
|
||||
protected function operatorForm(&$form, FormStateInterface $form_state) {}
|
||||
public function canExpose() {
|
||||
return FALSE;
|
||||
}
|
||||
@@ -27,10 +28,10 @@ class Access extends FilterPluginBase {
|
||||
$account = $this->view->getUser();
|
||||
if (!$account->hasPermission('bypass node access')) {
|
||||
$table = $this->ensureMyTable();
|
||||
$grants = db_or();
|
||||
$grants = new Condition('OR');
|
||||
foreach (node_access_grants('view', $account) as $realm => $gids) {
|
||||
foreach ($gids as $gid) {
|
||||
$grants->condition(db_and()
|
||||
$grants->condition((new Condition('AND'))
|
||||
->condition($table . '.gid', $gid)
|
||||
->condition($table . '.realm', $realm)
|
||||
);
|
||||
|
||||
@@ -14,11 +14,13 @@ use Drupal\views\Plugin\views\filter\FilterPluginBase;
|
||||
*/
|
||||
class Status extends FilterPluginBase {
|
||||
|
||||
public function adminSummary() { }
|
||||
public function adminSummary() {}
|
||||
|
||||
protected function operatorForm(&$form, FormStateInterface $form_state) { }
|
||||
protected function operatorForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
public function canExpose() { return FALSE; }
|
||||
public function canExpose() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function query() {
|
||||
$table = $this->ensureMyTable();
|
||||
|
||||
@@ -117,7 +117,8 @@ class NodeRevisionsTest extends NodeTestBase {
|
||||
|
||||
$node->save();
|
||||
|
||||
$node = Node::load($node->id()); // Make sure we get revision information.
|
||||
// Make sure we get revision information.
|
||||
$node = Node::load($node->id());
|
||||
$nodes[] = clone $node;
|
||||
}
|
||||
|
||||
@@ -168,9 +169,11 @@ class NodeRevisionsTest extends NodeTestBase {
|
||||
|
||||
// Confirm that revisions revert properly.
|
||||
$this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionid() . "/revert", [], t('Revert'));
|
||||
$this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.',
|
||||
['@type' => 'Basic page', '%title' => $nodes[1]->label(),
|
||||
'%revision-date' => format_date($nodes[1]->getRevisionCreationTime())]), 'Revision reverted.');
|
||||
$this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', [
|
||||
'@type' => 'Basic page',
|
||||
'%title' => $nodes[1]->label(),
|
||||
'%revision-date' => format_date($nodes[1]->getRevisionCreationTime())
|
||||
]), 'Revision reverted.');
|
||||
$node_storage->resetCache([$node->id()]);
|
||||
$reverted_node = $node_storage->load($node->id());
|
||||
$this->assertTrue(($nodes[1]->body->value == $reverted_node->body->value), 'Node reverted correctly.');
|
||||
@@ -191,9 +194,11 @@ class NodeRevisionsTest extends NodeTestBase {
|
||||
|
||||
// Confirm revisions delete properly.
|
||||
$this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/delete", [], t('Delete'));
|
||||
$this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.',
|
||||
['%revision-date' => format_date($nodes[1]->getRevisionCreationTime()),
|
||||
'@type' => 'Basic page', '%title' => $nodes[1]->label()]), 'Revision deleted.');
|
||||
$this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.', [
|
||||
'%revision-date' => format_date($nodes[1]->getRevisionCreationTime()),
|
||||
'@type' => 'Basic page',
|
||||
'%title' => $nodes[1]->label(),
|
||||
]), 'Revision deleted.');
|
||||
$this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid and vid = :vid', [':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()])->fetchField() == 0, 'Revision not found.');
|
||||
$this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid and vid = :vid', [':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()])->fetchField() == 0, 'Field revision not found.');
|
||||
|
||||
|
||||
@@ -427,14 +427,14 @@ class PagePreviewTest extends NodeTestBase {
|
||||
$this->assertFieldByName('revision_log[0][value]', $edit['revision_log[0][value]'], 'Revision log field displayed.');
|
||||
|
||||
// Save the node after coming back from the preview page so we can create a
|
||||
// forward revision for it.
|
||||
// pending revision for it.
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
$node = $this->drupalGetNodeByTitle($edit[$title_key]);
|
||||
|
||||
// Check that previewing a forward revision of a node works. This can not be
|
||||
// Check that previewing a pending revision of a node works. This can not be
|
||||
// accomplished through the UI so we have to use API calls.
|
||||
// @todo Change this test to use the UI when we will be able to create
|
||||
// forward revisions in core.
|
||||
// pending revisions in core.
|
||||
// @see https://www.drupal.org/node/2725533
|
||||
$node->setNewRevision(TRUE);
|
||||
$node->isDefaultRevision(FALSE);
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
+3
-3
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
+3
-3
@@ -7,8 +7,8 @@ package: Testing
|
||||
dependencies:
|
||||
- options
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -14,7 +14,6 @@ use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_ENTITY_TYPE_view() for node entities.
|
||||
*/
|
||||
@@ -156,7 +155,7 @@ function node_test_node_update(NodeInterface $node) {
|
||||
*/
|
||||
function node_test_entity_view_mode_alter(&$view_mode, EntityInterface $entity, $context) {
|
||||
// Only alter the view mode if we are on the test callback.
|
||||
$change_view_mode = \Drupal::state()->get( 'node_test_change_view_mode') ?: '';
|
||||
$change_view_mode = \Drupal::state()->get('node_test_change_view_mode') ?: '';
|
||||
if ($change_view_mode) {
|
||||
$view_mode = $change_view_mode;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ description: 'Support module for node configuration tests.'
|
||||
package: Testing
|
||||
# version: VERSION
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -9,8 +9,8 @@ dependencies:
|
||||
- views
|
||||
- language
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
+3
-3
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\node\Kernel\Migrate\d6\MigrateNodeTestBase;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
|
||||
/**
|
||||
* Tests the node access automatic cacheability bubbling logic.
|
||||
|
||||
@@ -114,7 +114,7 @@ class NodeAccessBaseTableTest extends NodeTestBase {
|
||||
|
||||
$this->drupalPostForm('node/add/article', $edit, t('Save'));
|
||||
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
$this->assertEqual($is_private, (int)$node->private->value, 'The private status of the node was properly set in the node_access_test table.');
|
||||
$this->assertEqual($is_private, (int) $node->private->value, 'The private status of the node was properly set in the node_access_test table.');
|
||||
if ($is_private) {
|
||||
$private_nodes[] = $node->id();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\block\Entity\Block;
|
||||
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
|
||||
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
/**
|
||||
|
||||
@@ -184,7 +184,7 @@ class NodeCreationTest extends NodeTestBase {
|
||||
$this->assertNoLinkByHref('/admin/structure/types/add');
|
||||
|
||||
// Test /node/add page without content types.
|
||||
foreach (\Drupal::entityManager()->getStorage('node_type')->loadMultiple() as $entity ) {
|
||||
foreach (\Drupal::entityManager()->getStorage('node_type')->loadMultiple() as $entity) {
|
||||
$entity->delete();
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ class NodeEditFormTest extends NodeTestBase {
|
||||
$edit['title[0][value]'] = $this->randomMachineName(8);
|
||||
$edit[$body_key] = $this->randomMachineName(16);
|
||||
$edit['revision'] = TRUE;
|
||||
$this->drupalPostForm(NULL, $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
|
||||
// Ensure that the node revision has been created.
|
||||
$revised_node = $this->drupalGetNodeByTitle($edit['title[0][value]'], TRUE);
|
||||
@@ -124,12 +124,21 @@ class NodeEditFormTest extends NodeTestBase {
|
||||
$edit['created[0][value][date]'] = $this->randomMachineName(8);
|
||||
// Get the current amount of open details elements.
|
||||
$open_details_elements = count($this->cssSelect('details[open="open"]'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
// The node author details must be open.
|
||||
$this->assertRaw('<details class="node-form-author js-form-wrapper form-wrapper" data-drupal-selector="edit-author" id="edit-author" open="open">');
|
||||
// Only one extra details element should now be open.
|
||||
$open_details_elements++;
|
||||
$this->assertEqual(count($this->cssSelect('details[open="open"]')), $open_details_elements, 'Exactly one extra open <details> element found.');
|
||||
|
||||
// Edit the same node, save it and verify it's unpublished after unchecking
|
||||
// the 'Published' boolean_checkbox and clicking 'Save'.
|
||||
$this->drupalGet("node/" . $node->id() . "/edit");
|
||||
$edit = ['status[value]' => FALSE];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->nodeStorage->resetCache([$node->id()]);
|
||||
$node = $this->nodeStorage->load($node->id());
|
||||
$this->assertFalse($node->isPublished(), 'Node is unpublished');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,7 +152,7 @@ class NodeEditFormTest extends NodeTestBase {
|
||||
$edit = [];
|
||||
$edit['title[0][value]'] = $this->randomMachineName(8);
|
||||
$edit[$body_key] = $this->randomMachineName(16);
|
||||
$this->drupalPostForm('node/add/page', $edit, t('Save and publish'));
|
||||
$this->drupalPostForm('node/add/page', $edit, t('Save'));
|
||||
|
||||
// Check that the node was authored by the currently logged in user.
|
||||
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
@@ -172,7 +181,7 @@ class NodeEditFormTest extends NodeTestBase {
|
||||
$this->drupalLogin($this->adminUser);
|
||||
|
||||
// Save the node without making any changes.
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and keep published'));
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save'));
|
||||
$this->nodeStorage->resetCache([$node->id()]);
|
||||
$node = $this->nodeStorage->load($node->id());
|
||||
$this->assertIdentical($this->webUser->id(), $node->getOwner()->id());
|
||||
@@ -184,12 +193,49 @@ class NodeEditFormTest extends NodeTestBase {
|
||||
|
||||
// Check that saving the node without making any changes keeps the proper
|
||||
// author ID.
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and keep published'));
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save'));
|
||||
$this->nodeStorage->resetCache([$node->id()]);
|
||||
$node = $this->nodeStorage->load($node->id());
|
||||
$this->assertIdentical($this->webUser->id(), $node->getOwner()->id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the node meta information.
|
||||
*/
|
||||
public function testNodeMetaInformation() {
|
||||
// Check that regular users (i.e. without the 'administer nodes' permission)
|
||||
// can not see the meta information.
|
||||
$this->drupalLogin($this->webUser);
|
||||
$this->drupalGet('node/add/page');
|
||||
$this->assertNoText('Not saved yet');
|
||||
|
||||
// Create node to edit.
|
||||
$edit['title[0][value]'] = $this->randomMachineName(8);
|
||||
$edit['body[0][value]'] = $this->randomMachineName(16);
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
|
||||
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
$this->drupalGet("node/" . $node->id() . "/edit");
|
||||
$this->assertNoText('Published');
|
||||
$this->assertNoText(format_date($node->getChangedTime(), 'short'));
|
||||
|
||||
// Check that users with the 'administer nodes' permission can see the meta
|
||||
// information.
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->drupalGet('node/add/page');
|
||||
$this->assertText('Not saved yet');
|
||||
|
||||
// Create node to edit.
|
||||
$edit['title[0][value]'] = $this->randomMachineName(8);
|
||||
$edit['body[0][value]'] = $this->randomMachineName(16);
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
|
||||
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
$this->drupalGet("node/" . $node->id() . "/edit");
|
||||
$this->assertText('Published');
|
||||
$this->assertText(format_date($node->getChangedTime(), 'short'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the "authored by" works correctly with various values.
|
||||
*
|
||||
@@ -203,13 +249,13 @@ class NodeEditFormTest extends NodeTestBase {
|
||||
$edit = [
|
||||
$form_element_name => 'invalid-name',
|
||||
];
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
|
||||
$this->assertRaw(t('There are no entities matching "%name".', ['%name' => 'invalid-name']));
|
||||
|
||||
// Change the authored by field to an empty string, which should assign
|
||||
// authorship to the anonymous user (uid 0).
|
||||
$edit[$form_element_name] = '';
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
|
||||
$this->nodeStorage->resetCache([$node->id()]);
|
||||
$node = $this->nodeStorage->load($node->id());
|
||||
$uid = $node->getOwnerId();
|
||||
@@ -228,7 +274,7 @@ class NodeEditFormTest extends NodeTestBase {
|
||||
// Change the authored by field to another user's name (that is not
|
||||
// logged in).
|
||||
$edit[$form_element_name] = $this->webUser->getUsername();
|
||||
$this->drupalPostForm(NULL, $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->nodeStorage->resetCache([$node->id()]);
|
||||
$node = $this->nodeStorage->load($node->id());
|
||||
$this->assertIdentical($node->getOwnerId(), $this->webUser->id(), 'Node authored by normal user.');
|
||||
|
||||
@@ -67,7 +67,7 @@ class NodeRevisionsUiBypassAccessTest extends NodeTestBase {
|
||||
|
||||
// Uncheck the create new revision checkbox and save the node.
|
||||
$edit = ['revision' => FALSE];
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save and keep published');
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save');
|
||||
|
||||
$this->assertUrl($node->toUrl());
|
||||
$this->assertNoLink(t('Revisions'));
|
||||
@@ -78,7 +78,7 @@ class NodeRevisionsUiBypassAccessTest extends NodeTestBase {
|
||||
|
||||
// Submit the form without changing the checkbox.
|
||||
$edit = [];
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save and keep published');
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save');
|
||||
|
||||
$this->assertUrl($node->toUrl());
|
||||
$this->assertLink(t('Revisions'));
|
||||
|
||||
@@ -55,7 +55,7 @@ class NodeRevisionsUiTest extends NodeTestBase {
|
||||
|
||||
// Uncheck the create new revision checkbox and save the node.
|
||||
$edit = ['revision' => FALSE];
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Load the node again and check the revision is the same as before.
|
||||
$node_storage->resetCache([$node->id()]);
|
||||
@@ -68,7 +68,7 @@ class NodeRevisionsUiTest extends NodeTestBase {
|
||||
|
||||
// Submit the form without changing the checkbox.
|
||||
$edit = [];
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Load the node again and check the revision is different from before.
|
||||
$node_storage->resetCache([$node->id()]);
|
||||
|
||||
@@ -109,8 +109,10 @@ class NodeSaveTest extends NodeTestBase {
|
||||
'uid' => $this->webUser->id(),
|
||||
'type' => 'article',
|
||||
'title' => $this->randomMachineName(8),
|
||||
'created' => 280299600, // Sun, 19 Nov 1978 05:00:00 GMT
|
||||
'changed' => 979534800, // Drupal 1.0 release.
|
||||
// Sun, 19 Nov 1978 05:00:00 GMT.
|
||||
'created' => 280299600,
|
||||
// Drupal 1.0 release.
|
||||
'changed' => 979534800,
|
||||
];
|
||||
|
||||
Node::create($edit)->save();
|
||||
|
||||
@@ -99,7 +99,9 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
|
||||
'source' => $default_langcode,
|
||||
'target' => $langcode
|
||||
], ['language' => $language]);
|
||||
$this->drupalPostForm($add_url, $this->getEditValues($values, $langcode), t('Save and unpublish (this translation)'));
|
||||
$edit = $this->getEditValues($values, $langcode);
|
||||
$edit['status[value]'] = FALSE;
|
||||
$this->drupalPostForm($add_url, $edit, t('Save (this translation)'));
|
||||
|
||||
$storage->resetCache([$this->entityId]);
|
||||
$entity = $storage->load($this->entityId);
|
||||
@@ -136,18 +138,6 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
|
||||
return ['title' => [['value' => $this->randomMachineName()]]] + parent::getNewEntityValues($langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getFormSubmitAction(EntityInterface $entity, $langcode) {
|
||||
if ($entity->getTranslation($langcode)->isPublished()) {
|
||||
return t('Save and keep published') . $this->getFormSubmitSuffix($entity, $langcode);
|
||||
}
|
||||
else {
|
||||
return t('Save and keep unpublished') . $this->getFormSubmitSuffix($entity, $langcode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -158,18 +148,18 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
|
||||
$entity = $storage->load($this->entityId);
|
||||
$languages = $this->container->get('language_manager')->getLanguages();
|
||||
|
||||
$actions = [
|
||||
t('Save and keep published'),
|
||||
t('Save and unpublish'),
|
||||
$statuses = [
|
||||
TRUE,
|
||||
FALSE,
|
||||
];
|
||||
|
||||
foreach ($actions as $index => $action) {
|
||||
foreach ($statuses as $index => $value) {
|
||||
// (Un)publish the node translations and check that the translation
|
||||
// statuses are (un)published accordingly.
|
||||
foreach ($this->langcodes as $langcode) {
|
||||
$options = ['language' => $languages[$langcode]];
|
||||
$url = $entity->urlInfo('edit-form', $options);
|
||||
$this->drupalPostForm($url, [], $action . $this->getFormSubmitSuffix($entity, $langcode), $options);
|
||||
$this->drupalPostForm($url, ['status[value]' => $value], t('Save') . $this->getFormSubmitSuffix($entity, $langcode), $options);
|
||||
}
|
||||
$storage->resetCache([$this->entityId]);
|
||||
$entity = $storage->load($this->entityId);
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Update;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Tests that node settings are properly updated during database updates.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the node entity type has a 'published' entity key.
|
||||
*
|
||||
* @see node_update_8301()
|
||||
*/
|
||||
public function testPublishedEntityKey() {
|
||||
// Check that the 'published' entity key does not exist prior to the update.
|
||||
$entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('node');
|
||||
$this->assertFalse($entity_type->getKey('published'));
|
||||
|
||||
// Run updates.
|
||||
$this->runUpdates();
|
||||
|
||||
// Check that the entity key exists and it has the correct value.
|
||||
$entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('node');
|
||||
$this->assertEqual('status', $entity_type->getKey('published'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the node entity form has the status checkbox.
|
||||
*
|
||||
* @see node_post_update_configure_status_field_widget()
|
||||
*/
|
||||
public function testStatusCheckbox() {
|
||||
// Run updates.
|
||||
$this->runUpdates();
|
||||
|
||||
$query = \Drupal::entityQuery('entity_form_display')
|
||||
->condition('targetEntityType', 'node');
|
||||
$ids = $query->execute();
|
||||
$form_displays = EntityFormDisplay::loadMultiple($ids);
|
||||
|
||||
/**
|
||||
* @var string $id
|
||||
* @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display
|
||||
*/
|
||||
foreach ($form_displays as $id => $form_display) {
|
||||
$component = $form_display->getComponent('status');
|
||||
$this->assertEqual('boolean_checkbox', $component['type']);
|
||||
$this->assertEqual(['display_label' => TRUE], $component['settings']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -67,9 +67,9 @@ class BulkFormAccessTest extends NodeTestBase {
|
||||
// Create a private node (author may view, edit and delete, others may not).
|
||||
$node = $this->drupalCreateNode([
|
||||
'type' => 'article',
|
||||
'private' => [[
|
||||
'value' => TRUE,
|
||||
]],
|
||||
'private' => [
|
||||
['value' => TRUE],
|
||||
],
|
||||
'uid' => $author->id(),
|
||||
]);
|
||||
// Create an account that may view the private node, but not edit it.
|
||||
@@ -134,9 +134,9 @@ class BulkFormAccessTest extends NodeTestBase {
|
||||
// Create a private node (author may view, edit and delete, others may not).
|
||||
$private_node = $this->drupalCreateNode([
|
||||
'type' => 'article',
|
||||
'private' => [[
|
||||
'value' => TRUE,
|
||||
]],
|
||||
'private' => [
|
||||
['value' => TRUE],
|
||||
],
|
||||
'uid' => $author->id(),
|
||||
]);
|
||||
// Create an account that may view the private node, but not delete it.
|
||||
@@ -146,9 +146,9 @@ class BulkFormAccessTest extends NodeTestBase {
|
||||
// deleted by the author.
|
||||
$own_node = $this->drupalCreateNode([
|
||||
'type' => 'article',
|
||||
'private' => [[
|
||||
'value' => TRUE,
|
||||
]],
|
||||
'private' => [
|
||||
['value' => TRUE],
|
||||
],
|
||||
'uid' => $account->id(),
|
||||
]);
|
||||
$this->drupalLogin($account);
|
||||
|
||||
@@ -170,19 +170,29 @@ class BulkFormTest extends NodeTestBase {
|
||||
// operations are always applied to individual translations.
|
||||
$edit = [
|
||||
// Original and all translations.
|
||||
'node_bulk_form[0]' => TRUE, // Node 1, English, original.
|
||||
'node_bulk_form[1]' => TRUE, // Node 1, British English.
|
||||
'node_bulk_form[2]' => TRUE, // Node 1, Italian.
|
||||
// Node 1, English, original.
|
||||
'node_bulk_form[0]' => TRUE,
|
||||
// Node 1, British English.
|
||||
'node_bulk_form[1]' => TRUE,
|
||||
// Node 1, Italian.
|
||||
'node_bulk_form[2]' => TRUE,
|
||||
// Original and only one translation.
|
||||
'node_bulk_form[3]' => TRUE, // Node 2, English.
|
||||
'node_bulk_form[4]' => TRUE, // Node 2, British English, original.
|
||||
'node_bulk_form[5]' => FALSE, // Node 2, Italian.
|
||||
// Node 2, English.
|
||||
'node_bulk_form[3]' => TRUE,
|
||||
// Node 2, British English, original.
|
||||
'node_bulk_form[4]' => TRUE,
|
||||
// Node 2, Italian.
|
||||
'node_bulk_form[5]' => FALSE,
|
||||
// Only a single translation.
|
||||
'node_bulk_form[6]' => TRUE, // Node 3, English.
|
||||
'node_bulk_form[7]' => FALSE, // Node 3, Italian, original.
|
||||
// Node 3, English.
|
||||
'node_bulk_form[6]' => TRUE,
|
||||
// Node 3, Italian, original.
|
||||
'node_bulk_form[7]' => FALSE,
|
||||
// Only a single untranslated node.
|
||||
'node_bulk_form[8]' => TRUE, // Node 4, English, untranslated.
|
||||
'node_bulk_form[9]' => FALSE, // Node 5, British English, untranslated.
|
||||
// Node 4, English, untranslated.
|
||||
'node_bulk_form[8]' => TRUE,
|
||||
// Node 5, British English, untranslated.
|
||||
'node_bulk_form[9]' => FALSE,
|
||||
'action' => 'node_unpublish_action',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
|
||||
@@ -211,19 +221,29 @@ class BulkFormTest extends NodeTestBase {
|
||||
// nodes and individual translations are properly deleted.
|
||||
$edit = [
|
||||
// Original and all translations.
|
||||
'node_bulk_form[0]' => TRUE, // Node 1, English, original.
|
||||
'node_bulk_form[1]' => TRUE, // Node 1, British English.
|
||||
'node_bulk_form[2]' => TRUE, // Node 1, Italian.
|
||||
// Node 1, English, original.
|
||||
'node_bulk_form[0]' => TRUE,
|
||||
// Node 1, British English.
|
||||
'node_bulk_form[1]' => TRUE,
|
||||
// Node 1, Italian.
|
||||
'node_bulk_form[2]' => TRUE,
|
||||
// Original and only one translation.
|
||||
'node_bulk_form[3]' => TRUE, // Node 2, English.
|
||||
'node_bulk_form[4]' => TRUE, // Node 2, British English, original.
|
||||
'node_bulk_form[5]' => FALSE, // Node 2, Italian.
|
||||
// Node 2, English.
|
||||
'node_bulk_form[3]' => TRUE,
|
||||
// Node 2, British English, original.
|
||||
'node_bulk_form[4]' => TRUE,
|
||||
// Node 2, Italian.
|
||||
'node_bulk_form[5]' => FALSE,
|
||||
// Only a single translation.
|
||||
'node_bulk_form[6]' => TRUE, // Node 3, English.
|
||||
'node_bulk_form[7]' => FALSE, // Node 3, Italian, original.
|
||||
// Node 3, English.
|
||||
'node_bulk_form[6]' => TRUE,
|
||||
// Node 3, Italian, original.
|
||||
'node_bulk_form[7]' => FALSE,
|
||||
// Only a single untranslated node.
|
||||
'node_bulk_form[8]' => TRUE, // Node 4, English, untranslated.
|
||||
'node_bulk_form[9]' => FALSE, // Node 5, British English, untranslated.
|
||||
// Node 4, English, untranslated.
|
||||
'node_bulk_form[8]' => TRUE,
|
||||
// Node 5, British English, untranslated.
|
||||
'node_bulk_form[9]' => FALSE,
|
||||
'action' => 'node_delete_action',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
|
||||
|
||||
@@ -54,10 +54,12 @@ class FilterNodeAccessTest extends NodeTestBase {
|
||||
$this->drupalLogin($web_user);
|
||||
foreach ([0 => 'Public', 1 => 'Private'] as $is_private => $type) {
|
||||
$settings = [
|
||||
'body' => [[
|
||||
'value' => $type . ' node',
|
||||
'format' => filter_default_format(),
|
||||
]],
|
||||
'body' => [
|
||||
[
|
||||
'value' => $type . ' node',
|
||||
'format' => filter_default_format(),
|
||||
],
|
||||
],
|
||||
'title' => t('@private_public Article created by @user', ['@private_public' => $type, '@user' => $web_user->getUsername()]),
|
||||
'type' => 'article',
|
||||
'uid' => $web_user->id(),
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\FunctionalJavascript;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
|
||||
/**
|
||||
* Tests the JavaScript updating of summaries on content type form.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class TestSettingSummariesContentType extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$admin_user = $this->drupalCreateUser(['administer content types']);
|
||||
$this->drupalLogin($admin_user);
|
||||
$this->drupalCreateContentType(['type' => 'test']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a vertical tab 'Workflow' summary.
|
||||
*/
|
||||
public function testWorkflowSummary() {
|
||||
$this->drupalGet('admin/structure/types/manage/test');
|
||||
$page = $this->getSession()->getPage();
|
||||
$page->findField('options[status]')->uncheck();
|
||||
$page->findField('options[sticky]')->check();
|
||||
$page->findField('options[promote]')->check();
|
||||
$page->findField('options[revision]')->check();
|
||||
$locator = '[href="#edit-workflow"] .vertical-tabs__menu-item-summary';
|
||||
$page->waitFor(10, function () use ($page, $locator) {
|
||||
$summary = $page->find('css', $locator)->getText();
|
||||
return strpos('Not published', $summary) !== FALSE;
|
||||
});
|
||||
$summary = $page->find('css', $locator)->getText();
|
||||
$this->assertEquals('Not published, Promoted to front page, Sticky at top of lists, Create new revision', $summary);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Tests node translation redirections.
|
||||
*
|
||||
* @group migrate_drupal
|
||||
* @group node
|
||||
*/
|
||||
class NodeTranslationRedirectTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'content_translation',
|
||||
'language',
|
||||
'menu_ui',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installConfig(['node']);
|
||||
$this->installSchema('node', ['node_access']);
|
||||
$this->installSchema('system', ['key_value']);
|
||||
$this->migrateUsers(FALSE);
|
||||
$this->migrateFields();
|
||||
|
||||
$this->executeMigrations([
|
||||
'language',
|
||||
'd6_language_types',
|
||||
'd6_language_negotiation_settings',
|
||||
'd6_node_settings',
|
||||
'd6_node',
|
||||
'd6_node_translation',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that not found node translations are redirected.
|
||||
*/
|
||||
public function testNodeTranslationRedirect() {
|
||||
$kernel = $this->container->get('http_kernel');
|
||||
$request = Request::create('/node/11');
|
||||
$response = $kernel->handle($request);
|
||||
$this->assertSame(301, $response->getStatusCode());
|
||||
$this->assertSame('/node/10', $response->getTargetUrl());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,22 +18,32 @@ class MigrateNodeDeriverTest extends MigrateDrupal7TestBase {
|
||||
*/
|
||||
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');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->assertSame([], $migrations,
|
||||
"No node translation migrations without content_translation");
|
||||
$this->assertTrue($this->moduleHandler->moduleExists('node'));
|
||||
$this->assertEmpty($migrations);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\Tests\node\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
|
||||
use Drupal\Tests\file\Kernel\Migrate\d7\FileMigrationSetupTrait;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\NodeInterface;
|
||||
@@ -13,6 +15,8 @@ use Drupal\node\NodeInterface;
|
||||
*/
|
||||
class MigrateNodeTest extends MigrateDrupal7TestBase {
|
||||
|
||||
use FileMigrationSetupTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -20,7 +24,9 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
|
||||
'content_translation',
|
||||
'comment',
|
||||
'datetime',
|
||||
'file',
|
||||
'filter',
|
||||
'forum',
|
||||
'image',
|
||||
'language',
|
||||
'link',
|
||||
@@ -37,11 +43,14 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->fileMigrationSetup();
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installEntitySchema('comment');
|
||||
$this->installEntitySchema('taxonomy_term');
|
||||
$this->installEntitySchema('file');
|
||||
$this->installConfig(static::$modules);
|
||||
$this->installSchema('comment', ['comment_entity_statistics']);
|
||||
$this->installSchema('forum', ['forum', 'forum_index']);
|
||||
$this->installSchema('node', ['node_access']);
|
||||
$this->installSchema('system', ['sequences']);
|
||||
|
||||
@@ -52,6 +61,8 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
|
||||
'd7_node_type',
|
||||
'd7_language_content_settings',
|
||||
'd7_comment_type',
|
||||
'd7_comment_field',
|
||||
'd7_comment_field_instance',
|
||||
'd7_taxonomy_vocabulary',
|
||||
'd7_field',
|
||||
'd7_field_instance',
|
||||
@@ -87,18 +98,18 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
|
||||
protected function assertEntity($id, $type, $langcode, $title, $uid, $status, $created, $changed, $promoted, $sticky) {
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
$node = Node::load($id);
|
||||
$this->assertTrue($node instanceof NodeInterface);
|
||||
$this->assertIdentical($type, $node->getType());
|
||||
$this->assertIdentical($langcode, $node->langcode->value);
|
||||
$this->assertIdentical($title, $node->getTitle());
|
||||
$this->assertIdentical($uid, $node->getOwnerId());
|
||||
$this->assertIdentical($status, $node->isPublished());
|
||||
$this->assertIdentical($created, $node->getCreatedTime());
|
||||
$this->assertInstanceOf(NodeInterface::class, $node);
|
||||
$this->assertEquals($type, $node->getType());
|
||||
$this->assertEquals($langcode, $node->langcode->value);
|
||||
$this->assertEquals($title, $node->getTitle());
|
||||
$this->assertEquals($uid, $node->getOwnerId());
|
||||
$this->assertEquals($status, $node->isPublished());
|
||||
$this->assertEquals($created, $node->getCreatedTime());
|
||||
if (isset($changed)) {
|
||||
$this->assertIdentical($changed, $node->getChangedTime());
|
||||
$this->assertEquals($changed, $node->getChangedTime());
|
||||
}
|
||||
$this->assertIdentical($promoted, $node->isPromoted());
|
||||
$this->assertIdentical($sticky, $node->isSticky());
|
||||
$this->assertEquals($promoted, $node->isPromoted());
|
||||
$this->assertEquals($sticky, $node->isSticky());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,11 +128,11 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
|
||||
*/
|
||||
protected function assertRevision($id, $title, $uid, $log, $timestamp) {
|
||||
$revision = \Drupal::entityManager()->getStorage('node')->loadRevision($id);
|
||||
$this->assertTrue($revision instanceof NodeInterface);
|
||||
$this->assertIdentical($title, $revision->getTitle());
|
||||
$this->assertIdentical($uid, $revision->getRevisionUser()->id());
|
||||
$this->assertIdentical($log, $revision->revision_log->value);
|
||||
$this->assertIdentical($timestamp, $revision->getRevisionCreationTime());
|
||||
$this->assertInstanceOf(NodeInterface::class, $revision);
|
||||
$this->assertEquals($title, $revision->getTitle());
|
||||
$this->assertEquals($uid, $revision->getRevisionUser()->id());
|
||||
$this->assertEquals($log, $revision->revision_log->value);
|
||||
$this->assertEquals($timestamp, $revision->getRevisionCreationTime());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,53 +144,64 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
|
||||
|
||||
$node = Node::load(1);
|
||||
$this->assertTrue($node->field_boolean->value);
|
||||
$this->assertIdentical('99-99-99-99', $node->field_phone->value);
|
||||
// Use assertEqual() here instead, since SQLite interprets floats strictly.
|
||||
$this->assertEqual('1', $node->field_float->value);
|
||||
$this->assertIdentical('5', $node->field_integer->value);
|
||||
$this->assertIdentical('Some more text', $node->field_text_list[0]->value);
|
||||
$this->assertIdentical('7', $node->field_integer_list[0]->value);
|
||||
$this->assertIdentical('qwerty', $node->field_text->value);
|
||||
$this->assertIdentical('2', $node->field_file->target_id);
|
||||
$this->assertIdentical('file desc', $node->field_file->description);
|
||||
$this->assertEquals('99-99-99-99', $node->field_phone->value);
|
||||
$this->assertEquals('1', $node->field_float->value);
|
||||
$this->assertEquals('5', $node->field_integer->value);
|
||||
$this->assertEquals('Some more text', $node->field_text_list[0]->value);
|
||||
$this->assertEquals('7', $node->field_integer_list[0]->value);
|
||||
$this->assertEquals('qwerty', $node->field_text->value);
|
||||
$this->assertEquals('2', $node->field_file->target_id);
|
||||
$this->assertEquals('file desc', $node->field_file->description);
|
||||
$this->assertTrue($node->field_file->display);
|
||||
$this->assertIdentical('1', $node->field_images->target_id);
|
||||
$this->assertIdentical('alt text', $node->field_images->alt);
|
||||
$this->assertIdentical('title text', $node->field_images->title);
|
||||
$this->assertIdentical('93', $node->field_images->width);
|
||||
$this->assertIdentical('93', $node->field_images->height);
|
||||
$this->assertIdentical('http://google.com', $node->field_link->uri);
|
||||
$this->assertIdentical('Click Here', $node->field_link->title);
|
||||
$this->assertEquals('1', $node->field_images->target_id);
|
||||
$this->assertEquals('alt text', $node->field_images->alt);
|
||||
$this->assertEquals('title text', $node->field_images->title);
|
||||
$this->assertEquals('93', $node->field_images->width);
|
||||
$this->assertEquals('93', $node->field_images->height);
|
||||
$this->assertEquals('http://google.com', $node->field_link->uri);
|
||||
$this->assertEquals('Click Here', $node->field_link->title);
|
||||
// Test that an email field is migrated.
|
||||
$this->assertSame('default@example.com', $node->field_email->value);
|
||||
$this->assertSame('another@example.com', $node->field_email[1]->value);
|
||||
$this->assertEquals('default@example.com', $node->field_email->value);
|
||||
$this->assertEquals('another@example.com', $node->field_email[1]->value);
|
||||
$this->assertEquals(CommentItemInterface::OPEN, $node->comment_node_test_content_type->status);
|
||||
|
||||
$node = Node::load(2);
|
||||
$this->assertSame('en', $node->langcode->value);
|
||||
$this->assertIdentical("...is that it's the absolute best show ever. Trust me, I would know.", $node->body->value);
|
||||
$this->assertSame('The thing about Deep Space 9', $node->label());
|
||||
$this->assertIdentical('internal:/', $node->field_link->uri);
|
||||
$this->assertIdentical('Home', $node->field_link->title);
|
||||
$this->assertEquals('en', $node->langcode->value);
|
||||
$this->assertEquals("...is that it's the absolute best show ever. Trust me, I would know.", $node->body->value);
|
||||
$this->assertEquals('The thing about Deep Space 9', $node->label());
|
||||
$this->assertEquals('internal:/', $node->field_link->uri);
|
||||
$this->assertEquals('Home', $node->field_link->title);
|
||||
$this->assertEquals(CommentItemInterface::OPEN, $node->comment_node_article->status);
|
||||
$this->assertTrue($node->hasTranslation('is'), "Node 2 has an Icelandic translation");
|
||||
|
||||
$translation = $node->getTranslation('is');
|
||||
$this->assertSame('is', $translation->langcode->value);
|
||||
$this->assertSame("is - ...is that it's the absolute best show ever. Trust me, I would know.", $translation->body->value);
|
||||
$this->assertSame('is - The thing about Deep Space 9', $translation->label());
|
||||
$this->assertSame('internal:/', $translation->field_link->uri);
|
||||
$this->assertSame('Home', $translation->field_link->title);
|
||||
$this->assertEquals('is', $translation->langcode->value);
|
||||
$this->assertEquals("is - ...is that it's the absolute best show ever. Trust me, I would know.", $translation->body->value);
|
||||
$this->assertEquals('is - The thing about Deep Space 9', $translation->label());
|
||||
$this->assertEquals('internal:/', $translation->field_link->uri);
|
||||
$this->assertEquals(CommentItemInterface::OPEN, $translation->comment_node_article->status);
|
||||
$this->assertEquals('Home', $translation->field_link->title);
|
||||
|
||||
// Test that content_translation_source is set.
|
||||
$manager = $this->container->get('content_translation.manager');
|
||||
$this->assertSame('en', $manager->getTranslationMetadata($node->getTranslation('is'))->getSource());
|
||||
$this->assertEquals('en', $manager->getTranslationMetadata($node->getTranslation('is'))->getSource());
|
||||
|
||||
// Node 3 is a translation of node 2, and should not be imported separately.
|
||||
$this->assertNull(Node::load(3), "Node 3 doesn't exist in D8, it was a translation");
|
||||
|
||||
// Test that content_translation_source for a source other than English.
|
||||
$node = Node::load(4);
|
||||
$this->assertSame('is', $manager->getTranslationMetadata($node->getTranslation('en'))->getSource());
|
||||
$this->assertEquals('is', $manager->getTranslationMetadata($node->getTranslation('en'))->getSource());
|
||||
$this->assertEquals(CommentItemInterface::CLOSED, $node->comment_node_article->status);
|
||||
|
||||
$translation = $node->getTranslation('en');
|
||||
$this->assertEquals(CommentItemInterface::CLOSED, $translation->comment_node_article->status);
|
||||
|
||||
$node = Node::load(6);
|
||||
$this->assertEquals(CommentItemInterface::CLOSED, $node->comment_forum->status);
|
||||
|
||||
$node = Node::load(7);
|
||||
$this->assertEquals(CommentItemInterface::OPEN, $node->comment_forum->status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Tests node translation redirections.
|
||||
*
|
||||
* @group migrate_drupal
|
||||
* @group node
|
||||
*/
|
||||
class NodeTranslationRedirectTest extends MigrateDrupal7TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'content_translation',
|
||||
'language',
|
||||
'menu_ui',
|
||||
'node',
|
||||
'text',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installConfig('node');
|
||||
$this->installSchema('node', ['node_access']);
|
||||
$this->installSchema('system', ['key_value']);
|
||||
|
||||
$this->executeMigrations([
|
||||
'language',
|
||||
'd7_language_types',
|
||||
'd7_language_negotiation_settings',
|
||||
'd7_user_role',
|
||||
'd7_user',
|
||||
'd7_node_type',
|
||||
'd7_node',
|
||||
'd7_node_translation',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that not found node translations are redirected.
|
||||
*/
|
||||
public function testNodeTranslationRedirect() {
|
||||
$kernel = $this->container->get('http_kernel');
|
||||
$request = Request::create('/node/3');
|
||||
$response = $kernel->handle($request);
|
||||
$this->assertSame(301, $response->getStatusCode());
|
||||
$this->assertSame('/node/2', $response->getTargetUrl());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -57,9 +57,139 @@ class NodeTypeTest extends MigrateSqlSourceTestBase {
|
||||
'orig_type' => 'story',
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['variable'] = [
|
||||
[
|
||||
'name' => 'comment_anonymous_page',
|
||||
'value' => 'i:0;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_anonymous_story',
|
||||
'value' => 'i:1;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_default_mode_page',
|
||||
'value' => 'i:0;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_default_mode_story',
|
||||
'value' => 'i:1;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_default_per_page_page',
|
||||
'value' => 's:2:"10";',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_default_per_page_story',
|
||||
'value' => 's:2:"20";',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_form_location_page',
|
||||
'value' => 'i:0;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_form_location_story',
|
||||
'value' => 'i:1;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_page',
|
||||
'value' => 's:1:"0";',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_preview_page',
|
||||
'value' => 's:1:"0";',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_preview_story',
|
||||
'value' => 's:1:"1";',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_story',
|
||||
'value' => 's:1:"1";',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_subject_field_page',
|
||||
'value' => 'i:0;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_subject_field_story',
|
||||
'value' => 'i:1;',
|
||||
],
|
||||
[
|
||||
'name' => 'node_options_page',
|
||||
'value' => 'a:1:{i:0;s:6:"status";}',
|
||||
],
|
||||
[
|
||||
'name' => 'node_options_story',
|
||||
'value' => 'a:1:{i:0;s:6:"status";}',
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['system'] = [
|
||||
[
|
||||
'type' => 'module',
|
||||
'name' => 'comment',
|
||||
'status' => '1',
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = $tests[0]['source_data']['node_type'];
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'type' => 'page',
|
||||
'name' => 'Page',
|
||||
'module' => 'node',
|
||||
'description' => 'A <em>page</em>, similar in form to a <em>story</em>, is a simple method for creating and displaying information that rarely changes, such as an "About us" section of a website. By default, a <em>page</em> entry does not allow visitor comments and is not featured on the site\'s initial home page.',
|
||||
'help' => '',
|
||||
'title_label' => 'Title',
|
||||
'has_body' => 1,
|
||||
'body_label' => 'Body',
|
||||
'min_word_count' => 0,
|
||||
'custom' => 1,
|
||||
'modified' => 0,
|
||||
'locked' => 0,
|
||||
'orig_type' => 'page',
|
||||
'options' => [
|
||||
'promote' => FALSE,
|
||||
'sticky' => FALSE,
|
||||
'status' => TRUE,
|
||||
'revision' => FALSE,
|
||||
],
|
||||
'comment' => 0,
|
||||
'comment_default_mode' => 0,
|
||||
'comment_default_per_page' => '10',
|
||||
'comment_anonymous' => 0,
|
||||
'comment_subject_field' => 0,
|
||||
'comment_preview' => 0,
|
||||
'comment_form_location' => 0,
|
||||
],
|
||||
[
|
||||
'type' => 'story',
|
||||
'name' => 'Story',
|
||||
'module' => 'node',
|
||||
'description' => 'A <em>story</em>, similar in form to a <em>page</em>, is ideal for creating and displaying content that informs or engages website visitors. Press releases, site announcements, and informal blog-like entries may all be created with a <em>story</em> entry. By default, a <em>story</em> entry is automatically featured on the site\'s initial home page, and provides the ability to post comments.',
|
||||
'help' => '',
|
||||
'title_label' => 'Title',
|
||||
'has_body' => 1,
|
||||
'body_label' => 'Body',
|
||||
'min_word_count' => 0,
|
||||
'custom' => 1,
|
||||
'modified' => 0,
|
||||
'locked' => 0,
|
||||
'orig_type' => 'story',
|
||||
'options' => [
|
||||
'promote' => FALSE,
|
||||
'sticky' => FALSE,
|
||||
'status' => TRUE,
|
||||
'revision' => FALSE,
|
||||
],
|
||||
'comment' => 1,
|
||||
'comment_default_mode' => 1,
|
||||
'comment_default_per_page' => '20',
|
||||
'comment_anonymous' => 1,
|
||||
'comment_subject_field' => 1,
|
||||
'comment_preview' => 1,
|
||||
'comment_form_location' => 1,
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,62 @@ class NodeTypeTest extends MigrateSqlSourceTestBase {
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['variable'] = [
|
||||
[
|
||||
'name' => 'comment_anonymous_page',
|
||||
'value' => 'i:0;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_anonymous_story',
|
||||
'value' => 'i:1;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_default_mode_page',
|
||||
'value' => 'i:0;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_default_mode_story',
|
||||
'value' => 'i:1;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_default_per_page_page',
|
||||
'value' => 's:2:"10";',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_default_per_page_story',
|
||||
'value' => 's:2:"20";',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_form_location_page',
|
||||
'value' => 'i:0;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_form_location_story',
|
||||
'value' => 'i:1;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_page',
|
||||
'value' => 's:1:"0";',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_preview_page',
|
||||
'value' => 's:1:"0";',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_preview_story',
|
||||
'value' => 's:1:"1";',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_story',
|
||||
'value' => 's:1:"1";',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_subject_field_page',
|
||||
'value' => 'i:0;',
|
||||
],
|
||||
[
|
||||
'name' => 'comment_subject_field_story',
|
||||
'value' => 'i:1;',
|
||||
],
|
||||
[
|
||||
'name' => 'node_options_page',
|
||||
'value' => 'a:1:{i:0;s:6:"status";}',
|
||||
@@ -77,9 +133,78 @@ class NodeTypeTest extends MigrateSqlSourceTestBase {
|
||||
'data' => 'a:1:{s:5:"label";s:4:"Body";}',
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['system'] = [
|
||||
[
|
||||
'type' => 'module',
|
||||
'name' => 'comment',
|
||||
'status' => '1',
|
||||
],
|
||||
[
|
||||
'type' => 'module',
|
||||
'name' => 'field',
|
||||
'status' => '1',
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = $tests[0]['source_data']['node_type'];
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'type' => 'page',
|
||||
'name' => 'Page',
|
||||
'base' => 'node',
|
||||
'description' => 'A <em>page</em>, similar in form to a <em>story</em>, is a simple method for creating and displaying information that rarely changes, such as an "About us" section of a website. By default, a <em>page</em> entry does not allow visitor comments and is not featured on the site\'s initial home page.',
|
||||
'help' => '',
|
||||
'title_label' => 'Title',
|
||||
'custom' => 1,
|
||||
'modified' => 0,
|
||||
'locked' => 0,
|
||||
'disabled' => 0,
|
||||
'orig_type' => 'page',
|
||||
'options' => [
|
||||
'promote' => FALSE,
|
||||
'sticky' => FALSE,
|
||||
'status' => TRUE,
|
||||
'revision' => FALSE,
|
||||
],
|
||||
'create_body' => TRUE,
|
||||
'body_label' => 'Body',
|
||||
'comment' => 0,
|
||||
'comment_default_mode' => 0,
|
||||
'comment_default_per_page' => '10',
|
||||
'comment_anonymous' => 0,
|
||||
'comment_subject_field' => 0,
|
||||
'comment_preview' => 0,
|
||||
'comment_form_location' => 0,
|
||||
],
|
||||
[
|
||||
'type' => 'story',
|
||||
'name' => 'Story',
|
||||
'base' => 'node',
|
||||
'description' => 'A <em>story</em>, similar in form to a <em>page</em>, is ideal for creating and displaying content that informs or engages website visitors. Press releases, site announcements, and informal blog-like entries may all be created with a <em>story</em> entry. By default, a <em>story</em> entry is automatically featured on the site\'s initial home page, and provides the ability to post comments.',
|
||||
'help' => '',
|
||||
'title_label' => 'Title',
|
||||
'custom' => 1,
|
||||
'modified' => 0,
|
||||
'locked' => 0,
|
||||
'disabled' => 0,
|
||||
'orig_type' => 'story',
|
||||
'options' => [
|
||||
'promote' => FALSE,
|
||||
'sticky' => FALSE,
|
||||
'status' => TRUE,
|
||||
'revision' => FALSE,
|
||||
],
|
||||
'create_body' => TRUE,
|
||||
'body_label' => 'Body',
|
||||
'comment' => 1,
|
||||
'comment_default_mode' => 1,
|
||||
'comment_default_per_page' => '20',
|
||||
'comment_anonymous' => 1,
|
||||
'comment_subject_field' => 1,
|
||||
'comment_preview' => 1,
|
||||
'comment_form_location' => 1,
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Traits;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Provides methods to create content type from given values.
|
||||
*
|
||||
* This trait is meant to be used only by test classes.
|
||||
*/
|
||||
trait ContentTypeCreationTrait {
|
||||
|
||||
/**
|
||||
* Creates a custom content type based on default settings.
|
||||
*
|
||||
* @param array $values
|
||||
* An array of settings to change from the defaults.
|
||||
* Example: 'type' => 'foo'.
|
||||
*
|
||||
* @return \Drupal\node\Entity\NodeType
|
||||
* Created content type.
|
||||
*/
|
||||
protected function createContentType(array $values = []) {
|
||||
// Find a non-existent random type name.
|
||||
if (!isset($values['type'])) {
|
||||
do {
|
||||
$id = strtolower($this->randomMachineName(8));
|
||||
} while (NodeType::load($id));
|
||||
}
|
||||
else {
|
||||
$id = $values['type'];
|
||||
}
|
||||
$values += [
|
||||
'type' => $id,
|
||||
'name' => $id,
|
||||
];
|
||||
$type = NodeType::create($values);
|
||||
$status = $type->save();
|
||||
node_add_body_field($type);
|
||||
|
||||
if ($this instanceof TestCase) {
|
||||
$this->assertSame($status, SAVED_NEW, (new FormattableMarkup('Created content type %type.', ['%type' => $type->id()]))->__toString());
|
||||
}
|
||||
else {
|
||||
$this->assertEqual($status, SAVED_NEW, (new FormattableMarkup('Created content type %type.', ['%type' => $type->id()]))->__toString());
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Traits;
|
||||
|
||||
use Drupal\node\Entity\Node;
|
||||
|
||||
/**
|
||||
* Provides methods to create node based on default settings.
|
||||
*
|
||||
* This trait is meant to be used only by test classes.
|
||||
*/
|
||||
trait NodeCreationTrait {
|
||||
|
||||
/**
|
||||
* Get a node from the database based on its title.
|
||||
*
|
||||
* @param string|\Drupal\Component\Render\MarkupInterface $title
|
||||
* A node title, usually generated by $this->randomMachineName().
|
||||
* @param $reset
|
||||
* (optional) Whether to reset the entity cache.
|
||||
*
|
||||
* @return \Drupal\node\NodeInterface
|
||||
* A node entity matching $title.
|
||||
*/
|
||||
public function getNodeByTitle($title, $reset = FALSE) {
|
||||
if ($reset) {
|
||||
\Drupal::entityTypeManager()->getStorage('node')->resetCache();
|
||||
}
|
||||
// Cast MarkupInterface objects to string.
|
||||
$title = (string) $title;
|
||||
$nodes = \Drupal::entityTypeManager()
|
||||
->getStorage('node')
|
||||
->loadByProperties(['title' => $title]);
|
||||
// Load the first node returned from the database.
|
||||
$returned_node = reset($nodes);
|
||||
return $returned_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a node based on default settings.
|
||||
*
|
||||
* @param array $settings
|
||||
* (optional) An associative array of settings for the node, as used in
|
||||
* entity_create(). Override the defaults by specifying the key and value
|
||||
* in the array, for example:
|
||||
* @code
|
||||
* $this->drupalCreateNode(array(
|
||||
* 'title' => t('Hello, world!'),
|
||||
* 'type' => 'article',
|
||||
* ));
|
||||
* @endcode
|
||||
* The following defaults are provided:
|
||||
* - body: Random string using the default filter format:
|
||||
* @code
|
||||
* $settings['body'][0] = array(
|
||||
* 'value' => $this->randomMachineName(32),
|
||||
* 'format' => filter_default_format(),
|
||||
* );
|
||||
* @endcode
|
||||
* - title: Random string.
|
||||
* - type: 'page'.
|
||||
* - uid: The currently logged in user, or anonymous.
|
||||
*
|
||||
* @return \Drupal\node\NodeInterface
|
||||
* The created node entity.
|
||||
*/
|
||||
protected function createNode(array $settings = []) {
|
||||
// Populate defaults array.
|
||||
$settings += [
|
||||
'body' => [
|
||||
[
|
||||
'value' => $this->randomMachineName(32),
|
||||
'format' => filter_default_format(),
|
||||
],
|
||||
],
|
||||
'title' => $this->randomMachineName(8),
|
||||
'type' => 'page',
|
||||
'uid' => \Drupal::currentUser()->id(),
|
||||
];
|
||||
$node = Node::create($settings);
|
||||
$node->save();
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user