从hook_node_insert调用时,实体元数据包装器保存VS节点保存 -- entities 领域 和 nodes 领域 drupal 相关 的问题

Entity Metadata Wrapper Save VS Node Save when invoked from hook_node_insert


简体版||繁體版
5
vote

问题

中文

hook_node_insert() 被调用?该文档解释说

请注意,调用此挂钩时,更改尚未写入数据库,因为数据库事务仍在进行中。该事务未完成,直到保存操作完全完成,并且node_save()超出范围。

事实上,当我尝试做 node_save($node) 时,它会给我一个错误。 但是,如果我这样做,
  $nodeWrapper = entity_metadata_wrapper('node', node_load($node->nid)); $nodeWrapper->title->set(t("Saved by Entity Save")); $nodeWrapper->save();   

它很好。在 $nodeWrapper->save() 被执行后,新节点是否在数据库中执行?

英文原文

Can somebody shine a light into the difference of the two, in terms of their interaction with database when hook_node_insert() is invoked? The documentation explains that

Note that when this hook is invoked, the changes have not yet been written to the database, because a database transaction is still in progress. The transaction is not finalized until the save operation is entirely completed and node_save() goes out of scope.

In fact, when I tried doing node_save($node), it will give me an error.

However, if I was doing it this way,

$nodeWrapper = entity_metadata_wrapper('node', node_load($node->nid)); $nodeWrapper->title->set(t("Saved by Entity Save")); $nodeWrapper->save(); 

It works just fine. Has the new node being committed into the database after the $nodeWrapper->save() was executed?

     
         
         

回答列表

2
 
vote
vote
最佳答案
 

本质上, node_save() 99887662 方法之间的 99887662 方法之间的差异实际上并不大。然而,也不会用于将通过参数的节点保存为 hook_node_insert()

参数通过引用传递(由于它是一个对象,并且所有对象都在稍后的PHP版本中通过引用传递),并且当通过Drupal保存在完成后,您将包含对其的任何更改将包括在完成之后呼叫挂钩实现。

尝试再次手动保存相同的节点可以触发到您的 hook_node_insert() 实现中的无休止递归。

只需更改节点对象,如您所看到的拟合(在这种情况下设置标题,但这不是一个可翻译的字符串,所以用 check_plain() )替换 t() 没有。

如果您需要做更复杂的更改,实体元数据包装器可能会派上好此,但您必须记住必须保存的任何更改必须在作为引用 99887667 99887667 < /代码>。这意味着您首先在此首先引起代码> node_load($node->nid) ,因为它实际上只需创建一个已在数据库中的数据的新节点对象。如果您确实可以保存该节点副本而不结束递归循环,则意味着节点已在进行中保存 - 原因 hook_node_insert() 最初被称为 - 覆盖您所做的任何更改或失败,因为要保存的新节点已经存在。

而言,通过 node_save()0 参数直接发出 node_save()1 ,包装器将能够为您更改正确的节点对象,但请记住不要调用 node_save()2 在包装器上!

 

Essentially, there really isn't much difference between node_save() and the save() method of the entity metadata wrapper. Neither should however be used to save the node passed in as the argument to hook_node_insert().

