FeedAPI mapper support
reikiman - September 2, 2009 - 05:00
| Project: | RSS Remote Enclosure |
| Version: | 6.x-1.0 |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | reikiman |
| Status: | active |
Jump to:
Description
To be done after: #565904: Add CCK support
Implement a FeedAPI mapper function to convert enclosure tags on incoming feeds into encl_remote fields.
I have code here: http://hg.davidherron.com/index.cgi/drupalv6/file/tip/sites/all/modules/...

#1
As noted in the other issue (to convert encl_remote into a CCK type) I just wrote a FieldAPI mapper that converts RSS elements into encl_remote fields. It involves adding two small functions to encl_remote.
With the functions encl_remote shows up in the list of targets.
I'm using FeedAPI with the simplepie parser. Am able to define a mapping from options->all->enclosure to the encl_remote target and it works perfectly.
I need to do this as a proper patch, yes, but this is the code.
//////////////////////////
// FEEDAPI MAPPER SUPPORT
//////////////////////////
/**
* Implement hook_feedapi_mapper() to map an element of a feed to a field on a
* node.
*
* Mapping flow
*
* 1) hook_feedapi_mapper('list')
*
* This operation is invoked when the mapper is about to present mapping
* options to the user. When $op is 'list' the $node parameter contains the
* type of the node at $node->type, all other parameters are not present.
* Examine $node->type and determine which mapping targets are available.
*
* If no mapping target is available return FALSE.
*
* If a single mapping target is available return:
* array(
* 'single_target' => t('Single target'), // 'single_target' will be the value of $field_name on 'map'
* )
*
* If multiple mapping targets are available return:
* array(
* 'target1' => t('Target 1'), // 'target1' will be the field name on 'map'
* 'target2' => t('Target 2'), // 'target2' will be the field name on 'map'
* )
*
* Feed Element Mapper also supports sub fields:
* array(
* 'multiple_targets' => array( // 'multiple_targets' will be the value of $field_name on 'map'
* 'target1' => t('Target 1'), // 'target1' will be the value of $sub_field on 'map'
* 'target2' => t('Target 2'), // 'target2' will be the value of $sub_field on 'map'
* )
* )
*
*
* 2) hook_feedapi_mapper('map')
*
* This operation is invoked when the actual mapping happens. If a user
* selected the mapping functionality exposed on 'list' hook_feedapi_mapper
* will be called on node prepare with $op == 'map', $node = feed item node the
* mapping is performed on, $feed_element = the element of the feed that a user
* chose as a mapping source, $field_name = the name of the field that a user
* chose as a mapping target, $sub_field = the name of the sub field that a user
* chose as a mapping target.
*
*
* hook_feedapi_mapper('describe') is used to generate help text on the
* mapping form.
*
* Which feed elements are available for mapping is up to the parser.
*
* @param $op
* Operation to perform.
* Value of $op is one of 'describe', 'list' or 'map'.
* @param $node
* Drupal node object.
* @param $feed_element
* Parameter only present on $op = 'map'
* Element of the feed to map from. A simple data type (number, string) or a
* one dimensional array of simple types.
* @param $field_name
* Parameter only present on $op = 'map'
* Name of the field to map to.
* @param $sub_field
* Parameter only present on $op = 'map'
* If given, a subfield on the node to map to.
* This parameter will depend on if the hook implementation returns a subfield on
* $op = 'list'.
*
*/
function encl_remote_feedapi_mapper($op, $node, $feed_element = array(), $field_name = '', $sub_field = '') {
// Test for the node field that we would like to map to.
if ($op == 'describe') {
return t('Maps an enclosure tag to encl_remote.');
}
else if ($op == 'list') {
if (_encl_remote_is_nodetype_allowed($node->type)) {
$fields = array();
$field_name = 'encl_remote';
$fields[$field_name] = $field_name;
return $fields;
}
return FALSE;
}
else if ($op == 'map') {
if (is_array($feed_element)) {
// These are the attributes of an <enclosure>
$node->url = $feed_element['@url'];
$node->link_text = $feed_element['#text'];
$node->size = $feed_element['@length'];
$node->mime_type = $feed_element['@type'];
// The rest is handled in nodeapi hook presave && update/insert
}
return $node;
}
}
/**
* Implement hook_feedapi_mapper_elements to define standard elements that your
* configuration should be able to map to.
*
* When FeedAPI Mapper exposes the mapping form on a feed node (node/%/map), it
* parses the feed and uses the result to make elements of it available as
* mapping sources.
*
* However, when FeedAPI mapper exposes the mapping form on a content type
* form (admin/content/node-type/%/map), there is no feed to parse for
* discovering feed elements. In this case FeedAPI Mapper exposes some standard
* elements. You may find yourself in the need for more specific standard
* elements on the content type level, in this case implement
* hook_feedapi_mapper_elements() in your module.
*
* @see _feedapi_mapper_get_standard_elements().
*
* @return
* An array of arrays that describe the path to a feed element on a feed.
*/
function encl_remote_feedapi_mapper_elements() {
return array(
array('options', 'enclosures'),
);
}