Index: feeds.api.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feeds/feeds.api.php,v retrieving revision 1.10 diff -u -p -r1.10 feeds.api.php --- feeds.api.php 24 Feb 2010 01:19:33 -0000 1.10 +++ feeds.api.php 17 May 2010 17:11:03 -0000 @@ -108,6 +108,19 @@ function hook_feeds_after_import(FeedsIm */ /** + * Alter mapping targets for users. Use this hook to add additional target + * options to the mapping form of User processors. + * + * For an example implementation, see mappers/location.inc + * + * @param: &$targets + * Array containing the targets to be offered to the user. Add to this array + * to expose additional options. Remove from this array to suppress options. + */ +function hook_feeds_user_processor_targets_alter(&$targets) { +} + +/** * Alter mapping targets for nodes. Use this hook to add additional target * options to the mapping form of Node processors. * Index: mappers/location.inc =================================================================== RCS file: mappers/location.inc diff -N mappers/location.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ mappers/location.inc 17 May 2010 17:11:03 -0000 @@ -0,0 +1,194 @@ + 0) { + $location_fields = _location_feeds_fields(); + + // We need the collect settings + $fields = $settings['form']['fields']; + // locpick is a compound field. So split it + $fields['locpick][user_latitude'] = $fields['locpick']; + $fields['locpick][user_longitude'] = $fields['locpick']; + unset($fields['locpick']); + + foreach ($fields as $field => $values) { + if (! $values['collect']) { + unset($location_fields[$field]); + } + } + + _location_feeds_fill_targets($targets, 'location', 'locations', $location_fields, TRUE); + } +} + +/** + * Implementation of feeds_node_processor_target_alter + * + * For sub elements we use the '][' construct + * + * @param $targets array of target fields + * @param $content_type + */ +function location_feeds_node_processor_targets_alter(&$targets, $content_type) { + + // location.module logic + $settings = variable_get('location_settings_node_'. $content_type, array()); + // Only add fields when collecting locations + if (isset($settings['multiple']['max']) && $settings['multiple']['max'] > 0) { + $location_fields= _location_feeds_fields(); + + // We need the collect settings + $fields = $settings['form']['fields']; + // locpick is a compound field. So split it + $fields['locpick][user_latitude'] = $fields['locpick']; + $fields['locpick][user_longitude'] = $fields['locpick']; + unset($fields['locpick']); + + foreach ($fields as $field => $values) { + if (! $values['collect']) { + unset($location_fields[$field]); + } + } + + _location_feeds_fill_targets($targets, 'location', 'locations', $location_fields); + } + + // location_cck.module logic + $info = content_types($content_type); + if (isset($info['fields']) && count($info['fields'])) { + foreach ($info['fields'] as $field_name => $field) { + $location_fields= _location_feeds_fields(); + if (in_array($field['type'], array('location'))) { + $name = isset($field['widget']['label']) ? $field['widget']['label'] : $field_name; + _location_feeds_fill_targets($targets, 'location_cck', $name, $location_fields); + } + } + } +} + +/** + * Helper function to add target fields + * + * @param $targets + * @param $module + * Module name providing the field. + * @param $field_name + * Field name where values are supposed to get stored to. + * @param $sub_fields + * Location elements for the given $field_name + * @param $isnode + * Flag for whether or not this is a node import + */ +function _location_feeds_fill_targets(&$targets, $module, $field_name, $sub_fields, $isnode = FALSE) { + foreach ($sub_fields as $sub_field => $value) { + $targets[ $field_name . ':' . $sub_field] = array( + 'name' => $module . " module: " . $field_name . '.' . t('@label', array('@label' => $value)), + 'callback' => $isnode ? 'location_feeds_set_target' : 'location_feeds_set_user_target', + 'description' => t('The @label for the location of the node.', array('@label' => $sub_field)), + ); + } +} + +/** + * Helper function to get to manage target fields + * + * @return array of key/value field name/field label + */ +function _location_feeds_fields() { + static $fields; + if (isset($fields)) { + return $fields; + } + + $fields= location_field_names(TRUE); + unset($fields['locpick']); + $fields['locpick][user_latitude'] = t("Latitude"); + $fields['locpick][user_longitude'] = t("Longitude"); + + // province_name / country_name / map_link are display fields + unset($fields['province_name']); + unset($fields['country_name']); + unset($fields['map_link']); + + return $fields; +} + +/** + * Implementation of feed_set_target + * + * @param object $node + * @param string $target + * When targeting sub arrays the '][' is used to drill down. + * Note that this implementation is lazy ... we assume just depth=2 + * @param $value + * @return object + */ +function location_feeds_set_target($node, $target, $value) { + list($field_name, $sub_field) = split(':', $target); + if (strpos($sub_field, '][') > 0) { + // TODO : make this algorithm recursive. + list($sub_field, $last_field) = split('\]\[', $sub_field, 2); + } + + if (!is_array($value)) { + $value = array($value); + } + + foreach ($value as $i => $val) { + if (isset($last_field)) { + $node->{$field_name}[$i][$sub_field][$last_field] = $val; + } + else { + $node->{$field_name}[$i][$sub_field] = $val; + } + } + return $node; +} + +/** + * Implementation of feed_set_user_target + * + * @param object $account + * @param string $target + * When targeting sub arrays the '][' is used to drill down. + * Note that this implementation is lazy ... we assume just depth=2 + * @param $value + * @return object + */ +function location_feeds_set_user_target($account, $target, $value) { + list($field_name, $sub_field) = split(':', $target); + if (strpos($sub_field, '][') > 0) { + // TODO : make this algorithm recursive. + list($sub_field, $last_field) = split('\]\[', $sub_field, 2); + } + + if (!is_array($value)) { + $value = array($value); + } + + foreach ($value as $i => $val) { + if (isset($last_field)) { + $account->{$field_name}[$i][$sub_field][$last_field] = $val; + } + else { + $account->{$field_name}[$i][$sub_field] = $val; + } + } + return $account; +} + Index: plugins/FeedsUserProcessor.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feeds/plugins/FeedsUserProcessor.inc,v retrieving revision 1.10 diff -u -p -r1.10 FeedsUserProcessor.inc --- plugins/FeedsUserProcessor.inc 28 Apr 2010 22:18:30 -0000 1.10 +++ plugins/FeedsUserProcessor.inc 17 May 2010 17:11:03 -0000 @@ -94,6 +94,26 @@ class FeedsUserProcessor extends FeedsPr } /** + * Loads on-behalf implementations from mappers/ + */ + protected static function loadMappers() { + static $loaded = FALSE; + + if (!$loaded) { + $path = drupal_get_path('module', 'feeds') .'/mappers'; + $files = drupal_system_listing('.*\.inc$', $path, 'name', 0); + foreach ($files as $file) { + if (strstr($file->filename, '/mappers/')) { + require_once("./$file->filename"); + } + } + // Rebuild cache. + module_implements('', FALSE, TRUE); + } + $loaded = TRUE; + } + + /** * Execute mapping on an item. */ protected function map($source_item) { @@ -188,6 +208,11 @@ class FeedsUserProcessor extends FeedsPr 'optional_unique' => TRUE, ); } + + // Let other modules expose mapping targets. + self::loadMappers(); + drupal_alter('feeds_user_processor_targets', $targets); + return $targets; }