Index: uc_upsell_admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_upsell/Attic/uc_upsell_admin.inc,v
retrieving revision 1.1.2.11
diff -u -p -r1.1.2.11 uc_upsell_admin.inc
--- uc_upsell_admin.inc	13 Jun 2009 08:09:15 -0000	1.1.2.11
+++ uc_upsell_admin.inc	1 Jul 2009 00:45:10 -0000
@@ -29,7 +29,7 @@ function uc_upsell_form_alter(&$form, $f
       }
 
       // Alphabetize the array (since there's no telling by nid)
-      (is_array($current_products)) ? asort($current_products) : '' ;
+      (is_array($current_prods_array)) ? asort($current_prods_array) : '' ;
 
       // Get product types
       $config = uc_upsell_get_config();
@@ -62,6 +62,7 @@ function uc_upsell_form_alter(&$form, $f
         );
 
       $form['base']['relatedProducts'] = $assoc_form;
+      $form['#submit'] = array_merge(array('uc_upsell_form_submit'), $form['#submit']);
     }
   }
 }
@@ -76,88 +77,123 @@ function uc_upsell_form_alter(&$form, $f
  *  Ex: When editing Product A, add Product B as related.
  *  Upon form submission, uc_upsell also adds Product A to Product B's list of related products.
  */
-function uc_upsell_form_submit(&$node) {
+function uc_upsell_form_submit(&$form, $form_state) {
   global $user;
 
-  // Get list of product types
-  $product_types = array_keys(uc_product_node_info());
-  // Include product kits also
-  $product_types[] = 'product_kit';
-
-  // Create an array of selected related products and add the current product to the related products lists for each of them
-  if (in_array($node->type, $product_types) && is_array($node->relatedProducts)) {
-
-    foreach ($node->relatedProducts as $product) {
-      $ary = array();
-      $ary[] = $node->nid;
-      $products[] = $product;
+  // Insert and update nids from form for this particular node.
+  $reciprocals = uc_upsell_relateds_relate($form_state['values']['nid'], $form_state['values']['relatedProducts']);
 
-      $related = db_result(db_query("SELECT related_products FROM {uc_upsell_products} WHERE nid = %d", $product));
+  // Insert reciprocals; include source $nid
+  uc_upsell_reciprocals_relate($form_state['values']['nid'], $reciprocals);
 
-      if (!$related) {
-        db_query("INSERT INTO {uc_upsell_products} (nid, related_products) VALUES (%d, '%s')", $product, serialize($node->nid));
-      }
-      else {
-        if (is_array($ary)) {
-          if (is_array(unserialize($related))) {
-            $related = unserialize($related);
-            $ary = array_merge($ary, $related);
-            $ary = array_unique($ary);
-            $ary = serialize($ary);
-          }
-        }
-        db_query("UPDATE {uc_upsell_products} SET related_products = '%s' WHERE nid = %d", $ary, $product);
-      }
+  drupal_set_message(t('Related products were updated for node '.$form_state['values']['nid']));
+ // drupal_set_message(t('Included reciprocal assocations for: ');
+}
+
+
+/**
+ * Insert or update the db with related products for a particular node
+ * @param $nid
+ *   The current node id of the product we are updating
+ * @param $products
+ *   An array of product nids to associate with $nid
+ * @return array $reciprocals
+ *   Return an array of the reciprocal nids associated with this product, so we can go through and add their relationships
+ */
+function uc_upsell_relateds_relate($nid, $products) {
+  // Init the array to return
+  $reciprocals = array();
+
+  // Init the array of reciprocals to update
+  $updatenids = array();
+
+  // First, get an array of the nids currently associated with the product.
+  $currentnids = _uc_upsell_get_related($nid);
+
+  // If we get a result of current nids, unserialize so we can do array comparisons.
+  if (is_array($currentnids) && count($currentnids) > 0) {
+
+    // Take the difference of the current nids vs. the newly-selected ones
+    $remove_array = array_diff($products, $currentnids);
+
+    // Go through each related nid and remove its association with the current node
+    foreach ($remove_array as $remove) {
+      //dsm('removed nid '.$remove);
+      _uc_upsell_remove_related($remove, $nid);
     }
+  }
 
-    // Loop through the array of associate nodes and update them with the whole array.
-    if (is_array($products) && count($products > 0)) {
-      foreach ($products AS $key => $value) {
-        $currentnids = db_result(db_query("SELECT related_products FROM {uc_upsell_products} WHERE nid = %d", $value));
-        if (is_array(unserialize($currentnids))) {
-          $merge = array_merge(unserialize($currentnids), $products);
-          //drupal_set_message('current: '.print_r($currentnids ,true));
-          //drupal_set_message('should update '.print_r($value, true).' with '.print_r($merge,true));
-          db_query("UPDATE {uc_upsell_products} SET related_products = '%s' WHERE nid = %d", serialize($merge), $value);
-        }
-      }
+  // Now let's insert or update the db for the current nid
+  if (is_array($products) && count($products) > 0) {
+    $products = array_unique($products);
+    // Decide whether we are updating the related products entry or inserting a new one.
+    if (!$currentnids) {
+      db_query("INSERT INTO {uc_upsell_products} (nid, related_products) VALUES (%d, '%s')", $nid, serialize($products));
     }
+    else {
+      db_query("UPDATE {uc_upsell_products} SET `related_products` = '%s' WHERE `nid` = %d", serialize($products), $nid);
+    }
+  }
+  return $products;
+}
 
-    // Get the list of related products for the current product
-    $currentnids = db_result(db_query("SELECT related_products FROM {uc_upsell_products} WHERE nid = %d", $node->nid));
 
-    if (is_array(unserialize($currentnids)) && count(unserialize($currentnids)) > 0) {
-      $currentnids = unserialize($currentnids);
-      // Delete current product from the related products list for any products that are being removed
-      foreach ($currentnids as $currentnid) {
-        if (!in_array($currentnid, $products)) {
-          $nidarray = array();
-          $nidarray[] = $node->nid;
-          $updatenids = db_result(db_query("SELECT related_products FROM {uc_upsell_products} WHERE nid = %d", $currentnid));
-          if (is_array(unserialize($updatenids)) && count(unserialize($updatenids)) > 0) {
-            $updatenids = array_unique(unserialize($updatenids));
-            $updatenids = array_diff($updatenids, $nidarray);
-          }
-          db_query("UPDATE {uc_upsell_products} SET related_products = '%s' WHERE nid = %d", serialize($updatenids), $currentnid);
-        }
-      }
-    }
+/**
+ * Update a node's reciprocal products
+ *
+ * @param $nid
+ *   The source node id of the original node (from a form submit)
+ * @param $reciprocals
+ *   The returned, updated array of $nids which comprise the reciprocal nodes
+ */
+function uc_upsell_reciprocals_relate($nid = array(), $reciprocals = array()) {
 
-    if (is_array($products) && count($products) > 0) {
-      // Decide whether we are updating the related products entry or inserting a new one.
-      if (!db_result(db_query("SELECT related_products FROM {uc_upsell_products} WHERE nid = %d", $node->nid))) {
-        db_query("INSERT INTO {uc_upsell_products} (nid, related_products) VALUES (%d, '%s')", $node->nid, serialize($products));
-      }
-      else {
-        db_query("UPDATE {uc_upsell_products} SET `related_products` = '%s' WHERE `nid` = %d", serialize($products), $node->nid);
-      }
-      drupal_set_message(t('Related products were updated.'));
-    }
+  $family = array_merge((array)$nid, $reciprocals);
+  //dsm('family: '.print_r($family, true));
 
+  // Examine each nid in $reciprocals
+  foreach ($reciprocals as $product) {
+    if ($product != $nid) {
+      // Get the current related array for this reciprocal (or create a blank array if there are none)
+      $currentnids = _uc_upsell_get_related($product);
+      if (!is_array($currentnids)) $currentnids = array();
+
+      $newfamily = array_diff($family, (array)$product);
+      //dsm('adjusted family for '.$product.print_r($newfamily, true));
+
+      // Create an array that combines the current nids of this product with the source nid
+
+      $updatenids = array_unique(array_merge($currentnids, $newfamily));
+      uc_upsell_relateds_relate($product, $updatenids);
+      //dsm ('updated node '.$product.' with '.print_r($updatenids, true));
+      //dsm('RECIP: '.$product);
+    }
   }
 }
 
 
+function _uc_upsell_get_related($nid) {
+  $currentnids = db_result(db_query("SELECT related_products FROM {uc_upsell_products} WHERE nid = %d", $nid));
+  return unserialize($currentnids);
+}
+
+/**
+ * @param $removed
+ *   The nid of the node whose db table we are updating
+ * @param $nid
+ *   The nid of the product to remove from the array
+ */
+function _uc_upsell_remove_related($nid, $removed) {
+  $currentnids = _uc_upsell_get_related($nid);
+
+  if (is_array($currentnids)) {
+    if (!is_array($removed)) $removed = array($removed);
+
+    // Get the array minus the nid to be removed and update the db
+    $updatenids = array_diff($currentnids, $removed);
+    db_query("UPDATE {uc_upsell_products} SET related_products = '%s' WHERE nid = %d", serialize($updatenids), $nid);
+  }
+}
 /**
  * Administer the related products area
  */
@@ -381,6 +417,7 @@ function uc_upsell_settings_form() {
   return $form;
 }
 
+
 /**
  * Submit the settings form
  */
