geofield.feeds.inc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <?php
  2. /**
  3. * @file
  4. * Provides integration with Feeds module (http://drupal.org/project/feeds)
  5. */
  6. /**
  7. * Implements hook_feeds_parser_sources_alter().
  8. *
  9. * @see geofield_feeds_combined_source()
  10. */
  11. function geofield_feeds_parser_sources_alter(&$sources, $content_type) {
  12. $sources['geofield'] = array(
  13. 'name' => t('Geofield (combined)'),
  14. 'description' => t('All geographic information from the item.'),
  15. 'callback' => 'geofield_feeds_combined_source',
  16. );
  17. }
  18. /**
  19. * Callback; Provides a source combining geo information from items.
  20. *
  21. * Currently handles geo output from:
  22. * - simplepie 1.3
  23. * - common syndication parser (feeds 7.x-2.x)
  24. *
  25. * @param $source
  26. * The FeedsSource object being imported.
  27. * @param $result
  28. * The FeedsParserResult object being mapped from.
  29. * @param $key
  30. * The key specified in the $sources array in
  31. * hook_feeds_parser_sources_alter().
  32. *
  33. * @return
  34. * The value to be extracted from the source.
  35. *
  36. * @see geofield_feeds_parser_sources_alter()
  37. */
  38. function geofield_feeds_combined_source($source, FeedsParserResult $result, $key) {
  39. $values = array();
  40. $item = $result->currentItem();
  41. // Simplepie 1.3 output
  42. if (isset($item['location_latitude'])) {
  43. // Lon X; lat Y
  44. foreach ($item['location_latitude'] as $key => $lat) {
  45. $point = array('lat' => $lat, 'lon' => $item['location_longitude'][$key]);
  46. $values[] = geofield_compute_values($point, 'latlon');
  47. }
  48. }
  49. // Common Syndication Parser
  50. elseif (isset($item['geolocations'][0]) && is_a($item['geolocations'][0], 'FeedsGeoTermElement')) {
  51. // Presently Common Syndication Parser is just parsing points?
  52. // and is creating FeedsGeoTermElements, which is possibly not so useful.
  53. // Maybe better if we could read access the original item, or add in to the item parsing?
  54. foreach ($item['geolocations'] as $geolocation) {
  55. $point = array('lat' => $geolocation->lat, 'lon' => $geolocation->lon);
  56. $values[] = geofield_compute_values($point, 'latlon');
  57. }
  58. }
  59. return $values;
  60. }
  61. /**
  62. * Implements hook_feeds_node_processor_targets_alter().
  63. */
  64. function geofield_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
  65. foreach (field_info_instances($entity_type, $bundle_name) as $name => $instance) {
  66. $info = field_info_field($name);
  67. if ($info['type'] == 'geofield') {
  68. $targets[$info['field_name'] . ':wkt'] = array(
  69. 'name' => t($instance['label'] . ' WKT'),
  70. 'callback' => 'geofield_set_target_wkt',
  71. 'real_target' => $info['field_name'],
  72. );
  73. $targets[$info['field_name'] . ':lat'] = array(
  74. 'name' => t($instance['label'] . ' Latitude'),
  75. 'callback' => 'geofield_set_target_simple',
  76. 'real_target' => $info['field_name'],
  77. );
  78. $targets[$info['field_name'] . ':lon'] = array(
  79. 'name' => t($instance['label'] . ' Longitude'),
  80. 'callback' => 'geofield_set_target_simple',
  81. 'real_target' => $info['field_name'],
  82. );
  83. $targets[$info['field_name'] . ':left'] = array(
  84. 'name' => t($instance['label'] . ' Left Latitude'),
  85. 'callback' => 'geofield_set_target_simple',
  86. 'real_target' => $info['field_name'],
  87. );
  88. $targets[$info['field_name'] . ':top'] = array(
  89. 'name' => t($instance['label'] . ' Top Longitude'),
  90. 'callback' => 'geofield_set_target_simple',
  91. 'real_target' => $info['field_name'],
  92. );
  93. $targets[$info['field_name'] . ':right'] = array(
  94. 'name' => t($instance['label'] . ' Right Latitude'),
  95. 'callback' => 'geofield_set_target_simple',
  96. 'real_target' => $info['field_name'],
  97. );
  98. $targets[$info['field_name'] . ':bottom'] = array(
  99. 'name' => t($instance['label'] . ' Bottom Longitude'),
  100. 'callback' => 'geofield_set_target_simple',
  101. 'real_target' => $info['field_name'],
  102. );
  103. $targets[$info['field_name'] . ':combined'] = array(
  104. 'name' => t($instance['label'] . ' (combined)'),
  105. 'callback' => 'geofield_set_target_combined',
  106. 'real_target' => $info['field_name'],
  107. );
  108. }
  109. }
  110. }
  111. /**
  112. * Example callback specified in hook_feeds_processor_targets_alter().
  113. *
  114. * @param $source
  115. * Field mapper source settings.
  116. * @param $entity
  117. * An entity object, for instance a node object.
  118. * @param $target
  119. * A string identifying the target on the node.
  120. * @param $values
  121. * The values to populate the target with.
  122. *
  123. */
  124. function geofield_set_target_simple($source, $entity, $target, $values) {
  125. list($field_name, $sub_field) = explode(':', $target, 2);
  126. if (!is_array($values)) {
  127. $values = array($values);
  128. }
  129. $field = isset($entity->$field_name) ? $entity->$field_name : array(LANGUAGE_NONE => array());
  130. $delta = 0;
  131. foreach ($values as $value) {
  132. $field[LANGUAGE_NONE][$delta][$sub_field] = $value;
  133. $delta++;
  134. }
  135. // Compute all the geofield values for each field value.
  136. foreach ($field[LANGUAGE_NONE] as $delta => $value) {
  137. if (!empty($value['lat']) && !empty($value['lon'])) {
  138. $field[LANGUAGE_NONE][$delta] = geofield_compute_values($value, GEOFIELD_INPUT_LAT_LON);
  139. }
  140. elseif (!empty($value['top']) && !empty($value['right']) && !empty($value['bottom']) && !empty($value['left'])) {
  141. $value = array('geom' => $value);
  142. $field[LANGUAGE_NONE][$delta] = geofield_compute_values($value, GEOFIELD_INPUT_BOUNDS);
  143. }
  144. }
  145. $entity->$field_name = $field;
  146. }
  147. /**
  148. * Feeds processor target callback from the already combined source.
  149. *
  150. * @see geofield_feeds_parser_sources_alter()
  151. *
  152. * @param $source
  153. * Field mapper source settings.
  154. * @param $entity
  155. * An entity object, for instance a node object.
  156. * @param $target
  157. * A string identifying the target on the node.
  158. * @param $values
  159. * The values to populate the target with.
  160. *
  161. */
  162. function geofield_set_target_combined($source, $entity, $target, $values) {
  163. $field_name = substr($target, 0, strpos($target, ':'));
  164. _geofield_set_target($source, $entity, $field_name, $values);
  165. }
  166. /**
  167. * Feeds processor target callback for WKT source.
  168. */
  169. function geofield_set_target_wkt($source, $entity, $target, $values) {
  170. $field_name = substr($target, 0, strpos($target, ':'));
  171. if (!is_array($values)) {
  172. $values = array($values);
  173. }
  174. $geofield_values = array();
  175. foreach ($values as $wkt) {
  176. $field = array('geom' => $wkt);
  177. $geofield_values[] = geofield_compute_values($field, 'wkt');
  178. }
  179. _geofield_set_target($source, $entity, $field_name, $geofield_values);
  180. }
  181. /**
  182. * Helper function to set values and respect ordinality of field.
  183. *
  184. * Based on _field_feeds_set_target(). But type set, more keys than just value.
  185. *
  186. * @param $source
  187. * A FeedsSource object.
  188. * @param $entity
  189. * The entity to map to.
  190. * @param $target
  191. * The target key on $entity to map to.
  192. * @param $values
  193. * The value to map. MUST be an array.
  194. */
  195. function _geofield_set_target($source, $entity, $target, $values) {
  196. if (empty($values)) {
  197. return;
  198. }
  199. // Iterate over all values.
  200. $i = 0;
  201. $field = isset($entity->$target) ? $entity->$target : array(LANGUAGE_NONE => array());
  202. foreach ($values as $value) {
  203. // Check if field value is empty.
  204. if(empty($value)){
  205. continue;
  206. }
  207. if (is_array($value) || is_object($value)) {
  208. $field[LANGUAGE_NONE][$i] = $value;
  209. }
  210. $i++;
  211. }
  212. $entity->{$target} = $field;
  213. }