? .svn
? hook_feedapi_mapper.patch
? mappers/.svn
Index: feedapi_mapper.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/sandbox/alex_b/feedapi_mapper/feedapi_mapper.module,v
retrieving revision 1.21
diff -u -r1.21 feedapi_mapper.module
--- feedapi_mapper.module	12 Nov 2007 19:57:19 -0000	1.21
+++ feedapi_mapper.module	21 Nov 2007 21:57:13 -0000
@@ -92,7 +92,7 @@
         $element_path = unserialize($element_path);
         // Get the feed item element on $element_path and pass it into the mapping function.
         $feed_item_element = _feedapi_mapper_get_feed_item_element($element_path, $feed_item);
-        $node = call_user_func('feedapi_mapper_map_'. $field[0], 'map', $node, $feed_item_element, $field[1]);
+        $node = call_user_func($field[0] .'_feedapi_mapper', $field[1], 'map', $node, $feed_item_element, $field[2]);
       }
     }
   }
@@ -134,7 +134,8 @@
     $node_type_settings = _feedapi_get_settings(array('node_type' => $node->type));
     $feed_item_type = $node_type_settings['processors']['feedapi_node']['content_type'];
   }
-  $node_fields = _feedapi_mapper_get_fields($feed_item_type);
+  $field_mappers = _feedapi_mapper_get_field_mappers($feed_item_type);
+
   // Get elements of feed items.
   if ($merged_item = _feedapi_mapper_get_items_merged($node)) {
     $elements = _feedapi_mapper_get_feed_elements($merged_item);
@@ -157,7 +158,7 @@
       );
     $form['feed_item']['item'] = array(
       '#type' => 'markup',
-      '#value' => '<pre>'. print_r($merged_item, true) .'</pre>',
+      '#value' => '<pre>'. print_r(_feedapi_mapper_truncate_array($merged_item), true) .'</pre>',
       );
   }
   $form['nid'] = array(
@@ -166,13 +167,33 @@
     );
   // Pass on feed item elements.
   $form['elements'] = array('#type' => 'value', '#value' => $elements);
+  // Print descriptions if there are any.
+  if ($descriptions = theme('feedapi_mapper_descriptions', _feedapi_mapper_get_field_mappers_descriptions($feed_item_type))) {
+    $form['descriptions'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Description of available mappers'),
+      '#collapsible' => TRUE,
+      '#collapsed' => FALSE,
+      '#tree' => TRUE,
+      );  
+    $form['descriptions']['descriptions'] = array(
+      '#type' => 'markup',
+      '#value' => $descriptions,
+      );  
+  }
   // Create mapping form.
-  $form['mapping'] = array('#tree' => TRUE);
+  $form['mapping'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Edit mapping'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#tree' => TRUE,
+    );
   foreach ($elements as $element_name => $path) {
     $form['mapping'][$element_name] = array(
       '#type' => 'select',
       '#title' => $element_name,
-      '#options' => $node_fields,
+      '#options' => $field_mappers,
       '#default_value' => $mapping[$path],
       );
   }
@@ -193,11 +214,11 @@
 /**
  * Store mapping.
  * @param $param
- * node id or node type.
+ *   node id or node type.
  * @param $mapping
- * Mapping.
+ *   Mapping.
  * @param $elements
- * All elements of feed item.
+ *   All elements of feed item.
  */
 function _feedapi_mapper_store_mapping($param, $mapping, $elements) {
   // Wrap the mapping array (element_name => node_field)
@@ -263,6 +284,8 @@
     foreach($files as $file) {
       require_once("./$file->filename");
     }
+    // Rebuild cache.
+    module_implements('', FALSE, TRUE);
   }
   $loaded = TRUE;
 }
@@ -381,6 +404,22 @@
 }
 
 /**
+ * Truncates all strings in cascaded array.
+ */
+function _feedapi_mapper_truncate_array($array) {
+  foreach ($array as $k => $v) {
+    if (is_string($v)) {
+      $array[$k] = strip_tags($v);
+      $array[$k] = truncate_utf8($array[$k], 200, TRUE, TRUE);
+    }
+    else if (is_array($v)) {
+      $array[$k] = _feedapi_mapper_truncate_array($v);
+    }
+  }
+  return $array;
+}
+
+/**
  * Like array_merge_recursive. Only difference: does NOT merge 
  * two different keys into an array, but merges key on key.
  * Argument 1 always has to be an array.
@@ -408,32 +447,68 @@
 }
 
 /**
- * Get fields for a given node type.
+ * Get field mappers for a given node type. Returns an array of all 
+ * feed mappers that are applicable to this node type.
+ * @param $node_type
+ *   Valid node type.
+ * @return 
+ *   Array of fields that are mappable for this content type.
  */
