Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Copy an author's cpt custom field/s to the author's normal posts WordPress

I'm trying to copy an author's CPT post custom field (and value) to the same author's normal post.

Here's the scenario...
Author publishes a CPT post with a custom field, then the same author publishes a normal post. I want the normal post to be automatically populated/updated with the custom field (and value) of the previous CPT post.

When the custom field/s of the CPT post is updated so should the custom field of the author's normal posts.

Here's what I have so far, the problem is the normal post custom field is populated with the last CPT post of ANY author, not the normal post's author...

I'm also using this with the front end posting plugin WP User Frontend Pro, however when I try to post from the front end it(publishing) throws an error, but not on the backend.

I want to be able to edit the code to add specific CPT custom field/s.
I want each/all custom field/s to be updated on the normal posts whenever the cpt custom field/s are updated.

This might help as well...
[[LINK href="http://wpquestions.com/question/showChronoLoggedIn/id/10746"]]http://wpquestions.com/question/showChronoLoggedIn/id/10746[[/LINK]]

This is the code so far that doesn't work from Stack Exchange
[[LINK href="http://wordpress.stackexchange.com/questions/203349/how-to-copy-a-users-custom-field-from-the-users-cpt-to-the-users-posts"]]http://wordpress.stackexchange.com/questions/203349/how-to-copy-a-users-custom-field-from-the-users-cpt-to-the-users-posts[[/LINK]]

function wpse_203349_copy_post_meta( $post_ID, $post, $update ) {
if ( $post->post_type !== 'post' )
return;

$users_custom_posts = get_posts(
array(
'posts_per_page' => 1,
'post_author' => $post->post_author,
'post_type' => 'custom_post_type',
)
);

if ( ! $users_custom_posts )
return; // This author doesn't currently have any custom posts

$fields = get_post_custom( $users_custom_posts[0]->ID );

foreach ( $fields as $field => $value ) {
if ( $field[0] !== '_' && ( empty( $value[0] ) || ! is_array( $value[0] ) ) ) // Ignore "private" fields (prefixed with an underscore or serialized data)
add_post_meta( $post_ID, $field, empty( $value[0] ) ? '' : $value[0], true /* Unique */ ); // If the field already exists, it won't be overwritten, unlike update_post_meta()
}
}

add_action( 'wp_insert_post', 'wpse_203349_copy_post_meta', 10, 3 );


Thanks

Answers (2)

2015-09-23

Arnav Joy answers:

Hi ,

I think I can help you with this .. but I will have to check your site and would need access to it.

So please add me on skype : arnav.joy


pjeaje comments:

Can you please try to help without access. The previous wpquestions link just used the plugin hooks


pjeaje comments:

I'll pm you


pjeaje comments:

Arnav Joy no longer available


pjeaje comments:

Unfortunately Arnav Joy uses the "skype me" tactic then demands double what he was going to do the work for. If you don't like my price, 1. say so here, 2. don't tell me you can do it.

[quote]
[9:18:47 PM] Arnav Joy: $50 ?
[9:18:56 PM] Pete and Angus: what?
[9:19:10 PM] Pete and Angus: as per the wpquestions
[9:19:10 PM] Arnav Joy: I would like to have $50 for this work
[9:19:23 PM] Pete and Angus: is this how you operate?
[9:19:37 PM] Pete and Angus: you ask me to skype you then raise your price?
[9:19:56 PM] Arnav Joy: you can see other person are written that the price is too low
[9:20:11 PM] Arnav Joy: so we could either post msg there or talk here on skype
[9:20:16 PM] Arnav Joy: but cost is too low for it
[9:20:39 PM] Pete and Angus: i think you like to manipulate the user into paying you more
[9:20:53 PM] Pete and Angus: if it is too low why did you agree on wp questions?
[9:21:07 PM] Arnav Joy: I have not agreed .. I just wanted to discuss
[9:21:19 PM] Pete and Angus: no, you agreed on wpquestions
[9:21:20 PM] Arnav Joy: I have not taken anything from you yet
[9:22:18 PM] Pete and Angus: i don't like your manipulative methods
[9:22:32 PM] Arnav Joy: don't like then don't talk
[9:22:44 PM] Arnav Joy: I am too busy my friend


