Skip Navigation

[Resolved] Syncing Parent Custom Field to Child Custom Field

This support ticket is created 3 years, 4 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 - - 9:00 – 13:00
14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 - - 14:00 – 18:00

Supporter timezone: Africa/Casablanca (GMT+01:00)

This topic contains 5 replies, has 2 voices.

Last updated by nedG 3 years, 4 months ago.

Assisted by: Jamal.

Author
Posts
#2104987

I have a site that has a parent CPT called EVENTS.

Then I have also set up a child CPT called EVENT INSTANCES. (these are the various dates that are used for the events)

Most of my Views use the EVENT INSTANCES (because everything needs to be sorted by dates), and then within the Views I simply grab whatever information is needed to be displayed from the parent event. Works great for many years.

I have a small issue that I can't see to get right and hopefully isn't outside of the scope of this forum.

My EVENTS have a custom field called Free Event? (wpcf-free-event).
I have also set up this same exact custom field on the EVENT INSTANCES.

What I need is a custom PHP function so that when the parent EVENT is created/updated, it synchronizes the value of wpcf-free-event custom field to each of its child EVENT INSTANCES.

I am trying to use save_post_{$post_type} for my function and it seems that it should be pretty simple, but I am not getting very far.

Any help is appreciated.

#2105005

Here is my current ROUGH code....

function sync-field-to-event-instance($post_id) {
    $free-event-value = get_post_meta( $post_id, 'wpcf-free-event', true);

//Get a list of all child instances using the new Query method... https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/how-to-migrate-your-site-to-new-post-relationships/
  $query = new WP_Query( 
 array(
  'post_type' => 'event-instances',
  'posts_per_page' => -1,
  //new toolset_relationships query argument
  'toolset_relationships' => array(
   'role' => 'child',
   'related_to' => get_the_ID(),
   // this will work only with relationships that have existed before the migration
   // if possible, use the relationship slug instead of an array
   'relationship' => array( 'events', 'event-instances' )
  ),
  
  'order' => 'ASC',
 )
);
$child_instances = $query->posts;


//Update each child instance with custom field values from the parent 
  foreach($child_instances as $event_instance) {    
      update_post_meta($event_instance, 'wpcf-free-event',$free-event-value);
  }

}
add_action( 'save_post_events', 'sync-field-to-event-instance', 10, 3 );
#2105025

Ahhhhh.. just a followup. UI found the erros inmy code and now updated the code to this

/******** SYNC EVENT CUSTOM FIELD TO SAME CUSTOM FIELD IN EVENT INSTANCE _ START ***************/
add_action( 'save_post_events', 'sync_field_to_event_instance', 10, 3 );

function sync_field_to_event_instance($post_id) {

$free_event_value = get_post_meta( $post_id, 'wpcf-free-event', true);

//Get a list of all child instances using the new Query method... https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/how-to-migrate-your-site-to-new-post-relationships/
$query = new WP_Query( 
 array(
  'post_type' => 'event-instances',
  'posts_per_page' => -1,
  //new toolset_relationships query argument
  'toolset_relationships' => array(
   'role' => 'child',
   'related_to' => get_the_ID(),
   // this will work only with relationships that have existed before the migration
   // if possible, use the relationship slug instead of an array
   'relationship' => array( 'events', 'event-instances' )
  ),
  
  'order' => 'ASC',
 )
);
$child_instances = $query->posts;


//Update each child instance with custom field values from the parent 
  foreach($child_instances as $event_instance) {    
      update_post_meta($event_instance, 'wpcf-free-event',$free_event_value);
  }

}


/******** SYNC EVENT CUSTOM FIELD TO SAME CUSTOM FIELD IN EVENT INSTANCE _ END ***************/

It seems to work. However I noticed something dreadful. When I created the Custom field called FREE EVENT? It was supposed to be a single checkbox (either checked (1) or unchecked (0) ).... unfortunately I created it using the "checkboxes" field type instead of the "checkbox" field type... so the meta data ends up looking like this....

wpcf-free-event' a:1:{s:64:"wpcf-fields-checkboxes-option-17e0316e3e3a6047d13f777dedfa05a8-1";a:1:{i:0;s:1:"1";}}'

Any suggestions on how I can easily convert the "checkboxes" field type to a single "checkbox" so that the meta data is correct?

#2105079

Update... I have been able to manually convert the wpcf-free-event custom field type from "checkboxes" to a single "checkbox".

Everything looks fine in that regard.

Unfortunately I still am unable to get my coding quite right.

I took a different approach and here is myu current code.

/******** SYNC EVENT CUSTOM FIELD TO SAME CUSTOM FIELD IN EVENT INSTANCE _ START ***************/
add_action( 'save_post', 'hook_update_event_instance_free_event_meta', 10, 3 );

