Index: feedapi_mapper.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/Attic/feedapi_mapper.admin.inc,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 feedapi_mapper.admin.inc
--- feedapi_mapper.admin.inc	4 Aug 2009 20:03:52 -0000	1.1.2.1
+++ feedapi_mapper.admin.inc	5 Aug 2009 14:12:40 -0000
@@ -27,19 +27,32 @@ function theme_feedapi_mapper_descriptio
  */
 function theme_feedapi_mapper_form($form) {
   $output = '';
-
+  _feedapi_mapper_load_mappers();
   $type_url_str = str_replace('_', '-', $form['#node']->type);
-  $url = isset($form['#node']->nid) ?
+  $url_delete = isset($form['#node']->nid) ?
     'node/' . $form['#node']->nid .'/map/delete/' :
     'admin/content/node-type/'. $type_url_str .'/map/delete/';
+  $url_toggle_unique = isset($form['#node']->nid) ?
+    'node/' . $form['#node']->nid .'/map/unique/' :
+    'admin/content/node-type/'. $type_url_str .'/map/unique/';
   if (isset($form['#mapping']['mapping'])) {
     foreach ($form['#mapping']['mapping'] as $feed_path => $node_path) {
+      $target = unserialize($node_path);
+      if (function_exists($target[0] .'_feedapi_mapper')) {
+        $unique_supported = call_user_func($target[0] .'_feedapi_mapper', 'unique supported', $form['#node'], NULL, $target[1]);
+        if ($unique_supported === TRUE) {
+          $unique = $form['#mapping']['unique'][$feed_path] ? l(t('Yes'), $url_toggle_unique . base64_encode($feed_path)) : l(t('No'), $url_toggle_unique . base64_encode($feed_path));
+        }
+        else {
+          $unique = 'N/A';
+        }
+      }
       $rows[] = array(
         // @todo: Set proper messages.
         isset($form['#feed_map'][$feed_path]) ? $form['#feed_map'][$feed_path] : '',
         isset($form['#field_map'][$node_path]) ? $form['#field_map'][$node_path] : t('<em>Error: missing target.</em>'),
-        $form['#mapping']['unique'][$feed_path] ? t('Yes') : t('No'),
-        l(t('Delete'), $url . base64_encode($feed_path)),
+	$unique,
+        l(t('Delete'), $url_delete . base64_encode($feed_path)),
       );
     }
   }
@@ -96,6 +109,28 @@ function feedapi_mapper_delete_form_subm
 }
 
 /**
+ * Toggles the value of the unique-ness of the given key
+ * @see theme_feedapi_mapper_form()
+ */
+function feedapi_mapper_unique_toggle($param, $encoded_key) {
+  $key = base64_decode($encoded_key);
+  if (is_string($param)) {
+    $node = new stdClass();
+    $node->type = str_replace('-', '_', $param);
+    $path = 'admin/content/node-type/'. $param .'/map';
+  }
+  else {
+    $node = $param;
+    $path = "node/{$node->nid}/map";
+    $param = $node->nid;
+  }
+  $mapping = feedapi_mapper_load_mapping($node);
+  feedapi_mapper_delete_mapping($param, $key);
+  feedapi_mapper_add_mapping($param, $key, $mapping['mapping'][$key], !$mapping['unique'][$key]);
+  drupal_goto($path);
+}
+
+/**
  * Form callback confirmation form for fall back to default.
  */
 function feedapi_mapper_default_form($form_state, $feed_node) {
@@ -234,9 +269,6 @@ function feedapi_mapper_form($form_state
     '#type' => 'select',
     '#options' => $field_map_options,
   );
-  $form['unique'] = array(
-    '#type' => 'checkbox',
-  );
   $form['add'] = array(
     '#type' => 'submit',
     '#value' => t('Add'),
@@ -306,5 +338,5 @@ function feedapi_mapper_form_validate($f
  */
 function feedapi_mapper_form_submit($form, &$form_state) {
   $param = ($form['#node']->nid && $form['#override']) ? $form['#node']->nid : $form['#node']->type;
-  feedapi_mapper_add_mapping($param, $form_state['values']['source'], $form_state['values']['target'], $form_state['values']['unique']);
+  feedapi_mapper_add_mapping($param, $form_state['values']['source'], $form_state['values']['target'], FALSE);
 }
Index: feedapi_mapper.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/feedapi_mapper.module,v
retrieving revision 1.2.2.14
diff -u -p -r1.2.2.14 feedapi_mapper.module
--- feedapi_mapper.module	4 Aug 2009 20:03:52 -0000	1.2.2.14
+++ feedapi_mapper.module	5 Aug 2009 14:12:40 -0000
@@ -36,6 +36,13 @@ function feedapi_mapper_menu() {
     'access arguments' => array(1),
     'file' => 'feedapi_mapper.admin.inc',
   );
+  $items['node/%node/map/unique/%'] = array(
+    'page callback' => 'feedapi_mapper_unique_toggle',
+    'page arguments' => array(1, 4),
+    'access callback' => 'feedapi_mapper_access_mapper',
+    'access arguments' => array(1),
+    'file' => 'feedapi_mapper.admin.inc',
+  );
   $items['node/%node/map/default'] = array(
     'title' => 'Default',
     'page callback' => 'drupal_get_form',
@@ -76,6 +83,14 @@ function feedapi_mapper_menu() {
       'access arguments' => array(3),
       'file' => 'feedapi_mapper.admin.inc',
     );
+    $items['admin/content/node-type/'. $type_url_str .'/map/unique/%'] = array(
+      'page callback' => 'feedapi_mapper_unique_toggle',
+      'page arguments' => array(3, 6),
+      'load arguments' => array(3),
+      'access callback' => 'feedapi_mapper_access_mapper',
+      'access arguments' => array(3),
+      'file' => 'feedapi_mapper.admin.inc',
+    );
   }
   return $items;
 }
@@ -179,6 +194,23 @@ function feedapi_mapper_map($feed_node, 
 }
 
 /**
+ * Collects the ids of the duplicated items of $item
+ */
+function feedapi_mapper_unique($feed_node, $item) {
+  _feedapi_mapper_load_mappers();
+  $uniques = feedapi_mapper_get_uniques($feed_node);
+  $fields_ids = array();
+  foreach ($uniques as $unique) {
+    $feed_item_element = feedapi_mapper_get_element($unique['source'], _feedapi_mapper_obj2array($item));
+    $fields_ids[] = call_user_func($unique['target'][0] .'_feedapi_mapper', 'unique', $feed_node, NULL, $feed_item_element, $unique['target'][1]);
+  }
+  if (count($fields_ids) < 2) {
+    return array_pop($fields_ids);
+  }
+  return call_user_func_array('array_intersect', $fields_ids);
+}
+
+/**
  * Returns paths to unique feed elements.
  * 
  * @param $feed_node