Arnav Joy comments:

You are happy to post it here ?? This will solve your problem ?if yes then post it 100 times .. if no then try to concentrate on your work.

2015-09-23

dimadin answers:

You do not have any code that is working, right? Because this code you have posted is not doing anything you want.

I can create code that whenever a new post of CPT is made creates a new post of "Post" post type and copies custom meta fields, however, syncing it when CPT is edited is way more advanced and needs to be tested well so it can't be done immediately nor for amount you offer.

Also, I don't see how is error from WP User Frontend Pro related to this, it is separate problem.


dimadin comments:

I can create code that creates new post whenever new CPT is made with fields copied from CPT.

Updating that post when CPT is updated is more advanced and tested, and although I can do it too, can't be done immediately and for this small amount.

I don't see how error for WP User Frontend Pro is related to this, it should be separate problem.


pjeaje comments:

OK, is it easy to update the custom field when the normal lost is updated then?

See here for the WPUF plugin action hooks...

http://docs.wedevs.com/using-action-hook-field/


pjeaje comments:

OK, is it easy to update the custom field when the normal lost is updated then?

See here for the WPUF plugin action hooks...

http://docs.wedevs.com/using-action-hook-field/


dimadin comments:

Here is a code that will copy content of 'cpt' when it is created to 'post'.

Replace 'cpt' with name of your custom post type.

Also replace 'custom_meta_field' with name of custom meta field that you want to copy. If you need multiple custom meta fields, just copy that line how many time is needed.

It is tested with default admin new/edit screens and it works. I don't know will it work with WPUF plugin.



/**
* Copy CPT to post when it is published.
*
* @param int $post_ID Post ID.
* @param WP_Post $_post Post object.
*/
function md_copy_cpt_to_post( $post_ID, $_post ) {
// If new is 'publish'
if ( 'publish' != $_post->post_status ) {
return;
}

// If new is 'cpt' and old is not 'publish'
if ( 'cpt' != $_post->post_type ) {
return;
}

$sibling = false;

// Is this new post or update
if ( $sibling = get_post_meta( $post_ID, '_md_sibling_post', true ) ) {
// Update existing post with updated 'cpt'

// Create post object
$new_post_args = array(
'ID' => $sibling,
'post_title' => $_post->post_title,
'post_title' => $_post->post_title,
'post_content' => $_post->post_content,
'post_author' => $_post->post_author,
'post_status' => $_post->post_status,
);

// Insert the post into the database
$new_post_id = wp_insert_post( $new_post_args );
} else {
// We should first insert a new post

// Create post object
$new_post_args = array(
'post_title' => $_post->post_title,
'post_content' => $_post->post_content,
'post_author' => $_post->post_author,
'post_status' => $_post->post_status,
);

// Insert the post into the database
$new_post_id = wp_insert_post( $new_post_args );

// Check if it isn't error
if ( ! is_wp_error( $new_post_id ) ) {
// Save sibling ID
$sibling = $new_post_id;

// Save relationship details to both posts
add_post_meta( $new_post_id, '_md_sibling_post', $post_ID );
add_post_meta( $post_ID, '_md_sibling_post', $new_post_id );
}
}

// Check if sibling exists
if ( ! $sibling ) {
return;
}

// Copy meta field from 'cpt' to 'post'
update_post_meta( $sibling, 'custom_meta_field', get_post_meta( $post_ID, 'custom_meta_field', true ) );
}
add_action( 'wp_insert_post', 'md_copy_cpt_to_post', 10, 2 );


pjeaje comments:

Thanks but i need it to work with WPUF Pro... here's a link to their hooks
http://docs.wedevs.com/category/plugins/wp-user-frontend-pro/developer-documentation/actions/


