Am două module, module_alpha și module_beta.
Ambele module instalează un tabel de bază de date cu hook_schema()
pe care le folosesc pentru a urmări informații despre nodurile publicate. Datele sunt înregistrate în tabel cu metodele de service executate din hook_node_insert()
și hook_node_update()
cârlige. Toate acestea funcționează.
Dar, trebuie să procesez toate nodurile existente atunci când modulul este instalat pentru a completa tabelele personalizate cu informații despre nodurile deja existente publicate.Fiecare modul implementează hook_install()
și utilizează un proces batch pentru a procesa toate nodurile publicate existente. Cu toate acestea, văd inconsecvențe ciudate. Uneori procesul batch se execută, alteori nu. Un scenariu poate funcționa pentru un modul, dar nu pentru celălalt. Toate acestea, chiar dacă codul este aproape identic. Iată scenariile pe care le-am testat:
Metoda de instalare a modulului |
Modulul Alpha |
Modul Beta |
drush ro MYMODULE |
Lotul se execută |
Lotul nu se execută |
drush cim |
Lotul nu se execută |
Lotul nu se execută |
UI, activați modulul din /admin/modules |
Lotul se execută |
Lotul se execută |
UI, sincronizați configurația din /admin/config/development/configuration |
Lotul se execută |
Lotul se execută |
Executarea lotului indică faptul că lotul se execută complet conform așteptărilor, cu mesaje de progres, iar tabelul meu este umplut cu date. Lotul nu se execută indică faptul că lotul nu este executat deloc. Nu sunt afișate mesaje de eroare sau în jurnale. Cea mai ciudată parte a acestor date este că drush en module_alpha
întotdeauna reușește și drush en module_beta
eșuează întotdeauna.
Ce ar putea cauza procesul batch să funcționeze în unele cazuri, dar nu în altele? Cum pot executa în mod consecvent acest proces lot în toate aceste 4 metode, indiferent dacă modulul este activat prin interfață de utilizare sau prin drush? Sincer să fiu, singura metodă pe care o voi folosi este drush cim
Cod:
În MYMODULE.install:
funcția MYMODULE_install() {
$lot = nou \Drupal\Core\Batch\BatchBuilder();
$lot
->setTitle(t('Procesarea în bloc a articolelor existente.'))
// Această operație face referire la o funcție diferită per modul.
// În ambele cazuri, funcția se află în MYMODULE.module și codul este aproape identic.
->addOperation('_MYMODULE_initialize_items', []);
batch_set($batch->toArray());
}
În MYMODULE.module:
funcția _MYMODULE_initialize_items(&$context) {
$batch_size = 25;
$entity_type = 'nod';
// Țintesc pachete diferite în module_alpha și module_beta.
$bundle = 'MY_TARGET_BUNDLE';
dacă (!isset($context['sandbox']['processed'])) {
$context['sandbox']['processed'] = 0;
}
dacă (gol ($context['sandbox']['entity_ids'])) {
$context['sandbox']['entity_ids'] = \Drupal::entityTypeManager()
->getStorage($entity_type)
->getQuery()
->condition('tip', $bundle)
->condition('status', 1)
->execute();
dacă (is_array($context['sandbox']['entity_ids'])) {
$context['sandbox']['total'] = count($context['sandbox']['entity_ids']);
}
}
dacă (!empty($context['sandbox']['entity_ids'])) {
$current_batch_ids = array_slice($context['sandbox']['entity_ids'], $context['sandbox']['processed'], $batch_size);
$current_batch_entities = \Drupal::entityTypeManager()
->getStorage($entity_type)
->loadMultiple($current_batch_ids);
foreach ($current_batch_entities ca $entity) {
// Folosesc servicii și metode diferite în module_alpha și module_beta.
\Drupal::service('MYMODULE.my_service')
->processEntity($entity);
$context['sandbox']['processed']++;
}
}
dacă (!empty($context['sandbox']['total'])) {
$context['finished'] = $context['sandbox']['processed'] / $context['sandbox']['total'];
$context['mesaj'] = t('Processate @processed of @total items.', [
'@processed' => $context['sandbox']['processed'],
'@total' => $context['sandbox']['total'],
]);
}
else {
$context['terminat'] = 1;
}
}
Exemplu de metodă de serviciu numită în procesul batch:
funcția publică processEntity(EntityInterface $entity) {
// $this->db este injectat serviciul `@database`, adică \Drupal::service('database');
returnează $this->db
->insert('MYMODULE_mytable')
->câmpuri([
'entity_type' => $entity->getEntityTypeId(),
'entity_bundle' => $entity->bundle(),
'entity_uuid' => $entity->uuid(),
// etc...
])
->execute();
}