Tôi có hai mô-đun, module_alpha và module_beta.
Cả hai mô-đun cài đặt một bảng cơ sở dữ liệu với hook_schema()
mà họ sử dụng để theo dõi thông tin về các nút đã xuất bản. Dữ liệu được ghi vào bảng với các phương thức dịch vụ được thực thi từ hook_node_insert()
và hook_node_update()
móc câu. Tất cả điều này hoạt động.
Tuy nhiên, tôi cần xử lý tất cả các nút hiện có khi mô-đun được cài đặt để chèn lấp các bảng tùy chỉnh với thông tin về các nút đã xuất bản hiện có.Mỗi mô-đun thực hiện hook_install()
và sử dụng quy trình hàng loạt để xử lý tất cả các nút đã xuất bản hiện có. Tuy nhiên, tôi đang thấy sự mâu thuẫn kỳ lạ. Đôi khi quá trình hàng loạt thực thi, đôi khi không. Một kịch bản có thể phù hợp với mô-đun này nhưng không phù hợp với mô-đun kia. Tất cả điều này mặc dù mã gần như giống hệt nhau. Dưới đây là các tình huống tôi đã thử nghiệm:
Phương pháp cài đặt mô-đun |
Mô-đun Alpha |
Mô-đun Beta |
drush trong MYMODULE |
hàng loạt thực hiện |
Lô không thực hiện |
drush cim |
Lô không thực thi |
Lô không thực hiện |
Giao diện người dùng, kích hoạt mô-đun từ/admin/mô-đun |
hàng loạt thực hiện |
hàng loạt thực hiện |
Giao diện người dùng, cấu hình đồng bộ hóa từ/admin/config/Development/configuration |
hàng loạt thực hiện |
hàng loạt thực hiện |
Thực thi hàng loạt chỉ ra rằng lô thực thi hoàn toàn như mong đợi, với thông báo tiến trình và bảng của tôi chứa đầy dữ liệu. Lô không thực thi chỉ ra rằng lô hoàn toàn không được thực thi. Không có thông báo lỗi nào được hiển thị hoặc trong nhật ký. Phần kỳ lạ nhất về dữ liệu này là drush trong module_alpha
luôn thành công và drush trong module_beta
luôn luôn thất bại.
Điều gì có thể khiến quá trình xử lý hàng loạt hoạt động trong một số trường hợp nhưng không hoạt động trong những trường hợp khác? Làm cách nào tôi có thể thực hiện nhất quán quy trình hàng loạt này trên tất cả 4 phương pháp này, cho dù mô-đun được bật thông qua giao diện người dùng hay drush? Thành thật mà nói, phương pháp duy nhất tôi sẽ sử dụng là drush cim
Mã số:
Trong MYMODULE.install:
hàm MYMODULE_install() {
$batch = mới \Drupal\Core\Batch\BatchBuilder();
đợt hàng $
->setTitle(t('Xử lý hàng loạt các mục hiện có.'))
// Thao tác này tham chiếu đến một chức năng khác cho mỗi mô-đun.
// Trong cả hai trường hợp, hàm nằm trong MYMODULE.module và mã gần như giống hệt nhau.
->addOperation('_MYMODULE_initialize_items', []);
batch_set($batch->toArray());
}
Trong MYMODULE.module:
hàm _MYMODULE_initialize_items(&$context) {
$batch_size = 25;
$entity_type = 'nút';
// Tôi nhắm mục tiêu các gói khác nhau trong module_alpha và module_beta.
$bundle = 'MY_TARGET_BUNDLE';
if (!isset($context['sandbox']['processed'])) {
$context['sandbox']['đã xử lý'] = 0;
}
if (empty($context['sandbox']['entity_ids'])) {
$context['sandbox']['entity_ids'] = \Drupal::entityTypeManager()
->getStorage($entity_type)
->getQuery()
-> điều kiện ('loại', gói $)
->điều kiện('trạng thái', 1)
->thực thi();
if (is_array($context['sandbox']['entity_ids'])) {
$context['sandbox']['total'] = count($context['sandbox']['entity_ids']);
}
}
if (!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 as $entity) {
// Tôi sử dụng các dịch vụ và phương thức khác nhau trong module_alpha và module_beta.
\Drupal::service('MYMODULE.my_service')
-> processEntity($entity);
$context['sandbox']['đã xử lý']++;
}
}
if (!empty($context['sandbox']['total'])) {
$context['finished'] = $context['sandbox']['đã xử lý'] / $context['sandbox']['total'];
$context['message'] = t('Đã xử lý @đã xử lý của @tổng số mục.', [
'@đã xử lý' => $context['sandbox']['đã xử lý'],
'@total' => $context['sandbox']['total'],
]);
}
khác {
$context['finished'] = 1;
}
}
Phương thức dịch vụ ví dụ được gọi trong quy trình hàng loạt:
chức năng công khai processEntity(EntityInterface $entity) {
// $this->db được đưa vào dịch vụ `@database`, tức là \Drupal::service('database');
trả về $this->db
->chèn('MYMODULE_mytable')
-> trường([
'entity_type' => $entity->getEntityTypeId(),
'entity_bundle' => $entity->bundle(),
'entity_uuid' => $entity->uuid(),
// vân vân...
])
->thực thi();
}