WordPress 插件:挂钩 post_row_actions 函数自定义 PHP 的内容

WordPress Plugin: Hook to post_row_actions function the content of a custom PHP

我创建了一个 WordPress 插件,带有一个钩子,用于在后端 posts 的概述下方创建 links(对于自定义 post 类型)。

link 应该重定向到一个自定义的 PHP-文件。目前是这样解决的(对于 Terminierungsverwaltung):

class CustomPlugin
{


function __construct(){

    #... more code

    /**
     * Terminverwaltung
     */
    add_filter( 'post_row_actions', array( $this,'termin_add_user_action_button'), 10, 2 );

    #... more code

}

#... more code

function termin_add_user_action_button($actions, $post){
    global $wpdb;
    $post_id = $post->ID;                       //post ID
    $poll_id;                                   //poll ID

    
    $wordpress_polls = $wpdb->get_results("SELECT wordpress_id, poll_id FROM " . self::WORDPRESS_TABLE_NAME . " WHERE wordpress_id = " . $post_id);
    $wordpress_polls_rows = $wpdb->num_rows;
    
    foreach($wordpress_polls as $wordpress_poll){
        $poll_id  = $wordpress_poll->poll_id;
    }

    if($wordpress_polls_rows === NULL || $wordpress_polls_rows === 0){
        return $actions;
    } else{
        if(get_post_type() === 'workshop'){
            $url = add_query_arg(
                array(
                  'post_id' => $post->ID,
                  'poll_id' => $poll_id,
                ), 
                plugins_url( '/attendees.php', __FILE__ )
              );
            $actions['termin_add_user'] = '<a href="' . $url . '" target="_blank">Teilnehmerverwaltung</a>';
        }
        return $actions;
    }
}

#... more code

}

所以目前我直接指向源文件attendees.php(位于插件目录内)并且它不受保护。

我的目标是通过以下方式保护 attendees.php

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly.
}

显然,我需要以某种方式将文件挂接到插件或 WordPress,因此定义了 ABSPATH。但我不知道该怎么做。有谁知道如何完成这项工作?

我是 PHP 和 WordPress 的新手,很抱歉这是一个新手问题。

提前致谢!

THE-E

如果attendees.php很重要,它目前有这个结构,应该独立显示:

<?php
// if ( ! defined( 'ABSPATH' ) ) {
//  exit; // Exit if accessed directly.
// }
require '../../../wp-load.php';
require 'src/attendees_function.php';
?>

<!DOCTYPE html>
<html lang="de">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel = "stylesheet"
      type = "text/css"
      href = "style/attendeesStyle.css" />
    <title>Teilnehmerverwaltung: <?php echo get_the_title($_REQUEST['post_id']);?></title>
  </head>
  <body>
    <?php add_user_form(); ?>
    <?php delete_attendee(); ?>
    <?php upload(); ?>
    <H1>Teilnehmerverwaltung</H1>
    <H2><?php echo get_the_title($_REQUEST['post_id']);?></H2>
    <section>
    <div id="add-users-upload">
      <form method="POST" enctype="multipart/form-data" id="csv-form">
        <input type="file" name="teilnehmer-csv" accept=".csv"><br>
        <button type="submit" name="csv-upload" id="top-buttons">Teilnehmer CSV hochladen</button>
      </form>

      <form method="post">
        <label for="kuerzel">Kürzel:</label>
        <input type="hidden" name="poll-id" value="<?php $poll_id = $_REQUEST['poll_id']; echo $poll_id; ?>"/>
        <input type="hidden" name="table" value="<?php $table = "oc_polls_share"; echo $table; ?>"/>
        <input type="text" class="form-control"  id="input-kuerzel" name="kuerzel"><br>
        <button type="submit" name="add-user-form" id="top-buttons">Teilnehmer anlegen</button>
      </form>
    </div>
    </section>
    <div id="table-div">
        <table>
          </thead>
            <tr>
            <td id="index">#</td>
            <td id="index">Status</td>
            <td id="header">Kürzel</td>
            <td id="header">E-Mail</td>
            <td id="header">Vorname</td>
            <td id="header">Nachname</td>
            <td id="header">Geburtstag</td>
            <td id="header">Token</td>
            <td id="header">Löschen</td>
            <td id="header">Umfrage-Link</td>
            <td id="header">Webseiten-Link</td>
            <td id="header">Senden</td>
            </tr>
          </thead>
          <tbody>
            <?php
            
            $nextcloud_base_url = "https://example.com";
            $nextcloud_attendees_base_url = $nextcloud_base_url . "/apps/polls/s/";

            if(isset($_REQUEST['post_id']) && isset($_REQUEST['poll_id'])){
              $post_id = $_REQUEST['post_id'];                  //post ID
              $poll_id = $_REQUEST['poll_id'];                                  //poll ID
            }
            $wordpress_polls_table_name = 'wordpress_polls';    //storage of primary keys of post id and poll id
            $polls_share_table_name = 'oc_polls_share'; //attendees table
            
            $wordpress_polls = get_wordpress_polls($wordpress_polls_table_name, $post_id);
            $wordpress_polls_rows = get_wordpress_polls($wordpress_polls_table_name, $post_id);


            $poll_id = get_poll_id($wordpress_polls);

            if($wordpress_polls_rows === NULL || $wordpress_polls_rows === 0){
              return;
            } else {
              $attendees = get_attendees($polls_share_table_name, $poll_id);
              $attendees_rows = get_attendees_rows($polls_share_table_name, $poll_id);
              create_attendee_rows($attendees, $nextcloud_attendees_base_url); 

            }
            ?>
            </tbody>
            </table>
    </div>
    <div id="legende">
      <p>
        Status-Legende:<br>
        &#x274C; = Abstimmung nicht erfolgt<br>
        &#x2705; = Abstimmung erfolgt
      </p>
    </div>
  </body>
