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	19 Aug 2009 09:36:14 -0000
@@ -0,0 +1,101 @@
+<?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, $node, $feed_element = array(), $field_name = '', $sub_field = '') {
+  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')) || in_array($field['type'], array('image'))) {
+            // 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 = isset($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 = html_entity_decode($element['link']);
+        }
+        elseif (is_string($element) && valid_url($element)) {
+          $href = html_entity_decode($element);
+        }
+        else {
+          continue;
+        }
+        $filepath = file_destination(file_directory_temp() . '/' . basename($href), FILE_EXISTS_RENAME);
+        if (ini_get('allow_url_fopen')) {
+          $ok = copy($href, $filepath);
+        }
+        else {
+          // Fallback, it's not as flexible as the PHP stream wrapper system
+          $result = drupal_http_request($href);
+          $ok = !empty($result->data);
+          if ($ok) {
+            $fp = fopen($filepath, 'w');
+            $ok = $ok && fwrite($fp, $result->data);
+            fclose($fp);
+          }
+        }
+        if ($ok) {
+          $ctype = content_types($node->type);
+          if ($ctype['fields'][$field_name]) {
+            $target_dir = filefield_widget_file_path($ctype['fields'][$field_name], user_load($node->uid));
+            if (field_file_check_directory($target_dir, FILE_CREATE_DIRECTORY)) {
+              $info = field_file_save_file($filepath, array(), $target_dir);
+              if ($info) {
+                $items[$onval] = $info;
+                $onval++;
+              }
+	    }
+            else {
+              watchdog("feedapi_mapper", "Could not save file @file", array('@file' => $filepath));
+            }
+          }
+          else {
+            watchdog("feedapi_mapper", "Could not save file @file", array('@file' => $filepath)); 
+          }
+          // Clean up temporary file
+          unlink($filepath);
+        }
+        else {
+          watchdog("feedapi_mapper", "Could not fetch @url", array('@url' => $href));
+        }
+      }
+
+      $node->$field_name = $items;
+      return $node;
+      break;
+  }
+}
Index: tests/feedapi_mapper_filefield.test
===================================================================
RCS file: tests/feedapi_mapper_filefield.test
diff -N tests/feedapi_mapper_filefield.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/feedapi_mapper_filefield.test	19 Aug 2009 09:36:14 -0000
@@ -0,0 +1,95 @@
+<?php
+// $Id: feedapi_mapper_filefield.test,v 1.2 2009/07/14 17:18:22 alexb Exp $
+
+require_once(drupal_get_path('module', 'feedapi_mapper') . '/tests/feedapi_mapper_test.inc');
+
+/**
+ * Class for testing feedapi_mapper_filefield (Date fields).
+ */
+class FeedApiMapperFileFieldTestCase extends FeedApiMapperTestCase {
+
+  /**
+   * Drupal SimpleTest method: return metadata about the test.
+   */
+  public static function getInfo() {
+    return array(
+      'name' => t('FeedAPI Mapper FileField'),
+      'description' => t('Test FeedAPI Mapper support for File Fields (Requires internet connection)'),
+      'group' => t('FeedAPI Mapper'),
+    );
+  }
+
+  /**
+   * SimpleTest core method: code run before each and every test method.
+   */
+  function setUp() {
+    // Always call the setUp() function from the parent class.
+    @parent::setUp(
+      'feedapi',
+      'feedapi_node',
+      'parser_simplepie',
+      'parser_common_syndication',
+      'feedapi_mapper',
+      'content',
+      'filefield'
+    );
+
+    // Create users.
+    $this->admin_user = $this->drupalCreateUser(
+      array(
+        'administer content types',
+        'administer feedapi',
+        'administer nodes',
+        'administer site configuration',
+        'advanced feedapi options',
+        'create feed content',
+      )
+    );
+  }
+
+  /**
+   * SimpleTest main test method: runs actual test with significant help from parent class methods.
+   */
+  function testFileFieldMapping() {
+    $options = array(
+      'fields' => array(
+        'alpha' => 'filefield',
+        'beta' => 'filefield',
+      ),
+      'filename' => 'flickr.xml', // This feed references images online; if they move the test will break.
+      'mappers' => array('node'),
+      'mapping' => array(
+        serialize(array('title')) => serialize(array('node', 'title')),
+        serialize(array('description')) => serialize(array('node', 'body')),
+        serialize(array('options', 'enclosures', 'image', 'jpeg')) => serialize(array('filefield', 'field_alpha')),
+      ),
+    );
+
+    $this->drupalLogin($this->admin_user);
+    $this->enableParsers(TRUE, FALSE);
+    $feed_url = $this->setupFeed($options);
+
+    // Check one of the nodes
+    $this->drupalGet('admin/content/node/overview');
+    $this->clickLink('Tubing is awesome');
+
+    $node = node_load(array('title' => 'Tubing is awesome'), NULL, TRUE);
+    $this->assertTrue(isset($node->field_alpha[0]), t("File created, #1"));
+    $this->assertTrue(file_exists($node->field_alpha[0]['filepath']), t('Image file exists, #1'));
+
+    $this->assertText('Tubing is awesome');
+    
+    // Check one of the nodes
+    $this->drupalGet('admin/content/node/overview');
+    $this->clickLink('Jeff vs Tom');
+
+    $node = node_load(array('title' => 'Jeff vs Tom'), NULL, TRUE);
+    $this->assertTrue(isset($node->field_alpha[0]), t("File created, #2"));
+    $this->assertTrue(file_exists($node->field_alpha[0]['filepath']), t('Image file exists, #2'));
+
+    $this->assertText('Jeff vs Tom');
+
+    $this->deleteFeed($feed_url);
+    $this->drupalLogout();
+  }
+}
Index: tests/feedapi_mapper_test.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/tests/feedapi_mapper_test.inc,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 feedapi_mapper_test.inc
--- tests/feedapi_mapper_test.inc	13 Jul 2009 19:59:52 -0000	1.1.2.2
+++ tests/feedapi_mapper_test.inc	19 Aug 2009 09:36:14 -0000
@@ -175,6 +175,10 @@ class FeedApiMapperTestCase extends Drup
       'text' => 'text_textfield',
       'userreference' => 'userreference_select',
     );
