Skip Navigation

[Resolved] Relationship Migration – Synchronize taxonomy terms across related CPTs (PART1)

This support ticket is created 5 years, 1 month 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
- 10:00 – 13:00 10:00 – 13:00 10:00 – 13:00 10:00 – 13:00 10: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: Asia/Kolkata (GMT+05:30)

Author
Posts
#1392769

I have a LIVE website that is using the "old" relationship method provided by WP-TYPES

I wanted to take advantage of Layouts as well as the "new" relationships method and repeatable fields provided by WP-TYPES, so I moved a copy of my website to a DEV server and went through the necessary relationship migration process.

After some tweaking and development of the necessary LAYOUT pages, everything seems to be OK (for the most part 🙂 )... except that my site is quite complex and some certain custom functionalities have broken after the relationship migration. This is PART 1 (of 2) of a functionality that has broken and I don't know what to do about it.
======================
PART 1
======================
So my site is a tourism site and I have a complex "events" system that includes the following custom post types and relationships...

=== CPTS=====
EVENTS - They are simply the names of the EVENTS that I have
EVENT VENUES - They are simply the names of the EVENT VENUES that I have
EVENT INSTANCES - This originally was an intermediary post that contains each of the date information instances for each EVENT. There can be multiple EVENT INSTANCES for a single EVENT.

==== CPT RELATIONSHIPS====
EVENT INSTANCES belong to EVENTS (many-to-one relationship)
EVENT INSTANCES belong to EVENT VENUES (many-to-one relationship)

The easiest thing for me to do is edit an EVENT in the admin panel. It contains most of the custom fields that I need to display on the front-end. Each event has some taxonomies. One particular taxonomy is called FEATURED PLACEMENT TAGS. It allows me to select various "placement" terms that I have created and place that event in the various specific locations that I want by using a view attribute.

So here is my problem...
When I create a view, I need to use the EVENT INSTANCES post type because the date information is the critical information that I need when it comes to the views. Once the EVENT INSTANCES are found, I can then find ways to display the PARENT post information using TOOLSET shortcodes. It works great. In order to get the correct EVENT INSTANCES when it came to the FEATURED PLACEMENT TAGS I wrote a function that "mirrored (or synced)" the FEATURED PLACEMENT TAGS taxonomy for the EVENT and synced it to the EVENT INSTANCES. It has worked great for 3+ years. However, it has now broken after the relationship migration.

Here is the code...

/** SYNCRONIZE EVENTS AND EVENT INSTANCES *****/
 * This function is hooked in the save_post event and updates the taxonomy of a child CPT based on the values of the parent.
 *
 * Currently used for updating event-instances when an event is updated.
 *
 * This function can also be executed manually by passing it the parent post's ID.
 */

function update_event_instance_meta($parent_post_id){
   // Define what we're going to be doing:
  $cpt_target = 'event-instances';
  $tax_to_copy = array('featured-placement-tag', 'eventtype');

  $tax_data = array();

  // get an array of term ids, and push into a key/value array for each taxonomy
  foreach($tax_to_copy as $taxonomy) {
    $terms_array = array();
    $terms = get_the_terms($parent_post_id, $taxonomy);
    if(is_array($terms) && count($terms) > 0 ) {
      foreach($terms as $term) {
        array_push($terms_array, $term->term_id);
      }
    }
    $tax_data[$taxonomy] = $terms_array;
  }

  //Get a list of all child instances
  $child_instances = get_posts(array(
    'post_type' => $cpt_target,
    'nopaging' => true,
    'meta_query' => array(
      array(
        'key' => '_wpcf_belongs_events_id',
        'value' => $parent_post_id,
      )
    )
  ));

  //Update each child instance with values for each taxonomy
  foreach($child_instances as $event_instance) {
    foreach($tax_data as $taxonomy => $terms) {
      wp_set_object_terms($event_instance->ID, $terms, $taxonomy, false); // Last parameter set to false to 'replace' existing terms rather than append them.
    }
  }
}

function hook_update_event_instance_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_meta($parent_post_id);
    }

}

add_action( 'save_post', 'hook_update_event_instance_meta', 10, 3 );
/*****************************************************/

As you can see from above, the troes to sync 'featured-placement-tag' and 'eventtype' taxonomies. They are important for filtering purposes in the views.

The custom code "sort of works". Each time I update any EVENT, it synchronizes the 'featured-placement-tag' and 'eventtype' taxonomies with all of the EVENT INSTANCES instead of just the EVENT INSTANCES that it has a relationship with.

I guess I just don't know enough about your post type relationships development.

#1392949

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

Hello. Thank you for contacting the Toolset support.

It seems that the following code needs the adjustment with the code you shared.

//Get a list of all child instances
  $child_instances = get_posts(array(
    'post_type' => $cpt_target,
    'nopaging' => true,
    'meta_query' => array(
      array(
        'key' => '_wpcf_belongs_events_id',
        'value' => $parent_post_id,
      )
    )
  ));

To get related child posts, you can use now post-relationship API function: toolset_get_related_posts()
=> https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts

Even you can try the following new approach:

$query = new WP_Query( 
 array(
  'post_type' => 'book',
  '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( 'writer', 'book' )
  ),
 
  'order' => 'ASC',
 )
);
$posts = $query->posts;

Where:
- You need to adjust your post types as required where applicable with the above code.

More info:
=> https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/how-to-migrate-your-site-to-new-post-relationships/

If you still need further help, I would be really happy to help you further - just get in touch with me 🙂

#1393317

My issue is resolved now. Thank you!

I was able to use the following updated custom function with the new Query and it works just fine...

/** SYNCRONIZE EVENTS AND EVENT INSTANCES *****/
// This function is hooked in the save_post event and updates the taxonomy of a child CPT based on the values of the parent.
// Currently used for updating event-instances when an event is updated.
// This function can also be executed manually by passing it the parent post's ID.

function update_event_instance_meta($parent_post_id){
   // Define what we're going to be doing:
  $cpt_target = 'event-instances';
  $tax_to_copy = array('featured-placement-tag', 'eventtype','event-month','event-management-company');

  $tax_data = array();

  // get an array of term ids, and push into a key/value array for each taxonomy
  foreach($tax_to_copy as $taxonomy) {
    $terms_array = array();
    $terms = get_the_terms($parent_post_id, $taxonomy);
    if(is_array($terms) && count($terms) > 0 ) {
      foreach($terms as $term) {
        array_push($terms_array, $term->term_id);
      }
    }
    $tax_data[$taxonomy] = $terms_array;
  }

//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 values for each taxonomy
  foreach($child_instances as $event_instance) {
    foreach($tax_data as $taxonomy => $terms) {
      wp_set_object_terms($event_instance->ID, $terms, $taxonomy, false); // Last parameter set to false to 'replace' existing terms rather than append them.
    }
  }
}

function hook_update_event_instance_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_meta($parent_post_id);
    }

}

add_action( 'save_post', 'hook_update_event_instance_meta', 10, 3 );
/*****************************************************/