The argument is passed by reference (since it's an object and all objects are passed by reference in later PHP versions), and any changes you make to it will be included when the node is saved by Drupal just after it's done calling the hook implementation.

Trying to manually save the same node again could trigger endless recursion into your hook_node_insert() implementation.

Just alter the node object as you see fit (setting the title in this case, though that is not a translatable string, so replace t() with check_plain()) and do nothing more.

If you need to do more complex alterations, the entity metadata wrapper could come in handy, but you must remember that any alterations you want to have saved must be performed on the node instance passed as a reference to hook_node_insert(). This means you can't node_load($node->nid) here first, since that would actually just create a new node object with data that's already in the database. If you do manage to save that node copy without ending up in a recursion loop, it would either mean that the node save already in progress - the reason hook_node_insert() was originally called - overwrites any changes you made, or fails because the new node to be saved already exists.

Instead, pass the $node argument to entity_metadata_wrapper() directly and the wrapper will be able to alter the correct node object for you, but remember to not call save() on the wrapper!

 
 
1
 
vote

调用 node_save()3 从内部a node_save()4 实现是容易出错的,只能用足够的条件检查来完成,因为不引人注目的函数嵌套。

当您调用 node_save()5 来自插入操作并保存 node_save()6 对象,它已经有 node_save()7 ,然后是<代码的调用> node_save()8 可能会创建更新操作,这可能会导致奇怪的错误。我没有完全遵循这里的信息流,但我猜这两个呼叫中的两个调用中的一个可以很容易地遇到一个问题。

在插入之前要更改节点属性(例如状态,促销,标题,...)的情况下的正确方法是使用 save()0 。如果要更新 998877621 中的字段值,则应通过调用 save()2

使用 save()3 save()4 并不完全感觉到。查看 EntityDrupalWrapper :: save ,我假设是负责的包装类,看起来 save()5 也将在最后调用。但我从来没有真正使用过实体包装,所以我这里有点短暂。

编辑:关于entity_metadata:_wrapper,再次查看 998876626 的代码,我意识到它不是 save()7 在最后调用,但这完全由实体模块处理。最后,如果我没有弄错: EntityApicontroller ::保存。我不确定,它如何解释评论中描述的行为。

 

Calling node_save() from inside a hook_node_insert() implementation is error prone and should only be done with sufficient condition checks as to not provoke function nesting.

When you call node_save() coming from an insert operation and saving the $node object that already has an nid, then this call of node_save probably creates an update operation, which might result in strange errors. I don't fully follow the information flow here, but I would guess that one of the two calls to node_save() can easily run into a problem.

The correct way in a scenario where you want to alter node properties (e.g. status, promote, title, ...) prior to inserting, is to use hook_node_presave(). If you want to update field values inside a hook_node_insert(), that should be done by calling field_attach_update('node', $node).

Using the save() method of entity_metadata_wrapper doesn't exactly feel good either. Looking at the code in EntityDrupalWrapper::save, which I suppose is the wrapper class that is responsible, it looks like node_save() is going to be called in the end too. But I have never really used Entity Wrapper, so I'm a bit short here.

Edit: Regarding entity_metadata:_wrapper, looking again at the code of entity_save() I realize that it's not node_save() that is called in the end, but that this is entirely handled by the Entity module. At the end it will end up here if I'm not mistaken: EntityAPIController::save. I'm not sure though how that explains the behavior described in the comment.

 
 
   
   
0
 
vote

为什么 node_save($node->nid) 为您提供错误是因为node_save占用要保存的节点对象,而不是节点ID。只需将其更改为 node_save($node) 并且它将正常工作。

在简单的术语中,节点保存只是一种特定的实体保存,只是通过做你要做的事情来使你的生活更轻松地(如在你的情况下,node_save是一行,保存实体是相同的但是,你必须不必要地处理元数据包装器)。

 

The reason why node_save($node->nid) gives you an error is because node_save takes node object to be saved, not a node id. Just change it to node_save($node) and it will work just fine.

In simple terms, node save is just a specific kind of entity save and just makes your life easier by doing things that you would have to do yourself (like in your case, node_save is one line, saving the entity does the same thing but you have to deal with metadata wrapper unnecessarily).

 
 
 
 

相关问题

0  如何执行函数的特定部分  ( How to execute a specific part of a function ) 
我在自定义模块中构建函数,我希望能够仅执行该函数的特定部分。 我从 hook_node_api 看看是否发生事件,如果发生该事件,则希望执行该自定义函数的特定部分。 function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { switch...

1  如何获得浏览量行的NID? [关闭]  ( How to get nid of views row ) 
关闭。这个问题需要详细信息或清晰度。它目前不接受答案。 想要改进这个问题?添加详细信息并阐明编辑此帖子的问题。 关闭去年。 ...

0  将内容类型添加到每个视图行的类  ( Adding content type to the class of each views row ) 
我有一个视图,有一个过滤器只能从2种内容类型中拉出结果。我希望每个视图条目都有一个显示节点内容类型的类。我该怎么做? ...

2  如何以编程方式修改以编程方式创建的内容类型?  ( How do you programmatically modify a programmatically created content type ) 
我正在创建一个有许多内容类型的Drupal 7站点,这些内容类型是以编程方式定义的。很可能在启动后,我需要略微修改一些内容类型。在开发过程中,每当我需要进行更改时,我只卸载模块,就会在代码中进行更改,然后重新安装它。在数据需要保持稳定的生产环境中,这显然是不可接受的。 如何以编程方式修改我的现有内容类型之一?此外,...

4  使用参数创建节点  ( Node creation with parameters ) 
我有一种表单,当提交和验证时,需要重定向到页面以创建节点(节点/添加/ factura-tmn),但我想向此页面发送参数。是否有可能? 我目前有以下代码: function add_invoice_file_form_submit($form, &$form_state) { $form_state['red...

0  在菜单项上显示类型的节点:Drupal 7  ( Display nodes of types on a menu item drupal 7 ) 
我已经创建了一些类型的书籍,现在我想在菜单项上显示其中一些。我怎样才能在没有使用视图的情况下做到这一点? mome |书籍|.阿里克里| 节点类型:(机器名称:书籍) 例如,上面是我的菜单结构。当用户点击书籍时,它将显示我创建的一些书籍。 ...

0  视图显示引用节点  ( Views show referencing nodes ) 
我有一个称为"问题" 的自定义内容类型,少数人,"a" ,"b" ,"c" 。 (实际上,命名是无关紧要的)。 以下内容类型"a" ,"b" ,"c" 中的每一个都具有一个字段,该字段是引用具有内容类型"问题" 的特定节点。 我想做的是在一个查看所有问题和旁边的每个问题旁边,引用节点的标题(带有链接到节点)。 应该采...

3  如何在分层上订购节点的分类术语?  ( How to order a nodes taxonomy terms hierarchically ) 
是默认顺序排序的节点的分类数组中的术语? 如果不是,那么最有效的方法是什么? ...

-1  Drupal 7在节点创建后自动创建和填充每个节点的字段引用  ( Drupal 7 automatically create and populate a field reference per node after node ) 
如何在创建节点(内容类型A)之后自动创建多个节点(内容类型B),然后与节点(内容B)的关系到节点(内容类型A) 谢谢 ...

3  如何仅列出视图中所有节点的最新版本?  ( How to list only the latest revision of all nodes in a view ) 
我目前有一个view,列出了所有节点,这是我们对内容仪表板的使用。它显示最近更新的节点,他们的工作流状态和其他一些细节。 我们似乎拥有的问题是,我们使用的修改,每次用户更新节点时,我们都会创建新的待处理版本。当用户更新节点时,工作流状态(自定义CCK字段)会自动切换到 repysid 。由于当前已发布的节点具有工作流...




© 2022 it.wenda123.org All Rights Reserved. 问答之家 版权所有