Index: product.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/ecommerce/product/product.module,v
retrieving revision 1.117
diff -u -r1.117 product.module
--- product.module	3 Jun 2006 00:47:27 -0000	1.117
+++ product.module	5 Jun 2006 06:13:01 -0000
@@ -300,26 +300,6 @@
         'type' => MENU_CALLBACK
       );
     }
-    if (arg(0) == 'node' && is_numeric(arg(1)) && user_access('administer products')) {
-      // Only add the product-tab for non-product pages:
-      if (db_result(db_query(db_rewrite_sql("SELECT COUNT(n.nid) FROM {node} n WHERE n.nid = %d AND n.type != 'product'"), arg(1))) > 0) {
-        $items[] = array(
-          'path' => 'node/'. arg(1) .'/product',
-          'title' => t('product'),
-          'callback' => 'product_to_product',
-          'access' => user_access('administer products'),
-          'type' => MENU_LOCAL_TASK,
-          'weight' => 2
-        );
-        $items[] = array(
-          'path' => 'node/'. arg(1) .'/product/delete',
-          'title' => t('delete product'),
-          'callback' => 'product_to_product_delete',
-          'access' => user_access('administer products'),
-          'type' => MENU_CALLBACK,
-        );
-      }
-    }
   }
 
   return $items;
