1

I'm using DevinVinson/WordPress-Plugin-Boilerplate as the base of the plugin, I already created a custom post type as book and a taxonomy linked to it as rack.

What I need is to limit the number of books to 10 per rack; if the number exceeds, it should save the post as a draft and show an error.. lost right now .. need help..

Here's what I have so far!

private function define_admin_hooks() {
    $this->loader->add_action( 'save_post', $plugin_admin, 'save_post' );
    $this->loader->add_action( 'admin_notices', $plugin_admin, 'admin_notices' );
}

I've another admin class in which the above mentioned functions are defined

public function save_post( $post_id ) {
    global $post;
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
        return;
    if (isset($_POST['post_type']) && $_POST['post_type'] == 'book') {
        // If the book is assigned to taxonomy "rack" having more than 10 books, the admin_notices function is to be called
        return;
    }
}

public function admin_notices() {
    if ( ! isset( $_GET['YOUR_QUERY_VAR'] ) ) {
        return;
    }
    ?>
    <div class="error">
        <p><?php _e( 'Max Book limit reached for the selected rack!', 'odin-lms' ); ?></p>
    </div>
    <?php
}

2 Answers 2

0

In this specific case it is better to have some handling of bad configuration than trying to prevent it from happening, as there are just too many possible ways in which it can happen without coming from the post edit page. Short list that comes to my mind right now

  • quick edit from the post list
  • bulk update from the post list
  • any plugin that may combine terms
  • remote publishing via xml-rpc or the rest api

Blocking the save, especially for users that do not use the post edit screen, is going to end in bad UX as the user will not know why the save fails.

0

Use a normal query for said post type and check if the number of resulting posts is greater than 10:

public function save_post( $post_id ) {

global $post;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
    return;
}
if (isset($_POST['post_type']) && $_POST['post_type'] == 'book') {
    $max_allowed = 10;

    $terms = get_terms( ['taxonomy' => 'rack'] );
    $terms_ids = wp_list_pluck( $terms, 'term_id' );

    $args = [
        'post_type' => 'book',
        'post_status' => 'published',
        'tax_query' => [
            [
                'taxonomy' => 'rack',
                'field' => 'term_id',
                'terms' => $terms_ids
            ]
        ],
        'numberposts' => $max_allowed + 1 // just need to retrieve one more than the allowed to know whether it passed the max
    ];

    $posts = get_posts( $args );

    if( count( $posts ) > $max_allowed ) {

        // Assuming this is the right method to remove actions; use the right one otherwise;
        // This is to prevent infinite loop
        $this->loader->remove_action( 'save_post', $plugin_admin, 'save_post' );

        $post = [
            'ID' => $post_id,
            'post_status' => 'draft'
        ]

        // Update the post with status "draft"
        wp_update_post( $post );

        // Re-add the action
        $this->loader->add_action( 'save_post', $plugin_admin, 'save_post' );

    }

}

}

5
  • The thing is to stop the publish process and show an error; and the condition is the post is linked to a taxonomy rack; and a rack can contain max 10 books.. Commented May 13, 2018 at 19:50
  • Added the tax query. Do you want to stop the creation of te post or only quit the transition of status to "published"?
    – Casper
    Commented May 13, 2018 at 20:02
  • Just save it as draft .. Commented May 13, 2018 at 20:12
  • This is an action during post save ... a query at post level is needed .. I need to identify if the rack which is being assigned to a book has already 10 books or not .. if it has, I have to save the book as draft and show an error! Commented May 13, 2018 at 20:14
  • Updated your "save_post" method. The "admin_notice" part is tricky because there's a redirect after saving. Will come back later with a solution if I can think of any. PS.: SO is putting the last bracket outside the code block.
    – Casper
    Commented May 13, 2018 at 21:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.