問題描述

讓我先說說我幾乎沒有使用 WordPress – 事實上,我在 WordPress 的最後一次網站是在 2.2 之前回來的。昨天我做了一切的一切,問了幾個問題,試圖讓一個基本的選單外掛工作。

我現在有外掛完全正常執行,所以我決定在這裡做一些小的修改,增加功能和相容性,包括使用 Settings API 。然而,在閱讀這個 API 的教程的一段很短的時間裡,我變得很困惑,那麼這個混亂只會在我閱讀時加深,並試圖實現這些例子 – 這種情況使我的外掛被實現為一個類。

除非我做錯了,從我所理解的使用設定 API 需要建立一個新的功能 PER SETTING 。這意味著平均外掛的 3-5 個功能,更高階的外掛最多可達數百個。當您可以輕鬆地將所有適用的 $_POST 變數匯入陣列並放棄整個混亂時,寫出這麼多函式 (並開發命名系統以避免混淆) 似乎是荒唐的。

也許我是 old-fashioned,但是除非有什麼可以從中獲益,否則我看不出有什麼原因使我寫的程式碼數量翻了三倍或四倍。嘗試新增設定 API 之前,我管理選項的方式如下:

    function __construct() {
        /* constructor stuff */
        $this->options = $this->db_options = get_option( 'de-menu-options' );
        if( $this->options === false ){
            $this->options = $this->defaults;
        }
        if (is_admin()) {
            add_action('admin_menu', array(&$this, 'admin_menu'));
        }   
        /* more stuff */

        // When WordPress shuts down we store changes to options
        add_action('shutdown', array(&$this, 'update'));
    }

    public function admin_menu() {
        add_options_page('DE Menu Options', 'DE Menu', 'manage_options', 'de-menu-options', array(&$this, 'options'));
        add_option('de-menu-options', $this->options);
    }

    public function options() {
        if (!current_user_can('manage_options')) {
            wp_die( __('You do not have sufficient permissions to access this page.') );
        }
        if ( !empty($_POST) && check_admin_referer('de-menu-options') ) {
            // These options are saved to the database at shutdown
            $this->options = array(
                "columns" => $_POST["de-menu-columns"],
                "maintenance" => $_POST["de-menu-maintenance"]
            );
            echo 'DE Menu options saved';
        }
?>

<div class="wrap">
    <h2>DE Menu Plugin</h2>
    <form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
        <?php settings_fields('de-menu-options'); ?>
        <input type="checkbox" name="de-menu-maintenance" />
        <label for="de-menu-columns">Columns:</label>
        <input type="text" name="de-menu-columns" value="<?php echo $this->options['columns']; ?>" />
        <p class="submit">
        <input type="submit" name="de-menu-submit" value="Update Options »" />
        </p>
    </form>
</div>
<?php
    }

    function update() {
        // By storing all changes at the end we avoid multiple database calls
        $diff = array_diff( $this->options, $this->db_options );
        if( !empty( $diff )  ){
            update_option('de-menu-options', $this->options);
        }
    }

現在使用設定 API 我有一些更像以下內容:

    function __construct() {
        /* constructor stuff */
        // Do I load options? Will they be loaded for me? Who knows?
        if (is_admin()) {
            add_action('admin_menu', array(&$this, 'admin_menu'));
            add_action('admin_init', array(&$this, 'admin_init'));
        }   
        /* more stuff */
        // Settings API should update options for me... I think
    }

    public function admin_menu() {
        add_options_page('DE Menu Options', 'DE Menu', 'manage_options', 'de-menu-options', array(&$this, 'options'));
        add_option('de-menu-options', $this->options);
    }

    public function admin_init() {
        register_setting('de-menu-options','de-menu-options',array(&$this,'validate'));
        add_settings_section('de-menu-main-options', 'Main Settings', 'options_section', 'de-menu-options');
        add_settings_field('de-menu-maintenance', 'Maintenance Mode', array(&$this,'options_maintenance'), 'de-menu-options', 'de-menu-main-options');
        add_settings_field('de-menu-columns', 'Columns', array(&$this,'options_columns'), 'de-menu-options', 'de-menu-main-options');
    }

    public function options() {
        if (!current_user_can('manage_options')) {
            wp_die( __('You do not have sufficient permissions to access this page.') );
        }
        if ( !empty($_POST) && check_admin_referer('de-menu-options') ) {
            // These options are saved to the database at shutdown
            $this->options = array(
                "columns" => $_POST["de-menu-columns"],
                "maintenance" => $_POST["de-menu-maintenance"]
            );
            echo 'DE Menu options saved';
        }
?>

<div class="wrap">
    <h2>DE Menu Plugin</h2>
    <form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
        <?php settings_fields('de-menu-options'); ?>
        <?php do_settings_sections('de-menu-options'); ?>
        <p class="submit">
        <input type="submit" name="de-menu-submit" value="Update Options »" />
        </p>
    </form>
</div>
<?php
    }

    public function options_section() {
        echo '<p>' . __('Main description of this section here.','de-menu-lang') . '</p>';
    }

    public function options_maintenance() {
        echo "<input id='de-menu-maintenance' name='options[maintenance]' type='checkbox' />";
    }

    public function options_columns() {
        echo "<input id='de-menu-columns' name='options[columns]' type='checkbox' value=".$this->options['columns']."/>";
    }

    function validate($options) {
        return $options; // I guess?
    }

從捲軸中可能很顯而易見的是,只需兩個選項,程式碼已經更長了。這是 like-wise 從評論中顯而易見的,我不完全明白我在做什麼。那麼就有 5 個新功能 (僅刪除 1 個) 才能完成所有這些功能。

那麼我從這些額外的工作中獲得什麼優勢呢?

最佳解決方案

我的觀點是,設定 API 的主要目的和好處是結構。

它有助於保持複雜的設定設定:

  • 有序 (註冊和部分的邏輯);

  • 安全 (nonces,驗證回撥);

  • 可擴充套件 (鉤入另一頁或允許掛鉤) 。

與任何這樣的結構性開銷一樣,它會使更復雜的用例受益,而且不太簡單。

所以你可以實現任何設定 API,而不使用它。問題是如果你能以可靠,安全和可擴充套件的方式來實現這一點。

次佳解決方案

如果您正確使用回撥,則不需要所有冗餘程式碼。 Here’s how I implement the Settings API, in a way that is completely scalable

優點 (除其他外):

  • 「設定」API 強制對不受信任的使用者資料進行清理。

  • 「設定」API 強制將註冊為選項陣列的選項導致單個 wp_options 資料庫條目,而不是每個選項的離散資料庫條目

  • 「設定」API 可幫助設定表單的安全加固

  • 「設定」API 可幫助管理介面與核心管理介面一致,從而實現更好的使用者體驗

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。