Skip to content
Snippets Groups Projects

Make node and other operations more discoverable by moving them to traits

4 files
+ 259
232
Compare changes
  • Side-by-side
  • Inline
Files
4
+ 7
230
@@ -20,9 +20,6 @@ use Drupal\Core\Session\AccountSwitcherInterface;
@@ -20,9 +20,6 @@ use Drupal\Core\Session\AccountSwitcherInterface;
use Drupal\Core\State\State;
use Drupal\Core\State\State;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\Core\Url;
use Drupal\node\NodeInterface;
use Drupal\node\NodeStorageInterface;
use Drupal\taxonomy\Entity\Term;
use Drupal\user\UserStorageInterface;
use Drupal\user\UserStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -33,6 +30,8 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -33,6 +30,8 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
class BatchOperations implements ContainerInjectionInterface {
class BatchOperations implements ContainerInjectionInterface {
use BatchOperationsFilesTrait;
use BatchOperationsFilesTrait;
 
use BatchOperationsNodeTrait;
 
use BatchOperationsVocabularyTrait;
use DependencySerializationTrait;
use DependencySerializationTrait;
use StringTranslationTrait;
use StringTranslationTrait;
@@ -236,26 +235,6 @@ class BatchOperations implements ContainerInjectionInterface {
@@ -236,26 +235,6 @@ class BatchOperations implements ContainerInjectionInterface {
$this->batchOpLog->setOwnerId($user_id);
$this->batchOpLog->setOwnerId($user_id);
}
}
/**
* Get the node storage.
*
* @return \Drupal\node\NodeStorageInterface
* Node storage.
*/
public function getNodeStorage(): NodeStorageInterface {
return $this->entityTypeManager->getStorage('node');
}
/**
* Get the term storage.
*
* @return \Drupal\taxonomy\TermStorageInterface
* Term storage.
*/
public function getTermStorage(): NodeStorageInterface {
return $this->entityTypeManager->getStorage('taxonomy_term');
}
/**
/**
* Get the user storage.
* Get the user storage.
*/
*/
@@ -288,208 +267,6 @@ class BatchOperations implements ContainerInjectionInterface {
@@ -288,208 +267,6 @@ class BatchOperations implements ContainerInjectionInterface {
$this->batchOpLog->setOwnerId($uid);
$this->batchOpLog->setOwnerId($uid);
}
}
/**
* Load the latest revision of a node.
*
* @param int $nid
* The node ID.
*
* @return \Drupal\node\NodeInterface
* The latest revision of that node.
*/
public function getNodeLatestRevision(int $nid): NodeInterface {
$node_storage = $this->getNodeStorage();
// @todo Resolve deprecation.
return $node_storage->loadRevision($node_storage->getLatestRevisionId($nid));
}
/**
* Load the default revision of a node.
*
* If never published, the default revision is the most recent draft. When
* published, the gets the most recent published revision.
*
* @param int $nid
* The node ID.
*
* @return \Drupal\node\NodeInterface
* The latest revision of that node.
*/
public function getNodeDefaultRevision(int $nid): NodeInterface {
return $this->getNodeStorage()->load($nid);
}
/**
* Load all revisions of a node.
*
* @param int $nid
* The node ID.
*
* @return \Drupal\node\NodeInterface[]
* All revisions of that node.
*/
public function getNodeAllRevisions(int $nid): array {
$node_storage = $this->getNodeStorage();
$node = $node_storage->load($nid);
$vids = $node_storage->revisionIds($node);
return $node_storage->loadMultipleRevisions($vids);
}
/**
* Load all from the default and any forward revisions beyond that.
*
* @param int $nid
* The node ID.
*
* @return \Drupal\node\NodeInterface[]
* The default and all forward revisions of that node.
*/
public function getNodeDefaultAndForwardRevisions(int $nid): array {
$node_storage = $this->getNodeStorage();
$node = $node_storage->load($nid);
$rids = $node_storage->revisionIds($node);
$default_node = $this->getNodeDefaultRevision($nid);
$default_rid = $default_node->getRevisionId();
$default_and_forward_rids = [];
foreach ($rids as $rid) {
if ($rid >= $default_rid) {
// This must be either default or forward so add it to list.
$default_and_forward_rids[] = $rid;
}
}
return $node_storage->loadMultipleRevisions($default_and_forward_rids);
}
/**
* Get an array of node ids for batch processing.
*
* @param string $node_bundle
* The bundle name of the nodes to lookup.
* @param bool $published_only
* TRUE if you need only published nodes.
*
* @return array
* An array of nids for for the requested bundle, keyed by 'NID'.
*/
public function getNidsOfType($node_bundle, $published_only = FALSE): array {
$query = $this->entityTypeManager->getStorage('node')->getQuery()
->condition('type', $node_bundle)
->accessCheck(FALSE);
if ($published_only) {
$query->condition('status', 1);
}
$nids = $query->execute();
// Use the node ids as the keys, regardless of bundle type.
$node_ids = array_combine(array_values($nids), array_values($nids));
return $node_ids;
}
/**
* Saves a node revision with log messaging.
*
* @param \Drupal\node\NodeInterface $node
* The node to serialize.
* @param string $message
* The log message for the new revision.
* @param bool $new
* Whether the revision should be created or updated.
*
* @return int
* Either SAVED_NEW or SAVED_UPDATED, depending on the operation performed.
*/
public function saveNodeRevision(NodeInterface $node, $message = '', $new = TRUE): int {
$moderation_state = $node->get('moderation_state')->value;
$node->setNewRevision($new);
$node->setSyncing(TRUE);
$node->setValidationRequired(FALSE);
$node->enforceIsNew(FALSE);
// New revisions deserve special treatment.
if ($new) {
$node->setChangedTime(time());
$node->setRevisionCreationTime(time());
$uid = $this->getUser();
}
else {
$uid = $node->getRevisionUserId();
// Append new log message to previous log message.
$prefix = !empty($message) ? $node->getRevisionLogMessage() . ' - ' : '';
$message = $prefix . $message;
}
$node->setRevisionUserId($uid);
$revision_time = $node->getRevisionCreationTime();
// Incrementing by a nano second to bypass Drupal core logic
// that will update the "changed" value to request time if
// the value is not different from the original value.
$revision_time++;
$node->setRevisionCreationTime($revision_time);
$node->setRevisionLogMessage($message);
$node->set('moderation_state', $moderation_state);
return $node->save();
}
/**
* Saves a node revision with no new revision or log.
*
* @param \Drupal\node\NodeInterface $revision
* The node to serialize.
*
* @return int
* Either SAVED_NEW or SAVED_UPDATED, depending on the operation performed.
*/
public function saveNodeExistingRevisionWithoutLog(NodeInterface $revision): int {
$revision->setNewRevision(FALSE);
$revision->enforceIsNew(FALSE);
$revision->setSyncing(TRUE);
$revision->setValidationRequired(FALSE);
$revision_time = $revision->getRevisionCreationTime();
// Incrementing by a nano second to bypass Drupal core logic
// that will update the "changed" value to request time if
// the value is not different from the original value.
$revision_time++;
$revision->setRevisionCreationTime($revision_time);
$revision->setChangedTime($revision_time);
return $revision->save();
}
/**
* Create new terms for if they do not exist.
*
* @param string $vocabulary_id
* The machine name of the taxonomy vocabulary.
* @param array $terms
* An array of terms in the form of 'term name' => 'description'.
*
* @return int
* The number of terms created.
*/
public function saveNewTerms($vocabulary_id, array $terms): int {
$terms_created = 0;
foreach ($terms as $name => $description) {
// Make sure we are not creating duplicate terms.
$tid = $this->entityTypeManager->getStorage('taxonomy_term')->getQuery()
->condition('name', $name)
->condition('vid', $vocabulary_id)
->accessCheck(FALSE)
->execute();
if (empty($tid)) {
// Term does not exist, so create it.
$term = Term::create([
'name' => $name,
'vid' => $vocabulary_id,
]);
$term->setNewRevision(TRUE);
$term->setDescription($description);
$term->setRevisionUserId($this->getUser());
$term->setSyncing(TRUE);
$term->setValidationRequired(FALSE);
$term->save();
$terms_created++;
}
}
return $terms_created;
}
/**
/**
* Initializes the basic sandbox values.
* Initializes the basic sandbox values.
*
*
@@ -514,7 +291,7 @@ class BatchOperations implements ContainerInjectionInterface {
@@ -514,7 +291,7 @@ class BatchOperations implements ContainerInjectionInterface {
// There are no items to process, so bail out.
// There are no items to process, so bail out.
return;
return;
}
}
// @phpstan-ignore deprecated.method
// @phpstan-ignore-next-line (known deprecated.method)
$pre_msg = $this->preBatchMethod($sandbox);
$pre_msg = $this->preBatchMethod($sandbox);
$pre_msg .= $this->preRun($sandbox);
$pre_msg .= $this->preRun($sandbox);
$this->batchOpLog->appendLog("preRun: {$pre_msg}");
$this->batchOpLog->appendLog("preRun: {$pre_msg}");
@@ -584,7 +361,7 @@ class BatchOperations implements ContainerInjectionInterface {
@@ -584,7 +361,7 @@ class BatchOperations implements ContainerInjectionInterface {
if (!$allow_skip) {
if (!$allow_skip) {
// We are not allowed to skip, so log error and get out.
// We are not allowed to skip, so log error and get out.
$this->logger->error("Error encountered while processing @key. => <pre>{$item_text}</pre></br> Completed @completed of @total.</br> @error", $vars);
$this->logger->error("Error encountered while processing @key. => <pre>{$item_text}</pre></br> Completed @completed of @total.</br> @error", $vars);
// @phpstan-ignore deprecated.method
// @phpstan-ignore-next-line (known deprecated.method)
$post_msg = $this->postBatchMethod($sandbox);
$post_msg = $this->postBatchMethod($sandbox);
$post_msg .= $this->postRun($sandbox);
$post_msg .= $this->postRun($sandbox);
$this->batchOpLog->appendError("{$key} => {$item_text}")
$this->batchOpLog->appendError("{$key} => {$item_text}")
@@ -760,7 +537,7 @@ class BatchOperations implements ContainerInjectionInterface {
@@ -760,7 +537,7 @@ class BatchOperations implements ContainerInjectionInterface {
$summary = new FormattableMarkup('Completed: @completed/@total. Skipped: @skipped_count/@total.', $vars);
$summary = new FormattableMarkup('Completed: @completed/@total. Skipped: @skipped_count/@total.', $vars);
$message .= PHP_EOL;
$message .= PHP_EOL;
$message .= t('Process completed:') . " {$logged_message}" . PHP_EOL;
$message .= t('Process completed:') . " {$logged_message}" . PHP_EOL;
// @phpstan-ignore deprecated.method
// @phpstan-ignore-next-line (known deprecated.method)
$post_msg = $this->postBatchMethod($sandbox);
$post_msg = $this->postBatchMethod($sandbox);
$post_msg .= $this->postRun($sandbox);
$post_msg .= $this->postRun($sandbox);
$this->batchOpLog->setCompleted()
$this->batchOpLog->setCompleted()
@@ -1008,7 +785,7 @@ class BatchOperations implements ContainerInjectionInterface {
@@ -1008,7 +785,7 @@ class BatchOperations implements ContainerInjectionInterface {
/**
/**
* Deprecated backward compatible version of preRun().
* Deprecated backward compatible version of preRun().
*
*
* @deprecated in 1.0.1 and is removed from 2.0.
* @deprecated in codit_batch_operations:1.0.1 and is removed from codit_batch_operations:2.0.0 Use preRun() instead.
* @see https://www.drupal.org/project/codit_batch_operations/issues/3463174
* @see https://www.drupal.org/project/codit_batch_operations/issues/3463174
*/
*/
public function preBatchMethod(&$sandbox): string {
public function preBatchMethod(&$sandbox): string {
@@ -1028,7 +805,7 @@ class BatchOperations implements ContainerInjectionInterface {
@@ -1028,7 +805,7 @@ class BatchOperations implements ContainerInjectionInterface {
/**
/**
* Deprecated backward compatible version of postRun().
* Deprecated backward compatible version of postRun().
*
*
* @deprecated in 1.0.1 and is removed from 2.0.
* @deprecated in codit_batch_operations:1.0.1 and is removed from codit_batch_operations:2.0.0 Use postRun() instead.
* @see https://www.drupal.org/project/codit_batch_operations/issues/3463174
* @see https://www.drupal.org/project/codit_batch_operations/issues/3463174
*/
*/
public function postBatchMethod(&$sandbox): string {
public function postBatchMethod(&$sandbox): string {
Loading