如何使用默认语言删除节点时删除所有翻译? -- nodes 领域 和 hooks 领域 drupal 相关 的问题

How to delete all translations when deleting a node using default language?


2
vote

问题

中文

我正在尝试使用默认语言删除节点时删除所有翻译?

对于此目的,我使用了 hook_node_delete ,但我无法调用 node_delete()来自它。它导致致命错误,过程无法终止。即使是我删除的第一个节点也不会删除术前。

   function hook_node_delete($node){         $translation_list = translation_node_get_translations($node->tnid);         $default_language = language_default()->language;          if($translation_list!=""){            foreach($translation_list as $translation_list_item){                   if ($translation_list_item->language!=$default_language){                   node_delete($translation_list_item->nid);               }            };         };     }   

所以我被迫通过这样做的东西来解开翻译:

   function hook_node_delete($node){                 $translation_list = translation_node_get_translations($node->tnid);                 $default_language = language_default()->language;                  if($translation_list!=""){                    foreach($translation_list as $translation_list_item){                           if ($translation_list_item->language!=$default_language){                           $node_translated = node_load($translation_list_item->nid);                           $node_translated->status = 0;                           node_save($node_translated);                       }                    };                 };             }   

为什么我不能调用 node_delete() 从 hook_node_delete()< / a> ??

英文原文

I'm trying to delete all translations when deleting a node using default language?

For that purpose, I am using the hook_node_delete, but I am not able to invoke node_delete() from it. It cause a fatal error and the process can't terminate. Even the first node I am deleting isn't deleted preoperly.

 function hook_node_delete($node){         $translation_list = translation_node_get_translations($node->tnid);         $default_language = language_default()->language;          if($translation_list!=""){            foreach($translation_list as $translation_list_item){                   if ($translation_list_item->language!=$default_language){                   node_delete($translation_list_item->nid);               }            };         };     } 

So I am forced to simply unpublish the translations by doing something like that:

 function hook_node_delete($node){                 $translation_list = translation_node_get_translations($node->tnid);                 $default_language = language_default()->language;                  if($translation_list!=""){                    foreach($translation_list as $translation_list_item){                           if ($translation_list_item->language!=$default_language){                           $node_translated = node_load($translation_list_item->nid);                           $node_translated->status = 0;                           node_save($node_translated);                       }                    };                 };             } 

Why can I not invoke node_delete() from hook_node_delete()??

     

回答列表

3
 
vote

首先必须在删除它们之前从翻译集中删除节点。所以这样做的事情:

  function hook_node_delete($node){     $all = translation_node_get_translations($node->tnid);      foreach($all as $del){         if($node->nid != $del->nid){             translation_remove_from_set(node_load($del->nid));             node_delete($del->nid);         }     } }   
 

you first have to remove the nodes from the translation set before you can delete them. So do something like this:

function hook_node_delete($node){     $all = translation_node_get_translations($node->tnid);      foreach($all as $del){         if($node->nid != $del->nid){             translation_remove_from_set(node_load($del->nid));             node_delete($del->nid);         }     } } 
 
 
2
 
vote

118218提供的答案对我不起作用,因为如果要删除源节点(翻译集创建的第一节节点),则函数 translation_node_get_translations 将返回 null ,由于该翻译集的其他节点的 tnid 将在执行 hook_node_delete 的执行之前更新。

我的解决方案是覆盖 node/%node/delete 菜单项:

  /**  * Implements hook_menu_alter().  */ function my_module_menu_alter(&$items) {     $items['node/%node/delete']['page arguments'] = array('my_module_custom_node_delete', 1);     $items['node/%node/delete']['file path'] = drupal_get_path('module', 'my_module');     $items['node/%node/delete']['file'] = 'my_module.module'; }   

然后实现删除确认表单并提交函数在节点删除之前创建回调:

  function get_menu_id($menu_title) {     $menu_names = menu_get_names();     foreach ($menu_names as $menu_name) {         $menu = menu_load($menu_name);          if ($menu['title'] == $menu_title) {             return $menu_name;         }     } } 0  

实现其他节点的删除:

  function get_menu_id($menu_title) {     $menu_names = menu_get_names();     foreach ($menu_names as $menu_name) {         $menu = menu_load($menu_name);          if ($menu['title'] == $menu_title) {             return $menu_name;         }     } } 1  

最后,您可以从您想要的任何模块调用删除功能,只需实现钩子 function get_menu_id($menu_title) { $menu_names = menu_get_names(); foreach ($menu_names as $menu_name) { $menu = menu_load($menu_name); if ($menu['title'] == $menu_title) { return $menu_name; } } } 2

  function get_menu_id($menu_title) {     $menu_names = menu_get_names();     foreach ($menu_names as $menu_name) {         $menu = menu_load($menu_name);          if ($menu['title'] == $menu_title) {             return $menu_name;         }     } } 3  
 

