Home › Forums › General Issues › Programmatic duplication
Hello – I need to duplicate posts and their meta by code. I also need to carry over their ACF fields. Therefore, I must do my own implementation of what ACF has done for WPML (~/core/wpml.php) for very similar reasons.
Without success, I was under the impression that I could have duplicated ACF fields and content from one post to another using :
$fields = get_field_objects($originalPostId);
acf_duplicate_fields($fields, $duplicatePostId);
Has any one ever played with ACF’s internals enough to explain the linking hierarchy from a post to it’s acf-fields ? Obviously, just copying the post metas doesn’t help because the unique field key doesn’t change.
Any help appreciated.
I’m not 100% certain, didn’t dig that far, but I think the function you’re calling acf_duplicate_fields();
is an internal ACF function that’s used to either duplicate a field group or to duplicated fields inside a field group and not to duplicate the meta values associated with a post.
If you need to manually duplicate all of the post meta attached to a post then use.
$meta = get_post_meta($post_id);
when used without a meta_key
this returns an array of all meta values attached to a post. For more information see the codex here https://developer.wordpress.org/reference/functions/get_post_meta/
Then you’d need to loop through this array and use add_post_meta()
for each key in the array to add it to the new post. As far as I know there isn’t a function to add all the meta values in one go.
Thank you, and you are right on all accounts.
Everything “works” when I copy the meta values, but the “field_abc123” key still references the original post and so everything breaks when we re-save the copy post.
That’s why I was looking at the internal functions to find something that would have generated the new field groups.
I’m a little confused about why the field key references the old post if you get all the meta from one post and add them to another.
You should end up with something like.
post_id meta_key meta_value
{old_post} field_name value
{old_post} _field_name field_1234567890123
{new_post} field_name value
{new_post} _field_name field_1234567890123
The field keys should still be the same with a different post_id, unless you’re trying to also put the fields into a duplicated field group with different field keys.
Either that or I’m completely lost about what you’re trying to accomplish. If you’re just trying to duplicate a post have you tried https://wordpress.org/plugins/duplicate-post/. It works well with ACF.
Are you implying that two (or more) entries of field_1234567890123 shouldn’t break ACF’s datasources and that these two posts could be updated separately?
I expected field_1234567890123 to have to be unique throughout. It could mean I have issues with my side of the code then, which is quite possible, and I would close this thread.
That’s correct. As long as that field key is associated with another post ID. Field keys are only unique for a field group. The same field key is used for all meta values related to you field.
Awesome that information should help me debug the rest. Thanks for your time
Sorry to resurrect such an old thread, but I was wondering if you managed to find a solution, and whether you could share the approach?
Huge thanks in advance
Nevermind, ended up coding it myself (in this case, I want to clone a user’s meta). Code below for anyone else who might be interested:
clone_user_meta(16,8);
function clone_user_meta($source_user,$destination_user) {
// check the users exist
if(!user_exists($source_user) || !user_exists($destination_user)) {
return new WP_Error('whoops', __( "One of the specified users does not exist", 'my_textdomain' ));
}
// ignore any fields BEGINNING WITH
$ignore_wildcard = array(
'billing_',
'shipping_',
);
// ignore specific FULLY NAMED fields
$ignore = array(
'nickname',
'first_name',
'last_name',
);
$source_meta = get_user_meta($source_user);
foreach($source_meta as $key => $value) {
// the current key is not in the $ignore list, continue
if(!in_array($key, $ignore)) {
$skip = false;
// check if the current key matches a "wildcard ignore"
foreach($ignore_wildcard as $wildcard_key) {
if(starts_with($wildcard_key,$key)) {
$skip = true;
break; // we found one! break out of the loop
}
}
if(!$skip && $value[0] != '') { // valid field to clone
update_user_meta($destination_user,$key,$value); // add/update the value
}
}
}
return true;
}
function starts_with($needle, $haystack) {
return strpos($haystack, $needle, 0)=== 0 ? true : false;
}
function user_exists($user_id) {
$user = get_userdata($user_id);
if ($user === false) {
return false;
}
return true;
}
The topic ‘Programmatic duplication’ is closed to new replies.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.