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 filefield_feedapi_mapper($op, $node, $feed_element = array(), $field_name = '', $sub_field = '') { switch ($op) { case 'describe': return t('Maps a feed element image element to an cck filefield in a node'); break; case 'list': $info = content_types($node->type); $fields = array(); if (!empty($info['fields']) && is_array($info['fields'])) { foreach ($info['fields'] as $field_name => $field) { if (in_array($field['type'], array('filefield'))) { $fields[$field_name] = isset($field['widget']['label']) ? $field['widget']['label'] : $field_name; } } } if (!empty($fields)) { return $fields; } return FALSE; break; case 'map': // mapping takes place here $imgurl = NULL; // extract image if (!empty($feed_element)) { if (!is_array($feed_element) && is_string($feed_element)) { $imgurl = $feed_element; } else { // FIXME: these expect "exhaustive parser" if (!empty($feed_element['#text'])) { $imgurl = $feed_element['#text']; } else if (!empty($feed_element['url']['#text'])) { $imgurl = $feed_element['url']['#text']; } } if (!empty($imgurl)) { // store image in temporary location $image = _filefield_feedapi_mapper_save_tmp($imgurl); // get field info $field = content_fields($field_name, $node->type); // retrieve all validators file must go through $validators = array_merge(filefield_widget_upload_validators($field), imagefield_widget_upload_validators($field)); // determine where to save image $files_path = filefield_widget_file_path($field); // save file and get imagefiled information $file = field_file_save_file($image, $validators, $files_path, FILE_EXISTS_REPLACE); // set / replace first imagefield for content type $node->{$field_name} = array(0 => $file); } } return $node; break; } } /** * save file from url into temporary location * * @param string $url * url to fetch contents from * @param integer $replace (optional) * not used for now, in theory to define whether to replace existing file or not * @return string * path to temporary file */ function _filefield_feedapi_mapper_save_tmp ($url, $replace = FILE_EXISTS_REPLACE) { if ($img = file_get_contents($url)) { // FIXME: clean up temp name for real $filename = basename($url); $filepath = realpath(file_directory_temp()) . DIRECTORY_SEPARATOR . 'tmp_filefield_' . $filename; if ($filepath && file_put_contents($filepath, $img)) { return $filepath; } } return FALSE; }