Home Forums General Issues Programmatic duplication


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

    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 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:

    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(
        // ignore specific FULLY NAMED fields
        $ignore = array(
        $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;
Viewing 9 posts - 1 through 9 (of 9 total)

You must be logged in to reply to this topic.