? .svn ? hook_feedapi_mapper.patch ? mappers/.svn Index: feedapi_mapper.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/sandbox/alex_b/feedapi_mapper/feedapi_mapper.module,v retrieving revision 1.21 diff -u -r1.21 feedapi_mapper.module --- feedapi_mapper.module 12 Nov 2007 19:57:19 -0000 1.21 +++ feedapi_mapper.module 21 Nov 2007 21:57:13 -0000 @@ -92,7 +92,7 @@ $element_path = unserialize($element_path); // Get the feed item element on $element_path and pass it into the mapping function. $feed_item_element = _feedapi_mapper_get_feed_item_element($element_path, $feed_item); - $node = call_user_func('feedapi_mapper_map_'. $field[0], 'map', $node, $feed_item_element, $field[1]); + $node = call_user_func($field[0] .'_feedapi_mapper', $field[1], 'map', $node, $feed_item_element, $field[2]); } } } @@ -134,7 +134,8 @@ $node_type_settings = _feedapi_get_settings(array('node_type' => $node->type)); $feed_item_type = $node_type_settings['processors']['feedapi_node']['content_type']; } - $node_fields = _feedapi_mapper_get_fields($feed_item_type); + $field_mappers = _feedapi_mapper_get_field_mappers($feed_item_type); + // Get elements of feed items. if ($merged_item = _feedapi_mapper_get_items_merged($node)) { $elements = _feedapi_mapper_get_feed_elements($merged_item); @@ -157,7 +158,7 @@ ); $form['feed_item']['item'] = array( '#type' => 'markup', - '#value' => '
'. print_r($merged_item, true) .'
', + '#value' => '
'. print_r(_feedapi_mapper_truncate_array($merged_item), true) .'
', ); } $form['nid'] = array( @@ -166,13 +167,33 @@ ); // Pass on feed item elements. $form['elements'] = array('#type' => 'value', '#value' => $elements); + // Print descriptions if there are any. + if ($descriptions = theme('feedapi_mapper_descriptions', _feedapi_mapper_get_field_mappers_descriptions($feed_item_type))) { + $form['descriptions'] = array( + '#type' => 'fieldset', + '#title' => t('Description of available mappers'), + '#collapsible' => TRUE, + '#collapsed' => FALSE, + '#tree' => TRUE, + ); + $form['descriptions']['descriptions'] = array( + '#type' => 'markup', + '#value' => $descriptions, + ); + } // Create mapping form. - $form['mapping'] = array('#tree' => TRUE); + $form['mapping'] = array( + '#type' => 'fieldset', + '#title' => t('Edit mapping'), + '#collapsible' => TRUE, + '#collapsed' => FALSE, + '#tree' => TRUE, + ); foreach ($elements as $element_name => $path) { $form['mapping'][$element_name] = array( '#type' => 'select', '#title' => $element_name, - '#options' => $node_fields, + '#options' => $field_mappers, '#default_value' => $mapping[$path], ); } @@ -193,11 +214,11 @@ /** * Store mapping. * @param $param - * node id or node type. + * node id or node type. * @param $mapping - * Mapping. + * Mapping. * @param $elements - * All elements of feed item. + * All elements of feed item. */ function _feedapi_mapper_store_mapping($param, $mapping, $elements) { // Wrap the mapping array (element_name => node_field) @@ -263,6 +284,8 @@ foreach($files as $file) { require_once("./$file->filename"); } + // Rebuild cache. + module_implements('', FALSE, TRUE); } $loaded = TRUE; } @@ -381,6 +404,22 @@ } /** + * Truncates all strings in cascaded array. + */ +function _feedapi_mapper_truncate_array($array) { + foreach ($array as $k => $v) { + if (is_string($v)) { + $array[$k] = strip_tags($v); + $array[$k] = truncate_utf8($array[$k], 200, TRUE, TRUE); + } + else if (is_array($v)) { + $array[$k] = _feedapi_mapper_truncate_array($v); + } + } + return $array; +} + +/** * Like array_merge_recursive. Only difference: does NOT merge * two different keys into an array, but merges key on key. * Argument 1 always has to be an array. @@ -408,32 +447,68 @@ } /** - * Get fields for a given node type. + * Get field mappers for a given node type. Returns an array of all + * feed mappers that are applicable to this node type. + * @param $node_type + * Valid node type. + * @return + * Array of fields that are mappable for this content type. */ -function _feedapi_mapper_get_fields($node_type) { +function _feedapi_mapper_get_field_mappers($node_type) { // Not sure wether to take fields from node or from form... // Pro form: there might be elements on form that you can't see on node (?). $form = _feedapi_mapper_get_node_form($node_type); $node->type = $node_type; - $fields[0] = t('No mapping'); + $field_mappers[0] = t('No mapping'); // Load all available mappers and create an array of fields available as mapping target. _feedapi_mapper_load_mappers(); + $modules = module_implements('feedapi_mapper'); foreach ($form as $field_name => $field) { - if (function_exists('feedapi_mapper_map_'. $field_name)) { - if ($sub_fields = call_user_func('feedapi_mapper_map_'. $field_name, 'list', $node)) { + foreach ($modules as $module) { + if ($sub_fields = module_invoke($module, 'feedapi_mapper', $field_name, 'list', $node)) { + $field_category = t('Map to') .' '. $field_name .' '. t('(!module_name module)', array('!module_name' => $module)); if (is_array($sub_fields)) { - $fields[$field_name] = array(); + $field_mappers[$field_category] = array(); foreach ($sub_fields as $sub_field_id => $sub_field_name) { - $fields[$field_name][serialize(array($field_name, $sub_field_id))] = $sub_field_name; + $field_mappers[$field_category][serialize(array($module, $field_name, $sub_field_id))] = $sub_field_name; } } else { - $fields[serialize(array($field_name))] = $field_name; + $field_mappers[serialize(array($module, $field_name))] = $field_category; } } } } - return $fields; + return $field_mappers; +} + +/** + * Returns descriptions for all mappable fields of given node type. + * @return + * Array in the format + * array('field_name_a' => + * array('module_name_a' => 'Descriptive text'), + * 'module_name_b' => ...), + * 'field_name_b' => array(...), + * ); + */ +function _feedapi_mapper_get_field_mappers_descriptions($node_type) { + // Not sure wether to take fields from node or from form... + // Pro form: there might be elements on form that you can't see on node (?). + $form = _feedapi_mapper_get_node_form($node_type); + $node->type = $node_type; + // Load all available mappers and create an array of fields available as mapping target. + _feedapi_mapper_load_mappers(); + $modules = module_implements('feedapi_mapper'); + $descriptions = array(); + foreach ($form as $field_name => $field) { + foreach ($modules as $module) { + if ($description = module_invoke($module, 'feedapi_mapper', $field_name, 'describe', $node)) { + $descriptions[$field_name][$module] = $description; + } + } + } + return $descriptions; } function _feedapi_mapper_get_node_form($node_type) { @@ -449,4 +524,23 @@ drupal_process_form($form_id, $form); // return drupal_render_form($args[0], $form); return $form; +} + +/** + * Theming function for outputting result of _feedapi_mapper_get_field_mappers_descriptions(). + * @param $descriptions + * Result of _feedapi_mapper_get_field_mappers_descriptions(). + * @return + * HTML output. + */ +function theme_feedapi_mapper_descriptions($descriptions) { + $output .= '
'; + foreach ($descriptions as $field_mapper => $implementations) { + foreach ($implementations as $module => $description) { + $output .= '
'. $field_mapper .' '. t('(!module_name module)', array('!module_name' => $module)) .'
'; + $output .= '
'. $description .'
'; + } + } + $output .= '
'; + return $output; } \ No newline at end of file Index: mappers/feedapi_mapper_taxonomy.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/sandbox/alex_b/feedapi_mapper/mappers/feedapi_mapper_taxonomy.inc,v retrieving revision 1.2 diff -u -r1.2 feedapi_mapper_taxonomy.inc --- mappers/feedapi_mapper_taxonomy.inc 12 Nov 2007 19:57:21 -0000 1.2 +++ mappers/feedapi_mapper_taxonomy.inc 21 Nov 2007 21:57:13 -0000 @@ -22,29 +22,34 @@ * Heads up: for doing this, we will need to return a destinct name on 'list' or we use the * module name. */ -function feedapi_mapper_map_taxonomy($op = 'map', $node, $feed_element = array(), $sub_field = '') { - if ($op == 'list') { - if ($vocabularies = taxonomy_get_vocabularies($node->type)) { - foreach ($vocabularies as $v) { - $sub_fields[$v->vid] = $v->name; - } - return $sub_fields; +function taxonomy_feedapi_mapper($field, $op = 'map', $node, $feed_element = array(), $sub_field = '') { + if ($field == 'taxonomy') { + if ($op == 'describe') { + return t('Maps a string or an array of strings to taxonomy terms. Chose a vocabulary from sub options.'); } - return FALSE; - } - else if ($op == 'map') { - // Todo: some plausibility check of $feed_element - // Todo: security check of $feed_element - if (is_string($feed_element)) { - $feed_element = array($feed_element); + else if ($op == 'list') { + if ($vocabularies = taxonomy_get_vocabularies($node->type)) { + foreach ($vocabularies as $v) { + $sub_fields[$v->vid] = $v->name; + } + return $sub_fields; + } + return FALSE; } - if (is_array($feed_element)) { - if (!is_array($node->taxonomy)) { - $node->taxonomy = array(); + else if ($op == 'map') { + // Todo: some plausibility check of $feed_element + // Todo: security check of $feed_element + if (is_string($feed_element)) { + $feed_element = array($feed_element); + } + if (is_array($feed_element)) { + if (!is_array($node->taxonomy)) { + $node->taxonomy = array(); + } + $node->taxonomy = array_merge($node->taxonomy, _feedapi_mapper_create_terms($feed_element, $sub_field)); } - $node->taxonomy = array_merge($node->taxonomy, _feedapi_mapper_create_terms($feed_element, $sub_field)); + return $node; } - return $node; } }