dimadin comments:

Please first try it. If they use native, standard functions for inserting/updating posts this should work there too.


pjeaje comments:

They don't


pjeaje comments:

It didn't work... the custom field and the value did not copy to the post


pjeaje comments:

It didn't work... the custom field and the value did not copy to the post (via the front end form)

http://wpquestions.com/question/showChronoLoggedIn/id/10746


pjeaje comments:

It doesn't work even if i post from the backend in admin


pjeaje comments:

any luck?


pjeaje comments:

https://wordpress.org/support/topic/copy-an-authors-cpt-post-custom-field-to-the-same-authors-normal-post?replies=3


dimadin comments:

I don't have access to WPUF Pro but based on their documentation this should work alongside with previous code I have already posted:


/**
* Copy CPT to post when it is published via WPUF.
*
* @param int $post_ID Post ID.
*/
function md_copy_cpt_to_post_wpuf( $post_ID ) {
// Use other function
md_copy_cpt_to_post( $post_ID, get_post( $post_ID ) );
}
add_action( 'wpuf_add_post_after_insert', 'md_copy_cpt_to_post_wpuf' );
add_action( 'wpuf_edit_post_after_update', 'md_copy_cpt_to_post_wpuf' );


<blockquote>It doesn't work even if i post from the backend in admin</blockquote>

That is impossible, before writing here, I have personally tested this code and it should work, it uses native WordPress functions so it is not possible that it doesn't work, you either didn't follow steps I said (like replacing 'cpt' with you custom post type) or placed it where it shouldn't be.

If this doesn't help you, I can't do anything more from here, I need access to see what is going on because it should work.


pjeaje comments:

where does the above code go?


pjeaje comments:

Oh no... the code is copying <strong>the entire cpt post</strong> to the normal post type. I only want the custom field and it's value copied.


dimadin comments:

It should be placed in either your theme's functions.php file or in some of your plugins, preferably where you place your custom code.

Or, best solution, is to place it mu-plugins dir. Open your /wp-content directory. If there isn't already, create a new directory inside it called 'mu-plugins'. Then, in that 'mu-plugins' directory, create file that you can name however you wish, for example md-copy-cpt-to-post.php

In that file place following code:


<?php

/* Exit if accessed directly */
if ( ! defined( 'ABSPATH' ) ) exit;


/**

* Copy CPT to post when it is published.

*

* @param int $post_ID Post ID.

* @param WP_Post $_post Post object.

*/

function md_copy_cpt_to_post( $post_ID, $_post ) {

// If new is 'publish'

if ( 'publish' != $_post->post_status ) {

return;

}



// If new is 'cpt' and old is not 'publish'

if ( 'cpt' != $_post->post_type ) {

return;

}



$sibling = false;



// Is this new post or update

if ( $sibling = get_post_meta( $post_ID, '_md_sibling_post', true ) ) {

// Update existing post with updated 'cpt'



// Create post object

$new_post_args = array(

'ID' => $sibling,

'post_title' => $_post->post_title,

'post_title' => $_post->post_title,

'post_content' => $_post->post_content,

'post_author' => $_post->post_author,

'post_status' => $_post->post_status,

);



// Insert the post into the database

$new_post_id = wp_insert_post( $new_post_args );

} else {

// We should first insert a new post



// Create post object

$new_post_args = array(

'post_title' => $_post->post_title,

'post_content' => $_post->post_content,

'post_author' => $_post->post_author,

'post_status' => $_post->post_status,

);



// Insert the post into the database

$new_post_id = wp_insert_post( $new_post_args );



// Check if it isn't error

if ( ! is_wp_error( $new_post_id ) ) {

// Save sibling ID

$sibling = $new_post_id;



// Save relationship details to both posts

add_post_meta( $new_post_id, '_md_sibling_post', $post_ID );

add_post_meta( $post_ID, '_md_sibling_post', $new_post_id );

}

}



// Check if sibling exists

if ( ! $sibling ) {

return;

}



// Copy meta field from 'cpt' to 'post'

update_post_meta( $sibling, 'custom_meta_field', get_post_meta( $post_ID, 'custom_meta_field', true ) );

}

