From 7ce2c5f8fb9ba5f0677a1c05e4743c67a406b6ef Mon Sep 17 00:00:00 2001
From: Alex Barth <alex_b@53995.no-reply.drupal.org>
Date: Sat, 19 Sep 2009 15:52:46 +0000
Subject: [PATCH] Start work on mapper.

---
 feeds_ui/feeds_ui.admin.inc        | 70 ++++++++++++++++++++++++++++--
 feeds_ui/feeds_ui.module           | 12 +++++
 includes/feed.inc                  | 28 +++++++++++-
 plugins/FeedsNodeProcessor.inc     | 26 +++++------
 plugins/FeedsSyndicationParser.inc |  5 +++
 5 files changed, 121 insertions(+), 20 deletions(-)

diff --git a/feeds_ui/feeds_ui.admin.inc b/feeds_ui/feeds_ui.admin.inc
index e56aff48..f59a13c9 100644
--- a/feeds_ui/feeds_ui.admin.inc
+++ b/feeds_ui/feeds_ui.admin.inc
@@ -159,10 +159,31 @@ function feeds_ui_build_edit_form_submit($form, &$form_state) {
  */
 function feeds_ui_build_mapping_form(&$form_state, $feed) {
   $form = array();
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-  );
+
+  // Build a mapping form for each processor configured.
+  $sources = $feed->parser->getMappingSources();
+  foreach ($feed->processors as $class => $processor) {
+    $mappings = $processor->getMappings();
+    $targets = $processor->getMappingTargets();
+    $form['processors'][$class] = array(
+      '#type' => 'fieldset',
+      '#title' => $class, // @todo: human readable title.
+    );
+    $form['processors'][$class]['#mappings'] = $mappings;
+    $form['processors'][$class]['#targets'] = $targets;
+    $form['processors'][$class]['sources'] = array(
+      '#type' => 'select',
+      '#options' => array('' => t('Select a source')) + drupal_map_assoc($sources),
+    );
+    $form['processors'][$class]['targets'] = array(
+      '#type' => 'select',
+      '#options' => array('' => t('Select a target')) + drupal_map_assoc(array_keys($targets)),
+    );
+    $form['processors'][$class]['add'] = array(
+      '#type' => 'submit',
+      '#value' => t('Add'),
+    );
+  }
   return $form;
 }
 
@@ -218,4 +239,45 @@ function feeds_ui_build_delete_form(&$form_state, $feed) {
  */
 function feeds_ui_build_delete_form_submit($form, &$form_state) {
   feeds_delete($form['#feed']->getId());
+}
+
+/**
+ * Theme function for feeds_ui_build_mapping_form().
+ */
+function theme_feeds_ui_build_mapping_form($form) {
+  $output = '';
+  $header = array(
+    t('Source'),
+    t('Target'),
+    t('Unique'),
+    t('Remove'),
+  );
+
+  foreach (element_children($form['processors']) as $processor) {
+    $rows = array();
+    if (is_array($form['processors'][$processor]['#mappings'])) {
+      foreach ($form['processors'][$processor]['#mappings'] as $mapping) {
+        $rows[] = array(
+          // @todo.
+        ); 
+      }
+    }
+    if (!count($rows)) {
+      $rows[] = array(
+        array(
+          'colspan' => 4,
+          'data' => t('No mappings defined.'),
+        ),
+      );
+    }
+    $rows[] = array(
+      drupal_render($form['processors'][$processor]['sources']),
+      drupal_render($form['processors'][$processor]['targets']),
+      '',
+      drupal_render($form['processors'][$processor]['add']),
+    );
+    $form['processors'][$processor]['#value'] = theme('table', $header, $rows);
+  }
+  $output .= drupal_render($form);
+  return $output;
 }
\ No newline at end of file
diff --git a/feeds_ui/feeds_ui.module b/feeds_ui/feeds_ui.module
index 5dfe1be4..1671894a 100644
--- a/feeds_ui/feeds_ui.module
+++ b/feeds_ui/feeds_ui.module
@@ -91,6 +91,18 @@ function feeds_ui_menu() {
   return $items;
 }
 
+/**
+ * Implementation of hook_theme().
+ */
+function feeds_ui_theme() {
+  return array(
+    'feeds_ui_build_mapping_form' => array(
+      'arguments' => array('form'),
+      'file' => 'feeds_ui.admin.inc',
+    ),
+  );
+}
+
 /**
  * Title callback.
  */
diff --git a/includes/feed.inc b/includes/feed.inc
index cf805131..c7832886 100644
--- a/includes/feed.inc
+++ b/includes/feed.inc
@@ -397,9 +397,33 @@ class FeedsProcessor extends FeedsConfigurable {
    * Declare possible mapping targets.
    *
    * @return
-   *   An array of mapping targets.
+   *   An array of mapping targets. Keys are paths to targets
+   *   separated by ->, values are TRUE if target can be unique, 
+   *   FALSE otherwise.
    */
   public function getMappingTargets() {
-    return NULL;
+    // @todo: invoke hook_feeds_mapper() here.
+    return array();
+  }
+
+  /**
+   * Get mappings.
+   */
+  public function getMappings() {
+    return $this->config->mappings;
+  }
+
+  /**
+   * Execute mapping on an item.
+   */
+  public function map($item) {
+    // @todo.
+  }
+
+  /**
+   * Determine whether a given item is unique.
+   */
+  public function unique($item) {
+    // @todo.
   }
 }
\ No newline at end of file
diff --git a/plugins/FeedsNodeProcessor.inc b/plugins/FeedsNodeProcessor.inc
index 35008062..416a37bf 100644
--- a/plugins/FeedsNodeProcessor.inc
+++ b/plugins/FeedsNodeProcessor.inc
@@ -5,25 +5,23 @@ class FeedsNodeProcessor extends FeedsProcessor {
 
   function process($feed) {
     foreach ($feed->items as $item) {
-      if (feeds_unique('FeedsNodeProcessor', $item)) {
-        $node = feeds_map('FeedsNodeProcessor', $item);
+      if ($this->unique($item)) {
+        $node = $this->map($item);
         node_save($node);
       }
     }
   }
 
+  /**
+   * Return available mapping targets.
+   */
   function getMappingTargets() {
-    $config = $this->getConfiguration();
-    $default = array('title', 'body', 'status');
-    $default += module_invoke('feedapi_mapper', 'list', 'FeedsNodeProcessor', $config->content_type);
-    return $default;
-  }
-
-  function map() {
-    
-  }
-
-  function unique() {
-    
+    return array(
+      'title' => FALSE, 
+      'body' => FALSE, 
+      'status' => FALSE, 
+      'url' => TRUE, 
+      'guid' => TRUE,
+    );
   }
 }
\ No newline at end of file
diff --git a/plugins/FeedsSyndicationParser.inc b/plugins/FeedsSyndicationParser.inc
index b7a6ecd9..f7a84ed7 100644
--- a/plugins/FeedsSyndicationParser.inc
+++ b/plugins/FeedsSyndicationParser.inc
@@ -1,6 +1,11 @@
 <?php
 // $Id$
 
+/**
+ * Class definition for Common Syndication Parser.
+ * 
+ * Parses RSS and Atom feeds.
+ */
 class FeedsSyndicationParser extends FeedsParser {
 
   /**
-- 
GitLab