Search code examples
phpsqlwordpresspluginscustom-post-type

Wordpress: How do I create a plugin for the post overview in the backend?


I would like to create a plugin, which should add a button for each post in the backend in the post overview section so that I can click on it and run a database operation referencing the post title. Elementor for example does that (as shown in the image).

Overview of posts in WordPress backend

Unfortunately, I don't know where to find or search for the area to create something for the backend post overview.

The actual aim was to create a table entry for each post entry. I tried to accomplish this with the use of hooks, but I couldn't prevent it from firing twice or when updating the post. Other than that, it worked as expected.

add_action('save_post', 'add_workshop_poll_nc');
function add_workshop_poll_nc( $post_id ) {
    global $wpdb;
    //Check to see if user posted first time
    if ( !(wp_is_post_revision($post_id)) || wp_is_post_autosave($post_id)){
        return;
    }
    if(get_post_type(4)){
        $table_name = 'oc_polls_polls';
        $poll_title = get_the_title($post_id);
    
        $wpdb->insert(
            $table_name,
            array(
                'type'  => 'datePoll',
                'title' => $poll_title,
                'description' => '',
                'owner' => 'admin',
                'created' => 1602851840,
                'expire' => 1604151026,
                'deleted' => 0,
                'access' => 'hidden',
                'anonymous' => 1,
                'full_anonymous' => 0,
                'allow_maybe' => 1,
                'options' => '',
                'settings' => '',
                'vote_limit' => 0,
                'show_results' => 'expired',
                'admin_access' => 1,
                'important' => 0)); 
    }
    remove_action('save_post', 'add_workshop_poll_nc'); //to prevent multiple database entries of same post
}

That is the reason I would like to do use a manual trigger such as a link/button. These links/buttons should only be visible to a custom post type (workshop).

Can someone give me a hint, how to approach this problem or help me solve it?

I am new to WordPress/PHP so please be indulgent :)

EDIT:

Thanks to Chris Haas I managed to get it work with the following Code:

add_filter( 'post_row_actions', 'termin_add_action_button', 10, 2 );
function termin_add_action_button($actions, $post){

    if(get_post_type() === 'workshop'){
        $url = add_query_arg(
            array(
              'post_id' => $post->ID,
              'my_action' => 'custom_termin_post',
            )
          );
    $actions['termin'] = '<a href="' . esc_url( $url ) . '" target="_blank">Terminierung anlegen</a>';
    }
    return $actions;
}

add_action( 'admin_init', 'custom_termin_function' );
function custom_termin_function(){
  if ( isset( $_REQUEST['my_action'] ) && 
   'custom_termin_post' == $_REQUEST['my_action']  ) {
    global $wpdb;

    $table_name = 'oc_polls_polls';
    $poll_title = get_the_title($_REQUEST['post_id']);
    
    $wpdb->insert(
        $table_name,
        array(
            'type'  => 'datePoll',
            'title' => $poll_title,
            'description' => '',
            'owner' => 'admin',
            'created' => 1602851840,
            'expire' => 1604151026,
            'deleted' => 0,
            'access' => 'hidden',
            'anonymous' => 1,
            'full_anonymous' => 0,
            'allow_maybe' => 1,
            'options' => '',
            'settings' => '',
            'vote_limit' => 0,
            'show_results' => 'expired',
            'admin_access' => 1,
            'important' => 0
        )
    );
    exit;
  }
}

I have one problem left. If I click on the button, currently it opens a new tab and performs the action. I would rather have the operation to be invisible. Is this possible? If I don't use target="_blank" than I am being redirected to a blank white page.

Is there a better solution? :)


Solution

  • SOLUTION:

    Thanks to Chris Haas I managed to get it work with the following Code:

    /**
     * Action to create a workshop poll in Nextcloud
     */
    add_filter( 'post_row_actions', 'termin_add_action_button', 10, 2 );
    function termin_add_action_button($actions, $post){
    
        if(get_post_type() === 'workshop'){
            $url = add_query_arg(
                array(
                  'post_id' => $post->ID,
                  'my_action' => 'custom_termin_post',
                )
              );
        $actions['termin_add'] = '<a href="' . esc_url( $url ) . '" target="_blank">Terminierung anlegen</a>';
        }
        return $actions;
    }
    
    add_action( 'admin_init', 'custom_termin_add_function' );
    function custom_termin_add_function(){
      if ( isset( $_REQUEST['my_action'] ) && 'custom_termin_post' == $_REQUEST['my_action']) {
        global $wpdb;
    
        $poll_table_name = 'oc_polls_polls';                                        //table name of polls
        $wordpress_table_name = 'wordpress_polls';                          //storage of primary keys of post id and poll id 
        $poll_title = get_the_title($_REQUEST['post_id']);                          //poll title
        $curTimestamp = current_datetime();                                         //current time stamp
        $time_created = $curTimestamp->getTimestamp()+$curTimestamp->getOffset();   //creation date
        $time_expire = $time_created + 1814400;                                     //expire date 3 weeks after creation date
        $poll_id;                                                                   //poll id
        
        $wordpress_polls = $wpdb->get_results("SELECT wordpress_id, poll_id FROM ".$wordpress_table_name." WHERE wordpress_id = ".$_REQUEST['post_id']);
        $wordpress_polls_rows = $wpdb->num_rows;
    
        if($wordpress_polls_rows === NULL || $wordpress_polls_rows === 0){
    
            //create poll
            $wpdb->insert(
                $poll_table_name,
                array(
                    'type'  => 'datePoll',
                    'title' => $poll_title,
                    'description' => '',
                    'owner' => 'admin',
                    'created' => $time_created,
                    'expire' => $time_expire,
                    'deleted' => 0,
                    'access' => 'hidden',
                    'anonymous' => 1,
                    'full_anonymous' => 0,
                    'allow_maybe' => 1,
                    'options' => '',
                    'settings' => '',
                    'vote_limit' => 0,
                    'show_results' => 'expired',
                    'admin_access' => 1,
                    'important' => 0
                )
            );
            $poll_id = $wpdb->insert_id; //save ID of poll
            
            //create poll and wordpress relation
            $wpdb->insert(
                $wordpress_table_name,
                array(
                    'wordpress_id'  => $_REQUEST['post_id'],
                    'poll_id' => $poll_id
                    )
                );
                echo "<script>window.close();</script>";
                exit;
            } else {
                echo "<script>window.close();</script>";
                exit;
            }
        }
    }
    

    If there is a better or optimized solution, please let me know :)