Search code examples
wordpresscustom-post-typecustom-wordpress-pages

WordPress Update custom post status by clicking custom link in admin


i have a site where i get posts from users, those posts save in WP as a custom post with status pending, Admin have custom link in that custom post type page Approve | Reject Approve should change post status to Public Reject Should change post status to trash/del

enter image description here

can anyone tell any hook to anything which i can run to change post status from backend by clicking these custom links

the code of approve | reject button if anyone want to see

add_filter( 'manage_dream_posts_columns', 'smashing_filter_posts_columns' );
function smashing_filter_posts_columns( $columns ) {
  $columns['decision'] = __( 'Decision Pending', 'rima' );
  return $columns;
}
add_action( 'manage_dream_posts_custom_column', 'smashing_dream_column', 10, 2);
function smashing_dream_column( $column, $post_id ) {

  if ( 'decision' === $column ) {
    if (get_post_status ( $post_id ) == 'pending') {
        echo '<div class="decision"><a href="#" data-userID="'.$post_id.'" class="dapprove" onclick="decision()">Approve</a><a href="#" class="dreject">Reject</a></div>';
    }
    else {
        echo '<div class="decision"><span class="dapprove">Approved</span></div>';
    }
  }
}

Solution

  • You could do something like this - it's a bit hacky and uses jQuery but is a quick fix for your issue using an Ajax method so it all works realtime with your admin screen. You can approve/reject multiple posts without any page reloads, including some colour feedback to let you know what's happening.

    You need to add 2 new actions:

    add_action( 'wp_ajax_set_post_status', 'set_post_status_ajax_handler' );
    add_action( 'admin_footer', 'set_post_status_js' );
    

    Then add these functions:

    function set_post_status_js()
    {
      $nonce = wp_create_nonce('set_post_status');
      $ajax_url = admin_url('admin-ajax.php'); ?>
    
      <script type="text/javascript">
        (function($){
          $(document).ready(function(){
            $('.decision a').click(function(event){
              event.preventDefault();
              $.post( "<?= $ajax_url; ?>", {
                nonce: "<?= $nonce; ?>",
                action: 'set_post_status',
                post_id: $(this).data('post_id'),
                status: $(this).data('status'),
              }, function(data){
                if (data.ok) {
                  var postStateLabel = (data.status === 'publish') ? '<span style="color: #009900;">Approved</span>' : '<span style="color: #990000;">Rejected</span>';
    
                  $('#post-' + data.id)
                    .css('background', data.status === 'publish' ? '#EEFFEE' : '#FFEEEE')
                    .find('.post-state').html( postStateLabel );
                }
              });
            });
          });
        })(jQuery)
      </script>
    
      <?php
    }
    

    And

    function set_post_status_ajax_handler()
    {
      $nonce = $_POST['nonce'];
    
      if ( ! wp_verify_nonce( $nonce, 'set_post_status' ) )
        die ( 'Not permitted');
    
      // Extract the vars from the Ajax request
      $post_id = $_POST['post_id'];
      $status = $_POST['status'];
    
      // Now update the relevant post
      $post_id = wp_update_post([
        'ID' => $post_id,
        'post_status' => $status,
      ], true);
    
      // make sure it all went OK
      if (is_wp_error($post_id))
      {
        $response = [
          'ok' => false,
        ];
      } else 
      {
        $response = [
          'ok'      => true,
          'id'      => $post_id,
          'status'  => $status,
        ];
      }
    
      // Return the response
      wp_send_json( $response );
    }
    

    Finally, you need to change your Approve / Reject links to this HTML:

    echo '
    <div class="decision">
      <a href="#" data-post_id="' . $post_id . '" data-status="publish" class="dapprove">Approve</a>
      <a href="#" data-post_id="' . $post_id . '" data-status="trash" class="dreject">Reject</a>
    </div>';
    

    Hopefully that will get you sorted. Cheers.