-function _feedapi_mapper_get_fields($node_type) {
+function _feedapi_mapper_get_field_mappers($node_type) {
   // Not sure wether to take fields from node or from form...
   // Pro form: there might be elements on form that you can't see on node (?).
   $form = _feedapi_mapper_get_node_form($node_type);
   $node->type = $node_type;
-  $fields[0] = t('No mapping');
+  $field_mappers[0] = t('No mapping');
   // Load all available mappers and create an array of fields available as mapping target.
   _feedapi_mapper_load_mappers();
+  $modules = module_implements('feedapi_mapper');
   foreach ($form as $field_name => $field) {
-    if (function_exists('feedapi_mapper_map_'. $field_name)) {
-      if ($sub_fields = call_user_func('feedapi_mapper_map_'. $field_name, 'list', $node)) {
+    foreach ($modules as $module) {
+      if ($sub_fields = module_invoke($module, 'feedapi_mapper', $field_name, 'list', $node)) {
+        $field_category = t('Map to') .' '. $field_name .' '. t('(!module_name module)', array('!module_name' => $module));
         if (is_array($sub_fields)) {
-          $fields[$field_name] = array();
+          $field_mappers[$field_category] = array();
           foreach ($sub_fields as $sub_field_id => $sub_field_name) {
-            $fields[$field_name][serialize(array($field_name, $sub_field_id))] = $sub_field_name;
+            $field_mappers[$field_category][serialize(array($module, $field_name, $sub_field_id))] = $sub_field_name;
           }
         }
         else {
-          $fields[serialize(array($field_name))] = $field_name;
+          $field_mappers[serialize(array($module, $field_name))] = $field_category;
         }
       }
     }
   }
-  return $fields;
+  return $field_mappers;
+}
+
+/**
+ * Returns descriptions for all mappable fields of given node type.
+ * @return 
+ *   Array in the format 
+ *   array('field_name_a' => 
+ *          array('module_name_a' => 'Descriptive text'), 
+ *                'module_name_b' => ...),
+ *         'field_name_b' =>  array(...),
+ *         );
+ */
+function _feedapi_mapper_get_field_mappers_descriptions($node_type) {
+  // Not sure wether to take fields from node or from form...
+  // Pro form: there might be elements on form that you can't see on node (?).
+  $form = _feedapi_mapper_get_node_form($node_type);
+  $node->type = $node_type;
+  // Load all available mappers and create an array of fields available as mapping target.
+  _feedapi_mapper_load_mappers();
+  $modules = module_implements('feedapi_mapper');
+  $descriptions = array();
+  foreach ($form as $field_name => $field) {
+    foreach ($modules as $module) {
+      if ($description = module_invoke($module, 'feedapi_mapper', $field_name, 'describe', $node)) {
+        $descriptions[$field_name][$module] = $description;
+      }
+    }
+  }
+  return $descriptions;
 }
 
 function _feedapi_mapper_get_node_form($node_type) {
@@ -449,4 +524,23 @@
   drupal_process_form($form_id, $form);
   // return drupal_render_form($args[0], $form);
   return $form;
+}
+
+/**
+ * Theming function for outputting result of _feedapi_mapper_get_field_mappers_descriptions().
+ * @param $descriptions
+ *   Result of _feedapi_mapper_get_field_mappers_descriptions().
+ * @return 
+ *   HTML output.
+ */
+function theme_feedapi_mapper_descriptions($descriptions) {
+  $output .= '<dl>';
+  foreach ($descriptions as $field_mapper => $implementations) {
+    foreach ($implementations as $module => $description) {
+      $output .= '<dt><strong>'. $field_mapper .' '. t('(!module_name module)', array('!module_name' => $module)) .'</strong></dt>';
+      $output .= '<dd>'. $description .'</dd>';
+    }
+  }
+  $output .= '</dl>';
+  return $output;
 }
\ No newline at end of file
Index: mappers/feedapi_mapper_taxonomy.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/sandbox/alex_b/feedapi_mapper/mappers/feedapi_mapper_taxonomy.inc,v
retrieving revision 1.2
diff -u -r1.2 feedapi_mapper_taxonomy.inc
--- mappers/feedapi_mapper_taxonomy.inc	12 Nov 2007 19:57:21 -0000	1.2
+++ mappers/feedapi_mapper_taxonomy.inc	21 Nov 2007 21:57:13 -0000
@@ -22,29 +22,34 @@
  * Heads up: for doing this, we will need to return a destinct name on 'list' or we use the 
  * module name.
  */
-function feedapi_mapper_map_taxonomy($op = 'map', $node, $feed_element = array(), $sub_field = '') {
-  if ($op == 'list') {
-    if ($vocabularies = taxonomy_get_vocabularies($node->type)) {
-      foreach ($vocabularies as $v) {
-        $sub_fields[$v->vid] = $v->name;
-      }
-      return $sub_fields;
+function taxonomy_feedapi_mapper($field, $op = 'map', $node, $feed_element = array(), $sub_field = '') {
+  if ($field == 'taxonomy') {
+    if ($op == 'describe') {
+      return t('Maps a string or an array of strings to taxonomy terms. Chose a vocabulary from sub options.');
     }
-    return FALSE;
-  }
-  else if ($op == 'map') {
-    // Todo: some plausibility check of $feed_element
-    // Todo: security check of $feed_element
-    if (is_string($feed_element)) {
-      $feed_element = array($feed_element);
+    else if ($op == 'list') {
+      if ($vocabularies = taxonomy_get_vocabularies($node->type)) {
+        foreach ($vocabularies as $v) {
+          $sub_fields[$v->vid] = $v->name;
+        }
+        return $sub_fields;
+      }
+      return FALSE;
     }
-    if (is_array($feed_element)) {
-      if (!is_array($node->taxonomy)) {
-        $node->taxonomy = array();
+    else if ($op == 'map') {
+      // Todo: some plausibility check of $feed_element
+      // Todo: security check of $feed_element
+      if (is_string($feed_element)) {
+        $feed_element = array($feed_element);
+      }
+      if (is_array($feed_element)) {
+        if (!is_array($node->taxonomy)) {
+          $node->taxonomy = array();
+        }
+        $node->taxonomy = array_merge($node->taxonomy, _feedapi_mapper_create_terms($feed_element, $sub_field));
       }
-      $node->taxonomy = array_merge($node->taxonomy, _feedapi_mapper_create_terms($feed_element, $sub_field));
+      return $node;
     }
-    return $node;
   }
 }
 
