Puncte:2

Nu se pot resalva nodurile cu entity->save(), fără o eroare specială

drapel cn

Încerc să scriu o comandă drush pentru a salva toate nodurile de pe site-ul meu.

Am căutat un modul și am găsit Salvați din nou toate nodurile modul, dar comanda sa drush nu este încă gata. Așa că am decis să încerc să scriu eu.

Cu toate acestea, nu pot face ca nodurile mele să fie salvate din nou $entity->salvare(), și nu înțeleg de ce.

<?php

spațiu de nume Drupal\resave_all_nodes\Commands;

utilizați Drupal\Core\Entity\EntityTypeManagerInterface;
utilizați Drupal\node\Entity\Node;
utilizați Drush\Commands\DrushCommands;

/**
 * O clasă de comandă Drush pentru conversiile modulului Resave All Nodes.
 */
clasa ResaveAllNodesCommands extinde DrushCommands
{

  /**
   * Managerul de tip de entitate.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  privat $entityTypeManager;


  /**
   * Construiește un obiect ResaveAllNodesCommands.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   * Managerul de tip de entitate.
   */
  funcția publică __construct(EntityTypeManagerInterface $entity_type_manager)
  {
    $this->entityTypeManager = $entity_type_manager;

    părinte::__construct();
  }

  /**
   * Resaveți toate nodurile.
   *
   * @command resave-all-nodes:resave
   *
   * @usage drush resave-all-nodes:resave
   * Resaveți toate nodurile de pe site.
   *
   * @aliases a alergat
   */
  funcția publică resaveAllNodes()
  {
    $my_node = Nod::load(1);
    $nodul_meu->salvare();
    \Drupal::logger('resave_all_nodes')->notice("nodul 1 salvat!");
  }
}

Când rulez comanda, jurnalele arată notificările loggerului:

  • Văd „nodul 1 salvat!” în bușteni
  • Am un alt mesaj de logare hook_entity_presave(), care apare și

Dar, când merg la /admin/conținut, „data actualizată” pentru nodul 1 nu s-a schimbat. De asemenea, conținutul nodului nu este ressalvat.

Dacă mă duc la nod/1/edit și re-salvați manual, nodul este re-salvat așa cum m-aș aștepta (data actualizată este actualizată, iar valorile câmpului sunt actualizate).

Deci, de ce nod->salvare() eșuează în tăcere (data actualizării și valorile câmpului rămân aceleași), atunci când salvarea manuală funcționează?

Am câteva module personalizate și le-am dezactivat și am reconstruit memoria cache, dar problema rămâne.

drapel br
Aveți vreo logică care ignoră PHP_SAPI sau un modul care ignoră logica cu PHP_SAPI?
drapel cn
@Jonh, nu cred. Tocmai mi-am greșit baza de cod pentru `PHP_SAPI` și singurele referințe non-core non-Symfony sunt la modulul webform. Rularea site-ului meu local în lando a fost trasă din platform.sh.
4uk4 avatar
drapel cn
*Dar, când merg la /admin/content, „data actualizată” pentru nodul 1 nu s-a schimbat.* Trebuie să setați ora modificată: `$my_node->setChangedTime(\Drupal::time()->getRequestTime ());` Dacă tot nu îl vedeți, încercați să ștergeți memoria cache.
drapel cn
@4k4 Ok, a funcționat. Deci, resalvarea unui nod în UI este de fapt diferită de a face node->save(), în acel nod->save() nu face nicio modificare decât dacă le specificați în mod explicit?
drapel cn
Entitățile nu persistă datele dacă nimic nu s-a schimbat (din motive evidente de performanță). Trimiterea unui formular de entitate actualizează marcajul de timp modificat înainte ca salvarea să fie apelată, astfel încât persistența este declanșată. Trebuie doar să faci același lucru
Puncte:2
drapel cn

Datorită lui @4k4 și @Clive, am reușit să lucrez. Această comandă drush salvează toate nodurile. Urmează codul, dar mai întâi câteva note:

  • După ce a sunat batch_set(), pentru comenzi drush, trebuie să suni drush_backend_batch_process() sau lotul nu va fi niciodată rulat.
  • The Modulul Drush 9 Exemplu de procesare în lot este un exemplu foarte util.
  • În dumneavoastră batchOperation() comanda, dacă tastați indiciu $context, trebuie să folosești \DrushBatchContext|matrice $context nu doar matrice pentru că drush se va prăbuși puternic. Există zeci de probleme pe drupal.org despre asta.

Ok, iată codul meu:

<?php

spațiu de nume Drupal\resave_all_nodes\Commands;

utilizați Drupal\Core\Batch\BatchBuilder;
utilizați Drupal\Core\Entity\EntityTypeManagerInterface;
utilizați Drupal\Core\StringTranslation\StringTranslationTrait;
utilizați Drush\Commands\DrushCommands;

/**
 * O clasă de comandă Drush pentru conversiile modulului Resave All Nodes.
 */
clasa ResaveAllNodesCommands extinde DrushCommands
{
  utilizați StringTranslationTrait;

  /**
   * Managerul de tip de entitate.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  privat $entityTypeManager;


  /**
   * Construiește un obiect ResaveAllNodesCommands.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   * Managerul de tip de entitate.
   */
  funcția publică __construct(EntityTypeManagerInterface $entity_type_manager)
  {
    $this->entityTypeManager = $entity_type_manager;

    părinte::__construct();
  }

  /**
   * Resaveți toate nodurile.
   *
   * @comandă resave:noduri
   *
   * @usage drush resave:noduri
   * Resaveți toate nodurile de pe site.
   *
   * @aliases a alergat
   */
  funcția publică resaveAllNodes()
  {
    // O matrice cu multe ID-uri de noduri.
    $nids = $this->getNodeIds();
    // Tăiați matricea în sub-matrice (bucăți) de dimensiunea specificată.
    $bucăți = array_chunk($nids, 250);
    $num_bucăți = count($bucăți);

    // Acum resaveți toate nodurile bucată cu bucată.
    $batchBuilder = nou BatchBuilder();
    pentru ($i = 0; $i < $num_bucăți; $i++) {
      $batchBuilder->addOperation('\Drupal\resave_all_nodes\Batch\ResaveAllNodesBatch::batchOperation',
        [$bucăți[$i]]
      );
    }

    $batchBuilder->setTitle(t('Resalvarea nodurilor'))
      ->setFinishCallBack('\Drupal\resave_all_nodes\Batch\ResaveAllNodesBatch::batchFinished');

    batch_set($batchBuilder->toArray());
    drush_backend_batch_process();
  }

  /**
   * Obțineți ID-uri de nod de matrice.
   *
   * @return array|int
   * O serie de ID-uri de noduri în cel mai bun caz.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  funcția publică getNodeIds() {
    $interogare = $this->entityTypeManager->getStorage('nod')->getQuery();
    $nids = $query->execute();
    # Pentru a obține tipuri de noduri.
    # $nids = $query->condition('tip', $node_types, 'IN')->execute();

    returnează $nids;
  }
}

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.