it-swarm-ko.tech

주어진 노드를 참조하는 모든 노드를 삭제하는 방법은 무엇입니까?

저는 Drupal Commerce를 기반으로 한 카탈로그 작업 중입니다. 제품 엔티티를 참조하는 제품 디스플레이 콘텐츠 유형이 있습니다. 콘텐츠 관리자의 삶을 더 쉽게 만드는 방법을 생각하고 있습니다.

제품이 생성 될 때 실행되는 규칙을 만들고 해당 제품 디스플레이를 생성했습니다. 그러나 제품이 삭제 될 때 제품 디스플레이 노드를 삭제하는 가장 좋은 방법을 찾을 수 없습니다.

지금까지 VBO를 시도했지만 Drupal 7 rules2에는 VBO 작업을 실행하는 기능이 부족합니다.

빠르고 더러운 해결책은이 작업을위한 모듈을 작성하는 것이라고 생각하지만 더 우아한 것을 찾고 있습니다. 어떤 아이디어?

2
Dmitry Vyal

"빠르고 더러운"모듈이 더 우아한 방법이라고 생각합니다. 최근에 ubercart를 사용하여 drupal 6에서 비슷한 작업을 수행했습니다. 때때로 제품과 연결되어야하고 때로는 연결되지 않는 콘텐츠 유형이 있습니다. 사용자 지정 노드 중 하나가 삭제되면 제거해야하는 제품이 연결되어 있습니다.

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