2

I'm working on a catalog based on Drupal Commerce. I have a product display content type referencing product entities. I'm thinking about the ways to make life of a content manager easier.

I made a rule which fires when product is created and creates a corresponding Product display. But I can't figure out the best way to delete a product display nodes when the product is deleted.

Till now I've tried VBO, but seems in Drupal 7 rules2 lacks the ability to run VBO actions.

I guess a quick and dirty solution is to write a module for this task, but I'm looking for something more elegant. Any ideas?

1
  • 2
    A note for anyone reading this a bit later than Jun 1st, VBO now provides a way for Rules to load its result set (list of entities), on which you can then run your actions / rules, giving you a more elegant way of "running VBO actions". This happened in VBO 7.x-3.0-beta1, released on July 16th. Commented Aug 3, 2011 at 23:26

4 Answers 4

4

I think a "quick and dirty" module would be the more elegant way. I did something similar recently in drupal 6 with ubercart. I have a content type that sometimes needs to be associated with a product and sometimes doesn't. When one of the custom nodes is deleted, if it has a product associated with it, that needs to be removed as well:

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);
    }
  }
}

In this case, field_product_list was a node reference field added to the product. I'm sure something similar would work in your case.

1
0

Just to add to @David_L's answer, and extending the scenario of the problem.

  • The example below makes use of EntityFieldQuery.
  • I point out that nested entity references can be handled hook_node_delete() by simply adding another IF, there is no need to write a sub-loop as the hook is called for each deletion.

    <?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

This might not be the best solution but I am using the below: Also, you can do delete mutiple.

    /**
     * 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);
          }
        }
      }
    }
-1

The following has been borrowed from here.

Insert the following into your custom module.

/**
 * Implements hook_node_delete().
 */
function mymodule_node_delete($node) {
  if ($node->type == 'mynodetype'){
    $nids = db_query('SELECT entity_id FROM {field_data_field_review_reference} WHERE field_review_reference_nid = :nid', array(':nid' => $node->nid))->fetchCol();
    node_delete_multiple($nids);
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.