【问题标题】:Post-save callback?保存后回调?
【发布时间】:2011-03-15 07:00:40
【问题描述】:

如何在每次更新节点时执行函数?我尝试使用 hook_nodeapi,但看起来钩子已从 Drupal 7 中删除。

我想做的是,

  1. 向我的内容类型添加一个名为“主图像(布尔)”的新字段,让管理员设置主图像。
  2. 我将使用 Views 模块显示节点,但按“主图像”字段和添加日期排序节点。
  3. 因此第一个节点始终是主图像。

为此,我需要确保始终只有一个节点将“主图像”设置为 true。

【问题讨论】:

  • 您可以使用 drupal-7 标签,而不是在问题标题中添加 Drupal 7,这样可以节省一些空间。
  • @berdir // 我会这样做的。谢谢你的建议
  • 根据 Berdir 的建议编辑了帖子。顺便说一句,现在有一个专门用于 Drupal 的 Stack Exchange 站点:drupal.stackexchange.com
  • @marcvangend // 感谢您的编辑和 drupal 站点!

标签: drupal hook drupal-7


【解决方案1】:

目前 Drupal 核心不提供任何挂钩来在数据库中插入/更新/删除节点/实体后执行操作。例如,您不能在插入节点后发送提及该节点的电子邮件,因为 Drupal 使用 SQL 事务,并且在调用钩子节点 presave 时节点尚未完全写入数据库,因此如果出于任何原因回滚事务,用户会收到假邮件。

所以Hook Post Action module 引入了几个新的 Drupal 钩子来克服这个限制:

  • hook_entity_postsave
  • hook_entity_postinsert
  • hook_entity_postupdate
  • hook_entity_postdelete
  • hook_node_postsave
  • hook_node_postinsert
  • hook_node_postupdate
  • hook_node_postdelete

https://drupal.org/project/hook_post_action

【讨论】:

  • 谢谢 - 这看起来很有用。我想在添加、删除或更新节点后重建我的 sitemap.xml,因此这看起来非常适合我的需求。我已经安装了它,一切似乎也很完美:)
【解决方案2】:

钩子并没有被移除,而是为每个 $op 拆分成单独的钩子。

见:http://api.drupal.org/api/search/7/hook_node

对于后期保存,您需要 hook_node_insert()hook_node_update()

【讨论】:

  • 此时节点还没有完全保存,因为事务还没有提交。
  • 正如 Jorrit 所说,这是不正确的,因为交易仍在进行中。
  • 从执行代码的角度来看,节点是完全保存的,对DB的查询将按预期工作并找到节点数据,因为它们将在事务内部执行。这种“完全保存”的定义适合 OP 用例。
【解决方案3】:

我想hook_entity_presave 可能是你正在寻找的钩子,如果你想在你的节点更新之前采取行动:

在实体即将开始之前对其采取行动 被创建或更新。


或者,如果您更喜欢在更新后表演,请查看hook_entity_update

更新时对实体采取行动。

【讨论】:

    【解决方案4】:

    只是为了完成这一点,如果您需要在节点保存/更新后执行任何操作,您可以使用@sina-salek 推荐的模块,或者您可以使用此代码:

    // Same for hook_node_save!
    function my_module_node_update($node) {
      if ($node->type == 'content_type_name') {
        // Invoke your callback function AFTER the node is updated.
        drupal_register_shutdown_function('_my_module_the_function_to_call', $node);
      }
    }
    
    
    function _my_module_the_function_to_call($node) {
      // do stuff...
    }
    

    通过使用drupal_register_shutdown_function,您可以确保在钩子完成并且节点已保存在数据库上时调用您的自定义函数。

    【讨论】:

    • 这是最小最简单的解决方案。
    【解决方案5】:

    实现此目的的另一种方法是使用您的自定义类扩展 Node 实体并在 Node::postSave 方法中调用您的代码。当节点被保存或更新时,该方法将被调用。

    您通过实现名为 hook_entity_type_build 的钩子来指定您的自定义扩展类并提供您的新类,例如:$entity_types['node']->setClass(NodeExtended::class)

    在您的班级中,您可以覆盖 postSave 方法。我通常只是在这里调度我的自定义事件,以便其他模块可以订阅此节点发布保存事件,但这是另一个主题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-11
      • 1970-01-01
      • 2016-08-17
      • 2018-08-16
      • 1970-01-01
      • 1970-01-01
      • 2022-07-08
      • 1970-01-01
      相关资源
      最近更新 更多