+    
+    $field_options = array(
+      'filefield' => array('file_extensions' => 'jpg jpeg gif png txt'),
+    );
 
     // Create the fields
     foreach ($fields as $field_name => $field_type) {
@@ -189,11 +193,12 @@ class FeedApiMapperTestCase extends Drup
       $this->drupalPost($admin_type_url . '/fields', $edit, 'Save');
 
       // (Default) Configure the field.
-      $edit = array();
+      $edit = isset($field_options[$field_name]) ? $field_options[$field_name] : array();
       $this->drupalPost(NULL, $edit, 'Save field settings');
       $this->assertText('Added field ' . $label);
     }
-
+    // Clear content type cache.
+    _content_type_info(TRUE);
     return $typename;
   }
 
Index: tests/samples/flickr.xml
===================================================================
RCS file: tests/samples/flickr.xml
diff -N tests/samples/flickr.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/samples/flickr.xml	19 Aug 2009 09:36:15 -0000
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<feed xmlns="http://www.w3.org/2005/Atom"
+      xmlns:dc="http://purl.org/dc/elements/1.1/"  xmlns:flickr="urn:flickr:" xmlns:media="http://search.yahoo.com/mrss/">
+
+	<title>Content from My picks</title>
+	<link rel="self" href="http://api.flickr.com/services/feeds/photoset.gne?set=72157603970496952&amp;nsid=28242329@N00&amp;lang=en-us" />
+	<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/a-barth/sets/72157603970496952"/>
+	<id>tag:flickr.com,2005:http://www.flickr.com/photos/28242329@N00/sets/72157603970496952</id>
+	<icon>http://farm1.static.flickr.com/42/86410049_bd6dcdd5f9_s.jpg</icon>
+	<subtitle>Some of my shots I like best in random order.</subtitle>
+	<updated>2009-07-09T21:48:04Z</updated>
+	<generator uri="http://www.flickr.com/">Flickr</generator>
+    
+	<entry>
+		<title>Tubing is awesome</title>
+		<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/a-barth/3596408735/in/set-72157603970496952/"/>
+		<id>tag:flickr.com,2005:/photo/3596408735/in/set-72157603970496952</id>
+		<published>2009-07-09T21:48:04Z</published>
+		<updated>2009-07-09T21:48:04Z</updated>
+                <dc:date.Taken>2009-05-01T00:00:00-08:00</dc:date.Taken>
+		<content type="html">&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/people/a-barth/&quot;&gt;Alex Barth&lt;/a&gt; posted a photo:&lt;/p&gt;
+
+&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/a-barth/3596408735/&quot; title=&quot;Tubing is awesome&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3599/3596408735_ce2f0c4824_m.jpg&quot; width=&quot;240&quot; height=&quot;161&quot; alt=&quot;Tubing is awesome&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
+
+
+&lt;p&gt;Virginia, 2009&lt;/p&gt;</content>
+		<author>
+			<name>Alex Barth</name>
+			<uri>http://www.flickr.com/people/a-barth/</uri>
+					</author>
+		<link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc/2.0/deed.en" />
+        <link rel="enclosure" type="image/jpeg" href="http://farm4.static.flickr.com/3599/3596408735_091162e986_o.jpg" />
+
+		<category term="color" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="film" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="virginia" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="awesome" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="ishootfilm" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="va" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="badge" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="tubing" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="fuji160c" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="anfamiliebarth" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="canon24l" scheme="http://www.flickr.com/photos/tags/" />
+                	</entry>
+	<entry>
+		<title>Jeff vs Tom</title>
+		<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/a-barth/2640019371/in/set-72157603970496952/"/>
+		<id>tag:flickr.com,2005:/photo/2640019371/in/set-72157603970496952</id>
+		<published>2009-07-09T21:45:50Z</published>
+		<updated>2009-07-09T21:45:50Z</updated>
+                <dc:date.Taken>2008-06-01T00:00:00-08:00</dc:date.Taken>
+		<content type="html">&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/people/a-barth/&quot;&gt;Alex Barth&lt;/a&gt; posted a photo:&lt;/p&gt;
+
+&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/a-barth/2640019371/&quot; title=&quot;Jeff vs Tom&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3261/2640019371_495c3f51a2_m.jpg&quot; width=&quot;240&quot; height=&quot;159&quot; alt=&quot;Jeff vs Tom&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
+
+
+</content>
+		<author>
+			<name>Alex Barth</name>
+			<uri>http://www.flickr.com/people/a-barth/</uri>
+					</author>
+		<link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc/2.0/deed.en" />
+        <link rel="enclosure" type="image/jpeg" href="http://farm4.static.flickr.com/3261/2640019371_6b4fe5966a_o.jpg" />
+
+		<category term="b" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="blackandwhite" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="bw" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="jeff" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="tom" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="washingtondc" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="blackwhite" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="dc" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="nikon" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="wideangle" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="ilfordhp5" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="foosball" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="20mm" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="nikonfe2" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="800asa" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="foosballtable" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="wuzler" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="wuzln" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="tischfusball" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="jeffmiccolis" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="ilfordhp5800asa" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="widean" scheme="http://www.flickr.com/photos/tags/" />
+                	</entry>
+	<entry>
+		<title>Attersee 1</title>
+		<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/a-barth/3686290986/in/set-72157603970496952/"/>
+		<id>tag:flickr.com,2005:/photo/3686290986/in/set-72157603970496952</id>
+		<published>2009-07-09T21:42:01Z</published>
+		<updated>2009-07-09T21:42:01Z</updated>
+                <dc:date.Taken>2009-06-01T00:00:00-08:00</dc:date.Taken>
+		<content type="html">&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/people/a-barth/&quot;&gt;Alex Barth&lt;/a&gt; posted a photo:&lt;/p&gt;
+
+&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/a-barth/3686290986/&quot; title=&quot;Attersee 1&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3606/3686290986_334c427e8c_m.jpg&quot; width=&quot;240&quot; height=&quot;238&quot; alt=&quot;Attersee 1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
+
+
+&lt;p&gt;Upper Austria, 2009&lt;/p&gt;</content>
+		<author>
+			<name>Alex Barth</name>
+			<uri>http://www.flickr.com/people/a-barth/</uri>
+					</author>
+		<link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc/2.0/deed.en" />
+        <link rel="enclosure" type="image/jpeg" href="http://farm4.static.flickr.com/3606/3686290986_99b827612b_o.jpg" />
+
+		<category term="lake" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="green" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="water" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="austria" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="holga" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="toycamera" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="ishootfilm" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="fujireala" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="badge" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="100asa" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="attersee" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="plasticlens" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="colornegative" scheme="http://www.flickr.com/photos/tags/" />
+                	</entry>
+	<entry>
+		<title>H Street North East</title>
+		<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/a-barth/2640845934/in/set-72157603970496952/"/>
+		<id>tag:flickr.com,2005:/photo/2640845934/in/set-72157603970496952</id>
+		<published>2008-09-23T13:26:13Z</published>
+		<updated>2008-09-23T13:26:13Z</updated>
+                <dc:date.Taken>2008-06-01T00:00:00-08:00</dc:date.Taken>
+		<content type="html">&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/people/a-barth/&quot;&gt;Alex Barth&lt;/a&gt; posted a photo:&lt;/p&gt;
+
+&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/a-barth/2640845934/&quot; title=&quot;H Street North East&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3083/2640845934_85c11e5a18_m.jpg&quot; width=&quot;240&quot; height=&quot;159&quot; alt=&quot;H Street North East&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
+
+
+&lt;p&gt;Washington DC 2008&lt;br /&gt;
+&lt;a href=&quot;http://dcist.com/2008/07/07/photo_of_the_day_july_7_2008.php&quot;&gt;Photo of the Day July 7 on DCist&lt;/a&gt;&lt;/p&gt;</content>
+		<author>
+			<name>Alex Barth</name>
+			<uri>http://www.flickr.com/people/a-barth/</uri>
+					</author>
+		<link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc/2.0/deed.en" />
+        <link rel="enclosure" type="image/jpeg" href="http://farm4.static.flickr.com/3083/2640845934_6f1b5eba3c_o.jpg" />
+
+		<category term="nightphotography" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="b" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="blackandwhite" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="bw" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="night" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="washingtondc" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="blackwhite" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="dc" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="nikon" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="dof" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="wideangle" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="explore" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="ilfordhp5" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="badge" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="dcist" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="20mm" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="hstreet" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="nikonfe2" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="800asa" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="hstreetne" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="anfamiliebarth" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="ilfordhp5800asa" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="hstreetbynight" scheme="http://www.flickr.com/photos/tags/" />
+		<category term="forlaia" scheme="http://www.flickr.com/photos/tags/" />
+                	</entry>
+</feed>
\ No newline at end of file