? 397682_mappers_define_targets.patch
Index: feedapi_mapper.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/feedapi_mapper.module,v
retrieving revision 1.1.2.7.2.24
diff -u -p -r1.1.2.7.2.24 feedapi_mapper.module
--- feedapi_mapper.module	11 Apr 2009 00:16:36 -0000	1.1.2.7.2.24
+++ feedapi_mapper.module	14 Apr 2009 12:09:42 -0000
@@ -135,7 +135,7 @@ function _feedapi_mapper_map(&$node) {
         $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($field[0] .'_feedapi_mapper', 'map', $node, $field[1], $feed_item_element, isset($field[2]) ? $field[2] : NULL);
+        $node = call_user_func($field[0] .'_feedapi_mapper', 'map', $node, $feed_item_element, $field[1], isset($field[2]) ? $field[2] : NULL);
       }
     }
   }
@@ -551,16 +551,16 @@ function _feedapi_mapper_array_merge_rec
  *   Array of fields that are mappable for this content type.
  */
 function _feedapi_mapper_get_field_mappers($node_type) {
-  $field_names = _feedapi_mapper_get_field_names($node_type);
+  $node = new stdClass();
   $node->type = $node_type;
   $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 ($field_names as $field_name) {
-    foreach ($modules as $module) {
-      if ($sub_fields = module_invoke($module, 'feedapi_mapper', 'list', $node, $field_name)) {
+  foreach ($modules as $module) {
+    if ($fields = module_invoke($module, 'feedapi_mapper', 'list', $node)) {
+      foreach ($fields as $field_name => $sub_fields) {
         $field_category = t('Map to @field (@module)', array('@field' => $field_name, '@module' => $module));
         if (is_array($sub_fields)) {
           foreach ($sub_fields as $sub_field_id => $sub_field_name) {
@@ -588,88 +588,16 @@ function _feedapi_mapper_get_field_mappe
  *         );
  */
 function _feedapi_mapper_get_field_mappers_descriptions($node_type) {
-  $field_names = _feedapi_mapper_get_field_names($node_type);
+  $node = new stdClass();
   $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 ($field_names as $field_name) {
-    foreach ($modules as $module) {
-      if ($description = module_invoke($module, 'feedapi_mapper', 'describe', $node, $field_name)) {
-        $descriptions[$field_name][$module] = $description;
-      }
+  foreach ($modules as $module) {
+    if ($description = module_invoke($module, 'feedapi_mapper', 'describe', $node)) {
+      $descriptions[$field_name][$module] = $description;
     }
   }
   return $descriptions;
 }
-
-function _feedapi_mapper_get_node_form($node_type) {
-  $form_id = $node_type .'_node_form';
-  $node = new stdClass();
-  $node->type = $node_type;
-  $node->name = NULL; // prevent PHP notice from node_form()
-
-  // Borrow this from CCK:
-  // Some modules (userreview...) "hide" their node forms, resulting in no field
-  // being listed. We set a special flag to inform them this form is special.
-  $node->cck_dummy_node_form = TRUE;
-
-  // Include node.pages.inc which contains the node_form definitions.
-  include_once(drupal_get_path('module', 'node') .'/node.pages.inc');
-  $form_state = array('storage' => NULL, 'submitted' => FALSE);
-  $form = drupal_retrieve_form($form_id, $form_state, $node);
-  drupal_prepare_form($form_id, $form, $form_state);
-
-  return $form;
-}
-
-/**
- * Retrieve all field names on a given node type.
- *
- * @todo:
- * This is still somewhat of a cooking recipe and e. g. does not expose teaser nor body filter,
- * as they are not present as such neither on the form nor in the node of the initial form.
- *
- * If there are suggestions on how to improve this routine, I'd be happy to know them.
- */
-function _feedapi_mapper_get_field_names($node_type) {
-  static $field_names;
-  if (!is_array($field_names[$node_type])) {
-    $form = _feedapi_mapper_get_node_form($node_type);
-
-    $node = (array)$form['#node'];
-    $node['taxonomy'] = array();
-    $fields = array_merge($form, $node);
-    $field_names[$node_type] = _feedapi_mapper_extract_names($fields);
-    
-    // Make sure CCK fields in unexpected locations get added.
-    if (function_exists('content_types')) {
-      $node_fields = content_types($node_type);
-      $cck_fields = array_keys($node_fields['fields']);
-      $field_names[$node_type] = array_merge($field_names[$node_type], $cck_fields);
-    }
-    sort($field_names[$node_type]);
-  }
-  return $field_names[$node_type];
-}
-
-/**
- * Recursively get the possible field names from the form structure.
- */
-function _feedapi_mapper_extract_names($fields) {
-  $names = array();
-  foreach ($fields as $k => $v ) {
-    if (strpos($k, '#') === FALSE) {
-      if (isset($v['#type'])) {
-        if ($v['#type'] == 'fieldset') {
-          $names = array_merge($names, _feedapi_mapper_extract_names($v));
-        }
-      }
-      else {
-        $names[] = $k;
-      }
-    }
-  }
-  return $names;
-}
Index: mappers/feedapi_mapper_content.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/mappers/Attic/feedapi_mapper_content.inc,v
retrieving revision 1.1.2.4.2.3
diff -u -p -r1.1.2.4.2.3 feedapi_mapper_content.inc
--- mappers/feedapi_mapper_content.inc	11 Apr 2009 00:43:45 -0000	1.1.2.4.2.3
+++ mappers/feedapi_mapper_content.inc	14 Apr 2009 12:09:42 -0000
@@ -6,55 +6,37 @@
  *
  * @see hook_feedapi_mapper()
  */
-function content_feedapi_mapper($op, $node, $field_name, $feed_element = array(), $sub_field = '') {
+function content_feedapi_mapper($op, $node, $feed_element = array(), $field_name = '', $sub_field = '') {
   // Test for the node field that we would like to map to.
-  if (strpos($field_name, 'field_') === 0) {
-    if ($op == 'describe') {
-      // Describe what we are doing in this mapper. This shows up as help text on the mapping page.
-      if (feedapi_mapper_content_is_cck_type($field_name, array('text', 'number_integer', 'number_decimal'))) {
-        return t('Maps a string or a number to this CCK field.');
-      }
-    }
-    else if ($op == 'list') {
-      // Here we are being asked to list sub fields we would like to map to.
-      if (feedapi_mapper_content_is_cck_type($field_name, array('text', 'number_integer', 'number_decimal'))) {
-        return TRUE;
+  if ($op == 'describe') {
+    return t('Maps a string or a number to this CCK field.');
+  }
+  else if ($op == 'list') {
+    $info = content_types($node->type);
+    $fields = array();
+    if (@count($info['fields'])) {
+      foreach ($info['fields'] as $field_name => $field) {
+        if (in_array($field['type'], array('text', 'number_integer', 'number_decimal'))) {
+          $fields[$field_name] = $field_name;
+        }
       }
-      return FALSE;
     }
-    else if ($op == 'map') {
-      // Here is where the actual mapping happens.
-      // When we are called at this point, $field_name contains the name of the field the user has
-      // decided to map to and $field_element is the feed item element the user has decided to map.
-      // We just need to put the two things together. The data structure here depends a lot on
-      // CCK. We stick the value in $feed_element into $node->$field_name[0]['value'].
-      if (!is_array($feed_element)) {
-        $field = isset($node->$field_name) ? $node->$field_name : array();
-        $field[0]['value'] = $feed_element;
-        $node->$field_name = $field;
-      }
-      return $node;
+    if (count($fields)) {
+      return $fields;
     }
-  }
-}
-
-/**
- * Determines if a given field is of a given type
- *
- * @param string $node_type
- *   Drupal content type.
- * @param string $field_name
- *   Name of the field to determine the type of.
- * @param array $field_types
- *   Array of field types that should be tested for.
- * @return unknown
- */
-function feedapi_mapper_content_is_cck_type($field_name, $field_types) {
-  $field = content_fields($field_name);
-  if (in_array($field['type'], $field_types)) {
-    return $field;
-  }
-  else {
     return FALSE;
   }
+  else if ($op == 'map') {
+    // Here is where the actual mapping happens.
+    // When we are called at this point, $field_name contains the name of the field the user has
+    // decided to map to and $field_element is the feed item element the user has decided to map.
+    // We just need to put the two things together. The data structure here depends a lot on
+    // CCK. We stick the value in $feed_element into $node->$field_name[0]['value'].
+    if (!is_array($feed_element)) {
+      $field = isset($node->$field_name) ? $node->$field_name : array();
+      $field[0]['value'] = $feed_element;
+      $node->$field_name = $field;
+    }
+    return $node;
+  }
 }
\ No newline at end of file
Index: mappers/feedapi_mapper_date.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/mappers/Attic/feedapi_mapper_date.inc,v
retrieving revision 1.1.2.3.2.4
diff -u -p -r1.1.2.3.2.4 feedapi_mapper_date.inc
--- mappers/feedapi_mapper_date.inc	11 Apr 2009 00:43:45 -0000	1.1.2.3.2.4
+++ mappers/feedapi_mapper_date.inc	14 Apr 2009 12:09:42 -0000
@@ -6,7 +6,7 @@
  *
  * @see hook_feedapi_mapper()
  */
-function date_feedapi_mapper($op, &$node, $field_name, $feed_element = array(), $sub_field = '') {
+function date_feedapi_mapper($op, $node, $feed_element = array(), $field_name = '', $sub_field = '') {
   if (!$field = feedapi_mapper_content_is_cck_type($field_name, array('date', 'datestamp', 'datetime'))) {
     // if not a date just return
     return;
Index: mappers/feedapi_mapper_emimage.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/mappers/Attic/feedapi_mapper_emimage.inc,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 feedapi_mapper_emimage.inc
--- mappers/feedapi_mapper_emimage.inc	11 Apr 2009 00:43:45 -0000	1.1.2.2
+++ mappers/feedapi_mapper_emimage.inc	14 Apr 2009 12:09:42 -0000
@@ -6,7 +6,7 @@
  *
  * @see hook_feedapi_mapper()
  */
-function emimage_feedapi_mapper($op, $node, $field_name, $feed_element = array(), $sub_field = '') {
+function emimage_feedapi_mapper($op, $node, $feed_element = array(), $field_name = '', $sub_field = '') {
   $field = content_fields($field_name);
   if ($field['type'] != 'emimage') {
     // if not an emvideo field just return
Index: mappers/feedapi_mapper_emvideo.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/mappers/Attic/feedapi_mapper_emvideo.inc,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 feedapi_mapper_emvideo.inc
--- mappers/feedapi_mapper_emvideo.inc	11 Apr 2009 00:43:45 -0000	1.1.2.2
+++ mappers/feedapi_mapper_emvideo.inc	14 Apr 2009 12:09:42 -0000
@@ -6,7 +6,7 @@
  *
  * @see hook_feedapi_mapper()
  */
-function emvideo_feedapi_mapper($op, $node, $field_name, $feed_element = array(), $sub_field = '') {
+function emvideo_feedapi_mapper($op, $node, $feed_element = array(), $field_name = '', $sub_field = '') {
   $field = content_fields($field_name);
   if ($field['type'] != 'emvideo') {
     // if not an emvideo field just return
Index: mappers/feedapi_mapper_link.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/mappers/Attic/feedapi_mapper_link.inc,v
retrieving revision 1.1.2.4.2.2
diff -u -p -r1.1.2.4.2.2 feedapi_mapper_link.inc
--- mappers/feedapi_mapper_link.inc	11 Apr 2009 00:43:45 -0000	1.1.2.4.2.2
+++ mappers/feedapi_mapper_link.inc	14 Apr 2009 12:09:42 -0000
@@ -6,35 +6,37 @@
  * 
  * @see hook_feedapi_mapper()
  */
-function link_feedapi_mapper($op, $node, $field_name, $feed_element = array(), $sub_field = '') {
+function link_feedapi_mapper($op, $node, $feed_element = array(), $field_name = '', $sub_field = '') {
   // Test for the node field that we would like to map to.
-  if (strpos($field_name, 'field_') === 0) {
-    if ($op == 'describe') {
-      if (feedapi_mapper_content_is_cck_type($field_name, array('link'))) {
-        return t('Maps a URL to this link CCK field.');
+  if ($op == 'describe') {
+    return t('Maps a URL to this link CCK field.');
+  }
+  else if ($op == 'list') {
+    $info = content_types($node->type);
+    $fields = array();
+    if (@count($info['fields'])) {
+      foreach ($info['fields'] as $field_name => $field) {
+        if (in_array($field['type'], array('link'))) {
+          $fields[$field_name] = $field_name;
+        }
       }
-      // Describe what we are doing in this mapper. This shows up as help text on the mapping page.
     }
-    else if ($op == 'list') {
-      if (feedapi_mapper_content_is_cck_type($field_name, array('link'))) {
-        return TRUE;
-      }
-      // Here we are being asked to list sub fields we would like to map to.
-      // In this case, we only map to the CCK field or not, so we return just TRUE.
-      return FALSE;
+    if (count($fields)) {
+      return $fields;
     }
-    else if ($op == 'map') {
-      // Here is where the actual mapping happens.
-      // When we are called at this point, $field_name contains the name of the field the user has
-      // decided to map to and $field_element is the feed item element the user has decided to map.
-      // We just need to put the two things together. The data structure here depends a lot on
-      // CCK. We stick the value in $feed_element into $node->$field_name[0]['value'].
-      if (!is_array($feed_element)) {
-        $field = $node->$field_name;
-        $field[0]['url'] = link_validate_url($feed_element) ? $feed_element : NULL;
-        $node->$field_name = $field;
-        return $node;
-      }
+    return FALSE;
+  }
+  else if ($op == 'map') {
+    // Here is where the actual mapping happens.
+    // When we are called at this point, $field_name contains the name of the field the user has
+    // decided to map to and $field_element is the feed item element the user has decided to map.
+    // We just need to put the two things together. The data structure here depends a lot on
+    // CCK. We stick the value in $feed_element into $node->$field_name[0]['value'].
+    if (!is_array($feed_element)) {
+      $field = $node->$field_name;
+      $field[0]['url'] = link_validate_url($feed_element) ? $feed_element : NULL;
+      $node->$field_name = $field;
+      return $node;
     }
   }
 }
Index: mappers/feedapi_mapper_location.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/mappers/Attic/feedapi_mapper_location.inc,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 feedapi_mapper_location.inc
--- mappers/feedapi_mapper_location.inc	11 Apr 2009 00:43:45 -0000	1.1.2.2
+++ mappers/feedapi_mapper_location.inc	14 Apr 2009 12:09:42 -0000
@@ -6,7 +6,7 @@
  * 
  * @see hook_feedapi_mapper()
  */
-function location_feedapi_mapper($op, $node, $field_name, $feed_element = array(), $sub_field = '') {
+function location_feedapi_mapper($op, $node, $feed_element = array(), $field_name = '', $sub_field = '') {
   if ($field_name == 'locations' && variable_get('location_maxnum_'. $node->type, 0)) {
     if ($op == 'describe') {
       return t('Maps pairs of geographic coordinates to the location of a node.');
Index: mappers/feedapi_mapper_node.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/mappers/Attic/feedapi_mapper_node.inc,v
retrieving revision 1.1.2.3
diff -u -p -r1.1.2.3 feedapi_mapper_node.inc
--- mappers/feedapi_mapper_node.inc	11 Apr 2009 00:43:45 -0000	1.1.2.3
+++ mappers/feedapi_mapper_node.inc	14 Apr 2009 12:09:42 -0000
@@ -12,7 +12,7 @@
  * - if default mapping is removed, nothing is mapped to target (= e. g. body 
  *   stays empty)
  */
-function node_feedapi_mapper($op, $node, $field_name, $feed_element = array(), $sub_field = '') {
+function node_feedapi_mapper($op, $node, $feed_element = array(), $field_name = '', $sub_field = '') {
   if (in_array($field_name, array('title', 'body', 'created'))) {
     if ($op == 'describe') {
       return t('Maps a feed element to a title, created date or a body of a node. Note that standard field mapping by FeedAPI still applies. For example if there is no feed element mapped to the node body you will still find the description in node body because that is how FeedAPI stores nodes.');
Index: mappers/feedapi_mapper_taxonomy.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/mappers/feedapi_mapper_taxonomy.inc,v
retrieving revision 1.1.4.3
diff -u -p -r1.1.4.3 feedapi_mapper_taxonomy.inc
--- mappers/feedapi_mapper_taxonomy.inc	11 Apr 2009 00:43:45 -0000	1.1.4.3
+++ mappers/feedapi_mapper_taxonomy.inc	14 Apr 2009 12:09:42 -0000
@@ -6,34 +6,32 @@
  * 
  * @see hook_feedapi_mapper()
  */
-function taxonomy_feedapi_mapper($op, $node, $field_name, $feed_element = array(), $sub_field = '') {
-  if ($field_name == 'taxonomy') {
-    if ($op == 'describe') {
-      return t('Maps a string or an array of strings to taxonomy terms. Chose a vocabulary from sub options.');
-    }
-    else 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($op, $node, $feed_element = array(), $field_name = '', $sub_field = '') {
+  if ($op == 'describe') {
+    return t('Maps a string or an array of strings to taxonomy terms. Chose a vocabulary from sub options.');
+  }
+  else if ($op == 'list') {
+    if ($vocabularies = taxonomy_get_vocabularies($node->type)) {
+      foreach ($vocabularies as $v) {
+        $sub_fields[$v->vid] = $v->name;
       }
-      return FALSE;
+      return array('taxonomy' => $sub_fields);
     }
-    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 (!isset($node->taxonomy) || !is_array($node->taxonomy)) {
-          $node->taxonomy = array();
-        }
-        $node->taxonomy = array_merge($node->taxonomy, _feedapi_mapper_create_terms($feed_element, $sub_field));
+    return FALSE;
+  }
+  else if ($op == 'map' && $field_name == 'taxonomy') {
+    // 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 (!isset($node->taxonomy) || !is_array($node->taxonomy)) {
+        $node->taxonomy = array();
       }
-      return $node;
+      $node->taxonomy = array_merge($node->taxonomy, _feedapi_mapper_create_terms($feed_element, $sub_field));
     }
+    return $node;
   }
 }
 