</html>

编辑: 我正在查看自定义端点文档,但暂时无法使用它。

同时附一张我要整合的内容图片(attendees.php)

有很多方法可以解决这个问题,我将尝试概述这些方法。这些是不是的推荐顺序,只是意识流。但是,如果它可行,我会推荐 #2。

1 - 手动启动 WordPress

这个 question shows shows how to do this and this answer 给出了每个的优缺点,但一般的想法是 require_once 来自 root 的 wp-load.phpwp-blog-header.php 文件,然后你' d 可能想要前者。但是,通常不鼓励这样做,我只建议您在需要访问基本 WordPress 功能的情况下使用它。如果你这样做,WordPress 不知道你的安全要求是什么,所以你可以使用 current_user_can.

之类的东西来执行访问控制。

虽然我先发布了这个,但我强烈建议避免这种情况,如果你正在分发你的插件,尤其是在 WordPress.org 仓库中,绝对不要这样做,因为我很确定它会被拒绝了。

2 - 创建一个真正的 WordPress 管理页面

如果您愿意牺牲一些像素 space(对于管理工具栏),这是推荐的方式。只需使用 add_menu_page 注册一个菜单,您就可以 echoinclude/require 您的代码:

add_action(
    'admin_menu',
    static function () {
        add_menu_page(
            'My Plugin',
            'My Plugin',
            'manage_options',
            'my-plugin',
            static function () {
                // Either echo here or use an include/require
                echo '<h1>Hello world</h1>';
            }
        );
    }
);

此页面的 URL 基于该函数的第四个参数,使用上面的参数将是 /wp-admin/admin.php?page=my-plugin。访问控制由第三个参数自动处理,该参数确保用户具有 manage_options 权限。您可以根据需要对其进行自定义,也可以选择创建自己的权限。

3 - 通过模板注入

template_include函数用于确定使用哪个前端WordPress模板。就个人而言,我不喜欢将它用于管理事务,因为我喜欢将事物彼此分开,但那只是我。在下面的代码示例中,我在主题文件夹中设置了一个模板,但它也可以很容易地位于插件文件夹中。

add_filter(
    'template_include',
    static function ($template) {
        // Pick whatever logic you want here, it could be `_GET` or `_POST` or pretty much anything
        if ('my-plugin' === ($_GET['action'] ?? null)) {
            $template = get_template_directory() . '/searchform.php';
        }
        return $template;
    }
);

if逻辑是你想做什么就做什么。我只是展示了一个简单的 _GET 检查 URL 的位置 /?action=my-plugin。安全性再次取决于您,但您可以完全访问 WordPress 核心功能,例如 current_user_can 以执行任何必要的操作。

4 - 重写端点

这实际上是#3 的一个版本,因为您只是让 URL 更漂亮。我个人认为它过于复杂,因为它是一个包含很多移动部件的多步骤过程,但如果 URL 对你很重要,它可能会起作用。确保刷新你的永久链接!这样做的关键是 rewrite_rules_array ,您可以在其中为 URL 注册一个自定义正则表达式,并且您可以提供您需要的任何逻辑,包括查询字符串等等。

// Register a global variable for the URL so that WordPress is aware that you care about it
add_filter(
    'query_vars',
    static function ($vars) {
        $vars[] = 'my-plugin';
        return $vars;
    }
);

// Add special regex-like syntax for URLs. You can go wild here, too
add_action(
    'rewrite_rules_array',
    static function ($rules) {
        $newrules = array();
        // The true isn't important, it could be anything. The my-plugin is what
        // matters. Make sure to flush your permalinks!
        $newrules['my-plugin/?$'] = 'index.php?my-plugin=true';

        return $newrules + $rules;
    }
);

add_action(
    'template_include',
    static function ($template) {
        if (get_query_var('my-plugin')) {
            $template = get_template_directory() . '/searchform.php';
        }

        return $template;
    }
);