Shortcode to display an edit link to each Venue (or Organizer) not used by any Event (All Events, not just Upcoming Events). For https://theeventscalendar.com/support/forums/topic/removing-unlinked-venues-organizers/
<?php
/*
* Shortcode to display an edit link to each Venue (or Organizer) not used by any Event (All Events, not just Upcoming Events). Also has a scary single line of commented-out code to then DELETE all such results (they don't even end up in the Trash). You've been warned!
* Examples:
* Venues: [tribe_unused_posts] - https://cl.ly/0q441G1I3I05
* same as above: [tribe_unused_posts type=venues]
* Venues with Debug: [tribe_unused_posts debug=true] - https://cl.ly/2v0S2z420x0U
* Organizers: [tribe_unused_posts type=organizers] - https://cl.ly/1H3q2o1w2o3v
* Organizers with Debug: [tribe_unused_posts type=organizers debug=true] - https://cl.ly/0Y2s1k1n0T0R
* Note: if multiple Organizers are assigned to an Event, there will be multiple _EventOrganizerID meta keys with single values, not a single _EventOrganizerID key with an array or comma-separated list of values.
*
* From https://gist.github.com/cliffordp/b9cde5ad57eecefca3bcd578fc5e6a61
*/
function tribe_unused_posts_logic( $atts ) {
if ( ! class_exists( 'Tribe__Events__Main' ) ) {
return false;
}
$defaults = array(
'type' => 'venues', // 'organizers'
'debug' => 'false', // 'true'
);
$atts = shortcode_atts( $defaults, $atts, 'tribe_unused_posts' );
global $wpdb;
$tec_main = Tribe__Events__Main::instance();
// $events_type = $tec_main::POSTTYPE;
$type = strtolower( $atts['type'] );
if ( 'organizers' == $type || 'organizer' == $type ) {
$post_type = $tec_main::ORGANIZER_POST_TYPE;
$meta_key = '_EventOrganizerID';
} else {
$post_type = $tec_main::VENUE_POST_TYPE;
$meta_key = '_EventVenueID';
}
// Get all posts of the specified post type
// https://codex.wordpress.org/Class_Reference/WP_Query
$args = array(
'post_type' => $post_type,
'posts_per_page' => -1,
'fields' => 'ids',
'order' => 'ASC',
'post_status' => 'any', // Retrieves any status except those from post statuses with 'exclude_from_search' set to true (i.e. trash and auto-draft)
);
$ids_all = get_posts( $args );
// Gets all database values for '_EventVenueID' or '_EventOrganizerID', whether or not they are valid, whether or not used by Events post type or another
// https://codex.wordpress.org/wpdb
$ids_in_use = $wpdb->get_col( $wpdb->prepare(
"
SELECT DISTINCT meta_value
FROM $wpdb->postmeta
WHERE meta_key = %s
",
$meta_key
) );
sort( $ids_in_use );
// Get all valid post IDs of the specified post type that are not used in the database
$ids_unused = array_diff( $ids_all, $ids_in_use );
$output = '<div class="tribe_unused_posts-shortcode">';
$debug = strtolower( $atts['debug'] );
if ( 'true' == $debug ) {
$output .= '<h3>Debug Info:</h3>';
$output .= '<h4>All of post type</h4>';
$output .= print_r( $ids_all, true );
$output .= '<h4>All in use:</h4>';
$output .= print_r( $ids_in_use, true );
$output .= '<h4>Unused:</h4>';
$output .= print_r( $ids_unused, true ) ;
$output .= '<br>';
}
// short circuit if no Unused found -- doesn't mean there aren't invalid values in the database, such as '_EventOrganizerID' = 'abcd' (invalid since only integers should be in the db), or if invalid because set to zero, which isn't a valid post ID
if ( empty( $ids_unused ) ) {
$output .= sprintf( '<h3>We did not find any unused <strong>%s</strong>.</h3>', $post_type );
$output .= '</div>';
return $output;
}
// output the list of unused posts, along with their edit link, title, ID, and Post Status
$output .= sprintf( '<h3>Unused <strong>%s</strong>:</h3><ul>', $post_type );
foreach ( $ids_unused as $key => $value ) {
$value = (int)$value;
$output .= sprintf( '<li><a href="%s">%s - %d (%s)</a></li>', get_edit_post_link( $value ), get_the_title( $value ), $value, get_post_status( $value ) );
// could optionally uncomment the following line of code to then DELETE each post of this type via https://developer.wordpress.org/reference/functions/wp_delete_post/
// WARNING!!! // wp_delete_post( $value );
}
$output .= '</ul>';
$output .= '</div>';
return $output;
}
add_shortcode( 'tribe_unused_posts', 'tribe_unused_posts_logic' );