Product Module  : zing_auction
Coded and Maintained by Benjamin Melançon of Agaric Design Collective
Based on the e-commerce contrib auction module:
  Original Author : Matt Westgate
  Maintainer: Simon Hobbs
// actually, don't have any settings yet...  but if we did, would be here
Settings        : > administer > store > settings > zing auction 

********************************************************************
DESCRIPTION:

Creates a simple product that can be bid on by users.

You cannot use role-based price adjustments with this module:
( > admin > store > settings > role discounts )
Doing so will mess up your pricing.

********************************************************************

See README.txt (in E-Commerce root) for other info.

/* below would be useful to rework as extension to auction mod if that is desired */
// Actually, none of this is necessary because I can add value and display_value in the same way "expires" is added.  
// this is part of how I should refactor zing_auction if I'm to do it as an extension of, rather than replacement for, the contrib auction module.

/*
 * Add new attributes to the zing_auction product
 * following the example of
 * http://api.drupal.org/api/file/developer/examples/nodeapi_example.module/4.7
 */

/** 
 * Implementation of hook_form_alter(). 
 * 
 * By implementing this hook, we're able to modify any form. We'll only make 
 * changes to two types: a node's content type configuration and edit forms. 
 */ 
function nodeapi_example_form_alter($form_id, &$form) { 
  // add fields for editing value to node edit page
  // below should be more direct than this: isset($form['type']) && $form['type'] == 'product'
  if ($form_id == 'product_node_form' && $form['ptype'] == 'zing_auction') { 
    $form['zing_auction_value'] = array( 
      '#type' => 'select', 
      '#title' => t('Value'), 
      '#default_value' => $form['#node']->zing_auction_value, 
      '#required' => TRUE, 
      '#weight' => 0, 
    );
    $form['zing_auction_value_display'] = array(
      '#type' => 
    )
  } 
  return; 
} 

/** 
 * Implementation of hook_nodeapi(). 
 * 
 * We will implement several node API operations here. This hook allows us to 
 * act on all major node operations, so we can manage our additional data 
 * appropriately. 
 */ 
function nodeapi_example_nodeapi(&$node, $op, $teaser, $page) { 
  switch ($op) { 
    // When the content editing form is submitted, we need to validate the input 
    // to make sure the user made a selection, since we are requiring the rating 
    // field. We have to check that the value has been set to avoid showing an 
    // error message when a new blank form is presented. Calling form_set_error() 
    // when the field is set but zero ensures not only that an error message is 
    // presented, but also that the user must correct the error before being able 
    // to submit the node. 
    case 'validate': 
      if (variable_get('nodeapi_example_'. $node->type, TRUE)) { 
        if (isset($node->nodeapi_example_rating) && !$node->nodeapi_example_rating) { 
          form_set_error('nodeapi_example_rating', t('You must rate this content.')); 
        } 
      } 
      break; 

    // Now we need to take care of loading one of the extended nodes from the 
    // database. An array containing our extra field needs to be returned. 
    case 'load': 
      $object = db_fetch_object(db_query('SELECT rating FROM {nodeapi_example} WHERE nid = %d', $node->nid)); 
      return array('nodeapi_example_rating' => $object->rating); 
      break; 

    // Insert is called after the node has been validated and saved to the 
    // database. It gives us a chance to create our own record in the database. 
    case 'insert': 
      db_query('INSERT INTO {nodeapi_example} (nid, rating) VALUES (%d, %d)', $node->nid, $node->nodeapi_example_rating); 
      break; 

    // Update is called when an existing node has been changed. Here, we use a 
    // DELETE then an INSERT rather than an UPDATE. The reason is that a node 
    // created before this module was installed won't already have a rating 
    // saved so there would be nothing to update. 
    case 'update': 
      db_query('DELETE FROM {nodeapi_example} WHERE nid = %d', $node->nid); 
      db_query('INSERT INTO {nodeapi_example} (nid, rating) VALUES (%d, %d)', $node->nid, $node->nodeapi_example_rating); 
      break; 

    // Delete is called whn the node is being deleted, it gives us a chance 
    // to delete the rating too. 
    case 'delete': 
      db_query('DELETE FROM {nodeapi_example} WHERE nid = %d', $node->nid); 
      break; 

    // Finally, we need to take care of displaying our rating when the node is 
    // viewed. This operation is called after the node has already been prepared 
    // into HTML and filtered as necessary, so we know we are dealing with an 
    // HTML teaser and body. We will inject our additional information at the front 
    // of the node copy. 
    // 
    // Using nodeapi('view') is more appropriate than using a filter here, because 
    // filters transform user-supplied content, whereas we are extending it with 
    // additional information. 
    case 'view': 
      $node->body = theme('nodeapi_example_rating', $node->nodeapi_example_rating) . $node->body; 
      $node->teaser = theme('nodeapi_example_rating', $node->nodeapi_example_rating) . $node->teaser; 
      break; 
  } 
} 
