? 624088-34-feeds_file.patch
? 624088-35-feeds_file.patch
? libraries/simplepie.inc
? mappers/filefield.inc
? tests/feeds_mapper_filefield.test
? tests/feeds/flickr.xml
Index: feeds.plugins.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feeds/feeds.plugins.inc,v
retrieving revision 1.2
diff -u -p -r1.2 feeds.plugins.inc
--- feeds.plugins.inc	21 Oct 2009 20:01:18 -0000	1.2
+++ feeds.plugins.inc	12 Jan 2010 16:12:04 -0000
@@ -113,7 +113,7 @@ function _feeds_feeds_plugins() {
       'description' => 'Parse RSS and Atom feeds.',
       'help' => 'Use <a href="http://simplepie.org">SimplePie</a> to parse XML feeds in RSS 1, RSS 2 and Atom format.',
       'handler' => array(
-        'parent' => 'FeedsParser',
+        'parent' => 'FeedsSyndicationParser',
         'class' => 'FeedsSimplePieParser',
         'file' => 'FeedsSimplePieParser.inc',
         'path' => $path,
Index: plugins/FeedsParser.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsParser.inc,v
retrieving revision 1.4
diff -u -p -r1.4 FeedsParser.inc
--- plugins/FeedsParser.inc	20 Dec 2009 23:54:44 -0000	1.4
+++ plugins/FeedsParser.inc	12 Jan 2010 16:12:05 -0000
@@ -2,6 +2,47 @@
 // $Id: FeedsParser.inc,v 1.4 2009/12/20 23:54:44 alexb Exp $
 
 /**
+ * Defines an element of a parsed result. Such an element can be a simple type,
+ * a complex type (derived from FeedsElement) or an array of either.
+ *
+ * @see FeedsEnclosure
+ */
+class FeedsElement {
+  // The standard value of this element. This value can contain be a simple type,
+  // a FeedsElement or an array of either.
+  protected $value;
+
+  /**
+   * Constructor.
+   */
+  public function __construct($value) {
+    $this->value = $value;
+  }
+
+  /**
+   * @return
+   *   Standard value of this FeedsElement.
+   */
+  public function getValue() {
+    return $this->value;
+  }
+
+  /**
+   * @return
+   *   A string representation of this element.
+   */
+  public function __toString() {
+    if (is_array($this->value)) {
+      return 'Array';
+    }
+    if (is_object($this->value)) {
+      return 'Object';
+    }
+    return (string) $this->value;
+  }
+}
+
+/**
  * Abstract class, defines interface for parsers.
  */
 abstract class FeedsParser extends FeedsPlugin {
Index: plugins/FeedsSimplePieParser.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsSimplePieParser.inc,v
retrieving revision 1.7
diff -u -p -r1.7 FeedsSimplePieParser.inc
--- plugins/FeedsSimplePieParser.inc	20 Dec 2009 23:54:44 -0000	1.7
+++ plugins/FeedsSimplePieParser.inc	12 Jan 2010 16:12:05 -0000
@@ -2,6 +2,34 @@
 // $Id: FeedsSimplePieParser.inc,v 1.7 2009/12/20 23:54:44 alexb Exp $
 
 /**
+ * Adapter to present SimplePie_Enclosure as FeedsEnclosure object.
+ */
+class FeedsSimplePieEnclosure extends FeedsEnclosure {
+  protected $simplepie_enclosure;
+
+  /**
+   * Constructor requires SimplePie enclosure object.
+   */
+  function __construct(SimplePie_Enclosure $enclosure) {
+    $this->simplepie_enclosure = $enclosure;
+  }
+
+  /**
+   * Override parent::getValue().
+   */
+  public function getValue() {
+    return $this->simplepie_enclosure->get_link();
+  }
+
+  /**
+   * Override parent::getMIMEType().
+   */
+  public function getMIMEType() {
+    return $this->simplepie_enclosure->get_real_type();
+  }
+}
+
+/**
  * Class definition for Common Syndication Parser.
  *
  * Parses RSS and Atom feeds.
@@ -13,7 +41,7 @@ class FeedsSimplePieParser extends Feeds
    */
   public function parse(FeedsImportBatch $batch, FeedsSource $source) {
     feeds_include_library('simplepie.inc', 'simplepie');
-
+    
     // Initialize SimplePie.
     $parser = new SimplePie();
     $parser->set_raw_data($batch->getRaw());
@@ -54,11 +82,7 @@ class FeedsSimplePieParser extends Feeds
       $enclosures = $simplepie_item->get_enclosures();
       if (is_array($enclosures)) {
         foreach ($enclosures as $enclosure) {
-          $mime = $enclosure->get_real_type();
-          if ($mime != '') {
-            list($type, $subtype) = split('/', $mime);
-            $item['enclosures'][$type][$subtype][] = $enclosure;
-          }
+          $item['enclosures'][] = new FeedsSimplePieEnclosure($enclosure);
         }
       }
       // Location
Index: plugins/FeedsSyndicationParser.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsSyndicationParser.inc,v
retrieving revision 1.10
diff -u -p -r1.10 FeedsSyndicationParser.inc
--- plugins/FeedsSyndicationParser.inc	20 Dec 2009 23:54:44 -0000	1.10
+++ plugins/FeedsSyndicationParser.inc	12 Jan 2010 16:12:05 -0000
@@ -2,6 +2,67 @@
 // $Id: FeedsSyndicationParser.inc,v 1.10 2009/12/20 23:54:44 alexb Exp $
 
 /**
+ * Enclosure element, can be part of the result array.
+ */
+class FeedsEnclosure extends FeedsElement {
+  protected $mime_type;
+  protected $file;
+
+  /**
+   * Constructor, requires MIME type.
+   */
+  public function __construct($value, $mime_type) {
+    parent::__construct($value);
+    $this->mime_type = $mime_type;
+  }
+
+  /**
+   * @return
+   *   MIME type of return value of getValue().
+   */
+  public function getMIMEType() {
+    return $this->mime_type;
+  }
+
+  /**
+   * @return
+   *   The content of the referenced resource.
+   */
+  public function getContent() {
+    feeds_include_library('http_request.inc', 'http_request');
+    $result = http_request_get($this->getValue());
+    if ($result->code != 200) {
+      throw new Exception(t('Download of @url failed with code !code.', array('@url' => $this->getValue(), '!code' => $result->code)));
+    }
+    return $result->data;
+  }
+
+  /**
+   * @return
+   *   The file path to the downloaded resource referenced by the enclosure.
+   *   Downloads resource if not downloaded yet.
+   *
+   * @todo Get file extension from mime_type.
+   * @todo This is not concurrency safe.
+   */
+  public function getFile() {
+    if(!isset($this->file)) {
+      $dest = file_destination(file_directory_temp() .'/'. get_class($this) .'-'. basename($this->getValue()), FILE_EXISTS_RENAME);
+      if (ini_get('allow_url_fopen')) {
+        $this->file = copy($this->getValue(), $dest) ? $dest : 0;
+      }
+      else {
+        $this->file = file_save_data($this->getContent(), $dest);
+      }
+      if ($this->file === 0) {
+        throw new Exception(t('Cannot write content to %dest', array('%dest' => $dest)));
+      }
+    }
+    return $this->file;
+  }
+}
+
+/**
  * Class definition for Common Syndication Parser.
  *
  * Parses RSS and Atom feeds.
