/[drupal]/contributions/modules/feedapi_mapper/feedapi_mapper.module
ViewVC logotype

Contents of /contributions/modules/feedapi_mapper/feedapi_mapper.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Tue Jul 14 17:18:22 2009 UTC (4 months, 2 weeks ago) by alexb
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--2
Changes since 1.1: +415 -208 lines
File MIME type: text/x-php
Merge changes in DRUPAL-6--1 into HEAD.
1 <?php
2 // $Id: feedapi_mapper.module,v 1.1.2.7.2.30 2009/07/14 01:25:16 alexb Exp $
3
4 /**
5 * Implementation of hook_help().
6 */
7 function feedapi_mapper_help($path, $arg) {
8 switch ($path) {
9 case 'admin/help#feedapi_mapper':
10 return t('FeedAPI Mapper - maps feed item elements to node fields');
11 case 'feedapi_mapper/full_name':
12 return t('FeedAPI Mapper - maps feed item elements to node fields');
13 }
14 }
15
16 /**
17 * Implementation of hook_menu().
18 */
19 function feedapi_mapper_menu() {
20 $items = array();
21 $items['node/%node/map'] = array(
22 'title' => 'Map',
23 'page callback' => 'feedapi_mapper_page',
24 'page arguments' => array(1),
25 'type' => MENU_LOCAL_TASK,
26 'access callback' => 'feedapi_mapper_access_mapper',
27 'access arguments' => array(1),
28 );
29 $items['node/%node/map/delete/%'] = array(
30 'title' => 'Delete',
31 'page callback' => 'drupal_get_form',
32 'page arguments' => array('feedapi_mapper_delete_form', 1, 4),
33 'type' => MENU_CALLBACK,
34 'access callback' => 'feedapi_mapper_access_mapper',
35 'access arguments' => array(1),
36 );
37 foreach (node_get_types() as $type) {
38 $type_url_str = str_replace('_', '-', $type->type);
39 $items['admin/content/node-type/'. $type_url_str .'/map'] = array(
40 'title' => 'Map',
41 'page callback' => 'feedapi_mapper_page',
42 'page arguments' => array(3),
43 'load arguments' => array(3),
44 'type' => MENU_LOCAL_TASK,
45 'access callback' => 'feedapi_mapper_access_mapper',
46 'access arguments' => array(3),
47 );
48 $items['admin/content/node-type/'. $type_url_str .'/map/delete/%'] = array(
49 'title' => 'Delete',
50 'page callback' => 'drupal_get_form',
51 'page arguments' => array('feedapi_mapper_delete_form', 3, 6),
52 'load arguments' => array(3),
53 'type' => MENU_LOCAL_TASK,
54 'access callback' => 'feedapi_mapper_access_mapper',
55 'access arguments' => array(3),
56 );
57 }
58 return $items;
59 }
60
61 /**
62 * Implementation of hook_nodeapi().
63 */
64 function feedapi_mapper_nodeapi(&$node, $op, $teaser, $page) {
65 switch ($op) {
66 case 'prepare':
67 if (isset($node->feedapi) && $node->feedapi->feed_item) {
68 _feedapi_mapper_map($node);
69 }
70 break;
71 }
72 }
73
74 /**
75 * Implementation of hook_theme().
76 */
77 function feedapi_mapper_theme() {
78 return array(
79 'feedapi_mapper_form' => array(
80 'arguments' => array('form'),
81 ),
82 'feedapi_mapper_descriptions' => array(
83 'arguments' => array('descriptions'),
84 ),
85 );
86 }
87
88 /**
89 * Theming function for outputting result of _feedapi_mapper_get_field_mappers_descriptions().
90 * @param $descriptions
91 * Result of _feedapi_mapper_get_field_mappers_descriptions().
92 * @return
93 * HTML output.
94 */
95 function theme_feedapi_mapper_descriptions($descriptions) {
96 $output = '<dl>';
97 foreach ($descriptions as $module => $description) {
98 $output .= '<dt><strong>'. t('(!module_name module)', array('!module_name' => $module)) .'</strong></dt>';
99 $output .= '<dd>'. $description .'</dd>';
100 }
101 $output .= '</dl>';
102 return $output;
103 }
104
105 /**
106 * Theming function for showing the current mapping.
107 */
108 function theme_feedapi_mapper_form($form) {
109 $output = '';
110
111 $url = isset($form['#node']->nid) ?
112 'node/' . $form['#node']->nid .'/map/delete/' :
113 'admin/content/node-type/'. $form['#node']->type .'/map/delete/';
114 foreach ($form['#mapping'] as $feed_path => $node_path) {
115 $rows[] = array(
116 $form['#feed_map'][$feed_path],
117 $form['#field_map'][$node_path],
118 l(t('Delete'), $url . base64_encode($feed_path)),
119 );
120 }
121
122 $rows[] = array(
123 drupal_render($form['source']),
124 drupal_render($form['target']),
125 drupal_render($form['add']),
126 );
127
128 $form['mapping']['table']['#value'] = theme('table', array(t('Feed item'), t('Node')), $rows);
129
130 $output .= drupal_render($form);
131
132 return $output;
133 }
134
135 /**
136 * Determine whether current user can map on a given content type.
137 * Primarily used as menu acess callback. @see feedapi_mapper_menu()
138 *
139 * @param $node
140 * String that defines a content type or node object.
141 * @return
142 * TRUE if current user can map feed elements AND content type is feed enabled.
143 * FALSE otherwise.
144 */
145 function feedapi_mapper_access_mapper($node) {
146 if (user_access('administer feedapi')) {
147 if (is_string($node)) {
148 // String comes from directly from path, substitute - with _.
149 $node_type = str_replace('-', '_', $node);
150 }
151 elseif (is_string($node->type)) {
152 $node_type = $node->type;
153 }
154 else {
155 return FALSE;
156 }
157 $settings = feedapi_get_settings($node_type);
158 if (!empty($settings['processors']['feedapi_node']['enabled'])) {
159 return TRUE;
160 }
161 }
162 return FALSE;
163 }
164
165 /**
166 * Map feed item elements to node.
167 */
168 function _feedapi_mapper_map(&$node) {
169 // Load mapping stored for this node.
170 $feed_node = node_load($node->feedapi->feed_nid);
171 if (!$mapping = _feedapi_mapper_load_mapping($node->feedapi->feed_nid)) {
172 $mapping = _feedapi_mapper_load_mapping($feed_node->type);
173 }
174 if ($mapping) {
175 // Load available mappers.
176 _feedapi_mapper_load_mappers();
177 // Convert item to array:
178 $feed_item = _feedapi_mapper_obj2array($node->feedapi->feed_item);
179 $feed_item = _feedapi_mapper_simplify_raw($feed_item, $feed_node->feed->parsers);
180 foreach ($mapping as $element_path => $field) {
181 if ($field) { // Double check if field is set - @todo: this step could be skipped.
182 $field = unserialize($field);
183 $element_path = unserialize($element_path);
184 // Get the feed item element on $element_path and pass it into the mapping function.
185 $feed_item_element = _feedapi_mapper_get_feed_item_element($element_path, $feed_item);
186 $node = call_user_func($field[0] .'_feedapi_mapper', 'map', $node, $feed_item_element, $field[1], isset($field[2]) ? $field[2] : NULL);
187 }
188 }
189 }
190 }
191
192 /**
193 * Returns feed item element on given path.
194 */
195 function _feedapi_mapper_get_feed_item_element($path, $item) {
196 $p = array_shift($path);
197 if (count($path) > 0) {
198 return _feedapi_mapper_get_feed_item_element($path, $item[$p]);
199 }
200 else if (isset($item[$p])) {
201 return $item[$p];
202 }
203 }
204
205
206 /**
207 * Page callback for deleting field mapings.
208 */
209 function feedapi_mapper_delete_form($form_state, $param, $encoded_key) {
210 $form = array();
211 $key = base64_decode($encoded_key);
212 if (is_string($param)) {
213 $node = new stdClass();
214 $node->type = str_replace('-', '_', $param);
215 $path = 'admin/content/node-type/'. $param .'/map';
216 }
217 else {
218 $node = $param;
219 $path = "node/{$node->nid}/map";
220 }
221
222 $form['#node'] = $node;
223 $form['#redirect'] = $path;
224 $form['#source'] = $key;
225
226 return confirm_form($form,
227 t('Are you sure you want to delete this mapping?'),
228 $path,
229 t('Are you sure you want to delete the mapping for the %path feed element? This cannot be undone.', array('%path' => join('->', unserialize($key)))),
230 t('Delete'), t('Cancel')
231 );
232 }
233
234 function feedapi_mapper_delete_form_submit($form, &$form_state) {
235 $param = isset($form['#node']->nid) ? $form['#node']->nid : $form['#node']->type;
236 feedapi_mapper_delete_mapping($param, $form['#source']);
237 drupal_set_message(t('The mapping entry has been deleted successfully'));
238 }
239
240 /**
241 * Callback function for hook_menu().
242 */
243 function feedapi_mapper_page($node) {
244 if (is_string($node)) {
245 $node_type = $node;
246 $node = new stdClass();
247 $node->type = str_replace('-', '_', $node_type);
248 }
249 $names = node_get_types('names');
250 drupal_set_title(check_plain($node->title ? $node->title : $names[$node->type]));
251 $output = t('Map feed item elements to feed item node fields.');
252 $output .= drupal_get_form('feedapi_mapper_form', $node);
253 return $output;
254 }
255
256 /**
257 * Mapping form.
258 */
259 function feedapi_mapper_form($form_state, $node) {
260 // Get fields of node type with available feed element mappers.
261 if (isset($node->feed->settings['processors']['feedapi_node']['content_type'])) {
262 $settings = $node->feed->settings;
263 }
264 else {
265 $settings = feedapi_get_settings($node->type);
266 }
267 $feed_item_type = $settings['processors']['feedapi_node']['content_type'];
268 $field_map = _feedapi_mapper_get_field_mappers($feed_item_type);
269
270 // Get elements of feed items.
271 $elements = array();
272 if ($merged_item = _feedapi_mapper_get_items_merged($node)) {
273 $merged_item = _feedapi_mapper_simplify_raw($merged_item, $node->feed->parsers);
274 $elements = _feedapi_mapper_get_feed_elements($merged_item);
275 }
276 $elements = array_merge($elements, _feedapi_mapper_get_standard_elements());
277 asort($elements);
278 $feed_map = array_flip($elements);
279
280 // Load stored mapping.
281 if (!$mapping = _feedapi_mapper_load_mapping($node->nid)) {
282 $mapping = _feedapi_mapper_load_mapping($node->type);
283 }
284
285 $form['#node'] = $node;
286
287 $form['#feed_map'] = $feed_map;
288 $form['#field_map'] = $field_map;
289 // Flatten array for theme_feedapi_mapper_form().
290 foreach ($form['#field_map'] as $k => $v) {
291 if (is_array($v)) {
292 unset($form['#field_map'][$k]);
293 $form['#field_map'] = array_merge($form['#field_map'], $v);
294 }
295 }
296 $form['#mapping'] = $mapping;
297 // Create a placeholder for mapping form elements. This will be populated in
298 // theme_feedapi_mapper_form().
299 $form['mapping'] = array(
300 '#type' => 'fieldset',
301 '#title' => t('Mapping'),
302 );
303
304 // Filter out maps that already exist from our list since we don't support multiple mappings.
305 $feed_map_options = array_merge(array(t('Select a source')), $feed_map);
306 foreach ($mapping as $feed_path => $node_path) {
307 if (isset($feed_map_options[$feed_path])) {
308 unset($feed_map_options[$feed_path]);
309 }
310 }
311 $field_map_options = array_merge(array(t('Select a target')), $field_map);
312 foreach ($mapping as $feed_path => $node_path) {
313 if (isset($field_map_options[$node_path])) {
314 unset($field_map_options[$node_path]);
315 }
316 }
317
318 $form['source'] = array(
319 '#type' => 'select',
320 '#options' => $feed_map_options,
321 );
322 $form['target'] = array(
323 '#type' => 'select',
324 '#options' => $field_map_options,
325 );
326 $form['add'] = array(
327 '#type' => 'submit',
328 '#value' => t('Add'),
329 );
330
331 // Print descriptions for available mapping targets.
332 // This is done by iterating through $field_map and extracting module names from it.
333 $descriptions = _feedapi_mapper_get_field_mappers_descriptions($feed_item_type);
334 $descriptions_filtered = array();
335 foreach ($field_map as $key => $target) {
336 if (is_array($target)) {
337 $key = unserialize(key($target));
338 }
339 else {
340 $key = unserialize($key);
341 }
342 if (is_array($key)) {
343 $module = $key[0];
344 $descriptions_filtered[$module] = $descriptions[$module];
345 }
346 }
347
348 if ($merged_item) {
349 $form['feed_item'] = array(
350 '#type' => 'fieldset',
351 '#title' => t('Feed item example'),
352 '#collapsible' => TRUE,
353 '#collapsed' => TRUE,
354 '#description' => t('All feed items of this feed merged into one. Here you can see which feed item elements are available for mapping. As this view is derived from the actual feed items on this feed, there might be more mappable elements than those listed here.'),
355 );
356 $form['feed_item']['item'] = array(
357 '#type' => 'markup',
358 '#value' => '<pre>'. print_r(_feedapi_mapper_truncate_array($merged_item), TRUE) .'</pre>',
359 );
360 }
361
362 if ($descriptions = theme('feedapi_mapper_descriptions', $descriptions_filtered)) {
363 $form['descriptions'] = array(
364 '#type' => 'fieldset',
365 '#title' => t('Description of available mappers'),
366 '#description' => t('This is a list of mappers available for the <em>feed item</em> content type for this feed.'),
367 '#tree' => TRUE,
368 );
369 $form['descriptions']['descriptions'] = array(
370 '#type' => 'markup',
371 '#value' => $descriptions,
372 );
373 }
374
375 return $form;
376 }
377
378 /**
379 * Validate hook.
380 */
381 function feedapi_mapper_form_validate($form, &$form_state) {
382 if (empty($form_state['values']['source'])) {
383 form_set_error('source', t('You need to specify a valid source from the dropdown list.'));
384 }
385 elseif (empty($form_state['values']['target'])) {
386 form_set_error('target', t('You need to specify a valid destination from the dropdown list.'));
387 }
388 }
389
390 /**
391 * Submit hook.
392 */
393 function feedapi_mapper_form_submit($form, &$form_state) {
394 $param = $form['#node']->nid ? $form['#node']->nid : $form['#node']->type;
395 feedapi_mapper_add_mapping($param, $form_state['values']['source'], $form_state['values']['target']);
396 }
397
398 /**
399 * Add an additional map to a given mapping.
400 *
401 * @param $param
402 * Either a node id of a node type. Used to determine storage.
403 * @param $source
404 * A serialized string mapping to the source feed element.
405 * @param $target
406 * A serialized string mapping to the target node element.
407 */
408 function feedapi_mapper_add_mapping($param, $source, $target) {
409 if (is_numeric($param)) {
410 $map = unserialize(db_result(db_query('SELECT mapping FROM {feedapi_mapper} WHERE nid = %d', $param)));
411 if (is_array($map)) {
412 $map[$source] = $target;
413 db_query('UPDATE {feedapi_mapper} SET mapping = \'%s\' WHERE nid = %d', serialize($map), $param);
414 }
415 else {
416 $map = array($source => $target);
417 db_query("INSERT INTO {feedapi_mapper} (nid, mapping) VALUES (%d, '%s')", $param, serialize($map));
418 }
419 }
420 else if (is_string($param)) {
421 $variable = 'feedapi_mapper_mapping_'. $param;
422 $map = variable_get($variable, array());
423 $map[$source] = $target;
424 variable_set($variable, $map);
425 }
426 }
427
428 function feedapi_mapper_delete_mapping($param, $source) {
429 if (is_numeric($param)) {
430 if ($map = unserialize(db_result(db_query('SELECT mapping FROM {feedapi_mapper} WHERE nid = %d', $param)))) {
431 unset($map[$source]);
432 db_query('UPDATE {feedapi_mapper} SET mapping = \'%s\' WHERE nid = %d', serialize($map), $param);
433 }
434 }
435 else if (is_string($param)) {
436 $variable = 'feedapi_mapper_mapping_'. $param;
437 $map = variable_get($variable, array());
438 unset($map[$source]);
439 variable_set($variable, $map);
440 }
441 }
442
443 /**
444 * Retrieve mapping from db.
445 * @param $param
446 * node id or node type
447 * @return
448 * Associative array in the format
449 * array(
450 * element_path1 => node_field1,
451 * element_path2 => node_field2,
452 * );
453 * where element_pathx and node_fieldx are both serialized arrays.
454 */
455 function _feedapi_mapper_load_mapping($param) {
456 static $mappings;
457 if (is_numeric($param)) {
458 if (isset($mappings[$param])) {
459 return $mappings[$param];
460 }
461 if ($mapping = db_result(db_query('SELECT mapping FROM {feedapi_mapper} WHERE nid = %d', $param))) {
462 $mappings[$param] = unserialize($mapping);
463 return $mappings[$param];
464 }
465 }
466 else if (is_string($param)) {
467 return variable_get('feedapi_mapper_mapping_'. $param, array());
468 }
469 }
470
471 /**
472 * Load mapper implementations.
473 */
474 function _feedapi_mapper_load_mappers() {
475 static $loaded = FALSE;
476 if (!$loaded) {
477 // Load all feedapi mapper implementations from ./mappers
478 $path = drupal_get_path('module', 'feedapi_mapper') .'/mappers';
479 $files = drupal_system_listing('.*\.inc$', $path, 'name', 0);
480 foreach ($files as $file) {
481 require_once("./$file->filename");
482 }
483 // Rebuild cache.
484 module_implements('', FALSE, TRUE);
485 }
486 $loaded = TRUE;
487 }
488
489 /**
490 * @todo: move this function to feedapi as feedapi_parse().
491 */
492 function _feedapi_parse($feed) {
493 return _feedapi_call_parsers($feed, $feed->parsers, $feed->half_done ? FALSE : TRUE);
494 }
495
496 /**
497 * Simplifies options->raw item on feed item.
498 */
499 function _feedapi_mapper_simplify_raw($item, $parsers) {
500 if (isset($item['options']['raw'])) {
501 if (in_array('parser_simplepie', $parsers)) {
502 $item['options']['raw'] = parser_simplepie_simplify_raw_item($item['options']['raw']);
503 }
504 }
505 return $item;
506 }
507
508 /**
509 * Returns all feed items on node as one merged item.
510 */
511 function _feedapi_mapper_get_items_merged($node) {
512 if ($node->feed) {
513 $feed = _feedapi_parse($node->feed);
514 // Convert items to array.
515 $items = _feedapi_mapper_obj2array($feed->items);
516 // Merge items to one item.
517 $merged = NULL;
518 if (is_array($items)) {
519 $i = 0;
520 foreach ($items as $item) {
521 if ($i++ > 10) {
522 break;
523 }
524 $merged = _feedapi_mapper_array_merge_recursive($item, $merged);
525 }
526 }
527 return $merged;
528 }
529 }
530
531 /**
532 * Sister function of _feedapi_mapper_get_feed_elements().
533 * Returns array in same format. Only difference: does not take
534 * a real feed that it analyzes, but returns some standard elements.
535 *
536 * Standard elements:
537 *
538 * options-&gt;original_author-&gt;name
539 * options-&gt;original_author-&gt;picture
540 * options-&gt;original_author
541 * options-&gt;tags
542 *
543 * Implement hook_feedapi_mapper_elements() to add custom standard
544 * elements.
545 *
546 * @see hook_feedapi_mapper_elements().
547 *
548 * @return
549 * Array in the format array('pathname' => 'serializedpath')
550 */
551 function _feedapi_mapper_get_standard_elements() {
552 $paths = array();
553 $paths[] = array('options', 'original_author', 'name');
554 $paths[] = array('options', 'original_author', 'picture');
555 $paths[] = array('options', 'original_author');
556 $paths[] = array('options', 'tags');
557 // hook_feedapi_mapper_elements() - allow other modules to add paths.
558 // These should be in the exact same format as the paths above, i.e.:
559 // array(array('foo', 'bar'), array('fnargle', 'bargle'),);
560 foreach (module_implements('feedapi_mapper_elements') as $module) {
561 $result = call_user_func($module .'_feedapi_mapper_elements');
562 if (is_array($result)) {
563 $paths = array_merge($paths, $result);
564 }
565 }
566
567 foreach ($paths as $path) {
568 $elements[implode('->', $path)] = serialize($path);
569 }
570 return $elements;
571 }
572
573 /**
574 * Takes a feed item and retrieves paths to all elements.
575 * Use a merged feed item (_feedapi_mapper_get_items_merged()) for best results.
576 *
577 * @return
578 * Array in the format array('pathname' => 'serializedpath')
579 */
580 function _feedapi_mapper_get_feed_elements($merged_item) {
581 // Retrieve paths to elements in merged item.
582 // Stick them into an array where the key is the serialized path and the value is the element name.
583 $elements = array();
584 while (count($merged_item)) {
585 $path = array();
586 $path = _feedapi_mapper_next_element_path($merged_item, $path, TRUE);
587 if ($path == FALSE) {
588 break;
589 }
590 $elements[implode('->', $path)] = serialize($path);
591 }
592 return $elements;
593 }
594
595 /**
596 * Traverse an associative array and look for path to first leaf.
597 * If found, unset leaf and return path to it.
598 *
599 * @return
600 * A path to a leaf element in the format
601 * array(path, to, leaf, element);
602 */
603 function _feedapi_mapper_next_element_path(&$items, &$path, $reset_count = FALSE) {
604 // This recursion is a bit shaky. Put on breaks.
605 static $i = 0;
606 $i++;
607 if ($reset_count) {
608 $i = 0;
609 }
610 if ($i > 200) {
611 drupal_set_message(t('Error in recursion _feedapi_mapper_next_element_path()'), 'error');
612 return FALSE;
613 }
614 foreach ($items as $key => $value) {
615 $path[] = $key;
616 // Recurse if value is array and if it contains elements.
617 if (is_array($items[$key]) && count($items[$key])) {
618 // Arrays with keys of 0 are not considered collections of same items - reached a leaf.
619 if (isset($items[$key][0])) {
620 unset($items[$key]);
621 return $path;
622 }
623 else if ($result_path = _feedapi_mapper_next_element_path($items[$key], $path)) {
624 // Leaf was found, pass it up.
625 return $result_path;
626 }
627 }
628 else {
629 // Reached leaf, unset it and return path to it.
630 unset($items[$key]);
631 return $path;
632 }
633 }
634 // No leaves found in this pass.
635 return FALSE;
636 }
637
638 /**
639 * Converts a multidemensional associative array with interdispersed objects into
640 * an associative array only.
641 */
642 function _feedapi_mapper_obj2array($items) {
643 if (is_object($items)) {
644 $items = (array) $items;
645 }
646 if (is_array($items)) {
647 foreach ($items as $key => $value) {
648 $items[$key] = _feedapi_mapper_obj2array($value);
649 }
650 }
651 return $items;
652 }
653
654 /**
655 * Truncates all strings in cascaded array.
656 */
657 function _feedapi_mapper_truncate_array($array) {
658 foreach ($array as $k => $v) {
659 if (is_string($v)) {
660 $array[$k] = strip_tags($v);
661 $array[$k] = truncate_utf8($array[$k], 200, TRUE, TRUE);
662 }
663 else if (is_array($v)) {
664 $array[$k] = _feedapi_mapper_truncate_array($v);
665 }
666 }
667 return $array;
668 }
669
670 /**
671 * Like array_merge_recursive. Only difference: does NOT merge
672 * two different keys into an array, but merges key on key.
673 * Argument 1 always has to be an array.
674 */
675 function _feedapi_mapper_array_merge_recursive($array1, $array2) {
676 $result = NULL;
677 foreach ($array1 as $k => $v) {
678 if (is_array($array1[$k])) {
679 $result[$k] = _feedapi_mapper_array_merge_recursive($array1[$k], isset($array2[$k]) ? $array2[$k] : NULL);
680 }
681 else {
682 $result[$k] = $array1[$k];
683 }
684 }
685 if (is_array($array2)) {
686 foreach ($array2 as $k => $v) {
687 if (is_array($array2[$k])) {
688 $result[$k] = _feedapi_mapper_array_merge_recursive($array2[$k], isset($array1[$k]) ? $array1[$k] : NULL);
689 }
690 else {
691 $result[$k] = $array2[$k];
692 }
693 }
694 }
695 return $result;
696 }
697
698 /**
699 * Get field mappers for a given node type. Returns an array of all
700 * feed mappers that are applicable to this node type.
701 * @param $node_type
702 * Valid node type.
703 * @return
704 * Array of fields that are mappable for this content type.
705 */
706 function _feedapi_mapper_get_field_mappers($node_type) {
707 $node = new stdClass();
708 $node->type = $node_type;
709
710 // Load all available mappers and create an array of fields available as mapping target.
711 _feedapi_mapper_load_mappers();
712 $modules = module_implements('feedapi_mapper');
713 foreach ($modules as $module) {
714 if ($fields = module_invoke($module, 'feedapi_mapper', 'list', $node)) {
715 foreach ($fields as $field_name => $sub_fields) {
716 $field_label = is_string($sub_fields) ? $sub_fields : $field_name;
717 $field_category = t('Map to @field (@module)', array('@field' => $field_label, '@module' => $module));
718 if (is_array($sub_fields)) {
719 foreach ($sub_fields as $sub_field_id => $sub_field_name) {
720 $field_mappers[$field_category][serialize(array($module, $field_name, $sub_field_id))] = $field_category .': '. $sub_field_name;
721 }
722 }
723 else {
724 $field_mappers[serialize(array($module, $field_name))] = $field_category;
725 }
726 }
727 }
728 }
729
730 return $field_mappers;
731 }
732
733 /**
734 * Returns descriptions for all mappable fields of given node type.
735 * @return
736 * Array in the format
737 * array('field_name_a' =>
738 * array('module_name_a' => 'Descriptive text'),
739 * 'module_name_b' => ...),
740 * 'field_name_b' => array(...),
741 * );
742 */
743 function _feedapi_mapper_get_field_mappers_descriptions($node_type) {
744 $node = new stdClass();
745 $node->type = $node_type;
746 // Load all available mappers and create an array of fields available as mapping target.
747 _feedapi_mapper_load_mappers();
748 $modules = module_implements('feedapi_mapper');
749 $descriptions = array();
750 foreach ($modules as $module) {
751 if ($description = module_invoke($module, 'feedapi_mapper', 'describe', $node)) {
752 $descriptions[$module] = $description;
753 }
754 }
755 return $descriptions;
756 }

  ViewVC Help
Powered by ViewVC 1.1.2