Wordpress:如何在后端为 post 概览创建插件?

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

我想创建一个插件,应该在 post 概述部分的后端为每个 post 添加一个按钮,以便我可以单击它并 运行引用 post 标题的数据库操作。例如,Elementor 就是这样做的(如图所示)。

不幸的是,我不知道在哪里可以找到或搜索该区域来为后端 post 概述创建一些东西。

实际目的是为每个 post 条目创建一个 table 条目。我试图通过使用挂钩来完成此操作,但我无法阻止它触发两次或在更新 post 时触发。除此之外,它按预期工作。

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
}

这就是我想要使用手动触发器(例如 link/button)的原因。这些 links/buttons 应该只对自定义 post 类型(车间)可见。

谁能给我提示,如何处理或帮助我解决这个问题?

我是 WordPress/PHP 的新手所以请多多包涵 :)

编辑:

感谢 Chris Haas,我设法使用以下代码让它工作:

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;
  }
}

我还有一个问题。如果我单击该按钮,目前它会打开一个新选项卡并执行该操作。我宁愿让手术不可见。这可能吗?如果我不使用 target="_blank",我将被重定向到空白页面。

有更好的解决办法吗? :)

解决方案:

感谢 Chris Haas,我设法使用以下代码让它工作:

/**
 * 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;
        }
    }
}

如果有更好的或优化的解决方案,请告诉我:)