webentwicklung-frage-antwort-db.com.de

Was sind die Vorteile der Einstellungs-API?

Lassen Sie mich vorwegnehmen, dass ich kaum mit WordPress arbeite - tatsächlich war das letzte Mal, dass ich eine Site in WordPress erstellte, 2.2. Gestern habe ich alles durcheinander gebracht und hier einige Fragen gestellt, um ein einfaches Menü-Plugin zum Laufen zu bringen.

Ich habe jetzt das Plugin voll funktionsfähig und verhalte mich genau so, wie ich es erwartet habe. Deshalb habe ich mich entschlossen, hier und da kleinere Änderungen vorzunehmen, um Funktionalität und Kompatibilität hinzuzufügen - einschließlich der Verwendung der Einstellungs-API. Ein sehr kurzer Moment, in dem ich Tutorials zu dieser API gelesen hatte, und ich war ziemlich verwirrt, dann wurde diese Verwirrung nur noch größer, als ich weiterlas und versuchte, die Beispiele zu implementieren - was durch die Tatsache, dass mein Plugin als Klasse implementiert ist, noch schwieriger wurde .

Sofern ich nichts falsch mache, muss nach meinem Verständnis für die Verwendung der Einstellungs-API eine neue Funktion PRO EINSTELLUNG erstellt werden. Dies bedeutet 3-5 Funktionen für das durchschnittliche Plugin und bis zu Hunderten für fortgeschrittenere Plugins. Es erscheint einfach lächerlich, so viele Funktionen zu schreiben (und ein Benennungssystem zu entwickeln, um sie nicht zu verwirren), wenn Sie genauso einfach alle anwendbaren $_POST -Variablen in ein Array importieren und auf das gesamte Durcheinander verzichten können.

Vielleicht bin ich altmodisch, aber es sei denn, es gibt etwas zu gewinnen, sehe ich keinen Grund, um zu verdreifachen oder zu vervierfachen, wie viel Code ich schreibe. So verwaltete ich Optionen, bevor ich versuchte, die Einstellungs-API hinzuzufügen:

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

Jetzt habe ich mit der Einstellungs-API etwas Ähnliches:

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

An den Bildlaufleisten ist wahrscheinlich schmerzlich zu erkennen, dass der Code mit nur zwei Optionen bereits länger ist. Aus den Kommentaren geht ebenfalls hervor, dass ich nicht ganz verstehe, was ich tue. Dann muss man 5 neue Funktionen haben (und nur 1 entfernen), um all dies zu erreichen.

Welchen Vorteil habe ich von all dieser zusätzlichen Arbeit?

12
stevendesu

Meiner Ansicht nach ist das Hauptziel und der Hauptnutzen der Einstellungs-API Struktur .

Es hilft, komplexe Einstellungs-Setups beizubehalten:

  • ordentlich (Logik der Registrierung und Abschnitte);
  • sicher (nonces, validation callbacks);
  • erweiterbar (in eine andere Seite einbinden oder einbinden lassen).

Wie bei jedem derartigen strukturellen Aufwand ergeben sich Vorteile für komplexere Anwendungsfälle und für weniger einfache.

Sie können also alles implementieren, was die Einstellungs-API tut, ohne sie zu verwenden. Die Frage ist, ob Sie dies auf zuverlässige, sichere und erweiterbare Weise erreichen können.

8
Rarst

Wenn Sie Rückrufe ordnungsgemäß verwenden, ist nicht der gesamte redundante Code erforderlich. So implementiere ich die Einstellungs-API auf eine Weise, die vollständig skalierbar ist .

Vorteile (unter anderem):

  • Die Einstellungs-API erzwingt die Bereinigung nicht vertrauenswürdiger Benutzerdaten.
  • Die Einstellungs-API erzwingt die Registrierung von Optionen als Optionsarray. Dies führt zu einem einzelnen wp_options-DB-Eintrag und nicht zu einzelnen DB-Einträgen für jede Option
  • Die Einstellungs-API erleichtert die Sicherheitshärtung des Einstellungsformulars
  • Die Einstellungs-API vereinfacht die Benutzeroberfläche für Administratoren im Einklang mit der zentralen Benutzeroberfläche für Administratoren, was zu einer besseren Benutzeroberfläche führt
5
Chip Bennett

Danke, dass du das gepostet hast, ich habe mich genau das Gleiche gefragt. Viele Funktionen.

Um sie zu reduzieren, können Sie Ihre Optionen als Arrays speichern. Wordpress serialisiert die Daten für Sie. Das spart Code (oder funktioniert trotzdem), verschlechtert aber die Daten. Wenn Sie beispielsweise Ihre Tabellen sortieren, von Hand bearbeiten, exportieren usw. möchten, haben sie diese serialisierten Werte. Andererseits fügt Ihr Plugin der Optionstabelle weniger Einträge hinzu und sie sind einfacher zu bereinigen.

