Index: mappers/feedapi_mapper_filefield.inc
===================================================================
RCS file: mappers/feedapi_mapper_filefield.inc
diff -N mappers/feedapi_mapper_filefield.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ mappers/feedapi_mapper_filefield.inc	31 Jul 2009 21:56:05 -0000
@@ -0,0 +1,84 @@
+<?php
+// $Id$
+
+/**
+* Implementation of hook_feedapi_mapper for pulling a file from an enclosure or plaintext url into a node.
+*/
+function filefield_feedapi_mapper($op, $feed_node, $node = NULL, $feed_element = array(), $field_name = '', $sub_field = '') {
+  // Only map nodes.
+  if (!$node_type = feedapi_mapper_get_item_node_type($feed_node)) {
+    return;
+  }
+
+  switch ($op) {
+    case 'describe':
+      return t('Maps a url or enclosure to a file in a FileField CCK field.');
+      break;
+
+    case '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('filefield'))) {
+            // Images are supported because the imagefield module smartly reuses the filefield module for cck storage.
+            $fields[$field_name] = isset($field['widget']['label']) ? $field['widget']['label'] : $field_name;
+          }
+        }
+      }
+      if (count($fields)) {
+        return $fields;
+      }
+      return FALSE;
+      break;
+
+    case 'map':
+      /**
+       * Supported/expected input cases follow. Please feel encouraged to submit patches with additional support for common parsers/feed sources/combinations therein.
+       * General
+       * 1) $feed_element is just a string, ie http://mysite.com/myfile.doc
+       * 2) $feed_element is an array of strings, all of which will added to the cck field if there's sufficient room
+       * Parsed Enclosure as returned by SimplePie or similar
+       * 1) $feed_element is an associative array with a 'link' field
+       * 2) $feed_element is an array of such associative arrays, all of which will added to the cck field if there's sufficient room
+      */
+      $items = $node->{$field_name} ? $node->{$field_name} : array();
+      if (!is_array($feed_element)) {
+        // Make a string into an array and then pull it out 8 lines later. Allows non-redundant code.
+        $feed_element = array($feed_element);
+      }
+      $onval = 0;
+      foreach ($feed_element as $element) {
+        $href = '';
+        if (is_array($element) && valid_url($element['link'])) {
+          $href = $element['link'];
+        }
+        elseif (is_string($element) && valid_url($element)) {
+          $href = $element;
+        }
+        else {
+          continue;
+        }
+        // straight link usually from options->original_url or options->guid
+        $filepath = file_destination(file_directory_temp() . '/' . basename($href), FILE_EXISTS_RENAME);
+        $ok = copy($href, $filepath); // TODO: use curl?
+        if ($ok) {
+          $info = field_file_save_file($filepath, array(), file_directory_path());
+          if ($info) {
+            $items[$onval] = $info;
+            $onval++;
+          }
+          else {
+            watchdog("feedapi_mapper", "Could not save file @file", array('@file' => $filepath));
+          }
+        }
+        else {
+          watchdog("feedapi_mapper", "Could not fetch @url", array('@url' => $href));
+        }
+      }
+
+      $node->$field_name = $items;
+      return $node;
+      break;
+  }
+}
