Skip to content

Instantly share code, notes, and snippets.

@sudar
Created June 27, 2015 08:10
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save sudar/e2f97e1455b30dc71d07 to your computer and use it in GitHub Desktop.
Save sudar/e2f97e1455b30dc71d07 to your computer and use it in GitHub Desktop.
Creating single select WordPress taxonomies. Explanation at http://sudarmuthu.com/blog/creating-single-select-wordpress-taxonomies/
<?php
/**
* Display an error message at the top of the post edit screen explaining that ratings is required.
*
* Doing this prevents users from getting confused when their new posts aren't published, as we
* require a valid rating custom taxonomy.
*
* @param WP_Post The current post object.
*/
function show_required_field_error_msg( $post ) {
if ( 'movie' === get_post_type( $post ) && 'auto-draft' !== get_post_status( $post ) ) {
$rating = wp_get_object_terms( $post->ID, 'movie_rating', array( 'orderby' => 'term_id', 'order' => 'ASC' ) );
if ( is_wp_error( $rating ) || empty( $rating ) ) {
printf(
'<div class="error below-h2"><p>%s</p></div>',
esc_html__( 'Rating is mandatory for creating a new movie post' )
);
}
}
}
// Unfortunately, 'admin_notices' puts this too high on the edit screen
add_action( 'edit_form_top', 'show_required_field_error_msg' );
<?php
/**
* Display Movie Rating meta box
*/
function movie_rating_meta_box( $post ) {
$terms = get_terms( 'movie_rating', array( 'hide_empty' => false ) );
$post = get_post();
$rating = wp_get_object_terms( $post->ID, 'movie_rating', array( 'orderby' => 'term_id', 'order' => 'ASC' ) );
$name = '';
if ( ! is_wp_error( $rating ) ) {
if ( isset( $rating[0] ) && isset( $rating[0]->name ) ) {
$name = $rating[0]->name;
}
}
foreach ( $terms as $term ) {
?>
<label title='<?php esc_attr_e( $term->name ); ?>'>
<input type="radio" name="movie_rating" value="<?php esc_attr_e( $term->name ); ?>" <?php checked( $term->name, $name ); ?>>
<span><?php esc_html_e( $term->name ); ?></span>
</label><br>
<?php
}
}
<?php
/**
* Register 'Movie Rating' custom taxonomy.
*/
function register_movie_rating_taxonomy() {
$args = array(
'label' => __( 'Rating' ),
'hierarchical' => false,
'show_ui' => true,
'show_admin_column' => true,
'meta_box_cb' => 'movie_rating_meta_box',
);
register_taxonomy( 'movie_rating', 'movie', $args );
}
add_action( 'init', 'register_movie_rating_taxonomy' );
<?php
/**
* Save the movie meta box results.
*
* @param int $post_id The ID of the post that's being saved.
*/
function save_movie_rating_meta_box( $post_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( ! isset( $_POST['movie_rating'] ) ) {
return;
}
$rating = sanitize_text_field( $_POST['movie_rating'] );
// A valid rating is required, so don't let this get published without one
if ( empty( $rating ) ) {
// unhook this function so it doesn't loop infinitely
remove_action( 'save_post_movie', 'save_movie_rating_meta_box' );
$postdata = array(
'ID' => $post_id,
'post_status' => 'draft',
);
wp_update_post( $postdata );
} else {
$term = get_term_by( 'name', $rating, 'movie_rating' );
if ( ! empty( $term ) && ! is_wp_error( $term ) ) {
wp_set_object_terms( $post_id, $term->term_id, 'movie_rating', false );
}
}
}
add_action( 'save_post_movie', 'save_movie_rating_meta_box' );
@Wooody82
Copy link

Wooody82 commented Jan 1, 2018

Hi,
Thanks for your nice code.. I think there is something wrong need to fix when trying to save without select category its not saved as draft.. still published.

You already check first and return if category not selected...
if ( ! isset( $_POST['movie_rating'] ) ) {
return;
}

And then you check there and this will not be coz u return it already before...
$rating = sanitize_text_field( $_POST['movie_rating'] );
// A valid rating is required, so don't let this get published without one
if ( empty( $rating ) ) {

@samholguin
Copy link

samholguin commented Apr 18, 2018

I agree with @malasaad82.

save_post.php

Remove lines 12 - 14
Replace line 16 with:
$status = isset($_POST['movie_rating']) ? sanitize_text_field($_POST['movie_rating']) : '';

Some additional checks you could run:

$post = get_post($post_id);

if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
    || (defined('DOING_AJAX') && DOING_AJAX)
    || ! current_user_can('edit_post', $post_id)
    || false !== wp_is_post_revision($post_id)
    || 'trash' == get_post_status($post_id)
    || isset($post->post_status) && 'auto-draft' == $post->post_status) {
    return;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment