Skip to content

Commit 3f21f66

Browse files
committed
Enable location geocoding
1 parent eced48e commit 3f21f66

7 files changed

Lines changed: 792 additions & 27 deletions

File tree

dt-import/LOCATION_IMPORT_GUIDE.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Location Field Import Guide
2+
3+
This guide explains how to import location data using the DT CSV Import feature.
4+
5+
## Location Field Types
6+
7+
### 1. `location_grid`
8+
- **Purpose**: Direct reference to location grid entries
9+
- **Required Format**: Numeric grid ID only
10+
- **Example**: `12345`
11+
- **Validation**: Must be a valid grid ID that exists in the location grid table
12+
13+
### 2. `location_grid_meta`
14+
- **Purpose**: Flexible location data with optional geocoding
15+
- **Supported Formats**:
16+
- **Numeric grid ID**: `12345`
17+
- **Coordinates**: `40.7128, -74.0060` (latitude, longitude)
18+
- **Address**: `123 Main St, New York, NY 10001`
19+
- **Geocoding**: Can use Google Maps or Mapbox to convert addresses to coordinates
20+
21+
### 3. `location` (Legacy)
22+
- **Purpose**: Generic location field
23+
- **Behavior**:
24+
- Numeric values treated as grid IDs
25+
- Other values treated as location_grid_meta
26+
27+
## Geocoding Services
28+
29+
### Available Services
30+
1. **Google Maps** - Requires Google Maps API key
31+
2. **Mapbox** - Requires Mapbox API key
32+
3. **None** - No geocoding (addresses saved as-is)
33+
34+
### Geocoding Process
35+
When a geocoding service is selected:
36+
37+
1. **Addresses** → Converted to coordinates → Assigned to location grid
38+
2. **Coordinates** → Assigned to location grid → Address lookup (reverse geocoding)
39+
3. **Grid IDs** → Validated and used directly
40+
41+
### Rate Limiting
42+
- Automatic delays added for large imports to respect API limits
43+
- Batch processing available for performance
44+
45+
## CSV Format Examples
46+
47+
### location_grid Field
48+
```csv
49+
name,location_grid
50+
John Doe,12345
51+
Jane Smith,67890
52+
```
53+
54+
### location_grid_meta Field
55+
```csv
56+
name,location_grid_meta
57+
John Doe,12345
58+
Jane Smith,"40.7128, -74.0060"
59+
Bob Johnson,"123 Main St, New York, NY"
60+
```
61+
62+
### Mixed Location Data
63+
```csv
64+
name,location_grid_meta,notes
65+
Person 1,12345,Direct grid ID
66+
Person 2,"40.7128, -74.0060",Coordinates
67+
Person 3,"New York City",Address (requires geocoding)
68+
```
69+
70+
## Configuration
71+
72+
### Setting Up Geocoding
73+
1. Configure API keys in DT settings:
74+
- Google Maps: Settings → Mapping → Google Maps API
75+
- Mapbox: Settings → Mapping → Mapbox API
76+
77+
2. Select geocoding service during import process
78+
79+
### Import Process
80+
1. Upload CSV file
81+
2. Map columns to fields
82+
3. For location_grid_meta fields, select geocoding service
83+
4. Preview import to verify location processing
84+
5. Execute import
85+
86+
## Error Handling
87+
88+
### Common Issues
89+
- **Invalid grid ID**: Non-existent grid IDs will cause import errors
90+
- **Invalid coordinates**: Out-of-range lat/lng values will be rejected
91+
- **Geocoding failures**: Addresses that can't be geocoded will be saved as-is with error notes
92+
- **API limits**: Rate limiting may slow down large imports
93+
94+
### Error Resolution
95+
- Check API key configuration
96+
- Verify data formats
97+
- Review geocoding service status
98+
- Use smaller batch sizes for large imports
99+
100+
## Best Practices
101+
102+
1. **Validate Data**: Check grid IDs and coordinate formats before import
103+
2. **Use Consistent Formats**: Stick to one format per field when possible
104+
3. **Test Small Batches**: Test with a few records before large imports
105+
4. **Monitor API Usage**: Be aware of geocoding API limits and costs
106+
5. **Backup Data**: Always backup before large imports
107+
108+
## Technical Details
109+
110+
### Field Handlers
111+
- `handle_location_grid_field()`: Validates numeric grid IDs
112+
- `handle_location_grid_meta_field()`: Processes flexible location data
113+
- `DT_CSV_Import_Geocoding`: Handles all geocoding operations
114+
115+
### Data Flow
116+
1. Raw CSV value input
117+
2. Field type detection
118+
3. Format validation
119+
4. Geocoding (if enabled)
120+
5. Location grid assignment
121+
6. Data formatting for DT_Posts API
122+
7. Record creation
123+
124+
### Performance Considerations
125+
- Geocoding adds processing time
126+
- Large imports may take longer with geocoding enabled
127+
- Background processing available for large datasets
128+
- Progress tracking during import
129+
130+
## Support
131+
132+
For issues with location imports:
133+
1. Check error logs for detailed error messages
134+
2. Verify API key configuration
135+
3. Test with sample data
136+
4. Review CSV format requirements
137+
5. Contact system administrator if needed

