updated core to 8.6.1 via composer
This commit is contained in:
@@ -6,5 +6,5 @@ dependencies:
|
||||
id: node_delete_action
|
||||
label: 'Delete content'
|
||||
type: node
|
||||
plugin: node_delete_action
|
||||
plugin: entity:delete_action:node
|
||||
configuration: { }
|
||||
|
||||
@@ -80,6 +80,8 @@ action.configuration.node_save_action:
|
||||
type: action_configuration_default
|
||||
label: 'Save content configuration'
|
||||
|
||||
# @deprecated in Drupal 8.6.x, to be removed before Drupal 9.0.0.
|
||||
# @see https://www.drupal.org/node/2934349
|
||||
action.configuration.node_delete_action:
|
||||
type: action_configuration_default
|
||||
label: 'Delete content configuration'
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Javascript for the node content editing form.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
(function($, Drupal) {
|
||||
/**
|
||||
* Behaviors for setting summaries on content type form.
|
||||
*
|
||||
@@ -16,38 +16,61 @@
|
||||
attach(context) {
|
||||
const $context = $(context);
|
||||
// Provide the vertical tab summaries.
|
||||
$context.find('#edit-submission').drupalSetSummary((context) => {
|
||||
$context.find('#edit-submission').drupalSetSummary(context => {
|
||||
const vals = [];
|
||||
vals.push(Drupal.checkPlain($(context).find('#edit-title-label').val()) || Drupal.t('Requires a title'));
|
||||
vals.push(
|
||||
Drupal.checkPlain(
|
||||
$(context)
|
||||
.find('#edit-title-label')
|
||||
.val(),
|
||||
) || Drupal.t('Requires a title'),
|
||||
);
|
||||
return vals.join(', ');
|
||||
});
|
||||
$context.find('#edit-workflow').drupalSetSummary((context) => {
|
||||
$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')) {
|
||||
$(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) => {
|
||||
$('#edit-language', context).drupalSetSummary(context => {
|
||||
const vals = [];
|
||||
|
||||
vals.push($('.js-form-item-language-configuration-langcode select option:selected', context).text());
|
||||
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()));
|
||||
});
|
||||
$('input:checked', context)
|
||||
.next('label')
|
||||
.each(function() {
|
||||
vals.push(Drupal.checkPlain($(this).text()));
|
||||
});
|
||||
|
||||
return vals.join(', ');
|
||||
});
|
||||
$context.find('#edit-display').drupalSetSummary((context) => {
|
||||
$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()));
|
||||
});
|
||||
$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"));
|
||||
}
|
||||
@@ -55,4 +78,4 @@
|
||||
});
|
||||
},
|
||||
};
|
||||
}(jQuery, Drupal));
|
||||
})(jQuery, Drupal);
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
id: d6_node_translation
|
||||
label: Node translations
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Content
|
||||
deriver: Drupal\node\Plugin\migrate\D6NodeDeriver
|
||||
source:
|
||||
plugin: d6_node
|
||||
translations: true
|
||||
process:
|
||||
# If you are using this file to build a custom migration consider removing
|
||||
# the nid field to allow incremental migrations.
|
||||
nid: tnid
|
||||
type: type
|
||||
langcode:
|
||||
plugin: default_value
|
||||
source: language
|
||||
default_value: "und"
|
||||
title: title
|
||||
uid: node_uid
|
||||
status: status
|
||||
created: created
|
||||
changed: changed
|
||||
promote: promote
|
||||
sticky: sticky
|
||||
'body/format':
|
||||
plugin: migration_lookup
|
||||
migration: d6_filter_format
|
||||
source: format
|
||||
'body/value': body
|
||||
'body/summary': teaser
|
||||
revision_uid: revision_uid
|
||||
revision_log: log
|
||||
revision_timestamp: timestamp
|
||||
content_translation_source: source_langcode
|
||||
|
||||
# unmapped d6 fields.
|
||||
# translate
|
||||
# moderate
|
||||
# comment
|
||||
|
||||
destination:
|
||||
plugin: entity:node
|
||||
translations: true
|
||||
destination_module: content_translation
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d6_user
|
||||
- d6_node_type
|
||||
- d6_node_settings
|
||||
- d6_filter_format
|
||||
- language
|
||||
optional:
|
||||
- d6_field_instance_widget_settings
|
||||
- d6_field_formatter_settings
|
||||
- d6_upload_field_instance
|
||||
@@ -0,0 +1,32 @@
|
||||
id: d7_node_entity_translation
|
||||
label: Node entity translations
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- translation
|
||||
- Content
|
||||
- Multilingual
|
||||
deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
|
||||
source:
|
||||
plugin: d7_node_entity_translation
|
||||
process:
|
||||
nid: entity_id
|
||||
type: type
|
||||
langcode: language
|
||||
title: title
|
||||
uid: uid
|
||||
status: status
|
||||
created: created
|
||||
changed: changed
|
||||
promote: promote
|
||||
sticky: sticky
|
||||
revision_uid: revision_uid
|
||||
revision_log: log
|
||||
revision_timestamp: timestamp
|
||||
content_translation_source: source
|
||||
destination:
|
||||
plugin: entity:node
|
||||
translations: true
|
||||
destination_module: content_translation
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d7_node
|
||||
@@ -1,43 +0,0 @@
|
||||
id: d7_node_translation
|
||||
label: Node translations
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- translation
|
||||
- Content
|
||||
deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
|
||||
source:
|
||||
plugin: d7_node
|
||||
translations: true
|
||||
process:
|
||||
# If you are using this file to build a custom migration consider removing
|
||||
# the nid field to allow incremental migrations.
|
||||
nid: tnid
|
||||
type: type
|
||||
langcode:
|
||||
plugin: default_value
|
||||
source: language
|
||||
default_value: "und"
|
||||
title: title
|
||||
uid: node_uid
|
||||
status: status
|
||||
created: created
|
||||
changed: changed
|
||||
promote: promote
|
||||
sticky: sticky
|
||||
revision_uid: revision_uid
|
||||
revision_log: log
|
||||
revision_timestamp: timestamp
|
||||
content_translation_source: source_langcode
|
||||
destination:
|
||||
plugin: entity:node
|
||||
translations: true
|
||||
content_translation_update_definitions:
|
||||
- node
|
||||
destination_module: content_translation
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d7_user
|
||||
- d7_node_type
|
||||
- language
|
||||
optional:
|
||||
- d7_field_instance
|
||||
@@ -35,7 +35,7 @@ function node_mass_update(array $nodes, array $updates, $langcode = NULL, $load
|
||||
if (count($nodes) > 10) {
|
||||
$batch = [
|
||||
'operations' => [
|
||||
['_node_mass_update_batch_process', [$nodes, $updates, $langcode, $load, $revisions]]
|
||||
['_node_mass_update_batch_process', [$nodes, $updates, $langcode, $load, $revisions]],
|
||||
],
|
||||
'finished' => '_node_mass_update_batch_finished',
|
||||
'title' => t('Processing'),
|
||||
@@ -60,7 +60,7 @@ function node_mass_update(array $nodes, array $updates, $langcode = NULL, $load
|
||||
}
|
||||
_node_mass_update_helper($node, $updates, $langcode);
|
||||
}
|
||||
drupal_set_message(t('The update has been performed.'));
|
||||
\Drupal::messenger()->addStatus(t('The update has been performed.'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,16 +164,16 @@ function _node_mass_update_batch_process(array $nodes, array $updates, $langcode
|
||||
*/
|
||||
function _node_mass_update_batch_finished($success, $results, $operations) {
|
||||
if ($success) {
|
||||
drupal_set_message(t('The update has been performed.'));
|
||||
\Drupal::messenger()->addStatus(t('The update has been performed.'));
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('An error occurred and processing did not complete.'), 'error');
|
||||
\Drupal::messenger()->addError(t('An error occurred and processing did not complete.'));
|
||||
$message = \Drupal::translation()->formatPlural(count($results), '1 item successfully processed:', '@count items successfully processed:');
|
||||
$item_list = [
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $results,
|
||||
];
|
||||
$message .= \Drupal::service('renderer')->render($item_list);
|
||||
drupal_set_message($message);
|
||||
\Drupal::messenger()->addStatus($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ function hook_node_access_records(\Drupal\node\NodeInterface $node) {
|
||||
'grant_view' => 1,
|
||||
'grant_update' => 0,
|
||||
'grant_delete' => 0,
|
||||
'langcode' => 'ca'
|
||||
'langcode' => 'ca',
|
||||
];
|
||||
}
|
||||
// For the example_author array, the GID is equivalent to a UID, which
|
||||
@@ -183,7 +183,7 @@ function hook_node_access_records(\Drupal\node\NodeInterface $node) {
|
||||
'grant_view' => 1,
|
||||
'grant_update' => 1,
|
||||
'grant_delete' => 1,
|
||||
'langcode' => 'ca'
|
||||
'langcode' => 'ca',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -297,11 +297,17 @@ function hook_node_grants_alter(&$grants, \Drupal\Core\Session\AccountInterface
|
||||
* permission may always view and edit content through the administrative
|
||||
* interface.
|
||||
*
|
||||
* Note that not all modules will want to influence access on all node types. If
|
||||
* your module does not want to explicitly allow or forbid access, return an
|
||||
* AccessResultInterface object with neither isAllowed() nor isForbidden()
|
||||
* equaling TRUE. Blindly returning an object with isForbidden() equaling TRUE
|
||||
* will break other node access modules.
|
||||
* The access to a node can be influenced in several ways:
|
||||
* - To explicitly allow access, return an AccessResultInterface object with
|
||||
* isAllowed() returning TRUE. Other modules can override this access by
|
||||
* returning TRUE for isForbidden().
|
||||
* - To explicitly forbid access, return an AccessResultInterface object with
|
||||
* isForbidden() returning TRUE. Access will be forbidden even if your module
|
||||
* (or another module) also returns TRUE for isNeutral() or isAllowed().
|
||||
* - To neither allow nor explicitly forbid access, return an
|
||||
* AccessResultInterface object with isNeutral() returning TRUE.
|
||||
* - If your module does not return an AccessResultInterface object, neutral
|
||||
* access will be assumed.
|
||||
*
|
||||
* Also note that this function isn't called for node listings (e.g., RSS feeds,
|
||||
* the default home page at path 'node', a recent content block, etc.) See
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Defines Javascript behaviors for the node module.
|
||||
*/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
(function($, Drupal, drupalSettings) {
|
||||
/**
|
||||
* Behaviors for tabs in the node edit form.
|
||||
*
|
||||
@@ -16,30 +16,36 @@
|
||||
attach(context) {
|
||||
const $context = $(context);
|
||||
|
||||
$context.find('.node-form-author').drupalSetSummary((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 });
|
||||
return Drupal.t('By @name on @date', {
|
||||
'@name': name,
|
||||
'@date': date,
|
||||
});
|
||||
}
|
||||
else if (name) {
|
||||
if (name) {
|
||||
return Drupal.t('By @name', { '@name': name });
|
||||
}
|
||||
else if (date) {
|
||||
if (date) {
|
||||
return Drupal.t('Authored on @date', { '@date': date });
|
||||
}
|
||||
});
|
||||
|
||||
$context.find('.node-form-options').drupalSetSummary((context) => {
|
||||
$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())));
|
||||
});
|
||||
$optionsContext
|
||||
.find('input:checked')
|
||||
.next('label')
|
||||
.each(function() {
|
||||
vals.push(Drupal.checkPlain($.trim($(this).text())));
|
||||
});
|
||||
return vals.join(', ');
|
||||
}
|
||||
|
||||
@@ -47,4 +53,4 @@
|
||||
});
|
||||
},
|
||||
};
|
||||
}(jQuery, Drupal, drupalSettings));
|
||||
})(jQuery, Drupal, drupalSettings);
|
||||
|
||||
@@ -6,4 +6,4 @@ version: VERSION
|
||||
core: 8.x
|
||||
configure: entity.node_type.collection
|
||||
dependencies:
|
||||
- text
|
||||
- drupal:text
|
||||
|
||||
@@ -16,10 +16,15 @@
|
||||
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 on @date', {
|
||||
'@name': name,
|
||||
'@date': date
|
||||
});
|
||||
}
|
||||
if (name) {
|
||||
return Drupal.t('By @name', { '@name': name });
|
||||
} else if (date) {
|
||||
}
|
||||
if (date) {
|
||||
return Drupal.t('Authored on @date', { '@date': date });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -20,6 +20,7 @@ drupal.node.preview:
|
||||
- core/jquery
|
||||
- core/jquery.once
|
||||
- core/drupal
|
||||
- core/drupal.dialog
|
||||
- core/drupal.form
|
||||
|
||||
drupal.content_types:
|
||||
|
||||
@@ -104,7 +104,7 @@ function node_help($route_name, RouteMatchInterface $route_match) {
|
||||
else {
|
||||
$message = t('The content access permissions need to be rebuilt. <a href=":node_access_rebuild">Rebuild permissions</a>.', [':node_access_rebuild' => \Drupal::url('node.configure_rebuild_confirm')]);
|
||||
}
|
||||
drupal_set_message($message, 'error');
|
||||
\Drupal::messenger()->addError($message);
|
||||
}
|
||||
|
||||
switch ($route_name) {
|
||||
@@ -547,9 +547,12 @@ function template_preprocess_node_add_list(&$variables) {
|
||||
* Implements hook_preprocess_HOOK() for HTML document templates.
|
||||
*/
|
||||
function node_preprocess_html(&$variables) {
|
||||
// If on an individual node page, add the node type to body classes.
|
||||
if (($node = \Drupal::routeMatch()->getParameter('node')) && $node instanceof NodeInterface) {
|
||||
$variables['node_type'] = $node->getType();
|
||||
// If on an individual node page or node preview page, add the node type to
|
||||
// the body classes.
|
||||
if (($node = \Drupal::routeMatch()->getParameter('node')) || ($node = \Drupal::routeMatch()->getParameter('node_preview'))) {
|
||||
if ($node instanceof NodeInterface) {
|
||||
$variables['node_type'] = $node->getType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,7 +809,7 @@ function node_get_recent($number = 10) {
|
||||
* the global content language of the current request.
|
||||
*
|
||||
* @return array
|
||||
* An array as expected by drupal_render().
|
||||
* An array as expected by \Drupal\Core\Render\RendererInterface::render().
|
||||
*/
|
||||
function node_view(NodeInterface $node, $view_mode = 'full', $langcode = NULL) {
|
||||
return entity_view($node, $view_mode, $langcode);
|
||||
@@ -824,7 +827,8 @@ function node_view(NodeInterface $node, $view_mode = 'full', $langcode = NULL) {
|
||||
* content language of the current request.
|
||||
*
|
||||
* @return array
|
||||
* An array in the format expected by drupal_render().
|
||||
* An array in the format expected by
|
||||
* \Drupal\Core\Render\RendererInterface::render().
|
||||
*/
|
||||
function node_view_multiple($nodes, $view_mode = 'teaser', $langcode = NULL) {
|
||||
return entity_view_multiple($nodes, $view_mode, $langcode);
|
||||
@@ -840,7 +844,7 @@ function node_page_top(array &$page) {
|
||||
$page['page_top']['node_preview'] = [
|
||||
'#type' => 'container',
|
||||
'#attributes' => [
|
||||
'class' => ['node-preview-container', 'container-inline']
|
||||
'class' => ['node-preview-container', 'container-inline'],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -1034,7 +1038,6 @@ function node_access_view_all_nodes($account = NULL) {
|
||||
return $access[$account->id()];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_query_TAG_alter().
|
||||
*
|
||||
@@ -1185,7 +1188,7 @@ function node_access_rebuild($batch_mode = FALSE) {
|
||||
'operations' => [
|
||||
['_node_access_rebuild_batch_operation', []],
|
||||
],
|
||||
'finished' => '_node_access_rebuild_batch_finished'
|
||||
'finished' => '_node_access_rebuild_batch_finished',
|
||||
];
|
||||
batch_set($batch);
|
||||
}
|
||||
@@ -1221,7 +1224,7 @@ function node_access_rebuild($batch_mode = FALSE) {
|
||||
}
|
||||
|
||||
if (!isset($batch)) {
|
||||
drupal_set_message(t('Content permissions have been rebuilt.'));
|
||||
\Drupal::messenger()->addStatus(t('Content permissions have been rebuilt.'));
|
||||
node_access_needs_rebuild(FALSE);
|
||||
}
|
||||
}
|
||||
@@ -1294,11 +1297,11 @@ function _node_access_rebuild_batch_operation(&$context) {
|
||||
*/
|
||||
function _node_access_rebuild_batch_finished($success, $results, $operations) {
|
||||
if ($success) {
|
||||
drupal_set_message(t('The content access permissions have been rebuilt.'));
|
||||
\Drupal::messenger()->addStatus(t('The content access permissions have been rebuilt.'));
|
||||
node_access_needs_rebuild(FALSE);
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('The content access permissions have not been properly rebuilt.'), 'error');
|
||||
\Drupal::messenger()->addError(t('The content access permissions have not been properly rebuilt.'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Preview behaviors.
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
(function($, Drupal) {
|
||||
/**
|
||||
* Disables all non-relevant links in node previews.
|
||||
*
|
||||
@@ -23,9 +23,17 @@
|
||||
// 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) {
|
||||
if (
|
||||
event.button === 0 &&
|
||||
!event.altKey &&
|
||||
!event.ctrlKey &&
|
||||
!event.metaKey &&
|
||||
!event.shiftKey
|
||||
) {
|
||||
event.preventDefault();
|
||||
const $previewDialog = $(`<div>${Drupal.theme('nodePreviewModal')}</div>`).appendTo('body');
|
||||
const $previewDialog = $(
|
||||
`<div>${Drupal.theme('nodePreviewModal')}</div>`,
|
||||
).appendTo('body');
|
||||
Drupal.dialog($previewDialog, {
|
||||
title: Drupal.t('Leave preview?'),
|
||||
buttons: [
|
||||
@@ -34,7 +42,8 @@
|
||||
click() {
|
||||
$(this).dialog('close');
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
text: Drupal.t('Leave preview'),
|
||||
click() {
|
||||
window.top.location.href = event.target.href;
|
||||
@@ -45,14 +54,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
const $preview = $(context).find('.content').once('node-preview');
|
||||
const $preview = $(context).once('node-preview');
|
||||
if ($(context).find('.node-preview-container').length) {
|
||||
$preview.on('click.preview', 'a:not([href^=#], #edit-backlink, #toolbar-administration a)', clickPreviewModal);
|
||||
$preview.on(
|
||||
'click.preview',
|
||||
'a:not([href^="#"], .node-preview-container a)',
|
||||
clickPreviewModal,
|
||||
);
|
||||
}
|
||||
},
|
||||
detach(context, settings, trigger) {
|
||||
if (trigger === 'unload') {
|
||||
const $preview = $(context).find('.content').removeOnce('node-preview');
|
||||
const $preview = $(context)
|
||||
.find('.content')
|
||||
.removeOnce('node-preview');
|
||||
if ($preview.length) {
|
||||
$preview.off('click.preview');
|
||||
}
|
||||
@@ -70,9 +85,11 @@
|
||||
*/
|
||||
Drupal.behaviors.nodePreviewSwitchViewMode = {
|
||||
attach(context) {
|
||||
const $autosubmit = $(context).find('[data-drupal-autosubmit]').once('autosubmit');
|
||||
const $autosubmit = $(context)
|
||||
.find('[data-drupal-autosubmit]')
|
||||
.once('autosubmit');
|
||||
if ($autosubmit.length) {
|
||||
$autosubmit.on('formUpdated.preview', function () {
|
||||
$autosubmit.on('formUpdated.preview', function() {
|
||||
$(this.form).trigger('submit');
|
||||
});
|
||||
}
|
||||
@@ -85,10 +102,11 @@
|
||||
* @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>`;
|
||||
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));
|
||||
})(jQuery, Drupal);
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
var $preview = $(context).find('.content').once('node-preview');
|
||||
var $preview = $(context).once('node-preview');
|
||||
if ($(context).find('.node-preview-container').length) {
|
||||
$preview.on('click.preview', 'a:not([href^=#], #edit-backlink, #toolbar-administration a)', clickPreviewModal);
|
||||
$preview.on('click.preview', 'a:not([href^="#"], .node-preview-container a)', clickPreviewModal);
|
||||
}
|
||||
},
|
||||
detach: function detach(context, settings, trigger) {
|
||||
|
||||
@@ -2,8 +2,17 @@ node.multiple_delete_confirm:
|
||||
path: '/admin/content/node/delete'
|
||||
defaults:
|
||||
_form: '\Drupal\node\Form\DeleteMultiple'
|
||||
entity_type_id: 'node'
|
||||
requirements:
|
||||
_permission: 'administer nodes'
|
||||
_entity_delete_multiple_access: 'node'
|
||||
|
||||
entity.node.delete_multiple_form:
|
||||
path: '/admin/content/node/delete'
|
||||
defaults:
|
||||
_form: '\Drupal\node\Form\DeleteMultiple'
|
||||
entity_type_id: 'node'
|
||||
requirements:
|
||||
_entity_delete_multiple_access: 'node'
|
||||
|
||||
node.add_page:
|
||||
path: '/node/add'
|
||||
|
||||
@@ -4,8 +4,9 @@ namespace Drupal\node\ContextProvider;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Plugin\Context\Context;
|
||||
use Drupal\Core\Plugin\Context\ContextDefinition;
|
||||
use Drupal\Core\Plugin\Context\ContextProviderInterface;
|
||||
use Drupal\Core\Plugin\Context\EntityContext;
|
||||
use Drupal\Core\Plugin\Context\EntityContextDefinition;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
@@ -39,7 +40,7 @@ class NodeRouteContext implements ContextProviderInterface {
|
||||
*/
|
||||
public function getRuntimeContexts(array $unqualified_context_ids) {
|
||||
$result = [];
|
||||
$context_definition = new ContextDefinition('entity:node', NULL, FALSE);
|
||||
$context_definition = EntityContextDefinition::create('node')->setRequired(FALSE);
|
||||
$value = NULL;
|
||||
if (($route_object = $this->routeMatch->getRouteObject()) && ($route_contexts = $route_object->getOption('parameters')) && isset($route_contexts['node'])) {
|
||||
if ($node = $this->routeMatch->getParameter('node')) {
|
||||
@@ -65,7 +66,7 @@ class NodeRouteContext implements ContextProviderInterface {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAvailableContexts() {
|
||||
$context = new Context(new ContextDefinition('entity:node', $this->t('Node from URL')));
|
||||
$context = EntityContext::fromEntityTypeId('node', $this->t('Node from URL'));
|
||||
return ['node' => $context];
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
|
||||
* The node revision ID.
|
||||
*
|
||||
* @return array
|
||||
* An array suitable for drupal_render().
|
||||
* An array suitable for \Drupal\Core\Render\RendererInterface::render().
|
||||
*/
|
||||
public function revisionShow($node_revision) {
|
||||
$node = $this->entityManager()->getStorage('node')->loadRevision($node_revision);
|
||||
@@ -154,7 +154,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
|
||||
* A node object.
|
||||
*
|
||||
* @return array
|
||||
* An array as expected by drupal_render().
|
||||
* An array as expected by \Drupal\Core\Render\RendererInterface::render().
|
||||
*/
|
||||
public function revisionOverview(NodeInterface $node) {
|
||||
$account = $this->currentUser();
|
||||
|
||||
@@ -33,7 +33,8 @@ use Drupal\user\UserInterface;
|
||||
* "form" = {
|
||||
* "default" = "Drupal\node\NodeForm",
|
||||
* "delete" = "Drupal\node\Form\NodeDeleteForm",
|
||||
* "edit" = "Drupal\node\NodeForm"
|
||||
* "edit" = "Drupal\node\NodeForm",
|
||||
* "delete-multiple-confirm" = "Drupal\node\Form\DeleteMultiple"
|
||||
* },
|
||||
* "route_provider" = {
|
||||
* "html" = "Drupal\node\Entity\NodeRouteProvider",
|
||||
@@ -71,6 +72,7 @@ use Drupal\user\UserInterface;
|
||||
* links = {
|
||||
* "canonical" = "/node/{node}",
|
||||
* "delete-form" = "/node/{node}/delete",
|
||||
* "delete-multiple-form" = "/admin/content/node/delete",
|
||||
* "edit-form" = "/node/{node}/edit",
|
||||
* "version-history" = "/node/{node}/revisions",
|
||||
* "revision" = "/node/{node}/revisions/{node_revision}/view",
|
||||
@@ -210,7 +212,6 @@ class Node extends EditorialContentEntityBase implements NodeInterface {
|
||||
return $this->get('created')->value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -12,6 +12,13 @@ use Drupal\node\NodeTypeInterface;
|
||||
* @ConfigEntityType(
|
||||
* id = "node_type",
|
||||
* label = @Translation("Content type"),
|
||||
* label_collection = @Translation("Content types"),
|
||||
* label_singular = @Translation("content type"),
|
||||
* label_plural = @Translation("content types"),
|
||||
* label_count = @PluralTranslation(
|
||||
* singular = "@count content type",
|
||||
* plural = "@count content types",
|
||||
* ),
|
||||
* handlers = {
|
||||
* "access" = "Drupal\node\NodeTypeAccessControlHandler",
|
||||
* "form" = {
|
||||
@@ -179,7 +186,7 @@ class NodeType extends ConfigEntityBundleBase implements NodeTypeInterface {
|
||||
if ($update && $this->getOriginalId() != $this->id()) {
|
||||
$update_count = node_type_update_nodes($this->getOriginalId(), $this->id());
|
||||
if ($update_count) {
|
||||
drupal_set_message(\Drupal::translation()->formatPlural($update_count,
|
||||
\Drupal::messenger()->addStatus(\Drupal::translation()->formatPlural($update_count,
|
||||
'Changed the content type of 1 post from %old-type to %type.',
|
||||
'Changed the content type of @count posts from %old-type to %type.',
|
||||
[
|
||||
|
||||
@@ -2,78 +2,15 @@
|
||||
|
||||
namespace Drupal\node\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Entity\Form\DeleteMultipleForm as EntityDeleteMultipleForm;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Core\TempStore\PrivateTempStoreFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
|
||||
/**
|
||||
* Provides a node deletion confirmation form.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class DeleteMultiple extends ConfirmFormBase {
|
||||
|
||||
/**
|
||||
* The array of nodes to delete.
|
||||
*
|
||||
* @var string[][]
|
||||
*/
|
||||
protected $nodeInfo = [];
|
||||
|
||||
/**
|
||||
* The tempstore factory.
|
||||
*
|
||||
* @var \Drupal\Core\TempStore\PrivateTempStoreFactory
|
||||
*/
|
||||
protected $tempStoreFactory;
|
||||
|
||||
/**
|
||||
* The node storage.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityStorageInterface
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* Constructs a DeleteMultiple form object.
|
||||
*
|
||||
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
|
||||
* The tempstore factory.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $manager
|
||||
* The entity manager.
|
||||
*/
|
||||
public function __construct(PrivateTempStoreFactory $temp_store_factory, EntityManagerInterface $manager) {
|
||||
$this->tempStoreFactory = $temp_store_factory;
|
||||
$this->storage = $manager->getStorage('node');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('tempstore.private'),
|
||||
$container->get('entity.manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'node_multiple_delete_confirm';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return $this->formatPlural(count($this->nodeInfo), 'Are you sure you want to delete this item?', 'Are you sure you want to delete these items?');
|
||||
}
|
||||
class DeleteMultiple extends EntityDeleteMultipleForm {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -85,117 +22,15 @@ class DeleteMultiple extends ConfirmFormBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return t('Delete');
|
||||
protected function getDeletedMessage($count) {
|
||||
return $this->formatPlural($count, 'Deleted @count content item.', 'Deleted @count content items.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$this->nodeInfo = $this->tempStoreFactory->get('node_multiple_delete_confirm')->get(\Drupal::currentUser()->id());
|
||||
if (empty($this->nodeInfo)) {
|
||||
return new RedirectResponse($this->getCancelUrl()->setAbsolute()->toString());
|
||||
}
|
||||
/** @var \Drupal\node\NodeInterface[] $nodes */
|
||||
$nodes = $this->storage->loadMultiple(array_keys($this->nodeInfo));
|
||||
|
||||
$items = [];
|
||||
foreach ($this->nodeInfo as $id => $langcodes) {
|
||||
foreach ($langcodes as $langcode) {
|
||||
$node = $nodes[$id]->getTranslation($langcode);
|
||||
$key = $id . ':' . $langcode;
|
||||
$default_key = $id . ':' . $node->getUntranslated()->language()->getId();
|
||||
|
||||
// If we have a translated entity we build a nested list of translations
|
||||
// that will be deleted.
|
||||
$languages = $node->getTranslationLanguages();
|
||||
if (count($languages) > 1 && $node->isDefaultTranslation()) {
|
||||
$names = [];
|
||||
foreach ($languages as $translation_langcode => $language) {
|
||||
$names[] = $language->getName();
|
||||
unset($items[$id . ':' . $translation_langcode]);
|
||||
}
|
||||
$items[$default_key] = [
|
||||
'label' => [
|
||||
'#markup' => $this->t('@label (Original translation) - <em>The following content translations will be deleted:</em>', ['@label' => $node->label()]),
|
||||
],
|
||||
'deleted_translations' => [
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $names,
|
||||
],
|
||||
];
|
||||
}
|
||||
elseif (!isset($items[$default_key])) {
|
||||
$items[$key] = $node->label();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$form['nodes'] = [
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $items,
|
||||
];
|
||||
$form = parent::buildForm($form, $form_state);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
if ($form_state->getValue('confirm') && !empty($this->nodeInfo)) {
|
||||
$total_count = 0;
|
||||
$delete_nodes = [];
|
||||
/** @var \Drupal\Core\Entity\ContentEntityInterface[][] $delete_translations */
|
||||
$delete_translations = [];
|
||||
/** @var \Drupal\node\NodeInterface[] $nodes */
|
||||
$nodes = $this->storage->loadMultiple(array_keys($this->nodeInfo));
|
||||
|
||||
foreach ($this->nodeInfo as $id => $langcodes) {
|
||||
foreach ($langcodes as $langcode) {
|
||||
$node = $nodes[$id]->getTranslation($langcode);
|
||||
if ($node->isDefaultTranslation()) {
|
||||
$delete_nodes[$id] = $node;
|
||||
unset($delete_translations[$id]);
|
||||
$total_count += count($node->getTranslationLanguages());
|
||||
}
|
||||
elseif (!isset($delete_nodes[$id])) {
|
||||
$delete_translations[$id][] = $node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($delete_nodes) {
|
||||
$this->storage->delete($delete_nodes);
|
||||
$this->logger('content')->notice('Deleted @count posts.', ['@count' => count($delete_nodes)]);
|
||||
}
|
||||
|
||||
if ($delete_translations) {
|
||||
$count = 0;
|
||||
foreach ($delete_translations as $id => $translations) {
|
||||
$node = $nodes[$id]->getUntranslated();
|
||||
foreach ($translations as $translation) {
|
||||
$node->removeTranslation($translation->language()->getId());
|
||||
}
|
||||
$node->save();
|
||||
$count += count($translations);
|
||||
}
|
||||
if ($count) {
|
||||
$total_count += $count;
|
||||
$this->logger('content')->notice('Deleted @count content translations.', ['@count' => $count]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($total_count) {
|
||||
drupal_set_message($this->formatPlural($total_count, 'Deleted 1 post.', 'Deleted @count posts.'));
|
||||
}
|
||||
|
||||
$this->tempStoreFactory->get('node_multiple_delete_confirm')->delete(\Drupal::currentUser()->id());
|
||||
}
|
||||
|
||||
$form_state->setRedirect('system.admin_content');
|
||||
protected function getInaccessibleMessage($count) {
|
||||
return $this->formatPlural($count, "@count content item has not been deleted because you do not have the necessary permissions.", "@count content items have not been deleted because you do not have the necessary permissions.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ class NodePreviewForm extends FormBase {
|
||||
'#default_value' => $view_mode,
|
||||
'#attributes' => [
|
||||
'data-drupal-autosubmit' => TRUE,
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
$form['submit'] = [
|
||||
|
||||
@@ -118,7 +118,12 @@ class NodeRevisionDeleteForm extends ConfirmFormBase {
|
||||
|
||||
$this->logger('content')->notice('@type: deleted %title revision %revision.', ['@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]);
|
||||
$node_type = $this->nodeTypeStorage->load($this->revision->bundle())->label();
|
||||
drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', ['%revision-date' => format_date($this->revision->getRevisionCreationTime()), '@type' => $node_type, '%title' => $this->revision->label()]));
|
||||
$this->messenger()
|
||||
->addStatus($this->t('Revision from %revision-date of @type %title has been deleted.', [
|
||||
'%revision-date' => format_date($this->revision->getRevisionCreationTime()),
|
||||
'@type' => $node_type,
|
||||
'%title' => $this->revision->label(),
|
||||
]));
|
||||
$form_state->setRedirect(
|
||||
'entity.node.canonical',
|
||||
['node' => $this->revision->id()]
|
||||
|
||||
@@ -128,12 +128,18 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
|
||||
|
||||
$this->revision = $this->prepareRevertedRevision($this->revision, $form_state);
|
||||
$this->revision->revision_log = t('Copy of the revision from %date.', ['%date' => $this->dateFormatter->format($original_revision_timestamp)]);
|
||||
$this->revision->setRevisionUserId($this->currentUser()->id());
|
||||
$this->revision->setRevisionCreationTime($this->time->getRequestTime());
|
||||
$this->revision->setChangedTime($this->time->getRequestTime());
|
||||
$this->revision->save();
|
||||
|
||||
$this->logger('content')->notice('@type: reverted %title revision %revision.', ['@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]);
|
||||
drupal_set_message(t('@type %title has been reverted to the revision from %revision-date.', ['@type' => node_get_type_label($this->revision), '%title' => $this->revision->label(), '%revision-date' => $this->dateFormatter->format($original_revision_timestamp)]));
|
||||
$this->messenger()
|
||||
->addStatus($this->t('@type %title has been reverted to the revision from %revision-date.', [
|
||||
'@type' => node_get_type_label($this->revision),
|
||||
'%title' => $this->revision->label(),
|
||||
'%revision-date' => $this->dateFormatter->format($original_revision_timestamp),
|
||||
]));
|
||||
$form_state->setRedirect(
|
||||
'entity.node.version_history',
|
||||
['node' => $this->revision->id()]
|
||||
|
||||
@@ -50,7 +50,6 @@ class NodeAccessControlHandler extends EntityAccessControlHandler implements Nod
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Drupal\node;
|
||||
|
||||
use Drupal\Component\Datetime\TimeInterface;
|
||||
use Drupal\Core\Entity\ContentEntityForm;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityRepositoryInterface;
|
||||
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
@@ -35,8 +35,8 @@ class NodeForm extends ContentEntityForm {
|
||||
/**
|
||||
* Constructs a NodeForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
|
||||
* The entity repository.
|
||||
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
|
||||
* The factory for the temp store object.
|
||||
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
|
||||
@@ -46,8 +46,8 @@ class NodeForm extends ContentEntityForm {
|
||||
* @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, AccountInterface $current_user) {
|
||||
parent::__construct($entity_manager, $entity_type_bundle_info, $time);
|
||||
public function __construct(EntityRepositoryInterface $entity_repository, PrivateTempStoreFactory $temp_store_factory, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, TimeInterface $time = NULL, AccountInterface $current_user) {
|
||||
parent::__construct($entity_repository, $entity_type_bundle_info, $time);
|
||||
$this->tempStoreFactory = $temp_store_factory;
|
||||
$this->currentUser = $current_user;
|
||||
}
|
||||
@@ -57,7 +57,7 @@ class NodeForm extends ContentEntityForm {
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager'),
|
||||
$container->get('entity.repository'),
|
||||
$container->get('tempstore.private'),
|
||||
$container->get('entity_type.bundle.info'),
|
||||
$container->get('datetime.time'),
|
||||
@@ -102,7 +102,7 @@ class NodeForm extends ContentEntityForm {
|
||||
if ($this->operation == 'edit') {
|
||||
$form['#title'] = $this->t('<em>Edit @type</em> @title', [
|
||||
'@type' => node_get_type_label($node),
|
||||
'@title' => $node->label()
|
||||
'@title' => $node->label(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ class NodeForm extends ContentEntityForm {
|
||||
public function updateStatus($entity_type_id, NodeInterface $node, array $form, FormStateInterface $form_state) {
|
||||
$element = $form_state->getTriggeringElement();
|
||||
if (isset($element['#published_status'])) {
|
||||
$node->setPublished($element['#published_status']);
|
||||
$element['#published_status'] ? $node->setPublished() : $node->setUnpublished();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,11 +285,11 @@ class NodeForm extends ContentEntityForm {
|
||||
|
||||
if ($insert) {
|
||||
$this->logger('content')->notice('@type: added %title.', $context);
|
||||
drupal_set_message(t('@type %title has been created.', $t_args));
|
||||
$this->messenger()->addStatus($this->t('@type %title has been created.', $t_args));
|
||||
}
|
||||
else {
|
||||
$this->logger('content')->notice('@type: updated %title.', $context);
|
||||
drupal_set_message(t('@type %title has been updated.', $t_args));
|
||||
$this->messenger()->addStatus($this->t('@type %title has been updated.', $t_args));
|
||||
}
|
||||
|
||||
if ($node->id()) {
|
||||
@@ -312,7 +312,7 @@ class NodeForm extends ContentEntityForm {
|
||||
else {
|
||||
// In the unlikely case something went wrong on save, the node will be
|
||||
// rebuilt and node form redisplayed the same way as in preview.
|
||||
drupal_set_message(t('The post could not be saved.'), 'error');
|
||||
$this->messenger()->addError($this->t('The post could not be saved.'));
|
||||
$form_state->setRebuild();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class NodeStorage extends SqlContentEntityStorage implements NodeStorageInterfac
|
||||
*/
|
||||
public function revisionIds(NodeInterface $node) {
|
||||
return $this->database->query(
|
||||
'SELECT vid FROM {node_revision} WHERE nid=:nid ORDER BY vid',
|
||||
'SELECT vid FROM {' . $this->getRevisionTable() . '} WHERE nid=:nid ORDER BY vid',
|
||||
[':nid' => $node->id()]
|
||||
)->fetchCol();
|
||||
}
|
||||
@@ -29,7 +29,7 @@ class NodeStorage extends SqlContentEntityStorage implements NodeStorageInterfac
|
||||
*/
|
||||
public function userRevisionIds(AccountInterface $account) {
|
||||
return $this->database->query(
|
||||
'SELECT vid FROM {node_field_revision} WHERE uid = :uid ORDER BY vid',
|
||||
'SELECT vid FROM {' . $this->getRevisionDataTable() . '} WHERE uid = :uid ORDER BY vid',
|
||||
[':uid' => $account->id()]
|
||||
)->fetchCol();
|
||||
}
|
||||
@@ -38,14 +38,14 @@ class NodeStorage extends SqlContentEntityStorage implements NodeStorageInterfac
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function countDefaultLanguageRevisions(NodeInterface $node) {
|
||||
return $this->database->query('SELECT COUNT(*) FROM {node_field_revision} WHERE nid = :nid AND default_langcode = 1', [':nid' => $node->id()])->fetchField();
|
||||
return $this->database->query('SELECT COUNT(*) FROM {' . $this->getRevisionDataTable() . '} WHERE nid = :nid AND default_langcode = 1', [':nid' => $node->id()])->fetchField();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function updateType($old_type, $new_type) {
|
||||
return $this->database->update('node')
|
||||
return $this->database->update($this->getBaseTable())
|
||||
->fields(['type' => $new_type])
|
||||
->condition('type', $old_type)
|
||||
->execute();
|
||||
@@ -55,7 +55,7 @@ class NodeStorage extends SqlContentEntityStorage implements NodeStorageInterfac
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clearRevisionsLanguage(LanguageInterface $language) {
|
||||
return $this->database->update('node_revision')
|
||||
return $this->database->update($this->getRevisionTable())
|
||||
->fields(['langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED])
|
||||
->condition('langcode', $language->getId())
|
||||
->execute();
|
||||
|
||||
@@ -17,10 +17,12 @@ class NodeStorageSchema extends SqlContentEntityStorageSchema {
|
||||
protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) {
|
||||
$schema = parent::getEntitySchema($entity_type, $reset);
|
||||
|
||||
$schema['node_field_data']['indexes'] += [
|
||||
'node__frontpage' => ['promote', 'status', 'sticky', 'created'],
|
||||
'node__title_type' => ['title', ['type', 4]],
|
||||
];
|
||||
if ($data_table = $this->storage->getDataTable()) {
|
||||
$schema[$data_table]['indexes'] += [
|
||||
'node__frontpage' => ['promote', 'status', 'sticky', 'created'],
|
||||
'node__title_type' => ['title', ['type', 4]],
|
||||
];
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ class NodeTypeForm extends BundleEntityFormBase {
|
||||
DRUPAL_REQUIRED => t('Required'),
|
||||
],
|
||||
];
|
||||
$form['submission']['help'] = [
|
||||
$form['submission']['help'] = [
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Explanation or submission guidelines'),
|
||||
'#default_value' => $type->getHelp(),
|
||||
@@ -225,11 +225,11 @@ class NodeTypeForm extends BundleEntityFormBase {
|
||||
$t_args = ['%name' => $type->label()];
|
||||
|
||||
if ($status == SAVED_UPDATED) {
|
||||
drupal_set_message(t('The content type %name has been updated.', $t_args));
|
||||
$this->messenger()->addStatus($this->t('The content type %name has been updated.', $t_args));
|
||||
}
|
||||
elseif ($status == SAVED_NEW) {
|
||||
node_add_body_field($type);
|
||||
drupal_set_message(t('The content type %name has been added.', $t_args));
|
||||
$this->messenger()->addStatus($this->t('The content type %name has been added.', $t_args));
|
||||
$context = array_merge($t_args, ['link' => $type->link($this->t('View'), 'collection')]);
|
||||
$this->logger('node')->notice('Added content type %name.', $context);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class NodeTypeListBuilder extends ConfigEntityListBuilder {
|
||||
public function render() {
|
||||
$build = parent::render();
|
||||
$build['table']['#empty'] = $this->t('No content types available. <a href=":link">Add content type</a>.', [
|
||||
':link' => Url::fromRoute('node.type_add')->toString()
|
||||
':link' => Url::fromRoute('node.type_add')->toString(),
|
||||
]);
|
||||
return $build;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class NodeViewBuilder extends EntityViewBuilder {
|
||||
'#title' => t('Language'),
|
||||
'#markup' => $entity->language()->getName(),
|
||||
'#prefix' => '<div id="field-language-display">',
|
||||
'#suffix' => '</div>'
|
||||
'#suffix' => '</div>',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +280,7 @@ class NodeViewsData extends EntityViewsData {
|
||||
|
||||
// Define the base group of this table. Fields that don't have a group defined
|
||||
// will go into this field by default.
|
||||
$data['node_access']['table']['group'] = $this->t('Content access');
|
||||
$data['node_access']['table']['group'] = $this->t('Content access');
|
||||
|
||||
// For other base tables, explain how we join.
|
||||
$data['node_access']['table']['join'] = [
|
||||
@@ -322,7 +322,7 @@ class NodeViewsData extends EntityViewsData {
|
||||
'field' => 'sid',
|
||||
'table' => 'search_index',
|
||||
'extra' => "node_search_index.type = 'node_search' AND node_search_index.langcode = node_field_data.langcode",
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
$data['node_search_total']['table']['join'] = [
|
||||
|
||||
@@ -2,98 +2,33 @@
|
||||
|
||||
namespace Drupal\node\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Action\ActionBase;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Action\Plugin\Action\DeleteAction;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\TempStore\PrivateTempStoreFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Redirects to a node deletion form.
|
||||
*
|
||||
* @deprecated in Drupal 8.6.x, to be removed before Drupal 9.0.0.
|
||||
* Use \Drupal\Core\Action\Plugin\Action\DeleteAction instead.
|
||||
*
|
||||
* @see \Drupal\Core\Action\Plugin\Action\DeleteAction
|
||||
* @see https://www.drupal.org/node/2934349
|
||||
*
|
||||
* @Action(
|
||||
* id = "node_delete_action",
|
||||
* label = @Translation("Delete content"),
|
||||
* type = "node",
|
||||
* confirm_form_route_name = "node.multiple_delete_confirm"
|
||||
* label = @Translation("Delete content")
|
||||
* )
|
||||
*/
|
||||
class DeleteNode extends ActionBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The tempstore object.
|
||||
*
|
||||
* @var \Drupal\Core\TempStore\SharedTempStore
|
||||
*/
|
||||
protected $tempStore;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* Constructs a new DeleteNode object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin ID for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
|
||||
* The tempstore factory.
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* Current user.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
|
||||
$this->currentUser = $current_user;
|
||||
$this->tempStore = $temp_store_factory->get('node_multiple_delete_confirm');
|
||||
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
}
|
||||
class DeleteNode extends DeleteAction {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('tempstore.private'),
|
||||
$container->get('current_user')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function executeMultiple(array $entities) {
|
||||
$info = [];
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
foreach ($entities as $node) {
|
||||
$langcode = $node->language()->getId();
|
||||
$info[$node->id()][$langcode] = $langcode;
|
||||
}
|
||||
$this->tempStore->set($this->currentUser->id(), $info);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($object = NULL) {
|
||||
$this->executeMultiple([$object]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
/** @var \Drupal\node\NodeInterface $object */
|
||||
return $object->access('delete', $account, $return_as_object);
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $temp_store_factory, $current_user);
|
||||
@trigger_error(__NAMESPACE__ . '\DeleteNode is deprecated in Drupal 8.6.x, will be removed before Drupal 9.0.0. Use \Drupal\Core\Action\Plugin\Action\DeleteAction instead. See https://www.drupal.org/node/2934349.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class UnpublishByKeywordNode extends ConfigurableActionBase {
|
||||
foreach ($this->configuration['keywords'] as $keyword) {
|
||||
$elements = node_view(clone $node);
|
||||
if (strpos(\Drupal::service('renderer')->render($elements), $keyword) !== FALSE || strpos($node->label(), $keyword) !== FALSE) {
|
||||
$node->setPublished(FALSE);
|
||||
$node->setUnpublished();
|
||||
$node->save();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class NodeSelection extends DefaultSelection {
|
||||
|
||||
// In order to create a referenceable node, it needs to published.
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
$node->setPublished(TRUE);
|
||||
$node->setPublished();
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Access\AccessibleInterface;
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
@@ -114,6 +115,13 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
|
||||
*/
|
||||
const ADVANCED_FORM = 'advanced-form';
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -128,6 +136,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
|
||||
$container->get('config.factory')->get('search.settings'),
|
||||
$container->get('language_manager'),
|
||||
$container->get('renderer'),
|
||||
$container->get('messenger'),
|
||||
$container->get('current_user')
|
||||
);
|
||||
}
|
||||
@@ -153,16 +162,19 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
|
||||
* The language manager.
|
||||
* @param \Drupal\Core\Render\RendererInterface $renderer
|
||||
* The renderer.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The $account object to use for checking for access to advanced search.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, Config $search_settings, LanguageManagerInterface $language_manager, RendererInterface $renderer, AccountInterface $account = NULL) {
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, Config $search_settings, LanguageManagerInterface $language_manager, RendererInterface $renderer, MessengerInterface $messenger, AccountInterface $account = NULL) {
|
||||
$this->database = $database;
|
||||
$this->entityManager = $entity_manager;
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->searchSettings = $search_settings;
|
||||
$this->languageManager = $language_manager;
|
||||
$this->renderer = $renderer;
|
||||
$this->messenger = $messenger;
|
||||
$this->account = $account;
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
@@ -289,15 +301,15 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
|
||||
$status = $query->getStatus();
|
||||
|
||||
if ($status & SearchQuery::EXPRESSIONS_IGNORED) {
|
||||
drupal_set_message($this->t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', ['@count' => $this->searchSettings->get('and_or_limit')]), 'warning');
|
||||
$this->messenger->addWarning($this->t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', ['@count' => $this->searchSettings->get('and_or_limit')]));
|
||||
}
|
||||
|
||||
if ($status & SearchQuery::LOWER_CASE_OR) {
|
||||
drupal_set_message($this->t('Search for either of the two terms with uppercase <strong>OR</strong>. For example, <strong>cats OR dogs</strong>.'), 'warning');
|
||||
$this->messenger->addWarning($this->t('Search for either of the two terms with uppercase <strong>OR</strong>. For example, <strong>cats OR dogs</strong>.'));
|
||||
}
|
||||
|
||||
if ($status & SearchQuery::NO_POSITIVE_KEYWORDS) {
|
||||
drupal_set_message($this->formatPlural($this->searchSettings->get('index.minimum_word_size'), 'You must include at least one keyword to match in the content, and punctuation is ignored.', 'You must include at least one keyword to match in the content. Keywords must be at least @count characters, and punctuation is ignored.'), 'warning');
|
||||
$this->messenger->addWarning($this->formatPlural($this->searchSettings->get('index.minimum_word_size'), 'You must include at least one keyword to match in the content, and punctuation is ignored.', 'You must include at least one keyword to match in the content. Keywords must be at least @count characters, and punctuation is ignored.'));
|
||||
}
|
||||
|
||||
return $find;
|
||||
@@ -475,7 +487,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
|
||||
'#prefix' => '<h1>',
|
||||
'#plain_text' => $node->label(),
|
||||
'#suffix' => '</h1>',
|
||||
'#weight' => -1000
|
||||
'#weight' => -1000,
|
||||
];
|
||||
$text = $this->renderer->renderPlain($build);
|
||||
|
||||
@@ -781,7 +793,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
|
||||
'#open' => TRUE,
|
||||
];
|
||||
$form['content_ranking']['info'] = [
|
||||
'#markup' => '<p><em>' . $this->t('Influence is a numeric multiplier used in ordering search results. A higher number means the corresponding factor has more influence on search results; zero means the factor is ignored. Changing these numbers does not require the search index to be rebuilt. Changes take effect immediately.') . '</em></p>'
|
||||
'#markup' => '<p><em>' . $this->t('Influence is a numeric multiplier used in ordering search results. A higher number means the corresponding factor has more influence on search results; zero means the factor is ignored. Changing these numbers does not require the search index to be rebuilt. Changes take effect immediately.') . '</em></p>',
|
||||
];
|
||||
// Prepare table.
|
||||
$header = [$this->t('Factor'), $this->t('Influence')];
|
||||
|
||||
@@ -165,7 +165,7 @@ class D6NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
|
||||
$this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($plugin_id, ['core' => 6], $migration);
|
||||
}
|
||||
$this->fieldPluginCache[$field_type]
|
||||
->processFieldValues($migration, $field_name, $info);
|
||||
->defineValueProcessPipeline($migration, $field_name, $info);
|
||||
}
|
||||
catch (PluginNotFoundException $ex) {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\node\Plugin\migrate;
|
||||
|
||||
use Drupal\migrate\Plugin\Migration;
|
||||
use Drupal\migrate_drupal\Plugin\MigrationWithFollowUpInterface;
|
||||
|
||||
/**
|
||||
* Migration plugin for the Drupal 6 node translations.
|
||||
*/
|
||||
class D6NodeTranslation extends Migration implements MigrationWithFollowUpInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generateFollowUpMigrations() {
|
||||
$this->migrationPluginManager->clearCachedDefinitions();
|
||||
return $this->migrationPluginManager->createInstances('d6_entity_reference_translation');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -168,7 +168,7 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface {
|
||||
$this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($plugin_id, ['core' => 7], $migration);
|
||||
}
|
||||
$this->fieldPluginCache[$field_type]
|
||||
->processFieldValues($migration, $field_name, $info);
|
||||
->defineValueProcessPipeline($migration, $field_name, $info);
|
||||
}
|
||||
catch (PluginNotFoundException $ex) {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\node\Plugin\migrate;
|
||||
|
||||
use Drupal\migrate\Plugin\Migration;
|
||||
use Drupal\migrate_drupal\Plugin\MigrationWithFollowUpInterface;
|
||||
|
||||
/**
|
||||
* Migration plugin for the Drupal 7 node translations.
|
||||
*/
|
||||
class D7NodeTranslation extends Migration implements MigrationWithFollowUpInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generateFollowUpMigrations() {
|
||||
$this->migrationPluginManager->clearCachedDefinitions();
|
||||
return $this->migrationPluginManager->createInstances('d7_entity_reference_translation');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -104,17 +104,39 @@ class Node extends FieldableEntity {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$nid = $row->getSourceProperty('nid');
|
||||
$vid = $row->getSourceProperty('vid');
|
||||
$type = $row->getSourceProperty('type');
|
||||
|
||||
// If this entity was translated using Entity Translation, we need to get
|
||||
// its source language to get the field values in the right language.
|
||||
// The translations will be migrated by the d7_node_entity_translation
|
||||
// migration.
|
||||
$entity_translatable = $this->isEntityTranslatable('node') && (int) $this->variableGet('language_content_type_' . $type, 0) === 4;
|
||||
$language = $entity_translatable ? $this->getEntityTranslationSourceLanguage('node', $nid) : $row->getSourceProperty('language');
|
||||
|
||||
// Get Field API field values.
|
||||
foreach (array_keys($this->getFields('node', $row->getSourceProperty('type'))) as $field) {
|
||||
$nid = $row->getSourceProperty('nid');
|
||||
$vid = $row->getSourceProperty('vid');
|
||||
$row->setSourceProperty($field, $this->getFieldValues('node', $field, $nid, $vid));
|
||||
foreach ($this->getFields('node', $type) as $field_name => $field) {
|
||||
// Ensure we're using the right language if the entity and the field are
|
||||
// translatable.
|
||||
$field_language = $entity_translatable && $field['translatable'] ? $language : NULL;
|
||||
$row->setSourceProperty($field_name, $this->getFieldValues('node', $field_name, $nid, $vid, $field_language));
|
||||
}
|
||||
|
||||
// Make sure we always have a translation set.
|
||||
if ($row->getSourceProperty('tnid') == 0) {
|
||||
$row->setSourceProperty('tnid', $row->getSourceProperty('nid'));
|
||||
}
|
||||
|
||||
// If the node title was replaced by a real field using the Drupal 7 Title
|
||||
// module, use the field value instead of the node title.
|
||||
if ($this->moduleExists('title')) {
|
||||
$title_field = $row->getSourceProperty('title_field');
|
||||
if (isset($title_field[0]['value'])) {
|
||||
$row->setSourceProperty('title', $title_field[0]['value']);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\node\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
|
||||
|
||||
/**
|
||||
* Provides Drupal 7 node entity translations source plugin.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_node_entity_translation",
|
||||
* source_module = "entity_translation"
|
||||
* )
|
||||
*/
|
||||
class NodeEntityTranslation extends FieldableEntity {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('entity_translation', 'et')
|
||||
->fields('et', [
|
||||
'entity_id',
|
||||
'revision_id',
|
||||
'language',
|
||||
'source',
|
||||
'uid',
|
||||
'status',
|
||||
'created',
|
||||
'changed',
|
||||
])
|
||||
->fields('n', [
|
||||
'title',
|
||||
'type',
|
||||
'promote',
|
||||
'sticky',
|
||||
])
|
||||
->fields('nr', [
|
||||
'log',
|
||||
'timestamp',
|
||||
])
|
||||
->condition('et.entity_type', 'node')
|
||||
->condition('et.source', '', '<>');
|
||||
|
||||
$query->addField('nr', 'uid', 'revision_uid');
|
||||
|
||||
$query->innerJoin('node', 'n', 'n.nid = et.entity_id');
|
||||
$query->innerJoin('node_revision', 'nr', 'nr.vid = et.revision_id');
|
||||
|
||||
if (isset($this->configuration['node_type'])) {
|
||||
$query->condition('n.type', $this->configuration['node_type']);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$nid = $row->getSourceProperty('entity_id');
|
||||
$vid = $row->getSourceProperty('revision_id');
|
||||
$type = $row->getSourceProperty('type');
|
||||
$language = $row->getSourceProperty('language');
|
||||
|
||||
// Get Field API field values.
|
||||
foreach ($this->getFields('node', $type) as $field_name => $field) {
|
||||
// Ensure we're using the right language if the entity is translatable.
|
||||
$field_language = $field['translatable'] ? $language : NULL;
|
||||
$row->setSourceProperty($field_name, $this->getFieldValues('node', $field_name, $nid, $vid, $field_language));
|
||||
}
|
||||
|
||||
// If the node title was replaced by a real field using the Drupal 7 Title
|
||||
// module, use the field value instead of the node title.
|
||||
if ($this->moduleExists('title')) {
|
||||
$title_field = $row->getSourceProperty('title_field');
|
||||
if (isset($title_field[0]['value'])) {
|
||||
$row->setSourceProperty('title', $title_field[0]['value']);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return [
|
||||
'entity_id' => $this->t('Entity ID'),
|
||||
'revision_id' => $this->t('Revision ID'),
|
||||
'language' => $this->t('Node translation language'),
|
||||
'source' => $this->t('Node translation source language'),
|
||||
'uid' => $this->t('Node translation authored by (uid)'),
|
||||
'status' => $this->t('Published'),
|
||||
'created' => $this->t('Created timestamp'),
|
||||
'changed' => $this->t('Modified timestamp'),
|
||||
'title' => $this->t('Node title'),
|
||||
'type' => $this->t('Node type'),
|
||||
'promote' => $this->t('Promoted to front page'),
|
||||
'sticky' => $this->t('Sticky at top of lists'),
|
||||
'log' => $this->t('Revision log'),
|
||||
'timestamp' => $this->t('The timestamp the latest revision of this node was created.'),
|
||||
'revision_uid' => $this->t('Revision authored by (uid)'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return [
|
||||
'entity_id' => [
|
||||
'type' => 'integer',
|
||||
'alias' => 'et',
|
||||
],
|
||||
'language' => [
|
||||
'type' => 'string',
|
||||
'alias' => 'et',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,7 +29,7 @@ class Vid extends NumericArgument {
|
||||
protected $nodeStorage;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
* Constructs a \Drupal\node\Plugin\views\argument\Vid object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
|
||||
@@ -16,7 +16,9 @@ use Drupal\views\Plugin\views\filter\FilterPluginBase;
|
||||
class Access extends FilterPluginBase {
|
||||
|
||||
public function adminSummary() {}
|
||||
|
||||
protected function operatorForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
public function canExpose() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class Node extends WizardPluginBase {
|
||||
public function getAvailableSorts() {
|
||||
// You can't execute functions in properties, so override the method
|
||||
return [
|
||||
'node_field_data-title:ASC' => $this->t('Title')
|
||||
'node_field_data-title:ASC' => $this->t('Title'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -109,8 +109,8 @@ class NodeRevisionsTest extends NodeTestBase {
|
||||
$node->untranslatable_string_field->value = $this->randomString();
|
||||
$node->setNewRevision();
|
||||
|
||||
// Edit the 2nd revision with a different user.
|
||||
if ($i == 1) {
|
||||
// Edit the 1st and 2nd revision with a different user.
|
||||
if ($i < 2) {
|
||||
$editor = $this->drupalCreateUser();
|
||||
$node->setRevisionUserId($editor->id());
|
||||
}
|
||||
@@ -174,11 +174,15 @@ class NodeRevisionsTest extends NodeTestBase {
|
||||
$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-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.');
|
||||
// Confirm the revision author is the user performing the revert.
|
||||
$this->assertTrue($reverted_node->getRevisionUserId() == $this->loggedInUser->id(), 'Node revision author is user performing revert.');
|
||||
// And that its not the revision author.
|
||||
$this->assertTrue($reverted_node->getRevisionUserId() != $nodes[1]->getRevisionUserId(), 'Node revision author is not original revision author.');
|
||||
|
||||
// Confirm that this is not the default version.
|
||||
$node = node_revision_load($node->getRevisionId());
|
||||
|
||||
@@ -105,7 +105,7 @@ abstract class NodeTestBase extends WebTestBase {
|
||||
[
|
||||
'@result' => $result ? 'true' : 'false',
|
||||
'%op' => $operation,
|
||||
'%langcode' => !empty($langcode) ? $langcode : 'empty'
|
||||
'%langcode' => !empty($langcode) ? $langcode : 'empty',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ class NodeTypeTest extends NodeTestBase {
|
||||
// Navigate to content type administration screen
|
||||
$this->drupalGet('admin/structure/types');
|
||||
$this->assertRaw(t('No content types available. <a href=":link">Add content type</a>.', [
|
||||
':link' => Url::fromRoute('node.type_add')->toString()
|
||||
':link' => Url::fromRoute('node.type_add')->toString(),
|
||||
]), 'Empty text when there are no content types in the system is correct.');
|
||||
|
||||
$bundle_info->clearCachedBundles();
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Drupal\node\Tests;
|
||||
|
||||
use Drupal\comment\Tests\CommentTestTrait;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
@@ -88,7 +87,7 @@ class PagePreviewTest extends NodeTestBase {
|
||||
$field_config->save();
|
||||
|
||||
// Create a field.
|
||||
$this->fieldName = Unicode::strtolower($this->randomMachineName());
|
||||
$this->fieldName = mb_strtolower($this->randomMachineName());
|
||||
$handler_settings = [
|
||||
'target_bundles' => [
|
||||
$this->vocabulary->id() => $this->vocabulary->id(),
|
||||
@@ -134,7 +133,7 @@ class PagePreviewTest extends NodeTestBase {
|
||||
'type' => 'text',
|
||||
'settings' => [
|
||||
'max_length' => 50,
|
||||
]
|
||||
],
|
||||
]);
|
||||
$field_storage->save();
|
||||
FieldConfig::create([
|
||||
@@ -184,6 +183,10 @@ class PagePreviewTest extends NodeTestBase {
|
||||
$this->assertText($edit[$term_key], 'Term displayed.');
|
||||
$this->assertLink(t('Back to content editing'));
|
||||
|
||||
// Check that we see the class of the node type on the body element.
|
||||
$body_class_element = $this->xpath("//body[contains(@class, 'page-node-type-page')]");
|
||||
$this->assertTrue(!empty($body_class_element), 'Node type body class found.');
|
||||
|
||||
// Get the UUID.
|
||||
$url = parse_url($this->getUrl());
|
||||
$paths = explode('/', $url['path']);
|
||||
|
||||
+1
-1
@@ -5,4 +5,4 @@ package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- options
|
||||
- drupal:options
|
||||
|
||||
@@ -182,10 +182,10 @@ function node_test_node_insert(NodeInterface $node) {
|
||||
*/
|
||||
function node_test_form_alter(&$form, FormStateInterface $form_state, $form_id) {
|
||||
if (!$form_state->get('node_test_form_alter')) {
|
||||
drupal_set_message('Storage is not set');
|
||||
\Drupal::messenger()->addStatus('Storage is not set');
|
||||
$form_state->set('node_test_form_alter', TRUE);
|
||||
}
|
||||
else {
|
||||
drupal_set_message('Storage is set');
|
||||
\Drupal::messenger()->addStatus('Storage is set');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,6 @@ package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- node
|
||||
- views
|
||||
- language
|
||||
- drupal:node
|
||||
- drupal:views
|
||||
- drupal:language
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@ display:
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
text: 'Link to delete revision'
|
||||
text: 'Link to revert revision'
|
||||
entity_type: node
|
||||
plugin_id: node_revision_link_revert
|
||||
filters: { }
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
|
||||
use Drupal\Tests\node\Functional\Rest\NodeResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class NodeHalJsonAnonTest extends NodeResourceTestBase {
|
||||
|
||||
use HalEntityNormalizationTrait;
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $patchProtectedFieldNames = [
|
||||
'revision_timestamp' => NULL,
|
||||
'created' => "The 'administer nodes' permission is required.",
|
||||
'changed' => NULL,
|
||||
'promote' => "The 'administer nodes' permission is required.",
|
||||
'sticky' => "The 'administer nodes' permission is required.",
|
||||
'path' => "The following permissions are required: 'create url aliases' OR 'administer url aliases'.",
|
||||
'revision_uid' => NULL,
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
$default_normalization = parent::getExpectedNormalizedEntity();
|
||||
|
||||
$normalization = $this->applyHalFieldNormalization($default_normalization);
|
||||
|
||||
$author = User::load($this->entity->getOwnerId());
|
||||
return $normalization + [
|
||||
'_links' => [
|
||||
'self' => [
|
||||
'href' => $this->baseUrl . '/llama?_format=hal_json',
|
||||
],
|
||||
'type' => [
|
||||
'href' => $this->baseUrl . '/rest/type/node/camelids',
|
||||
],
|
||||
$this->baseUrl . '/rest/relation/node/camelids/revision_uid' => [
|
||||
[
|
||||
'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
|
||||
],
|
||||
],
|
||||
$this->baseUrl . '/rest/relation/node/camelids/uid' => [
|
||||
[
|
||||
'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
|
||||
'lang' => 'en',
|
||||
],
|
||||
],
|
||||
],
|
||||
'_embedded' => [
|
||||
$this->baseUrl . '/rest/relation/node/camelids/revision_uid' => [
|
||||
[
|
||||
'_links' => [
|
||||
'self' => [
|
||||
'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
|
||||
],
|
||||
'type' => [
|
||||
'href' => $this->baseUrl . '/rest/type/user/user',
|
||||
],
|
||||
],
|
||||
'uuid' => [
|
||||
['value' => $author->uuid()],
|
||||
],
|
||||
],
|
||||
],
|
||||
$this->baseUrl . '/rest/relation/node/camelids/uid' => [
|
||||
[
|
||||
'_links' => [
|
||||
'self' => [
|
||||
'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
|
||||
],
|
||||
'type' => [
|
||||
'href' => $this->baseUrl . '/rest/type/user/user',
|
||||
],
|
||||
],
|
||||
'uuid' => [
|
||||
['value' => $author->uuid()],
|
||||
],
|
||||
'lang' => 'en',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
return parent::getNormalizedPostEntity() + [
|
||||
'_links' => [
|
||||
'type' => [
|
||||
'href' => $this->baseUrl . '/rest/type/node/camelids',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class NodeHalJsonBasicAuthTest extends NodeHalJsonAnonTest {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class NodeHalJsonCookieTest extends NodeHalJsonAnonTest {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\node\Functional\Rest\NodeTypeResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class NodeTypeHalJsonAnonTest extends NodeTypeResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\node\Functional\Rest\NodeTypeResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class NodeTypeHalJsonBasicAuthTest extends NodeTypeResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal', 'basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\node\Functional\Rest\NodeTypeResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class NodeTypeHalJsonCookieTest extends NodeTypeResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
||||
@@ -28,10 +28,10 @@ class MigrateNodeRevisionTest extends MigrateNodeTestBase {
|
||||
* Test node revisions migration from Drupal 6 to 8.
|
||||
*/
|
||||
public function testNodeRevision() {
|
||||
$node = \Drupal::entityManager()->getStorage('node')->loadRevision(2);
|
||||
$node = \Drupal::entityManager()->getStorage('node')->loadRevision(2001);
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
$this->assertIdentical('1', $node->id());
|
||||
$this->assertIdentical('2', $node->getRevisionId());
|
||||
$this->assertIdentical('2001', $node->getRevisionId());
|
||||
$this->assertIdentical('und', $node->langcode->value);
|
||||
$this->assertIdentical('Test title rev 2', $node->getTitle());
|
||||
$this->assertIdentical('body test rev 2', $node->body->value);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
@@ -29,7 +28,7 @@ class MultiStepNodeFormBasicOptionsTest extends NodeTestBase {
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
// Create an unlimited cardinality field.
|
||||
$this->fieldName = Unicode::strtolower($this->randomMachineName());
|
||||
$this->fieldName = mb_strtolower($this->randomMachineName());
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => 'node',
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
@@ -51,11 +50,11 @@ class NodeAccessFieldTest extends NodeTestBase {
|
||||
$this->contentAdminUser = $this->drupalCreateUser(['access content', 'administer content types', 'administer node fields']);
|
||||
|
||||
// Add a custom field to the page content type.
|
||||
$this->fieldName = Unicode::strtolower($this->randomMachineName() . '_field_name');
|
||||
$this->fieldName = mb_strtolower($this->randomMachineName() . '_field_name');
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => 'node',
|
||||
'type' => 'text'
|
||||
'type' => 'text',
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
|
||||
@@ -34,14 +34,14 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
|
||||
/**
|
||||
* A normal authenticated user.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface.
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
/**
|
||||
* User 1.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface.
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class NodeAccessMenuLinkTest extends NodeTestBase {
|
||||
$this->contentAdminUser = $this->drupalCreateUser([
|
||||
'access content',
|
||||
'administer content types',
|
||||
'administer menu'
|
||||
'administer menu',
|
||||
]);
|
||||
|
||||
$this->config('user.role.' . RoleInterface::ANONYMOUS_ID)->set('permissions', [])->save();
|
||||
|
||||
@@ -52,7 +52,7 @@ class NodeAccessRebuildNodeGrantsTest extends NodeTestBase {
|
||||
for ($i = 0; $i < 30; $i++) {
|
||||
$nodes[] = $this->drupalCreateNode([
|
||||
'uid' => $this->webUser->id(),
|
||||
'private' => [['value' => 1]]
|
||||
'private' => [['value' => 1]],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -141,15 +141,32 @@ class NodeBlockFunctionalTest extends NodeTestBase {
|
||||
$label = $block->label();
|
||||
$this->assertNoText($label, 'Block was not displayed on the front page.');
|
||||
$this->assertCacheContexts(['languages:language_content', 'languages:language_interface', 'theme', 'url.query_args:' . MainContentViewSubscriber::WRAPPER_FORMAT, 'user', 'route']);
|
||||
|
||||
// Ensure that a page that does not have a node context can still be cached,
|
||||
// the front page is the user page which is already cached from the login
|
||||
// request above.
|
||||
$this->assertSame('HIT', $this->getSession()->getResponseHeader('X-Drupal-Dynamic-Cache'));
|
||||
|
||||
$this->drupalGet('node/add/article');
|
||||
$this->assertText($label, 'Block was displayed on the node/add/article page.');
|
||||
$this->assertCacheContexts(['languages:language_content', 'languages:language_interface', 'session', 'theme', 'url.path', 'url.query_args', 'user', 'route']);
|
||||
|
||||
// The node/add/article page is an admin path and currently uncacheable.
|
||||
$this->assertSame('UNCACHEABLE', $this->getSession()->getResponseHeader('X-Drupal-Dynamic-Cache'));
|
||||
|
||||
$this->drupalGet('node/' . $node1->id());
|
||||
$this->assertText($label, 'Block was displayed on the node/N when node is of type article.');
|
||||
$this->assertCacheContexts(['languages:language_content', 'languages:language_interface', 'theme', 'url.query_args:' . MainContentViewSubscriber::WRAPPER_FORMAT, 'user', 'route', 'timezone']);
|
||||
$this->assertSame('MISS', $this->getSession()->getResponseHeader('X-Drupal-Dynamic-Cache'));
|
||||
$this->drupalGet('node/' . $node1->id());
|
||||
$this->assertSame('HIT', $this->getSession()->getResponseHeader('X-Drupal-Dynamic-Cache'));
|
||||
|
||||
$this->drupalGet('node/' . $node5->id());
|
||||
$this->assertNoText($label, 'Block was not displayed on nodes of type page.');
|
||||
$this->assertCacheContexts(['languages:language_content', 'languages:language_interface', 'theme', 'url.query_args:' . MainContentViewSubscriber::WRAPPER_FORMAT, 'user', 'route', 'timezone']);
|
||||
$this->assertSame('MISS', $this->getSession()->getResponseHeader('X-Drupal-Dynamic-Cache'));
|
||||
$this->drupalGet('node/' . $node5->id());
|
||||
$this->assertSame('HIT', $this->getSession()->getResponseHeader('X-Drupal-Dynamic-Cache'));
|
||||
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->drupalGet('admin/structure/block');
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Drupal\Tests\node\Functional;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\system\Tests\Entity\EntityWithUriCacheTagsTestBase;
|
||||
use Drupal\Tests\system\Functional\Entity\EntityWithUriCacheTagsTestBase;
|
||||
|
||||
/**
|
||||
* Tests the Node entity's cache tags.
|
||||
@@ -32,7 +32,7 @@ class NodeCacheTagsTest extends EntityWithUriCacheTagsTestBase {
|
||||
// Create a "Llama" node.
|
||||
$node = Node::create(['type' => 'camelids']);
|
||||
$node->setTitle('Llama')
|
||||
->setPublished(TRUE)
|
||||
->setPublished()
|
||||
->save();
|
||||
|
||||
return $node;
|
||||
|
||||
@@ -14,7 +14,7 @@ class NodeHelpTest extends BrowserTestBase {
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array.
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block', 'node', 'help'];
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\user\Entity\Role;
|
||||
|
||||
/**
|
||||
* Tests the node entity preview functionality for anonymous user.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodePreviewAnonymousTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Enable node module to test on the preview.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Create Basic page node type.
|
||||
$this->drupalCreateContentType([
|
||||
'type' => 'page',
|
||||
'name' => 'Basic page',
|
||||
'display_submitted' => FALSE,
|
||||
]);
|
||||
|
||||
// Grant create and editing permissions to anonymous user:
|
||||
$anonymous_role = Role::load(AccountInterface::ANONYMOUS_ROLE);
|
||||
$anonymous_role->grantPermission('create page content');
|
||||
$anonymous_role->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the node preview functionality for anonymous users.
|
||||
*/
|
||||
public function testAnonymousPagePreview() {
|
||||
|
||||
$title_key = 'title[0][value]';
|
||||
$body_key = 'body[0][value]';
|
||||
|
||||
// Fill in node creation form and preview node.
|
||||
$edit = [
|
||||
$title_key => $this->randomMachineName(),
|
||||
$body_key => $this->randomMachineName(),
|
||||
];
|
||||
$this->drupalPostForm('node/add/page', $edit, t('Preview'));
|
||||
|
||||
// Check that the preview is displaying the title, body and term.
|
||||
$this->assertSession()->linkExists(t('Back to content editing'));
|
||||
$this->assertSession()->responseContains($edit[$body_key]);
|
||||
$this->assertSession()->titleEquals($edit[$title_key] . ' | Drupal');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,6 +26,13 @@ class NodeRevisionsAllTest extends NodeTestBase {
|
||||
*/
|
||||
protected $revisionLogs;
|
||||
|
||||
/**
|
||||
* An arbitrary user for revision authoring.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $revisionUser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -39,7 +46,7 @@ class NodeRevisionsAllTest extends NodeTestBase {
|
||||
'revert page revisions',
|
||||
'delete page revisions',
|
||||
'edit any page content',
|
||||
'delete any page content'
|
||||
'delete any page content',
|
||||
]
|
||||
);
|
||||
$this->drupalLogin($web_user);
|
||||
@@ -47,6 +54,10 @@ class NodeRevisionsAllTest extends NodeTestBase {
|
||||
// Create an initial node.
|
||||
$node = $this->drupalCreateNode();
|
||||
|
||||
// Create a user for revision authoring.
|
||||
// This must be different from user performing revert.
|
||||
$this->revisionUser = $this->drupalCreateUser();
|
||||
|
||||
$settings = get_object_vars($node);
|
||||
$settings['revision'] = 1;
|
||||
|
||||
@@ -86,6 +97,8 @@ class NodeRevisionsAllTest extends NodeTestBase {
|
||||
'format' => filter_default_format(),
|
||||
];
|
||||
$node->setNewRevision();
|
||||
// Ensure the revision author is a different user.
|
||||
$node->setRevisionUserId($this->revisionUser->id());
|
||||
$node->save();
|
||||
|
||||
return $node;
|
||||
@@ -109,7 +122,7 @@ class NodeRevisionsAllTest extends NodeTestBase {
|
||||
'revert all revisions',
|
||||
'delete all revisions',
|
||||
'edit any page content',
|
||||
'delete any page content'
|
||||
'delete any page content',
|
||||
]
|
||||
);
|
||||
$this->drupalLogin($content_admin);
|
||||
@@ -134,13 +147,18 @@ class NodeRevisionsAllTest extends NodeTestBase {
|
||||
[
|
||||
'@type' => 'Basic page',
|
||||
'%title' => $nodes[1]->getTitle(),
|
||||
'%revision-date' => format_date($nodes[1]->getRevisionCreationTime())
|
||||
'%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.');
|
||||
|
||||
// Confirm the revision author is the user performing the revert.
|
||||
$this->assertTrue($reverted_node->getRevisionUserId() == $this->loggedInUser->id(), 'Node revision author is user performing revert.');
|
||||
// And that its not the revision author.
|
||||
$this->assertTrue($reverted_node->getRevisionUserId() != $this->revisionUser->id(), 'Node revision author is not original revision author.');
|
||||
|
||||
// Confirm that this is not the current version.
|
||||
$node = node_revision_load($node->getRevisionId());
|
||||
$this->assertFalse($node->isDefaultRevision(), 'Third node revision is not the current one.');
|
||||
|
||||
@@ -102,7 +102,7 @@ abstract class NodeTestBase extends BrowserTestBase {
|
||||
[
|
||||
'@result' => $result ? 'true' : 'false',
|
||||
'%op' => $operation,
|
||||
'%langcode' => !empty($langcode) ? $langcode : 'empty'
|
||||
'%langcode' => !empty($langcode) ? $langcode : 'empty',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
|
||||
$add_url = Url::fromRoute("entity.$entity_type_id.content_translation_add", [
|
||||
$entity->getEntityTypeId() => $entity->id(),
|
||||
'source' => $default_langcode,
|
||||
'target' => $langcode
|
||||
'target' => $langcode,
|
||||
], ['language' => $language]);
|
||||
$edit = $this->getEditValues($values, $langcode);
|
||||
$edit['status[value]'] = FALSE;
|
||||
@@ -284,7 +284,7 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
|
||||
$translation = $node->addTranslation($langcode, $values[$langcode]);
|
||||
// Publish and promote the translation to frontpage.
|
||||
$translation->setPromoted(TRUE);
|
||||
$translation->setPublished(TRUE);
|
||||
$translation->setPublished();
|
||||
}
|
||||
$node->save();
|
||||
|
||||
@@ -501,4 +501,28 @@ class NodeTranslationUITest extends ContentTranslationUITestBase {
|
||||
$this->assertNoText('First rev en title');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that title is not escaped (but XSS-filtered) for details form element.
|
||||
*/
|
||||
public function testDetailsTitleIsNotEscaped() {
|
||||
$this->drupalLogin($this->administrator);
|
||||
// Make the image field a multi-value field in order to display a
|
||||
// details form element.
|
||||
$edit = ['cardinality_number' => 2];
|
||||
$this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.field_image/storage', $edit, t('Save field settings'));
|
||||
|
||||
// Make the image field non-translatable.
|
||||
$edit = ['settings[node][article][fields][field_image]' => FALSE];
|
||||
$this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
|
||||
|
||||
// Create a node.
|
||||
$nid = $this->createEntity(['title' => 'Node with multi-value image field en title'], 'en');
|
||||
|
||||
// Add a French translation and assert the title markup is not escaped.
|
||||
$this->drupalGet("node/$nid/translations/add/en/fr");
|
||||
$markup = 'Image <span class="translation-entity-all-languages">(all languages)</span>';
|
||||
$this->assertSession()->assertNoEscaped($markup);
|
||||
$this->assertSession()->responseContains($markup);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\Tests\node\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
@@ -83,6 +82,11 @@ class NodeTypeTranslationTest extends BrowserTestBase {
|
||||
protected function installParameters() {
|
||||
$parameters = parent::installParameters();
|
||||
$parameters['parameters']['langcode'] = $this->defaultLangcode;
|
||||
// Create an empty po file so we don't attempt to download one from
|
||||
// localize.drupal.org. It does not need to match the version exactly as the
|
||||
// multi-lingual system will fallback.
|
||||
\Drupal::service('file_system')->mkdir($this->publicFilesDirectory . '/translations', NULL, TRUE);
|
||||
file_put_contents($this->publicFilesDirectory . "/translations/drupal-8.0.0.{$this->defaultLangcode}.po", '');
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
@@ -90,7 +94,7 @@ class NodeTypeTranslationTest extends BrowserTestBase {
|
||||
* Tests the node type translation.
|
||||
*/
|
||||
public function testNodeTypeTranslation() {
|
||||
$type = Unicode::strtolower($this->randomMachineName(16));
|
||||
$type = mb_strtolower($this->randomMachineName(16));
|
||||
$name = $this->randomString();
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->drupalCreateContentType(['type' => $type, 'name' => $name]);
|
||||
@@ -124,7 +128,7 @@ class NodeTypeTranslationTest extends BrowserTestBase {
|
||||
* Tests the node type title label translation.
|
||||
*/
|
||||
public function testNodeTypeTitleLabelTranslation() {
|
||||
$type = Unicode::strtolower($this->randomMachineName(16));
|
||||
$type = mb_strtolower($this->randomMachineName(16));
|
||||
$name = $this->randomString();
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->drupalCreateContentType(['type' => $type, 'name' => $name]);
|
||||
@@ -154,7 +158,7 @@ class NodeTypeTranslationTest extends BrowserTestBase {
|
||||
$this->drupalPostForm(NULL, [], 'Save field settings');
|
||||
$this->drupalPostForm(NULL, [], 'Save settings');
|
||||
|
||||
$type = Unicode::strtolower($this->randomMachineName(16));
|
||||
$type = mb_strtolower($this->randomMachineName(16));
|
||||
$name = $this->randomString();
|
||||
$this->drupalCreateContentType(['type' => $type, 'name' => $name]);
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class NodeViewTest extends NodeTestBase {
|
||||
// ensure caches are handled properly.
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$edit = [
|
||||
'anonymous[edit own ' . $node->bundle() . ' content]' => TRUE
|
||||
'anonymous[edit own ' . $node->bundle() . ' content]' => TRUE,
|
||||
];
|
||||
$this->drupalPostForm('admin/people/permissions', $edit, 'Save permissions');
|
||||
$this->drupalLogout();
|
||||
|
||||
@@ -10,6 +10,7 @@ use Drupal\node\Entity\Node;
|
||||
* @group node
|
||||
*/
|
||||
class PageViewTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Tests an anonymous and unpermissioned user attempting to edit the node.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class NodeJsonAnonTest extends NodeResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class NodeJsonBasicAuthTest extends NodeResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class NodeJsonCookieTest extends NodeResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
|
||||
use Drupal\user\Entity\User;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
|
||||
abstract class NodeResourceTestBase extends EntityResourceTestBase {
|
||||
|
||||
use BcTimestampNormalizerUnixTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'path'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $entityTypeId = 'node';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $patchProtectedFieldNames = [
|
||||
'revision_timestamp' => NULL,
|
||||
'revision_uid' => NULL,
|
||||
'created' => "The 'administer nodes' permission is required.",
|
||||
'changed' => NULL,
|
||||
'promote' => "The 'administer nodes' permission is required.",
|
||||
'sticky' => "The 'administer nodes' permission is required.",
|
||||
'path' => "The following permissions are required: 'create url aliases' OR 'administer url aliases'.",
|
||||
];
|
||||
|
||||
/**
|
||||
* @var \Drupal\node\NodeInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpAuthorization($method) {
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
$this->grantPermissionsToTestedRole(['access content']);
|
||||
break;
|
||||
case 'POST':
|
||||
$this->grantPermissionsToTestedRole(['access content', 'create camelids content']);
|
||||
break;
|
||||
case 'PATCH':
|
||||
// Do not grant the 'create url aliases' permission to test the case
|
||||
// when the path field is protected/not accessible, see
|
||||
// \Drupal\Tests\rest\Functional\EntityResource\Term\TermResourceTestBase
|
||||
// for a positive test.
|
||||
$this->grantPermissionsToTestedRole(['access content', 'edit any camelids content']);
|
||||
break;
|
||||
case 'DELETE':
|
||||
$this->grantPermissionsToTestedRole(['access content', 'delete any camelids content']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
if (!NodeType::load('camelids')) {
|
||||
// Create a "Camelids" node type.
|
||||
NodeType::create([
|
||||
'name' => 'Camelids',
|
||||
'type' => 'camelids',
|
||||
])->save();
|
||||
}
|
||||
|
||||
// Create a "Llama" node.
|
||||
$node = Node::create(['type' => 'camelids']);
|
||||
$node->setTitle('Llama')
|
||||
->setOwnerId(static::$auth ? $this->account->id() : 0)
|
||||
->setPublished()
|
||||
->setCreatedTime(123456789)
|
||||
->setChangedTime(123456789)
|
||||
->setRevisionCreationTime(123456789)
|
||||
->set('path', '/llama')
|
||||
->save();
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
$author = User::load($this->entity->getOwnerId());
|
||||
return [
|
||||
'nid' => [
|
||||
['value' => 1],
|
||||
],
|
||||
'uuid' => [
|
||||
['value' => $this->entity->uuid()],
|
||||
],
|
||||
'vid' => [
|
||||
['value' => 1],
|
||||
],
|
||||
'langcode' => [
|
||||
[
|
||||
'value' => 'en',
|
||||
],
|
||||
],
|
||||
'type' => [
|
||||
[
|
||||
'target_id' => 'camelids',
|
||||
'target_type' => 'node_type',
|
||||
'target_uuid' => NodeType::load('camelids')->uuid(),
|
||||
],
|
||||
],
|
||||
'title' => [
|
||||
[
|
||||
'value' => 'Llama',
|
||||
],
|
||||
],
|
||||
'status' => [
|
||||
[
|
||||
'value' => TRUE,
|
||||
],
|
||||
],
|
||||
'created' => [
|
||||
$this->formatExpectedTimestampItemValues(123456789),
|
||||
],
|
||||
'changed' => [
|
||||
$this->formatExpectedTimestampItemValues($this->entity->getChangedTime()),
|
||||
],
|
||||
'promote' => [
|
||||
[
|
||||
'value' => TRUE,
|
||||
],
|
||||
],
|
||||
'sticky' => [
|
||||
[
|
||||
'value' => FALSE,
|
||||
],
|
||||
],
|
||||
'revision_timestamp' => [
|
||||
$this->formatExpectedTimestampItemValues(123456789),
|
||||
],
|
||||
'revision_translation_affected' => [
|
||||
[
|
||||
'value' => TRUE,
|
||||
],
|
||||
],
|
||||
'default_langcode' => [
|
||||
[
|
||||
'value' => TRUE,
|
||||
],
|
||||
],
|
||||
'uid' => [
|
||||
[
|
||||
'target_id' => (int) $author->id(),
|
||||
'target_type' => 'user',
|
||||
'target_uuid' => $author->uuid(),
|
||||
'url' => base_path() . 'user/' . $author->id(),
|
||||
],
|
||||
],
|
||||
'revision_uid' => [
|
||||
[
|
||||
'target_id' => (int) $author->id(),
|
||||
'target_type' => 'user',
|
||||
'target_uuid' => $author->uuid(),
|
||||
'url' => base_path() . 'user/' . $author->id(),
|
||||
],
|
||||
],
|
||||
'revision_log' => [],
|
||||
'path' => [
|
||||
[
|
||||
'alias' => '/llama',
|
||||
'pid' => 1,
|
||||
'langcode' => 'en',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
return [
|
||||
'type' => [
|
||||
[
|
||||
'target_id' => 'camelids',
|
||||
],
|
||||
],
|
||||
'title' => [
|
||||
[
|
||||
'value' => 'Dramallama',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedUnauthorizedAccessMessage($method) {
|
||||
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
|
||||
if ($method === 'GET' || $method == 'PATCH' || $method == 'DELETE') {
|
||||
return "The 'access content' permission is required.";
|
||||
}
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests PATCHing a node's path with and without 'create url aliases'.
|
||||
*
|
||||
* For a positive test, see the similar test coverage for Term.
|
||||
*
|
||||
* @see \Drupal\Tests\rest\Functional\EntityResource\Term\TermResourceTestBase::testPatchPath()
|
||||
*/
|
||||
public function testPatchPath() {
|
||||
$this->initAuthentication();
|
||||
$this->provisionEntityResource();
|
||||
$this->setUpAuthorization('GET');
|
||||
$this->setUpAuthorization('PATCH');
|
||||
|
||||
$url = $this->getEntityResourceUrl()->setOption('query', ['_format' => static::$format]);
|
||||
|
||||
// GET node's current normalization.
|
||||
$response = $this->request('GET', $url, $this->getAuthenticationRequestOptions('GET'));
|
||||
$normalization = $this->serializer->decode((string) $response->getBody(), static::$format);
|
||||
|
||||
// Change node's path alias.
|
||||
$normalization['path'][0]['alias'] .= 's-rule-the-world';
|
||||
|
||||
// Create node PATCH request.
|
||||
$request_options = [];
|
||||
$request_options[RequestOptions::HEADERS]['Content-Type'] = static::$mimeType;
|
||||
$request_options = array_merge_recursive($request_options, $this->getAuthenticationRequestOptions('PATCH'));
|
||||
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
|
||||
|
||||
// PATCH request: 403 when creating URL aliases unauthorized. Before
|
||||
// asserting the 403 response, assert that the stored path alias remains
|
||||
// unchanged.
|
||||
$response = $this->request('PATCH', $url, $request_options);
|
||||
$this->assertSame('/llama', $this->entityStorage->loadUnchanged($this->entity->id())->get('path')->alias);
|
||||
$this->assertResourceErrorResponse(403, "Access denied on updating field 'path'. " . static::$patchProtectedFieldNames['path'], $response);
|
||||
|
||||
// Grant permission to create URL aliases.
|
||||
$this->grantPermissionsToTestedRole(['create url aliases']);
|
||||
|
||||
// Repeat PATCH request: 200.
|
||||
$response = $this->request('PATCH', $url, $request_options);
|
||||
$this->assertResourceResponse(200, FALSE, $response);
|
||||
$updated_normalization = $this->serializer->decode((string) $response->getBody(), static::$format);
|
||||
$this->assertSame($normalization['path'], $updated_normalization['path']);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class NodeTypeJsonAnonTest extends NodeTypeResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class NodeTypeJsonBasicAuthTest extends NodeTypeResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class NodeTypeJsonCookieTest extends NodeTypeResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
|
||||
|
||||
/**
|
||||
* ResourceTestBase for NodeType entity.
|
||||
*/
|
||||
abstract class NodeTypeResourceTestBase extends EntityResourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $entityTypeId = 'node_type';
|
||||
|
||||
/**
|
||||
* The NodeType entity.
|
||||
*
|
||||
* @var \Drupal\node\NodeTypeInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpAuthorization($method) {
|
||||
$this->grantPermissionsToTestedRole(['administer content types', 'access content']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
// Create a "Camelids" node type.
|
||||
$camelids = NodeType::create([
|
||||
'name' => 'Camelids',
|
||||
'type' => 'camelids',
|
||||
'description' => 'Camelids are large, strictly herbivorous animals with slender necks and long legs.',
|
||||
]);
|
||||
|
||||
$camelids->save();
|
||||
|
||||
return $camelids;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
return [
|
||||
'dependencies' => [],
|
||||
'description' => 'Camelids are large, strictly herbivorous animals with slender necks and long legs.',
|
||||
'display_submitted' => TRUE,
|
||||
'help' => NULL,
|
||||
'langcode' => 'en',
|
||||
'name' => 'Camelids',
|
||||
'new_revision' => TRUE,
|
||||
'preview_mode' => 1,
|
||||
'status' => TRUE,
|
||||
'type' => 'camelids',
|
||||
'uuid' => $this->entity->uuid(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
// @todo Update in https://www.drupal.org/node/2300677.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedUnauthorizedAccessMessage($method) {
|
||||
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
|
||||
return "The 'access content' permission is required.";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class NodeTypeXmlAnonTest extends NodeTypeResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class NodeTypeXmlBasicAuthTest extends NodeTypeResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class NodeTypeXmlCookieTest extends NodeTypeResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class NodeXmlAnonTest extends NodeResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testPatchPath() {
|
||||
// Deserialization of the XML format is not supported.
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class NodeXmlBasicAuthTest extends NodeResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testPatchPath() {
|
||||
// Deserialization of the XML format is not supported.
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class NodeXmlCookieTest extends NodeResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function testPatchPath() {
|
||||
// Deserialization of the XML format is not supported.
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
* Tests that node settings are properly updated during database updates.
|
||||
*
|
||||
* @group node
|
||||
* @group legacy
|
||||
*/
|
||||
class NodeUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Views;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
@@ -88,7 +88,7 @@ class BulkFormAccessTest extends NodeTestBase {
|
||||
'action' => 'node_unpublish_action',
|
||||
];
|
||||
$this->drupalPostForm('test-node-bulk-form', $edit, t('Apply to selected items'));
|
||||
$this->assertRaw(SafeMarkup::format('No access to execute %action on the @entity_type_label %entity_label.', [
|
||||
$this->assertRaw(new FormattableMarkup('No access to execute %action on the @entity_type_label %entity_label.', [
|
||||
'%action' => 'Unpublish content',
|
||||
'@entity_type_label' => 'Content',
|
||||
'%entity_label' => $node->label(),
|
||||
@@ -117,7 +117,7 @@ class BulkFormAccessTest extends NodeTestBase {
|
||||
];
|
||||
$this->drupalPostForm('test-node-bulk-form', $edit, t('Apply to selected items'));
|
||||
// Test that the action message isn't shown.
|
||||
$this->assertNoRaw(SafeMarkup::format('%action was applied to 1 item.', [
|
||||
$this->assertNoRaw(new FormattableMarkup('%action was applied to 1 item.', [
|
||||
'%action' => 'Unpublish content',
|
||||
]));
|
||||
// Re-load the node and check the status.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Drupal\Tests\node\Functional\Views;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\views\Views;
|
||||
|
||||
@@ -55,7 +55,7 @@ class BulkFormTest extends NodeTestBase {
|
||||
'promote' => FALSE,
|
||||
];
|
||||
$node = $this->drupalCreateNode($values);
|
||||
$this->pass(SafeMarkup::format('Node %title created with language %langcode.', ['%title' => $node->label(), '%langcode' => $node->language()->getId()]));
|
||||
$this->pass(new FormattableMarkup('Node %title created with language %langcode.', ['%title' => $node->label(), '%langcode' => $node->language()->getId()]));
|
||||
$this->nodes[] = $node;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class BulkFormTest extends NodeTestBase {
|
||||
if (!$node->hasTranslation($langcode)) {
|
||||
$title = $this->randomMachineName() . ' [' . $node->id() . ':' . $langcode . ']';
|
||||
$translation = $node->addTranslation($langcode, ['title' => $title, 'promote' => FALSE]);
|
||||
$this->pass(SafeMarkup::format('Translation %title created with language %langcode.', ['%title' => $translation->label(), '%langcode' => $translation->language()->getId()]));
|
||||
$this->pass(new FormattableMarkup('Translation %title created with language %langcode.', ['%title' => $translation->label(), '%langcode' => $translation->language()->getId()]));
|
||||
}
|
||||
}
|
||||
$node->save();
|
||||
@@ -77,7 +77,7 @@ class BulkFormTest extends NodeTestBase {
|
||||
$langcode = 'en';
|
||||
$title = $this->randomMachineName() . ' [' . $node->id() . ':' . $langcode . ']';
|
||||
$translation = $node->addTranslation($langcode, ['title' => $title]);
|
||||
$this->pass(SafeMarkup::format('Translation %title created with language %langcode.', ['%title' => $translation->label(), '%langcode' => $translation->language()->getId()]));
|
||||
$this->pass(new FormattableMarkup('Translation %title created with language %langcode.', ['%title' => $translation->label(), '%langcode' => $translation->language()->getId()]));
|
||||
$node->save();
|
||||
|
||||
// Check that all created translations are selected by the test view.
|
||||
@@ -249,15 +249,15 @@ class BulkFormTest extends NodeTestBase {
|
||||
$this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
|
||||
|
||||
$label = $this->loadNode(1)->label();
|
||||
$this->assertText("$label (Original translation) - The following content translations will be deleted:");
|
||||
$this->assertText("$label (Original translation) - The following content item translations will be deleted:");
|
||||
$label = $this->loadNode(2)->label();
|
||||
$this->assertText("$label (Original translation) - The following content translations will be deleted:");
|
||||
$this->assertText("$label (Original translation) - The following content item translations will be deleted:");
|
||||
$label = $this->loadNode(3)->getTranslation('en')->label();
|
||||
$this->assertText($label);
|
||||
$this->assertNoText("$label (Original translation) - The following content translations will be deleted:");
|
||||
$this->assertNoText("$label (Original translation) - The following content item translations will be deleted:");
|
||||
$label = $this->loadNode(4)->label();
|
||||
$this->assertText($label);
|
||||
$this->assertNoText("$label (Original translation) - The following content translations will be deleted:");
|
||||
$this->assertNoText("$label (Original translation) - The following content item translations will be deleted:");
|
||||
|
||||
$this->drupalPostForm(NULL, [], t('Delete'));
|
||||
|
||||
@@ -273,7 +273,7 @@ class BulkFormTest extends NodeTestBase {
|
||||
$node = $this->loadNode(5);
|
||||
$this->assertTrue($node, '5: Node has not been deleted');
|
||||
|
||||
$this->assertText('Deleted 8 posts.');
|
||||
$this->assertText('Deleted 8 content items.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -284,7 +284,7 @@ class FrontPageTest extends ViewTestBase {
|
||||
[
|
||||
'value' => $this->randomMachineName(32),
|
||||
'format' => filter_default_format(),
|
||||
]
|
||||
],
|
||||
],
|
||||
'type' => 'article',
|
||||
'created' => $i,
|
||||
|
||||
@@ -75,7 +75,7 @@ class NodeLanguageTest extends NodeTestBase {
|
||||
],
|
||||
'fr' => [
|
||||
'Premier nœud fr',
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
// Create nodes with translations.
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\node\FunctionalJavascript;
|
||||
|
||||
use Drupal\filter\Entity\FilterFormat;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
|
||||
/**
|
||||
* Tests the JavaScript prevention of navigation away from node previews.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodePreviewLinkTest extends WebDriverTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'filter'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$filtered_html_format = FilterFormat::create([
|
||||
'format' => 'filtered_html',
|
||||
'name' => 'Filtered HTML',
|
||||
]);
|
||||
$filtered_html_format->save();
|
||||
|
||||
$this->drupalCreateContentType(['type' => 'test']);
|
||||
|
||||
$user = $this->drupalCreateUser([
|
||||
'access content',
|
||||
'edit own test content',
|
||||
'create test content',
|
||||
$filtered_html_format->getPermissionName(),
|
||||
]);
|
||||
$this->drupalLogin($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the behavior of clicking preview links.
|
||||
*/
|
||||
public function testPreviewLinks() {
|
||||
$assertSession = $this->assertSession();
|
||||
$this->drupalPostForm('node/add/test', [
|
||||
'title[0][value]' => 'Test node',
|
||||
'body[0][value]' => '<a href="#foo">Anchor link</a><a href="/foo">Normal link</a>',
|
||||
], t('Preview'));
|
||||
$this->clickLink('Anchor link');
|
||||
$assertSession->pageTextNotContains('Leave preview?');
|
||||
$this->clickLink('Normal link');
|
||||
$assertSession->pageTextContains('Leave preview?');
|
||||
$this->click('button:contains("Leave preview")');
|
||||
$this->assertStringEndsWith('/foo', $this->getUrl());
|
||||
}
|
||||
|
||||
}
|
||||
+4
-2
@@ -2,14 +2,14 @@
|
||||
|
||||
namespace Drupal\Tests\node\FunctionalJavascript;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
|
||||
/**
|
||||
* Tests the JavaScript updating of summaries on content type form.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class TestSettingSummariesContentType extends JavascriptTestBase {
|
||||
class TestSettingSummariesContentType extends WebDriverTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -33,6 +33,8 @@ class TestSettingSummariesContentType extends JavascriptTestBase {
|
||||
public function testWorkflowSummary() {
|
||||
$this->drupalGet('admin/structure/types/manage/test');
|
||||
$page = $this->getSession()->getPage();
|
||||
$page->find('css', 'a[href="#edit-workflow"]')->click();
|
||||
$this->assertSession()->waitForElementVisible('css', '[name="options[status]"]');
|
||||
$page->findField('options[status]')->uncheck();
|
||||
$page->findField('options[sticky]')->check();
|
||||
$page->findField('options[promote]')->check();
|
||||
|
||||
@@ -26,7 +26,7 @@ class NodeImportChangeTest extends KernelTestBase {
|
||||
parent::setUp();
|
||||
|
||||
// Set default storage backend.
|
||||
$this->installConfig(['field', 'node_test_config']);
|
||||
$this->installConfig(['system', 'field', 'node_test_config']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,7 @@ class NodeImportCreateTest extends KernelTestBase {
|
||||
$this->installEntitySchema('user');
|
||||
|
||||
// Set default storage backend.
|
||||
$this->installConfig(['field']);
|
||||
$this->installConfig(['system', 'field']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,7 @@ class MigrateNodeBundleSettingsTest extends MigrateDrupal6TestBase {
|
||||
$this->executeMigrations([
|
||||
'd6_node_setting_promote',
|
||||
'd6_node_setting_status',
|
||||
'd6_node_setting_sticky'
|
||||
'd6_node_setting_sticky',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,13 @@ class MigrateNodeTest extends MigrateNodeTestBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['language', 'content_translation', 'menu_ui'];
|
||||
public static $modules = [
|
||||
'language',
|
||||
'content_translation',
|
||||
'menu_ui',
|
||||
// Required for translation migrations.
|
||||
'migrate_drupal_multilingual',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -94,6 +100,10 @@ class MigrateNodeTest extends MigrateNodeTestBase {
|
||||
$this->assertCount(2, $node->field_company);
|
||||
$this->assertSame('Klingon Empire', $node->field_company[0]->entity->label());
|
||||
$this->assertSame('Romulan Empire', $node->field_company[1]->entity->label());
|
||||
$this->assertCount(1, $node->field_company_2);
|
||||
$this->assertSame('Klingon Empire', $node->field_company_2[0]->entity->label());
|
||||
$this->assertCount(1, $node->field_company_3);
|
||||
$this->assertSame('Romulan Empire', $node->field_company_3[0]->entity->label());
|
||||
|
||||
// Test that user reference field values were migrated.
|
||||
$this->assertCount(1, $node->field_commander);
|
||||
@@ -223,7 +233,7 @@ class MigrateNodeTest extends MigrateNodeTestBase {
|
||||
$default_connection = \Drupal::database();
|
||||
$default_connection->truncate($table_name)->execute();
|
||||
if ($new_row) {
|
||||
$hash = $migration->getIdMap()->getSourceIDsHash(['nid' => $new_row['sourceid1']]);
|
||||
$hash = $migration->getIdMap()->getSourceIdsHash(['nid' => $new_row['sourceid1']]);
|
||||
$new_row['source_ids_hash'] = $hash;
|
||||
$default_connection->insert($table_name)
|
||||
->fields($new_row)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user