Update to drupal 8.0.0-rc1. For more information, see https://www.drupal.org/node/2582663
This commit is contained in:
parent
eb34d130a8
commit
f32e58e4b1
8476 changed files with 211648 additions and 170042 deletions
|
@ -1,8 +1,9 @@
|
|||
id: node.full
|
||||
label: 'Full content'
|
||||
langcode: en
|
||||
status: false
|
||||
cache: true
|
||||
targetEntityType: node
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node.full
|
||||
label: 'Full content'
|
||||
targetEntityType: node
|
||||
cache: true
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
id: node.rss
|
||||
label: RSS
|
||||
langcode: en
|
||||
status: false
|
||||
cache: true
|
||||
targetEntityType: node
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node.rss
|
||||
label: RSS
|
||||
targetEntityType: node
|
||||
cache: true
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
id: node.search_index
|
||||
label: 'Search index'
|
||||
langcode: en
|
||||
status: false
|
||||
cache: true
|
||||
targetEntityType: node
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node.search_index
|
||||
label: 'Search index'
|
||||
targetEntityType: node
|
||||
cache: true
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
id: node.search_result
|
||||
label: 'Search result highlighting input'
|
||||
langcode: en
|
||||
status: false
|
||||
cache: true
|
||||
targetEntityType: node
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node.search_result
|
||||
label: 'Search result highlighting input'
|
||||
targetEntityType: node
|
||||
cache: true
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
id: node.teaser
|
||||
label: Teaser
|
||||
langcode: en
|
||||
status: true
|
||||
cache: true
|
||||
targetEntityType: node
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node.teaser
|
||||
label: Teaser
|
||||
targetEntityType: node
|
||||
cache: true
|
||||
|
|
|
@ -15,3 +15,4 @@ cardinality: 1
|
|||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: true
|
||||
custom_storage: false
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
id: node_delete_action
|
||||
label: 'Delete content'
|
||||
status: true
|
||||
langcode: en
|
||||
type: node
|
||||
plugin: node_delete_action
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node_delete_action
|
||||
label: 'Delete content'
|
||||
type: node
|
||||
plugin: node_delete_action
|
||||
configuration: { }
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
id: node_make_sticky_action
|
||||
label: 'Make content sticky'
|
||||
status: true
|
||||
langcode: en
|
||||
type: node
|
||||
plugin: node_make_sticky_action
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node_make_sticky_action
|
||||
label: 'Make content sticky'
|
||||
type: node
|
||||
plugin: node_make_sticky_action
|
||||
configuration: { }
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
id: node_make_unsticky_action
|
||||
label: 'Make content unsticky'
|
||||
status: true
|
||||
langcode: en
|
||||
type: node
|
||||
plugin: node_make_unsticky_action
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node_make_unsticky_action
|
||||
label: 'Make content unsticky'
|
||||
type: node
|
||||
plugin: node_make_unsticky_action
|
||||
configuration: { }
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
id: node_promote_action
|
||||
label: 'Promote content to front page'
|
||||
status: true
|
||||
langcode: en
|
||||
type: node
|
||||
plugin: node_promote_action
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node_promote_action
|
||||
label: 'Promote content to front page'
|
||||
type: node
|
||||
plugin: node_promote_action
|
||||
configuration: { }
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
id: node_publish_action
|
||||
label: 'Publish content'
|
||||
status: true
|
||||
langcode: en
|
||||
type: node
|
||||
plugin: node_publish_action
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node_publish_action
|
||||
label: 'Publish content'
|
||||
type: node
|
||||
plugin: node_publish_action
|
||||
configuration: { }
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
id: node_save_action
|
||||
label: 'Save content'
|
||||
status: true
|
||||
langcode: en
|
||||
type: node
|
||||
plugin: node_save_action
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node_save_action
|
||||
label: 'Save content'
|
||||
type: node
|
||||
plugin: node_save_action
|
||||
configuration: { }
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
id: node_unpromote_action
|
||||
label: 'Remove content from front page'
|
||||
status: true
|
||||
langcode: en
|
||||
type: node
|
||||
plugin: node_unpromote_action
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node_unpromote_action
|
||||
label: 'Remove content from front page'
|
||||
type: node
|
||||
plugin: node_unpromote_action
|
||||
configuration: { }
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
id: node_unpublish_action
|
||||
label: 'Unpublish content'
|
||||
status: true
|
||||
langcode: en
|
||||
type: node
|
||||
plugin: node_unpublish_action
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node_unpublish_action
|
||||
label: 'Unpublish content'
|
||||
type: node
|
||||
plugin: node_unpublish_action
|
||||
configuration: { }
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: node_search
|
||||
label: Content
|
||||
status: true
|
||||
langcode: en
|
||||
path: node
|
||||
weight: -10
|
||||
plugin: node_search
|
||||
configuration:
|
||||
rankings: { }
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
langcode: en
|
||||
status: false
|
||||
dependencies:
|
||||
config:
|
||||
- core.entity_view_mode.node.teaser
|
||||
module:
|
||||
- node
|
||||
- user
|
||||
id: archive
|
||||
label: Archive
|
||||
module: node
|
||||
|
@ -87,7 +90,7 @@ display:
|
|||
exception:
|
||||
title_enable: true
|
||||
title_enable: true
|
||||
title: '%1'
|
||||
title: '{{ arguments.created_year_month }}'
|
||||
default_argument_type: fixed
|
||||
summary:
|
||||
sort_order: desc
|
||||
|
@ -166,6 +169,16 @@ display:
|
|||
empty: { }
|
||||
relationships: { }
|
||||
fields: { }
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- 'languages:language_interface'
|
||||
- url
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
max-age: -1
|
||||
tags: { }
|
||||
block_1:
|
||||
id: block_1
|
||||
display_title: Block
|
||||
|
@ -186,7 +199,7 @@ display:
|
|||
exception:
|
||||
title_enable: true
|
||||
title_enable: true
|
||||
title: '%1'
|
||||
title: '{{ arguments.created_year_month }}'
|
||||
default_argument_type: fixed
|
||||
summary:
|
||||
format: default_summary
|
||||
|
@ -195,6 +208,16 @@ display:
|
|||
specify_validation: true
|
||||
plugin_id: date_year_month
|
||||
entity_type: node
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- 'languages:language_interface'
|
||||
- url
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
max-age: -1
|
||||
tags: { }
|
||||
page_1:
|
||||
id: page_1
|
||||
display_title: Page
|
||||
|
@ -205,3 +228,13 @@ display:
|
|||
type: views_query
|
||||
options: { }
|
||||
path: archive
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- 'languages:language_interface'
|
||||
- url
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
max-age: -1
|
||||
tags: { }
|
||||
|
|
|
@ -38,10 +38,10 @@ display:
|
|||
options:
|
||||
items_per_page: 50
|
||||
tags:
|
||||
previous: '‹ previous'
|
||||
next: 'next ›'
|
||||
first: '« first'
|
||||
last: 'last »'
|
||||
previous: '‹ Previous'
|
||||
next: 'Next ›'
|
||||
first: '« First'
|
||||
last: 'Last »'
|
||||
style:
|
||||
type: table
|
||||
options:
|
||||
|
@ -561,11 +561,15 @@ display:
|
|||
position: 0
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- languages
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- url
|
||||
- url.query_args
|
||||
- user
|
||||
- 'user.node_grants:view'
|
||||
cacheable: false
|
||||
- user.permissions
|
||||
max-age: 0
|
||||
tags: { }
|
||||
page_1:
|
||||
display_options:
|
||||
path: admin/content/node
|
||||
|
@ -589,8 +593,12 @@ display:
|
|||
position: 1
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- languages
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- url
|
||||
- url.query_args
|
||||
- user
|
||||
- 'user.node_grants:view'
|
||||
cacheable: false
|
||||
- user.permissions
|
||||
max-age: 0
|
||||
tags: { }
|
||||
|
|
|
@ -296,7 +296,8 @@ display:
|
|||
- user
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
cacheable: false
|
||||
max-age: 0
|
||||
tags: { }
|
||||
block_1:
|
||||
display_plugin: block
|
||||
id: block_1
|
||||
|
@ -311,4 +312,5 @@ display:
|
|||
- user
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
cacheable: false
|
||||
max-age: 0
|
||||
tags: { }
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- core.entity_view_mode.node.rss
|
||||
- core.entity_view_mode.node.teaser
|
||||
module:
|
||||
- node
|
||||
- user
|
||||
|
@ -173,10 +176,10 @@ display:
|
|||
offset: false
|
||||
offset_label: Offset
|
||||
tags:
|
||||
previous: '‹ previous'
|
||||
next: 'next ›'
|
||||
first: '« first'
|
||||
last: 'last »'
|
||||
previous: '‹ Previous'
|
||||
next: 'Next ›'
|
||||
first: '« First'
|
||||
last: 'Last »'
|
||||
quantity: 9
|
||||
query:
|
||||
type: views_query
|
||||
|
@ -233,10 +236,19 @@ display:
|
|||
relationships: { }
|
||||
fields: { }
|
||||
arguments: { }
|
||||
display_extenders: { }
|
||||
display_plugin: default
|
||||
display_title: Master
|
||||
id: default
|
||||
position: 0
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- 'languages:language_interface'
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
max-age: -1
|
||||
tags: { }
|
||||
feed_1:
|
||||
display_plugin: feed
|
||||
id: feed_1
|
||||
|
@ -264,10 +276,27 @@ display:
|
|||
options:
|
||||
relationship: none
|
||||
view_mode: rss
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- 'languages:language_interface'
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
max-age: -1
|
||||
tags: { }
|
||||
page_1:
|
||||
display_options:
|
||||
path: node
|
||||
display_extenders: { }
|
||||
display_plugin: page
|
||||
display_title: Page
|
||||
id: page_1
|
||||
position: 1
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- 'languages:language_interface'
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
max-age: -1
|
||||
tags: { }
|
||||
|
|
|
@ -346,6 +346,17 @@ display:
|
|||
plugin_id: language
|
||||
entity_type: node
|
||||
entity_field: langcode
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- url
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
max-age: 0
|
||||
tags: { }
|
||||
attachment_1:
|
||||
id: attachment_1
|
||||
display_title: Attachment
|
||||
|
@ -403,6 +414,17 @@ display:
|
|||
default: default
|
||||
page_1: page_1
|
||||
inherit_arguments: false
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- url
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
max-age: 0
|
||||
tags: { }
|
||||
page_1:
|
||||
id: page_1
|
||||
display_title: Page
|
||||
|
@ -419,3 +441,14 @@ display:
|
|||
weight: 0
|
||||
menu_name: main
|
||||
parent: ''
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- url
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
max-age: 0
|
||||
tags: { }
|
||||
|
|
|
@ -90,7 +90,7 @@ action.configuration.node_unpublish_by_keyword_action:
|
|||
type: mapping
|
||||
label: 'Unpublish content containing keyword(s) configuration'
|
||||
mapping:
|
||||
keyword:
|
||||
keywords:
|
||||
type: sequence
|
||||
label: 'Keywords'
|
||||
sequence:
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
$('#edit-language', context).drupalSetSummary(function (context) {
|
||||
var vals = [];
|
||||
|
||||
vals.push($(".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()));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d6_node
|
||||
label: Drupal 6 nodes
|
||||
label: Nodes
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
builder:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d6_node_revision
|
||||
label: Drupal 6 node revisions
|
||||
label: Node revisions
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
builder:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d6_node_setting_promote
|
||||
label: Drupal 6 node type 'promote' setting
|
||||
label: Node type 'promote' setting
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
|
@ -11,6 +11,9 @@ process:
|
|||
entity_type: 'constants/entity_type'
|
||||
bundle: type
|
||||
field_name: 'constants/field_name'
|
||||
label:
|
||||
plugin: default_value
|
||||
default_value: 'Promoted to front page'
|
||||
'default_value/0/value': 'options/promote'
|
||||
destination:
|
||||
plugin: entity:base_field_override
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d6_node_setting_status
|
||||
label: Drupal 6 node type 'status' setting
|
||||
label: Node type 'status' setting
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d6_node_setting_sticky
|
||||
label: Drupal 6 node type 'sticky' setting
|
||||
label: Node type 'sticky' setting
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
|
@ -11,6 +11,9 @@ process:
|
|||
entity_type: 'constants/entity_type'
|
||||
bundle: type
|
||||
field_name: 'constants/field_name'
|
||||
label:
|
||||
plugin: default_value
|
||||
default_value: 'Sticky at the top of lists'
|
||||
'default_value/0/value': 'options/sticky'
|
||||
destination:
|
||||
plugin: entity:base_field_override
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d6_node_settings
|
||||
label: Drupal 6 node configuration
|
||||
label: Node configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d6_node_type
|
||||
label: Drupal 6 node type configuration
|
||||
label: Node type configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d6_view_modes
|
||||
label: Drupal 6 view modes
|
||||
label: View modes
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d7_node
|
||||
label: Drupal 7 nodes
|
||||
label: Nodes
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
builder:
|
||||
|
@ -30,3 +30,5 @@ migration_dependencies:
|
|||
required:
|
||||
- d7_user
|
||||
- d7_node_type
|
||||
optional:
|
||||
- d7_field_instance
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d7_node_revision
|
||||
label: Drupal 7 node revisions
|
||||
label: Node revisions
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
builder:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d7_node_settings
|
||||
label: Drupal 7 node configuration
|
||||
label: Node configuration
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
source:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d7_node_title_label
|
||||
label: Drupal 7 node title label
|
||||
label: Node title label
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
source:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: d7_node_type
|
||||
label: Drupal 7 node type configuration
|
||||
label: Node type configuration
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
source:
|
||||
|
|
|
@ -319,15 +319,13 @@ function hook_node_grants_alter(&$grants, \Drupal\Core\Session\AccountInterface
|
|||
* - "view"
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user object to perform the access check operation on.
|
||||
* @param string $langcode
|
||||
* The language code to perform the access check operation on.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The access result.
|
||||
*
|
||||
* @ingroup node_access
|
||||
*/
|
||||
function hook_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account, $langcode) {
|
||||
function hook_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account) {
|
||||
$type = $node->bundle();
|
||||
|
||||
switch ($op) {
|
||||
|
@ -364,8 +362,6 @@ function hook_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Se
|
|||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The node being displayed in a search result.
|
||||
* @param string $langcode
|
||||
* Language code of result being displayed.
|
||||
*
|
||||
* @return array
|
||||
* Extra information to be displayed with search result. This information
|
||||
|
@ -378,7 +374,7 @@ function hook_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Se
|
|||
*
|
||||
* @ingroup entity_crud
|
||||
*/
|
||||
function hook_node_search_result(\Drupal\node\NodeInterface $node, $langcode) {
|
||||
function hook_node_search_result(\Drupal\node\NodeInterface $node) {
|
||||
$rating = db_query('SELECT SUM(points) FROM {my_rating} WHERE nid = :nid', array('nid' => $node->id()))->fetchField();
|
||||
return array('rating' => \Drupal::translation()->formatPlural($rating, '1 point', '@count points'));
|
||||
}
|
||||
|
@ -391,15 +387,13 @@ function hook_node_search_result(\Drupal\node\NodeInterface $node, $langcode) {
|
|||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The node being indexed.
|
||||
* @param string $langcode
|
||||
* Language code of the variant of the node being indexed.
|
||||
*
|
||||
* @return string
|
||||
* Additional node information to be indexed.
|
||||
*
|
||||
* @ingroup entity_crud
|
||||
*/
|
||||
function hook_node_update_index(\Drupal\node\NodeInterface $node, $langcode) {
|
||||
function hook_node_update_index(\Drupal\node\NodeInterface $node) {
|
||||
$text = '';
|
||||
$ratings = db_query('SELECT title, description FROM {my_ratings} WHERE nid = :nid', array(':nid' => $node->id()));
|
||||
foreach ($ratings as $rating) {
|
||||
|
|
|
@ -7,4 +7,3 @@ core: 8.x
|
|||
configure: entity.node_type.collection
|
||||
dependencies:
|
||||
- text
|
||||
- entity_reference
|
||||
|
|
|
@ -28,8 +28,8 @@ function node_requirements($phase) {
|
|||
$requirements['node_access'] = array(
|
||||
'title' => t('Node Access Permissions'),
|
||||
'value' => $value,
|
||||
'description' => t('If the site is experiencing problems with permissions to content, you may have to rebuild the permissions cache. Rebuilding will remove all privileges to content and replace them with permissions based on the current modules and settings. Rebuilding may take some time if there is a lot of content or complex permission settings. After rebuilding has completed, content will automatically use the new permissions. <a href="@rebuild">Rebuild permissions</a>', array(
|
||||
'@rebuild' => \Drupal::url('node.configure_rebuild_confirm'),
|
||||
'description' => t('If the site is experiencing problems with permissions to content, you may have to rebuild the permissions cache. Rebuilding will remove all privileges to content and replace them with permissions based on the current modules and settings. Rebuilding may take some time if there is a lot of content or complex permission settings. After rebuilding has completed, content will automatically use the new permissions. <a href=":rebuild">Rebuild permissions</a>', array(
|
||||
':rebuild' => \Drupal::url('node.configure_rebuild_confirm'),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
@ -197,10 +197,7 @@ function node_update_8003() {
|
|||
// The 'status' and 'uid' fields were added to the 'entity_keys' annotation
|
||||
// of \Drupal\node\Entity\Node in https://www.drupal.org/node/2498919, but
|
||||
// this update function wasn't added until
|
||||
// https://www.drupal.org/node/2542748. In between, sites could have
|
||||
// performed interim updates, which would have included automated entity
|
||||
// schema updates prior to that being removed (see that issue for details).
|
||||
// Therefore, we check for whether the keys have already been installed.
|
||||
// https://www.drupal.org/node/2542748.
|
||||
$manager = \Drupal::entityDefinitionUpdateManager();
|
||||
$entity_type = $manager->getEntityType('node');
|
||||
$entity_keys = $entity_type->getKeys();
|
||||
|
@ -212,10 +209,10 @@ function node_update_8003() {
|
|||
// @todo The above should be enough, since that is the only definition that
|
||||
// changed. But \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema varies
|
||||
// field schema by whether a field is an entity key, so invoke
|
||||
// onFieldStorageDefinitionUpdate() with an unmodified
|
||||
// $field_storage_definition to trigger the necessary changes.
|
||||
// SqlContentEntityStorageSchema::onEntityTypeUpdate() should be fixed to
|
||||
// automatically handle this.
|
||||
// EntityDefinitionUpdateManagerInterface::updateFieldStorageDefinition()
|
||||
// with an unmodified field storage definition to trigger the necessary
|
||||
// changes. SqlContentEntityStorageSchema::onEntityTypeUpdate() should be
|
||||
// fixed to automatically handle this.
|
||||
// See https://www.drupal.org/node/2554245.
|
||||
foreach (array('status', 'uid') as $field_name) {
|
||||
$manager->updateFieldStorageDefinition($manager->getFieldStorageDefinition($field_name, 'node'));
|
||||
|
|
|
@ -20,14 +20,14 @@
|
|||
var $context = $(context);
|
||||
$context.find('.node-form-revision-information').drupalSetSummary(function (context) {
|
||||
var $revisionContext = $(context);
|
||||
var revisionCheckbox = $revisionContext.find('.form-item-revision input');
|
||||
var revisionCheckbox = $revisionContext.find('.js-form-item-revision input');
|
||||
|
||||
// Return 'New revision' if the 'Create new revision' checkbox is
|
||||
// checked, or if the checkbox doesn't exist, but the revision log does.
|
||||
// For users without the "Administer content" permission the checkbox
|
||||
// won't appear, but the revision log will if the content type is set to
|
||||
// auto-revision.
|
||||
if (revisionCheckbox.is(':checked') || (!revisionCheckbox.length && $revisionContext.find('.form-item-revision-log textarea').length)) {
|
||||
// Return 'New revision' if the 'Create new revision' checkbox is
|
||||
// checked, or if the checkbox doesn't exist, but the revision log does.
|
||||
// For users without the "Administer content" permission the checkbox
|
||||
// won't appear, but the revision log will if the content type is set to
|
||||
// auto-revision.
|
||||
if (revisionCheckbox.is(':checked') || (!revisionCheckbox.length && $revisionContext.find('.js-form-item-revision-log textarea').length)) {
|
||||
return Drupal.t('New revision');
|
||||
}
|
||||
|
||||
|
@ -61,13 +61,13 @@
|
|||
$context.find('fieldset.node-translation-options').drupalSetSummary(function (context) {
|
||||
var $translationContext = $(context);
|
||||
var translate;
|
||||
var $checkbox = $translationContext.find('.form-item-translation-translate input');
|
||||
var $checkbox = $translationContext.find('.js-form-item-translation-translate input');
|
||||
|
||||
if ($checkbox.size()) {
|
||||
translate = $checkbox.is(':checked') ? Drupal.t('Needs to be updated') : Drupal.t('Does not need to be updated');
|
||||
}
|
||||
else {
|
||||
$checkbox = $translationContext.find('.form-item-translation-retranslate input');
|
||||
$checkbox = $translationContext.find('.js-form-item-translation-retranslate input');
|
||||
translate = $checkbox.is(':checked') ? Drupal.t('Flag other translations as outdated') : Drupal.t('Do not flag other translations as outdated');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
entity.node_type.collection:
|
||||
title: 'Content types'
|
||||
parent: system.admin_structure
|
||||
description: 'Manage content types, including default status, front page promotion, comment settings, etc.'
|
||||
description: 'Create content types and manage their default settings.'
|
||||
route_name: entity.node_type.collection
|
||||
node.add_page:
|
||||
title: 'Add content'
|
||||
|
|
|
@ -73,7 +73,7 @@ function node_help($route_name, RouteMatchInterface $route_match) {
|
|||
$message = t('The content access permissions need to be rebuilt.');
|
||||
}
|
||||
else {
|
||||
$message = t('The content access permissions need to be rebuilt. <a href="@node_access_rebuild">Rebuild permissions</a>.', array('@node_access_rebuild' => \Drupal::url('node.configure_rebuild_confirm')));
|
||||
$message = t('The content access permissions need to be rebuilt. <a href=":node_access_rebuild">Rebuild permissions</a>.', array(':node_access_rebuild' => \Drupal::url('node.configure_rebuild_confirm')));
|
||||
}
|
||||
drupal_set_message($message, 'error');
|
||||
}
|
||||
|
@ -82,19 +82,19 @@ function node_help($route_name, RouteMatchInterface $route_match) {
|
|||
case 'help.page.node':
|
||||
$output = '';
|
||||
$output .= '<h3>' . t('About') . '</h3>';
|
||||
$output .= '<p>' . t('The Node module manages the creation, editing, deletion, settings, and display of the main site content. Content items managed by the Node module are typically displayed as pages on your site, and include a title, some meta-data (author, creation time, content type, etc.), and optional fields containing text or other data (fields are managed by the <a href="!field">Field module</a>). For more information, see <a href="!node">the online documentation for the Node module</a>.', array('!node' => 'https://www.drupal.org/documentation/modules/node', '!field' => \Drupal::url('help.page', array('name' => 'field')))) . '</p>';
|
||||
$output .= '<p>' . t('The Node module manages the creation, editing, deletion, settings, and display of the main site content. Content items managed by the Node module are typically displayed as pages on your site, and include a title, some meta-data (author, creation time, content type, etc.), and optional fields containing text or other data (fields are managed by the <a href=":field">Field module</a>). For more information, see the <a href=":node">online documentation for the Node module</a>.', array(':node' => 'https://www.drupal.org/documentation/modules/node', ':field' => \Drupal::url('help.page', array('name' => 'field')))) . '</p>';
|
||||
$output .= '<h3>' . t('Uses') . '</h3>';
|
||||
$output .= '<dl>';
|
||||
$output .= '<dt>' . t('Creating content') . '</dt>';
|
||||
$output .= '<dd>' . t('When new content is created, the Node module records basic information about the content, including the author, date of creation, and the <a href="!content-type">Content type</a>. It also manages the <em>publishing options</em>, which define whether or not the content is published, promoted to the front page of the site, and/or sticky at the top of content lists. Default settings can be configured for each <a href="!content-type">type of content</a> on your site.', array('!content-type' => \Drupal::url('entity.node_type.collection'))) . '</dd>';
|
||||
$output .= '<dd>' . t('When new content is created, the Node module records basic information about the content, including the author, date of creation, and the <a href=":content-type">Content type</a>. It also manages the <em>publishing options</em>, which define whether or not the content is published, promoted to the front page of the site, and/or sticky at the top of content lists. Default settings can be configured for each <a href=":content-type">type of content</a> on your site.', array(':content-type' => \Drupal::url('entity.node_type.collection'))) . '</dd>';
|
||||
$output .= '<dt>' . t('Creating custom content types') . '</dt>';
|
||||
$output .= '<dd>' . t('The Node module gives users with the <em>Administer content types</em> permission the ability to <a href="!content-new">create new content types</a> in addition to the default ones already configured. Creating custom content types gives you the flexibility to add <a href="!field">fields</a> and configure default settings that suit the differing needs of various site content.', array('!content-new' => \Drupal::url('node.type_add'), '!field' => \Drupal::url('help.page', array('name' => 'field')))) . '</dd>';
|
||||
$output .= '<dd>' . t('The Node module gives users with the <em>Administer content types</em> permission the ability to <a href=":content-new">create new content types</a> in addition to the default ones already configured. Creating custom content types gives you the flexibility to add <a href=":field">fields</a> and configure default settings that suit the differing needs of various site content.', array(':content-new' => \Drupal::url('node.type_add'), ':field' => \Drupal::url('help.page', array('name' => 'field')))) . '</dd>';
|
||||
$output .= '<dt>' . t('Administering content') . '</dt>';
|
||||
$output .= '<dd>' . t('The <a href="!content">Content</a> page lists your content, allowing you add new content, filter, edit or delete existing content, or perform bulk operations on existing content.', array('!content' => \Drupal::url('system.admin_content'))) . '</dd>';
|
||||
$output .= '<dd>' . t('The <a href=":content">Content</a> page lists your content, allowing you add new content, filter, edit or delete existing content, or perform bulk operations on existing content.', array(':content' => \Drupal::url('system.admin_content'))) . '</dd>';
|
||||
$output .= '<dt>' . t('Creating revisions') . '</dt>';
|
||||
$output .= '<dd>' . t('The Node module also enables you to create multiple versions of any content, and revert to older versions using the <em>Revision information</em> settings.') . '</dd>';
|
||||
$output .= '<dt>' . t('User permissions') . '</dt>';
|
||||
$output .= '<dd>' . t('The Node module makes a number of permissions available for each content type, which can be set by role on the <a href="!permissions">permissions page</a>.', array('!permissions' => \Drupal::url('user.admin_permissions', array(), array('fragment' => 'module-node')))) . '</dd>';
|
||||
$output .= '<dd>' . t('The Node module makes a number of permissions available for each content type, which can be set by role on the <a href=":permissions">permissions page</a>.', array(':permissions' => \Drupal::url('user.admin_permissions', array(), array('fragment' => 'module-node')))) . '</dd>';
|
||||
$output .= '</dl>';
|
||||
return $output;
|
||||
|
||||
|
@ -1340,3 +1340,10 @@ function node_comment_delete($comment) {
|
|||
node_reindex_node_search($comment->getCommentedEntityId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_config_translation_info_alter().
|
||||
*/
|
||||
function node_config_translation_info_alter(&$info) {
|
||||
$info['node_type']['class'] = 'Drupal\node\ConfigTranslation\NodeTypeMapper';
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@ bypass node access:
|
|||
restrict access: true
|
||||
administer content types:
|
||||
title: 'Administer content types'
|
||||
description: 'Promote, change ownership, edit revisions, and perform other tasks across all content types.'
|
||||
description: 'Maintain the types of content available and the fields that are associated with those types.'
|
||||
restrict access: true
|
||||
administer nodes:
|
||||
title: 'Administer content'
|
||||
description: 'Promote, change ownership, edit revisions, and perform other tasks across all content types.'
|
||||
restrict access: true
|
||||
access content overview:
|
||||
title: 'Access the Content overview page'
|
||||
|
|
|
@ -68,6 +68,16 @@ node.revision_revert_confirm:
|
|||
options:
|
||||
_node_operation_route: TRUE
|
||||
|
||||
node.revision_revert_translation_confirm:
|
||||
path: '/node/{node}/revisions/{node_revision}/revert/{langcode}'
|
||||
defaults:
|
||||
_form: '\Drupal\node\Form\NodeRevisionRevertTranslationForm'
|
||||
_title: 'Revert to earlier revision of a translation'
|
||||
requirements:
|
||||
_access_node_revision: 'update'
|
||||
options:
|
||||
_node_operation_route: TRUE
|
||||
|
||||
node.revision_delete_confirm:
|
||||
path: '/node/{node}/revisions/{node_revision}/delete'
|
||||
defaults:
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* Builds placeholder replacement tokens for node-related data.
|
||||
*/
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Datetime\Entity\DateFormat;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Render\BubbleableMetadata;
|
||||
|
@ -96,8 +95,6 @@ function node_tokens($type, $tokens, array $data, array $options, BubbleableMeta
|
|||
else {
|
||||
$langcode = LanguageInterface::LANGCODE_DEFAULT;
|
||||
}
|
||||
$sanitize = !empty($options['sanitize']);
|
||||
|
||||
$replacements = array();
|
||||
|
||||
if ($type == 'node' && !empty($data['node'])) {
|
||||
|
@ -116,16 +113,16 @@ function node_tokens($type, $tokens, array $data, array $options, BubbleableMeta
|
|||
break;
|
||||
|
||||
case 'type':
|
||||
$replacements[$original] = $sanitize ? Html::escape($node->getType()) : $node->getType();
|
||||
$replacements[$original] = $node->getType();
|
||||
break;
|
||||
|
||||
case 'type-name':
|
||||
$type_name = node_get_type_label($node);
|
||||
$replacements[$original] = $sanitize ? Html::escape($type_name) : $type_name;
|
||||
$replacements[$original] = $type_name;
|
||||
break;
|
||||
|
||||
case 'title':
|
||||
$replacements[$original] = $sanitize ? Html::escape($node->getTitle()) : $node->getTitle();
|
||||
$replacements[$original] = $node->getTitle();
|
||||
break;
|
||||
|
||||
case 'body':
|
||||
|
@ -133,14 +130,13 @@ function node_tokens($type, $tokens, array $data, array $options, BubbleableMeta
|
|||
$translation = \Drupal::entityManager()->getTranslationFromContext($node, $langcode, array('operation' => 'node_tokens'));
|
||||
if ($translation->hasField('body') && ($items = $translation->get('body')) && !$items->isEmpty()) {
|
||||
$item = $items[0];
|
||||
$field_definition = \Drupal::entityManager()->getFieldDefinitions('node', $node->bundle())['body'];
|
||||
// If the summary was requested and is not empty, use it.
|
||||
if ($name == 'summary' && !empty($item->summary)) {
|
||||
$output = $sanitize ? $item->summary_processed : $item->summary;
|
||||
$output = $item->summary_processed;
|
||||
}
|
||||
// Attempt to provide a suitable version of the 'body' field.
|
||||
else {
|
||||
$output = $sanitize ? $item->processed : $item->value;
|
||||
$output = $item->processed;
|
||||
// A summary was requested.
|
||||
if ($name == 'summary') {
|
||||
// Generate an optionally trimmed summary of the body field.
|
||||
|
@ -159,12 +155,14 @@ function node_tokens($type, $tokens, array $data, array $options, BubbleableMeta
|
|||
$output = text_summary($output, $item->format, $length);
|
||||
}
|
||||
}
|
||||
// "processed" returns a \Drupal\Component\Render\MarkupInterface
|
||||
// via check_markup().
|
||||
$replacements[$original] = $output;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'langcode':
|
||||
$replacements[$original] = $sanitize ? Html::escape($node->language()->getId()) : $node->language()->getId();
|
||||
$replacements[$original] = $node->language()->getId();
|
||||
break;
|
||||
|
||||
case 'url':
|
||||
|
@ -179,7 +177,7 @@ function node_tokens($type, $tokens, array $data, array $options, BubbleableMeta
|
|||
case 'author':
|
||||
$account = $node->getOwner() ? $node->getOwner() : User::load(0);
|
||||
$bubbleable_metadata->addCacheableDependency($account);
|
||||
$replacements[$original] = $sanitize ? Html::escape($account->label()) : $account->label();
|
||||
$replacements[$original] = $account->label();
|
||||
break;
|
||||
|
||||
case 'created':
|
||||
|
|
|
@ -92,15 +92,11 @@ class NodeRevisionAccessCheck implements AccessInterface {
|
|||
* performed.
|
||||
* @param string $op
|
||||
* (optional) The specific operation being checked. Defaults to 'view.'
|
||||
* @param string|null $langcode
|
||||
* (optional) Language code for the variant of the node. Different language
|
||||
* variants might have different permissions associated. If NULL, the
|
||||
* original langcode of the node is used. Defaults to NULL.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the operation may be performed, FALSE otherwise.
|
||||
*/
|
||||
public function checkAccess(NodeInterface $node, AccountInterface $account, $op = 'view', $langcode = NULL) {
|
||||
public function checkAccess(NodeInterface $node, AccountInterface $account, $op = 'view') {
|
||||
$map = array(
|
||||
'view' => 'view all revisions',
|
||||
'update' => 'revert all revisions',
|
||||
|
@ -119,13 +115,9 @@ class NodeRevisionAccessCheck implements AccessInterface {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// If no language code was provided, default to the node revision's langcode.
|
||||
if (empty($langcode)) {
|
||||
$langcode = $node->language()->getId();
|
||||
}
|
||||
|
||||
// Statically cache access by revision ID, language code, user account ID,
|
||||
// and operation.
|
||||
$langcode = $node->language()->getId();
|
||||
$cid = $node->getRevisionId() . ':' . $langcode . ':' . $account->id() . ':' . $op;
|
||||
|
||||
if (!isset($this->access[$cid])) {
|
||||
|
@ -149,7 +141,7 @@ class NodeRevisionAccessCheck implements AccessInterface {
|
|||
else {
|
||||
// First check the access to the default revision and finally, if the
|
||||
// node passed in is not the default revision then access to that, too.
|
||||
$this->access[$cid] = $this->nodeAccess->access($this->nodeStorage->load($node->id()), $op, $langcode, $account) && ($node->isDefaultRevision() || $this->nodeAccess->access($node, $op, $langcode, $account));
|
||||
$this->access[$cid] = $this->nodeAccess->access($this->nodeStorage->load($node->id()), $op, $account) && ($node->isDefaultRevision() || $this->nodeAccess->access($node, $op, $account));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
29
core/modules/node/src/ConfigTranslation/NodeTypeMapper.php
Normal file
29
core/modules/node/src/ConfigTranslation/NodeTypeMapper.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\node\ConfigTranslation\NodeTypeMapper.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\ConfigTranslation;
|
||||
|
||||
use Drupal\config_translation\ConfigEntityMapper;
|
||||
use Drupal\Core\Config\Entity\ConfigEntityInterface;
|
||||
|
||||
/**
|
||||
* Provides a configuration mapper for node types.
|
||||
*/
|
||||
class NodeTypeMapper extends ConfigEntityMapper {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setEntity(ConfigEntityInterface $entity) {
|
||||
parent::setEntity($entity);
|
||||
|
||||
// Adds the title label to the translation form.
|
||||
$node_type = $entity->id();
|
||||
$this->addConfigName("core.base_field_override.node.$node_type.title");
|
||||
}
|
||||
|
||||
}
|
|
@ -13,12 +13,15 @@ use Drupal\Core\Plugin\Context\ContextDefinition;
|
|||
use Drupal\Core\Plugin\Context\ContextProviderInterface;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* Sets the current node as a context on node routes.
|
||||
*/
|
||||
class NodeRouteContext implements ContextProviderInterface {
|
||||
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* The route match object.
|
||||
*
|
||||
|
@ -41,18 +44,22 @@ class NodeRouteContext implements ContextProviderInterface {
|
|||
*/
|
||||
public function getRuntimeContexts(array $unqualified_context_ids) {
|
||||
$result = [];
|
||||
$context = new Context(new ContextDefinition('entity:node', NULL, FALSE));
|
||||
$context_definition = new ContextDefinition('entity:node', NULL, 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')) {
|
||||
$context->setContextValue($node);
|
||||
$value = $node;
|
||||
}
|
||||
}
|
||||
elseif ($this->routeMatch->getRouteName() == 'node.add') {
|
||||
$node_type = $this->routeMatch->getParameter('node_type');
|
||||
$context->setContextValue(Node::create(array('type' => $node_type->id())));
|
||||
$value = Node::create(array('type' => $node_type->id()));
|
||||
}
|
||||
|
||||
$cacheability = new CacheableMetadata();
|
||||
$cacheability->setCacheContexts(['route']);
|
||||
|
||||
$context = new Context($context_definition, $value);
|
||||
$context->addCacheableDependency($cacheability);
|
||||
$result['node'] = $context;
|
||||
|
||||
|
@ -63,7 +70,7 @@ class NodeRouteContext implements ContextProviderInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAvailableContexts() {
|
||||
$context = new Context(new ContextDefinition('entity:node'));
|
||||
$context = new Context(new ContextDefinition('entity:node', $this->t('Node from URL')));
|
||||
return ['node' => $context];
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,9 @@ namespace Drupal\node\Controller;
|
|||
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Datetime\DateFormatter;
|
||||
use Drupal\Core\Datetime\DateFormatterInterface;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\node\NodeTypeInterface;
|
||||
|
@ -25,7 +26,7 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
|
|||
/**
|
||||
* The date formatter service.
|
||||
*
|
||||
* @var \Drupal\Core\Datetime\DateFormatter
|
||||
* @var \Drupal\Core\Datetime\DateFormatterInterface
|
||||
*/
|
||||
protected $dateFormatter;
|
||||
|
||||
|
@ -39,12 +40,12 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
|
|||
/**
|
||||
* Constructs a NodeController object.
|
||||
*
|
||||
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter
|
||||
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
|
||||
* The date formatter service.
|
||||
* @param \Drupal\Core\Render\RendererInterface $renderer
|
||||
* The renderer service.
|
||||
*/
|
||||
public function __construct(DateFormatter $date_formatter, RendererInterface $renderer) {
|
||||
public function __construct(DateFormatterInterface $date_formatter, RendererInterface $renderer) {
|
||||
$this->dateFormatter = $date_formatter;
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
|
@ -71,13 +72,22 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
|
|||
* type.
|
||||
*/
|
||||
public function addPage() {
|
||||
$build = [
|
||||
'#theme' => 'node_add_list',
|
||||
'#cache' => [
|
||||
'tags' => $this->entityManager()->getDefinition('node_type')->getListCacheTags(),
|
||||
],
|
||||
];
|
||||
|
||||
$content = array();
|
||||
|
||||
// Only use node types the user has access to.
|
||||
foreach ($this->entityManager()->getStorage('node_type')->loadMultiple() as $type) {
|
||||
if ($this->entityManager()->getAccessControlHandler('node')->createAccess($type->id())) {
|
||||
$access = $this->entityManager()->getAccessControlHandler('node')->createAccess($type->id(), NULL, [], TRUE);
|
||||
if ($access->isAllowed()) {
|
||||
$content[$type->id()] = $type;
|
||||
}
|
||||
$this->renderer->addCacheableDependency($build, $access);
|
||||
}
|
||||
|
||||
// Bypass the node/add listing if only one content type is available.
|
||||
|
@ -86,10 +96,9 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
|
|||
return $this->redirect('node.add', array('node_type' => $type->id()));
|
||||
}
|
||||
|
||||
return array(
|
||||
'#theme' => 'node_add_list',
|
||||
'#content' => $content,
|
||||
);
|
||||
$build['#content'] = $content;
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,11 +162,14 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
|
|||
*/
|
||||
public function revisionOverview(NodeInterface $node) {
|
||||
$account = $this->currentUser();
|
||||
$langcode = $this->languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
|
||||
$langname = $this->languageManager()->getLanguageName($langcode);
|
||||
$languages = $node->getTranslationLanguages();
|
||||
$has_translations = (count($languages) > 1);
|
||||
$node_storage = $this->entityManager()->getStorage('node');
|
||||
$type = $node->getType();
|
||||
|
||||
$build = array();
|
||||
$build['#title'] = $this->t('Revisions for %title', array('%title' => $node->label()));
|
||||
$build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => $node->label()]) : $this->t('Revisions for %title', ['%title' => $node->label()]);
|
||||
$header = array($this->t('Revision'), $this->t('Operations'));
|
||||
|
||||
$revert_permission = (($account->hasPermission("revert $type revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes')) && $node->access('update'));
|
||||
|
@ -167,74 +179,83 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
|
|||
|
||||
$vids = $node_storage->revisionIds($node);
|
||||
|
||||
$latest_revision = TRUE;
|
||||
|
||||
foreach (array_reverse($vids) as $vid) {
|
||||
/** @var \Drupal\node\NodeInterface $revision */
|
||||
$revision = $node_storage->loadRevision($vid);
|
||||
$username = [
|
||||
'#theme' => 'username',
|
||||
'#account' => $revision->uid->entity,
|
||||
];
|
||||
|
||||
// Use revision link to link to revisions that are not active.
|
||||
$date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short');
|
||||
if ($vid != $node->getRevisionId()) {
|
||||
$link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid]));
|
||||
}
|
||||
else {
|
||||
$link = $node->link($date);
|
||||
}
|
||||
|
||||
$row = [];
|
||||
$column = [
|
||||
'data' => [
|
||||
'#type' => 'inline_template',
|
||||
'#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}',
|
||||
'#context' => [
|
||||
'date' => $link,
|
||||
'username' => $this->renderer->renderPlain($username),
|
||||
'message' => ['#markup' => $revision->revision_log->value, '#allowed_tags' => Xss::getHtmlTagList()],
|
||||
],
|
||||
],
|
||||
];
|
||||
// @todo Simplify once https://www.drupal.org/node/2334319 lands.
|
||||
$this->renderer->addCacheableDependency($column['data'], $username);
|
||||
$row[] = $column;
|
||||
|
||||
if ($vid == $node->getRevisionId()) {
|
||||
$row[0]['class'] = ['revision-current'];
|
||||
$row[] = [
|
||||
'data' => [
|
||||
'#prefix' => '<em>',
|
||||
'#markup' => $this->t('current revision'),
|
||||
'#suffix' => '</em>',
|
||||
],
|
||||
'class' => ['revision-current'],
|
||||
if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) {
|
||||
$username = [
|
||||
'#theme' => 'username',
|
||||
'#account' => $revision->uid->entity,
|
||||
];
|
||||
}
|
||||
else {
|
||||
$links = [];
|
||||
if ($revert_permission) {
|
||||
$links['revert'] = [
|
||||
'title' => $this->t('Revert'),
|
||||
'url' => Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid]),
|
||||
|
||||
// Use revision link to link to revisions that are not active.
|
||||
$date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short');
|
||||
if ($vid != $node->getRevisionId()) {
|
||||
$link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid]));
|
||||
}
|
||||
else {
|
||||
$link = $node->link($date);
|
||||
}
|
||||
|
||||
$row = [];
|
||||
$column = [
|
||||
'data' => [
|
||||
'#type' => 'inline_template',
|
||||
'#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}',
|
||||
'#context' => [
|
||||
'date' => $link,
|
||||
'username' => $this->renderer->renderPlain($username),
|
||||
'message' => ['#markup' => $revision->revision_log->value, '#allowed_tags' => Xss::getHtmlTagList()],
|
||||
],
|
||||
],
|
||||
];
|
||||
// @todo Simplify once https://www.drupal.org/node/2334319 lands.
|
||||
$this->renderer->addCacheableDependency($column['data'], $username);
|
||||
$row[] = $column;
|
||||
|
||||
if ($latest_revision) {
|
||||
$row[] = [
|
||||
'data' => [
|
||||
'#prefix' => '<em>',
|
||||
'#markup' => $this->t('Current revision'),
|
||||
'#suffix' => '</em>',
|
||||
],
|
||||
];
|
||||
foreach ($row as &$current) {
|
||||
$current['class'] = ['revision-current'];
|
||||
}
|
||||
$latest_revision = FALSE;
|
||||
}
|
||||
else {
|
||||
$links = [];
|
||||
if ($revert_permission) {
|
||||
$links['revert'] = [
|
||||
'title' => $this->t('Revert'),
|
||||
'url' => $has_translations ?
|
||||
Url::fromRoute('node.revision_revert_translation_confirm', ['node' => $node->id(), 'node_revision' => $vid, 'langcode' => $langcode]) :
|
||||
Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid]),
|
||||
];
|
||||
}
|
||||
|
||||
if ($delete_permission) {
|
||||
$links['delete'] = [
|
||||
'title' => $this->t('Delete'),
|
||||
'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid]),
|
||||
];
|
||||
}
|
||||
|
||||
$row[] = [
|
||||
'data' => [
|
||||
'#type' => 'operations',
|
||||
'#links' => $links,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
if ($delete_permission) {
|
||||
$links['delete'] = [
|
||||
'title' => $this->t('Delete'),
|
||||
'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid]),
|
||||
];
|
||||
}
|
||||
|
||||
$row[] = [
|
||||
'data' => [
|
||||
'#type' => 'operations',
|
||||
'#links' => $links,
|
||||
],
|
||||
];
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
$build['node_revisions_table'] = array(
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\node\Controller;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\Controller\EntityViewController;
|
||||
|
||||
|
@ -61,7 +60,7 @@ class NodePreviewController extends EntityViewController {
|
|||
* The page title.
|
||||
*/
|
||||
public function title(EntityInterface $node_preview) {
|
||||
return SafeMarkup::checkPlain($this->entityManager->getTranslationFromContext($node_preview)->label());
|
||||
return $this->entityManager->getTranslationFromContext($node_preview)->label();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -91,10 +91,15 @@ class Node extends ContentEntityBase implements NodeInterface {
|
|||
public function preSave(EntityStorageInterface $storage) {
|
||||
parent::preSave($storage);
|
||||
|
||||
// If no owner has been set explicitly, make the current user the owner.
|
||||
if (!$this->getOwner()) {
|
||||
$this->setOwnerId(\Drupal::currentUser()->id());
|
||||
foreach (array_keys($this->getTranslationLanguages()) as $langcode) {
|
||||
$translation = $this->getTranslation($langcode);
|
||||
|
||||
// If no owner has been set explicitly, make the anonymous user the owner.
|
||||
if (!$translation->getOwner()) {
|
||||
$translation->setOwnerId(0);
|
||||
}
|
||||
}
|
||||
|
||||
// If no revision author has been set explicitly, make the node owner the
|
||||
// revision author.
|
||||
if (!$this->getRevisionAuthor()) {
|
||||
|
@ -176,30 +181,9 @@ class Node extends ContentEntityBase implements NodeInterface {
|
|||
|
||||
return \Drupal::entityManager()
|
||||
->getAccessControlHandler($this->entityTypeId)
|
||||
->access($this, $operation, $this->prepareLangcode(), $account, $return_as_object);
|
||||
->access($this, $operation, $account, $return_as_object);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareLangcode() {
|
||||
$langcode = $this->language()->getId();
|
||||
// If the Language module is enabled, try to use the language from content
|
||||
// negotiation.
|
||||
if (\Drupal::moduleHandler()->moduleExists('language')) {
|
||||
// Load languages the node exists in.
|
||||
$node_translations = $this->getTranslationLanguages();
|
||||
// Load the language from content negotiation.
|
||||
$content_negotiation_langcode = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
|
||||
// If there is a translation available, use it.
|
||||
if (isset($node_translations[$content_negotiation_langcode])) {
|
||||
$langcode = $content_negotiation_langcode;
|
||||
}
|
||||
}
|
||||
return $langcode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -231,13 +215,6 @@ class Node extends ContentEntityBase implements NodeInterface {
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getChangedTime() {
|
||||
return $this->get('changed')->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -404,7 +381,6 @@ class Node extends ContentEntityBase implements NodeInterface {
|
|||
->setDescription(t('The username of the content author.'))
|
||||
->setRevisionable(TRUE)
|
||||
->setSetting('target_type', 'user')
|
||||
->setSetting('handler', 'default')
|
||||
->setDefaultValueCallback('Drupal\node\Entity\Node::getCurrentUserId')
|
||||
->setTranslatable(TRUE)
|
||||
->setDisplayOptions('view', array(
|
||||
|
@ -497,7 +473,7 @@ class Node extends ContentEntityBase implements NodeInterface {
|
|||
->setLabel(t('Revision log message'))
|
||||
->setDescription(t('Briefly describe the changes you have made.'))
|
||||
->setRevisionable(TRUE)
|
||||
->setTranslatable(TRUE)
|
||||
->setDefaultValue('')
|
||||
->setDisplayOptions('form', array(
|
||||
'type' => 'string_textarea',
|
||||
'weight' => 25,
|
||||
|
|
|
@ -86,7 +86,11 @@ class NodePreviewForm extends FormBase implements ContainerInjectionInterface {
|
|||
'#options' => array('attributes' => array('class' => array('node-preview-backlink'))) + $query_options,
|
||||
);
|
||||
|
||||
$view_mode_options = $this->getViewModeOptions($node);
|
||||
$view_mode_options = $this->entityManager->getViewModeOptionsByBundle('node', $node->bundle());
|
||||
|
||||
// Unset view modes that are not used in the front end.
|
||||
unset($view_mode_options['rss']);
|
||||
unset($view_mode_options['search_index']);
|
||||
|
||||
$form['uuid'] = array(
|
||||
'#type' => 'value',
|
||||
|
@ -124,46 +128,4 @@ class NodePreviewForm extends FormBase implements ContainerInjectionInterface {
|
|||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of available view modes for the current node.
|
||||
*
|
||||
* @param EntityInterface $node
|
||||
* The node being previewed.
|
||||
*
|
||||
* @return array
|
||||
* List of available view modes for the current node.
|
||||
*/
|
||||
protected function getViewModeOptions(EntityInterface $node) {
|
||||
$load_ids = array();
|
||||
$view_mode_options = array();
|
||||
|
||||
// Load all the node's view modes.
|
||||
$view_modes = $this->entityManager->getViewModes('node');
|
||||
|
||||
// Get the list of available view modes for the current node's bundle.
|
||||
$ids = $this->configFactory->listAll('core.entity_view_display.node.' . $node->bundle());
|
||||
foreach ($ids as $id) {
|
||||
$config_id = str_replace('core.entity_view_display' . '.', '', $id);
|
||||
$load_ids[] = $config_id;
|
||||
}
|
||||
$displays = entity_load_multiple('entity_view_display', $load_ids);
|
||||
|
||||
// Generate the display options array.
|
||||
foreach ($displays as $display) {
|
||||
|
||||
$view_mode_name = $display->get('mode');
|
||||
|
||||
// Skip view modes that are not used in the front end.
|
||||
if (in_array($view_mode_name, array('rss', 'search_index'))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($display->status()) {
|
||||
$view_mode_options[$view_mode_name] = ($view_mode_name == 'default') ? t('Default') : $view_modes[$view_mode_name]['label'];
|
||||
}
|
||||
}
|
||||
|
||||
return $view_mode_options;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\node\Form;
|
||||
|
||||
use Drupal\Core\Datetime\DateFormatter;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
@ -33,14 +34,24 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
|
|||
*/
|
||||
protected $nodeStorage;
|
||||
|
||||
/**
|
||||
* The date formatter service.
|
||||
*
|
||||
* @var \Drupal\Core\Datetime\DateFormatter
|
||||
*/
|
||||
protected $dateFormatter;
|
||||
|
||||
/**
|
||||
* Constructs a new NodeRevisionRevertForm.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $node_storage
|
||||
* The node storage.
|
||||
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter
|
||||
* The date formatter service.
|
||||
*/
|
||||
public function __construct(EntityStorageInterface $node_storage) {
|
||||
public function __construct(EntityStorageInterface $node_storage, DateFormatter $date_formatter) {
|
||||
$this->nodeStorage = $node_storage;
|
||||
$this->dateFormatter = $date_formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,7 +59,8 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
|
|||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getStorage('node')
|
||||
$container->get('entity.manager')->getStorage('node'),
|
||||
$container->get('date.formatter')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -63,7 +75,7 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return t('Are you sure you want to revert to the revision from %revision-date?', array('%revision-date' => format_date($this->revision->getRevisionCreationTime())));
|
||||
return t('Are you sure you want to revert to the revision from %revision-date?', ['%revision-date' => $this->dateFormatter->format($this->revision->getRevisionCreationTime())]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,17 +113,16 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$revision = $this->prepareRevertedRevision($this->revision);
|
||||
// The revision timestamp will be updated when the revision is saved. Keep
|
||||
// the original one for the confirmation message.
|
||||
$original_revision_timestamp = $this->revision->getRevisionCreationTime();
|
||||
|
||||
// The revision timestamp will be updated when the revision is saved. Keep the
|
||||
// original one for the confirmation message.
|
||||
$original_revision_timestamp = $revision->getRevisionCreationTime();
|
||||
$revision->revision_log = t('Copy of the revision from %date.', array('%date' => format_date($original_revision_timestamp)));
|
||||
$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->save();
|
||||
|
||||
$revision->save();
|
||||
|
||||
$this->logger('content')->notice('@type: reverted %title revision %revision.', array('@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.', array('@type' => node_get_type_label($this->revision), '%title' => $this->revision->label(), '%revision-date' => format_date($original_revision_timestamp))));
|
||||
$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)]));
|
||||
$form_state->setRedirect(
|
||||
'entity.node.version_history',
|
||||
array('node' => $this->revision->id())
|
||||
|
@ -123,34 +134,13 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
|
|||
*
|
||||
* @param \Drupal\node\NodeInterface $revision
|
||||
* The revision to be reverted.
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
*
|
||||
* @return \Drupal\node\NodeInterface
|
||||
* The prepared revision ready to be stored.
|
||||
*/
|
||||
protected function prepareRevertedRevision(NodeInterface $revision) {
|
||||
/** @var \Drupal\node\NodeInterface $default_revision */
|
||||
$default_revision = $this->nodeStorage->load($revision->id());
|
||||
|
||||
// If the entity is translated, make sure only translations affected by the
|
||||
// specified revision are reverted.
|
||||
$languages = $default_revision->getTranslationLanguages();
|
||||
if (count($languages) > 1) {
|
||||
// @todo Instead of processing all the available translations, we should
|
||||
// let the user decide which translations should be reverted. See
|
||||
// https://www.drupal.org/node/2465907.
|
||||
foreach ($languages as $langcode => $language) {
|
||||
if ($revision->hasTranslation($langcode) && !$revision->getTranslation($langcode)->isRevisionTranslationAffected()) {
|
||||
$revision_translation = $revision->getTranslation($langcode);
|
||||
$default_translation = $default_revision->getTranslation($langcode);
|
||||
foreach ($default_revision->getFieldDefinitions() as $field_name => $definition) {
|
||||
if ($definition->isTranslatable()) {
|
||||
$revision_translation->set($field_name, $default_translation->get($field_name)->getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareRevertedRevision(NodeInterface $revision, FormStateInterface $form_state) {
|
||||
$revision->setNewRevision();
|
||||
$revision->isDefaultRevision(TRUE);
|
||||
|
||||
|
|
123
core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php
Normal file
123
core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\node\Form\NodeRevisionRevertTranslationForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\Form;
|
||||
|
||||
use Drupal\Core\Datetime\DateFormatter;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a form for reverting a node revision for a single translation.
|
||||
*/
|
||||
class NodeRevisionRevertTranslationForm extends NodeRevisionRevertForm {
|
||||
|
||||
/**
|
||||
* The language to be reverted.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $langcode;
|
||||
|
||||
/**
|
||||
* The language manager.
|
||||
*
|
||||
* @var \Drupal\Core\Language\LanguageManagerInterface
|
||||
*/
|
||||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* Constructs a new NodeRevisionRevertTranslationForm.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $node_storage
|
||||
* The node storage.
|
||||
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter
|
||||
* The date formatter service.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
*/
|
||||
public function __construct(EntityStorageInterface $node_storage, DateFormatter $date_formatter, LanguageManagerInterface $language_manager) {
|
||||
parent::__construct($node_storage, $date_formatter);
|
||||
$this->languageManager = $language_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getStorage('node'),
|
||||
$container->get('date.formatter'),
|
||||
$container->get('language_manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'node_revision_revert_translation_confirm';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return t('Are you sure you want to revert @language translation to the revision from %revision-date?', ['@language' => $this->languageManager->getLanguageName($this->langcode), '%revision-date' => $this->dateFormatter->format($this->revision->getRevisionCreationTime())]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, $node_revision = NULL, $langcode = NULL) {
|
||||
$this->langcode = $langcode;
|
||||
$form = parent::buildForm($form, $form_state, $node_revision);
|
||||
|
||||
$form['revert_untranslated_fields'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Revert content shared among translations'),
|
||||
'#default_value' => FALSE,
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareRevertedRevision(NodeInterface $revision, FormStateInterface $form_state) {
|
||||
$revert_untranslated_fields = $form_state->getValue('revert_untranslated_fields');
|
||||
|
||||
/** @var \Drupal\node\NodeInterface $default_revision */
|
||||
$latest_revision = $this->nodeStorage->load($revision->id());
|
||||
$latest_revision_translation = $latest_revision->getTranslation($this->langcode);
|
||||
|
||||
$revision_translation = $revision->getTranslation($this->langcode);
|
||||
|
||||
foreach ($latest_revision_translation->getFieldDefinitions() as $field_name => $definition) {
|
||||
if ($definition->isTranslatable() || $revert_untranslated_fields) {
|
||||
$latest_revision_translation->set($field_name, $revision_translation->get($field_name)->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
$latest_revision_translation->setNewRevision();
|
||||
$latest_revision_translation->isDefaultRevision(TRUE);
|
||||
|
||||
return $latest_revision_translation;
|
||||
}
|
||||
|
||||
}
|
|
@ -60,7 +60,7 @@ class NodeAccessControlHandler extends EntityAccessControlHandler implements Nod
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access(EntityInterface $entity, $operation, $langcode = LanguageInterface::LANGCODE_DEFAULT, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
public function access(EntityInterface $entity, $operation, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
$account = $this->prepareUser($account);
|
||||
|
||||
if ($account->hasPermission('bypass node access')) {
|
||||
|
@ -71,7 +71,7 @@ class NodeAccessControlHandler extends EntityAccessControlHandler implements Nod
|
|||
$result = AccessResult::forbidden()->cachePerPermissions();
|
||||
return $return_as_object ? $result : $result->isAllowed();
|
||||
}
|
||||
$result = parent::access($entity, $operation, $langcode, $account, TRUE)->cachePerPermissions();
|
||||
$result = parent::access($entity, $operation, $account, TRUE)->cachePerPermissions();
|
||||
return $return_as_object ? $result : $result->isAllowed();
|
||||
}
|
||||
|
||||
|
@ -97,13 +97,12 @@ class NodeAccessControlHandler extends EntityAccessControlHandler implements Nod
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkAccess(EntityInterface $node, $operation, $langcode, AccountInterface $account) {
|
||||
protected function checkAccess(EntityInterface $node, $operation, AccountInterface $account) {
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
/** @var \Drupal\node\NodeInterface $translation */
|
||||
$translation = $node->getTranslation($langcode);
|
||||
|
||||
// Fetch information from the node object if possible.
|
||||
$status = $translation->isPublished();
|
||||
$uid = $translation->getOwnerId();
|
||||
$status = $node->isPublished();
|
||||
$uid = $node->getOwnerId();
|
||||
|
||||
// Check if authors can view their own unpublished nodes.
|
||||
if ($operation === 'view' && !$status && $account->hasPermission('view own unpublished content') && $account->isAuthenticated() && $account->id() == $uid) {
|
||||
|
@ -111,7 +110,7 @@ class NodeAccessControlHandler extends EntityAccessControlHandler implements Nod
|
|||
}
|
||||
|
||||
// Evaluate node grants.
|
||||
return $this->grantStorage->access($node, $operation, $langcode, $account);
|
||||
return $this->grantStorage->access($node, $operation, $account);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -83,7 +83,10 @@ class NodeForm extends ContentEntityForm {
|
|||
|
||||
if ($preview = $store->get($uuid)) {
|
||||
/** @var $preview \Drupal\Core\Form\FormStateInterface */
|
||||
$form_state = $preview;
|
||||
|
||||
foreach ($preview->getValues() as $name => $value) {
|
||||
$form_state->setValue($name, $value);
|
||||
}
|
||||
|
||||
// Rebuild the form.
|
||||
$form_state->setRebuild();
|
||||
|
@ -350,24 +353,6 @@ class NodeForm extends ContentEntityForm {
|
|||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildEntity(array $form, FormStateInterface $form_state) {
|
||||
/** @var \Drupal\node\NodeInterface $entity */
|
||||
$entity = parent::buildEntity($form, $form_state);
|
||||
// A user might assign the node author by entering a user name in the node
|
||||
// form, which we then need to translate to a user ID.
|
||||
// @todo: Remove it when https://www.drupal.org/node/2322525 is pushed.
|
||||
if (!empty($form_state->getValue('uid')[0]['target_id']) && $account = User::load($form_state->getValue('uid')[0]['target_id'])) {
|
||||
$entity->setOwnerId($account->id());
|
||||
}
|
||||
else {
|
||||
$entity->setOwnerId(0);
|
||||
}
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -67,14 +67,14 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access(NodeInterface $node, $operation, $langcode, AccountInterface $account) {
|
||||
public function access(NodeInterface $node, $operation, AccountInterface $account) {
|
||||
// If no module implements the hook or the node does not have an id there is
|
||||
// no point in querying the database for access grants.
|
||||
if (!$this->moduleHandler->getImplementations('node_grants') || !$node->id()) {
|
||||
// Return the equivalent of the default grant, defined by
|
||||
// self::writeDefault().
|
||||
if ($operation === 'view') {
|
||||
return AccessResult::allowedIf($node->getTranslation($langcode)->isPublished())->cacheUntilEntityChanges($node);
|
||||
return AccessResult::allowedIf($node->isPublished())->cacheUntilEntityChanges($node);
|
||||
}
|
||||
else {
|
||||
return AccessResult::neutral();
|
||||
|
@ -89,7 +89,7 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
|
|||
// Check for grants for this node and the correct langcode.
|
||||
$nids = $query->andConditionGroup()
|
||||
->condition('nid', $node->id())
|
||||
->condition('langcode', $langcode);
|
||||
->condition('langcode', $node->language()->getId());
|
||||
// If the node is published, also take the default grant into account. The
|
||||
// default is saved with a node ID of 0.
|
||||
$status = $node->isPublished();
|
||||
|
|
|
@ -102,8 +102,6 @@ interface NodeGrantDatabaseStorageInterface {
|
|||
* @param string $operation
|
||||
* The entity operation. Usually one of 'view', 'edit', 'create' or
|
||||
* 'delete'.
|
||||
* @param string $langcode
|
||||
* The language code for which to check access.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user for which to check access.
|
||||
*
|
||||
|
@ -115,7 +113,7 @@ interface NodeGrantDatabaseStorageInterface {
|
|||
* @see hook_node_access_records()
|
||||
* @see \Drupal\node\NodeGrantDatabaseStorageInterface::writeDefault()
|
||||
*/
|
||||
public function access(NodeInterface $node, $operation, $langcode, AccountInterface $account);
|
||||
public function access(NodeInterface $node, $operation, AccountInterface $account);
|
||||
|
||||
/**
|
||||
* Counts available node grants.
|
||||
|
|
|
@ -160,12 +160,4 @@ interface NodeInterface extends ContentEntityInterface, EntityChangedInterface,
|
|||
*/
|
||||
public function setRevisionAuthorId($uid);
|
||||
|
||||
/**
|
||||
* Prepares the langcode for a node.
|
||||
*
|
||||
* @return string
|
||||
* The langcode for this node.
|
||||
*/
|
||||
public function prepareLangcode();
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\node;
|
||||
|
||||
use Drupal\Core\Datetime\DateFormatter;
|
||||
use Drupal\Core\Datetime\DateFormatterInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityListBuilder;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
|
@ -26,7 +26,7 @@ class NodeListBuilder extends EntityListBuilder {
|
|||
/**
|
||||
* The date formatter service.
|
||||
*
|
||||
* @var \Drupal\Core\Datetime\DateFormatter
|
||||
* @var \Drupal\Core\Datetime\DateFormatterInterface
|
||||
*/
|
||||
protected $dateFormatter;
|
||||
|
||||
|
@ -44,12 +44,12 @@ class NodeListBuilder extends EntityListBuilder {
|
|||
* The entity type definition.
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
|
||||
* The entity storage class.
|
||||
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter
|
||||
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
|
||||
* The date formatter service.
|
||||
* @param \Drupal\Core\Routing\RedirectDestinationInterface $redirect_destination
|
||||
* The redirect destination service.
|
||||
*/
|
||||
public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, DateFormatter $date_formatter, RedirectDestinationInterface $redirect_destination) {
|
||||
public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, DateFormatterInterface $date_formatter, RedirectDestinationInterface $redirect_destination) {
|
||||
parent::__construct($entity_type, $storage);
|
||||
|
||||
$this->dateFormatter = $date_formatter;
|
||||
|
|
|
@ -78,10 +78,8 @@ class NodeTranslationHandler extends ContentTranslationHandler {
|
|||
if ($form_state->hasValue('content_translation')) {
|
||||
$translation = &$form_state->getValue('content_translation');
|
||||
$translation['status'] = $entity->isPublished();
|
||||
// $form['content_translation']['name'] is the equivalent field
|
||||
// for translation author uid.
|
||||
$account = $entity->uid->entity;
|
||||
$translation['name'] = $account ? $account->getUsername() : '';
|
||||
$translation['uid'] = $account ? $account->id() : 0;
|
||||
$translation['created'] = format_date($entity->created->value, 'custom', 'Y-m-d H:i:s O');
|
||||
}
|
||||
parent::entityFormEntityBuild($entity_type, $entity, $form, $form_state);
|
||||
|
|
|
@ -22,16 +22,25 @@ class NodeTypeAccessControlHandler extends EntityAccessControlHandler {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
|
||||
if ($operation == 'delete') {
|
||||
if ($entity->isLocked()) {
|
||||
return AccessResult::forbidden()->cacheUntilEntityChanges($entity);
|
||||
}
|
||||
else {
|
||||
return parent::checkAccess($entity, $operation, $langcode, $account)->cacheUntilEntityChanges($entity);
|
||||
}
|
||||
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
switch ($operation) {
|
||||
case 'view':
|
||||
return AccessResult::allowedIfHasPermission($account, 'access content');
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
if ($entity->isLocked()) {
|
||||
return AccessResult::forbidden()->cacheUntilEntityChanges($entity);
|
||||
}
|
||||
else {
|
||||
return parent::checkAccess($entity, $operation, $account)->cacheUntilEntityChanges($entity);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::checkAccess($entity, $operation, $account);
|
||||
break;
|
||||
}
|
||||
return parent::checkAccess($entity, $operation, $langcode, $account);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,18 +7,17 @@
|
|||
|
||||
namespace Drupal\node;
|
||||
|
||||
use Drupal\Core\Entity\EntityForm;
|
||||
use Drupal\Core\Entity\BundleEntityFormBase;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\language\Entity\ContentLanguageSettings;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Form controller for node type forms.
|
||||
*/
|
||||
class NodeTypeForm extends EntityForm {
|
||||
class NodeTypeForm extends BundleEntityFormBase {
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
|
@ -31,7 +30,7 @@ class NodeTypeForm extends EntityForm {
|
|||
* Constructs the NodeTypeForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager
|
||||
* The entity manager.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entity_manager) {
|
||||
$this->entityManager = $entity_manager;
|
||||
|
@ -96,7 +95,7 @@ class NodeTypeForm extends EntityForm {
|
|||
'#title' => t('Description'),
|
||||
'#type' => 'textarea',
|
||||
'#default_value' => $type->getDescription(),
|
||||
'#description' => t('Describe this content type. The text will be displayed on the <em>Add content</em> page.'),
|
||||
'#description' => t('This text will be displayed on the <em>Add new content</em> page.'),
|
||||
);
|
||||
|
||||
$form['additional_settings'] = array(
|
||||
|
@ -148,7 +147,8 @@ class NodeTypeForm extends EntityForm {
|
|||
// Prepare workflow options to be used for 'checkboxes' form element.
|
||||
$keys = array_keys(array_filter($workflow_options));
|
||||
$workflow_options = array_combine($keys, $keys);
|
||||
$form['workflow']['options'] = array('#type' => 'checkboxes',
|
||||
$form['workflow']['options'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => t('Default options'),
|
||||
'#default_value' => $workflow_options,
|
||||
'#options' => array(
|
||||
|
@ -187,7 +187,8 @@ class NodeTypeForm extends EntityForm {
|
|||
'#default_value' => $type->displaySubmitted(),
|
||||
'#description' => t('Author username and publish date will be displayed.'),
|
||||
);
|
||||
return $form;
|
||||
|
||||
return $this->protectBundleIdElement($form);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,7 +248,7 @@ class NodeTypeForm extends EntityForm {
|
|||
// @todo Make it possible to get default values without an entity.
|
||||
// https://www.drupal.org/node/2318187
|
||||
$node = $this->entityManager->getStorage('node')->create(array('type' => $type->id()));
|
||||
foreach (array('status', 'promote', 'sticky') as $field_name) {
|
||||
foreach (array('status', 'promote', 'sticky') as $field_name) {
|
||||
$value = (bool) $form_state->getValue(['options', $field_name]);
|
||||
if ($node->$field_name->value != $value) {
|
||||
$fields[$field_name]->getConfig($type->id())->setDefaultValue($value)->save();
|
||||
|
|
|
@ -60,8 +60,8 @@ 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()
|
||||
$build['table']['#empty'] = $this->t('No content types available. <a href=":link">Add content type</a>.', [
|
||||
':link' => Url::fromRoute('node.type_add')->toString()
|
||||
]);
|
||||
return $build;
|
||||
}
|
||||
|
|
|
@ -21,13 +21,13 @@ class NodeViewBuilder extends EntityViewBuilder {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildComponents(array &$build, array $entities, array $displays, $view_mode, $langcode = NULL) {
|
||||
public function buildComponents(array &$build, array $entities, array $displays, $view_mode) {
|
||||
/** @var \Drupal\node\NodeInterface[] $entities */
|
||||
if (empty($entities)) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent::buildComponents($build, $entities, $displays, $view_mode, $langcode);
|
||||
parent::buildComponents($build, $entities, $displays, $view_mode);
|
||||
|
||||
foreach ($entities as $id => $entity) {
|
||||
$bundle = $entity->bundle();
|
||||
|
@ -38,10 +38,9 @@ class NodeViewBuilder extends EntityViewBuilder {
|
|||
'#lazy_builder' => [get_called_class() . '::renderLinks', [
|
||||
$entity->id(),
|
||||
$view_mode,
|
||||
$langcode,
|
||||
$entity->language()->getId(),
|
||||
!empty($entity->in_preview),
|
||||
]],
|
||||
'#create_placeholder' => TRUE,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -61,8 +60,8 @@ class NodeViewBuilder extends EntityViewBuilder {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langcode) {
|
||||
$defaults = parent::getBuildDefaults($entity, $view_mode, $langcode);
|
||||
protected function getBuildDefaults(EntityInterface $entity, $view_mode) {
|
||||
$defaults = parent::getBuildDefaults($entity, $view_mode);
|
||||
|
||||
// Don't cache nodes that are in 'preview' mode.
|
||||
if (isset($defaults['#cache']) && isset($entity->in_preview)) {
|
||||
|
@ -149,9 +148,9 @@ class NodeViewBuilder extends EntityViewBuilder {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode, $langcode = NULL) {
|
||||
protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
|
||||
/** @var \Drupal\node\NodeInterface $entity */
|
||||
parent::alterBuild($build, $entity, $display, $view_mode, $langcode);
|
||||
parent::alterBuild($build, $entity, $display, $view_mode);
|
||||
if ($entity->id()) {
|
||||
$build['#contextual_links']['node'] = array(
|
||||
'route_parameters' =>array('node' => $entity->id()),
|
||||
|
|
|
@ -24,7 +24,7 @@ class NodeViewsData extends EntityViewsData {
|
|||
$data['node_field_data']['table']['base']['access query tag'] = 'node_access';
|
||||
$data['node_field_data']['table']['wizard_id'] = 'node';
|
||||
|
||||
$data['node_field_data']['nid']['field']['argument'] = [
|
||||
$data['node_field_data']['nid']['argument'] = [
|
||||
'id' => 'node_nid',
|
||||
'name field' => 'title',
|
||||
'numeric' => TRUE,
|
||||
|
|
|
@ -50,27 +50,4 @@ class SyndicateBlock extends BlockBase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::buildConfigurationForm($form, $form_state);
|
||||
|
||||
// @see ::getCacheMaxAge()
|
||||
$form['cache']['#disabled'] = TRUE;
|
||||
$form['cache']['max_age']['#value'] = Cache::PERMANENT;
|
||||
$form['cache']['#description'] = $this->t('This block is always cached forever, it is not configurable.');
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheMaxAge() {
|
||||
// The 'Syndicate' block is permanently cacheable, because its
|
||||
// contents can never change.
|
||||
return Cache::PERMANENT;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\node\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\SelectionBase;
|
||||
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
|
@ -21,7 +21,7 @@ use Drupal\Core\Form\FormStateInterface;
|
|||
* weight = 1
|
||||
* )
|
||||
*/
|
||||
class NodeSelection extends SelectionBase {
|
||||
class NodeSelection extends DefaultSelection {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\node\Plugin\Search;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Config\Config;
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Database\Query\SelectExtender;
|
||||
|
@ -167,6 +168,8 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
|
|||
$this->renderer = $renderer;
|
||||
$this->account = $account;
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->addCacheTags(['node_list']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -333,9 +336,10 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
|
|||
|
||||
// Fetch comments for snippet.
|
||||
$rendered = $this->renderer->renderPlain($build);
|
||||
$rendered .= ' ' . $this->moduleHandler->invoke('comment', 'node_update_index', array($node, $item->langcode));
|
||||
$this->addCacheableDependency(CacheableMetadata::createFromRenderArray($build));
|
||||
$rendered .= ' ' . $this->moduleHandler->invoke('comment', 'node_update_index', [$node]);
|
||||
|
||||
$extra = $this->moduleHandler->invokeAll('node_search_result', array($node, $item->langcode));
|
||||
$extra = $this->moduleHandler->invokeAll('node_search_result', [$node]);
|
||||
|
||||
$language = $this->languageManager->getLanguage($item->langcode);
|
||||
$username = array(
|
||||
|
@ -354,6 +358,14 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
|
|||
'langcode' => $node->language()->getId(),
|
||||
);
|
||||
|
||||
$this->addCacheableDependency($node);
|
||||
|
||||
// We have to separately add the node owner's cache tags because search
|
||||
// module doesn't use the rendering system, it does its own rendering
|
||||
// without taking cacheability metadata into account. So we have to do it
|
||||
// explicitly here.
|
||||
$this->addCacheableDependency($node->getOwner());
|
||||
|
||||
if ($type->displaySubmitted()) {
|
||||
$result += array(
|
||||
'user' => $this->renderer->renderPlain($username),
|
||||
|
@ -449,14 +461,14 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
|
|||
// Add the title to text so it is searchable.
|
||||
$build['search_title'] = [
|
||||
'#prefix' => '<h1>',
|
||||
'#plain_text' => $node->label($language->getId()),
|
||||
'#plain_text' => $node->label(),
|
||||
'#suffix' => '</h1>',
|
||||
'#weight' => -1000
|
||||
];
|
||||
$text = $this->renderer->renderPlain($build);
|
||||
|
||||
// Fetch extra data normally not visible.
|
||||
$extra = $this->moduleHandler->invokeAll('node_update_index', array($node, $language->getId()));
|
||||
$extra = $this->moduleHandler->invokeAll('node_update_index', [$node]);
|
||||
foreach ($extra as $t) {
|
||||
$text .= $t;
|
||||
}
|
||||
|
@ -554,7 +566,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
|
|||
);
|
||||
|
||||
// Add node types.
|
||||
$types = array_map(array('\Drupal\Component\Utility\SafeMarkup', 'checkPlain'), node_type_get_names());
|
||||
$types = array_map(array('\Drupal\Component\Utility\Html', 'escape'), node_type_get_names());
|
||||
$form['advanced']['types-fieldset'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Types'),
|
||||
|
|
|
@ -8,45 +8,35 @@
|
|||
namespace Drupal\node\Plugin\migrate\builder\d6;
|
||||
|
||||
use Drupal\migrate\Entity\Migration;
|
||||
use Drupal\migrate\Entity\MigrationInterface;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\builder\d6\CckBuilder;
|
||||
use Drupal\migrate\Exception\RequirementsException;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\builder\CckBuilder;
|
||||
|
||||
/**
|
||||
* @PluginID("d6_node")
|
||||
*/
|
||||
class Node extends CckBuilder {
|
||||
|
||||
/**
|
||||
* Already-instantiated cckfield plugins, keyed by ID.
|
||||
*
|
||||
* @var \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface[]
|
||||
*/
|
||||
protected $cckPluginCache = [];
|
||||
|
||||
/**
|
||||
* Gets a cckfield plugin instance.
|
||||
*
|
||||
* @param string $field_type
|
||||
* The field type (plugin ID).
|
||||
* @param \Drupal\migrate\Entity\MigrationInterface|NULL $migration
|
||||
* The migration, if any.
|
||||
*
|
||||
* @return \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface
|
||||
* The cckfield plugin instance.
|
||||
*/
|
||||
protected function getCckPlugin($field_type, MigrationInterface $migration = NULL) {
|
||||
if (empty($this->cckPluginCache[$field_type])) {
|
||||
$this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, [], $migration);
|
||||
}
|
||||
return $this->cckPluginCache[$field_type];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildMigrations(array $template) {
|
||||
$migrations = [];
|
||||
|
||||
// Read all CCK field instance definitions in the source database.
|
||||
$fields = array();
|
||||
$source_plugin = $this->getSourcePlugin('d6_field_instance', $template['source']);
|
||||
try {
|
||||
$source_plugin->checkRequirements();
|
||||
|
||||
foreach ($source_plugin as $field) {
|
||||
$info = $field->getSource();
|
||||
$fields[$info['type_name']][$info['field_name']] = $info;
|
||||
}
|
||||
}
|
||||
catch (RequirementsException $e) {
|
||||
// Don't do anything; $fields will be empty.
|
||||
}
|
||||
|
||||
foreach ($this->getSourcePlugin('d6_node_type', $template['source']) as $row) {
|
||||
$node_type = $row->getSourceProperty('type');
|
||||
$values = $template;
|
||||
|
@ -56,16 +46,15 @@ class Node extends CckBuilder {
|
|||
$values['source']['node_type'] = $node_type;
|
||||
$migration = Migration::create($values);
|
||||
|
||||
$fields = $this->getSourcePlugin('d6_field_instance', ['node_type' => $node_type] + $template['source']);
|
||||
foreach ($fields as $field) {
|
||||
$data = $field->getSource();
|
||||
|
||||
if ($this->cckPluginManager->hasDefinition($data['type'])) {
|
||||
$this->getCckPlugin($data['type'])
|
||||
->processCckFieldValues($migration, $data['field_name'], $data);
|
||||
}
|
||||
else {
|
||||
$migration->setProcessOfProperty($data['field_name'], $data['field_name']);
|
||||
if (isset($fields[$node_type])) {
|
||||
foreach ($fields[$node_type] as $field => $info) {
|
||||
if ($this->cckPluginManager->hasDefinition($info['type'])) {
|
||||
$this->getCckPlugin($info['type'])
|
||||
->processCckFieldValues($migration, $field, $info);
|
||||
}
|
||||
else {
|
||||
$migration->setProcessOfProperty($field, $field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
namespace Drupal\node\Plugin\migrate\builder\d7;
|
||||
|
||||
use Drupal\migrate\Entity\Migration;
|
||||
use Drupal\migrate\Plugin\migrate\builder\BuilderBase;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\builder\CckBuilder;
|
||||
|
||||
/**
|
||||
* @PluginID("d7_node")
|
||||
*/
|
||||
class Node extends BuilderBase {
|
||||
class Node extends CckBuilder {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -21,12 +21,11 @@ class Node extends BuilderBase {
|
|||
public function buildMigrations(array $template) {
|
||||
$migrations = [];
|
||||
|
||||
$fields = [];
|
||||
// Read all field instance definitions in the source database.
|
||||
$fields = array();
|
||||
foreach ($this->getSourcePlugin('d7_field_instance', $template['source']) as $field) {
|
||||
$entity_type = $field->getSourceProperty('entity_type');
|
||||
$bundle = $field->getSourceProperty('bundle');
|
||||
$field_name = $field->getSourceProperty('field_name');
|
||||
$fields[$entity_type][$bundle][$field_name] = $field->getSource();
|
||||
$info = $field->getSource();
|
||||
$fields[$info['entity_type']][$info['bundle']][$info['field_name']] = $info;
|
||||
}
|
||||
|
||||
foreach ($this->getSourcePlugin('d7_node_type', $template['source']) as $node_type) {
|
||||
|
@ -38,8 +37,14 @@ class Node extends BuilderBase {
|
|||
$migration = Migration::create($values);
|
||||
|
||||
if (isset($fields['node'][$bundle])) {
|
||||
foreach (array_keys($fields['node'][$bundle]) as $field) {
|
||||
$migration->setProcessOfProperty($field, $field);
|
||||
foreach ($fields['node'][$bundle] as $field => $data) {
|
||||
if ($this->cckPluginManager->hasDefinition($data['type'])) {
|
||||
$this->getCckPlugin($data['type'])
|
||||
->processCckFieldValues($migration, $field, $data);
|
||||
}
|
||||
else {
|
||||
$migration->setProcessOfProperty($field, $field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\node\Plugin\views\argument;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\views\Plugin\views\argument\StringArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
@ -76,7 +75,7 @@ class Type extends StringArgument {
|
|||
function node_type($type_name) {
|
||||
$type = $this->nodeTypeStorage->load($type_name);
|
||||
$output = $type ? $type->label() : $this->t('Unknown content type');
|
||||
return SafeMarkup::checkPlain($output);
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
|
||||
namespace Drupal\node\Plugin\views\argument_default;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\views\Plugin\CacheablePluginInterface;
|
||||
use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
@ -23,7 +24,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
* title = @Translation("Content ID from URL")
|
||||
* )
|
||||
*/
|
||||
class Node extends ArgumentDefaultPluginBase implements CacheablePluginInterface {
|
||||
class Node extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {
|
||||
|
||||
/**
|
||||
* The route match.
|
||||
|
@ -75,8 +76,8 @@ class Node extends ArgumentDefaultPluginBase implements CacheablePluginInterface
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCacheable() {
|
||||
return TRUE;
|
||||
public function getCacheMaxAge() {
|
||||
return Cache::PERMANENT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\node\Plugin\views\row;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\views\Plugin\views\row\RssPluginBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
@ -78,7 +77,7 @@ class Rss extends RssPluginBase {
|
|||
|
||||
public function summaryTitle() {
|
||||
$options = $this->buildOptionsForm_summary_options();
|
||||
return SafeMarkup::checkPlain($options[$this->options['view_mode']]);
|
||||
return $options[$this->options['view_mode']];
|
||||
}
|
||||
|
||||
public function preRender($values) {
|
||||
|
@ -122,7 +121,7 @@ class Rss extends RssPluginBase {
|
|||
),
|
||||
array(
|
||||
'key' => 'dc:creator',
|
||||
'value' => $node->getOwner()->getUsername(),
|
||||
'value' => $node->getOwner()->getDisplayName(),
|
||||
),
|
||||
array(
|
||||
'key' => 'guid',
|
||||
|
|
|
@ -22,7 +22,7 @@ class NodeImportChangeTest extends KernelTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'field', 'text', 'system', 'node_test_config', 'user', 'entity_reference');
|
||||
public static $modules = ['node', 'field', 'text', 'system', 'node_test_config', 'user'];
|
||||
|
||||
/**
|
||||
* Set the default field storage backend for fields created during tests.
|
||||
|
@ -44,16 +44,16 @@ class NodeImportChangeTest extends KernelTestBase {
|
|||
// Simulate config data to import:
|
||||
// - a modified version (modified label) of the node type config.
|
||||
$active = $this->container->get('config.storage');
|
||||
$staging = $this->container->get('config.storage.staging');
|
||||
$this->copyConfig($active, $staging);
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$this->copyConfig($active, $sync);
|
||||
|
||||
$node_type = $active->read($node_type_config_name);
|
||||
$new_label = 'Test update import field';
|
||||
$node_type['name'] = $new_label;
|
||||
// Save as files in the staging directory.
|
||||
$staging->write($node_type_config_name, $node_type);
|
||||
// Save as files in the sync directory.
|
||||
$sync->write($node_type_config_name, $node_type);
|
||||
|
||||
// Import the content of the staging directory.
|
||||
// Import the content of the sync directory.
|
||||
$this->configImporter()->import();
|
||||
|
||||
// Check that the updated config was correctly imported.
|
||||
|
|
|
@ -23,7 +23,7 @@ class NodeImportCreateTest extends KernelTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'field', 'text', 'system', 'user', 'entity_reference');
|
||||
public static $modules = array('node', 'field', 'text', 'system', 'user');
|
||||
|
||||
/**
|
||||
* Set the default field storage backend for fields created during tests.
|
||||
|
@ -61,19 +61,19 @@ class NodeImportCreateTest extends KernelTestBase {
|
|||
|
||||
// Simulate config data to import.
|
||||
$active = $this->container->get('config.storage');
|
||||
$staging = $this->container->get('config.storage.staging');
|
||||
$this->copyConfig($active, $staging);
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$this->copyConfig($active, $sync);
|
||||
// Manually add new node type.
|
||||
$src_dir = drupal_get_path('module', 'node_test_config') . '/staging';
|
||||
$target_dir = $this->configDirectories[CONFIG_STAGING_DIRECTORY];
|
||||
$src_dir = drupal_get_path('module', 'node_test_config') . '/sync';
|
||||
$target_dir = $this->configDirectories[CONFIG_SYNC_DIRECTORY];
|
||||
$this->assertTrue(file_unmanaged_copy("$src_dir/$node_type_config_name.yml", "$target_dir/$node_type_config_name.yml"));
|
||||
|
||||
// Import the content of the staging directory.
|
||||
// Import the content of the sync directory.
|
||||
$this->configImporter()->import();
|
||||
|
||||
// Check that the content type was created.
|
||||
$node_type = NodeType::load($node_type_id);
|
||||
$this->assertTrue($node_type, 'Import node type from staging was created.');
|
||||
$this->assertTrue($node_type, 'Import node type from sync was created.');
|
||||
$this->assertFalse(FieldConfig::loadByName('node', $node_type_id, 'body'));
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\node\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\migrate\Entity\MigrationInterface;
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
use Drupal\migrate\Entity\Migration;
|
||||
|
||||
|
@ -15,7 +16,10 @@ use Drupal\migrate\Entity\Migration;
|
|||
*/
|
||||
class MigrateNodeBuilderTest extends MigrateDrupal6TestBase {
|
||||
|
||||
public static $modules = ['migrate', 'migrate_drupal', 'node'];
|
||||
/**
|
||||
* @var MigrationInterface[]
|
||||
*/
|
||||
protected $builtMigrations = [];
|
||||
|
||||
/**
|
||||
* Asserts various aspects of a migration entity.
|
||||
|
@ -26,10 +30,10 @@ class MigrateNodeBuilderTest extends MigrateDrupal6TestBase {
|
|||
* The label.
|
||||
*/
|
||||
protected function assertEntity($id, $label) {
|
||||
$migration = Migration::load($id);
|
||||
$migration = $this->builtMigrations[$id];
|
||||
$this->assertTrue($migration instanceof Migration);
|
||||
$this->assertIdentical($id, $migration->Id());
|
||||
$this->assertIdentical($label, $migration->label());
|
||||
$this->assertIdentical($id, $migration->id());
|
||||
$this->assertEqual($label, $migration->label());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +62,11 @@ class MigrateNodeBuilderTest extends MigrateDrupal6TestBase {
|
|||
];
|
||||
|
||||
$migrations = \Drupal::service('migrate.migration_builder')->createMigrations($templates);
|
||||
$this->assertIdentical(11, count($migrations));
|
||||
// Key the array.
|
||||
foreach ($migrations as $migration) {
|
||||
$this->builtMigrations[$migration->id()] = $migration;
|
||||
}
|
||||
$this->assertIdentical(11, count($this->builtMigrations));
|
||||
$this->assertEntity('d6_node__article', 'Drupal 6 nodes (article)');
|
||||
$this->assertEntity('d6_node__company', 'Drupal 6 nodes (company)');
|
||||
$this->assertEntity('d6_node__employee', 'Drupal 6 nodes (employee)');
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
|
||||
namespace Drupal\node\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\Core\Field\Entity\BaseFieldOverride;
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
|
||||
/**
|
||||
* Test migrating node settings into the base_field_bundle_override config entity.
|
||||
|
@ -16,71 +18,46 @@ use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
|||
*/
|
||||
class MigrateNodeBundleSettingsTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Setup the bundles.
|
||||
entity_create('node_type', array('type' => 'test_page'))->save();
|
||||
entity_create('node_type', array('type' => 'test_planet'))->save();
|
||||
entity_create('node_type', array('type' => 'test_story'))->save();
|
||||
entity_create('node_type', array('type' => 'test_event'))->save();
|
||||
entity_create('node_type', array('type' => 'story'))->save();
|
||||
entity_create('node_type', array('type' => 'article'))->save();
|
||||
entity_create('node_type', array('type' => 'company'))->save();
|
||||
entity_create('node_type', array('type' => 'employee'))->save();
|
||||
entity_create('node_type', array('type' => 'page'))->save();
|
||||
entity_create('node_type', array('type' => 'sponsor'))->save();
|
||||
entity_create('node_type', array('type' => 'event'))->save();
|
||||
entity_create('node_type', array('type' => 'book'))->save();
|
||||
$this->installConfig(['node']);
|
||||
$this->executeMigration('d6_node_type');
|
||||
|
||||
// Create a config entity that already exists.
|
||||
entity_create('base_field_override', array('field_name' => 'promote', 'entity_type' => 'node', 'bundle' => 'page',))->save();
|
||||
BaseFieldOverride::create([
|
||||
'field_name' => 'promote',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
])->save();
|
||||
|
||||
$id_mappings = array(
|
||||
'd6_node_type' => array(
|
||||
array(array('test_page'), array('test_page')),
|
||||
array(array('test_planet'), array('test_planet')),
|
||||
array(array('test_story'), array('test_story')),
|
||||
array(array('test_event'), array('test_event')),
|
||||
array(array('story'), array('story')),
|
||||
),
|
||||
);
|
||||
$this->prepareMigrations($id_mappings);
|
||||
|
||||
$this->executeMigration('d6_node_setting_promote');
|
||||
$this->executeMigration('d6_node_setting_status');
|
||||
$this->executeMigration('d6_node_setting_sticky');
|
||||
$this->executeMigrations([
|
||||
'd6_node_setting_promote',
|
||||
'd6_node_setting_status',
|
||||
'd6_node_setting_sticky'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Drupal 6 node type settings to Drupal 8 migration.
|
||||
*/
|
||||
public function testNodeBundleSettings() {
|
||||
|
||||
// Test settings on test_page bundle.
|
||||
$node = entity_create('node', array('type' => 'test_page'));
|
||||
$node = Node::create(['type' => 'test_page']);
|
||||
$this->assertIdentical(1, $node->status->value);
|
||||
$this->assertIdentical(1, $node->promote->value);
|
||||
$this->assertIdentical(1, $node->sticky->value);
|
||||
|
||||
// Test settings for test_story bundle.
|
||||
$node = entity_create('node', array('type' => 'test_story'));
|
||||
$node = Node::create(['type' => 'test_story']);
|
||||
$this->assertIdentical(1, $node->status->value);
|
||||
$this->assertIdentical(1, $node->promote->value);
|
||||
$this->assertIdentical(0, $node->sticky->value);
|
||||
|
||||
// Test settings for the test_event bundle.
|
||||
$node = entity_create('node', array('type' => 'test_event'));
|
||||
$node = Node::create(['type' => 'test_event']);
|
||||
$this->assertIdentical(0, $node->status->value);
|
||||
$this->assertIdentical(0, $node->promote->value);
|
||||
$this->assertIdentical(1, $node->sticky->value);
|
||||
|
|
|
@ -19,13 +19,6 @@ class MigrateNodeConfigsTest extends MigrateDrupal6TestBase {
|
|||
|
||||
use SchemaCheckTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\node\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\migrate\Entity\Migration;
|
||||
|
||||
/**
|
||||
|
@ -22,24 +21,7 @@ class MigrateNodeRevisionTest extends MigrateNodeTestBase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$id_mappings = array(
|
||||
'd6_node:*' => array(
|
||||
array(array(1), array(1)),
|
||||
),
|
||||
);
|
||||
$this->prepareMigrations($id_mappings);
|
||||
|
||||
// Create our users for the node authors.
|
||||
$query = Database::getConnection('default', 'migrate')->query('SELECT * FROM {users} WHERE uid NOT IN (0, 1)');
|
||||
while(($row = $query->fetchAssoc()) !== FALSE) {
|
||||
$user = entity_create('user', $row);
|
||||
$user->enforceIsNew();
|
||||
$user->save();
|
||||
}
|
||||
|
||||
$migrations = Migration::loadMultiple(['d6_node_revision:*']);
|
||||
array_walk($migrations, [$this, 'executeMigration']);
|
||||
$this->executeMigrations(['d6_node:*', 'd6_node_revision:*']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\node\Tests\Migrate\d6\MigrateNodeSettingPromoteTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\Core\Field\Entity\BaseFieldOverride;
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateNodeSettingPromoteTest extends MigrateDrupal6TestBase {
|
||||
|
||||
public static $modules = ['node', 'text'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(['node']);
|
||||
$this->executeMigration('d6_node_type');
|
||||
$this->executeMigration('d6_node_setting_promote');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of the promote checkbox's settings.
|
||||
*/
|
||||
public function testMigration() {
|
||||
$this->assertIdentical('Promoted to front page', BaseFieldOverride::load('node.article.promote')->label());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\node\Tests\Migrate\d6\MigrateNodeSettingStickyTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\Core\Field\Entity\BaseFieldOverride;
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateNodeSettingStickyTest extends MigrateDrupal6TestBase {
|
||||
|
||||
public static $modules = ['node', 'text'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(['node']);
|
||||
$this->executeMigration('d6_node_type');
|
||||
$this->executeMigration('d6_node_setting_sticky');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of the sticky checkbox's settings.
|
||||
*/
|
||||
public function testMigration() {
|
||||
$this->assertIdentical('Sticky at the top of lists', BaseFieldOverride::load('node.article.sticky')->label());
|
||||
}
|
||||
|
||||
}
|
|
@ -23,14 +23,10 @@ class MigrateNodeTest extends MigrateNodeTestBase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Each node type is imported separately. In this test, we're asserting
|
||||
// on story and test_planet nodes.
|
||||
$this->executeMigration('d6_node__test_planet');
|
||||
$this->executeMigration('d6_node__story');
|
||||
$this->executeMigrations(['d6_node:*']);
|
||||
|
||||
// This is required for the second import below.
|
||||
\Drupal::database()->truncate(Migration::load('d6_node__story')->getIdMap()->mapTableName())->execute();
|
||||
$this->standalone = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,11 +53,6 @@ class MigrateNodeTest extends MigrateNodeTestBase {
|
|||
// This is empty on the first revision.
|
||||
$this->assertIdentical(NULL, $node_revision->revision_log->value);
|
||||
|
||||
// It is pointless to run the second half from MigrateDrupal6Test.
|
||||
if (empty($this->standalone)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Test that we can re-import using the EntityContentBase destination.
|
||||
$connection = Database::getConnection('default', 'migrate');
|
||||
$connection->update('node_revisions')
|
||||
|
@ -83,10 +74,6 @@ class MigrateNodeTest extends MigrateNodeTestBase {
|
|||
// Test a multi-column fields are correctly upgraded.
|
||||
$this->assertIdentical('test', $node->body->value);
|
||||
$this->assertIdentical('full_html', $node->body->format);
|
||||
|
||||
$node = Node::load(3);
|
||||
// Test that format = 0 from source maps to filtered_html.
|
||||
$this->assertIdentical('filtered_html', $node->body->format);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@ use Drupal\user\Entity\User;
|
|||
*/
|
||||
abstract class MigrateNodeTestBase extends MigrateDrupal6TestBase {
|
||||
|
||||
static $modules = array('node', 'text', 'filter', 'entity_reference');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -36,66 +34,11 @@ abstract class MigrateNodeTestBase extends MigrateDrupal6TestBase {
|
|||
'uid' => 1,
|
||||
'name' => $this->randomMachineName(),
|
||||
'status' => 1,
|
||||
])->enforceIsNew(TRUE)->save();
|
||||
])->enforceIsNew()->save();
|
||||
|
||||
|
||||
$node_type = entity_create('node_type', array('type' => 'test_planet'));
|
||||
$node_type->save();
|
||||
node_add_body_field($node_type);
|
||||
$node_type = entity_create('node_type', array('type' => 'story'));
|
||||
$node_type->save();
|
||||
node_add_body_field($node_type);
|
||||
|
||||
$id_mappings = array(
|
||||
'd6_node_type' => array(
|
||||
array(array('test_story'), array('story')),
|
||||
),
|
||||
'd6_filter_format' => array(
|
||||
array(array(1), array('filtered_html')),
|
||||
array(array(2), array('full_html')),
|
||||
),
|
||||
'd6_user' => array(
|
||||
array(array(1), array(1)),
|
||||
array(array(2), array(2)),
|
||||
),
|
||||
'd6_field_instance_widget_settings' => array(
|
||||
array(
|
||||
array('page', 'field_test'),
|
||||
array('node', 'page', 'default', 'test'),
|
||||
),
|
||||
),
|
||||
'd6_field_formatter_settings' => array(
|
||||
array(
|
||||
array('page', 'default', 'node', 'field_test'),
|
||||
array('node', 'page', 'default', 'field_test'),
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->prepareMigrations($id_mappings);
|
||||
|
||||
$migration = entity_load('migration', 'd6_node_settings');
|
||||
$migration->setMigrationResult(MigrationInterface::RESULT_COMPLETED);
|
||||
|
||||
// Create a test node.
|
||||
$node = entity_create('node', array(
|
||||
'type' => 'story',
|
||||
'nid' => 1,
|
||||
'vid' => 1,
|
||||
'revision_log' => '',
|
||||
'title' => $this->randomString(),
|
||||
));
|
||||
$node->enforceIsNew();
|
||||
$node->save();
|
||||
|
||||
$node = entity_create('node', array(
|
||||
'type' => 'test_planet',
|
||||
'nid' => 3,
|
||||
'vid' => 4,
|
||||
'revision_log' => '',
|
||||
'title' => $this->randomString(),
|
||||
));
|
||||
$node->enforceIsNew();
|
||||
$node->save();
|
||||
$this->migrateUsers(FALSE);
|
||||
$this->migrateFields();
|
||||
$this->executeMigration('d6_node_settings');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\node\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\migrate\Entity\Migration;
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
|
@ -18,19 +19,12 @@ use Drupal\node\Entity\NodeType;
|
|||
*/
|
||||
class MigrateNodeTypeTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'text', 'filter');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(array('node'));
|
||||
$this->installConfig(['node']);
|
||||
$this->executeMigration('d6_node_type');
|
||||
}
|
||||
|
||||
|
@ -38,14 +32,14 @@ class MigrateNodeTypeTest extends MigrateDrupal6TestBase {
|
|||
* Tests Drupal 6 node type to Drupal 8 migration.
|
||||
*/
|
||||
public function testNodeType() {
|
||||
$migration = entity_load('migration', 'd6_node_type');
|
||||
$id_map = Migration::load('d6_node_type')->getIdMap();
|
||||
// Test the test_page content type.
|
||||
$node_type_page = NodeType::load('test_page');
|
||||
$this->assertIdentical('test_page', $node_type_page->id(), 'Node type test_page loaded');
|
||||
$this->assertIdentical(TRUE, $node_type_page->displaySubmitted());
|
||||
$this->assertIdentical(FALSE, $node_type_page->isNewRevision());
|
||||
$this->assertIdentical(DRUPAL_OPTIONAL, $node_type_page->getPreviewMode());
|
||||
$this->assertIdentical($migration->getIdMap()->lookupDestinationID(array('test_page')), array('test_page'));
|
||||
$this->assertIdentical($id_map->lookupDestinationID(array('test_page')), array('test_page'));
|
||||
|
||||
// Test we have a body field.
|
||||
$field = FieldConfig::loadByName('node', 'test_page', 'body');
|
||||
|
@ -58,7 +52,7 @@ class MigrateNodeTypeTest extends MigrateDrupal6TestBase {
|
|||
$this->assertIdentical(TRUE, $node_type_story->displaySubmitted());
|
||||
$this->assertIdentical(FALSE, $node_type_story->isNewRevision());
|
||||
$this->assertIdentical(DRUPAL_OPTIONAL, $node_type_story->getPreviewMode());
|
||||
$this->assertIdentical($migration->getIdMap()->lookupDestinationID(array('test_story')), array('test_story'));
|
||||
$this->assertIdentical($id_map->lookupDestinationID(array('test_story')), array('test_story'));
|
||||
|
||||
// Test we don't have a body field.
|
||||
$field = FieldConfig::loadByName('node', 'test_story', 'body');
|
||||
|
@ -71,7 +65,7 @@ class MigrateNodeTypeTest extends MigrateDrupal6TestBase {
|
|||
$this->assertIdentical(TRUE, $node_type_event->displaySubmitted());
|
||||
$this->assertIdentical(TRUE, $node_type_event->isNewRevision());
|
||||
$this->assertIdentical(DRUPAL_OPTIONAL, $node_type_event->getPreviewMode());
|
||||
$this->assertIdentical($migration->getIdMap()->lookupDestinationID(array('test_event')), array('test_event'));
|
||||
$this->assertIdentical($id_map->lookupDestinationID(array('test_event')), array('test_event'));
|
||||
|
||||
// Test we have a body field.
|
||||
$field = FieldConfig::loadByName('node', 'test_event', 'body');
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\node\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityViewMode;
|
||||
use Drupal\migrate\Entity\Migration;
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
|
@ -17,13 +18,6 @@ use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
|||
*/
|
||||
class MigrateViewModesTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -40,8 +34,8 @@ class MigrateViewModesTest extends MigrateDrupal6TestBase {
|
|||
$view_mode = EntityViewMode::load('node.preview');
|
||||
$this->assertIdentical(FALSE, is_null($view_mode), 'Preview view mode loaded.');
|
||||
$this->assertIdentical('Preview', $view_mode->label(), 'View mode has correct label.');
|
||||
// Test the Id Map.
|
||||
$this->assertIdentical(array('node', 'preview'), entity_load('migration', 'd6_view_modes')->getIdMap()->lookupDestinationID(array(1)));
|
||||
// Test the ID map.
|
||||
$this->assertIdentical(array('node', 'preview'), Migration::load('d6_view_modes')->getIdMap()->lookupDestinationID(array(1)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,17 @@ use Drupal\node\NodeInterface;
|
|||
*/
|
||||
class MigrateNodeTest extends MigrateDrupal7TestBase {
|
||||
|
||||
static $modules = array('node', 'text', 'filter', 'entity_reference');
|
||||
static $modules = array(
|
||||
'comment',
|
||||
'datetime',
|
||||
'filter',
|
||||
'image',
|
||||
'link',
|
||||
'node',
|
||||
'taxonomy',
|
||||
'telephone',
|
||||
'text',
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -27,14 +37,21 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
|
|||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installConfig(['node']);
|
||||
$this->installEntitySchema('comment');
|
||||
$this->installEntitySchema('taxonomy_term');
|
||||
$this->installConfig(static::$modules);
|
||||
$this->installSchema('node', ['node_access']);
|
||||
$this->installSchema('system', ['sequences']);
|
||||
|
||||
$this->executeMigration('d7_user_role');
|
||||
$this->executeMigration('d7_user');
|
||||
$this->executeMigration('d7_node_type');
|
||||
$this->executeMigration('d7_node__test_content_type');
|
||||
$this->executeMigrations([
|
||||
'd7_user_role',
|
||||
'd7_user',
|
||||
'd7_node_type',
|
||||
'd7_comment_type',
|
||||
'd7_field',
|
||||
'd7_field_instance',
|
||||
'd7_node__test_content_type',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,6 +124,16 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
|
|||
public function testNode() {
|
||||
$this->assertEntity(1, 'test_content_type', 'en', 'A Node', '2', TRUE, '1421727515', '1441032132', TRUE, FALSE);
|
||||
$this->assertRevision(1, 'A Node', '2', NULL, '1441032132');
|
||||
|
||||
$node = Node::load(1);
|
||||
$this->assertTrue($node->field_boolean->value);
|
||||
$this->assertIdentical('99-99-99-99', $node->field_phone->value);
|
||||
// Use assertEqual() here instead, since SQLite interprets floats strictly.
|
||||
$this->assertEqual('1', $node->field_float->value);
|
||||
$this->assertIdentical('5', $node->field_integer->value);
|
||||
$this->assertIdentical('Some more text', $node->field_text_list[0]->value);
|
||||
$this->assertIdentical('7', $node->field_integer_list[0]->value);
|
||||
$this->assertIdentical('qwerty', $node->field_text->value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,8 +26,7 @@ class MigrateNodeTitleLabelTest extends MigrateDrupal7TestBase {
|
|||
parent::setUp();
|
||||
$this->installConfig(static::$modules);
|
||||
$this->installEntitySchema('node');
|
||||
$this->executeMigration('d7_node_type');
|
||||
$this->executeMigration('d7_node_title_label');
|
||||
$this->executeMigrations(['d7_node_type', 'd7_node_title_label']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,21 +30,21 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
|
|||
/**
|
||||
* A set of nodes to use in testing.
|
||||
*
|
||||
* @var array
|
||||
* @var \Drupal\node\NodeInterface[]
|
||||
*/
|
||||
protected $nodes = array();
|
||||
|
||||
/**
|
||||
* A normal authenticated user.
|
||||
*
|
||||
* @var \Drupal\user\Entity\UserInterface.
|
||||
* @var \Drupal\user\UserInterface.
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
/**
|
||||
* User 1.
|
||||
*
|
||||
* @var \Drupal\user\Entity\UserInterface.
|
||||
* @var \Drupal\user\UserInterface.
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
|
@ -110,7 +110,7 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
|
|||
'field_private' => array(array('value' => 0)),
|
||||
'private' => FALSE,
|
||||
));
|
||||
$translation = $node->getTranslation('ca');
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 0;
|
||||
$node->save();
|
||||
|
@ -121,7 +121,7 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
|
|||
'field_private' => array(array('value' => 0)),
|
||||
'private' => TRUE,
|
||||
));
|
||||
$translation = $node->getTranslation('ca');
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 0;
|
||||
$node->save();
|
||||
|
@ -132,7 +132,7 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
|
|||
'field_private' => array(array('value' => 1)),
|
||||
'private' => FALSE,
|
||||
));
|
||||
$translation = $node->getTranslation('ca');
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 0;
|
||||
$node->save();
|
||||
|
@ -143,7 +143,7 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
|
|||
'field_private' => array(array('value' => 0)),
|
||||
'private' => FALSE,
|
||||
));
|
||||
$translation = $node->getTranslation('ca');
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 1;
|
||||
$node->save();
|
||||
|
@ -154,7 +154,7 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
|
|||
'field_private' => array(array('value' => 1)),
|
||||
'private' => FALSE,
|
||||
));
|
||||
$translation = $node->getTranslation('ca');
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 1;
|
||||
$node->save();
|
||||
|
@ -165,7 +165,7 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
|
|||
'field_private' => array(array('value' => 1)),
|
||||
'private' => TRUE,
|
||||
));
|
||||
$translation = $node->getTranslation('ca');
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 1;
|
||||
$node->save();
|
||||
|
@ -200,78 +200,58 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
|
|||
$expected_node_access = array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE);
|
||||
$expected_node_access_no_access = array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE);
|
||||
|
||||
// When the node and both translations are public, access should only be
|
||||
// denied when a translation that does not exist is requested.
|
||||
// When the node and both translations are public, access should always be
|
||||
// granted.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_public'], $this->webUser, 'en');
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// If the node is marked private but both existing translations are not,
|
||||
// access should still be granted, because the grants are additive.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_public'], $this->webUser, 'en');
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// If the node is marked private, but a existing translation is public,
|
||||
// access should only be granted for the public translation. For a
|
||||
// translation that does not exist yet (English translation), the access is
|
||||
// denied. With the Hungarian translation marked as private, but the Catalan
|
||||
// translation public, the access is granted.
|
||||
// access should only be granted for the public translation. With the
|
||||
// Hungarian translation marked as private, but the Catalan translation
|
||||
// public, the access is granted.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_hu_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_hu_private'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_hu_private'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_hu_private'], $this->webUser, 'en');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_hu_private']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_hu_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// With the Catalan translation marked as private, but the node public,
|
||||
// access is granted for the existing Hungarian translation, but not for the
|
||||
// Catalan nor the English ones.
|
||||
// Catalan.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_ca_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_ca_private'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_ca_private'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_ca_private'], $this->webUser, 'en');
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_ca_private']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_ca_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// With both translations marked as private, but the node public, access
|
||||
// should be denied in all cases.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private'], $this->webUser, 'en');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// If the node and both its existing translations are private, access should
|
||||
// be denied in all cases.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private'], $this->webUser, 'en');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// No access for all languages as the language aware node access module
|
||||
// denies access.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_private'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_private'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_private'], $this->webUser, 'en');
|
||||
|
||||
// Access only for request with no language defined.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['public_no_language_public'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_public'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_public'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_public'], $this->webUser, 'en');
|
||||
|
||||
// No access for all languages as both node access modules deny access.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_private'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_private'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_private'], $this->webUser, 'en');
|
||||
|
||||
// No access for all languages as the non language aware node access module
|
||||
// denies access.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_public'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_public'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_public'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_public'], $this->webUser, 'en');
|
||||
|
||||
|
||||
// Query the node table with the node access tag in several languages.
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
|
|||
/**
|
||||
* A set of nodes to use in testing.
|
||||
*
|
||||
* @var array
|
||||
* @var \Drupal\node\NodeInterface[]
|
||||
*/
|
||||
protected $nodes = array();
|
||||
|
||||
|
@ -103,7 +103,7 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
|
|||
'langcode' => 'hu',
|
||||
'field_private' => array(array('value' => 0)),
|
||||
));
|
||||
$translation = $node->getTranslation('ca');
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 0;
|
||||
$node->save();
|
||||
|
@ -113,7 +113,7 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
|
|||
'langcode' => 'hu',
|
||||
'field_private' => array(array('value' => 0)),
|
||||
));
|
||||
$translation = $node->getTranslation('ca');
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 1;
|
||||
$node->save();
|
||||
|
@ -123,7 +123,7 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
|
|||
'langcode' => 'hu',
|
||||
'field_private' => array(array('value' => 1)),
|
||||
));
|
||||
$translation = $node->getTranslation('ca');
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 0;
|
||||
$node->save();
|
||||
|
@ -133,7 +133,7 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
|
|||
'langcode' => 'hu',
|
||||
'field_private' => array(array('value' => 1)),
|
||||
));
|
||||
$translation = $node->getTranslation('ca');
|
||||
$translation = $node->addTranslation('ca');
|
||||
$translation->title->value = $this->randomString();
|
||||
$translation->field_private->value = 1;
|
||||
$node->save();
|
||||
|
@ -157,60 +157,42 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
|
|||
$expected_node_access_no_access = array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE);
|
||||
|
||||
// When both Hungarian and Catalan are marked as public, access to the
|
||||
// Hungarian translation should be granted when no language is specified or
|
||||
// Hungarian translation should be granted with the default entity object or
|
||||
// when the Hungarian translation is specified explicitly.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public']->getTranslation('hu'), $this->webUser);
|
||||
// Access to the Catalan translation should also be granted.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public'], $this->webUser, 'ca');
|
||||
// There is no English translation, so a request to access the English
|
||||
// translation is denied.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['both_public'], $this->webUser, 'en');
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// When Hungarian is marked as private, access to the Hungarian translation
|
||||
// should be denied when no language is specified or when the Hungarian
|
||||
// should be denied with the default entity object or when the Hungarian
|
||||
// translation is specified explicitly.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['hu_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['hu_private'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['hu_private']->getTranslation('hu'), $this->webUser);
|
||||
// Access to the Catalan translation should be granted.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['hu_private'], $this->webUser, 'ca');
|
||||
// There is no English translation, so a request to access the English
|
||||
// translation is denied.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['hu_private'], $this->webUser, 'en');
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['hu_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// When Catalan is marked as private, access to the Hungarian translation
|
||||
// should be granted when no language is specified or when the Hungarian
|
||||
// should be granted with the default entity object or when the Hungarian
|
||||
// translation is specified explicitly.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['ca_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['ca_private'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['ca_private']->getTranslation('hu'), $this->webUser);
|
||||
// Access to the Catalan translation should be granted.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['ca_private'], $this->webUser, 'ca');
|
||||
// There is no English translation, so a request to access the English
|
||||
// translation is denied.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['ca_private'], $this->webUser, 'en');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['ca_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// When both translations are marked as private, access should be denied
|
||||
// regardless of the language specified.
|
||||
// regardless of the entity object specified.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['both_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['both_private'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['both_private'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['both_private'], $this->webUser, 'en');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['both_private']->getTranslation('hu'), $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['both_private']->getTranslation('ca'), $this->webUser);
|
||||
|
||||
// When no language is specified for a private node, access to every
|
||||
// language is denied.
|
||||
// When no language is specified for a private node, access to every node
|
||||
// translation is denied.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['no_language_private'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['no_language_private'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['no_language_private'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['no_language_private'], $this->webUser, 'en');
|
||||
|
||||
// When no language is specified for a public node, access should be granted
|
||||
// only for the existing language (not specified), so only the request with
|
||||
// no language will give access, as this request will be made with the
|
||||
// langcode of the node, which is "not specified".
|
||||
// When no language is specified for a public node, access should be
|
||||
// granted.
|
||||
$this->assertNodeAccess($expected_node_access, $this->nodes['no_language_public'], $this->webUser);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['no_language_public'], $this->webUser, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['no_language_public'], $this->webUser, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['no_language_public'], $this->webUser, 'en');
|
||||
|
||||
// Query the node table with the node access tag in several languages.
|
||||
|
||||
|
|
|
@ -62,13 +62,7 @@ class NodeAccessLanguageTest extends NodeTestBase {
|
|||
$this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user);
|
||||
|
||||
// Tests that Hungarian provided specifically results in the same.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user, 'hu');
|
||||
|
||||
// There is no specific Catalan version of this node and Croatian is not
|
||||
// even set up on the system in this scenario, so the user will not get
|
||||
// access to these nodes.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_hu, $web_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_hu, $web_user, 'hr');
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu->getTranslation('hu'), $web_user);
|
||||
|
||||
// Creating a public node with no special langcode, like when no language
|
||||
// module enabled.
|
||||
|
@ -81,15 +75,6 @@ class NodeAccessLanguageTest extends NodeTestBase {
|
|||
// Tests that access is granted if requested with no language.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_no_language, $web_user);
|
||||
|
||||
// Tests that access is not granted if requested with Hungarian language.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_no_language, $web_user, 'hu');
|
||||
|
||||
// There is no specific Catalan version of this node and Croatian is not
|
||||
// even set up on the system in this scenario, so the user will not get
|
||||
// access to these nodes.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_no_language, $web_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_no_language, $web_user, 'hr');
|
||||
|
||||
// Reset the node access cache and turn on our test node access code.
|
||||
\Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
|
||||
\Drupal::state()->set('node_access_test_secret_catalan', 1);
|
||||
|
@ -100,23 +85,20 @@ class NodeAccessLanguageTest extends NodeTestBase {
|
|||
$this->assertNodeAccess($expected_node_access, $node_public_no_language, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_ca, $web_user);
|
||||
|
||||
// Tests that Hungarian is still not accessible.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_no_language, $web_user, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_ca, $web_user, 'hu');
|
||||
|
||||
// Tests that Hungarian node is still accessible.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu->getTranslation('hu'), $web_user);
|
||||
|
||||
// Tests that Catalan is still not accessible.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_no_language, $web_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_ca, $web_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_ca->getTranslation('ca'), $web_user);
|
||||
|
||||
// Make Catalan accessible.
|
||||
\Drupal::state()->set('node_access_test_secret_catalan', 0);
|
||||
|
||||
// Tests that Catalan is accessible on a node with a Catalan version as the
|
||||
// static cache has not been reset.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_ca, $web_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_ca, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_ca->getTranslation('ca'), $web_user);
|
||||
|
||||
\Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
|
||||
|
||||
|
@ -124,18 +106,12 @@ class NodeAccessLanguageTest extends NodeTestBase {
|
|||
$this->assertNodeAccess($expected_node_access, $node_public_no_language, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_ca, $web_user);
|
||||
|
||||
// Tests that Hungarian is still not accessible.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_no_language, $web_user, 'hu');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_ca, $web_user, 'hu');
|
||||
|
||||
// Tests that Hungarian node is still accessible.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user, 'hu');
|
||||
|
||||
// Tests that Catalan is still not accessible on a node without a language.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_public_no_language, $web_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_hu->getTranslation('hu'), $web_user);
|
||||
|
||||
// Tests that Catalan is accessible on a node with a Catalan version.
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_ca, $web_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access, $node_public_ca->getTranslation('ca'), $web_user);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,13 +131,7 @@ class NodeAccessLanguageTest extends NodeTestBase {
|
|||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_hu, $web_user);
|
||||
|
||||
// Tests that Hungarian provided specifically results in the same.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_hu, $web_user, 'hu');
|
||||
|
||||
// There is no specific Catalan version of this node and Croatian is not
|
||||
// even set up on the system in this scenario, so the user will not get
|
||||
// access to these nodes.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_hu, $web_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_hu, $web_user, 'hr');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_hu->getTranslation('hu'), $web_user);
|
||||
|
||||
// Creating a private node with no special langcode, like when no language
|
||||
// module enabled.
|
||||
|
@ -174,15 +144,6 @@ class NodeAccessLanguageTest extends NodeTestBase {
|
|||
// Tests that access is not granted if requested with no language.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_no_language, $web_user);
|
||||
|
||||
// Tests that access is not granted if requested with Hungarian language.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_no_language, $web_user, 'hu');
|
||||
|
||||
// There is no specific Catalan version of this node and Croatian is not
|
||||
// even set up on the system in this scenario, so the user will not get
|
||||
// access to these nodes.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_no_language, $web_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_no_language, $web_user, 'hr');
|
||||
|
||||
// Reset the node access cache and turn on our test node access code.
|
||||
\Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
|
||||
\Drupal::state()->set('node_access_test_secret_catalan', 1);
|
||||
|
@ -190,12 +151,6 @@ class NodeAccessLanguageTest extends NodeTestBase {
|
|||
// Tests that access is not granted if requested with no language.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_no_language, $web_user);
|
||||
|
||||
// Tests that Hungarian is still not accessible.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_no_language, $web_user, 'hu');
|
||||
|
||||
// Tests that Catalan is still not accessible.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_no_language, $web_user, 'ca');
|
||||
|
||||
// Creating a private node with langcode Catalan to test that the
|
||||
// node_access_test_secret_catalan flag works.
|
||||
$private_ca_user = $this->drupalCreateUser(array('access content', 'node test view'));
|
||||
|
@ -203,19 +158,23 @@ class NodeAccessLanguageTest extends NodeTestBase {
|
|||
$this->assertTrue($node_private_ca->language()->getId() == 'ca', 'Node created as Catalan.');
|
||||
|
||||
// Tests that Catalan is still not accessible to either user.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca, $web_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca, $private_ca_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca->getTranslation('ca'), $web_user);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca, $private_ca_user);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca->getTranslation('ca'), $private_ca_user);
|
||||
|
||||
\Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
|
||||
\Drupal::state()->set('node_access_test_secret_catalan', 0);
|
||||
|
||||
// Tests that Catalan is still not accessible for a user with no access to
|
||||
// private nodes.
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca, $web_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca, $web_user);
|
||||
$this->assertNodeAccess($expected_node_access_no_access, $node_private_ca->getTranslation('ca'), $web_user);
|
||||
|
||||
// Tests that Catalan is accessible by a user with the permission to see
|
||||
// private nodes.
|
||||
$this->assertNodeAccess($expected_node_access, $node_private_ca, $private_ca_user, 'ca');
|
||||
$this->assertNodeAccess($expected_node_access, $node_private_ca, $private_ca_user);
|
||||
$this->assertNodeAccess($expected_node_access, $node_private_ca->getTranslation('ca'), $private_ca_user);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,7 +46,7 @@ class NodeAccessRebuildNodeGrantsTest extends NodeTestBase {
|
|||
));
|
||||
|
||||
// Default realm access and node records are present.
|
||||
$this->assertTrue(\Drupal::service('node.grant_storage')->access($node, 'view', 'en', $this->webUser), 'The expected node access records are present');
|
||||
$this->assertTrue(\Drupal::service('node.grant_storage')->access($node, 'view', $this->webUser), 'The expected node access records are present');
|
||||
$this->assertEqual(1, \Drupal::service('node.grant_storage')->checkAll($this->webUser), 'There is an all realm access record');
|
||||
$this->assertTrue(\Drupal::state()->get('node.node_access_needs_rebuild'), 'Node access permissions need to be rebuilt');
|
||||
|
||||
|
@ -57,7 +57,7 @@ class NodeAccessRebuildNodeGrantsTest extends NodeTestBase {
|
|||
|
||||
// Test if the rebuild has been successful.
|
||||
$this->assertNull(\Drupal::state()->get('node.node_access_needs_rebuild'), 'Node access permissions have been rebuilt');
|
||||
$this->assertTrue(\Drupal::service('node.grant_storage')->access($node, 'view', 'en', $this->webUser), 'The expected node access records are present');
|
||||
$this->assertTrue(\Drupal::service('node.grant_storage')->access($node, 'view', $this->webUser), 'The expected node access records are present');
|
||||
$this->assertFalse(\Drupal::service('node.grant_storage')->checkAll($this->webUser), 'There is no all realm access record');
|
||||
}
|
||||
|
||||
|
|
|
@ -118,18 +118,29 @@ class NodeAdminTest extends NodeTestBase {
|
|||
function testContentAdminPages() {
|
||||
$this->drupalLogin($this->adminUser);
|
||||
|
||||
$nodes['published_page'] = $this->drupalCreateNode(array('type' => 'page'));
|
||||
$nodes['published_article'] = $this->drupalCreateNode(array('type' => 'article'));
|
||||
$nodes['unpublished_page_1'] = $this->drupalCreateNode(array('type' => 'page', 'uid' => $this->baseUser1->id(), 'status' => 0));
|
||||
$nodes['unpublished_page_2'] = $this->drupalCreateNode(array('type' => 'page', 'uid' => $this->baseUser2->id(), 'status' => 0));
|
||||
// Use an explicit changed time to ensure the expected order in the content
|
||||
// admin listing. We want these to appear in the table in the same order as
|
||||
// they appear in the following code, and the 'content' View has a table
|
||||
// style configuration with a default sort on the 'changed' field DESC.
|
||||
$time = time();
|
||||
$nodes['published_page'] = $this->drupalCreateNode(array('type' => 'page', 'changed' => $time--));
|
||||
$nodes['published_article'] = $this->drupalCreateNode(array('type' => 'article', 'changed' => $time--));
|
||||
$nodes['unpublished_page_1'] = $this->drupalCreateNode(array('type' => 'page', 'changed' => $time--, 'uid' => $this->baseUser1->id(), 'status' => 0));
|
||||
$nodes['unpublished_page_2'] = $this->drupalCreateNode(array('type' => 'page', 'changed' => $time, 'uid' => $this->baseUser2->id(), 'status' => 0));
|
||||
|
||||
// Verify view, edit, and delete links for any content.
|
||||
$this->drupalGet('admin/content');
|
||||
$this->assertResponse(200);
|
||||
|
||||
$node_type_labels = $this->xpath('//td[contains(@class, "views-field-type")]');
|
||||
$delta = 0;
|
||||
foreach ($nodes as $node) {
|
||||
$this->assertLinkByHref('node/' . $node->id());
|
||||
$this->assertLinkByHref('node/' . $node->id() . '/edit');
|
||||
$this->assertLinkByHref('node/' . $node->id() . '/delete');
|
||||
// Verify that we can see the content type label.
|
||||
$this->assertEqual(trim((string) $node_type_labels[$delta]), $node->type->entity->label());
|
||||
$delta++;
|
||||
}
|
||||
|
||||
// Verify filtering by publishing status.
|
||||
|
|
|
@ -148,7 +148,7 @@ class NodeBlockFunctionalTest extends NodeTestBase {
|
|||
$this->assertCacheContexts(['languages:language_content', 'languages:language_interface', 'theme', 'url.query_args:' . MainContentViewSubscriber::WRAPPER_FORMAT, 'user', 'route']);
|
||||
$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', 'theme', 'url.path', 'url.query_args', 'user', 'route']);
|
||||
$this->assertCacheContexts(['languages:language_content', 'languages:language_interface', 'session', 'theme', 'url.path', 'url.query_args', 'user', 'route']);
|
||||
$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']);
|
||||
|
|
|
@ -27,7 +27,7 @@ class NodeBodyFieldStorageTest extends KernelTestBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('user', 'system', 'field', 'node', 'text', 'filter', 'entity_reference');
|
||||
public static $modules = ['user', 'system', 'field', 'node', 'text', 'filter'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
|
|
@ -52,7 +52,7 @@ class NodeCreationTest extends NodeTestBase {
|
|||
$this->drupalPostForm('node/add/page', $edit, t('Save'));
|
||||
|
||||
// Check that the Basic page has been created.
|
||||
$this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit['title[0][value]'])), 'Basic page created.');
|
||||
$this->assertRaw(t('@post %title has been created.', array('@post' => 'Basic page', '%title' => $edit['title[0][value]'])), 'Basic page created.');
|
||||
|
||||
// Check that the node exists in the database.
|
||||
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
|
@ -141,7 +141,7 @@ class NodeCreationTest extends NodeTestBase {
|
|||
$this->assertText(t('Test page text'));
|
||||
|
||||
// Confirm that the node was created.
|
||||
$this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit['title[0][value]'])));
|
||||
$this->assertRaw(t('@post %title has been created.', array('@post' => 'Basic page', '%title' => $edit['title[0][value]'])));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,20 +2,41 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\node\Tests\PageEditTest.
|
||||
* Contains \Drupal\node\Tests\NodeEditFormTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\Tests;
|
||||
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Create a node and test node edit functionality.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class PageEditTest extends NodeTestBase {
|
||||
class NodeEditFormTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* A normal logged in user.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
/**
|
||||
* A user with permission to bypass content access checks.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
/**
|
||||
* The node storage.
|
||||
*
|
||||
* @var \Drupal\node\NodeStorageInterface
|
||||
*/
|
||||
protected $nodeStorage;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
|
@ -29,12 +50,14 @@ class PageEditTest extends NodeTestBase {
|
|||
$this->webUser = $this->drupalCreateUser(array('edit own page content', 'create page content'));
|
||||
$this->adminUser = $this->drupalCreateUser(array('bypass node access', 'administer nodes'));
|
||||
$this->drupalPlaceBlock('local_tasks_block');
|
||||
|
||||
$this->nodeStorage = $this->container->get('entity.manager')->getStorage('node');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks node edit functionality.
|
||||
*/
|
||||
function testPageEdit() {
|
||||
public function testNodeEdit() {
|
||||
$this->drupalLogin($this->webUser);
|
||||
|
||||
$title_key = 'title[0][value]';
|
||||
|
@ -54,9 +77,10 @@ class PageEditTest extends NodeTestBase {
|
|||
$this->assertUrl($node->url('edit-form', ['absolute' => TRUE]));
|
||||
|
||||
// Check that the title and body fields are displayed with the correct values.
|
||||
$active = '<span class="visually-hidden">' . t('(active tab)') . '</span>';
|
||||
$link_text = t('!local-task-title!active', array('!local-task-title' => t('Edit'), '!active' => $active));
|
||||
$this->assertText(strip_tags($link_text), 0, 'Edit tab found and marked active.');
|
||||
// As you see the expected link text has no HTML, but we are using
|
||||
$link_text = 'Edit<span class="visually-hidden">(active tab)</span>';
|
||||
// @todo Ideally assertLink would support HTML, but it doesn't.
|
||||
$this->assertRaw($link_text, 'Edit tab found and marked active.');
|
||||
$this->assertFieldByName($title_key, $edit[$title_key], 'Title field displayed.');
|
||||
$this->assertFieldByName($body_key, $edit[$body_key], 'Body field displayed.');
|
||||
|
||||
|
@ -98,8 +122,7 @@ class PageEditTest extends NodeTestBase {
|
|||
/**
|
||||
* Tests changing a node's "authored by" field.
|
||||
*/
|
||||
function testPageAuthoredBy() {
|
||||
$node_storage = $this->container->get('entity.manager')->getStorage('node');
|
||||
public function testNodeEditAuthoredBy() {
|
||||
$this->drupalLogin($this->adminUser);
|
||||
|
||||
// Create node to edit.
|
||||
|
@ -113,18 +136,69 @@ class PageEditTest extends NodeTestBase {
|
|||
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
$this->assertIdentical($node->getOwnerId(), $this->adminUser->id(), 'Node authored by admin user.');
|
||||
|
||||
$this->checkVariousAuthoredByValues($node, 'uid[0][target_id]');
|
||||
|
||||
// Check that normal users cannot change the authored by information.
|
||||
$this->drupalLogin($this->webUser);
|
||||
$this->drupalGet('node/' . $node->id() . '/edit');
|
||||
$this->assertNoFieldByName('uid[0][target_id]');
|
||||
|
||||
// Now test with the Autcomplete (Tags) field widget.
|
||||
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
|
||||
$form_display = \Drupal::entityManager()->getStorage('entity_form_display')->load('node.page.default');
|
||||
$widget = $form_display->getComponent('uid');
|
||||
$widget['type'] = 'entity_reference_autocomplete_tags';
|
||||
$widget['settings'] = [
|
||||
'match_operator' => 'CONTAINS',
|
||||
'size' => 60,
|
||||
'placeholder' => '',
|
||||
];
|
||||
$form_display->setComponent('uid', $widget);
|
||||
$form_display->save();
|
||||
|
||||
$this->drupalLogin($this->adminUser);
|
||||
|
||||
// Save the node without making any changes.
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and keep published'));
|
||||
$this->nodeStorage->resetCache(array($node->id()));
|
||||
$node = $this->nodeStorage->load($node->id());
|
||||
$this->assertIdentical($this->webUser->id(), $node->getOwner()->id());
|
||||
|
||||
$this->checkVariousAuthoredByValues($node, 'uid[target_id]');
|
||||
|
||||
// Hide the 'authored by' field from the form.
|
||||
$form_display->removeComponent('uid')->save();
|
||||
|
||||
// Check that saving the node without making any changes keeps the proper
|
||||
// author ID.
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and keep published'));
|
||||
$this->nodeStorage->resetCache(array($node->id()));
|
||||
$node = $this->nodeStorage->load($node->id());
|
||||
$this->assertIdentical($this->webUser->id(), $node->getOwner()->id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the "authored by" works correctly with various values.
|
||||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* A node object.
|
||||
* @param string $form_element_name
|
||||
* The name of the form element to populate.
|
||||
*/
|
||||
protected function checkVariousAuthoredByValues(NodeInterface $node, $form_element_name) {
|
||||
// Try to change the 'authored by' field to an invalid user name.
|
||||
$edit = array(
|
||||
'uid[0][target_id]' => 'invalid-name',
|
||||
$form_element_name => 'invalid-name',
|
||||
);
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
|
||||
$this->assertRaw(t('There are no entities matching "%name".', array('%name' => 'invalid-name')));
|
||||
|
||||
// Change the authored by field to the anonymous user (uid 0).
|
||||
$edit['uid[0][target_id]'] = 'Anonymous (0)';
|
||||
// Change the authored by field to an empty string, which should assign
|
||||
// authorship to the anonymous user (uid 0).
|
||||
$edit[$form_element_name] = '';
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
|
||||
$node_storage->resetCache(array($node->id()));
|
||||
$node = $node_storage->load($node->id());
|
||||
$this->nodeStorage->resetCache(array($node->id()));
|
||||
$node = $this->nodeStorage->load($node->id());
|
||||
$uid = $node->getOwnerId();
|
||||
// Most SQL database drivers stringify fetches but entities are not
|
||||
// necessarily stored in a SQL database. At the same time, NULL/FALSE/""
|
||||
|
@ -133,15 +207,11 @@ class PageEditTest extends NodeTestBase {
|
|||
|
||||
// Change the authored by field to another user's name (that is not
|
||||
// logged in).
|
||||
$edit['uid[0][target_id]'] = $this->webUser->getUsername();
|
||||
$edit[$form_element_name] = $this->webUser->getUsername();
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
|
||||
$node_storage->resetCache(array($node->id()));
|
||||
$node = $node_storage->load($node->id());
|
||||
$this->nodeStorage->resetCache(array($node->id()));
|
||||
$node = $this->nodeStorage->load($node->id());
|
||||
$this->assertIdentical($node->getOwnerId(), $this->webUser->id(), 'Node authored by normal user.');
|
||||
|
||||
// Check that normal users cannot change the authored by information.
|
||||
$this->drupalLogin($this->webUser);
|
||||
$this->drupalGet('node/' . $node->id() . '/edit');
|
||||
$this->assertNoFieldByName('uid[0][target_id]');
|
||||
}
|
||||
|
||||
}
|
76
core/modules/node/src/Tests/NodeFormSaveChangedTimeTest.php
Normal file
76
core/modules/node/src/Tests/NodeFormSaveChangedTimeTest.php
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\node\Tests\NodeFormSaveChangedTimeTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\Tests;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests updating the changed time after API and FORM entity save.
|
||||
*
|
||||
* @group node
|
||||
*/
|
||||
class NodeFormSaveChangedTimeTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array(
|
||||
'node',
|
||||
);
|
||||
|
||||
/**
|
||||
* An user with permissions to create and edit articles.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $authorUser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a node type.
|
||||
$this->drupalCreateContentType(array(
|
||||
'type' => 'article',
|
||||
'name' => 'Article',
|
||||
));
|
||||
|
||||
$this->authorUser = $this->drupalCreateUser(['access content', 'create article content', 'edit any article content'], 'author');
|
||||
$this->drupalLogin($this->authorUser);
|
||||
|
||||
// Create one node of the above node type .
|
||||
$this->drupalCreateNode(array(
|
||||
'type' => 'article',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the changed time after API and FORM save without changes.
|
||||
*/
|
||||
public function testChangedTimeAfterSaveWithoutChanges() {
|
||||
$node = entity_load('node', 1);
|
||||
$changed_timestamp = $node->getChangedTime();
|
||||
|
||||
$node->save();
|
||||
$node = entity_load('node', 1, TRUE);
|
||||
$this->assertEqual($changed_timestamp, $node->getChangedTime(), "The entity's changed time wasn't updated after API save without changes.");
|
||||
|
||||
// Ensure different save timestamps.
|
||||
sleep(1);
|
||||
|
||||
// Save the node on the regular node edit form.
|
||||
$this->drupalPostForm('node/1/edit', array(), t('Save'));
|
||||
|
||||
$node = entity_load('node', 1, TRUE);
|
||||
$this->assertNotEqual($changed_timestamp, $node->getChangedTime(), "The entity's changed time was updated after form save without changes.");
|
||||
}
|
||||
}
|
83
core/modules/node/src/Tests/NodeOwnerTest.php
Normal file
83
core/modules/node/src/Tests/NodeOwnerTest.php
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains Drupal\node\Tests\NodeOwnerTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\Tests;
|
||||
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\system\Tests\Entity\EntityUnitTestBase;
|
||||
|
||||
/**
|
||||
* Tests node owner functionality.
|
||||
*
|
||||
* @group Entity
|
||||
*/
|
||||
class NodeOwnerTest extends EntityUnitTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'language');
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create the node bundles required for testing.
|
||||
$type = NodeType::create(array(
|
||||
'type' => 'page',
|
||||
'name' => 'page',
|
||||
));
|
||||
$type->save();
|
||||
|
||||
// Enable two additional languages.
|
||||
ConfigurableLanguage::createFromLangcode('de')->save();
|
||||
ConfigurableLanguage::createFromLangcode('it')->save();
|
||||
|
||||
$this->installSchema('node', 'node_access');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests node owner functionality.
|
||||
*/
|
||||
public function testOwner() {
|
||||
$user = $this->createUser();
|
||||
|
||||
$container = \Drupal::getContainer();
|
||||
$container->get('current_user')->setAccount($user);
|
||||
|
||||
// Create a test node.
|
||||
$english = Node::create(array(
|
||||
'type' => 'page',
|
||||
'title' => $this->randomMachineName(),
|
||||
'language' => 'en',
|
||||
));
|
||||
$english->save();
|
||||
|
||||
$this->assertEqual($user->id(), $english->getOwnerId());
|
||||
|
||||
$german = $english->addTranslation('de');
|
||||
$german->title = $this->randomString();
|
||||
$italian = $english->addTranslation('it');
|
||||
$italian->title = $this->randomString();
|
||||
|
||||
// Node::preSave() sets owner to anonymous user if owner is nor set.
|
||||
$english->set('uid', ['target_id' => NULL]);
|
||||
$german->set('uid', ['target_id' => NULL]);
|
||||
$italian->set('uid', ['target_id' => NULL]);
|
||||
|
||||
// Entity::save() saves all translations!
|
||||
$italian->save();
|
||||
|
||||
$this->assertEqual(0, $english->getOwnerId());
|
||||
$this->assertEqual(0, $german->getOwnerId());
|
||||
$this->assertEqual(0, $italian->getOwnerId());
|
||||
}
|
||||
|
||||
}
|
|
@ -45,16 +45,16 @@ class NodeRSSContentTest extends NodeTestBase {
|
|||
$this->drupalGet('rss.xml');
|
||||
|
||||
// Check that content added in 'rss' view mode appear in RSS feed.
|
||||
$rss_only_content = t('Extra data that should appear only in the RSS feed for node !nid.', array('!nid' => $node->id()));
|
||||
$rss_only_content = t('Extra data that should appear only in the RSS feed for node @nid.', array('@nid' => $node->id()));
|
||||
$this->assertText($rss_only_content, 'Node content designated for RSS appear in RSS feed.');
|
||||
|
||||
// Check that content added in view modes other than 'rss' doesn't
|
||||
// appear in RSS feed.
|
||||
$non_rss_content = t('Extra data that should appear everywhere except the RSS feed for node !nid.', array('!nid' => $node->id()));
|
||||
$non_rss_content = t('Extra data that should appear everywhere except the RSS feed for node @nid.', array('@nid' => $node->id()));
|
||||
$this->assertNoText($non_rss_content, 'Node content not designed for RSS does not appear in RSS feed.');
|
||||
|
||||
// Check that extra RSS elements and namespaces are added to RSS feed.
|
||||
$test_element = '<testElement>' . t('Value of testElement RSS element for node !nid.', array('!nid' => $node->id())) . '</testElement>';
|
||||
$test_element = '<testElement>' . t('Value of testElement RSS element for node @nid.', array('@nid' => $node->id())) . '</testElement>';
|
||||
$test_ns = 'xmlns:drupaltest="http://example.com/test-namespace"';
|
||||
$this->assertRaw($test_element, 'Extra RSS elements appear in RSS feed.');
|
||||
$this->assertRaw($test_ns, 'Extra namespaces appear in RSS feed.');
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
|
||||
namespace Drupal\node\Tests;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
@ -34,9 +37,22 @@ class NodeRevisionsTest extends NodeTestBase {
|
|||
|
||||
ConfigurableLanguage::createFromLangcode('it')->save();
|
||||
|
||||
/** @var \Drupal\content_translation\ContentTranslationManagerInterface $manager */
|
||||
$manager = \Drupal::service('content_translation.manager');
|
||||
$manager->setEnabled('node', 'article', TRUE);
|
||||
$field_storage_definition = array(
|
||||
'field_name' => 'untranslatable_string_field',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'string',
|
||||
'cardinality' => 1,
|
||||
'translatable' => FALSE,
|
||||
);
|
||||
$field_storage = FieldStorageConfig::create($field_storage_definition);
|
||||
$field_storage->save();
|
||||
|
||||
$field_definition = array(
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'page',
|
||||
);
|
||||
$field = FieldConfig::create($field_definition);
|
||||
$field->save();
|
||||
|
||||
// Create and log in user.
|
||||
$web_user = $this->drupalCreateUser(
|
||||
|
@ -75,6 +91,7 @@ class NodeRevisionsTest extends NodeTestBase {
|
|||
'value' => $this->randomMachineName(32),
|
||||
'format' => filter_default_format(),
|
||||
);
|
||||
$node->untranslatable_string_field->value = $this->randomString();
|
||||
$node->setNewRevision();
|
||||
$node->save();
|
||||
|
||||
|
@ -227,6 +244,9 @@ class NodeRevisionsTest extends NodeTestBase {
|
|||
public function testRevisionTranslationRevert() {
|
||||
// Create a node and a few revisions.
|
||||
$node = $this->drupalCreateNode(['langcode' => 'en']);
|
||||
|
||||
$initial_revision_id = $node->getRevisionId();
|
||||
$initial_title = $node->label();
|
||||
$this->createRevisions($node, 2);
|
||||
|
||||
// Translate the node and create a few translation revisions.
|
||||
|
@ -234,6 +254,7 @@ class NodeRevisionsTest extends NodeTestBase {
|
|||
$this->createRevisions($translation, 3);
|
||||
$revert_id = $node->getRevisionId();
|
||||
$translated_title = $translation->label();
|
||||
$untranslatable_string = $node->untranslatable_string_field->value;
|
||||
|
||||
// Create a new revision for the default translation in-between a series of
|
||||
// translation revisions.
|
||||
|
@ -247,7 +268,12 @@ class NodeRevisionsTest extends NodeTestBase {
|
|||
// Now revert the a translation revision preceding the last default
|
||||
// translation revision, and check that the desired value was reverted but
|
||||
// the default translation value was preserved.
|
||||
$this->drupalPostForm("node/" . $node->id() . "/revisions/" . $revert_id . "/revert", [], t('Revert'));
|
||||
$revert_translation_url = Url::fromRoute('node.revision_revert_translation_confirm', [
|
||||
'node' => $node->id(),
|
||||
'node_revision' => $revert_id,
|
||||
'langcode' => 'it',
|
||||
]);
|
||||
$this->drupalPostForm($revert_translation_url, [], t('Revert'));
|
||||
/** @var \Drupal\node\NodeStorage $node_storage */
|
||||
$node_storage = $this->container->get('entity.manager')->getStorage('node');
|
||||
$node_storage->resetCache();
|
||||
|
@ -256,6 +282,38 @@ class NodeRevisionsTest extends NodeTestBase {
|
|||
$this->assertTrue($node->getRevisionId() > $translation_revision_id);
|
||||
$this->assertEqual($node->label(), $default_translation_title);
|
||||
$this->assertEqual($node->getTranslation('it')->label(), $translated_title);
|
||||
$this->assertNotEqual($node->untranslatable_string_field->value, $untranslatable_string);
|
||||
|
||||
$latest_revision_id = $translation->getRevisionId();
|
||||
|
||||
// Now revert the a translation revision preceding the last default
|
||||
// translation revision again, and check that the desired value was reverted
|
||||
// but the default translation value was preserved. But in addition the
|
||||
// untranslated field will be reverted as well.
|
||||
$this->drupalPostForm($revert_translation_url, ['revert_untranslated_fields' => TRUE], t('Revert'));
|
||||
$node_storage->resetCache();
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
$node = $node_storage->load($node->id());
|
||||
$this->assertTrue($node->getRevisionId() > $latest_revision_id);
|
||||
$this->assertEqual($node->label(), $default_translation_title);
|
||||
$this->assertEqual($node->getTranslation('it')->label(), $translated_title);
|
||||
$this->assertEqual($node->untranslatable_string_field->value, $untranslatable_string);
|
||||
|
||||
$latest_revision_id = $translation->getRevisionId();
|
||||
|
||||
// Now revert the entity revision to the initial one where the translation
|
||||
// didn't exist.
|
||||
$revert_url = Url::fromRoute('node.revision_revert_confirm', [
|
||||
'node' => $node->id(),
|
||||
'node_revision' => $initial_revision_id,
|
||||
]);
|
||||
$this->drupalPostForm($revert_url, [], t('Revert'));
|
||||
$node_storage->resetCache();
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
$node = $node_storage->load($node->id());
|
||||
$this->assertTrue($node->getRevisionId() > $latest_revision_id);
|
||||
$this->assertEqual($node->label(), $initial_title);
|
||||
$this->assertFalse($node->hasTranslation('it'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -269,6 +327,7 @@ class NodeRevisionsTest extends NodeTestBase {
|
|||
protected function createRevisions(NodeInterface $node, $count) {
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$node->title = $this->randomString();
|
||||
$node->untranslatable_string_field->value = $this->randomString();
|
||||
$node->setNewRevision(TRUE);
|
||||
$node->save();
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue