Home › Toolset Professional Support › [Closed] New toolset relationships compatibility
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)
Tagged: Post-relationship
This topic contains 12 replies, has 2 voices.
Last updated by Jamal 3 years, 4 months ago.
Assisted by: Jamal.
Hi Shane,
Hope you're fine. We have updated on an old website the toolset relationships functionality. We have modified a lot of shortcodes and other but we struggle on queries.
For example, how to adapt this query ?
[code]
// All projections Query args
$programs_args = array(
'post_type' => 'projection',
'posts_per_page' => -1,
'nopaging' => true,
'order' => 'DESC',
'post_status' => 'publish',
'post__in' => $exclude,
'post__not_in' => $projections_results,
// In edition & in section
'tax_query' => array(
'relation' => 'AND',
array (
'taxonomy' => 'edition',
'field' => 'term_id',
'terms' => array($current_edition_id),
),
// Added by a conditionnal
),
// Have no films
'meta_query' => array(
'relation' => 'AND',
'belongs' => array(
'compare' => 'NOT EXISTS',
'key' => '_wpcf_belongs_film_id',
),
),
// Gets IDs
'fields' => 'ids',
);
[/code]
Or this one :
`
// Query args
$p_args = array(
'post_type' => 'projection',
'posts_per_page' => -1,
'nopaging' => true,
'order' => 'DESC',
'post_status' => 'publish',
'post__in' => $exclude,
// In edition & in section
'tax_query' => array(
'relation' => 'AND',
array (
'taxonomy' => 'edition',
'field' => 'term_id',
'terms' => array($current_edition_id),
),
// Added by a conditionnal
),
// Have films
'meta_query' => array(
'relation' => 'AND',
'belongs' => array(
'compare' => 'IN',
'key' => '_wpcf_belongs_film_id',
'value' => $films_in_section_results,
),
'p-highlights' => array(
'key' => $f,
'compare' => '=',
'value' => 1,
'type' => 'NUMERIC'
)
),
// Gets IDs
'fields' => 'ids',
);
`
Or, we tried updated this one, is that correct ?
// All projections Query args
$projections_args = array(
'post_type' => 'projection',
'posts_per_page' => -1,
'nopaging' => true,
'order' => 'DESC',
'post_status' => 'publish',
'post__in' => $exclude,
// In edition & in section
'tax_query' => array(
'relation' => 'AND',
array (
'taxonomy' => 'edition',
'field' => 'term_id',
'terms' => array($current_edition_id),
),
// Added by a conditionnal
),
// Have films / OLD approach before toolset 3.0
// 'meta_query' => array(
// 'relation' => 'AND',
// 'belongs' => array(
// 'compare' => 'IN',
// 'key' => '_wpcf_belongs_film_id', // A Revoir maj toolset
// 'value' => $films_in_section_results,
// ),
// ),
// Have film / NEW approach
// New toolset_relationships query argument
'toolset_relationships' => array(
'role' => 'child',
'related_to' => $films_in_section_results,
// this will work only with relationships that have existed before the migration
// if possible, use the relationship slug instead of an array
'relationship' => array( 'film', 'projection' )
),
// Gets IDs
'fields' => 'ids',
);
Best regards,
Wilhem
Hello Wilhem and thank you for contacting Toolset support.
Shane does not work on weekends. If you don't mind, I'll continue with you on this ticket. If you would prefer to have Shane, I can transfer this thread to him.
The following parts of the 1st and 2nd codes are not correct anymore:
'meta_query' => array( 'relation' => 'AND', 'belongs' => array( 'compare' => 'NOT EXISTS', 'key' => '_wpcf_belongs_film_id', ), ),
And:
'meta_query' => array( 'relation' => 'AND', 'belongs' => array( 'compare' => 'IN', 'key' => '_wpcf_belongs_film_id', 'value' => $films_in_section_results, ), 'p-highlights' => array( 'key' => $f, 'compare' => '=', 'value' => 1, 'type' => 'NUMERIC' ) ),
The "belongs" part is not correct anymore. Because now, Toolset stores the relationships in its own tables rather than in a specialized custom field "_wpcf_belongs_film_id".
In the 3rd code, this part is correct to handle realtionships:
'toolset_relationships' => array( 'role' => 'child', 'related_to' => $films_in_section_results, // this will work only with relationships that have existed before the migration // if possible, use the relationship slug instead of an array 'relationship' => array( 'film', 'projection' ) ),
You can read more about migrating your code to handle the new way of relationships:
- https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/how-to-migrate-your-site-to-new-post-relationships/
I would suggest building the queries in steps. First, try testing the parts of the relationship, then check the tax_query parts.
I hope this helps. Let me know if you have any questions.
Hi Jamal,
No worries ! It's fine !
( I'm sorry, I can't find the markup to show a code section. )
Yes, I just tried the new relationship query, and it's working fine. My first question wasn't accurate ; what I had not found it's how to check ( for example ) if we DON'T have a relationship between two PS.
( OLD )
'meta_query' => array(
'relation' => 'AND',
'belongs' => array(
'compare' => 'NOT EXISTS',
'key' => '_wpcf_belongs_film_id',
),
),
And how to have multiple queries :
( OLD )
'meta_query' => array(
'relation' => 'AND',
'belongs' => array(
'compare' => 'IN',
'key' => '_wpcf_belongs_film_id',
'value' => $films_in_section_results,
),
'p-highlights' => array(
'key' => $f,
'compare' => '=',
'value' => 1,
'type' => 'NUMERIC'
)
),
Is this code will work :
'toolset_relationships' => array(
'role' => 'child',
'related_to' => $films_in_section_results,
'relationship' => array( 'film', 'section' )
),
'meta_query' => array(
'p-highlights' => array(
'key' => $f,
'compare' => '=',
'value' => 1,
'type' => 'NUMERIC'
)
),
Thanks a lot !
Best
Wilhem
Regarding the last code, this does not seems correct to me:
'meta_query' => array( 'p-highlights' => array( 'key' => $f, 'compare' => '=', 'value' => 1, 'type' => 'NUMERIC' ) ),
This is the correct way, assuming that the meta_key you are checking against is "p-highlights":
'meta_query' => array( array( 'key' => 'p-highlights', 'compare' => '=', 'value' => 1, 'type' => 'NUMERIC' ) ),
Read more about WP_Query arguments here https://toolset.com/forums/topic/search-post-without-relation/#post-1227321
If it is a Toolset defined field, it will usually have a prefix "wpcf-", so the code should be:
'meta_query' => array( array( 'key' => 'wpcf-p-highlights', 'compare' => '=', 'value' => 1, 'type' => 'NUMERIC' ) ),
Check this https://toolset.com/documentation/customizing-sites-using-php/functions/
And regarding posts that do not have a connection in a relationship, we do not have a straightforward way to find them. You will have to search for the posts that have relationships and exclude them. Check the custom code in this ticket, even though you will not be using Toolset hooks, but it can give you an idea. If it is not clear, please elaborate more on your use case. Why are you looking for non-connected posts, and we'll find out a solution.
https://toolset.com/forums/topic/search-post-without-relation/
Hi Jamal,
It's working with the new approach ; but it seems a bit longer. Do you have a better idea ?
( $films_in_section_results is a list a films )
< 3.0
$projections_args = array( 'post_type' => 'projection', 'posts_per_page' => -1, 'nopaging' => true, 'order' => 'DESC', 'post_status' => 'publish', // Have film merged with exclude 'post__in' => $post__in, // In edition & in section 'tax_query' => array( 'relation' => 'AND', array ( 'taxonomy' => 'edition', 'field' => 'term_id', 'terms' => array($current_edition_id), ), // Added by a conditionnal ), // Have films / OLD approach before toolset 3.0 'meta_query' => array( 'relation' => 'AND', 'belongs' => array( 'compare' => 'IN', 'key' => '_wpcf_belongs_film_id', // A Revoir maj toolset 'value' => $films_in_section_results, ), ), // Gets IDs 'fields' => 'ids', );
> 3.0
$belongs_film_projection_ids = array(); $relationship = 'film_projection'; // get the child posts of the parent post $belongs_film_projection_ids[] = toolset_get_related_posts( array( 'parent' => $films_in_section_results ), //query_by_elements $relationship, //relationship array( 100, //limit 0, //offset array(), //args 'post_id', //return 'child' //role_to_return : 'parent' | 'child' | 'intermediary' | 'all' ) ); error_log("belongs_film : find parent returns child"); error_log(print_r($belongs_film_projection_ids, true)); if ( !is_array($exclude) ) $post__in = $belongs_film; else $post__in = array_merge( $exclude, $belongs_film); // All projections Query args $projections_args = array( 'post_type' => 'projection', 'posts_per_page' => -1, 'nopaging' => true, 'order' => 'DESC', 'post_status' => 'publish', // Have film merged with exclude 'post__in' => $post__in, // In edition & in section 'tax_query' => array( 'relation' => 'AND', array ( 'taxonomy' => 'edition', 'field' => 'term_id', 'terms' => array($current_edition_id), ), // Added by a conditionnal ), // Gets IDs 'fields' => 'ids', );
Best regards,
Wilhem
Hello Wilhem,
Actually, I don't have any more ideas on how to get the posts that do not have a relationship. Let me discuss it within the team, and if I get any feedback, I'll share it with you.
So, I discussed this with the team, and we would like to know more about your use case.
How do you display the results of this WP query? Is it used on the theme's template files?
Or are you using it along with a view?
We need to know more about your website to better advise you. Please share as many details as possible. Or maybe share credentials to your website so we can see this closely! Your next reply will be private to let you share credentials safely.
Hi Jamal,
So sorry for ma late reply, last week before holidays, it's a bit busy.
Yes, you are right, it's not inside a view, it's a shortcode used to count post with particular meta / tax / relation to an archive template.
I can paste you the whole function ( with many try ans comment, don't be afraid of ! )
/** * Used in taxonomies archives templates */ function get_counts($taxonomy_name = 'section', $taxonomy_id = array(), $exclude = array()) { /* Get Counts old SQL method */ /* // Get 'wpcf-p-is-guest' // SELECT proj.post_title, film.post_title, proj_meta_key.meta_value global $wpdb; $sql = <<<SQL SELECT film.post_title, film.ID FROM wp_posts AS proj, wp_posts AS film, wp_postmeta AS proj_meta_key, wp_postmeta AS proj_meta_film, wp_term_relationships AS trs1, wp_term_relationships AS trs2 WHERE ( proj.ID = proj_meta_key.post_id ) AND (proj_meta_film.post_id = proj.ID) AND (proj_meta_film.meta_key = '_wpcf_belongs_film_id') AND (proj_meta_film.meta_value = film.ID ) AND ( proj_meta_key.meta_key = 'wpcf-p-is-guest' AND CAST(proj_meta_key.meta_value AS SIGNED) = '1' ) AND proj.post_type = 'projection' AND ((proj.post_status = 'publish' OR proj.post_status = 'private')) AND trs1.object_id = film.ID AND trs1.term_taxonomy_id = 219 AND trs2.object_id = film.ID AND trs2.term_taxonomy_id = 221 GROUP BY proj.ID ORDER BY proj.menu_order, proj.post_date DESC SQL; $results = $wpdb->get_results($sql); print_r($results); print_r(count($results)); // Get 'wpcf-p-young-public' // SELECT proj.post_title, film.post_title, proj_meta_key.meta_value global $wpdb; $sql = <<<SQL SELECT film.post_title, film.ID FROM wp_posts AS proj, wp_posts AS film, wp_postmeta AS proj_meta_key, wp_postmeta AS proj_meta_film, wp_term_relationships AS trs1, wp_term_relationships AS trs2 WHERE ( proj.ID = proj_meta_key.post_id ) AND (proj_meta_film.post_id = proj.ID) AND (proj_meta_film.meta_key = '_wpcf_belongs_film_id') AND (proj_meta_film.meta_value = film.ID ) AND ( proj_meta_key.meta_key = 'wpcf-p-young-public' AND CAST(proj_meta_key.meta_value AS SIGNED) = '1' ) AND proj.post_type = 'projection' AND ((proj.post_status = 'publish' OR proj.post_status = 'private')) AND trs1.object_id = film.ID AND trs1.term_taxonomy_id = 219 AND trs2.object_id = film.ID AND trs2.term_taxonomy_id = 221 GROUP BY proj.ID ORDER BY proj.menu_order, proj.post_date DESC SQL; $results = $wpdb->get_results($sql); print_r($results); print_r(count($results)); // Get 'wpcf-p-highlights' // SELECT proj.post_title, film.post_title, proj_meta_key.meta_value global $wpdb; $sql = <<<SQL SELECT film.post_title, film.ID FROM wp_posts AS proj, wp_posts AS film, wp_postmeta AS proj_meta_key, wp_postmeta AS proj_meta_film, wp_term_relationships AS trs1, wp_term_relationships AS trs2 WHERE ( proj.ID = proj_meta_key.post_id ) AND (proj_meta_film.post_id = proj.ID) AND (proj_meta_film.meta_key = '_wpcf_belongs_film_id') AND (proj_meta_film.meta_value = film.ID ) AND ( proj_meta_key.meta_key = 'wpcf-p-highlights' AND CAST(proj_meta_key.meta_value AS SIGNED) = '1' ) AND proj.post_type = 'projection' AND ((proj.post_status = 'publish' OR proj.post_status = 'private')) AND trs1.object_id = film.ID AND trs1.term_taxonomy_id = 219 AND trs2.object_id = film.ID AND trs2.term_taxonomy_id = 221 GROUP BY proj.ID ORDER BY proj.menu_order, proj.post_date DESC SQL; $results = $wpdb->get_results($sql); print_r($results); print_r(count($results)); */ global $current_edition_id; // Get counts $counts = array(); /** * All films / OK */ // Films Args $films_in_section_args = array( 'post_type' => 'film', 'posts_per_page' => -1, 'nopaging' => true, 'order' => 'DESC', 'post_status' => 'publish', // In edition & in section 'tax_query' => array( 'relation' => 'AND', array ( 'taxonomy' => 'edition', 'field' => 'term_id', 'terms' => array($current_edition_id), ), // Added by a conditionnal ), // Has status required 'meta_query' => array( 'relation' => 'AND', array( 'key' => '_status', 'value' => ['approved','programmed'], 'compare' => 'IN' ) ), // Gets IDs 'fields' => 'ids', ); // Conditionnal if ( $taxonomy_name === 'section') $films_in_section_args['tax_query'][] = array ( 'taxonomy' => $taxonomy_name, 'field' => 'term_id', 'terms' => $taxonomy_id, ); // Query $films_in_section_query = new WP_Query($films_in_section_args); // Results $films_in_section_results = $films_in_section_query->posts; // Store count $counts['films'] = count($films_in_section_results); //found_posts // Restore original Post Data wp_reset_postdata(); /** * All promoted films ( with field ) */ // Promoted args $films_promoted_args = array( 'post_type' => 'film', 'posts_per_page' => -1, 'nopaging' => true, 'order' => 'DESC', 'post_status' => 'publish', // In edition & in section 'tax_query' => array( 'relation' => 'AND', array ( 'taxonomy' => 'edition', 'field' => 'term_id', 'terms' => array($current_edition_id), ), // Added by a conditionnal ), // Has status required 'meta_query' => array( 'relation' => 'AND', array( 'key' => '_status', 'value' => ['approved','programmed'], 'compare' => 'IN' ), array( 'key' => 'wpcf-f-promote', 'compare' => '=', 'value' => 1, 'type' => 'NUMERIC' ), ), // Gets IDs 'fields' => 'ids', ); // Conditionnal if ( $taxonomy_name === 'section') $films_promoted_args['tax_query'][] = array ( 'taxonomy' => $taxonomy_name, 'field' => 'term_id', 'terms' => $taxonomy_id, ); // Query $films_promoted_args = new WP_Query($films_promoted_args); // Results $films_promoted_results = $films_promoted_query->posts; // Store count $counts['wpcf-f-promote'] = count($films_promoted_results); // Restore original Post Data wp_reset_postdata(); /** * All projections belongs to a film */ error_log("> 3.0 films_in_section_results"); error_log(print_r($films_in_section_results, true)); $belongs_film_projection_ids = array(); $relationship = 'film_projection'; // get the child posts of the parent post $belongs_film_projection_ids[] = toolset_get_related_posts( array( 'parent' => $films_in_section_results ), //query_by_elements $relationship, //relationship array( // 'child', // query_by_role: Name of the element role to query by. This argument is required if a single post is provided in $query_by_elements, and in other cases, it must not be present at all. Accepted values: 'parent' | 'child' | 'intermediary'. 100, //limit 0, //offset array(), //args 'post_id', //return 'child' //role_to_return : 'parent' | 'child' | 'intermediary' | 'all' ) ); error_log("> 3.0 belongs_film : find parent returns child"); error_log(print_r($belongs_film_projection_ids, true)); // All projections Query args if ( !is_array($exclude) ) $post__in = $belongs_film; else $post__in = array_merge( $exclude, $belongs_film); $projections_args = array( 'post_type' => 'projection', 'posts_per_page' => -1, 'nopaging' => true, 'order' => 'DESC', 'post_status' => 'publish', // Have film merged with exclude 'post__in' => $post__in, // In edition & in section 'tax_query' => array( 'relation' => 'AND', array ( 'taxonomy' => 'edition', 'field' => 'term_id', 'terms' => array($current_edition_id), ), // Added by a conditionnal ), // Have films / OLD approach before toolset 3.0 // 'meta_query' => array( // 'relation' => 'AND', // 'belongs' => array( // 'compare' => 'IN', // 'key' => '_wpcf_belongs_film_id', // A Revoir maj toolset // 'value' => $films_in_section_results, // ), // ), // Have film / NEW approach > NOT WORKING FOR MANY IDs // New toolset_relationships query argument // 'toolset_relationships' => array( // 'role' => 'child', // 'related_to' => $films_in_section_results, // // this will work only with relationships that have existed before the migration // // if possible, use the relationship slug instead of an array // //'relationship' => array( 'film', 'projection' ), // 'relationship' => 'film_projection', // ), // Gets IDs 'fields' => 'ids', ); // Conditionnal if ( $taxonomy_name === 'room') $projections_args['tax_query'][] = array ( 'taxonomy' => $taxonomy_name, 'field' => 'term_id', 'terms' => $taxonomy_id, ); // Query $projections_query = new WP_Query($projections_args); // Results $projections_results = $projections_query->posts; // Store count $counts['projections'] = count($projections_results); /** * All projections not belongs to a film */ // All projections Query args $programs_args = array( 'post_type' => 'projection', 'posts_per_page' => -1, 'nopaging' => true, 'order' => 'DESC', 'post_status' => 'publish', 'post__in' => $exclude, 'post__not_in' => $projections_results, // In edition & in section 'tax_query' => array( 'relation' => 'AND', array ( 'taxonomy' => 'edition', 'field' => 'term_id', 'terms' => array($current_edition_id), ), // Added by a conditionnal ), // Have no films 'meta_query' => array( 'relation' => 'AND', 'belongs' => array( 'compare' => 'NOT EXISTS', 'key' => '_wpcf_belongs_film_id', ), ), // Gets IDs 'fields' => 'ids', ); // Conditionnal if ( $taxonomy_name === 'room') $programs_args['tax_query'][] = array ( 'taxonomy' => $taxonomy_name, 'field' => 'term_id', 'terms' => $taxonomy_id, ); // Query $programs_query = new WP_Query($programs_args); // Results $programs_results = $programs_query->posts; // Store count $counts['programs'] = count($programs_results); /** * Projection with fields */ $projection_count_fields = array('wpcf-p-is-guest', 'wpcf-p-young-public', 'wpcf-p-highlights'); foreach ($projection_count_fields as $f) { // Query args $p_args = array( 'post_type' => 'projection', 'posts_per_page' => -1, 'nopaging' => true, 'order' => 'DESC', 'post_status' => 'publish', 'post__in' => $exclude, // In edition & in section 'tax_query' => array( 'relation' => 'AND', array ( 'taxonomy' => 'edition', 'field' => 'term_id', 'terms' => array($current_edition_id), ), // Added by a conditionnal ), // Have films 'meta_query' => array( 'relation' => 'AND', 'belongs' => array( 'compare' => 'IN', 'key' => '_wpcf_belongs_film_id', 'value' => $films_in_section_results, ), 'p-highlights' => array( 'key' => $f, 'compare' => '=', 'value' => 1, 'type' => 'NUMERIC' ) ), // Gets IDs 'fields' => 'ids', ); // Conditionnal if ( $taxonomy_name === 'room') $p_args['tax_query'][] = array ( 'taxonomy' => $taxonomy_name, 'field' => 'term_id', 'terms' => $taxonomy_id, ); // Query $p_query = new WP_Query($p_args); // Results $p_results = $p_query->posts; // Store count $counts[$f] = count($p_results); if ($f === 'wpcf-p-is-guest') { $counts['guests'] = $p_results; } // Restore original Post Data wp_reset_postdata(); } return $counts; }
At that time, it's tricky to give you access to the website, I need authorizations.. I'll try !
Best regards, thanks again for your help !
I must confess the code is too long and it confused me. And I also do not like the solution to nest WP_Query inside another one using foreach. I get some time to work on it to day and I come up with and SQL query that can return all the posts that have a connection to another post within a relationship. we can use it to pass those post to "post__not_in" from wp_query.
- Get all connected parents
select DISTINCT parents.element_id from wp_toolset_connected_elements parents, wp_toolset_associations ta, wp_toolset_connected_elements children, wp_toolset_relationships tr where parents.id = ta.parent_id AND children.id = ta.child_id AND ta.relationship_id = tr.id AND tr.slug = 'state-city'
- Get all the connected children
select DISTINCT children.element_id from wp_toolset_connected_elements parents, wp_toolset_associations ta, wp_toolset_connected_elements children, wp_toolset_relationships tr where parents.id = ta.parent_id AND children.id = ta.child_id AND ta.relationship_id = tr.id AND tr.slug = 'state-city'
Notice the relationship slug on the last lines.
I'll be on my weekend for Wednesday and Thursday. After that, once I get the time to work on this, I'll test it on a wp_query code and get back to you. If you, in the meantime, find out how to integrate it into your code, it would be awesome.
All the best,
Jamal
Hi Jamal,
Thanks a lot.
However, I really hesitate to use an SQL query directly in a WP environment.
We will lose the WP_queries cache, WP updates, Toolset updates...
I don't see what you get more than :
$belongs_film_projection_ids [] = toolset_get_related_posts ( array ('parent' => $ films_in_section_results), // query_by_elements $ relationship, // relationship array ( 100, // limit 0, // offset array (), // args 'post_id', // return 'child' // role_to_return: 'parent' | 'child' | 'intermediary' | 'all' ) );
This version works well, however, I just need the posts that have no relations : "toolset_get_unrelated_posts";)
Maybe you'll going to suggest me that I do this with an array_diff comparing all post with a get_posts and selected posts with a toolset_get_related_posts ?
It will do the trick .. but, it's seems so boring!
The old relationships were simpler.
Have a great week-end !
Best,
Wilhem
Hello Wilhem,
I understand that you don't want to have an SQL query within your website. However, I believe it is the most efficient solution.
Unfortunately, Toolset does not have a proper API to get all the related posts or all the unrelated posts. If you believe this should be added, please suggest it as a feature here https://toolset.com/home/contact-us/suggest-a-new-feature-for-toolset/
Using these SQL queries is not related to WP Queries and WP-Cache, because they are against Toolset database tables instead of WP core tables. Maybe, they won't use Toolset cache, but that's not a documented feature, and honestly, I don't know how it works.
At this point, I am afraid, there is nothing else I could add. So, I'll remain at your disposal, if you have any further questions.
All the best,
Jamal
Hello Jamal,
So I'll try your solution.
Best regards,
Wilhem
Hi! Let me know if you have any questions. As of now, I'll set this ticket as waiting for your feedback, which should keep it open for 2 weeks.
The topic ‘[Closed] New toolset relationships compatibility’ is closed to new replies.