从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).

 
 
 
 

相关问题

4  如何在单内容类型上具有多个现场集合实例?  ( How to have multiple instances of a field collection on single content type ) 
我有一个内容类型,我想使用字段集合来组分组某些字段(单选按钮和文本字段)。我只需要许多这些在内容类型上,只有标签不同。 我希望在一个内容类型上制作一个字段收集实体并在一个内容类型上有多个实例,但现场收集不支持此。 基本上,我需要一组内容类型的一组字段的许多实例。我怎样才能完成这个? ...

1  如何排序字段_info_instances按字段权重返回值?  ( How to sort field info instances return value by field weight ) 
我正在使用 field_info_instances 函数来在内容类型下检索所有字段信息。 (例如: field_info_instances('node','bundle_name') )。 但返回阵列字段未按预期排序。我需要按照内容类型(根据权重)提到的顺序获取字段。 对于EX,管理字段列表中提交的重量为8(来自...

1  通过索引访问多个值  ( Access multiple values by index in a view ) 
我有一个多价字段。当我在图中输出此字段时,我使用 Rewrite results 并引用此字段为 [field_product_image] 。这输出了字段的所有图像。 如何仅输出此阵列的某些元素,例如,第二个图像使用重写结果(这是必不可少的)? 这些作品都不是: [field_product_image:0] ...

1  选择节点标题以charachter开头  ( Select nodes title start with charachter ) 
我想用 EntityFieldQuery 用 A 998887661 或 B ,但是没有明显的方法在物业条件下, 我不想使用 db_select 或 db_query 。 在这个链接没有来 like 但它的工作,但如果我想要使用 REGEX 运算符它返回给我错误。 $query=new EntityFiel...

3  如何使用字段和垂直选项卡以编程方式创建内容类型  ( How to create content type programmatically with fields and vertical tabs ) 
我正在使用drupal7.26创建模块,并希望使用不同类型的字段(如无线电/复选框/ drupdown和texfields)创建内容类型。 我在这个线程并且工作很好,除了安装模块时未创建Fieldset,垂直选项卡组和垂直选项卡。 我所做的是: 我创建了一个自定义模块,通过以下遵循 sitepoint < / a...

0  Drupal内容身体中的用户参考  ( User reference in drupal content body ) 
我是drupal newbie,我试图开发一个功能,以在我的Drupal博客条目内容中引用用户。 请查看屏幕截图: http://prntscr.com/2p5dtv 浏览解决方案,我找到了这个模块,但我不确定如何用它来使用它实现我的目标。 任何帮助都非常有用。谢谢。 ...

0  drupal函数field_get_Items vs user_load  ( Drupal function field get items vs user load ) 
在drupal中,我想在登录管理员帐户时读取一组用户的自定义字段值。我只需要每个用户的1个字段值,相同的字段,我不需要这个信息缓存。 当我使用 user_load 时,它请求用户对象,因为我只需要一个字段,这是非常效率的。 所以我调查了 field_get_items ,但我看不到如何使用 user_load 。我...

0  使用hook_update_n()更新实体属性  ( Updating entity properties with hook update n ) 
我有一个定义自定义实体的自定义模块。现在我想向此实体添加一个新字段,而无需重新安装我的模块。我用 hook_update_N() 功能: /** * Description */ function MY_MODULE_update_7100() { $spec = array( 'type' =>...

7  如何为计算字段添加标记和前缀/后缀  ( How add markup and prefix suffix for computed field ) 
我想在内容类型中添加包装元素到CCK计算字段。 我可以计算字段的值,但是当我在显示代码中使用HTML标记时,结果不会正确呈现。 例如,我在显示代码中使用此代码。 $display_output = '<div class="row">' . $entity_field_item['value'] . ' <sp...

0  禁用用于输入的字段,而不删除它(不丢失旧数据)  ( Disable a field for input without deleting it to not lose old data ) 
我在我的客户个人资料中有一个字段(运输/结算,无关紧要)。 结账时,我不再需要这个字段,但我想保留旧订单的数据。 (这可以扩展到任何实体类型,它只是发生的商务客户档案是我的用例) 是否有可能以某种方式禁用输入的字段,但不是真正删除它? 理想情况下用UI解决方案。 我已经知道hook_form_alter()会做这个技...

0  如何更改一个地址字段,说明“数据库中存在此字段的数据。现场设置不再更改。“?  ( How to change an address field that says there is data for this field in the da ) 
如何更改"数据库中存在此字段的数据" 的地址字段。字段设置不再更改。"?? 我想添加一个"公司" 字段作为地址的一部分。我不想抛弃所有现有的地址数据。我不想创建一个单独的字段。 ...

1  如何使用相对或外部URL显示图像?  ( How do i show an image using a relative or external url ) 
似乎是一个简单的问题,但找不到一个简单的解决方案。 基本上我有馈电模块从具有相对图像的相对URL的另一数据库填充内容类型。 IE。 /images/image1.jpg 我在文本字段类型中存储此值。 有没有办法可以轻松地将此字段的输出转换为 .theme0 ? ...

0  将前缀和后缀添加到内容类型字段  ( Adding prefix and suffix to a content type field ) 
有没有办法以机械化方式将内容添加到内容类型的字段?例如,我有一个字段,有多少份食谱,但我不希望我的用户必须写"制作" 和"服务" 。一遍又一遍地又冒出了错误的风险。 有没有办法制作它,所以她所需要的只是一个数字字段,我可以自自动地使它说"制作" [编号]"服务。" 也许有一个可以使用的钩子或模块? ...

0  查看列表机名称  ( View in a list machine names ) 
我是drupal7的新手,并在与不同的用户的网站上工作。 和我可能在我目前遇到的是,只要有人创建内容,字段等。它会生成一个机器名称。 使用drupal,它自动基于节点的给定标题生成一个。 但如果机器名称已存在,则不会保存。 无论如何都知道存在什么机器名称?并分配了此机器名称? ...

0  如何拍摄选项卡的内容并在节点内插入它们  ( How to take contents of a tab and insert them inside a node ) 
我猜这是一个非常基本的笨蛋的东西,但我没有经历过编码。我正在使用请愿节点模块,它显示了一个申请表和在标签上的该申请的结果相同的页面。我在请愿书的第174行中找到了这个代码.Module: $items['node/%petition_menu/signatures'] = array( 'title' => 'S...

3  命名字段收集主题文件的内容?  ( What to name field collection theme file ) 
这里有几个文章,解决主题现场收集,但没有专门涵盖实际达到Drupal识别所需的命名约定。 字段 - 字段 - 字段集合-name.tpl.php不适用于我。也许是因为我是主题我的现场集合的编辑页面,但字段 - field-collection-name - edit.tpl.php也不适用。我尝试了每一个渗透和...

0  如何将自定义CSS样式添加到身体字段?  ( How do i add custom css styles to the body field ) 
我有一个内容类型"页面与字段" ,我通过在页面开头添加两个文本字段来制作"基本页面" ,现在如下所示: 页面标题 Field1标签:Field1 Text Field2标签:Field2 Text 这里是长文本的身体字段文本。 问题是身体文本和字段之间缺少空间1和2.现在我想向身体字段添加一些自定义CSS...

1  在提交结果之前在所有领域投票  ( Voting in all fields before submit results ) 
我有一个包含多个速率字段(性能,电池范围,价格, ...)类型FiveStars。默认情况下,该模块每当单击星际时会通过Ajax发送结果;在发送结果之前,我需要的是在所有字段中投票(使用按钮)。 可以这样做吗?怎么样? ...

1  数据属性添加到Content类型字段中的块  ( Data attribute added to block from content type field ) 
所以这是一个非常复杂的一系列问题。我是一个新的模块开发(和这个问题的PHP)。 我有一个名为"视差块" 的内容类型,具有4个字段:标题,图像,从下拉(方向)和身体的选择。 我的终极目标是在生成内容类型时,它在每次生成内容类型的情况下都有一个模块,它内部创建一个标题和身体字段的块,但是使用方向和图像值作为每个主的数据属...

0  如何更改此字段的视图排序?  ( How do i change the view sorting for this field ) 
我正在使用drupal 7,我有一个列表(文本)字段,显示这个格式的列表: 0|a 1|b 2|c 3|d 10|e 11|f 现在,当我创建视图并排序它升序时,列表按此顺序显示:A,B,E,F,C,D。我需要它显示为a,b,c,d,e,f。 我有很多数据。我不得不选择一个整数列表...




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


Licensed under cc by-sa 3.0 with attribution required.