The answer provided by 118218 doesn't work for me because if you are deleting the source node (first node created of the translation set) the function translation_node_get_translations will return null, since the tnid of the other nodes of this translation set will be updated before the execution of hook_node_delete.

The solution for me was to overwrite the node/%node/delete menu item like this:

/**  * Implements hook_menu_alter().  */ function my_module_menu_alter(&$items) {     $items['node/%node/delete']['page arguments'] = array('my_module_custom_node_delete', 1);     $items['node/%node/delete']['file path'] = drupal_get_path('module', 'my_module');     $items['node/%node/delete']['file'] = 'my_module.module'; } 

and then implement the delete confirmation form and submit function creating a callback before the node deletion like this:

function my_module_custom_node_delete($form, &$form_state, $node) {     $form['#node'] = $node;     // Always provide entity id in the same form key as in the entity edit form.     $form['nid'] = array('#type' => 'value', '#value' => $node->nid);     return confirm_form($form,         t('Are you sure you want to delete %title?', array('%title' => $node->title)),         'node/' . $node->nid,         t('This action cannot be undone.'),         t('Delete'),         t('Cancel')     ); }  function my_module_custom_node_delete_submit($form, &$form_state) {     if ($form_state['values']['confirm']) {         $node = node_load($form_state['values']['nid']);         drupal_alter('before_node_delete', clone $node);         node_delete($form_state['values']['nid']);         watchdog('content', '@type: deleted %title.', array('@type' => $node->type, '%title' => $node->title));         drupal_set_message(t('@type %title has been deleted.', array('@type' => node_type_get_name($node), '%title' => $node->title)));     }     $form_state['redirect'] = '<front>'; } 

implement the deletion of the other nodes:

function my_module_delete_child_nodes($node) {     if($node->language == SOURCE_NODE_LANGUAGE) {         $all = translation_node_get_translations($node->tnid);         if(isset($all[SOURCE_NODE_LANGUAGE]))             unset($all[SOURCE_NODE_LANGUAGE]);         if(count($all) > 0) {             $nids = array();             foreach($all as $t) {                 $nids[] = $t->nid;             }             node_delete_multiple($nids);         }     } } 

and finally, you can call the deletion function from any module you want just implementing the hook MODULE_NAME_before_node_delete_alter($node)

/**  * Implements hook_before_node_delete_alter().  */ function MODULE_NAME_before_node_delete_alter($node) {         my_module_delete_child_nodes($node); } 
 
 
1
 
vote

作为"filipedelmonte" 答案说,如果删除翻译集的源节点,则函数 function get_menu_id($menu_title) { $menu_names = menu_get_names(); foreach ($menu_names as $menu_name) { $menu = menu_load($menu_name); if ($menu['title'] == $menu_title) { return $menu_name; } } } 4 将返回null,因为它是其他节点的 function get_menu_id($menu_title) { $menu_names = menu_get_names(); foreach ($menu_names as $menu_name) { $menu = menu_load($menu_name); if ($menu['title'] == $menu_title) { return $menu_name; } } } 5 在执行 function get_menu_id($menu_title) { $menu_names = menu_get_names(); foreach ($menu_names as $menu_name) { $menu = menu_load($menu_name); if ($menu['title'] == $menu_title) { return $menu_name; } } } 6 之前,将更新翻译集。然而,他的方法太复杂了。所以我改进了"Gert Van Den Buijs" 的答案,以便在所有情况下工作。这个想法是预先加载所有节点中的翻译:

  function get_menu_id($menu_title) {     $menu_names = menu_get_names();     foreach ($menu_names as $menu_name) {         $menu = menu_load($menu_name);          if ($menu['title'] == $menu_title) {             return $menu_name;         }     } } 7  
 

As "filipedelmonte" answer says, if the source node of the translation set is deleted, then the function translation_node_get_translations will return null since the tnid of the other nodes of the translation set will be updated before the execution of hook_node_delete. However, his approach is too complicated. So I improved "Gert van den buijs" answer to work in all cases. The idea is to preload the translation set in all nodes:

/**  * Implements hook_node_load().  */ function hook_node_load($nodes, $types) {   if (!is_array($nodes)) {     return;   }   foreach ($nodes as $node) {     $node->translation_set = translation_node_get_translations($node->tnid);   } }  /**  * Implements hook_node_delete().  */ function hook_node_delete($node) {   if (is_array($node->translation_set)) {     foreach ($node->translation_set as $del) {       if ($node->nid != $del->nid) {         translation_remove_from_set(node_load($del->nid));         node_delete($del->nid);       }     }   } } 
 
 
0
 
vote
vote
最佳答案
 

"gert van den buijs" 的答案对我不起作用。因此,我设法通过直接使用db_delete删除内容来进行。我不确定这是最好的方法,但至少它有效。

类似,递归不调用hook_node_delete,函数可以正确终止。

  function get_menu_id($menu_title) {     $menu_names = menu_get_names();     foreach ($menu_names as $menu_name) {         $menu = menu_load($menu_name);          if ($menu['title'] == $menu_title) {             return $menu_name;         }     } } 8  
 

The "Gert van den buijs" answer doesn't work for me. So I managed to do it by deleting the content directly with db_delete. I'm not sure it's the best way to do it but at least it works.

Like that, hook_node_delete isn't called recursively and the function can terminate properly.

function hook_node_delete($node){    $all = translation_node_get_translations($node->tnid);      unset($all[$node->language]);      if(isset($all)){             foreach($all as $del){                     if($node->nid != $del->nid){                         $nids[] = $del->nid;                              db_delete('node')                                 ->condition('nid', $nids, 'IN')                                 ->execute();                             db_delete('node_revision')                                 ->condition('nid', $nids, 'IN')                                 ->execute();                             db_delete('history')                                 ->condition('nid', $nids, 'IN')                                 ->execute();                             db_delete('node_access')                              ->condition('nid', $nids, 'IN')                              ->execute();                     }             }      } } 
 
 

相关问题

0  drupal 6 node_load,条件  ( Drupal 6 node load with conditions ) 
这里是情况: 我有两个内容类型。内容类型A具有用于内容类型B的CCK参考字段。 现在,我正在尝试从Content类型A中加载到内容类型B. 的内容类型a中的所有节点。 这是我的代码。 /* step 2 */ function media_mover_api_add_config_form_submit($for...

0  如何将图像库添加到内容类型  ( How to add an image gallery to content type ) 
我需要的是让用户在内容类型中添加一些图像,并且在用户发布标题后,正文消息,这些图像应该显示为节点上的图库。 我知道如何通过views gallericific做广播,但是如何将此库添加到节点? ...

1  获得剪辑的长度  ( Get length of the teaser ) 
我需要在设置自定义内容类型的长度上获取设置。 我试过谷歌,但到目前为止我有ziltch结果。 我还尝试在temis_config_instance,field_config和变量表中查看数据库,但它们无法给我一个值... 现在,我希望你专家可以帮助我指出我的正确方向? 会受到赞赏。 : - ) 提前感谢。 ...

9  如何在以编程方式创建节点时以编程方式添加图像?  ( How do i programmatically add an image while programmatically creating nodes ) 
我正在编写脚本以编程地添加节点,我不知道添加/附加图像的正确方法。实际上我不熟悉司布。 以下是我发现的(样本)图像对象 print_r ING现有 $node 我正在使用: field_image:array([und] =&gt; array([0] =&gt; array([fxid] =&gt; 3089 ...

1  从视图中显示特定节点结果对特定页面的结果  ( Display specific nodes from views result on specific pages ) 
如何从特定页面上的视图显示特定节点? 例如,我为内容类型广告创建CCK字段("节点ID:" )),并将内容类型 Basic Page 放在其中我想显示这个广告。 在没有额外的模块的情况下在那里实现这一点? ...

0  使用答案模块服务API奇怪  ( Service api acting strange with answers module ) 
我目前正在开发一个Android应用程序,它使用休息来与Drupal沟通 我已经设置了服务模块,并使用正常的"帖子" 内容类型节点 但是,如果我发布 question 节点从答案模块,它不起作用。 所以,我发布了这样的json字符串: {"node": { "title":"REST question", ...

2  添加到包含“默认”和“TEASER”的显示选项列表  ( Adding to that list of display options that includes default and teaser ) 
结构&gt;内容类型&gt;管理字段,右上角有显示选项。系统定义的系统是"默认的" ,但"令牌" ,但我已经看到了"令牌" 和"令牌" 和"ColorBox" 添加了Contract模块。 我用什么钩子或函数来为我的模块访问创建这些新内容类型显示? ...

4  Drupal如何知道要使用哪个实体视图模式?  ( How does drupal know which entity view mode to use ) 
当定义实体视图模式时,Drupal如何知道哪些使用?它们是否仅适用于视图,或者也可以在节点显示器中使用?如果是,则在模板中指定,或其他地方? ...

1  内容类型“自定义数据”  ( Content type custom data ) 
我创建了一个具有"接受" 字段的内容类型。我想添加一个按钮,"接受" ,到内容类型。当用户单击它时,它将暂时存储其用户名等,具体取决于接受字段的数量,内容类型将显示"1/10接受" 。我将如何执行此操作,并具有实时显示的接受数。谢谢!! ...

1  在用户创建节点之前获得付款  ( Get payment before users create a node ) 
当用户创建节点时,应将它们重定向到付款页面;如果付款成功,则用户可以看到节点。 有没有办法来实现这个? ...

4  如何在表单提交后将用户重定向到上一页?  ( How to redirect user to previous page after form submit ) 
我可以在向任何另一个页面添加节点后重定向用户,但想要将它们重定向到他们链接的上一页。现在我使用以下代码: function user_add_node_form_foto_node_form_alter(&$form, &$form_state, $form_id) { $form['actions']['s...

4  我想为像标准编辑和删除等节点创建一个新命令  ( I want to create a new command for the nodes like the standard edit and delete ) 
在drupal中,您有标准命令编辑和删除您访问的键入: didyouknow_item_edit()2 我想创建一些这样的命令: didyouknow_item_edit()3 我在哪里挂钩以访问命令并执行一些代码? ...

0  在响应主题中设置响应内容  ( Setting up responsive content within a responsive theme ) 
我想在响应的主要内容内进行布局。 我读过几十页,看了几个视频,仍然没有明确的呼吸内容。 我开始使用最新的禅宗,但展示套件和面板让我将我的字段放在不同的网格布局中,但这些网格最终不会响应。 我现在安装了omega,结束了同样的问题。 因此,哪些主题以及哪些模块让我在主内容中设置响应网格? ...

1  使用显示套件更改布局后,“管理显示”选项卡上的500 HTTP错误!我应该怎么办?  ( 500 http error on manage display tab after changing layout with display suite ) 
我将布局更改为"一列" 与显示套件给定内容类型的"管理显示" 选项卡,其中包含许多(〜30)字段。我也使用具有多个组的字段组模块。 保存后,DS将某些组的父元素设置为"已禁用" 。好的,我改变了它,我把这些拖到了一个支持的部分,保存后,我在长时间等待后的"管理显示" 选项卡时得到了500个HTTP代码! 我该怎么办...

0  实体参考的限制结果  ( Limit results of the entity reference ) 
我一直在尝试找到这个问题的解决方案。我正在引用具有实体引用的串行节点,但我只是想显示最新的3个节点。有没有办法我可以限制实体参考的结果?我需要拥有无限数量的值,但只需要显示该案例的最后3。我不使用视图。 我正在使用drupal 7 谢谢:) ...

1  如何允许对一个内容类型的匿名评论,但不是全部  ( How to allow anonymous comments on one content type but not all ) 
我希望匿名访问者能够评论我的'博客'内容类型,但只有注册用户对我的"论坛" 内容类型的评论。 似乎似乎匿名用户有权评论,这适用于启用注释的所有内容类型。 我缺少某个地方,如果内容类型是'论坛',用户是匿名的,我需要看看躲藏/禁用评论表单吗? ...

1  添加新节点但未编辑后重定向  ( Redirect after a new node is added but not edited ) 
我在节点上有一个自定义重定向。 function mymodule_form_alter(&$form, $form_state, $form_id) { $form['actions']['submit']['#submit'][] = 'custom_node_submit'; } function...

2  更改用于书节点的排序顺序  ( Change the sorting order used for book nodes ) 
如何更改用于书节点的订单,默认情况下基于重量和标题? 我有一组在使用结构化书的页面内显示的节点。我想用重量和随机排序,而不是重量和名称来显示它们。 本书用于构建不同类型的本地公司和餐馆。 我已经追踪了寻找解决方案的代码,但对我来说有点乱。 是有帮助的钩子来实现这个吗? ...

1  如何预先填充节点参考字段(复选框)  ( How to prepopulate a node reference field checkbox ) 
在节点/添加页面上,我有一个节点参考。窗口小部件类型是"复选框" ,我正在使用"用于选择节点" 功能的"视图" 功能在节点/添加页面上显示最多5个复选框。 我想用 prepopulate 模块,预先填充一个复选框。 复选框使用此HTML名称值: name="field_tribe_content[und][188...

23  卸载功能后无法删除功能内容类型  ( Unable to delete feature content type after uninstalling feature ) 
问题 卸载创建内容类型的功能隐藏 99887660 上的"删除" 链接。 在drupal.org上的问题 ...




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


Licensed under cc by-sa 3.0 with attribution required.