add_action( 'wp_insert_post', 'md_copy_cpt_to_post', 10, 2 );

/**

* Copy CPT to post when it is published via WPUF.

*

* @param int $post_ID Post ID.

*/

function md_copy_cpt_to_post_wpuf( $post_ID ) {

// Use other function

md_copy_cpt_to_post( $post_ID, get_post( $post_ID ) );

}

add_action( 'wpuf_add_post_after_insert', 'md_copy_cpt_to_post_wpuf' );

add_action( 'wpuf_edit_post_after_update', 'md_copy_cpt_to_post_wpuf' );



And then save it and it will be autoloaded.


dimadin comments:

<blockquote>Oh no... the code is copying the entire cpt post to the normal post type. I only want the custom field and it's value copied.</blockquote>

You should tell how title and content of new post will be, currently it does uses from original CPT because you haven't said anything.


pjeaje comments:

what? each time <strong>the author</strong> creates a new normal post the custom field "xyz" from the previous cpt is copied to that new normal post


pjeaje comments:

each time the author creates a new normal post the custom field "xyz" from the previous cpt the same author published is copied to that new normal post of the same author... am I clear?


pjeaje comments:

Do you have a fix for this?


dimadin comments:

No, you are not clear, instead of clarifying it now that you have some code that should be used as a starting point, you add even more confusion.

To make clear, here is what my code does without any modifications:

- You make post of 'cpt' post type, ABC
- When you publish it, new post of 'post' post type is created, DEF
- For that new 'post' post DEF, values of title, content, author, and of 'custom_meta_field' meta field are copied from 'cpt' post ABC

And second case, editing:

- You edit post of 'cpt' post type, ABC
- When you edit it, post of 'post' post type, DEF, is updated
- For that edited 'post' post DEF, values of title, content, author, and of 'custom_meta_field' meta field are copied from 'cpt' post ABC

Of course, these values can be changed, for example different title can be used, different meta fields etc, but this is starting point, I cannot change it when you are not clearly describing what you want exactly.

From my answers here or on other questions on this site it is very obvious that I know what I am doing. Problem is when person who requests help doesn't give precise description of what they wants.


pjeaje comments:

I created a mu-plugins folder
I copy and pasted the code below
The Author A CPT post is being duplicated as a normal Author A post, I don't want this.

<em>Author A creates a cpt post,
then Author A creates a normal post,
then only the custom field (and value) of the Author A cpt post is copied from the Author A cpt post to the Author A normal post/s
then when Author A updates cpt post the custom field is updated to all of author A's normal post/s.</em>


<?php



/* Exit if accessed directly */

if ( ! defined( 'ABSPATH' ) ) exit;





/**



* Copy CPT to post when it is published.



*



* @param int $post_ID Post ID.



* @param WP_Post $_post Post object.



*/



function md_copy_cpt_to_post( $post_ID, $_post ) {



// If new is 'publish'



if ( 'publish' != $_post->post_status ) {



return;



}







// If new is 'cpt' and old is not 'publish'



if ( 'employer' != $_post->post_type ) {



return;



}







$sibling = false;







// Is this new post or update



if ( $sibling = get_post_meta( $post_ID, '_md_sibling_post', true ) ) {



// Update existing post with updated 'cpt'







// Create post object



$new_post_args = array(



'ID' => $sibling,



'post_title' => $_post->post_title,



'post_title' => $_post->post_title,



'post_content' => $_post->post_content,



'post_author' => $_post->post_author,



'post_status' => $_post->post_status,



);







// Insert the post into the database



$new_post_id = wp_insert_post( $new_post_args );



} else {



// We should first insert a new post







// Create post object



$new_post_args = array(



'post_title' => $_post->post_title,



'post_content' => $_post->post_content,



'post_author' => $_post->post_author,



'post_status' => $_post->post_status,



);







// Insert the post into the database



$new_post_id = wp_insert_post( $new_post_args );







// Check if it isn't error



if ( ! is_wp_error( $new_post_id ) ) {



// Save sibling ID



$sibling = $new_post_id;







// Save relationship details to both posts



add_post_meta( $new_post_id, '_md_sibling_post', $post_ID );



add_post_meta( $post_ID, '_md_sibling_post', $new_post_id );



}



}







// Check if sibling exists



if ( ! $sibling ) {



return;



}







// Copy meta field from 'cpt' to 'post'



update_post_meta( $sibling, 'geo_address', get_post_meta( $post_ID, 'geo_address', true ) );



}