Also hier ist dein Code neu geschrieben. Ein paar Anmerkungen:

  • Mein Beispiel zeigt sowohl einfache Optionen (de_w, de_h) als auch eine Array-Option (de_width_height).
  • Benutzereingaben immer bereinigen. In diesem Beispiel habe ich Ganzzahlen verwendet, da diese leicht zu bereinigen sind.
  • Für die Verwendung der Einstellungs-API benötigen Sie nicht $ _POST, nonces, check_admin_referer (), update_option () usw.
  • Das Speichern erfolgt beim nächsten Laden der Seite, nicht beim Herunterfahren. Dann führt WP eine Weiterleitung zu Ihrer Seite durch. Drucken Sie zum Debuggen eine Ausgabe aus und rufen Sie wp_die () in einer der Validierungsfunktionen auf.
  • Die Formularaktion lautet immer "options.php". So funktioniert die Settings API. Verwenden Sie nichts anderes. Nun, Sie können admin_url ('options.php') verwenden, wenn Sie möchten.
  • WP druckt die Sicherungsnachricht für Sie aus.
  • Verbesserungen, die hier nicht enthalten sind: Verwenden von <label> für die Barrierefreiheit. Mit add_settings_error (), settings_error (), die sowohl Nachrichten als auch Fehler behandeln. Dies ist oft der einzige Grund, für jede Option separate Validierungsfunktionen zu haben. Unten sehen Sie, dass validate_w () und validate_h () eine Funktion sein können. Ich habe versucht, die Nachrichten zu abstrahieren, aber ich erinnere mich, dass der Validierungs-Rückruf nicht genügend Informationen enthält. Zum Beispiel, auf welchem ​​Gebiet Sie gerade arbeiten.
  • Die Validierungsrückruffunktionen erhalten einen Rohwert von $ _POST von der Einstellungs-API. Ich nenne den Parameter gerne $ raw. Für die Array-Option erhalten Sie ein Array wie Magie.
  • Bearbeiten: $ das ist besser als & $ das.

Code:

<?php
$foo= new de_Foo();
class de_Foo {
function __construct() {
    if (is_admin()) {
        add_action('admin_menu', array($this, 'admin_menu'));
        add_action('admin_init', array($this, 'admin_init'));
    } 
}
public function admin_menu() {
    add_options_page(
       'DE Menu Options',
       'DE Menu',
       'manage_options',
       'de-menu-options',
       array($this,'xoxptions')
    );
    // add_option('de-menu-options', $this->options);
}
public function admin_init() {
 register_setting(
      'de-menu-settings-group',
      'de_w',
      array($this, 'validate_w')
 );
 register_setting(
      'de-menu-settings-group',
      'de_h',
      array($this, 'validate_h')
 );
 register_setting(
      'de-menu-settings-group',
      'de_width_height',
      array($this, 'validate_width_height')
 );
 add_settings_section(
      'de-menu-settings-section-size',
      'Size',
      array($this, 'settings_section_size_render'),
      'de-menu-options'
 );
 add_settings_field(
      'de_w',
      'W',
      array($this, 'w_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_h',
      'H',
      array($this, 'h_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_width_height',
      'Width / Height',
      array($this, 'width_height_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
}
public function options() {
    if (!current_user_can('manage_options')) {
        wp_die( __('You do not have sufficient permissions to access this page.') );
    }
////////////////////////////
// no no no
////////////////////////////
//         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 admin_url('options.php'); ?>">
    <?php settings_fields('de-menu-settings-group'); ?>
    <?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 settings_section_size_render() {
    echo '<p>' . __('Main description of this section here.','de-menu-lang') . '</p>';
}
public function w_render() {
 $w= esc_attr( get_option('de_w') );
 echo "<p><input name='de_w' value='$w'></p>\n";
}
public function h_render() {
 $h= esc_attr( get_option('de_h') );
 echo "<p><input name='de_h' value='$h'></p>\n";
}
public function width_height_render() {
 $width_height= get_option('de_width_height', array());
 $width= esc_attr( @$width_height['width'] );
 $height= esc_attr( @$width_height['height'] );
 echo "<p>Width: <input name='de_width_height[width]' value='$width'></p>\n";
 echo "<p>Height: <input name='de_width_height[height]' value='$height'></p>\n";
}
function validate_w($raw) {
 return (int)$raw;
}
function validate_h($raw) {
 return (int)$raw;
}
function validate_width_height($raw) {
 is_array($raw) or $raw= array();
 $result= array();
 $result['width']= (int)@$raw['width'];
 $result['height']= (int)@$raw['height'];
 return $result;
}
}
0
kitchin