What I learned today: 2024-12-23
In one WordPress project in which I had to implement a function that handles a csv file uploaded with ACF field into a product custom post type and automatically populates an ACF repeater field.
The first version of the function was:
### Version 1
```php
function populate_technical_specifications_from_csv( $post_id ) {
// Check if it's a 'product' custom post type
if ( get_post_type( $post_id ) !== 'product' ) {
return;
}
// Get the uploaded file from the ACF field
$file = get_field('upload_technical_specification', $post_id);
// Make sure file exists and it's a CSV
if ( ! $file || pathinfo( $file['url'], PATHINFO_EXTENSION ) !== 'csv' ) {
return;
}
// Get the file path
$file_path = $file['url'];
// Open the file for reading
if ( ($handle = fopen( $file_path, 'r' )) !== FALSE ) {
// Skip the first line if it has column headings
$header = fgetcsv($handle);
// Prepare the data for repeater field
$repeater_data = array();
while ( ($row = fgetcsv($handle)) !== FALSE ) {
// Assuming the CSV columns are in the order: specification_name, specification_description
$repeater_data[] = array(
'specification_name' => $row[0], // First column
'specification_description' => $row[1], // Second column
);
}
fclose($handle);
// Check if there's any data to import
if ( ! empty( $repeater_data ) ) {
// First, clear existing repeater rows
delete_field('technical_specification', $post_id);
// Add new rows to the repeater field
foreach ( $repeater_data as $index => $spec ) {
add_row( 'technical_specification', $spec, $post_id );
}
}
}
}
add_action('save_post', 'populate_technical_specifications_from_csv', 20);
```
The problem was that in this version the function was working only if the csv delimiter was "," but what if the csv delimiter was let's say ";" or something else like "|"? In my case the only other option was ";" so I made the following modification:
### Version 2
```php
function populate_technical_specifications_from_csv( $post_id ) {
// Check if it's a 'product' custom post type
if ( get_post_type( $post_id ) !== 'product' ) {
return;
}
// Get the uploaded file from the ACF field
$file = get_field('upload_technical_specification', $post_id);
// Make sure file exists and it's a CSV
if ( ! $file || pathinfo( $file['url'], PATHINFO_EXTENSION ) !== 'csv' ) {
return;
}
// Get the file path
$file_path = $file['url'];
// Detect delimiter dynamically
$delimiter = ',';
if ( ( $handle = fopen( $file_path, 'r' ) ) !== FALSE ) {
$line = fgets( $handle );
fclose( $handle );
if ( strpos( $line, ';' ) !== FALSE ) {
$delimiter = ';';
}
}
// Open the file for reading
if ( ($handle = fopen( $file_path, 'r' )) !== FALSE ) {
// Skip the first line if it has column headings
$header = fgetcsv($handle, 0, $delimiter);
// Prepare the data for repeater field
$repeater_data = array();
while ( ($row = fgetcsv($handle, 0, $delimiter)) !== FALSE ) {
// Assuming the CSV columns are in the order: specification_name, specification_description
$repeater_data[] = array(
'specification_name' => $row[0], // First column
'specification_description' => $row[1], // Second column
);
}
fclose($handle);
// Check if there's any data to import
if ( ! empty( $repeater_data ) ) {
// First, clear existing repeater rows
delete_field('technical_specification', $post_id);
// Add new rows to the repeater field
foreach ( $repeater_data as $index => $spec ) {
add_row( 'technical_specification', $spec, $post_id );
}
}
}
}
add_action('save_post', 'populate_technical_specifications_from_csv', 20);
```
In this version on line 20 the function checks if the file delimiter is ";" and if so it uses the ";" as a delimiter if not it reverts to "," as a delimiter.