add_action( 'wp_insert_post', 'md_copy_cpt_to_post', 10, 2 );



/**



* Copy CPT to post when it is published via WPUF.



*



* @param int $post_ID Post ID.



*/



function md_copy_cpt_to_post_wpuf( $post_ID ) {



// Use other function



md_copy_cpt_to_post( $post_ID, get_post( $post_ID ) );



}



add_action( 'wpuf_add_post_after_insert', 'md_copy_cpt_to_post_wpuf' );



add_action( 'wpuf_edit_post_after_update', 'md_copy_cpt_to_post_wpuf' );


dimadin comments:

<blockquote>Author A creates a cpt post,
then Author A creates a normal post,
then only the custom field (and value) of the Author A cpt post is copied from the Author A cpt post to the Author A normal post/s
then when Author A updates cpt post the custom field is updated to all of author A's normal post/s.</blockquote>

OK, to summarize (lets ignore updating for a moment):

- You manually make post of 'cpt' post type, ABC
- You manually make post of 'post' post type, DEF
- When post DEF was created, meta field is copied from ABC

Am I right?

If so, you need some kind of connection between posts ABC and DEF so that we know where to take custom meta fields from. For example, you can have field on 'post' edit screen to choose this.

If you don't have, you can query posts like you did in initial question. However, this is not a good idea because there is no guarantee that this is right post. In some circumstances you will get right post, but that is not always case.


pjeaje comments:

<em>Am I right?</em> Yes.
<em>If so, you need some kind of connection between posts ABC and DEF so that we know where to take custom meta fields from.</em> Yes, the connection is the same author

- Author A manually make post of 'cpt' post type, ABC
- Author A make post of 'post' post type, DEF
- When post DEF was created, meta field is copied from ABC (must be same author)


dimadin comments:

OK, I think that this is not a good approach because one author can have multiple posts of 'cpt' types and in that case it is impossible to know from where you want to copy.

Now your code from the beginning makes sense. Does it work on admin or not? Do you need only code for WPFU or for both?


pjeaje comments:

<em>OK, I think that this is not a good approach because one author can have multiple posts of 'cpt' types and in that case it is impossible to know from where you want to copy.</em> Each Author will only have one cpt post, never multiple.

<em>Now your code from the beginning makes sense. Does it work on admin or not? Do you need only code for WPFU or for both?</em> Both


dimadin comments:

OK, for inserting a new post your example from begging is good but 'post_author' => $post->post_author needs to be 'author' => $post->post_author.

Then, for WPUF, you need to add slight modification.

You should replace 'cpt' with you post type. It is only for new posts, not updating.

So, whole code looks like this:


/**
* Copy CPT to post when post is published.
*
* @param int $post_ID Post ID.
* @param WP_Post $_post Post object.
* @param bool $update Is this update.
*/
function md_copy_cpt_to_post_2( $post_ID, $post, $update ) {
// This works only for 'post' post type
if ( $post->post_type !== 'post' ) {
return;
}

// Search for latest post of 'cpt' post type by same user
$users_custom_posts = get_posts(
array(
'posts_per_page' => 1,
'author' => $post->post_author,
'post_type' => 'cpt',
)
);

if ( ! $users_custom_posts ) {
// This author doesn't currently have any custom posts
return;
}

// Get all custom fields of 'cpt' post
$fields = get_post_custom( $users_custom_posts[0]->ID );

// Loop through all meta fielde
foreach ( $fields as $field => $value ) {
// Ignore "private" fields (prefixed with an underscore or serialized data)
if ( $field[0] !== '_' && ( empty( $value[0] ) || ! is_array( $value[0] ) ) ) {
// If the field already exists, it won't be overwritten, unlike update_post_meta()
add_post_meta( $post_ID, $field, empty( $value[0] ) ? '' : $value[0], true /* Unique */ );
}
}
}
add_action( 'wp_insert_post', 'md_copy_cpt_to_post_2', 10, 3 );


/**
* Copy CPT to post when post is published via WPUF.
*
* @param int $post_ID Post ID.
*/
function md_copy_cpt_to_post_wpuf_2( $post_ID ) {
// Use other function
md_copy_cpt_to_post_2( $post_ID, get_post( $post_ID ), false );
}
add_action( 'wpuf_add_post_after_insert', 'md_copy_cpt_to_post_wpuf_2' );


Tell is that what you want.


pjeaje comments:

<blockquote>but 'post_author' => $post->post_author needs to be 'author' => $post->post_author.</blockquote>
Yes... As I told you :)
<em>09/24/15 3:18pm
pjeaje says:
https://wordpress.org/support/topic/copy-an-authors-cpt-post-custom-field-to-the-same-authors-normal-post?replies=3
</em>



dimadin comments:

OK, this works for inserting new posts.

Updating: when 'cpt' is updated, you want to update all 'post' posts with custom meta fields from 'cpt', no manual editing of 'post' post?


pjeaje comments:

Yes! I think it works for creating a new post!!!!! I'll do some more testing

<strong>you want to update all 'post' posts with custom meta fields from 'cpt', no manual editing of 'post' post?</strong>
Auto updating if possible


dimadin comments:

OK, this is a code that is used on only for updating, replace 'cpt' with your custom post type.




/**
* Copy CPT to post when CPT is updated.
*
* @param int $post_ID Post ID.
* @param WP_Post $_post Post object.
* @param bool $update Is this update.
*/
function md_copy_cpt_to_post_update( $post_ID, $post, $update ) {
// This works only for 'post' post type
if ( $post->post_type !== 'cpt' ) {
return;
}

// This works only for update
if ( ! $update ) {
return;
}

// Search for all posts of 'post' post type by same user
$users_posts = get_posts(
array(
'posts_per_page' => -1,
'author' => $post->post_author,
'post_type' => 'post',
)
);

if ( ! $users_posts ) {
// This author doesn't currently have any posts
return;
}

// Loop through all meta fielde
foreach ( $users_posts as $users_post ) {
// Get all custom fields of 'cpt' post
$fields = get_post_custom( $post_ID );

// Loop through all meta fielde
foreach ( $fields as $field => $value ) {
// Ignore "private" fields (prefixed with an underscore or serialized data)
if ( $field[0] !== '_' && ( empty( $value[0] ) || ! is_array( $value[0] ) ) ) {
// If the field already exists, overwritte it
update_post_meta( $users_post->ID, $field, empty( $value[0] ) ? '' : $value[0] );
}
}
}
}
add_action( 'wp_insert_post', 'md_copy_cpt_to_post_update', 10, 3 );

/**
* Copy CPT to post when CPT is updated via WPUF.
*
* @param int $post_ID Post ID.
*/
function md_copy_cpt_to_post_wpuf_update( $post_ID ) {
// Use other function
md_copy_cpt_to_post_update( $post_ID, get_post( $post_ID ), true );
}
add_action( 'wpuf_add_post_after_insert', 'md_copy_cpt_to_post_wpuf_update' );


dimadin comments:

Well, does it work?