dt-import/admin/dt-import-admin-tab.php

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ private function enqueue_admin_scripts() {
102102
'postTypes' => $this->get_available_post_types(),
103103
'translations' => $this->get_translations(),
104104
'fieldTypes' => $this->get_field_types(),
105+
'geocodingServices' => $this->get_geocoding_services(),
105106
'maxFileSize' => $this->get_max_file_size(),
106107
'allowedFileTypes' => [ 'text/csv', 'application/csv', 'text/plain' ]
107108
]);
@@ -190,7 +191,16 @@ private function get_translations() {
190191
'warnings' => __( 'Warnings', 'disciple_tools' ),
191192
'importWarnings' => __( 'Import Warnings', 'disciple_tools' ),
192193
'newRecordsWillBeCreated' => __( 'Some records will create new connection records. Review the preview below for details.', 'disciple_tools' ),
193-
'newRecordIndicator' => __( '(NEW)', 'disciple_tools' )
194+
'newRecordIndicator' => __( '(NEW)', 'disciple_tools' ),
195+
196+
// Geocoding translations
197+
'geocodingService' => __( 'Geocoding Service', 'disciple_tools' ),
198+
'selectGeocodingService' => __( 'Select a geocoding service to convert addresses to coordinates', 'disciple_tools' ),
199+
'geocodingNote' => __( 'Note: Geocoding will be applied to location_meta fields that contain addresses or coordinates', 'disciple_tools' ),
200+
'geocodingOptional' => __( 'Geocoding is optional - you can import without it', 'disciple_tools' ),
201+
'locationInfo' => __( 'location fields accept grid IDs, coordinates (lat,lng), or addresses', 'disciple_tools' ),
202+
'locationMetaInfo' => __( 'location_meta fields accept grid IDs, coordinates (lat,lng), or addresses', 'disciple_tools' ),
203+
'noGeocodingService' => __( 'No geocoding service is available. Please configure Google Maps or Mapbox API keys.', 'disciple_tools' )
194204
];
195205
}
196206

@@ -207,8 +217,27 @@ private function get_field_types() {
207217
'communication_channel' => __( 'Communication Channel', 'disciple_tools' ),
208218
'connection' => __( 'Connection', 'disciple_tools' ),
209219
'user_select' => __( 'User Select', 'disciple_tools' ),
210-
'location' => __( 'Location', 'disciple_tools' )
220+
'location' => __( 'Location', 'disciple_tools' ),
221+
'location_meta' => __( 'Location Meta', 'disciple_tools' )
222+
];
223+
}
224+
225+
private function get_geocoding_services() {
226+
$available_services = DT_CSV_Import_Geocoding::get_available_geocoding_services();
227+
228+
$services = [
229+
'none' => __( 'No Geocoding', 'disciple_tools' )
211230
];
231+
232+
if ( in_array( 'google', $available_services ) ) {
233+
$services['google'] = __( 'Google Maps', 'disciple_tools' );
234+
}
235+
236+
if ( in_array( 'mapbox', $available_services ) ) {
237+
$services['mapbox'] = __( 'Mapbox', 'disciple_tools' );
238+
}
239+
240+
return $services;
212241
}
213242

214243
private function get_max_file_size() {

dt-import/admin/dt-import-processor.php

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,13 @@ public static function process_field_value( $raw_value, $field_key, $mapping, $p
179179
case 'location':
180180
return self::process_location_value( $raw_value );
181181

182+
case 'location_grid':
183+
return self::process_location_grid_value( $raw_value );
184+
185+
case 'location_meta':
186+
$geocode_service = $mapping['geocode_service'] ?? 'none';
187+
return self::process_location_grid_meta_value( $raw_value, $geocode_service );
188+
182189
default:
183190
return sanitize_text_field( trim( $raw_value ) );
184191
}
@@ -449,6 +456,21 @@ private static function process_location_value( $raw_value ) {
449456
];
450457
}
451458

459+
/**
460+
* Process location_grid field value
461+
*/
462+
private static function process_location_grid_value( $raw_value ) {
463+
return DT_CSV_Import_Field_Handlers::handle_location_grid_field( $raw_value, [] );
464+
}
465+
466+
/**
467+
* Process location_grid_meta field value
468+
*/
469+
private static function process_location_grid_meta_value( $raw_value, $geocode_service ) {
470+
$result = DT_CSV_Import_Field_Handlers::handle_location_grid_meta_field( $raw_value, [], $geocode_service );
471+
return $result;
472+
}
473+
452474
/**
453475
* Format processed value for DT_Posts API according to field type
454476
*/
@@ -514,6 +536,28 @@ public static function format_value_for_api( $processed_value, $field_key, $post
514536
}
515537
break;
516538

539+
case 'location_grid':
540+
// Format location grid ID for DT_Posts API
541+
if ( is_numeric( $processed_value ) ) {
542+
return [
543+
'values' => [
544+
[ 'value' => $processed_value ]
545+
]
546+
];
547+
}
548+
break;
549+
550+
case 'location_meta':
551+
// Format location meta for DT_Posts API (same as location_grid_meta)
552+
if ( is_array( $processed_value ) && !empty( $processed_value ) ) {
553+
return [
554+
'values' => [
555+
$processed_value
556+
]
557+
];
558+
}
559+
break;
560+
517561
case 'user_select':
518562
// Convert single user ID to proper format
519563
if ( is_numeric( $processed_value ) ) {
@@ -605,9 +649,11 @@ public static function execute_import( $session_id ) {
605649

606650
if ( is_wp_error( $result ) ) {
607651
$error_count++;
652+
$error_message = $result->get_error_message();
653+
608654
$errors[] = [
609655
'row' => $row_index + 2,
610-
'message' => $result->get_error_message()
656+
'message' => $error_message
611657
];
612658
} else {
613659
$imported_count++;

0 commit comments

Comments
 (0)