Index: mappers/filefield.inc
===================================================================
RCS file: mappers/filefield.inc
diff -N mappers/filefield.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ mappers/filefield.inc	12 Dec 2009 14:20:35 -0000
@@ -0,0 +1,127 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * On behalf implementation of Feeds mapping API for filefield.module (CCK).
+ *
+ * @todo Support the <em>list</em> subfields (howto provides default value ?)
+ * @todo Support the <em>data</em> subfileds (or its own subfiedss ?)
+ */
+
+/**
+ * Implementation of hook_feeds_node_processor_targets_alter()
+ */
+function filefield_feeds_node_processor_targets_alter($targets, $content_type) {
+  $info = content_types($content_type);
+  $fields = array();
+  if (isset($info['fields']) && count($info['fields'])) {
+    foreach ($info['fields'] as $field_name => $field) {
+      if ($field['type'] == 'filefield') {
+        $name = isset($field['widget']['label']) ? $field['widget']['label'] : $field_name;
+        $targets[$field_name] = array(
+          'name' => $name,
+          'callback' => $field['type'].'_feeds_set_target',
+          'description' => t('The URL for the CCK !name field of the node.', array('!name' => $name)),
+        );
+      }
+    }
+  }
+}
+
+/**
+ * Implementation of hook_feeds_set_target().
+ */
+function filefield_feeds_set_target($node, $field_name, $value) {
+  $items = isset($node->$field_name) ? $node->$field_name : array();
+  $enclosures = array($value);
+  //$enclosures always contains the enclosures to resolve
+  while (($enclosure = array_pop($enclosures)) !== NULL) {
+    if ($file = _enclosure_resolve($enclosure)) {
+      //$enclosure was resolved to a file
+      $field = content_fields($field_name, $node->type);
+      $target_dir = filefield_widget_file_path($field, user_load($node->uid));
+      $info = field_file_save_file($file, array(), $target_dir);
+      if ($info) {
+        if ($field['list_field']) {
+          $info['list'] = $field['list_default'];
+        }
+        $items[] = $info;
+        $error = false;
+      }
+    }
+    elseif (is_array($enclosure)) {
+      //$enclosure is probably an array of enclosures
+      foreach ($enclosure as $child) {
+        array_push($enclosures, $child);
+      }
+    }
+    else {
+      if (is_object($enclosure)) {
+        $enclosure = t('instance of !class', array('!class' => get_class($enclosure)));
+      }
+      watchdog("feeds", "Could not resolve enclosure %enclosure in field %field_name", array('%enclosure' => $enclosure, '%field_name' => $field_name));
+    }
+  }
+
+  $node->$field_name = $items;
+}
+
+/**
+ * Get the filename for an enclosure URL. If the URL is a valid external URL,
+ * its content is download as a temporary file. Otherwise, it is considered
+ * as a filename.
+ *
+ * @param $url
+ *   The URL
+ * @return
+ *   The filename for <code>$url</code>, or 0 on error.
+ */
+function _enclosure_resolve($enclosure) {
+  //Get enclosure URL
+  if (is_object($enclosure)) {
+    if (method_exists($enclosure, 'get_link')) {
+      //SimplePie_Enclosure style
+      $url = $enclosure->get_link();
+    }
+    elseif (method_exists($enclosure, 'getUrl')) {
+      //Generalized enclusore interface, as in inital patch in http://drupal.org/node/641522
+      $url = $enclosure->getUrl();
+    }
+    elseif (isset($enclosure->link)) {
+      //Fallback to a link property
+      $url = $enclosure->link;
+    }
+  }
+  elseif (is_array($enclosure) && isset($enclosure['link'])) {
+    $url = $enclosure['link'];
+  }
+  elseif (is_string($enclosure)) {
+    $url = $enclosure;
+  }
+  else {
+    return 0;
+  }
+  //Resolve URL
+  if (valid_url($url, true)) {
+    //this enclosure is an absolute URL, download it.
+    $filepath = file_destination(file_directory_temp().'/'.strtolower(get_class($this)).'/'.basename($url), FILE_EXISTS_RENAME);
+    if (ini_get('allow_url_fopen')) {
+      return copy($url, $filepath) ? $filepath : 0;
+    }
+    else {
+      feeds_include_library('http_request.inc', 'http_request');
+      $result = http_request_get($url);
+      if ($result->code != 200) {
+        watchdog('feeds', 'Download of @url failed with code !code.', array('@url' => $url, '!code' => $result->code));
+        return 0;
+      }
+      else {
+        return file_save_data($result->data, $filepath);
+      }
+    }
+  }
+  else {
+    return file_exists($url) ? $url : 0;
+  }
+}
\ No newline at end of file
Index: tests/feeds_mapper_filefield.test
===================================================================
RCS file: tests/feeds_mapper_filefield.test
diff -N tests/feeds_mapper_filefield.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/feeds_mapper_filefield.test	12 Dec 2009 14:20:35 -0000
@@ -0,0 +1,101 @@
+<?php
+// $Id:$
+
+require_once(drupal_get_path('module', 'feeds') . '/tests/feeds_mapper_test.inc');
+
+/**
+ * Class for testing Feeds FileField mapper.
+ * 
+ * @todo Add a test for enclosures returned as array
+ * @todo Add a test for enclosures returned as string
+ * @todo Add a test for enclosures using local file 
+ */
+class FeedsMapperFileFieldTestCase extends FeedsMapperTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => t('Mapper: FileField'),
+      'description' => t('Test Feeds Mapper support for FileField CCK fields'),
+      'group' => t('Feeds'),
+    );
+  }
+
+  /**
+   * Set up the 
+   */
+  public function setUp() {
+    // Call parent setup with the required module
+    parent::setUp(
+    	'devel', 'feeds', 'feeds_ui', 'ctools', 'content',
+    	'filefield'
+    );
+
+    // Create user and login
+    $this->drupalLogin($this->drupalCreateUser(
+        array(
+          'administer content types',
+          'administer feeds',
+          'administer nodes',
+          'administer site configuration',
+        	'access devel information'
+        )
+    ));
+  }
+
+  /**
+   * Basic test loading a single entry CSV file.
+   */
+  public function test() {
+  	$static_title = $this->randomName();
+  	//Create content type
+  	$typename = $this->createContentType(NULL, array(
+			'files' => array(
+				'type' => 'filefield',
+  			'settings' => array(
+  				'multiple' =>  '1',
+  				'file_extensions' => 'jpg'
+  			),
+			),
+    ));
+    
+    //Create importer configuration
+    $this->createFeedConfiguration(); //Create a default importer configuration
+    $this->setPlugin('syndication', 'FeedsSimplePieParser');
+    $this->setSettings('syndication', 'FeedsNodeProcessor', array('content_type' => $typename)); //Processor settings
+    $this->addMappings('syndication', array(
+			array(
+      	'source' => 'title',
+      	'target' => 'title'
+			),
+			array(
+				'source' => 'timestamp',
+				'target' => 'created'
+			),
+			array(
+				'source' => 'description',
+				'target' => 'body'
+			),
+			array(
+				'source' => 'enclosures',
+				'target' => 'field_files'
+			),
+    ));
+    
+    $nid = $this->createFeedNode('syndication', $GLOBALS['base_url'] .'/'. drupal_get_path('module', 'feeds') . '/tests/feeds/flickr.xml');
+    $this->assertText('Created 4 '.$typename.' nodes.');
+
+    $filename = array('3596408735_091162e986_o', '2640019371_6b4fe5966a_o', '3686290986_99b827612b_o', '2640845934_6f1b5eba3c_o');
+    for($i = 0; $i < 4; $i++) {
+      $this->drupalGet('node/'.($i+2).'/edit');
+      $this->assertText($filename[$i]);
+    }
+  }
+  
+  public function selectFieldWidget($fied_name, $field_type) {
+  	if($field_type == 'filefield') {
+  		return 'filefield_widget';
+  	} else {
+  		return parent::selectFieldWidget($fied_name, $field_type);
+  	}
+  }
+}
Index: tests/feeds/flickr.xml
===================================================================
RCS file: tests/feeds/flickr.xml
diff -N tests/feeds/flickr.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/feeds/flickr.xml	12 Dec 2009 14:20:35 -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
