web-dev-qa-db-ja.com

特定のノードを参照するすべてのノードを削除する方法は?

Drupal Commerceに基づいたカタログを作成しています。製品エンティティを参照する製品表示コンテンツタイプがあります。コンテンツマネージャの操作を簡単にする方法を考えています。

製品の作成時に起動し、対応する製品ディスプレイを作成するルールを作成しました。しかし、製品が削除されたときに製品表示ノードを削除する最良の方法がわかりません。

今まで私はVBOを試しましたが、Drupal 7のようです。rules2にはVBOアクションを実行する機能がありません。

このタスク用のモジュールを作成するのが手っ取り早い方法だと思いますが、もっとエレガントなものを探しています。何か案は?

2
Dmitry Vyal

「素早い、汚い」モジュールの方がエレガントな方法だと思います。私は最近drupal 6でubercartを使用して同様のことをしました。製品に関連付ける必要がある場合とそうでない場合があるコンテンツタイプがあります。カスタムノードの1つが削除された場合、関連付けられている製品があり、それも削除する必要があります。

your_module_nodeapi(&$node, $op) {
  if($op == 'delete') {
    $product_nid = db_result(db_query('SELECT nid FROM {content_type_product} WHERE field_product_list = %d', $node->nid));
    if(!empty($product_nid)) {
      node_delete($product_nid);
    }
  }
}

この場合、field_product_listは、製品に追加されたノード参照フィールドでした。あなたの場合も同様のものがうまくいくと思います。

4
David L

これは最善の解決策ではないかもしれませんが、以下を使用しています:また、複数を削除することもできます。

    /**
     * Implements hook_node_delete().
     */
    function my_module_node_delete($node) {
      // Gets the node type for the newly deleted node.
      $node_type = $node->type;
      $node_id = $node->nid;
      // Everything happens only if the node is
      // of type mytype.
      if ($node_type == 'mytype') {
        // Find all nodes that reference this node in the custom import reference field.
        // the table name is for the field that keeps the reference.

        $find_nodes = db_select('field_data_field_import_reference', 'f')
          ->fields('f', array('entity_id'))
          ->condition('f.bundle', 'myotherbundle', '=')
          ->condition('f.field_import_reference_target_id', $node_id, '=');

        try {
          // Execute query.
          $resulting_nodes = $find_nodes->execute()->fetchAll();
        }
        catch (Exception $e) {
          // Or catch exception.
          $error_message = $e->getMessage();
          watchdog('mymodule', $error_message);
        }
        // If we have nodes to delete.
        if (isset($resulting_nodes)) {
          // Get the nid for each.
          foreach ($resulting_nodes as $delete_node) {
            // Delete by nid.
            node_delete($delete_node->entity_id);
          }
        }
      }
    }
0
Lia

@David_Lの答えに追加して、問題のシナリオを拡張するだけです。

  • 以下の例では、EntityFieldQueryを使用しています。
  • ネストされたエンティティ参照は、別のIFを追加するだけでhook_node_delete()で処理できることを指摘します。削除ごとにフックが呼び出されるため、サブループを記述する必要はありません。

    <?php
    function mymodule_node_delete($node) {
        if ($node->type == 'product'){// if a product is being deleted
    
            $query = new EntityFieldQuery();
            $result = $query->entityCondition('entity_type', 'node')
                            ->entityCondition('bundle', 'product_display')
                            ->fieldCondition('field_product', 'target_id', $node->nid)
                            ->execute();
            if(!empty($result['node'])){
                $nids = array_keys($result['node']);
                node_delete_multiple($nids);
            }
        }
    
        if ($node->type == 'product_display'){// if a product's display is being deleted
    
            $query = new EntityFieldQuery();
            $result = $query->entityCondition('entity_type', 'node')
                            ->entityCondition('bundle', 'product_display_child')
                            ->fieldCondition('field_product_display', 'target_id', $node->nid)
                            ->execute();
            if(!empty($result['node'])){
                $nids = array_keys($result['node']);
                node_delete_multiple($nids);
            }
        }
    }
    ?>
    
0
Duncanmoo