location_feeds.module in Location Feeds 7
Same filename and directory in other branches
This module provides location mappers to feed importers.
@author: Elliott Foster
File
location_feeds.moduleView source
<?php
/**
* @file
*
* This module provides location mappers to feed importers.
*
* @author: Elliott Foster
*/
/**
* Implements hook_enable().
*/
function location_feeds_enable() {
cache_clear_all('plugins:feeds:plugins', 'cache');
}
/**
* Implements feeds_node_processor_target_alter().
*
* @param $targets array of target fields
* @param $entity_type
* @param $bundle_name
*/
function location_feeds_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
if ($entity_type == 'node') {
// location.module logic
$settings = variable_get('location_settings_node_' . $bundle_name, array());
// Only add fields when collecting locations
if (isset($settings['multiple']['max']) && $settings['multiple']['max'] > 0) {
_location_feeds_location($targets, $settings);
}
// Location cck logic.
if (module_exists('location_cck')) {
$fields = field_read_fields(array(
'module' => 'location_cck',
));
$location_fields = _location_feeds_fields();
foreach ($fields as $field_name => $field) {
_location_feeds_fill_targets($targets, 'location_cck', $field_name, $location_fields);
}
}
}
else {
if ($entity_type == 'user') {
$settings = variable_get('location_settings_user', array());
// Only add fields when collecting locations
if (isset($settings['multiple']['max']) && $settings['multiple']['max'] > 0) {
_location_feeds_location($targets, $settings);
}
}
}
}
/**
* Helper function to handle node and user locations
*
* For sub elements we use the '][' construct
*
* @param $targets
* @param $settings
*/
function _location_feeds_location(&$targets, $settings) {
$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);
}
/**
* 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
*/
function _location_feeds_fill_targets(&$targets, $module, $field_name, $sub_fields) {
foreach ($sub_fields as $sub_field => $value) {
$callback = 'location_feeds_set_target';
if ($sub_field == 'country') {
$callback = 'location_feeds_set_country';
}
else {
if (strpos($sub_field, 'locpick]') !== FALSE) {
$callback = 'location_feeds_set_point';
}
}
$targets[$field_name . ':' . $sub_field] = array(
'name' => $module . " module: " . $field_name . '.' . t('@label', array(
'@label' => $value,
)),
'callback' => $callback,
'description' => t('The @label for the location of the node.', array(
'@label' => $sub_field,
)),
);
}
// support georss
$targets[$field_name . ':georss:point'] = array(
'name' => $module . " module:" . $field_name . " georss:point",
'callback' => 'location_feeds_set_georss_point',
'description' => t('Map a georss point to location points'),
);
}
/**
* 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;
}
/**
* Implements feed_set_target().
*
* @param $source
* Field mapper source settings.
* @param $entity
* Either a user or node object dpending on where this is called
* @param $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($source, $entity, $target, $value) {
list($field_name, $sub_field) = explode(':', $target);
if (strpos($sub_field, '][') !== FALSE) {
list($sub_field, $last_field) = explode('][', $sub_field, 2);
}
if (!is_array($value)) {
$value = array(
$value,
);
}
// Check if this is a cck field since they're added to the node
// differently.
$cck = preg_match('/^field_.+/', $target);
foreach ($value as $i => $val) {
$val = trim($val);
// location_cck has issues with empty fields, so bail if we find one.
if ($val !== FALSE && $val !== 0 && empty($val)) {
continue;
}
if (isset($last_field)) {
if ($cck) {
if (!isset($entity->{$field_name}['und'][$i]['location_settings'])) {
$entity->{$field_name}['und'][$i]['location_settings'] = location_feeds_get_field_info($field_name);
}
$entity->{$field_name}['und'][$i][$sub_field][$last_field] = $val;
}
else {
$entity->{$field_name}[$i][$sub_field][$last_field] = $val;
}
}
else {
if ($cck) {
if (!isset($entity->{$field_name}['und'][$i]['location_settings'])) {
$entity->{$field_name}['und'][$i]['location_settings'] = location_feeds_get_field_info($field_name);
}
$entity->{$field_name}['und'][$i][$sub_field] = $val;
}
else {
$entity->{$field_name}[$i][$sub_field] = $val;
}
}
}
return $entity;
}
/**
* Set the country and attempt to support non-iso country imports
*
* @param $source
* Field mapper source settings.
* @param $entity
* Either a user or node object dpending on where this is called
* @param $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_country($source, $entity, $target, $value) {
module_load_include('inc', 'location', 'location');
list($field_name, $sub_field) = explode(':', $target);
static $iso_list = array();
if (!is_array($value)) {
$value = array(
$value,
);
}
// Check if this is a cck field since they're added to the node
// differently.
$cck = preg_match('/^field_.+/', $target);
foreach ($value as $i => $val) {
$val = trim($val);
// if the country is in iso format or close to it, store
// it, else try to figure out the iso format
$isoval = $val;
if (location_standardize_country_code($isoval)) {
if ($cck) {
if (!isset($entity->{$field_name}['und'][$i]['location_settings'])) {
$entity->{$field_name}['und'][$i]['location_settings'] = location_feeds_get_field_info($field_name);
}
$entity->{$field_name}['und'][$i][$sub_field] = $isoval;
}
else {
$entity->{$field_name}[$i][$sub_field] = $isoval;
}
}
else {
// only load this once...
if (sizeof($iso_list) == 0) {
$iso_list = location_get_iso3166_list();
}
$keys = array_keys($iso_list, $val);
if (isset($keys[0])) {
if ($cck) {
if (!isset($entity->{$field_name}['und'][$i]['location_settings'])) {
$entity->{$field_name}['und'][$i]['location_settings'] = location_feeds_get_field_info($field_name);
}
$entity->{$field_name}['und'][$i][$sub_field] = $keys[0];
}
else {
$entity->{$field_name}[$i][$sub_field] = $keys[0];
}
}
}
}
return $entity;
}
/**
* Sets a latitude or longitude point for the node
* and attempts to recognize either decimal or DMS
* notation.
*
* @param $source
* Field mapper source settings.
* @param object $entity
* @param string $target
* The target that invoked this
* @param $value
* @return $entity
*/
function location_feeds_set_point($source, $entity, $target, $value) {
list($field_name, $sub_field) = explode(':', $target);
if (strpos($sub_field, '][') !== FALSE) {
list($sub_field, $last_field) = explode('][', $sub_field, 2);
}
if (!is_array($value)) {
$value = array(
$value,
);
}
// Check if this is a cck field since they're added to the node
// differently.
$cck = preg_match('/^field_.+/', $target);
foreach ($value as $i => $val) {
$val = trim($val);
// Attempt to set a value for DMS notation.
if (!is_numeric($val)) {
$neg = FALSE;
if (strpos($val, '-') === 0) {
$neg = TRUE;
}
$val = trim(preg_replace('/[^\\d\\s\\.WSws]/', '', $val));
$dms = explode(' ', $val);
// Account for '77° 02' 15.691" W' format.
if (count($dms) == 4) {
if ($dms[3] == 'W' || $dms[3] == 'w' || $dms[3] == 'S' || $dms[3] == 's') {
$neg = TRUE;
unset($dms[3]);
}
}
if (count($dms) == 3) {
$val = (abs($dms[0]) + $dms[1] / 60 + $dms[2] / 3600) * ($neg ? -1 : 1);
}
}
if (isset($last_field)) {
if ($cck) {
if (!isset($entity->{$field_name}['und'][$i]['location_settings'])) {
$entity->{$field_name}['und'][$i]['location_settings'] = location_feeds_get_field_info($field_name);
}
$entity->{$field_name}['und'][$i][$sub_field][$last_field] = $val;
}
else {
$entity->{$field_name}[$i][$sub_field][$last_field] = $val;
}
}
else {
if ($cck) {
if (!isset($entity->{$field_name}['und'][$i]['location_settings'])) {
$entity->{$field_name}['und'][$i]['location_settings'] = location_feeds_get_field_info($field_name);
}
$entity->{$field_name}['und'][$i][$sub_field] = $val;
}
else {
$entity->{$field_name}[$i][$sub_field] = $val;
}
}
}
return $entity;
}
/**
* Sets a georss:point value for the node
*
* @param $source
* Field mapper source settings.
* @param $entity
* Either a user or node object depending on where this is called
* @param $target
* The target that invoked this
* @param $value
* @return object
*/
function location_feeds_set_georss_point($source, $entity, $target, $value) {
list($field_name, $georss, $point) = explode(':', $target);
if (!is_array($value)) {
$value = array(
$value,
);
}
// Check if this is a cck field since they're added to the node
// differently.
$cck = preg_match('/^field_.+/', $target);
foreach ($value as $i => $val) {
$val = trim($val);
list($lat, $long) = explode(' ', $val);
if ($cck) {
if (!isset($entity->{$field_name}['und'][$i]['location_settings'])) {
$entity->{$field_name}['und'][$i]['location_settings'] = location_feeds_get_field_info($field_name);
}
$entity->{$field_name}['und'][$i]['latitude'] = $lat;
$entity->{$field_name}['und'][$i]['longitude'] = $long;
}
else {
$entity->{$field_name}[$i]['latitude'] = $lat;
$entity->{$field_name}[$i]['longitude'] = $long;
}
}
return $entity;
}
/**
* Returns location field level settings.
*
* @param $field_name
* The field name to return info for.
* @retrun
* The field info array.
*/
function location_feeds_get_field_info($field_name) {
$field_settings = field_info_field($field_name);
return $field_settings['settings']['location_settings'];
}
Functions
Name | Description |
---|---|
location_feeds_enable | Implements hook_enable(). |
location_feeds_feeds_processor_targets_alter | Implements feeds_node_processor_target_alter(). |
location_feeds_get_field_info | Returns location field level settings. |
location_feeds_set_country | Set the country and attempt to support non-iso country imports |
location_feeds_set_georss_point | Sets a georss:point value for the node |
location_feeds_set_point | Sets a latitude or longitude point for the node and attempts to recognize either decimal or DMS notation. |
location_feeds_set_target | Implements feed_set_target(). |
_location_feeds_fields | Helper function to get to manage target fields |
_location_feeds_fill_targets | Helper function to add target fields |
_location_feeds_location | Helper function to handle node and user locations |