J'ai ajouté un champ de type champ calculé aux nœuds existants. Il est nécessaire de réenregistrer les nœuds pour définir/mettre à jour les valeurs de champ calculées. Comme je ne veux pas mettre à jour l'horodatage modifié, j'ai décidé de ne pas utiliser la mise à jour en bloc des vues pour réenregistrer le contenu. Le moyen le plus simple serait un script drush, de cette façon je peux réenregistrer le contenu chaque fois que cela est nécessaire.
Mon premier problème était que je ne pouvais pas laisser l'heure modifiée inchangée lors de la mise à jour ($ node-> save ()). Mais j'ai trouvé qu'il pouvait être réinitialisé sur une deuxième sauvegarde de nœud.
Mon problème est que sur chaque nœud, une nouvelle révision est créée. Le type de nœud est révisable et à côté de la modération du contenu du module principal est activé. J'apprécierais toute aide sur la façon d'empêcher la création de révisions.
Voici mon script de drush actuel dans custom_helper.drush.inc:
<?php
/**
* @file
* Provides drush command to update all articles.
*/
use Drupal\node\Entity\Node;
/**
* Implements hook_drush_command().
*/
function custom_helper_drush_command() {
$items = array();
$items['custom-resave-content'] = array(
'description' => dt('Resaves all article entities.'),
'options' => [
'types' => dt('Coma separated list of content type to be resaved.'),
'nids' => dt('Coma separated list if node ids.'),
'field' => dt('Machine name of computed field to be updated.')
],
'aliases' => array('custom-rc'),
);
return $items;
}
/**
* Moves paragraphs into one paragraph reference field.
*/
function drush_custom_helper_custom_resave_content() {
$nids = _convert_csv_to_array(drush_get_option('nids', []));
$types = _convert_csv_to_array(drush_get_option('types', []));
if (!$nids || $types) {
// Get an array of node IDs.
$query = \Drupal::entityQuery('node');
if ($types) {
$query->condition('type', $types, 'IN');
}
if ($nids) {
$query->condition('nid', $nids, 'IN');
}
$nids = $query->execute();
}
// Load all the nodes.
if ($nids) {
$field_name = drush_get_option('field', '');
$nodes = Node::loadMultiple($nids);
foreach ($nodes as $node) {
$entity_type = $node->getEntityType();
$original_changed = $node->getChangedTime();
if ($entity_type->isRevisionable()) {
$node->setNewRevision(FALSE);
}
// Force update of computed field.
if ($field_name) {
/** @var \Drupal\Core\Field\FieldItemListInterface $items */
$items = $node->get($field_name);
if (empty($items[0])) {
$items->appendItem();
}
$items->preSave();
}
// Save the updated computed field value.
$node->setChangedTime($original_changed);
if ($entity_type->isRevisionable()) {
$node->setNewRevision(FALSE);
}
$node->save();
// Reset changed time to original value.
$node->setChangedTime($original_changed);
if ($entity_type->isRevisionable()) {
$node->setNewRevision(FALSE);
}
$node->save();
$changed_after = $node->getChangedTime();
drush_print('node:' . $node->id() . ':' . $original_changed . ':' . $changed_after);
}
}
drush_log(dt('Resave finished.'), 'ok');
}
Pour le moment, cela n'est pas possible avec la modération de contenu installée sans effectuer de backflips tels que le remplacement du gestionnaire de modération pour le type d'entité de nœud.
Ceci est cependant en cours d'élaboration! Voici quelques problèmes liés au problème que vous rencontrez:
La proposition comporte essentiellement deux volets:
SynchronizableInterface::setSyncing()
quand il convient de marquer une entité comme "synchronisée".Je me cite du problème:
IMO, le statut de synchronisation actuel pour les entités de contenu se transforme en indicateur pour indiquer qu'une sauvegarde se produit dans des conditions qui sont en dehors d'une mise à jour de contenu typique initiée par l'utilisateur et que, autant que possible, les effets secondaires de cette sauvegarde doivent être limité. Des exemples pourraient être:
- Déployer un espace de travail.
- Mise à jour par lots des anciennes révisions.
- Exécution d'une mise à jour à partir d'une migration.
Après avoir défini certains de ces scénarios, il devient plus facile de rationaliser en éliminant certains des effets secondaires qui ont été discutés (gestion des révisions CM + horodatage modifié).
Dans votre cas, vous essayez de résoudre l'intégrité de votre modèle en mettant à jour en masse les entités/révisions existantes, cela ne fait pas partie d'un changement de contenu éditorial standard, donc à mon avis, il s'inscrit très clairement dans la sémantique proposée pour les entités de contenu et ce interface. Donc, avec quelques-uns de ces correctifs appliqués, votre exemple de code pourrait ressembler à:
$entity->setSyncing(TRUE);
$node->save();
Et puis l'horodatage modifié ne serait pas mis à jour et la modération du contenu ne forcerait pas la création d'une nouvelle révision.