? .DS_Store
? custom.diff
Index: auction.install
===================================================================
RCS file: /cvs/drupal/contributions/modules/ecommerce/contrib/auction/auction.install,v
retrieving revision 1.1.6.1
diff -u -F^f -r1.1.6.1 auction.install
--- auction.install	14 Feb 2007 06:48:25 -0000	1.1.6.1
+++ auction.install	13 Jun 2007 20:53:28 -0000
@@ -11,7 +11,8 @@ function auction_install() {
       db_query("CREATE TABLE {ec_product_auction} (
         nid int(10) unsigned NOT NULL default '0',
         expires int(11) NOT NULL default '0',
-        PRIMARY KEY  (nid)
+        buynow decimal(10,2) NOT NULL default '0.00',
+        PRIMARY KEY (nid)
       ) TYPE=MyISAM;");
       db_query("CREATE TABLE {ec_auction_bid} (
         nid int(10) unsigned NOT NULL default '0',
@@ -25,7 +26,8 @@ function auction_install() {
       db_query("CREATE TABLE {ec_product_auction} (
         nid integer NOT NULL default '0',
         expires integer NOT NULL default '0',
-        PRIMARY KEY  (nid)
+        buynow decimal(10,2) NOT NULL default '0.00',
+        PRIMARY KEY (nid)
       )");
       db_query("CREATE TABLE {ec_auction_bid} (
         nid integer NOT NULL default '0',
@@ -38,3 +40,21 @@ function auction_install() {
   }
   drupal_set_message(t('E-Commerce: Auction tables have been created.'));
 }
+
+/**
+ * Update table definitions.
+ */
+function auction_update_1000() {
+  $ret = array();
+
+  switch ($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      $ret[] = update_sql("ALTER TABLE {ec_product_auction} ADD buynow decimal(10,2) NOT NULL default '0.00'");
+      break;
+    case 'pgsql':
+      $ret[] = update_sql("ALTER TABLE {ec_product_auction} ADD buynow decimal(10,2) NOT NULL default '0.00'");
+      break;
+  }
+  return $ret;
+}
Index: auction.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/ecommerce/contrib/auction/auction.module,v
retrieving revision 1.19.2.3.2.1.2.13
diff -u -F^f -r1.19.2.3.2.1.2.13 auction.module
--- auction.module	28 Feb 2007 07:45:30 -0000	1.19.2.3.2.1.2.13
+++ auction.module	13 Jun 2007 20:53:28 -0000
@@ -101,12 +101,19 @@ function auction_link($type, $node = NUL
   $links = array();
 
   if ($type == 'node' && user_access('access content') && $teaser && $node->ptype == 'auction') {
-    if (time() > $node->expires) {
+    if (time() > $node->expires || _auction_bid_equals_buynow($node->nid)) {
       $links['bid'] = array(
         'title' => t('Bidding closed'),                   
         'attributes' => array('class' => 'bid-link'),
       );
     }
+    elseif ($node->buynow) {
+      $links['bid'] = array(
+        'title' => t('Buy now'),
+        'href' => "auction/$node->nid/buynow",
+        'attributes' => array('title' => t('Buy this item now'), 'class' => 'bid-link'),
+      );
+    }
     else {
       $links['bid'] = array(
         'title' => t('Bid now'),
@@ -153,7 +160,7 @@ function auction_productapi(&$node, $op,
   switch ($op) {
     /* Due to the way we have to build our node, we have to pass an array of values this module collects. */
     case 'fields':
-      return array('expires' => $node->expires, 'bid_history' => $node->bid_history);
+      return array('expires' => $node->expires, 'bid_history' => $node->bid_history, 'buynow' => $node->buynow);
 
     case 'validate':
       if (isset($node->expires)) {
@@ -165,6 +172,9 @@ function auction_productapi(&$node, $op,
       else {
         form_set_error('expires', t('Please enter an expiration date.'));
       }
+      if ($node->buynow < 0) {
+        form_set_error('buynow', t('Please enter a "Buy now" price that is positive.'));
+      }
       break;
 
     case 'wizard_select':
@@ -177,9 +187,9 @@ function auction_productapi(&$node, $op,
     case 'cart add item':
       /* This is not currently called internally. */
       global $user;
-      $expired = (time() > $node->expires) ? true : false;
+      $expired = (time() > $node->expires) ? TRUE: FALSE;
       $buyer = db_result(db_query_range('SELECT uid FROM {ec_auction_bid} WHERE uid = %d ORDER BY created DESC', $user->uid, 0, 1));
-      return (($buyer && $expired) ? true : false);
+      return $buyer && $expired;
 
     case 'form':
       if (!$node->expires) {
@@ -194,6 +204,17 @@ function auction_productapi(&$node, $op,
         '#maxlength' => 50,
         '#description' => t('Enter the date this product is no longer open for bidding.'),
       );
+      if (!$node->buynow) {
+        $node->buynow = 0.00;
+      }
+      $form['buynow'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Buy now price'),
+        '#default_value' => payment_format($node->buynow),
+        '#size' => 25,
+        '#maxlength' => 50,
+        '#description' => t('The price for which the item in the auction can be bought immediately. Leave it set to zero if you want it to be disabled.'),
+      );
       return $form;
 
       /* Similar to node_load */
@@ -205,17 +226,22 @@ function auction_productapi(&$node, $op,
       if (!is_numeric($node->expires)) {
         $node->expires = strtotime($node->expires);
       }
-      return db_query('INSERT INTO {ec_product_auction} (nid, expires) VALUES (%d, %d)', $node->nid, $node->expires);
+      if (!is_numeric($node->buynow)) {
+        $node->buynow = normalize_price($node->buynow);
+      }
+      return db_query('INSERT INTO {ec_product_auction} (nid, expires, buynow) VALUES (%d, %d, %d)', $node->nid, $node->expires, $node->buynow);
 
     case 'attributes':
       return array('in_stock', 'is_shippable');
 
     case 'update':
-
-    if (!is_numeric($node->expires)) {
-      $node->expires = strtotime($node->expires);
-    }
-      return db_query('UPDATE {ec_product_auction} SET expires = %d WHERE nid = %d', $node->expires, $node->nid);
+      if (!is_numeric($node->expires)) {
+        $node->expires = strtotime($node->expires);
+      }
+      if (!is_numeric($node->buynow)) {
+        $node->buynow = normalize_price($node->buynow);
+      }
+      return db_query('UPDATE {ec_product_auction} SET expires = %d, buynow = %d WHERE nid = %d', $node->expires, $node->buynow, $node->nid);
 
     case 'delete':
       db_query('DELETE FROM {ec_product_auction} WHERE nid = %d', $node->nid);
@@ -235,8 +261,10 @@ function auction_nodeapi(&$node, $op, $t
       if (isset($node->ptype) && $node->ptype == 'auction') {
         global $user;
         if ($page) {
-          $form = drupal_get_form('product_auction_view_form',$node,$user);
-          $node->content['body']['#value'] .= $form; // it appends rendered form to node body (node->body go through filters)  	 
+          $form = drupal_get_form('product_auction_view_form', $node, $user);
+          // This appends the rendered form to the node body. We must append
+          // the form because the node body goes through the filters.
+          $node->content['body']['#value'] .= $form;
         }
       }  	 
   }   
@@ -269,19 +297,26 @@ function auction_page($nid, $action) {
         }
         else {
           $edit['nid'] = $nid;
-          $output = drupal_get_form('auction_bid_form',$edit);
+          $output = drupal_get_form('auction_bid_form', $edit);
         }
         break;
 
+      case 'buynow':
+        $node = node_load($nid);
+        $edit['nid'] = $nid;
+        $edit['buynow'] = $node->buynow;
+        $output = drupal_get_form('auction_bid_form', $edit);
+        break;
+
       default:
         $edit['nid'] = $nid;
-        $output =  drupal_get_form('auction_bid_form',$edit);
+        $output = drupal_get_form('auction_bid_form', $edit);
         break;
     }
     return $output;
   }
   else {
-    drupal_set_message(t('You are not authorised to bid.'));
+    drupal_set_message(t('You are not authorized to bid.'));
     return $output;
   }
 }
@@ -354,6 +389,15 @@ function auction_bid_current($nid) {
 }
 
 /**
+ * Returns TRUE if an auction has reached the "buy now" price, FALSE otherwise.
+ */
+function _auction_bid_equals_buynow($nid) {
+  $node = node_load($nid);
+  $current_bid = auction_bid_current($nid);
+  return $node->buynow > 0 && $node->price > 0 && $current_bid['bid'] >= $node->buynow;
+}
+
+/**
  * Displays a bidding history for the passed node id. Currently displays that
  * data in a table with no option to retheme in anything but a table.
  *
@@ -371,7 +415,7 @@ function auction_bid_history($nid) {
   if ($rows) {
     $output = theme('table', $header, $rows);
   } 
-  $output.= l(t('Back'),'node/'.$nid);
+  $output .= l(t('Back'), "node/$nid");
   return $output;
 }
 
@@ -428,7 +472,7 @@ function auction_bid_save($edit) {
 function auction_bid_form($edit) {
   $product = node_load($edit['nid']);
 
-  if (time() > $product->expires) {
+  if ((time() > $product->expires) || _auction_bid_equals_buynow($product->nid)) {
     drupal_set_message(t('This auction has ended.'));
     drupal_goto("node/$product->nid");
   }
@@ -436,16 +480,31 @@ function auction_bid_form($edit) {
   $form['theme'] = array();
   $form['theme']['#high_bid'] = auction_bid_current($edit['nid']);
   $form['theme']['#current_bid'] = ($form['theme']['#high_bid']['bid']) ? $form['theme']['#high_bid']['bid'] : $product->price;
-  $form['bid'] = array(
-    '#type' => 'textfield',
-    '#title' => '',
-    '#default_value' => $edit['bid'],
-    '#size' => 10,
-    '#maxlength' => 50,
-    '#description' => t('Enter an amount above %base-bid-amount.', array('%base-bid-amount' => $form['theme']['#current_bid'])),
-    '#attributes' => null,
-    '#required' => true,
-  );
+  $form['theme']['#buynow'] = ($product->buynow) ? payment_format($product->buynow) : NULL;
+
+  if (isset($edit['buynow'])) {
+    $form['buynow'] = array(
+      '#type' => 'hidden',
+      '#value' => $edit['buynow'],
+    );
+    $form['bid'] = array(
+      '#type' => 'hidden',
+      '#default_value' => $edit['buynow'],
+      '#required' => TRUE,
+    );
+  }
+  else {
+    $form['bid'] = array(
+      '#type' => 'textfield',
+      '#title' => '',
+      '#default_value' => $edit['bid'],
+      '#size' => 10,
+      '#maxlength' => 50,
+      '#description' => t('Enter an amount above %base-bid-amount.', array('%base-bid-amount' => $form['theme']['#current_bid'])),
+      '#attributes' => NULL,
+      '#required' => TRUE,
+    );
+  }
   $form['nid'] = array(
     '#type' => 'hidden',
     '#value' => $edit['nid'],
@@ -472,11 +531,21 @@ function auction_bid_form($edit) {
  */
 function theme_auction_bid_form($form) {
 
-  drupal_set_title(t('Place a Bid'));
+  if (isset($form['buynow'])) {
+    drupal_set_title(t('Buy now'));
+  }
+  else {
+    drupal_set_title(t('Place a Bid'));
+  }
 
   $header = array();
   $rows[] = array(t('Current bid:'), payment_format($form['theme']['#current_bid']));
-  $rows[] = array(t('Your bid:'), drupal_render($form['bid']));
+  if (isset($form['buynow'])) {
+    $rows[] = array(t('Your bid:'), $form['theme']['#buynow']);
+  }
+  else {
+    $rows[] = array(t('Your bid:'), drupal_render($form['bid']));
+  }
   $rows[] = array('&nbsp;', drupal_render($form['submit']));
 
   $output = theme('table', $header, $rows);
@@ -502,12 +571,23 @@ function theme_product_auction_view_form
 
   $header = array();
   $rows[] = array(t('Time left:'), format_interval($form['theme']['#expire_time'] - time()));
+  $rows[] = array(t('Starting bid:'), $form['theme']['#price']);
   $rows[] = array(t('Current bid:'), $form['theme']['#high_bid_amount']);
-  $rows[] = array(t('High bidder:'), $form['theme']['#high_bid_name']);  
-  $bid_history = l(t('%num-bids',array('%num-bids' => format_plural($form['theme']['#high_bid']['count'], '1 bid', '@count bids'))),'auction/'. $form['theme']['#nid'] .'/bid/history',array(),NULL,NULL,FALSE,TRUE);
-  //WTF? $bid_history = t('(<a href="%bid-history-link">%num-bids</a>)', array('%bid-history-link' => url('auction/'. $form['theme']['#nid'] .'/bid/history'), '%num-bids' => format_plural($form['theme']['#high_bid']['count'], '1 bid', '@count bids')));
-  $rows[] = array(t('Bid history'), '( '.$bid_history.' )');
-  if ($form['theme']['#form']) {$rows[] = array(NULL,drupal_render($form['submit'])); }
+  $rows[] = array(t('Highest bidder:'), $form['theme']['#high_bid_name']);  
+  $bid_history = l(t('%num-bids', array('%num-bids' => format_plural($form['theme']['#high_bid']['count'], '1 bid', '@count bids'))),'auction/'. $form['theme']['#nid'] .'/bid/history', array(), NULL, NULL, FALSE, TRUE);
+  $rows[] = array(t('Bid history'), $bid_history);
+  
+  // Only render the 'Place Bid' and 'Buy now' buttons if the user has
+  // permission to make a bid.
+  // TODO: the '#form' key should be renamed to something like '#user_can_bid'
+  if ($form['theme']['#form']) {
+    $rows[] = array(NULL, drupal_render($form['submit']));
+    // Show the 'Buy now' link if this option is enabled for this auction.
+    if ($form['theme']['#buynow']) {
+      // TODO: this should be a button, not a link
+      $rows[] = array(NULL, l(t('Buy now for @buynow-price!', array('@buynow-price' => $form['theme']['#buynow'])), 'auction/'. $form['theme']['#nid'] . '/buynow'));
+    }
+  }
 
   $output .= theme('table', $header, $rows);
   $output .= drupal_render($form);
@@ -532,6 +612,7 @@ function product_auction_view_form($node
   $high_bid = auction_bid_current($node->nid);
   $form['theme'] = array();
   $form['theme']['#nid'] = $node->nid;
+  $form['theme']['#price'] = $node->price;
         $node->expires = 
   $form['theme']['#expire_time'] = ($node->expires) ? $node->expires : time() + (variable_get('auction_days', 1) * 24 * 60 * 60);
   $form['theme']['#high_bid'] = $high_bid;
