我正在开发一个 Drupal 10 模块,该模块实现
hook_entity_insert
和 hook_entity_update
以在创建或更新节点时自动标记节点中的 event
类型段落。钩子触发逻辑检查段落,将标签与节点组进行比较,并添加任何缺失的标签。
当钩子被触发时,段落并没有得到更新。日志有时会显示如下消息:
…尽管数据明显存在。没有抛出任何错误——只是……什么也没发生。
hook_entity_insert
或 hook_entity_update
的怪癖可能导致此行为?任何建议或见解将不胜感激!下面是相关代码:
/**
* Implements hook_entity_insert().
*/
function my_module_entity_insert(EntityInterface $entity) {
if ($entity instanceof NodeInterface) {
my_module_handle_event_paragraph_tagging($entity);
}
}
/**
* Implements hook_entity_update().
*/
function my_module_entity_update(EntityInterface $entity) {
if ($entity instanceof NodeInterface) {
my_module_handle_event_paragraph_tagging($entity);
}
}
/**
* Handles tagging for paragraphs of type 'event' in a given node.
*
* @param \Drupal\node\NodeInterface $entity
* The node entity being saved. This node contains referenced paragraphs.
*/
function my_module_handle_event_paragraph_tagging(NodeInterface $entity) {
if (!$entity->hasField('field_content_function')) {
\Drupal::logger('my_module')->warning('Node @id does not have field_content_function.', ['@id' => $entity->id()]);
return;
}
$paragraphs = FieldHelper::getReferencedEntities($entity, 'field_content_function');
if (empty($paragraphs)) {
\Drupal::logger('my_module')->notice('No paragraphs found in field_content_function for node @id.', ['@id' => $entity->id()]);
return;
}
$group = EntityHelper::getGroup($entity);
if (!$group) {
\Drupal::logger('my_module')->warning('Node @id is not associated with a group.', ['@id' => $entity->id()]);
return;
}
$auto_main_tag_groups = FieldHelper::getReferencedEntities($group, 'field_auto_main_tagged_groups') ?? [];
$auto_main_tag_group_ids = array_map(fn($g) => $g->id(), $auto_main_tag_groups);
foreach ($paragraphs as $paragraph) {
if ($paragraph->bundle() !== 'event') {
continue;
}
$main_event_list_groups = FieldHelper::getReferencedEntities($paragraph, 'field_main_tagged_groups') ?? [];
$main_event_list_group_ids = array_map(fn($g) => $g->id(), $main_event_list_groups);
$groups_to_add = array_diff($auto_main_tag_group_ids, $main_event_list_group_ids);
foreach ($groups_to_add as $group_id) {
$paragraph->get('field_main_tagged_groups')->appendItem(['target_id' => $group_id]);
}
try {
$paragraph->save();
} catch (\Exception $e) {
\Drupal::logger('my_module')->error('Error saving paragraph @id: @message', [
'@id' => $paragraph->id(),
'@message' => $e->getMessage(),
]);
}
}
}
/**
* Retrieves the group associated with a node.
*
* @param \Drupal\node\NodeInterface $node
* The node entity.
*
* @return \Drupal\group\Entity\Group|null
* The associated group entity, or NULL if no group is found.
*/
function my_module_get_group(NodeInterface $node) {
$group = FieldHelper::getReferencedEntities($node, 'field_group');
if (!empty($group)) {
return reset($group);
}
if ($node->hasField('field_parent_node')) {
$parent = FieldHelper::getReferencedEntities($node, 'field_parent_node');
if (!empty($parent) && $parent[0] instanceof NodeInterface) {
return my_module_get_group($parent[0]);
}
}
\Drupal::logger('my_module')->warning('No group found for node @id.', ['@id' => $node->id()]);
return NULL;
}
如果您遇到类似的情况或对我可能缺少的内容有想法,请告诉我。提前致谢! 🙏
文档指出“一旦更新实体存储,此挂钩就会运行。请注意,挂钩实现可能不会更改存储的实体数据。 ...”。
此挂钩内的更改将不会被保存,因为在更新已保存到数据库后会触发该事件。
您需要查看
hook_entity_presave
,它在实体保存到数据库之前但在应用所有字段更新之后在实体创建和更新时触发。 https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_ENTITY_TYPE_presave/10
插入和更新钩子都可以用这个钩子替换:
/**
* Implements hook_entity_presave().
*/
function my_module_entity_presave(EntityInterface $entity): void {
if ($entity instanceof NodeInterface) {
my_module_handle_event_paragraph_tagging($entity);
}
}
如果您订阅的实体始终是一个节点,您可以在钩子中指定它,使代码更小且更具可读性。
/**
* Implements hook_entity_presave().
*/
function my_module_node_presave(NodeInterface $node): void {
my_module_handle_event_paragraph_tagging($node);
}