diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php index 783404c..537c61f 100644 --- a/core/modules/node/lib/Drupal/node/Entity/Node.php +++ b/core/modules/node/lib/Drupal/node/Entity/Node.php @@ -24,7 +24,7 @@ * label = @Translation("Content"), * bundle_label = @Translation("Content type"), * controllers = { - * "storage" = "Drupal\node\NodeStorageController", + * "storage" = "Drupal\node\NodeStorage", * "view_builder" = "Drupal\node\NodeViewBuilder", * "access" = "Drupal\node\NodeAccessController", * "form" = { diff --git a/core/modules/node/lib/Drupal/node/NodeStorageController.php b/core/modules/node/lib/Drupal/node/NodeStorage.php similarity index 68% rename from core/modules/node/lib/Drupal/node/NodeStorageController.php rename to core/modules/node/lib/Drupal/node/NodeStorage.php index 55725a4..38cb869 100644 --- a/core/modules/node/lib/Drupal/node/NodeStorageController.php +++ b/core/modules/node/lib/Drupal/node/NodeStorage.php @@ -7,8 +7,9 @@ namespace Drupal\node; -use Drupal\Core\Entity\FieldableDatabaseStorageController; +use Drupal\Core\Entity\ContentEntityDatabaseStorage; use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Language\Language; /** * Defines the controller class for nodes. @@ -16,36 +17,7 @@ * This extends the Drupal\Core\Entity\DatabaseStorageController class, adding * required special handling for node entities. */ -class NodeStorageController extends FieldableDatabaseStorageController implements NodeStorageControllerInterface { - - /** - * {@inheritdoc} - */ - public function lastChanged($nid, $langcode) { - $result = $this->database->select('node_field_data', 'n') - ->fields('n', array('changed')) - ->condition('nid', $nid); - if (isset($langcode)) { - $result->condition('langcode', $langcode); - } - else { - $result->condition('default_langcode', 1); - } - - $result = $result->execute()->fetchField(); - return !empty($result) ? $result : FALSE; - } - - /** - * {@inheritdoc} - */ - public function userNodes(AccountInterface $account) { - return $this->database->select('node_field_data', 'n') - ->fields('n', array('nid')) - ->condition('uid', $account->id()) - ->execute() - ->fetchCol(); - } +class NodeStorage extends ContentEntityDatabaseStorage implements NodeStorageInterface { /** * {@inheritdoc} @@ -83,7 +55,7 @@ public function anonymizeUserRevisions(AccountInterface $account) { */ public function deleteRevisionsLanguage($language) { return $this->database->update('node_revision') - ->fields(array('langcode' => '')) + ->fields(array('langcode' => Language::LANGCODE_NOT_SPECIFIED)) ->condition('langcode', $language->id) ->execute(); } diff --git a/core/modules/node/lib/Drupal/node/NodeStorageControllerInterface.php b/core/modules/node/lib/Drupal/node/NodeStorageInterface.php similarity index 61% rename from core/modules/node/lib/Drupal/node/NodeStorageControllerInterface.php rename to core/modules/node/lib/Drupal/node/NodeStorageInterface.php index fbe993d..8dbdfb7 100644 --- a/core/modules/node/lib/Drupal/node/NodeStorageControllerInterface.php +++ b/core/modules/node/lib/Drupal/node/NodeStorageInterface.php @@ -2,29 +2,18 @@ /** * @file - * Contains \Drupal\node\nodeStorageControllerInterface. + * Contains \Drupal\node\NodeStorageControllerInterface. */ namespace Drupal\node; -use Drupal\Core\Entity\EntityStorageControllerInterface; +use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Session\AccountInterface; /** * Defines a common interface for node entity controller classes. */ -interface NodeStorageControllerInterface extends EntityStorageControllerInterface { - - /** - * Retrieve a list of nodes for a given user. - * - * @param \Drupal\Core\Session\AccountInterface $account - * The user entity. - * - * @return array - * Node ids. - */ - public function userNodes(AccountInterface $account); +interface NodeStorageInterface extends EntityStorageInterface { /** * Retrieve a list of revisions for a given user. @@ -38,19 +27,6 @@ public function userNodes(AccountInterface $account); public function userRevisions(AccountInterface $account); /** - * Retrieve the changed timestamp for a node. - * - * @param int $nid - * Node id. - * @param string $langcode - * Language code. - * - * @return int - * Last changed timestamp. - */ - public function lastChanged($nid, $langcode); - - /** * Updates all nodes of one type to be of another type. * * @param string $old_id @@ -80,12 +56,22 @@ public function anonymizeUserRevisions(AccountInterface $account); public function deleteRevisionsLanguage($language); /** - * Returns a list of all the existing revision numbers for the node passed in. + * Returns a list of data for all revisions of a specific node. * * @param \Drupal\node\NodeInterface * The node entity. + * * @return mixed - * An associative array keyed by node revision number. + * An associative array of objects containing specific properties (empty + * array if no result set), keyed by revision id. The keys of object + * properties are: + * - vid + * - current_vid (vid of the _current_ node, not this revision) + * - title + * - revision_timestamp + * - log + * - uid + * - name (user name linked to uid) */ public function revisionsList(NodeInterface $node); } diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc index a79328e..b0a806d 100644 --- a/core/modules/node/node.admin.inc +++ b/core/modules/node/node.admin.inc @@ -26,14 +26,17 @@ * @param bool $load * (optional) TRUE if $nodes contains an array of node IDs to be loaded, FALSE * if it contains fully loaded nodes. Defaults to FALSE. + * @param bool $revisions + * (optional) TRUE if $nodes contains an array of revision IDs instead of + * node IDs. Defaults to FALSE; will be ignored if $load is FALSE. */ -function node_mass_update(array $nodes, array $updates, $langcode = NULL, $load = FALSE) { +function node_mass_update(array $nodes, array $updates, $langcode = NULL, $load = FALSE, $revisions = FALSE) { // We use batch processing to prevent timeout when updating a large number // of nodes. if (count($nodes) > 10) { $batch = array( 'operations' => array( - array('_node_mass_update_batch_process', array($nodes, $updates, $langcode, $load)) + array('_node_mass_update_batch_process', array($nodes, $updates, $langcode, $load, $revisions)) ), 'finished' => '_node_mass_update_batch_finished', 'title' => t('Processing'), @@ -48,10 +51,13 @@ function node_mass_update(array $nodes, array $updates, $langcode = NULL, $load batch_set($batch); } else { - if ($load) { + if ($load && !$revisions) { $nodes = entity_load_multiple('node', $nodes); } foreach ($nodes as $node) { + if ($load && $revisions) { + $node = entity_revision_load('node', $node); + } _node_mass_update_helper($node, $updates, $langcode); } drupal_set_message(t('The update has been performed.')); @@ -97,10 +103,13 @@ function _node_mass_update_helper(NodeInterface $node, array $updates, $langcode * @param bool $load * TRUE if $nodes contains an array of node IDs to be loaded, FALSE if it * contains fully loaded nodes. + * @param bool $revisions + * (optional) TRUE if $nodes contains an array of revision IDs instead of + * node IDs. Defaults to FALSE; will be ignored if $load is FALSE. * @param array $context * An array of contextual key/values. */ -function _node_mass_update_batch_process(array $nodes, array $updates, $load, array &$context) { +function _node_mass_update_batch_process(array $nodes, array $updates, $load, $revisions, array &$context) { if (!isset($context['sandbox']['progress'])) { $context['sandbox']['progress'] = 0; $context['sandbox']['max'] = count($nodes); @@ -113,7 +122,8 @@ function _node_mass_update_batch_process(array $nodes, array $updates, $load, ar // For each nid, load the node, reset the values, and save it. $node = array_shift($context['sandbox']['nodes']); if ($load) { - $node = entity_load('node', $node); + $node = $revisions ? + entity_revision_load('node', $node) : entity_load('node', $node); } $node = _node_mass_update_helper($node, $updates); diff --git a/core/modules/node/node.module b/core/modules/node/node.module index d34a085..c75de6c 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -491,7 +491,7 @@ function node_entity_extra_field_info() { * The number of nodes whose node type field was modified. */ function node_type_update_nodes($old_id, $new_id) { - return \Drupal::entityManager()->getStorageController('node')->updateType($old_id, $new_id); + return \Drupal::entityManager()->getStorage('node')->updateType($old_id, $new_id); } /** @@ -810,19 +810,18 @@ function node_user_cancel($edit, $account, $method) { switch ($method) { case 'user_cancel_block_unpublish': // Unpublish nodes (current revisions). + $nids = \Drupal::entityQuery('node') + ->condition('uid', $account->id()) + ->execute(); module_load_include('inc', 'node', 'node.admin'); - $storage_controller = \Drupal::entityManager()->getStorageController('node'); - node_mass_update($storage_controller->userNodes($account), array('status' => 0), NULL, TRUE); + node_mass_update($nids, array('status' => 0), NULL, TRUE); break; case 'user_cancel_reassign': // Anonymize all of the nodes for this old account. module_load_include('inc', 'node', 'node.admin'); - $storage_controller = \Drupal::entityManager()->getStorageController('node'); - node_mass_update($storage_controller->userNodes($account), array('uid' => 0), NULL, TRUE); - // Note that if the number of nodes is large, they have not been updated - // yet at this point. - $storage_controller->anonymizeUserRevisions($account); + $vids = \Drupal::entityManager()->getStorage('node')->userRevisions($account); + node_mass_update($vids, array('uid' => 0), NULL, TRUE, TRUE); break; } } @@ -833,11 +832,12 @@ function node_user_cancel($edit, $account, $method) { function node_user_predelete($account) { // Delete nodes (current revisions). // @todo Introduce node_mass_delete() or make node_mass_update() more flexible. - $storage_controller = \Drupal::entityManager()->getStorageController('node'); - $nids = $storage_controller->userNodes($account); - $nodes = $storage_controller->loadMultiple($nids); - $storage_controller->delete($nodes); + $nids = \Drupal::entityQuery('node') + ->condition('uid', $account->id()) + ->execute(); + entity_delete_multiple('node', $nids); // Delete old revisions. + $storage_controller = \Drupal::entityManager()->getStorage('node'); $revisions = $storage_controller->userRevisions($account); foreach ($revisions as $revision) { node_revision_delete($revision); @@ -957,12 +957,26 @@ function node_page_title(NodeInterface $node) { * * @return string * A unix timestamp indicating the last time the node was changed. - * - * @deprecated as of Drupal 8.0. Use - * \Drupal\node\NodeStorageController->lastChanged(). */ function node_last_changed($nid, $langcode = NULL) { - return \Drupal::entityManager()->getStorageController('node')->lastChanged($nid, $langcode); + $query = \Drupal::entityQuery('node') + ->condition('nid', $nid); + if (isset($langcode)) { + $query->condition('langcode', $langcode); + } + else { + $query->condition('default_langcode', 1); + } + $nids = $query + ->addTag('node_access') + ->execute(); + + if ($nids) { + $nodes = node_load_multiple($nids); + return reset($nodes)->getChangedTime(); + } + + return FALSE; } /** @@ -975,7 +989,7 @@ function node_last_changed($nid, $langcode = NULL) { * An associative array keyed by node revision number. */ function node_revision_list(NodeInterface $node) { - return \Drupal::entityManager()->getStorageController('node')->revisionsList($node); + return \Drupal::entityManager()->getStorage('node')->revisionsList($node); } /** @@ -1790,7 +1804,7 @@ function node_file_download_access($field, EntityInterface $entity, File $file) */ function node_language_entity_delete(LanguageEntity $language) { // On nodes with this language, unset the language. - \Drupal::entityManager()->getStorageController('node')->deleteRevisionsLanguage($language); + \Drupal::entityManager()->getStorage('node')->deleteRevisionsLanguage($language); } /**