function update_event_instance_free_event_meta($parent_post_id) {

$free_event_value = get_post_meta( $parent_post_id, 'wpcf-free-event', true);

//Get a list of all child instances using the new Query method... https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/how-to-migrate-your-site-to-new-post-relationships/
$query = new WP_Query( 
 array(
  'post_type' => 'event-instances',
  'posts_per_page' => -1,
  //new toolset_relationships query argument
  'toolset_relationships' => array(
   'role' => 'child',
   'related_to' => get_the_ID(),
   // this will work only with relationships that have existed before the migration
   // if possible, use the relationship slug instead of an array
   'relationship' => array( 'events', 'event-instances' )
  ),
  
  'order' => 'ASC',
 )
);
$child_event_instances = $query->posts;


//Update each child instance with custom field values from the parent 
  foreach($child_event_instances as $event_instance_entity) {    
      update_post_meta($event_instance_entity, 'wpcf-free-event',$free_event_value);
  }

}

function hook_update_event_instance_free_event_meta( $parent_post_id, $post = null, $update = null) {

    //don't execute if it's not the correct CPT
    if ( $post->post_type == 'events') {
        update_event_instance_free_event_meta($parent_post_id);
    }
}
/******** SYNC EVENT CUSTOM FIELD TO SAME CUSTOM FIELD IN EVENT INSTANCE _ END ***************/

Still no luck and I'm unsure of where exactly the issue is. Seems like it should be working.

#2105477

Hello and thank you for contacting the Toolset support.

I would rather suggest using toolset_get_related_posts instead of the WP_Query.
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts

I run a small test on my local test site with different post types and I come up with the following code which you may adapt to your use case:

add_action( 'save_post', 'hook_update_event_instance_free_event_meta', 10, 3 );
function update_event_instance_free_event_meta($parent_post_id) {
	
	$field_slug = 'wpcf-artist-name';
	$relationship_slug = 'oeuvre-cocktail';
	
	$free_event_value = get_post_meta( $parent_post_id, $field_slug, true);
	
	$child_event_instances = toolset_get_related_posts( $parent_post_id, $relationship_slug, array('query_by_role' => 'parent', 'role_to_return' => 'child' ) );
	
	//Update each child instance with custom field values from the parent 
	foreach($child_event_instances as $event_instance_entity) {
		update_post_meta($event_instance_entity, $field_slug, $free_event_value);
	}
}
 
function hook_update_event_instance_free_event_meta( $parent_post_id, $post = null, $update = null) {
	//don't execute if it's not the correct CPT
	if ( $post->post_type == 'oeuvre') {
		update_event_instance_free_event_meta($parent_post_id);
	}
}

You will have to update lines 3-4 with your actual field slug(wpcf-free-event) and relationships slug(most probably 'events-event-instances').

If you still encounter issues with this code, please allow me temporary access to your website to check this closely. If you are working on a local install, please share a Duplicator copy through Google Drive or Dropbox.

I hope this helps. Let me know if you have any questions.

#2105595

My issue is resolved now. Thank you!

For anyone looking to do the same thing, here is the final code that I used. (I went to sleep last night thinking about the code and wondered why $parent_post_id was introduced into the code (by me 🙂 ). It wasn't right. I used your code and changed the variables, but i also had to change the $parent_post_id to $post_id. Now each time I update an event... all of the event instances also get updated with the field value!! Great! Allows me a lot of extra flexibility on creating View Filters!!

/******** SYNC EVENT CUSTOM FIELD TO SAME CUSTOM FIELD IN EVENT INSTANCE - START ***************/
add_action( 'save_post', 'hook_update_event_instance_free_event_meta', 10, 3 );
function update_event_instance_free_event_meta($post_id) {
     
    $field_slug = 'wpcf-free-event';
    $relationship_slug = 'events_event-instances';
     
    $free_event_value = get_post_meta( $post_id, $field_slug, true);
     
    $child_event_instances = toolset_get_related_posts( $post_id, $relationship_slug, array('query_by_role' => 'parent', 'role_to_return' => 'child' ) );
     
    //Update each child instance with custom field values from the parent 
    foreach($child_event_instances as $event_instance_entity) {
        update_post_meta($event_instance_entity, $field_slug, $free_event_value);
    }
}
  
function hook_update_event_instance_free_event_meta( $post_id, $post = null, $update = null) {
    //don't execute if it's not the correct CPT
    if ( $post->post_type == 'events') {
        update_event_instance_free_event_meta($post_id);
    }
} 
/******** SYNC EVENT CUSTOM FIELD TO SAME CUSTOM FIELD IN EVENT INSTANCE - END ***************/