@@ -343,21 +323,95 @@
  * Implementation of hook_form_alter()
  */
 function product_form_alter($form_id, &$form) {
-  if (isset($form['type'])) {
-    if ($form_id == $form['type']['#value'] .'_node_form') {
-      $form['ptype'] = array('#type' => 'value', '#value' => $form['#node']->ptype);
-    }
-    // Add a fieldset with links for configuring individual product types.
-    else if ($form_id == $form['type']['#value'] .'_node_settings') {
-      $form['product_types'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Configure product types'),
-        '#collapsible' => TRUE,
-        '#weight' => -10,
-        '#children' => product_types_configure()
-      );
+  if ($form['type'] && $form_id == $form['type']['#value'] . '_node_form') {
+    if (user_access('administer products') && $form['type']['#value'] != 'product') {
+      if ($form['#node']->ptype) {
+        $form['product'] = _product_transform_product_form($form['#node']);
+      }
+      $form['product_transform'] = _product_transform_form($form['#node']);
     }
   }
+  // Add a fieldset with links for configuring individual product types.
+  if ($form_id == $form['type']['#value'] . '_node_settings') {
+    $form['product_types'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Configure product types'),
+      '#collapsible' => TRUE,
+      '#weight' => -10,
+      '#children' => product_types_configure()
+    );
+  }
+}
+
+/**
+ * Generates product type options fieldset.
+ */
+function _product_transform_form(&$node) {
+  // Product type collapsed fieldset
+  $form = array(
+    '#type' => 'fieldset',
+    '#title' => t('Product'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE
+  );
+  // Choose a product type
+  $ptypes[FALSE] = array('name' => t('not a product'), 'help' => t('This item not for sale.'));
+  foreach (product_get_ptypes() as $key => $value) {
+    $ptypes[$key] = array(
+      'name' => $value,
+      'help' => module_invoke($key, 'help', 'node/add/product#' . $key)
+    );
+  }
+  // Display each radio option, with descriptive text
+  foreach ($ptypes as $key => $data) {
+    $form['ptype'][$key] = array(
+      '#type' => 'radio',
+      '#title' => $data['name'],
+      '#return_value' => $key,
+      '#default_value' => $node->ptype,
+      '#description' => $data['help'],
+      '#parents' => array('ptype'),
+     );
+  }
+  if ($node->ptype) {
+    // include a check box to make this node not a product
+    $form['product_remove'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Remove from store'),
+      '#description' => t('Check here to delete product information.  Takes effect when changes are submitted.')
+    );
+  }
+  else { 
+    $form['product_add'] = array(
+      '#type' => 'button',
+      '#value' => t('Add to store')
+    );
+  }
+  return $form;
+}
+
+/**
+ * Generates product form fields to be added into the node form.
+ */
+function _product_transform_product_form(&$node) {
+  // Get base form elements.
+  $form = product_base_form_elements($node);
+  // Get the product-type-specific bits.
+  $form = array_merge($form, (array) module_invoke($node->ptype, 'productapi', $node, 'form'));
+  // Add #after_build function to skip price validation
+  $form['#after_build'] = array('_product_transform_skip_validation');
+
+  return $form;
+}
+
+/**
+ * Skip price validation if we don't have submited price data.
+ */
+function _product_transform_skip_validation($form, $edit) {
+  if (!isset($_POST['edit']['price'])) {
+    unset($form['price']['#validate'], $form['price']['#needs_validation']);
+  }
+  return $form;
 }
 
 /**
@@ -409,20 +463,26 @@
         }
       }
       break;
+    case 'prepare':
+      if ($node->type != 'product' && !$node->ptype) {
+        $node->ptype = $_POST['edit']['ptype'];
+      }
+      break;
+
+    case 'validate':
+      if ($node->type != 'product' && $node->ptype) {
+        product_validate($node);
+      }
+      break;
 
     case 'insert':
     case 'update':
-      // copy the product to the next revision.
-      if ($node->type != 'product' && $node->revision) {
-        $last_vid = db_result(db_query('SELECT p.vid AS pvid FROM {node_revisions} r LEFT JOIN {ec_product} p ON r.vid = p.vid WHERE r.nid = %d AND r.vid <> %d ORDER BY r.vid DESC LIMIT 1', $node->nid, $node->vid));
-        if ($last_vid) {
-          $product->nid = $node->nid;
-          $product->vid = $last_vid;
-          if ($product = product_load($product)) {
-            $product->vid = $node->vid;
-            product_save($product);
-          }
-        }
+      if ($node->product_remove) {
+        // user has checked 'remove this item from store'.
+        product_delete($node);
+      }
+      else if ($node->ptype) {
+        product_save($node);
       }
       break;
  
@@ -679,98 +739,6 @@
   return theme('product_view_collection');
 }
 
-/**
- * Handles all product operations for non-product nodes.
- */
-function product_to_product() {
-  $op = $_POST['op'];
-  $node = node_load(arg(1));
-
-  if ($node->nid) {
-    drupal_set_title(t('%node-title (product)', array('%node-title' => $node->title)));
-    $product = db_fetch_object(db_query('SELECT * FROM {ec_product} WHERE vid = %d', $node->vid));
-    $ptypes = product_get_ptypes();
-    if ($product || (arg(3) && in_array(arg(3), array_keys($ptypes)))) {
-      $node->ptype = $node->ptype ? $node->ptype : arg(3);
-      $form = product_base_form_elements($node);
-      $form['#node'] = $node;
-      foreach (array('nid', 'vid', 'ptype') as $key) {
-        $form[$key] = array('#type' => 'value', '#value' => $node->$key);
-      }
-
-      $form = array_merge($form, (array)module_invoke($node->ptype, 'productapi', $node, 'form'));
-      if ($product) {
-        $form['update'] = array('#type' => 'submit', '#value' => t('Update product'), '#weight' => 40);
-        $form['remove'] = array('#type' => 'submit', '#value' => t('Remove product'), '#weight' => 45);
-      }
-      else {
-        $form['create'] = array('#type' => 'submit', '#value' => t('Create product'), '#weight' => 40);
-      }
-      return drupal_get_form('product_to_product', $form);
-    }
-    else {
-      return product_types_listing("node/$node->nid/product");
-    }
-  }
-}
-
-function product_to_product_validate($form_id, $form_values) {
-  $op = $_POST['op'];
-  $edit = (object) $form_values;
-
-  switch ($op) {
-    case t('Create product'):
-    case t('Update product'):
-      product_form_validate($edit);
-      break;
-  }
-}
-
-function product_to_product_submit($form_id, $form_values) {
-  $op = $_POST['op'];
-  $edit = (object) $form_values;
-
-  switch ($op) {
-    case t('Create product'):
-    case t('Update product'):
-      product_save($edit);
-      drupal_set_message(t('The product has been saved.'));
-      return "node/$edit->nid";
-      break;
-    case t('Remove product'):
-      //product_delete($edit, true);
-      //drupal_set_message(t('Removed the post from the product listings.'));
-      return "node/$edit->nid/product/delete";
-      break;
-  }
-}
-
-function product_to_product_delete() {
-  $node = node_load(arg(1));
-
-  $form['node'] = array('#type' => 'value', '#value' => $node);
-
-  $output.= confirm_form(
-    'product_to_product_delete',
-    $form,
-    t('Are you sure that you want to delete the product information for %title', array('%title' => $node->title)),
-    "node/{$node->nid}/product",
-    t('The product information will be permenantly removed.'),
-    t('Delete Product'),
-    t('Cancel')
-  );
-  return $output;
-}
-
-function product_to_product_delete_submit($form_id, $form_values) {
-  if ($form_values['confirm']) {
-    product_delete($form_values['node'], true);
-    drupal_set_message(t('Removed the post from the product listings.'));
-    return "node/{$form_values['node']->nid}";
-  }
-  return "node/{$form_values['node']->nid}/product";
-}
-
 function product_elements() {
   $items['product_price'] = array('#input' => true, '#validate' => array('valid_product_price' => array()));
 
