Skip to content

Instantly share code, notes, and snippets.

@gthayer
Last active November 11, 2022 20:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gthayer/0d71df7cb325549cc37661f1c9378fd9 to your computer and use it in GitHub Desktop.
Save gthayer/0d71df7cb325549cc37661f1c9378fd9 to your computer and use it in GitHub Desktop.
//add_action('wp_head', 'update_meta_values');
function update_meta_values() {
/*
* Takes a set of fields and resets them as part of a repeater
* To start, create a new repeater field and enter the slug in $new_repeater
* Find the fields you would like to move in wp_posts and set the post_parent to the new repeater's ID
*/
// Slug of the new repeater
$new_repeater = 'repeater_field';
// Set the fields you would like to move's slugs in $rows
$rows = array(
'foo',
'bar'
);
// Query the effected posts
$args = array(
'post_type' => array( 'cpt_post_type' ),
'posts_per_page' => -1
);
$posts = get_posts($args);
foreach ($posts as $post) {
// Update Meta Fields
$id = $post->ID;
$meta = get_post_meta( $id );
unset($updated);
// Loop each posts Meta values
foreach ( $meta as $key => $value ) {
// Loop the possible fields
foreach ( $rows as $row ) {
//Check if field name is in meta value
if ( strpos( $key, $row ) !== false ) {
// Grab the value's name, prepend it with the repeater name.
$new_post_meta = str_replace( $row, $new_repeater . '_0_' . $row , $key );
// Add new meta
update_post_meta( $id, $new_post_meta, $value[0] );
// Delete old meta
delete_post_meta( $id, $key );
$updated = true;
break;
}
}
}
// If this post has repeater rows, mark it with 1
if ($updated) {
update_post_meta( $id, 'resource_list', 1 );
update_post_meta( $id, '_resource_list', 'field_574ee7028384d' );
}
}
}
@schalkjoubert
Copy link

Hi, this is exactly what I'm looking for, but can't get it to work.
Could you possibly please put me in the right direction?
Do I add this to my theme's functions.php

Thank you!

I attached a screenshot of my my ACF and here is a link to my json export.
https://gist.github.com/schalkjoubert/cb55a02baf20ecc6e4733881c739ca98

Post Type: catalogue
Repeater Field: sale_catalogue_entry
Fields to move to Repeater Fields 9 as subfields ):
sales_lot_number
sales_ram_number
sales_symbol
sales_birth_status
sales_wean_mat_ebv
sales_wean_mat_symbol
etc. etc etc.

acf-move-fields-to-sub-fiedl-repeater

@carlosromanxyz
Copy link

@schalkjoubert Wow! Please consider add a Blank field and blank value inside repeater, with this, user can feel free to add any data in catalogue admin section.

I think that cleans up your code and gives the database a break

@webdev2178
Copy link

Hi Gary - This is the code I need! But cannot get it to work. I have one field that I need to move into a repeater.

'presentation-repeater' is my new repeater field (parent)
'presentation' is the old individual field I want to move

Do I need to define new field inside repeater? That field slug is 'associated_doc'
I appreciate any help you can offer!
Here is my code:

function update_meta_values() {

// Slug of the new repeater
$new_repeater = 'presentation-repeater';

// Set the fields you would like to move's slugs in $rows
$rows = array(
	'presentation'
);

// Query the effected posts
$args = array(
	'post_type' => array( 'resource' ),
	'posts_per_page' => -1
);

$posts = get_posts($args);

foreach ($posts as $post) {

	// Update Meta Fields
	$id = $post->ID;
	$meta = get_post_meta( $id );
	unset($updated);

	// Loop each posts Meta values
	foreach ( $meta as $key => $value ) {
		
		// Loop the possible fields
		foreach ( $rows as $row ) {
			
			//Check if field name is in meta value
			if ( strpos( $key, $row ) !== false ) {

				// Grab the value's name, prepend it with the repeater name.
				$new_post_meta = str_replace( $row, $new_repeater . '_0_' . $row , $key );
				
				// Add new meta
				update_post_meta( $id, $new_post_meta, $value[0] );
				
				// Delete old meta
				delete_post_meta( $id, $key );
				$updated = true;
				break;
			}
		}
	}

	// If this post has repeater rows, mark it with 1
	if ($updated) {
		update_post_meta( $id, 'resource_list', 1 );
		update_post_meta( $id, '_resource_list', 'field_574ee7028384d' );
	}

}

}

@gthayer
Copy link
Author

gthayer commented Apr 10, 2020

@webdev2178 - I believe you need to define the repeater field in ACF before running this script. This script is for the migration of the field values, not the field settings themselves.

However, to be honest, I've not used ACF in about 2 years and I don't have a strong memory of this exact use case.

You might also want to look into field_574ee7028384d. I don't remember why that was set, but my guess is it was specific to my case.

@abdechakour
Copy link

Thank you for this hack

I found how to do it directly in the back office
First you have to add a subfield to the repeater field and save
Then drag the desired field and drop it in the sub-fields block of the repeater

@kodie
Copy link

kodie commented Nov 11, 2022

@gthayer Thank you for this. I ended up taking your code and running with it for a plugin/WP CLI command: https://github.com/kodie/migrate-acf-field-data-to-repeater

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment