From 94cd6717a8bd07eb1333d79fb9ab8aa61d845129 Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org> Date: Tue, 27 Aug 2013 11:36:16 +0100 Subject: [PATCH] Issue #1939994 by Berdir, rlmumford: Complete conversion of nodes to the new Entity Field API. --- .../Core/Entity/EntityAccessController.php | 2 +- .../Core/Entity/EntityFormController.php | 4 +- core/modules/book/book.module | 10 ++ .../book/lib/Drupal/book/Tests/BookTest.php | 4 +- .../templates/book-node-export-html.html.twig | 2 +- core/modules/comment/comment.module | 24 +-- core/modules/comment/comment.pages.inc | 2 +- .../Drupal/comment/CommentFormController.php | 2 +- .../Drupal/comment/Tests/CommentLinksTest.php | 2 +- .../Tests/EntityReferenceAutoCreateTest.php | 2 +- .../Drupal/field/Plugin/views/field/Field.php | 8 +- .../Tests/Views/HandlerFieldFieldTest.php | 12 +- .../file/Tests/FileFieldDisplayTest.php | 2 +- .../Drupal/file/Tests/FileFieldPathTest.php | 6 +- .../file/Tests/FileFieldRSSContentTest.php | 2 +- .../file/Tests/FileFieldRevisionTest.php | 10 +- .../file/Tests/FileFieldValidateTest.php | 12 +- .../Drupal/file/Tests/FileFieldWidgetTest.php | 8 +- .../lib/Drupal/file/Tests/FileListingTest.php | 2 +- .../lib/Drupal/file/Tests/FilePrivateTest.php | 4 +- .../file/Tests/FileTokenReplaceTest.php | 2 +- .../filter/Tests/FilterSecurityTest.php | 4 +- core/modules/forum/forum.module | 33 ++-- .../lib/Drupal/forum/Tests/ForumTest.php | 2 +- .../templates/forum-topic-list.html.twig | 8 +- .../image/Tests/ImageFieldDisplayTest.php | 8 +- .../node/lib/Drupal/node/Entity/Node.php | 16 +- .../node/lib/Drupal/node/NodeBCDecorator.php | 148 ------------------ .../lib/Drupal/node/NodeFormController.php | 46 ++++-- .../Drupal/node/NodeGrantDatabaseStorage.php | 2 +- .../lib/Drupal/node/NodeStorageController.php | 32 +--- .../lib/Drupal/node/Plugin/views/row/Rss.php | 2 +- .../Tests/NodeFieldMultilingualTestCase.php | 6 +- .../node/Tests/NodeRevisionsAllTestCase.php | 6 +- .../Drupal/node/Tests/NodeRevisionsTest.php | 12 +- .../lib/Drupal/node/Tests/NodeSaveTest.php | 2 +- .../node/Tests/NodeTokenReplaceTest.php | 15 +- .../node/Tests/NodeTranslationUITest.php | 2 +- .../Drupal/node/Tests/Views/RowPluginTest.php | 16 +- core/modules/node/node.api.php | 4 +- core/modules/node/node.module | 45 +----- core/modules/node/node.pages.inc | 17 +- core/modules/node/node.tokens.inc | 2 +- core/modules/node/node.views.inc | 2 +- .../node_access_test/node_access_test.module | 29 +++- .../node_access_test_language.module | 3 +- .../tests/modules/node_test/node_test.module | 6 +- core/modules/path/path.module | 101 ++++-------- .../picture/Tests/PictureFieldDisplayTest.php | 2 +- .../rdf/Tests/FileFieldAttributesTest.php | 2 +- .../rdf/Tests/ImageFieldAttributesTest.php | 2 +- .../Tests/SearchMultilingualEntityTest.php | 6 +- .../system/Tests/Plugin/PluginTestBase.php | 2 +- .../Tests/Upgrade/FieldUpgradePathTest.php | 17 +- .../plugin_test/Plugin/MockBlockManager.php | 2 +- .../Drupal/taxonomy/Tests/TermIndexTest.php | 4 +- core/modules/taxonomy/taxonomy.module | 19 +-- .../translation/Tests/TranslationTest.php | 23 ++- core/modules/translation/translation.module | 74 +++++---- .../modules/translation/translation.pages.inc | 13 +- .../Drupal/views/Tests/DefaultViewsTest.php | 2 +- 61 files changed, 309 insertions(+), 550 deletions(-) delete mode 100644 core/modules/node/lib/Drupal/node/NodeBCDecorator.php diff --git a/core/lib/Drupal/Core/Entity/EntityAccessController.php b/core/lib/Drupal/Core/Entity/EntityAccessController.php index 164b83e4dfa7..4658d50f1974 100644 --- a/core/lib/Drupal/Core/Entity/EntityAccessController.php +++ b/core/lib/Drupal/Core/Entity/EntityAccessController.php @@ -58,7 +58,7 @@ public function access(EntityInterface $entity, $operation, $langcode = Language // We grant access to the entity if both of these conditions are met: // - No modules say to deny access. // - At least one module says to grant access. - $access = module_invoke_all($entity->entityType() . '_access', $entity->getBCEntity(), $operation, $account, $langcode); + $access = module_invoke_all($entity->entityType() . '_access', $entity, $operation, $account, $langcode); if (($return = $this->processAccessHookResults($access)) === NULL) { // No module had an opinion about the access, so let's the access diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php index 372bf359a77e..bc84d1677064 100644 --- a/core/lib/Drupal/Core/Entity/EntityFormController.php +++ b/core/lib/Drupal/Core/Entity/EntityFormController.php @@ -480,9 +480,7 @@ public function getEntity() { */ protected function getTranslatedEntity(array $form_state) { $langcode = $this->getFormLangcode($form_state); - $translation = $this->entity->getTranslation($langcode); - // Ensure that the entity object is a BC entity if the original one is. - return $this->entity instanceof EntityBCDecorator ? $translation->getBCEntity() : $translation; + return $this->entity->getTranslation($langcode); } /** diff --git a/core/modules/book/book.module b/core/modules/book/book.module index e9e863e785cd..525056e15558 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -327,9 +327,19 @@ function book_form_node_form_alter(&$form, &$form_state, $form_id) { 'css' => array(drupal_get_path('module', 'book') . '/css/book.admin.css'), ), ); + $form['#entity_builders'][] = 'book_node_builder'; } } +/** + * Entity form builder to add the book information to the node. + * + * @todo: Remove this in favor of an entity field. + */ +function book_node_builder($entity_type, $entity, &$form, &$form_state) { + $entity->book = $form_state['values']['book']; +} + /** * Form submission handler for node_form(). * diff --git a/core/modules/book/lib/Drupal/book/Tests/BookTest.php b/core/modules/book/lib/Drupal/book/Tests/BookTest.php index 85c8c85e357c..f4ad8754bd80 100644 --- a/core/modules/book/lib/Drupal/book/Tests/BookTest.php +++ b/core/modules/book/lib/Drupal/book/Tests/BookTest.php @@ -206,7 +206,7 @@ function checkBookNode(EntityInterface $node, $nodes, $previous = FALSE, $up = F // Check printer friendly version. $this->drupalGet('book/export/html/' . $node->id()); $this->assertText($node->label(), 'Printer friendly title found.'); - $this->assertRaw(check_markup($node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'], $node->body[Language::LANGCODE_NOT_SPECIFIED][0]['format']), 'Printer friendly body found.'); + $this->assertRaw($node->body->processed, 'Printer friendly body found.'); $number++; } @@ -281,7 +281,7 @@ function testBookExport() { // Make sure each part of the book is there. foreach ($nodes as $node) { $this->assertText($node->label(), 'Node title found in printer friendly version.'); - $this->assertRaw(check_markup($node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'], $node->body[Language::LANGCODE_NOT_SPECIFIED][0]['format']), 'Node body found in printer friendly version.'); + $this->assertRaw($node->body->processed, 'Node body found in printer friendly version.'); } // Make sure we can't export an unsupported format. diff --git a/core/modules/book/templates/book-node-export-html.html.twig b/core/modules/book/templates/book-node-export-html.html.twig index 7719bc7339a0..0efa9a7adcf4 100644 --- a/core/modules/book/templates/book-node-export-html.html.twig +++ b/core/modules/book/templates/book-node-export-html.html.twig @@ -15,7 +15,7 @@ * @ingroup themeable */ #} -<article id="node-{{ node.nid }}" class="section-{{ depth }}"> +<article id="node-{{ node.id }}" class="section-{{ depth }}"> <h1 class="book-heading">{{ title }}</h1> {{ content }} {{ children }} diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index b7869fbe8acb..ef12cc11bee3 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -516,7 +516,7 @@ function theme_comment_block($variables) { function comment_node_view(EntityInterface $node, EntityDisplay $display, $view_mode) { $links = array(); - if ($node->comment != COMMENT_NODE_HIDDEN) { + if ($node->comment->value != COMMENT_NODE_HIDDEN) { if ($view_mode == 'rss') { // Add a comments RSS element which is a URL to the comments of this node. $node->rss_elements[] = array( @@ -550,7 +550,7 @@ function comment_node_view(EntityInterface $node, EntityDisplay $display, $view_ } } } - if ($node->comment == COMMENT_NODE_OPEN) { + if ($node->comment->value == COMMENT_NODE_OPEN) { $comment_form_location = variable_get('comment_form_location_' . $node->getType(), COMMENT_FORM_BELOW); if (user_access('post comments')) { $links['comment-add'] = array( @@ -580,7 +580,7 @@ function comment_node_view(EntityInterface $node, EntityDisplay $display, $view_ // allowed to post comments and if this node is allowing new comments. // But we don't want this link if we're building the node for search // indexing or constructing a search result excerpt. - if ($node->comment == COMMENT_NODE_OPEN) { + if ($node->comment->value == COMMENT_NODE_OPEN) { $comment_form_location = variable_get('comment_form_location_' . $node->getType(), COMMENT_FORM_BELOW); if (user_access('post comments')) { // Show the "post comment" link if the form is on another page, or @@ -655,7 +655,7 @@ function comment_node_page_additions(EntityInterface $node) { } // Append comment form if needed. - if (user_access('post comments') && $node->comment == COMMENT_NODE_OPEN && (variable_get('comment_form_location_' . $node->getType(), COMMENT_FORM_BELOW) == COMMENT_FORM_BELOW)) { + if (user_access('post comments') && $node->comment->value == COMMENT_NODE_OPEN && (variable_get('comment_form_location_' . $node->getType(), COMMENT_FORM_BELOW) == COMMENT_FORM_BELOW)) { $additions['comment_form'] = comment_add($node); } @@ -874,7 +874,7 @@ function comment_view(Comment $comment, $view_mode = 'full', $langcode = NULL) { */ function comment_links(Comment $comment, EntityInterface $node) { $links = array(); - if ($node->comment == COMMENT_NODE_OPEN) { + if ($node->comment->value == COMMENT_NODE_OPEN) { if ($comment->access('delete')) { $links['comment-delete'] = array( 'title' => t('delete'), @@ -1072,7 +1072,7 @@ function comment_form_node_form_alter(&$form, $form_state) { '#weight' => 30, ); $comment_count = $node->id() ? db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array(':nid' => $node->id()))->fetchField() : 0; - $comment_settings = ($node->comment == COMMENT_NODE_HIDDEN && empty($comment_count)) ? COMMENT_NODE_CLOSED : $node->comment; + $comment_settings = ($node->comment->value == COMMENT_NODE_HIDDEN && empty($comment_count)) ? COMMENT_NODE_CLOSED : $node->comment->value; $form['comment_settings']['comment'] = array( '#type' => 'radios', '#title' => t('Comments'), @@ -1113,7 +1113,7 @@ function comment_node_load($nodes, $types) { // assign values without hitting the database. foreach ($nodes as $node) { // Store whether comments are enabled for this node. - if ($node->comment != COMMENT_NODE_HIDDEN) { + if ($node->comment->value != COMMENT_NODE_HIDDEN) { $comments_enabled[] = $node->id(); } else { @@ -1142,7 +1142,7 @@ function comment_node_load($nodes, $types) { * Implements hook_node_prepare_form(). */ function comment_node_prepare_form(NodeInterface $node, $form_display, $operation, array &$form_state) { - if (!isset($node->comment)) { + if (!isset($node->comment->value)) { $node->comment = variable_get('comment_' . $node->getType(), COMMENT_NODE_OPEN); } } @@ -1209,8 +1209,8 @@ function comment_node_update_index(EntityInterface $node, $langcode) { if ($index_comments) { $mode = variable_get('comment_default_mode_' . $node->getType(), COMMENT_MODE_THREADED); - $comments_per_page = variable_get('comment_default_per_page_' . $node->getType(), 50); - if ($node->comment && $cids = comment_get_thread($node, $mode, $comments_per_page)) { + $comments_per_page = variable_get('comment_default_per_page_' . $node->bundle(), 50); + if ($node->comment->value && $cids = comment_get_thread($node, $mode, $comments_per_page)) { $comments = comment_load_multiple($cids); comment_prepare_thread($comments); $build = comment_view_multiple($comments, $langcode); @@ -1236,11 +1236,11 @@ function comment_update_index() { */ function comment_node_search_result(EntityInterface $node) { // Do not make a string if comments are hidden. - if (user_access('access comments') && $node->comment != COMMENT_NODE_HIDDEN) { + if (user_access('access comments') && $node->comment->value != COMMENT_NODE_HIDDEN) { $comments = db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array('nid' => $node->id()))->fetchField(); // Do not make a string if comments are closed and there are currently // zero comments. - if ($node->comment != COMMENT_NODE_CLOSED || $comments > 0) { + if ($node->comment->value != COMMENT_NODE_CLOSED || $comments > 0) { return array('comment' => format_plural($comments, '1 comment', '@count comments')); } } diff --git a/core/modules/comment/comment.pages.inc b/core/modules/comment/comment.pages.inc index b11b4938be51..d193132b84ff 100644 --- a/core/modules/comment/comment.pages.inc +++ b/core/modules/comment/comment.pages.inc @@ -84,7 +84,7 @@ function comment_reply(EntityInterface $node, $pid = NULL) { } // Should we show the reply box? - if ($node->comment != COMMENT_NODE_OPEN) { + if ($node->comment->value != COMMENT_NODE_OPEN) { drupal_set_message(t("This discussion is closed: you can't post new comments."), 'error'); return new RedirectResponse(url('node/' . $node->id(), array('absolute' => TRUE))); } diff --git a/core/modules/comment/lib/Drupal/comment/CommentFormController.php b/core/modules/comment/lib/Drupal/comment/CommentFormController.php index ad4b9a007f79..750f7481db14 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentFormController.php +++ b/core/modules/comment/lib/Drupal/comment/CommentFormController.php @@ -318,7 +318,7 @@ public function save(array $form, array &$form_state) { $node = node_load($form_state['values']['nid']); $comment = $this->entity; - if (user_access('post comments') && (user_access('administer comments') || $node->comment == COMMENT_NODE_OPEN)) { + if (user_access('post comments') && (user_access('administer comments') || $node->comment->value == COMMENT_NODE_OPEN)) { // Save the anonymous user information to a cookie for reuse. if (user_is_anonymous()) { user_cookie_save(array_intersect_key($form_state['values'], array_flip(array('name', 'mail', 'homepage')))); diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php index fd86097fba36..bf7cdb5b255c 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php @@ -169,7 +169,7 @@ function setEnvironment(array $info) { // Change comment settings. variable_set('comment_form_location_' . $this->node->getType(), $info['form']); variable_set('comment_anonymous_' . $this->node->getType(), $info['contact']); - if ($this->node->comment != $info['comments']) { + if ($this->node->comment->value != $info['comments']) { $this->node->comment = $info['comments']; $this->node->save(); } diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php index f5f74d0a95d0..a19e1a97ce49 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php @@ -113,7 +113,7 @@ public function testAutoCreate() { $referencing_nid = key($result); $referencing_node = node_load($referencing_nid); - $this->assertEqual($referenced_nid, $referencing_node->test_field[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'], 'Newly created node is referenced from the referencing node.'); + $this->assertEqual($referenced_nid, $referencing_node->test_field->target_id, 'Newly created node is referenced from the referencing node.'); // Now try to view the node and check that the referenced node is shown. $this->drupalGet('node/' . $referencing_node->id()); diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php index fdfea1062825..a487a7afc1c5 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php +++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php @@ -726,10 +726,10 @@ function process_entity(EntityInterface $entity) { if ($data) { // Now, overwrite the original value with our aggregated value. // This overwrites it so there is always just one entry. - $processed_entity->{$this->definition['field_name']}[$langcode] = array($base_value); + $processed_entity->getTranslation($langcode)->{$this->definition['field_name']} = array($base_value); } else { - $processed_entity->{$this->definition['field_name']}[$langcode] = array(); + $processed_entity->getTranslation($langcode)->{$this->definition['field_name']} = array(); } } @@ -740,7 +740,7 @@ function process_entity(EntityInterface $entity) { // We are supposed to show only certain deltas. if ($this->limit_values && !empty($processed_entity->{$this->definition['field_name']})) { - $all_values = !empty($processed_entity->{$this->definition['field_name']}[$langcode]) ? $processed_entity->{$this->definition['field_name']}[$langcode] : array(); + $all_values = !empty($processed_entity->getTranslation($langcode)->{$this->definition['field_name']}) ? $processed_entity->getTranslation($langcode)->{$this->definition['field_name']}->getValue() : array(); if ($this->options['delta_reversed']) { $all_values = array_reverse($all_values); } @@ -786,7 +786,7 @@ function process_entity(EntityInterface $entity) { } } } - $processed_entity->{$this->definition['field_name']}[$langcode] = $new_values; + $processed_entity->getTranslation($langcode)->{$this->definition['field_name']} = $new_values; } return $processed_entity; diff --git a/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php b/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php index 8658c523e659..c42950d55743 100644 --- a/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php @@ -107,7 +107,7 @@ public function _testSimpleFieldRender() { for ($key = 0; $key < 2; $key++) { $field = $this->fields[$key]; $rendered_field = $view->style_plugin->getField($i, $field['field_name']); - $expected_field = $this->nodes[$i]->{$field['field_name']}[Language::LANGCODE_NOT_SPECIFIED][0]['value']; + $expected_field = $this->nodes[$i]->{$field['field_name']}->value; $this->assertEqual($rendered_field, $expected_field); } } @@ -146,7 +146,7 @@ public function _testMultipleFieldRender() { for ($i = 0; $i < 3; $i++) { $rendered_field = $view->style_plugin->getField($i, $field_name); $items = array(); - $pure_items = $this->nodes[$i]->{$field_name}[Language::LANGCODE_NOT_SPECIFIED]; + $pure_items = $this->nodes[$i]->{$field_name}->getValue(); $pure_items = array_splice($pure_items, 0, 3); foreach ($pure_items as $j => $item) { $items[] = $pure_items[$j]['value']; @@ -169,7 +169,7 @@ public function _testMultipleFieldRender() { for ($i = 0; $i < 3; $i++) { $rendered_field = $view->style_plugin->getField($i, $field_name); $items = array(); - $pure_items = $this->nodes[$i]->{$field_name}[Language::LANGCODE_NOT_SPECIFIED]; + $pure_items = $this->nodes[$i]->{$field_name}->getValue(); $pure_items = array_splice($pure_items, 1, 3); foreach ($pure_items as $j => $item) { $items[] = $pure_items[$j]['value']; @@ -189,7 +189,7 @@ public function _testMultipleFieldRender() { for ($i = 0; $i < 3; $i++) { $rendered_field = $view->style_plugin->getField($i, $field_name); $items = array(); - $pure_items = $this->nodes[$i]->{$field_name}[Language::LANGCODE_NOT_SPECIFIED]; + $pure_items = $this->nodes[$i]->{$field_name}->getValue(); array_splice($pure_items, 0, -3); $pure_items = array_reverse($pure_items); foreach ($pure_items as $j => $item) { @@ -210,7 +210,7 @@ public function _testMultipleFieldRender() { for ($i = 0; $i < 3; $i++) { $rendered_field = $view->style_plugin->getField($i, $field_name); $items = array(); - $pure_items = $this->nodes[$i]->{$field_name}[Language::LANGCODE_NOT_SPECIFIED]; + $pure_items = $this->nodes[$i]->{$field_name}->getValue(); $items[] = $pure_items[0]['value']; $items[] = $pure_items[4]['value']; $this->assertEqual($rendered_field, implode(', ', $items), 'Take sure that the amount of items are limited.'); @@ -228,7 +228,7 @@ public function _testMultipleFieldRender() { for ($i = 0; $i < 3; $i++) { $rendered_field = $view->style_plugin->getField($i, $field_name); $items = array(); - $pure_items = $this->nodes[$i]->{$field_name}[Language::LANGCODE_NOT_SPECIFIED]; + $pure_items = $this->nodes[$i]->{$field_name}->getValue(); $pure_items = array_splice($pure_items, 0, 3); foreach ($pure_items as $j => $item) { $items[] = $pure_items[$j]['value']; diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php index 4ef654dc981f..7f3f5c8bba94 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldDisplayTest.php @@ -60,7 +60,7 @@ function testNodeDisplay() { // Check that the default formatter is displaying with the file name. $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); $file_link = array( '#theme' => 'file_link', '#file' => $node_file, diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php index f2c45b670bfd..374b5fd06916 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php @@ -35,7 +35,7 @@ function testUploadPath() { // Check that the file was uploaded to the file root. $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); $this->assertPathMatch('public://' . $test_file->getFilename(), $node_file->getFileUri(), format_string('The file %file was uploaded to the correct path.', array('%file' => $node_file->getFileUri()))); // Change the path to contain multiple subdirectories. @@ -46,7 +46,7 @@ function testUploadPath() { // Check that the file was uploaded into the subdirectory. $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'], TRUE); + $node_file = file_load($node->{$field_name}->target_id, TRUE); $this->assertPathMatch('public://foo/bar/baz/' . $test_file->getFilename(), $node_file->getFileUri(), format_string('The file %file was uploaded to the correct path.', array('%file' => $node_file->getFileUri()))); // Check the path when used with tokens. @@ -58,7 +58,7 @@ function testUploadPath() { // Check that the file was uploaded into the subdirectory. $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); // Do token replacement using the same user which uploaded the file, not // the user running the test case. $data = array('user' => $this->admin_user); diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php index d031ffe492bb..7f051f5f201c 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldRSSContentTest.php @@ -67,7 +67,7 @@ function testFileFieldRSSContent() { // Get the uploaded file from the node. $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); // Check that the RSS enclosure appears in the RSS feed. $this->drupalGet('rss.xml'); diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldRevisionTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldRevisionTest.php index a6225b501062..c7c2c72164d9 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldRevisionTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldRevisionTest.php @@ -47,7 +47,7 @@ function testRevisions() { // Check that the file exists on disk and in the database. $node = node_load($nid, TRUE); - $node_file_r1 = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file_r1 = file_load($node->{$field_name}->target_id); $node_vid_r1 = $node->getRevisionId(); $this->assertFileExists($node_file_r1, 'New file saved to disk on node creation.'); $this->assertFileEntryExists($node_file_r1, 'File entry exists in database on node creation.'); @@ -56,7 +56,7 @@ function testRevisions() { // Upload another file to the same node in a new revision. $this->replaceNodeFile($test_file, $field_name, $nid); $node = node_load($nid, TRUE); - $node_file_r2 = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file_r2 = file_load($node->{$field_name}->target_id); $node_vid_r2 = $node->getRevisionId(); $this->assertFileExists($node_file_r2, 'Replacement file exists on disk after creating new revision.'); $this->assertFileEntryExists($node_file_r2, 'Replacement file entry exists in database after creating new revision.'); @@ -64,7 +64,7 @@ function testRevisions() { // Check that the original file is still in place on the first revision. $node = node_revision_load($node_vid_r1); - $current_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $current_file = file_load($node->{$field_name}->target_id); $this->assertEqual($node_file_r1->id(), $current_file->id(), 'Original file still in place after replacing file in new revision.'); $this->assertFileExists($node_file_r1, 'Original file still in place after replacing file in new revision.'); $this->assertFileEntryExists($node_file_r1, 'Original file entry still in place after replacing file in new revision'); @@ -74,7 +74,7 @@ function testRevisions() { // Check that the file is still the same as the previous revision. $this->drupalPost('node/' . $nid . '/edit', array('revision' => '1'), t('Save and keep published')); $node = node_load($nid, TRUE); - $node_file_r3 = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file_r3 = file_load($node->{$field_name}->target_id); $node_vid_r3 = $node->getRevisionId(); $this->assertEqual($node_file_r2->id(), $node_file_r3->id(), 'Previous revision file still in place after creating a new revision without a new file.'); $this->assertFileIsPermanent($node_file_r3, 'New revision file is permanent.'); @@ -82,7 +82,7 @@ function testRevisions() { // Revert to the first revision and check that the original file is active. $this->drupalPost('node/' . $nid . '/revisions/' . $node_vid_r1 . '/revert', array(), t('Revert')); $node = node_load($nid, TRUE); - $node_file_r4 = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file_r4 = file_load($node->{$field_name}->target_id); $node_vid_r4 = $node->getRevisionId(); $this->assertEqual($node_file_r1->id(), $node_file_r4->id(), 'Original revision file still in place after reverting to the original revision.'); $this->assertFileIsPermanent($node_file_r4, 'Original revision file still permanent after reverting to the original revision.'); diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php index a7cf1e57bc03..2b3019cdf32d 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php @@ -47,7 +47,7 @@ function testRequired() { $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); $this->assertFileExists($node_file, 'File exists after uploading to the required field.'); $this->assertFileEntryExists($node_file, 'File entry exists after uploading to the required field.'); @@ -63,7 +63,7 @@ function testRequired() { // Create a new node with the uploaded file into the multivalue field. $nid = $this->uploadNodeFile($test_file, $field_name, $type_name); $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); $this->assertFileExists($node_file, 'File exists after uploading to the required multiple value field.'); $this->assertFileEntryExists($node_file, 'File entry exists after uploading to the required multiple value field.'); } @@ -93,7 +93,7 @@ function testFileMaxSize() { // Create a new node with the small file, which should pass. $nid = $this->uploadNodeFile($small_file, $field_name, $type_name); $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); $this->assertFileExists($node_file, format_string('File exists after uploading a file (%filesize) under the max limit (%maxsize).', array('%filesize' => format_size($small_file->getSize()), '%maxsize' => $max_filesize))); $this->assertFileEntryExists($node_file, format_string('File entry exists after uploading a file (%filesize) under the max limit (%maxsize).', array('%filesize' => format_size($small_file->getSize()), '%maxsize' => $max_filesize))); @@ -109,7 +109,7 @@ function testFileMaxSize() { // Upload the big file successfully. $nid = $this->uploadNodeFile($large_file, $field_name, $type_name); $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); $this->assertFileExists($node_file, format_string('File exists after uploading a file (%filesize) with no max limit.', array('%filesize' => format_size($large_file->getSize())))); $this->assertFileEntryExists($node_file, format_string('File entry exists after uploading a file (%filesize) with no max limit.', array('%filesize' => format_size($large_file->getSize())))); } @@ -131,7 +131,7 @@ function testFileExtension() { // Check that the file can be uploaded with no extension checking. $nid = $this->uploadNodeFile($test_file, $field_name, $type_name); $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); $this->assertFileExists($node_file, 'File exists after uploading a file with no extension checking.'); $this->assertFileEntryExists($node_file, 'File entry exists after uploading a file with no extension checking.'); @@ -149,7 +149,7 @@ function testFileExtension() { // Check that the file can be uploaded with extension checking. $nid = $this->uploadNodeFile($test_file, $field_name, $type_name); $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); $this->assertFileExists($node_file, 'File exists after uploading a file with extension checking.'); $this->assertFileEntryExists($node_file, 'File entry exists after uploading a file with extension checking.'); } diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php index e48138470e04..24a54752f482 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php @@ -46,7 +46,7 @@ function testSingleValuedWidget() { // does not yet support file uploads. $nid = $this->uploadNodeFile($test_file, $field_name, $type_name); $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); $this->assertFileExists($node_file, 'New file saved to disk on node creation.'); // Ensure the file can be downloaded. @@ -79,7 +79,7 @@ function testSingleValuedWidget() { // Save the node and ensure it does not have the file. $this->drupalPost(NULL, array(), t('Save and keep published')); $node = node_load($nid, TRUE); - $this->assertTrue(empty($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']), 'File was successfully removed from the node.'); + $this->assertTrue(empty($node->{$field_name}->target_id), 'File was successfully removed from the node.'); } } @@ -196,7 +196,7 @@ function testMultiValuedWidget() { preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches); $nid = $matches[1]; $node = node_load($nid, TRUE); - $this->assertTrue(empty($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']), 'Node was successfully saved without any files.'); + $this->assertTrue(empty($node->{$field_name}->target_id), 'Node was successfully saved without any files.'); } } @@ -216,7 +216,7 @@ function testPrivateFileSetting() { $this->drupalPost("admin/structure/types/manage/$type_name/fields/$instance->id/field", $edit, t('Save field settings')); $nid = $this->uploadNodeFile($test_file, $field_name, $type_name); $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); $this->assertFileExists($node_file, 'New file saved to disk on node creation.'); // Ensure the private file is available to the user who uploaded it. diff --git a/core/modules/file/lib/Drupal/file/Tests/FileListingTest.php b/core/modules/file/lib/Drupal/file/Tests/FileListingTest.php index 693f23693176..69842eb3465a 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileListingTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileListingTest.php @@ -82,7 +82,7 @@ function testFileListingPages() { 'files[file_' . Language::LANGCODE_NOT_SPECIFIED . '_' . 0 . ']' => drupal_realpath($file->getFileUri()), ); $this->drupalPost(NULL, $edit, t('Save')); - $node = entity_load('node', $node->id())->getNGEntity(); + $node = entity_load('node', $node->id()); } $this->drupalGet('admin/content/files'); diff --git a/core/modules/file/lib/Drupal/file/Tests/FilePrivateTest.php b/core/modules/file/lib/Drupal/file/Tests/FilePrivateTest.php index 1b8a82f651e9..cfeee72f2c22 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FilePrivateTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FilePrivateTest.php @@ -50,7 +50,7 @@ function testPrivateFile() { $test_file = $this->getTestFile('text'); $nid = $this->uploadNodeFile($test_file, $field_name, $type_name, TRUE, array('private' => TRUE)); $node = node_load($nid, TRUE); - $node_file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$field_name}->target_id); // Ensure the file can be downloaded. $this->drupalGet(file_create_url($node_file->getFileUri())); $this->assertResponse(200, 'Confirmed that the generated URL is correct by downloading the shipped file.'); @@ -62,7 +62,7 @@ function testPrivateFile() { $this->drupalLogin($this->admin_user); $nid = $this->uploadNodeFile($test_file, $no_access_field_name, $type_name, TRUE, array('private' => TRUE)); $node = node_load($nid, TRUE); - $node_file = file_load($node->{$no_access_field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $node_file = file_load($node->{$no_access_field_name}->target_id); // Ensure the file cannot be downloaded. $this->drupalGet(file_create_url($node_file->getFileUri())); $this->assertResponse(403, 'Confirmed that access is denied for the file without view field access permission.'); diff --git a/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php b/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php index 36d323d156e8..5036c3ec11fd 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php @@ -47,7 +47,7 @@ function testFileTokenReplacement() { // Load the node and the file. $node = node_load($nid, TRUE); - $file = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $file = file_load($node->{$field_name}->target_id); // Generate and test sanitized tokens. $tests = array(); diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterSecurityTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterSecurityTest.php index 75af0b0310d4..2023434f846e 100644 --- a/core/modules/filter/lib/Drupal/filter/Tests/FilterSecurityTest.php +++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterSecurityTest.php @@ -72,8 +72,8 @@ function setUp() { function testDisableFilterModule() { // Create a new node. $node = $this->drupalCreateNode(array('promote' => 1)); - $body_raw = $node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value']; - $format_id = $node->body[Language::LANGCODE_NOT_SPECIFIED][0]['format']; + $body_raw = $node->body->value; + $format_id = $node->body->format; $this->drupalGet('node/' . $node->id()); $this->assertText($body_raw, 'Node body found.'); diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index 41d26040ead3..9352e0dd2c47 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -278,17 +278,17 @@ function forum_node_validate(EntityInterface $node, $form) { if (_forum_node_check_node_type($node)) { $langcode = $form['taxonomy_forums']['#language']; // vocabulary is selected, not a "container" term. - if (!empty($node->taxonomy_forums[$langcode])) { + if (!$node->taxonomy_forums->isEmpty()) { // Extract the node's proper topic ID. $containers = Drupal::config('forum.settings')->get('containers'); - foreach ($node->taxonomy_forums[$langcode] as $delta => $item) { + foreach ($node->taxonomy_forums as $delta => $item) { // If no term was selected (e.g. when no terms exist yet), remove the // item. - if (empty($item['target_id'])) { - unset($node->taxonomy_forums[$langcode][$delta]); + if (empty($item->target_id)) { + unset($node->taxonomy_forums[$delta]); continue; } - $term = entity_load('taxonomy_term', $item['target_id']); + $term = $item->entity; if (!$term) { form_set_error('taxonomy_forums', t('Select a forum.')); continue; @@ -311,19 +311,18 @@ function forum_node_validate(EntityInterface $node, $form) { * Assigns the forum taxonomy when adding a topic from within a forum. */ function forum_node_presave(EntityInterface $node) { + if (_forum_node_check_node_type($node)) { // Make sure all fields are set properly: $node->icon = !empty($node->icon) ? $node->icon : ''; - reset($node->taxonomy_forums); - $langcode = key($node->taxonomy_forums); - if (!empty($node->taxonomy_forums[$langcode])) { - $node->forum_tid = $node->taxonomy_forums[$langcode][0]['target_id']; + if (!$node->taxonomy_forums->isEmpty()) { + $node->forum_tid = $node->taxonomy_forums->target_id; // Only do a shadow copy check if this is not a new node. if (!$node->isNew()) { $old_tid = db_query_range("SELECT f.tid FROM {forum} f INNER JOIN {node} n ON f.vid = n.vid WHERE n.nid = :nid ORDER BY f.vid DESC", 0, 1, array(':nid' => $node->id()))->fetchField(); if ($old_tid && isset($node->forum_tid) && ($node->forum_tid != $old_tid) && !empty($node->shadow)) { // A shadow copy needs to be created. Retain new term and add old term. - $node->taxonomy_forums[$langcode][] = array('target_id' => $old_tid); + $node->taxonomy_forums[count($node->taxonomy_forums)] = array('target_id' => $old_tid); } } } @@ -501,6 +500,7 @@ function forum_comment_delete($comment) { * Implements hook_field_storage_pre_insert(). */ function forum_field_storage_pre_insert(EntityInterface $entity, &$skip_fields) { + $entity = $entity->getNGEntity(); if ($entity->entityType() == 'node' && $entity->isPublished() && _forum_node_check_node_type($entity)) { $query = db_insert('forum_index')->fields(array('nid', 'title', 'tid', 'sticky', 'created', 'comment_count', 'last_comment_timestamp')); foreach ($entity->getTranslationLanguages() as $langcode => $language) { @@ -525,6 +525,7 @@ function forum_field_storage_pre_insert(EntityInterface $entity, &$skip_fields) function forum_field_storage_pre_update(EntityInterface $entity, &$skip_fields) { $first_call = &drupal_static(__FUNCTION__, array()); + $entity = $entity->getNGEntity(); if ($entity->entityType() == 'node' && _forum_node_check_node_type($entity)) { // If the node is published, update the forum index. @@ -1126,11 +1127,15 @@ function template_preprocess_forum_topic_list(&$variables) { } else { $variables['topics'][$id]->moved = FALSE; - $variables['topics'][$id]->title = l($topic->getTitle(), 'node/' . $topic->id()); + $variables['topics'][$id]->title_link = l($topic->getTitle(), 'node/' . $topic->id()); $variables['topics'][$id]->message = ''; } - $forum_submitted = array('#theme' => 'forum_submitted', '#topic' => $topic); - $variables['topics'][$id]->created = drupal_render($forum_submitted); + $forum_submitted = array('#theme' => 'forum_submitted', '#topic' => (object) array( + 'uid' => $topic->getAuthorId(), + 'name' => $topic->getAuthor()->getUsername(), + 'created' => $topic->getCreatedTime(), + )); + $variables['topics'][$id]->submitted = drupal_render($forum_submitted); $forum_submitted = array( '#theme' => 'forum_submitted', '#topic' => isset($topic->last_reply) ? $topic->last_reply : NULL, @@ -1140,7 +1145,7 @@ function template_preprocess_forum_topic_list(&$variables) { $variables['topics'][$id]->new_text = ''; $variables['topics'][$id]->new_url = ''; if ($topic->new_replies) { - $variables['topics'][$id]->new_text = format_plural($topic->new_replies, '1 new post<span class="visually-hidden"> in topic %title</span>', '@count new posts<span class="visually-hidden"> in topic %title</span>', array('%title' => $variables['topics'][$id]->title)); + $variables['topics'][$id]->new_text = format_plural($topic->new_replies, '1 new post<span class="visually-hidden"> in topic %title</span>', '@count new posts<span class="visually-hidden"> in topic %title</span>', array('%title' => $variables['topics'][$id]->label())); $variables['topics'][$id]->new_url = url('node/' . $topic->id(), array('query' => comment_new_page_count($topic->comment_count, $topic->new_replies, $topic), 'fragment' => 'new')); } diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php index c6f25332a9d3..b8e41edac714 100644 --- a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php +++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php @@ -529,7 +529,7 @@ function createForumTopic($forum, $container = FALSE) { // Retrieve node object, ensure that the topic was created and in the proper forum. $node = $this->drupalGetNodeByTitle($title); $this->assertTrue($node != NULL, format_string('Node @title was loaded', array('@title' => $title))); - $this->assertEqual($node->taxonomy_forums[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'], $tid, 'Saved forum topic was in the expected forum'); + $this->assertEqual($node->taxonomy_forums->target_id, $tid, 'Saved forum topic was in the expected forum'); // View forum topic. $this->drupalGet('node/' . $node->id()); diff --git a/core/modules/forum/templates/forum-topic-list.html.twig b/core/modules/forum/templates/forum-topic-list.html.twig index 85888bae163d..0e8cd1651e1f 100644 --- a/core/modules/forum/templates/forum-topic-list.html.twig +++ b/core/modules/forum/templates/forum-topic-list.html.twig @@ -13,7 +13,7 @@ * - icon: The icon to display. * - moved: A flag to indicate whether the topic has been moved to another * forum. - * - title: The title of the topic. Safe to output. + * - title_link: The title of the topic. Safe to output. * - message: If the topic has been moved, this contains an explanation and a * link. * - zebra: 'even' or 'odd', used for row class. @@ -21,7 +21,7 @@ * - new_replies: A flag to indicate whether there are unread comments. * - new_url: If there are unread replies, this is a link to them. * - new_text: Text containing the translated, properly pluralized count. - * - created: Text representing when the topic was posted. Safe to output. + * - submitted: Text representing when the topic was posted. Safe to output. * - last_reply: Text representing when the topic was last replied to. * - timestamp: The raw timestamp this topic was posted. * - topic_id: Numeric ID for the current forum topic. @@ -42,10 +42,10 @@ {{ topic.icon }} <div class="title"> <div> - {{ topic.title }} + {{ topic.title_link }} </div> <div> - {{ topic.created }} + {{ topic.submitted }} </div> </div> </td> diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php index e7f8d72544cf..b7d1b158e677 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php @@ -58,7 +58,7 @@ function _testImageFieldFormatters($scheme) { $node = node_load($nid, TRUE); // Test that the default formatter is being used. - $image_uri = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri(); + $image_uri = file_load($node->{$field_name}->target_id)->getFileUri(); $image = array( '#theme' => 'image', '#uri' => $image_uri, @@ -182,7 +182,7 @@ function testImageFieldSettings() { $node = node_load($nid, TRUE); $image_style = array( '#theme' => 'image_style', - '#uri' => file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri(), + '#uri' => file_load($node->{$field_name}->target_id)->getFileUri(), '#width' => 220, '#height' => 110, '#style_name' => 'medium', @@ -193,7 +193,7 @@ function testImageFieldSettings() { // Add alt/title fields to the image and verify that they are displayed. $image = array( '#theme' => 'image', - '#uri' => file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri(), + '#uri' => file_load($node->{$field_name}->target_id)->getFileUri(), '#alt' => $this->randomName(), '#title' => $this->randomName(), '#width' => 40, @@ -266,7 +266,7 @@ function testImageFieldDefaultImage() { $node = node_load($nid, TRUE); $image = array( '#theme' => 'image', - '#uri' => file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri(), + '#uri' => file_load($node->{$field_name}->target_id)->getFileUri(), '#width' => 40, '#height' => 20, ); diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php index 0452e995ceda..b0d33dff3caa 100644 --- a/core/modules/node/lib/Drupal/node/Entity/Node.php +++ b/core/modules/node/lib/Drupal/node/Entity/Node.php @@ -12,7 +12,6 @@ use Drupal\Core\Entity\Annotation\EntityType; use Drupal\Core\Annotation\Translation; use Drupal\node\NodeInterface; -use Drupal\node\NodeBCDecorator; /** * Defines the node entity class. @@ -104,7 +103,7 @@ public function preSaveRevision(EntityStorageControllerInterface $storage_contro // need to make sure $entity->log is reset whenever it is empty. // Therefore, this code allows us to avoid clobbering an existing log // entry with an empty one. - $record->log = $this->original->log; + $record->log = $this->original->log->value; } } @@ -116,21 +115,10 @@ public function postSave(EntityStorageControllerInterface $storage_controller, $ // default revision. There's no need to delete existing records if the node // is new. if ($this->isDefaultRevision()) { - \Drupal::entityManager()->getAccessController('node')->writeGrants($this->getBCEntity(), $update); + \Drupal::entityManager()->getAccessController('node')->writeGrants($this, $update); } } - /** - * {@inheritdoc} - */ - public function getBCEntity() { - if (!isset($this->bcEntity)) { - $this->getPropertyDefinitions(); - $this->bcEntity = new NodeBCDecorator($this, $this->fieldDefinitions); - } - return $this->bcEntity; - } - /** * {@inheritdoc} */ diff --git a/core/modules/node/lib/Drupal/node/NodeBCDecorator.php b/core/modules/node/lib/Drupal/node/NodeBCDecorator.php deleted file mode 100644 index b65bc4e15038..000000000000 --- a/core/modules/node/lib/Drupal/node/NodeBCDecorator.php +++ /dev/null @@ -1,148 +0,0 @@ -<?php - -/** - * @file - * Contains \Drupal\node\NodeBCDecorator. - */ - -namespace Drupal\node; - -use Drupal\Core\Entity\EntityBCDecorator; - -/** - * Defines the node specific entity BC decorator. - */ -class NodeBCDecorator extends EntityBCDecorator implements NodeInterface { - - /** - * {@inheritdoc} - */ - public function getType() { - return $this->decorated->getType(); - } - - /** - * {@inheritdoc} - */ - public function setTitle($title) { - return $this->decorated->setTitle($title); - } - /** - * {@inheritdoc} - */ - public function getTitle() { - return $this->decorated->getTitle(); - } - - /** - * {@inheritdoc} - */ - public function getCreatedTime() { - return $this->decorated->getCreatedTime(); - } - - /** - * {@inheritdoc} - */ - public function setCreatedTime($timestamp) { - return $this->decorated->setCreatedTime($timestamp); - } - - /** - * {@inheritdoc} - */ - public function getChangedTime() { - return $this->decorated->getChangedTime(); - } - - /** - * {@inheritdoc} - */ - public function isPromoted() { - return $this->decorated->isPromoted(); - } - - /** - * {@inheritdoc} - */ - public function setPromoted($promoted) { - $this->decorated->setPromoted($promoted); - } - - /** - * {@inheritdoc} - */ - public function isSticky() { - return $this->decorated->isSticky(); - } - - /** - * {@inheritdoc} - */ - public function setSticky($sticky) { - $this->decorated->setSticky($sticky); - } - /** - * {@inheritdoc} - */ - public function getAuthor() { - return $this->decorated->getAuthor(); - } - - /** - * {@inheritdoc} - */ - public function getAuthorId() { - return $this->decorated->getAuthorId(); - } - - /** - * {@inheritdoc} - */ - public function setAuthorId($uid) { - $this->decorated->setAuthorId($uid); - } - - /** - * {@inheritdoc} - */ - public function isPublished() { - return $this->decorated->isPublished(); - } - - /** - * {@inheritdoc} - */ - public function setPublished($published) { - $this->decorated->setPublished($published); - } - - /** - * {@inheritdoc} - */ - public function getRevisionCreationTime() { - return $this->decorated->getRevisionCreationTime(); - } - - /** - * {@inheritdoc} - */ - public function setRevisionCreationTime($timestamp) { - return $this->decorated->setRevisionCreationTime($timestamp); - } - - /** - * {@inheritdoc} - */ - public function getRevisionAuthor() { - return $this->decorated->getRevisionAuthor(); - } - - /** - * {@inheritdoc} - */ - public function setRevisionAuthorId($uid) { - return $this->decorated->setRevisionAuthorId($uid); - } - -} diff --git a/core/modules/node/lib/Drupal/node/NodeFormController.php b/core/modules/node/lib/Drupal/node/NodeFormController.php index 08f54d159568..0609e9c03749 100644 --- a/core/modules/node/lib/Drupal/node/NodeFormController.php +++ b/core/modules/node/lib/Drupal/node/NodeFormController.php @@ -9,13 +9,13 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Datetime\DrupalDateTime; -use Drupal\Core\Entity\EntityFormController; +use Drupal\Core\Entity\EntityFormControllerNG; use Drupal\Core\Language\Language; /** * Form controller for the node edit forms. */ -class NodeFormController extends EntityFormController { +class NodeFormController extends EntityFormControllerNG { /** * Default settings for this content/node type. @@ -42,7 +42,7 @@ protected function prepareEntity() { if ($node->isNew()) { foreach (array('status', 'promote', 'sticky') as $key) { // Multistep node forms might have filled in something already. - if (!isset($node->$key)) { + if ($node->$key->isEmpty()) { $node->$key = (int) in_array($key, $this->settings['options']); } } @@ -105,7 +105,7 @@ public function form(array $form, array &$form_state) { '#type' => 'textfield', '#title' => check_plain($node_type->title_label), '#required' => TRUE, - '#default_value' => $node->title, + '#default_value' => $node->title->value, '#maxlength' => 255, '#weight' => -5, ); @@ -155,7 +155,7 @@ public function form(array $form, array &$form_state) { '#type' => 'textarea', '#title' => t('Revision log message'), '#rows' => 4, - '#default_value' => !empty($node->log) ? $node->log : '', + '#default_value' => !empty($node->log->value) ? $node->log->value : '', '#description' => t('Briefly describe the changes you have made.'), '#states' => array( 'visible' => array( @@ -191,7 +191,7 @@ public function form(array $form, array &$form_state) { '#title' => t('Authored by'), '#maxlength' => 60, '#autocomplete_route_name' => 'user_autocomplete', - '#default_value' => !empty($node->name) ? $node->name : '', + '#default_value' => $node->getAuthorId()? $node->getAuthor()->getUsername() : '', '#weight' => -1, '#description' => t('Leave blank for %anonymous.', array('%anonymous' => $user_config->get('anonymous'))), ); @@ -332,11 +332,11 @@ public function validate(array $form, array &$form_state) { } // Validate the "authored by" field. - if (!empty($node->name) && !($account = user_load_by_name($node->name))) { + if (!empty($form_state['values']['name']) && !($account = user_load_by_name($form_state['values']['name']))) { // The use of empty() is mandatory in the context of usernames // as the empty string denotes the anonymous user. In case we // are dealing with an anonymous user we set the user ID to 0. - form_set_error('name', t('The username %name does not exist.', array('%name' => $node->name))); + form_set_error('name', t('The username %name does not exist.', array('%name' => $form_state['values']['name']))); } // Validate the "authored on" field. @@ -373,9 +373,13 @@ public function submit(array $form, array &$form_state) { // Save as a new revision if requested to do so. if (!empty($form_state['values']['revision'])) { $node->setNewRevision(); + // If a new revision is created, save the current user as revision author. + $node->setRevisionCreationTime(REQUEST_TIME); + global $user; + $node->setRevisionAuthorId($user->id()); } - node_submit($node); + $node->validated = TRUE; foreach (\Drupal::moduleHandler()->getImplementations('node_submit') as $module) { $function = $module . '_node_submit'; $function($node, $form, $form_state); @@ -429,6 +433,30 @@ public function unpublish(array $form, array &$form_state) { return $node; } + /** + * {@inheritdoc} + */ + public function buildEntity(array $form, array &$form_state) { + $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. + if (!empty($form_state['values']['name']) && $account = user_load_by_name($form_state['values']['name'])) { + $entity->setAuthorId($account->id()); + } + else { + $entity->setAuthorId(0); + } + + if (!empty($form_state['values']['date']) && $form_state['values']['date'] instanceOf DrupalDateTime) { + $entity->setCreatedTime($form_state['values']['date']->getTimestamp()); + } + else { + $entity->setCreatedTime(REQUEST_TIME); + } + return $entity; + } + + /** * Overrides Drupal\Core\Entity\EntityFormController::save(). */ diff --git a/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php b/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php index b274a1f798b8..094c2626738e 100644 --- a/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php +++ b/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php @@ -213,7 +213,7 @@ public function write(NodeInterface $node, array $grants, $realm = NULL, $delete $grant['nid'] = $node->id(); $grant['langcode'] = $grant_langcode; // The record with the original langcode is used as the fallback. - if ($grant['langcode'] == $node->langcode) { + if ($grant['langcode'] == $node->language()->id) { $grant['fallback'] = 1; } else { diff --git a/core/modules/node/lib/Drupal/node/NodeStorageController.php b/core/modules/node/lib/Drupal/node/NodeStorageController.php index 1a874fe56620..ee282d8b1563 100644 --- a/core/modules/node/lib/Drupal/node/NodeStorageController.php +++ b/core/modules/node/lib/Drupal/node/NodeStorageController.php @@ -26,22 +26,21 @@ public function create(array $values) { if (empty($values['created'])) { $values['created'] = REQUEST_TIME; } - return parent::create($values)->getBCEntity(); + return parent::create($values); } /** * Overrides Drupal\Core\Entity\DatabaseStorageControllerNG::attachLoad(). */ protected function attachLoad(&$queried_entities, $load_revision = FALSE) { - $nodes = $this->mapFromStorageRecords($queried_entities, $load_revision); + $queried_entities = $this->mapFromStorageRecords($queried_entities, $load_revision); // Create an array of nodes for each content type and pass this to the // object type specific callback. To preserve backward-compatibility we // pass on BC decorators to node-specific hooks, while we pass on the // regular entity objects else. $typed_nodes = array(); - foreach ($nodes as $id => $node) { - $queried_entities[$id] = $node->getBCEntity(); + foreach ($queried_entities as $id => $node) { $typed_nodes[$node->bundle()][$id] = $queried_entities[$id]; } @@ -71,31 +70,6 @@ protected function attachLoad(&$queried_entities, $load_revision = FALSE) { } } - /** - * Overrides Drupal\Core\Entity\DatabaseStorageController::invokeHook(). - */ - protected function invokeHook($hook, EntityInterface $node) { - $node = $node->getUntranslated()->getBCEntity(); - - // Inline parent::invokeHook() to pass on BC-entities to node-specific - // hooks. - - $function = 'field_attach_' . $hook; - // @todo: field_attach_delete_revision() is named the wrong way round, - // consider renaming it. - if ($function == 'field_attach_revision_delete') { - $function = 'field_attach_delete_revision'; - } - if (!empty($this->entityInfo['fieldable']) && function_exists($function)) { - $function($node); - } - - // Invoke the hook. - module_invoke_all($this->entityType . '_' . $hook, $node); - // Invoke the respective entity-level hook. - module_invoke_all('entity_' . $hook, $node, $this->entityType); - } - /** * {@inheritdoc} */ diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/row/Rss.php b/core/modules/node/lib/Drupal/node/Plugin/views/row/Rss.php index 124f0bb7337c..7d69106b11d6 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/views/row/Rss.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/row/Rss.php @@ -122,7 +122,7 @@ public function render($row) { ), array( 'key' => 'dc:creator', - 'value' => $node->name, + 'value' => $node->getAuthor()->getUsername(), ), array( 'key' => 'guid', diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php index 6df2698557e3..c66865e9de2c 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php @@ -82,7 +82,7 @@ function testMultilingualNodeForm() { $this->drupalPost('node/add/page', $edit, t('Save')); // Check that the node exists in the database. - $node = $this->drupalGetNodeByTitle($edit[$title_key])->getNGEntity(); + $node = $this->drupalGetNodeByTitle($edit[$title_key]); $this->assertTrue($node, 'Node found in database.'); $this->assertTrue($node->language()->id == $langcode && $node->body->value == $body_value, 'Field language correctly set.'); @@ -94,7 +94,7 @@ function testMultilingualNodeForm() { 'langcode' => $langcode, ); $this->drupalPost(NULL, $edit, t('Save')); - $node = $this->drupalGetNodeByTitle($edit[$title_key], TRUE)->getNGEntity(); + $node = $this->drupalGetNodeByTitle($edit[$title_key], TRUE); $this->assertTrue($node, 'Node found in database.'); $this->assertTrue($node->language()->id == $langcode && $node->body->value == $body_value, 'Field language correctly changed.'); @@ -136,7 +136,7 @@ function testMultilingualDisplaySettings() { ':id' => 'node-' . $node->id(), ':class' => 'content', )); - $this->assertEqual(current($body), $node->body['en'][0]['value'], 'Node body found.'); + $this->assertEqual(current($body), $node->body->value, 'Node body found.'); } } diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsAllTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsAllTestCase.php index d6ddc3b15072..c98515f94645 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsAllTestCase.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsAllTestCase.php @@ -59,7 +59,7 @@ function setUp() { // Create revision with a random title and body and update variables. $node->title = $this->randomName(); - $node->body[$node->language()->id][0] = array( + $node->body = array( 'value' => $this->randomName(32), 'format' => filter_default_format(), ); @@ -98,7 +98,7 @@ function testRevisions() { // Confirm the correct revision text appears on "view revisions" page. $this->drupalGet("node/" . $node->id() . "/revisions/" . $node->getRevisionId() . "/view"); - $this->assertText($node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'], 'Correct text displays for version.'); + $this->assertText($node->body->value, 'Correct text displays for version.'); // Confirm the correct log message appears on "revisions overview" page. $this->drupalGet("node/" . $node->id() . "/revisions"); @@ -119,7 +119,7 @@ function testRevisions() { )), 'Revision reverted.'); $reverted_node = node_load($node->id(), TRUE); - $this->assertTrue(($nodes[1]->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'] == $reverted_node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value']), 'Node reverted correctly.'); + $this->assertTrue(($nodes[1]->body->value == $reverted_node->body->value), 'Node reverted correctly.'); // Confirm that this is not the current version. $node = node_revision_load($node->getRevisionId()); diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php index 1580f8629ec8..7a58feda7b21 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeRevisionsTest.php @@ -59,7 +59,7 @@ function setUp() { // Create revision with a random title and body and update variables. $node->title = $this->randomName(); - $node->body[$node->language()->id][0] = array( + $node->body = array( 'value' => $this->randomName(32), 'format' => filter_default_format(), ); @@ -86,7 +86,7 @@ function testRevisions() { // Confirm the correct revision text appears on "view revisions" page. $this->drupalGet("node/" . $node->id() . "/revisions/" . $node->getRevisionId() . "/view"); - $this->assertText($node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'], 'Correct text displays for version.'); + $this->assertText($node->body->value, 'Correct text displays for version.'); // Confirm the correct log message appears on "revisions overview" page. $this->drupalGet("node/" . $node->id() . "/revisions"); @@ -103,7 +103,7 @@ function testRevisions() { array('@type' => 'Basic page', '%title' => $nodes[1]->label(), '%revision-date' => format_date($nodes[1]->getRevisionCreationTime()))), 'Revision reverted.'); $reverted_node = node_load($node->id(), TRUE); - $this->assertTrue(($nodes[1]->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'] == $reverted_node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value']), 'Node reverted correctly.'); + $this->assertTrue(($nodes[1]->body->value == $reverted_node->body->value), 'Node reverted correctly.'); // Confirm that this is not the default version. $node = node_revision_load($node->getRevisionId()); @@ -136,7 +136,7 @@ function testRevisions() { // This will create a new revision that is not "front facing". $new_node_revision = clone $node; $new_body = $this->randomName(); - $new_node_revision->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'] = $new_body; + $new_node_revision->body->value = $new_body; // Save this as a non-default revision. $new_node_revision->setNewRevision(); $new_node_revision->isDefaultRevision = FALSE; @@ -183,7 +183,7 @@ function testNodeRevisionWithoutLogMessage() { $this->drupalGet('node/' . $node->id()); $this->assertText($new_title, 'New node title appears on the page.'); $node_revision = node_load($node->id(), TRUE); - $this->assertEqual($node_revision->log, $log, 'After an existing node revision is re-saved without a log message, the original log message is preserved.'); + $this->assertEqual($node_revision->log->value, $log, 'After an existing node revision is re-saved without a log message, the original log message is preserved.'); // Create another node with an initial log message. $node = $this->drupalCreateNode(array('log' => $log)); @@ -201,6 +201,6 @@ function testNodeRevisionWithoutLogMessage() { $this->drupalGet('node/' . $node->id()); $this->assertText($new_title, 'New node title appears on the page.'); $node_revision = node_load($node->id(), TRUE); - $this->assertTrue(empty($node_revision->log), 'After a new node revision is saved with an empty log message, the log message for the node is empty.'); + $this->assertTrue(empty($node_revision->log->value), 'After a new node revision is saved with an empty log message, the log message for the node is empty.'); } } diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php index 64f109a605fc..a3f16f869999 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeSaveTest.php @@ -56,7 +56,7 @@ function testImport() { 'type' => 'article', 'nid' => $test_nid, ); - $node = node_submit(entity_create('node', $node)); + $node = entity_create('node', $node); $node->enforceIsNew(); // Verify that node_submit did not overwrite the user ID. diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php index 0713d751dbdf..1e55f29610fd 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php @@ -50,12 +50,12 @@ function testNodeTokenReplacement() { $tests = array(); $tests['[node:nid]'] = $node->id(); $tests['[node:vid]'] = $node->getRevisionId(); - $tests['[node:tnid]'] = $node->tnid; + $tests['[node:tnid]'] = $node->tnid->value; $tests['[node:type]'] = 'article'; $tests['[node:type-name]'] = 'Article'; $tests['[node:title]'] = check_plain($node->getTitle()); - $tests['[node:body]'] = text_sanitize($instance['settings']['text_processing'], $node->language()->id, $node->body[$node->language()->id][0], 'value'); - $tests['[node:summary]'] = text_sanitize($instance['settings']['text_processing'], $node->language()->id, $node->body[$node->language()->id][0], 'summary'); + $tests['[node:body]'] = text_sanitize($instance['settings']['text_processing'], $node->language()->id, $node->body[0]->getValue(), 'value'); + $tests['[node:summary]'] = text_sanitize($instance['settings']['text_processing'], $node->language()->id, $node->body[0]->getValue(), 'summary'); $tests['[node:langcode]'] = check_plain($node->language()->id); $tests['[node:url]'] = url('node/' . $node->id(), $url_options); $tests['[node:edit-url]'] = url('node/' . $node->id() . '/edit', $url_options); @@ -75,8 +75,9 @@ function testNodeTokenReplacement() { // Generate and test unsanitized tokens. $tests['[node:title]'] = $node->getTitle(); - $tests['[node:body]'] = $node->body[$node->language()->id][0]['value']; - $tests['[node:summary]'] = $node->body[$node->language()->id][0]['summary']; + $tests['[node:title]'] = $node->label(); + $tests['[node:body]'] = $node->body->value; + $tests['[node:summary]'] = $node->body->summary; $tests['[node:langcode]'] = $node->language()->id; $tests['[node:author:name]'] = user_format_name($account); @@ -96,7 +97,7 @@ function testNodeTokenReplacement() { // Generate and test sanitized token - use full body as expected value. $tests = array(); - $tests['[node:summary]'] = text_sanitize($instance['settings']['text_processing'], $node->language()->id, $node->body[$node->language()->id][0], 'value'); + $tests['[node:summary]'] = text_sanitize($instance['settings']['text_processing'], $node->language()->id, $node->body[0]->getValue(), 'value'); // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated for node without a summary.'); @@ -107,7 +108,7 @@ function testNodeTokenReplacement() { } // Generate and test unsanitized tokens. - $tests['[node:summary]'] = $node->body[$node->language()->id][0]['value']; + $tests['[node:summary]'] = $node->body->value; foreach ($tests as $input => $expected) { $output = $token_service->replace($input, array('node' => $node), array('language' => $language_interface, 'sanitize' => FALSE)); diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php index dac3575112e5..6861c52dcc60 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php @@ -69,7 +69,7 @@ protected function getNewEntityValues($langcode) { * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getFormSubmitAction(). */ protected function getFormSubmitAction(EntityInterface $entity) { - if ($entity->status) { + if ($entity->isPublished()) { return t('Save and unpublish'); } return t('Save and keep unpublished'); diff --git a/core/modules/node/lib/Drupal/node/Tests/Views/RowPluginTest.php b/core/modules/node/lib/Drupal/node/Tests/Views/RowPluginTest.php index f5c59aeee985..6d347f9c047f 100644 --- a/core/modules/node/lib/Drupal/node/Tests/Views/RowPluginTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/Views/RowPluginTest.php @@ -93,7 +93,7 @@ public function drupalCreateComment(array $settings = array()) { $node = node_load($settings['nid']); $settings += array( 'subject' => $this->randomName(), - 'node_type' => "comment_node_{$node->bundle()}", + 'node_type' => 'comment_node_' . $node->bundle(), 'comment_body' => $this->randomName(40), ); @@ -116,11 +116,8 @@ public function testRowPlugin() { $output = $view->preview(); $output = drupal_render($output); foreach ($this->nodes as $node) { - $body = $node->body; - $teaser = $body[Language::LANGCODE_NOT_SPECIFIED][0]['summary']; - $full = $body[Language::LANGCODE_NOT_SPECIFIED][0]['value']; - $this->assertFalse(strpos($output, $teaser) !== FALSE, 'Make sure the teaser appears in the output of the view.'); - $this->assertTrue(strpos($output, $full) !== FALSE, 'Make sure the full text appears in the output of the view.'); + $this->assertFalse(strpos($output, $node->body->summary) !== FALSE, 'Make sure the teaser appears in the output of the view.'); + $this->assertTrue(strpos($output, $node->body->value) !== FALSE, 'Make sure the full text appears in the output of the view.'); } // Test with teasers. @@ -128,11 +125,8 @@ public function testRowPlugin() { $output = $view->preview(); $output = drupal_render($output); foreach ($this->nodes as $node) { - $body = $node->body; - $teaser = $body[Language::LANGCODE_NOT_SPECIFIED][0]['summary']; - $full = $body[Language::LANGCODE_NOT_SPECIFIED][0]['value']; - $this->assertTrue(strpos($output, $teaser) !== FALSE, 'Make sure the teaser appears in the output of the view.'); - $this->assertFalse(strpos($output, $full) !== FALSE, 'Make sure the full text does not appears in the output of the view if teaser is set as viewmode.'); + $this->assertTrue(strpos($output, $node->body->summary) !== FALSE, 'Make sure the teaser appears in the output of the view.'); + $this->assertFalse(strpos($output, $node->body->value) !== FALSE, 'Make sure the full text does not appears in the output of the view if teaser is set as viewmode.'); } // Test with links disabled. diff --git a/core/modules/node/node.api.php b/core/modules/node/node.api.php index a6ec9ef4ae4c..4616ab46f44d 100644 --- a/core/modules/node/node.api.php +++ b/core/modules/node/node.api.php @@ -260,7 +260,7 @@ function hook_node_grants($account, $op) { function hook_node_access_records(\Drupal\node\NodeInterface $node) { // We only care about the node if it has been marked private. If not, it is // treated just like any other node and we completely ignore it. - if ($node->private) { + if ($node->private->value) { $grants = array(); // Only published Catalan translations of private nodes should be viewable // to all users. If we fail to check $node->isPublished(), all users would be able @@ -611,7 +611,7 @@ function hook_node_access(\Drupal\node\NodeInterface $node, $op, $account, $lang * @ingroup node_api_hooks */ function hook_node_prepare_form(\Drupal\node\NodeInterface $node, $form_display, $operation, array &$form_state) { - if (!isset($node->comment)) { + if (!isset($node->comment->value)) { $node->comment = variable_get('comment_' . $node->getType(), COMMENT_NODE_OPEN); } } diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 2353be3f3e69..44f60e7b9284 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -520,12 +520,7 @@ function node_type_update_nodes($old_id, $new_id) { * @see Drupal\Core\Entity\Query\EntityQueryInterface */ function node_load_multiple(array $nids = NULL, $reset = FALSE) { - $entities = entity_load_multiple('node', $nids, $reset); - // Return BC-entities. - foreach ($entities as $id => $entity) { - $entities[$id] = $entity->getBCEntity(); - } - return $entities; + return entity_load_multiple('node', $nids, $reset); } /** @@ -541,8 +536,7 @@ function node_load_multiple(array $nids = NULL, $reset = FALSE) { * A fully-populated node entity, or NULL if the node is not found. */ function node_load($nid = NULL, $reset = FALSE) { - $entity = entity_load('node', $nid, $reset); - return $entity ? $entity->getBCEntity() : NULL; + return entity_load('node', $nid, $reset); } /** @@ -558,41 +552,6 @@ function node_revision_load($vid = NULL) { return entity_revision_load('node', $vid); } -/** - * Prepares a node for saving by populating the author and creation date. - * - * @param \Drupal\Core\Entity\EntityInterface $node - * A node object. - * - * @return Drupal\node\Node - * An updated node object. - */ -function node_submit(EntityInterface $node) { - global $user; - - // 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. - if (isset($node->name)) { - if ($account = user_load_by_name($node->name)) { - $node->setAuthorId($account->id()); - } - else { - $node->setAuthorId(0); - } - } - - // If a new revision is created, save the current user as revision author. - if ($node->isNewRevision()) { - $node->setRevisionAuthorId($user->id()); - $node->setRevisionCreationTime(REQUEST_TIME); - } - - $node->setCreatedTime(!empty($node->date) && $node->date instanceOf DrupalDateTime ? $node->date->getTimestamp() : REQUEST_TIME); - $node->validated = TRUE; - - return $node; -} - /** * Deletes a node revision. * diff --git a/core/modules/node/node.pages.inc b/core/modules/node/node.pages.inc index 4cb383b34805..d80898e9ff4b 100644 --- a/core/modules/node/node.pages.inc +++ b/core/modules/node/node.pages.inc @@ -91,7 +91,7 @@ function node_add($node_type) { 'name' => $user->getUsername(), 'type' => $type, 'langcode' => $langcode ? $langcode : language_default()->id, - ))->getBCEntity(); + )); drupal_set_title(t('Create @name', array('@name' => $node_type->name)), PASS_THROUGH); return Drupal::entityManager()->getForm($node); } @@ -109,21 +109,6 @@ function node_add($node_type) { */ function node_preview(NodeInterface $node) { if (node_access('create', $node) || node_access('update', $node)) { - // Load the user's name when needed. - if (isset($node->name)) { - // The use of isset() is mandatory in the context of user IDs, because - // user ID 0 denotes the anonymous user. - if ($user = user_load_by_name($node->name)) { - $node->setAuthorId($user->id()); - } - else { - $node->setAuthorId(0); // anonymous user - } - } - elseif ($node->getAuthorId()) { - $user = $node->getAuthor(); - $node->name = $user->getUsername(); - } $node->changed = REQUEST_TIME; diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc index 3094ae6830e9..92404974eded 100644 --- a/core/modules/node/node.tokens.inc +++ b/core/modules/node/node.tokens.inc @@ -119,7 +119,7 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr break; case 'tnid': - $replacements[$original] = $node->tnid; + $replacements[$original] = $node->tnid->value; break; case 'type': diff --git a/core/modules/node/node.views.inc b/core/modules/node/node.views.inc index b2d00a670b3c..deacf4d98260 100644 --- a/core/modules/node/node.views.inc +++ b/core/modules/node/node.views.inc @@ -635,7 +635,7 @@ function node_row_node_view_preprocess_node(&$variables) { unset($variables['content']['links']); } - if (!empty($options['comments']) && user_access('access comments') && $node->comment) { + if (!empty($options['comments']) && user_access('access comments') && $node->comment->value) { $variables['content']['comments'] = comment_node_page_additions($node); } } diff --git a/core/modules/node/tests/modules/node_access_test/node_access_test.module b/core/modules/node/tests/modules/node_access_test/node_access_test.module index c200908b964d..abc18c6a635d 100644 --- a/core/modules/node/tests/modules/node_access_test/node_access_test.module +++ b/core/modules/node/tests/modules/node_access_test/node_access_test.module @@ -36,7 +36,7 @@ function node_access_test_node_grants($account, $op) { function node_access_test_node_access_records(NodeInterface $node) { $grants = array(); // For NodeAccessBaseTableTestCase, only set records for private nodes. - if (!Drupal::state()->get('node_access_test.private') || $node->private) { + if (!Drupal::state()->get('node_access_test.private') || $node->private->value) { $grants[] = array( 'realm' => 'node_access_test', 'gid' => 8888, @@ -77,6 +77,21 @@ function node_access_test_permission() { return array('node test view' => array('title' => 'View content')); } +/** + * Implements hook_entity_field_info(). + */ +function node_access_test_entity_field_info($entity_type) { + if ($entity_type === 'node') { + $info['definitions']['private'] = array( + 'type' => 'boolean_field', + 'label' => t('Private'), + 'computed' => TRUE, + 'list' => TRUE, + ); + return $info; + } +} + /** * Implements hook_form_BASE_FORM_ID_alter(). */ @@ -88,7 +103,7 @@ function node_access_test_form_node_form_alter(&$form, $form_state) { '#type' => 'checkbox', '#title' => t('Private'), '#description' => t('Check here if this content should be set private and only shown to privileged users.'), - '#default_value' => isset($node->private) ? $node->private : FALSE, + '#default_value' => $node->private->value, ); } } @@ -129,12 +144,10 @@ function node_access_test_node_update(EntityInterface $node) { * Helper for node insert/update. */ function _node_access_test_node_write(EntityInterface $node) { - if (isset($node->private)) { - db_merge('node_access_test') - ->key(array('nid' => $node->id())) - ->fields(array('private' => (int) $node->private)) - ->execute(); - } + db_merge('node_access_test') + ->key(array('nid' => $node->id())) + ->fields(array('private' => (int) $node->private->value)) + ->execute(); } /** diff --git a/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.module b/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.module index 1baa48e7548f..fb217f2997d0 100644 --- a/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.module +++ b/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.module @@ -29,10 +29,11 @@ function node_access_test_language_node_access_records(EntityInterface $node) { // Create grants for each translation of the node. foreach ($node->getTranslationLanguages() as $langcode => $language) { // If the translation is not marked as private, grant access. + $translation = $node->getTranslation($langcode); $grants[] = array( 'realm' => 'node_access_language_test', 'gid' => 7888, - 'grant_view' => empty($node->field_private[$langcode][0]['value']) ? 1 : 0, + 'grant_view' => empty($translation->field_private->value) ? 1 : 0, 'grant_update' => 0, 'grant_delete' => 0, 'priority' => 0, diff --git a/core/modules/node/tests/modules/node_test/node_test.module b/core/modules/node/tests/modules/node_test/node_test.module index 3da1eea03517..835f82cf97c4 100644 --- a/core/modules/node/tests/modules/node_test/node_test.module +++ b/core/modules/node/tests/modules/node_test/node_test.module @@ -139,7 +139,7 @@ function node_test_node_presave(EntityInterface $node) { // Determine changes. if (!empty($node->original) && $node->original->getTitle() == 'test_changes') { if ($node->original->getTitle() != $node->getTitle()) { - $node->title .= '_presave'; + $node->title->value .= '_presave'; } } } @@ -151,7 +151,7 @@ function node_test_node_update(EntityInterface $node) { // Determine changes on update. if (!empty($node->original) && $node->original->getTitle() == 'test_changes') { if ($node->original->getTitle() != $node->getTitle()) { - $node->title .= '_update'; + $node->title->value .= '_update'; } } } @@ -177,7 +177,7 @@ function node_test_entity_view_mode_alter(&$view_mode, Drupal\Core\Entity\Entity function node_test_node_insert(EntityInterface $node) { // Set the node title to the node ID and save. if ($node->getTitle() == 'new') { - $node->title = 'Node '. $node->id(); + $node->setTitle('Node '. $node->id()); $node->save(); } } diff --git a/core/modules/path/path.module b/core/modules/path/path.module index 9a52a9853129..38ebaa2cc6dd 100644 --- a/core/modules/path/path.module +++ b/core/modules/path/path.module @@ -6,8 +6,7 @@ */ use Drupal\Core\Language\Language; -use Drupal\node\NodeInterface; -use Drupal\taxonomy\Entity\Term; +use Drupal\Core\Entity\EntityInterface; /** * Implements hook_help(). @@ -180,51 +179,6 @@ function path_form_element_validate($element, &$form_state, $complete_form) { } } -/** - * Implements hook_node_insert(). - */ -function path_node_insert(NodeInterface $node) { - if (isset($node->path)) { - $alias = trim($node->path['alias']); - // Only save a non-empty alias. - if (!empty($alias)) { - // Ensure fields for programmatic executions. - $source = 'node/' . $node->id(); - $langcode = $node->language()->id; - Drupal::service('path.crud')->save($source, $alias, $langcode); - } - } -} - -/** - * Implements hook_node_update(). - */ -function path_node_update(NodeInterface $node) { - if (isset($node->path)) { - $path = $node->path; - $alias = trim($path['alias']); - // Delete old alias if user erased it. - if (!empty($path['pid']) && empty($path['alias'])) { - Drupal::service('path.crud')->delete(array('pid' => $path['pid'])); - } - // Only save a non-empty alias. - if (!empty($path['alias'])) { - // Ensure fields for programmatic executions. - $source = 'node/' . $node->id(); - $langcode = $node->language()->id; - Drupal::service('path.crud')->save($source, $alias, $langcode, $path['pid']); - } - } -} - -/** - * Implements hook_node_predelete(). - */ -function path_node_predelete(NodeInterface $node) { - // Delete all aliases associated with this node. - Drupal::service('path.crud')->delete(array('source' => 'node/' . $node->id())); -} - /** * Implements hook_form_FORM_ID_alter() for taxonomy_term_form(). */ @@ -265,7 +219,7 @@ function path_form_taxonomy_term_form_alter(&$form, $form_state) { * Implements hook_entity_field_info(). */ function path_entity_field_info($entity_type) { - if ($entity_type === 'taxonomy_term') { + if ($entity_type === 'taxonomy_term' || $entity_type === 'node') { $info['definitions']['path'] = array( 'type' => 'path_field', 'label' => t('The path alias'), @@ -277,48 +231,53 @@ function path_entity_field_info($entity_type) { } /** - * Implements hook_taxonomy_term_insert(). + * Implements hook_entity_insert(). + * + * @todo: Move this to methods on the FieldItem class. */ -function path_taxonomy_term_insert(Term $term) { - if (isset($term->path)) { - $term->path->alias = trim($term->path->alias); +function path_entity_insert(EntityInterface $entity) { + if ($entity->getPropertyDefinition('path')) { + $entity->path->alias = trim($entity->path->alias); // Only save a non-empty alias. - if (!empty($term->path->alias)) { + if (!empty($entity->path->alias)) { // Ensure fields for programmatic executions. - $source = 'taxonomy/term/' . $term->id(); - $langcode = Language::LANGCODE_NOT_SPECIFIED; - Drupal::service('path.crud')->save($source, $term->path->alias, $langcode); + $uri = $entity->uri(); + $langcode = $entity->language()->id; + Drupal::service('path.crud')->save($uri['path'], $entity->path->alias, $langcode); } } } /** - * Implements hook_taxonomy_term_update(). + * Implements hook_entity_update(). */ -function path_taxonomy_term_update(Term $term) { - if (isset($term->path)) { - $term->path->alias = trim($term->path->alias); +function path_entity_update(EntityInterface $entity) { + if ($entity->getPropertyDefinition('path')) { + $entity->path->alias = trim($entity->path->alias); // Delete old alias if user erased it. - if (!empty($term->path->pid) && empty($term->path->alias)) { - Drupal::service('path.crud')->delete(array('pid' => $term->path->pid)); + if ($entity->path->pid && !$entity->path->alias) { + Drupal::service('path.crud')->delete(array('pid' => $entity->path->pid)); } // Only save a non-empty alias. - if ($term->path->alias) { - $pid = (!empty($term->path->pid) ? $term->path->pid : NULL); + if ($entity->path->alias) { + $pid = $entity->path->pid; // Ensure fields for programmatic executions. - $source = 'taxonomy/term/' . $term->id(); - $langcode = Language::LANGCODE_NOT_SPECIFIED; - Drupal::service('path.crud')->save($source, $term->path->alias, $langcode, $pid); + $uri = $entity->uri(); + $langcode = $entity->language()->id; + Drupal::service('path.crud')->save($uri['path'], $entity->path->alias, $langcode, $pid); } } } /** - * Implements hook_taxonomy_term_delete(). + * Implements hook_entity_predelete(). */ -function path_taxonomy_term_delete(Term $term) { - // Delete all aliases associated with this term. - Drupal::service('path.crud')->delete(array('source' => 'taxonomy/term/' . $term->id())); +function path_entity_predelete(EntityInterface $entity) { + if ($entity->getPropertyDefinition('path')) { + // Delete all aliases associated with this term. + $uri = $entity->uri(); + Drupal::service('path.crud')->delete(array('source' => $uri['path'])); + } } /** diff --git a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php index 6b3c18f89d64..1e1598ac1202 100644 --- a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php +++ b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php @@ -123,7 +123,7 @@ public function _testPictureFieldFormatters($scheme) { $node = node_load($nid, TRUE); // Test that the default formatter is being used. - $image_uri = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri(); + $image_uri = file_load($node->{$field_name}->target_id)->getFileUri(); $image = array( '#theme' => 'image', '#uri' => $image_uri, diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/FileFieldAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/FileFieldAttributesTest.php index 11176dc54523..f1a69cce87d5 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/FileFieldAttributesTest.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/FileFieldAttributesTest.php @@ -73,7 +73,7 @@ public function setUp() { $nid = $this->uploadNodeFile($test_file, $this->fieldName, $type_name); $this->node = node_load($nid, TRUE); - $this->file = file_load($this->node->{$this->fieldName}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $this->file = file_load($this->node->{$this->fieldName}->target_id); } diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php index a622a8c2e870..14af8f672dec 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php @@ -73,7 +73,7 @@ public function setUp() { // Save a node with the image. $nid = $this->uploadNodeImage($image, $this->fieldName, 'article'); $this->node = node_load($nid); - $this->file = file_load($this->node->{$this->fieldName}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id']); + $this->file = file_load($this->node->{$this->fieldName}->target_id); } /** diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php index e1021b4abf41..95f51b80aaea 100644 --- a/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php +++ b/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php @@ -118,10 +118,8 @@ function testSearchingMultilingualFieldValues() { search_update_totals(); foreach ($this->searchable_nodes as $node) { // Each searchable node that we created contains values in the body field - // in one or more languages. Let's pick the last language variant from the - // body array and execute a search using that as a search keyword. - $body_language_variant = end($node->body); - $search_result = node_search_execute($body_language_variant[0]['value']); + // in one or more languages. + $search_result = node_search_execute($node->body->value); // See whether we get the same node as a result. $this->assertEqual($search_result[0]['node']->id(), $node->id(), 'The search has resulted the correct node.'); } diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/PluginTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/PluginTestBase.php index c58033893e24..c73fd671d660 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Plugin/PluginTestBase.php +++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/PluginTestBase.php @@ -89,7 +89,7 @@ public function setUp() { 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockComplexContextBlock', 'context' => array( 'user' => array('class' => 'Drupal\user\UserInterface'), - 'node' => array('class' => 'Drupal\Core\Entity\EntityBCDecorator'), + 'node' => array('class' => 'Drupal\node\NodeInterface'), ), ), ); diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php index 66a95c0ef429..0f660e36b484 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php @@ -6,7 +6,8 @@ */ namespace Drupal\system\Tests\Upgrade; -use Drupal\Core\Language\Language; + +use Drupal\field\Field; /** * Tests upgrade of system variables. @@ -209,16 +210,10 @@ function testFieldUpgradeToConfig() { // The deleted field uuid and deleted instance field_uuid must match. $this->assertEqual($deleted_field['uuid'], $deleted_instance['field_uuid']); - // Check that pre-existing deleted field values are read correctly. - $entity = _field_create_entity_from_ids((object) array( - 'entity_type' => 'node', - 'bundle' => 'article', - 'entity_id' => 2, - 'revision_id' => 2, - )); - field_attach_load('node', array(2 => $entity), FIELD_LOAD_CURRENT, array('instance' => entity_create('field_instance', $deleted_instance))); - $deleted_value = $entity->get('test_deleted_field'); - $this->assertEqual($deleted_value[Language::LANGCODE_NOT_SPECIFIED][0]['value'], 'Some deleted value'); + // Check that pre-existing deleted field table is renamed correctly. + $field_entity = new Field($deleted_field); + $table_name = _field_sql_storage_tablename($deleted_field); + $this->assertEqual("field_deleted_data_" . substr(hash('sha256', $deleted_field['uuid']), 0, 10), $table_name); // Check that creation of a new node works as expected. $value = $this->randomName(); diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/MockBlockManager.php b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/MockBlockManager.php index a89716089d64..386841bc9a15 100644 --- a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/MockBlockManager.php +++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/MockBlockManager.php @@ -91,7 +91,7 @@ public function __construct() { 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockComplexContextBlock', 'context' => array( 'user' => array('class' => 'Drupal\user\UserInterface'), - 'node' => array('class' => 'Drupal\Core\Entity\EntityBCDecorator'), + 'node' => array('class' => 'Drupal\node\NodeInterface'), ), )); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php index 991f274ef869..239e927d7467 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php @@ -170,7 +170,7 @@ function testTaxonomyIndex() { $this->assertEqual(1, $index_count, 'Term 2 is indexed once.'); // Update the article to change one term. - $node->{$this->field_name_1}[$langcode] = array(array('target_id' => $term_1->id())); + $node->{$this->field_name_1} = array(array('target_id' => $term_1->id())); $node->save(); // Check that both terms are indexed. @@ -186,7 +186,7 @@ function testTaxonomyIndex() { $this->assertEqual(1, $index_count, 'Term 2 is indexed.'); // Update the article to change another term. - $node->{$this->field_name_2}[$langcode] = array(array('target_id' => $term_1->id())); + $node->{$this->field_name_2} = array(array('target_id' => $term_1->id())); $node->save(); // Check that only one term is indexed. diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index f4258cd5b7aa..2d08f286dc6f 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -1133,21 +1133,10 @@ function taxonomy_build_node_index($node) { $field_name = $instance['field_name']; $field = field_info_field($field_name); if ($field['module'] == 'taxonomy' && $field['storage']['type'] == 'field_sql_storage') { - // If a field value is not set in the node object when $node->save() is - // called, the old value from $node->original is used. - if (isset($node->{$field_name})) { - $items = $node->{$field_name}; - } - elseif (isset($node->original->{$field_name})) { - $items = $node->original->{$field_name}; - } - else { - continue; - } - foreach (field_available_languages('node', $field) as $langcode) { - if (!empty($items[$langcode])) { - foreach ($items[$langcode] as $item) { - $tid_all[$item['target_id']] = $item['target_id']; + foreach ($node->getTranslationLanguages() as $language) { + foreach ($node->getTranslation($language->id)->$field_name as $item) { + if (!$item->isEmpty()) { + $tid_all[$item->target_id] = $item->target_id; } } } diff --git a/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php b/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php index 434464e98447..072b3df59aaa 100644 --- a/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php +++ b/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php @@ -112,11 +112,11 @@ function testContentTranslation() { $edit["body[$langcode][0][value]"] = $this->randomName(); $this->drupalPost('node/add/page', $edit, t('Save'), array('query' => array('translation' => $node->id(), 'language' => 'es'))); $duplicate = $this->drupalGetNodeByTitle($edit["title"]); - $this->assertEqual($duplicate->tnid, 0, 'The node does not have a tnid.'); + $this->assertEqual($duplicate->tnid->value, 0, 'The node does not have a tnid.'); // Update original and mark translation as outdated. $node_body = $this->randomName(); - $node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'] = $node_body; + $node->body->value = $node_body; $edit = array(); $edit["body[$langcode][0][value]"] = $node_body; $edit['translation[retranslate]'] = TRUE; @@ -139,7 +139,7 @@ function testContentTranslation() { $this->drupalGet('node/add/page'); $this->assertFieldByXPath('//select[@name="langcode"]//option', Language::LANGCODE_NOT_SPECIFIED, 'Language neutral is available in language selection with disabled languages.'); $node2 = $this->createPage($this->randomName(), $this->randomName(), Language::LANGCODE_NOT_SPECIFIED); - $this->assertRaw($node2->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'], 'Language neutral content created with disabled languages available.'); + $this->assertRaw($node2->body->value, 'Language neutral content created with disabled languages available.'); // Leave just one language installed and check that the translation overview // page is still accessible. @@ -171,7 +171,7 @@ function testLanguageSwitchLinks() { // Unpublish the Spanish translation to check that the related language // switch link is not shown. $this->drupalLogin($this->admin_user); - $this->drupalPost("node/$translation_es->nid/edit", array(), t('Save and unpublish')); + $this->drupalPost('node/' . $translation_es->id() . '/edit', array(), t('Save and unpublish')); $this->drupalLogin($this->translator); $this->assertLanguageSwitchLinks($node, $translation_es, FALSE); @@ -181,7 +181,7 @@ function testLanguageSwitchLinks() { $edit = array('language_interface[enabled][language-url]' => FALSE); $this->drupalPost('admin/config/regional/language/detection', $edit, t('Save settings')); $this->resetCaches(); - $this->drupalPost("node/$translation_es->nid/edit", array(), t('Save and publish')); + $this->drupalPost('node/' . $translation_es->id() . '/edit', array(), t('Save and publish')); $this->drupalLogin($this->translator); $this->assertLanguageSwitchLinks($node, $translation_es, TRUE, 'node'); } @@ -396,7 +396,7 @@ function createTranslation(EntityInterface $node, $title, $body, $langcode) { // Check to make sure that translation was successful. $translation = $this->drupalGetNodeByTitle($title); $this->assertTrue($translation, 'Node found in database.'); - $this->assertTrue($translation->tnid == $node->id(), 'Translation set id correctly stored.'); + $this->assertTrue($translation->tnid->value == $node->id(), 'Translation set id correctly stored.'); return $translation; } @@ -440,7 +440,7 @@ function assertContentByXPath($xpath, array $arguments = array(), $value = NULL, * @return * TRUE if the language switch links are found, FALSE if not. */ - function assertLanguageSwitchLinks(NodeInterface $node, $translation, $find = TRUE, $types = NULL) { + function assertLanguageSwitchLinks(NodeInterface $node, NodeInterface $translation, $find = TRUE, $types = NULL) { if (empty($types)) { $types = array('node', 'block-language'); } @@ -449,10 +449,9 @@ function assertLanguageSwitchLinks(NodeInterface $node, $translation, $find = TR } $result = TRUE; - $languages = language_list(); - $page_language = $languages[$node->language()->id]; - $translation_language = $languages[$translation->langcode]; - $url = url("node/$translation->nid", array('language' => $translation_language)); + $page_language = $node->language(); + $translation_language = $translation->language(); + $url = url('node/' . $translation->id(), array('language' => $translation_language)); $this->drupalGet('node/' . $node->id(), array('language' => $page_language)); @@ -468,7 +467,7 @@ function assertLanguageSwitchLinks(NodeInterface $node, $translation, $find = TR // node uses the article tag. $tag = $type == 'node' ? 'article' : 'div'; - if ($translation->nid) { + if ($translation->id()) { $xpath = '//' . $tag . '[contains(@class, :type)]//a[@href=:url]'; } else { diff --git a/core/modules/translation/translation.module b/core/modules/translation/translation.module index 398fd4f65e41..9843f069d0c0 100644 --- a/core/modules/translation/translation.module +++ b/core/modules/translation/translation.module @@ -201,31 +201,29 @@ function translation_form_node_form_alter(&$form, &$form_state) { $node = $form_state['controller']->getEntity(); if (translation_supported_type($node->getType())) { if (!empty($node->translation_source)) { - // We are creating a translation. Add values and lock language field. - $form['translation_source'] = array('#type' => 'value', '#value' => $node->translation_source); + // We are creating a translation. Lock language field. $form['langcode']['#disabled'] = TRUE; } - elseif (!$node->isNew() && !empty($node->tnid)) { + elseif (!$node->isNew() && $node->tnid->value) { // Disable languages for existing translations, so it is not possible // to switch this node to some language which is already in the // translation set. Also remove the language neutral option. unset($form['langcode']['#options'][Language::LANGCODE_NOT_SPECIFIED]); - foreach (translation_node_get_translations($node->tnid) as $langcode => $translation) { + foreach (translation_node_get_translations($node->tnid->value) as $langcode => $translation) { if ($translation->nid != $node->id()) { unset($form['langcode']['#options'][$langcode]); } } // Add translation values and workflow options. - $form['tnid'] = array('#type' => 'value', '#value' => $node->tnid); $form['translation'] = array( '#type' => 'details', '#title' => t('Translation settings'), '#access' => translation_user_can_translate_node($node), - '#collapsed' => !$node->translate, + '#collapsed' => !$node->translate->value, '#tree' => TRUE, '#weight' => 30, ); - if ($node->tnid == $node->id()) { + if ($node->tnid->value == $node->id()) { // This is the source node of the translation. $form['translation']['retranslate'] = array( '#type' => 'checkbox', @@ -239,14 +237,26 @@ function translation_form_node_form_alter(&$form, &$form_state) { $form['translation']['status'] = array( '#type' => 'checkbox', '#title' => t('This translation needs to be updated'), - '#default_value' => $node->translate, + '#default_value' => $node->translate->value, '#description' => t('When this option is checked, this translation needs to be updated because the source post has changed. Uncheck when the translation is up to date again.'), ); } + $form['#entity_builders'][] = 'translation_node_builder'; } } } +/** + * Entity form builder to add translation metadata to the node. + * + * @todo: Remove this in favor of an entity field. + */ +function translation_node_builder($entity_type, $entity, &$form, &$form_state) { + if (isset($form_state['values']['translation'])) { + $entity->translation = $form_state['values']['translation']; + } +} + /** * Implements hook_node_view(). * @@ -257,7 +267,7 @@ function translation_form_node_form_alter(&$form, &$form_state) { function translation_node_view(EntityInterface $node, EntityDisplay $display, $view_mode) { // If the site has no translations or is not multilingual we have no content // translation links to display. - if (isset($node->tnid) && language_multilingual() && $translations = translation_node_get_translations($node->tnid)) { + if ($node->tnid->value && language_multilingual() && $translations = translation_node_get_translations($node->tnid->value)) { $languages = language_list(Language::STATE_ALL); // There might be a language provider enabled defining custom language @@ -331,8 +341,8 @@ function translation_node_prepare_form(NodeInterface $node, $form_display, $oper } // Ensure we don't have an existing translation in this language. - if (!empty($source_node->tnid)) { - $translations = translation_node_get_translations($source_node->tnid); + if (!empty($source_node->tnid->value)) { + $translations = translation_node_get_translations($source_node->tnid->value); if (isset($translations[$langcode])) { drupal_set_message(t('A translation of %title in %language already exists, a new %type will be created instead of a translation.', array('%title' => $source_node->label(), '%language' => $language_list[$langcode]->name, '%type' => $node->getType())), 'error'); return; @@ -353,9 +363,9 @@ function translation_node_insert(EntityInterface $node) { // Only act if we are dealing with a content type supporting translations. if (translation_supported_type($node->getType())) { if (!empty($node->translation_source)) { - if ($node->translation_source->tnid) { + if ($node->translation_source->tnid->value) { // Add node to existing translation set. - $tnid = $node->translation_source->tnid; + $tnid = $node->translation_source->tnid->value; } else { // Create new translation set, using nid from the source node. @@ -387,11 +397,11 @@ function translation_node_insert(EntityInterface $node) { function translation_node_update(NodeInterface $node) { // Only act if we are dealing with a content type supporting translations. if (translation_supported_type($node->getType())) { - if (isset($node->translation) && $node->translation && $node->tnid) { + if (isset($node->translation) && $node->translation && $node->tnid->value) { // Update translation information. db_update('node') ->fields(array( - 'tnid' => $node->tnid, + 'tnid' => $node->tnid->value, 'translate' => $node->translation['status'], )) ->condition('nid', $node->id()) @@ -401,7 +411,7 @@ function translation_node_update(NodeInterface $node) { db_update('node') ->fields(array('translate' => 1)) ->condition('nid', $node->id(), '<>') - ->condition('tnid', $node->tnid) + ->condition('tnid', $node->tnid->value) ->execute(); } } @@ -413,11 +423,11 @@ function translation_node_update(NodeInterface $node) { * * Ensures that duplicate translations can't be created for the same source. */ -function translation_node_validate(EntityInterface $node, $form, &$form_state) { +function translation_node_validate(NodeInterface $node, $form, &$form_state) { // Only act on translatable nodes with a tnid or translation_source. $form_node = $form_state['controller']->getEntity(); - if (translation_supported_type($node->getType()) && (!empty($node->tnid) || ($form_node->translation_source && $form_node->translation_source->id()))) { - $tnid = !empty($node->tnid) ? $node->tnid : $form_node->translation_source->id(); + if (translation_supported_type($node->getType()) && ($node->tnid->value || ($form_node->translation_source && $form_node->translation_source->id()))) { + $tnid = $node->tnid->value ?: $form_node->translation_source->id(); $translations = translation_node_get_translations($tnid); if (isset($translations[$node->language()->id]) && $translations[$node->language()->id]->nid != $node->id()) { form_set_error('langcode', t('There is already a translation in this language.')); @@ -428,7 +438,7 @@ function translation_node_validate(EntityInterface $node, $form, &$form_state) { /** * Implements hook_node_predelete(). */ -function translation_node_predelete(EntityInterface $node) { +function translation_node_predelete(NodeInterface $node) { // Only act if we are dealing with a content type supporting translations. if (translation_supported_type($node->getType())) { translation_remove_from_set($node); @@ -441,17 +451,17 @@ function translation_node_predelete(EntityInterface $node) { * @param $node * A node entity. */ -function translation_remove_from_set($node) { - if (isset($node->tnid)) { +function translation_remove_from_set(NodeInterface $node) { + if ($node->tnid->value) { $query = db_update('node') ->fields(array( 'tnid' => 0, 'translate' => 0, )); - if (db_query('SELECT COUNT(*) FROM {node} WHERE tnid = :tnid', array(':tnid' => $node->tnid))->fetchField() == 1) { + if (db_query('SELECT COUNT(*) FROM {node} WHERE tnid = :tnid', array(':tnid' => $node->tnid->value))->fetchField() == 1) { // There is only one node left in the set: remove the set altogether. $query - ->condition('tnid', $node->tnid) + ->condition('tnid', $node->tnid->value) ->execute(); } else { @@ -461,11 +471,11 @@ function translation_remove_from_set($node) { // If the node being removed was the source of the translation set, // we pick a new source - preferably one that is up to date. - if ($node->tnid == $node->id()) { - $new_tnid = db_query('SELECT nid FROM {node} WHERE tnid = :tnid ORDER BY translate ASC, nid ASC', array(':tnid' => $node->tnid))->fetchField(); + if ($node->tnid->value == $node->id()) { + $new_tnid = db_query('SELECT nid FROM {node} WHERE tnid = :tnid ORDER BY translate ASC, nid ASC', array(':tnid' => $node->tnid->value))->fetchField(); db_update('node') ->fields(array('tnid' => $new_tnid)) - ->condition('tnid', $node->tnid) + ->condition('tnid', $node->tnid->value) ->execute(); } } @@ -531,8 +541,8 @@ function translation_supported_type($type) { function translation_path_get_translations($path) { $paths = array(); // Check for a node related path, and for its translations. - if ((preg_match("!^node/(\d+)(/.+|)$!", $path, $matches)) && ($node = node_load((int) $matches[1])) && !empty($node->tnid)) { - foreach (translation_node_get_translations($node->tnid) as $language => $translation_node) { + if ((preg_match("!^node/(\d+)(/.+|)$!", $path, $matches)) && ($node = node_load((int) $matches[1])) && $node->tnid->value) { + foreach (translation_node_get_translations($node->tnid->value) as $language => $translation_node) { $paths[$language] = 'node/' . $translation_node->id() . $matches[2]; } } @@ -549,7 +559,7 @@ function translation_language_switch_links_alter(array &$links, $type, $path) { if ($type == $language_type && preg_match("!^node/(\d+)(/.+|)!", $path, $matches)) { $node = node_load((int) $matches[1]); - if (empty($node->tnid)) { + if (empty($node->tnid->value)) { // If the node cannot be found nothing needs to be done. If it does not // have translations it might be a language neutral node, in which case we // must leave the language switch links unaltered. This is true also for @@ -560,13 +570,13 @@ function translation_language_switch_links_alter(array &$links, $type, $path) { $translations = array($node->language()->id => $node); } else { - $translations = translation_node_get_translations($node->tnid); + $translations = translation_node_get_translations($node->tnid->value); } foreach ($links as $langcode => $link) { if (isset($translations[$langcode]) && $translations[$langcode]->status) { // Translation in a different node. - $nid = $translations[$langcode]->nid; + $nid = $translations[$langcode] instanceof EntityInterface ? $translations[$langcode]->id() : $translations[$langcode]->nid; $links[$langcode]['href'] = 'node/' . $nid . $matches[2]; } else { diff --git a/core/modules/translation/translation.pages.inc b/core/modules/translation/translation.pages.inc index 2b787bf9b02d..b5ec442cb39b 100644 --- a/core/modules/translation/translation.pages.inc +++ b/core/modules/translation/translation.pages.inc @@ -22,14 +22,14 @@ function translation_node_overview(EntityInterface $node) { include_once DRUPAL_ROOT . '/core/includes/language.inc'; - if ($node->tnid) { + if ($node->tnid->value) { // Already part of a set, grab that set. - $tnid = $node->tnid; - $translations = translation_node_get_translations($node->tnid); + $tnid = $node->tnid->value; + $translations = translation_node_get_translations($node->tnid->value); } else { // We have no translation source nid, this could be a new set, emulate that. - $tnid = $node->nid; + $tnid = $node->id(); $translations = array($node->language()->id => $node); } @@ -42,7 +42,8 @@ function translation_node_overview(EntityInterface $node) { if (isset($translations[$langcode])) { // Existing translation in the translation set: display status. // We load the full node to check whether the user can edit it. - $translation_node = node_load($translations[$langcode]->nid); + $nid = $translations[$langcode] instanceof EntityInterface ? $translations[$langcode]->id() : $translations[$langcode]->nid; + $translation_node = node_load($nid); $path = 'node/' . $translation_node->id(); $links = language_negotiation_get_switch_links($type, $path); $title = empty($links->links[$langcode]['href']) ? l($translation_node->label(), $path) : l($translation_node->label(), $links->links[$langcode]['href'], $links->links[$langcode]); @@ -56,7 +57,7 @@ function translation_node_overview(EntityInterface $node) { } } $status = $translation_node->isPublished() ? t('Published') : t('Not published'); - $status .= $translation_node->translate ? ' - <span class="marker">' . t('outdated') . '</span>' : ''; + $status .= $translation_node->translate->value ? ' - <span class="marker">' . t('outdated') . '</span>' : ''; if ($translation_node->id() == $tnid) { $language_name = t('<strong>@language_name</strong> (source)', array('@language_name' => $language_name)); } diff --git a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php index 066f5187c377..3306755b410f 100644 --- a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php @@ -97,7 +97,7 @@ protected function setUp() { $node = $this->drupalCreateNode($values); - search_index($node->id(), 'node', $node->body[Language::LANGCODE_NOT_SPECIFIED][0]['value'], Language::LANGCODE_NOT_SPECIFIED); + search_index($node->id(), 'node', $node->body->value, Language::LANGCODE_NOT_SPECIFIED); $comment = array( 'uid' => $user->id(), -- GitLab