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.