ข้อดีของ API การตั้งค่าคืออะไร


13

ให้ฉันนำหน้าสิ่งนี้โดยบอกว่าฉันแทบจะไม่เคยทำงานกับ WordPress - ในความเป็นจริงครั้งล่าสุดที่ฉันทำเว็บไซต์ใน WordPress กลับมาในช่วง 2.2 เมื่อวานนี้ฉันทำทุกอย่างยุ่ง ๆ และถามคำถามหลายข้อที่นี่เพื่อพยายามใช้งานปลั๊กอินเมนูพื้นฐาน

ตอนนี้ฉันมีปลั๊กอินทำงานได้อย่างสมบูรณ์และทำงานตามที่ฉันคาดไว้ดังนั้นฉันจึงตัดสินใจเปลี่ยนแปลงเล็กน้อยที่นี่และเพิ่มฟังก์ชั่นและความเข้ากันได้รวมถึงการใช้ API การตั้งค่า อย่างไรก็ตามช่วงเวลาสั้น ๆ ในการอ่านบทช่วยสอนเกี่ยวกับ API นี้และฉันค่อนข้างสับสนแล้วความสับสนนี้จะลึกซึ้งยิ่งขึ้นเมื่อฉันอ่านและพยายามใช้ตัวอย่าง - ซึ่งทำให้ยากยิ่งขึ้นโดยความจริงที่ว่าปลั๊กอินของฉันถูกใช้เป็นคลาส .

หากฉันทำสิ่งผิดปกติจากสิ่งที่ฉันเข้าใจในการใช้งาน API การตั้งค่าต้องมีการสร้างฟังก์ชั่นใหม่ต่อการตั้งค่า นี่หมายถึงฟังก์ชั่น 3-5 ตัวสำหรับปลั๊กอินเฉลี่ยและสูงสุดถึงร้อยสำหรับปลั๊กอินขั้นสูงเพิ่มเติม ดูเหมือนว่าน่าหัวเราะที่จะเขียนฟังก์ชั่นมากมาย (และพัฒนาระบบการตั้งชื่อเพื่อไม่ให้เกิดความสับสน) เมื่อคุณสามารถนำเข้า$_POSTตัวแปรที่เกี่ยวข้องทั้งหมดลงในอาเรย์และนำไปสู่ความยุ่งเหยิงทั้งหมดได้อย่างง่ายดาย

บางทีฉันอาจจะล้าสมัย แต่ถ้ามีบางอย่างที่จะได้รับจากสิ่งนี้ฉันไม่เห็นเหตุผลที่จะเพิ่มจำนวนสามเท่าหรือสี่เท่าของรหัสที่ฉันเขียน นี่คือวิธีที่ฉันจัดการตัวเลือกก่อนพยายามเพิ่มการตั้งค่า 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?
    }

มันอาจจะเจ็บปวดอย่างเห็นได้ชัดจากแถบเลื่อนที่รหัสนั้นมีอยู่แล้วด้วยตัวเลือกเพียงสองตัว มันชัดเจนเหมือนกันจากความคิดเห็นที่ฉันไม่เข้าใจว่าฉันทำอะไร แล้วมีเรื่องของการมี 5 ฟังก์ชั่นใหม่ (และลบออกเพียง 1) เพื่อให้บรรลุทั้งหมดนี้

ดังนั้นฉันได้เปรียบอะไรจากงานพิเศษทั้งหมดนี้


อย่าใช้พวกเขาสำหรับกรณีดังกล่าว ฉันคิดว่าพวกเขามีไว้สำหรับผู้เริ่มต้น PHP ที่ต้องการตัวเลือก 3-4 ภายในปลั๊กอิน / ชุดรูปแบบของพวกเขา นี่คือหนึ่งใน "คุณสมบัติ" ที่ควรได้รับการดำเนินการที่ไม่เคย ... มันเป็นพื้น API สำหรับ API อีก :)
onetrickpony

3
ฉันใช้ API การตั้งค่าสำหรับทุกสิ่งที่ฉันเขียนทุกอย่างขึ้นอยู่กับว่าคุณใช้อย่างไรโปรดทราบว่าคุณสามารถใช้ API ได้โดยไม่ต้องใช้add_settings_sectionและadd_settings_fieldทั้งสองฟังก์ชั่นเหล่านี้จะเพิ่ม bloat ให้กับรหัสของคุณมากกว่าสิ่งอื่น ๆ
t31os

1
ฉันทำสิ่งเดียวกันกับ t3los: ลงทะเบียนการตั้งค่าเองจากนั้นฉันก็โค้ดในรูปแบบ HTML ในหน้าการตั้งค่าของฉัน หากคุณต้องการเห็นวิธีที่ง่ายมากในการทำเช่นนี้และเก็บรหัสไว้ใช้ภายหลังตรวจสอบปลั๊กอิน WordPress SEO ของ Yoast
chrisguitarguy

คำตอบ:


8

มุมมองของฉันคือว่าวัตถุประสงค์หลักและประโยชน์ของการตั้งค่า API เป็นโครงสร้าง

ช่วยให้การตั้งค่าที่ซับซ้อนยังคงอยู่:

  • เป็นระเบียบ (ตรรกะของการลงทะเบียนและส่วน);
  • ปลอดภัย (nonces, callbacks การตรวจสอบความถูกต้อง);
  • ขยายได้ (เชื่อมต่อไปยังหน้าอื่นหรืออนุญาตให้เชื่อมต่อ)

เช่นเดียวกับค่าใช้จ่ายในโครงสร้างดังกล่าวจะได้รับประโยชน์กรณีการใช้ที่ซับซ้อนมากขึ้นและประโยชน์ที่ได้ง่ายขึ้น

ดังนั้นคุณสามารถใช้ API การตั้งค่าใดก็ได้โดยไม่ต้องใช้ คำถามคือถ้าคุณสามารถทำได้โดยใช้วิธีที่เชื่อถือได้ปลอดภัยและสามารถขยายได้


ในที่สุดฉันก็มีหน้าการตั้งค่าของฉันทำงานด้วยความช่วยเหลือจากบทช่วยสอนนี้: alisothegeek.com/2011/01/wordpress-settings-api-tutorial-1และด้วยความช่วยเหลือของคำสั่งสวิตช์และฟังก์ชั่นตัวช่วยฉันต้องบอกว่าตอนนี้สิ่งต่าง ๆ เป็นระเบียบมากขึ้น ในรหัสของฉัน (ซึ่งเป็นสิ่งที่ดีตั้งแต่ฉันวางแผนที่จะย้ายจากการตั้งค่าการทดสอบทั้งสองของฉันไปยังการตั้งค่าทั้งหมด 15-20 แห่ง)
stevendesu

1
@steven_desu ใช่เรื่องตลกที่กำลังทำงานอยู่คือทุกคนที่ใช้ API การตั้งค่าจะเขียนเฟรมเวิร์ก :) ฟังก์ชั่นผู้ช่วยคู่รักเกือบจะหลีกเลี่ยงไม่ได้ โปรดทราบด้วยว่าการตั้งค่า API นั้นไม่ถือเป็นข้อสรุปและมีแผน (คลุมเครือ) ในการปรับปรุงในอนาคต (ฉันคิดว่ามันถูกกล่าวถึงในบริบทของแผน 3.3)
Rarst

1
ฉันหวังว่ามันจะดีขึ้นอย่างแน่นอน ฉันไม่เห็นข้อดีของการตั้งค่า API แต่ข้อดีทุกข้อที่ฉันได้รับในตอนนี้คือผลลัพธ์ของกรอบการทำงานที่ฉันยืมมา ฉันชอบที่องค์ประกอบของแบบฟอร์มทั้งหมดจะถูกสร้างขึ้นแบบไดนามิกที่มีลักษณะเดียวกัน ... แต่นั่นไม่ใช่การตั้งค่า API ฉันชอบการตั้งค่าเริ่มต้นและการตั้งค่าการลงทะเบียนถูกจัดการโดยคำจำกัดความเดียวกัน ... แต่นั่นไม่ใช่การตั้งค่า API ฉันชอบที่ jQuery ไม่เพียง แต่ทำให้รูปแบบสวย แต่จะเพิ่มความก้าวหน้า - แต่ผมต้องรหัสด้วยตนเองการเพิ่มประสิทธิภาพของความก้าวหน้า ...
stevendesu

5

หากคุณใช้การโทรกลับอย่างถูกต้องไม่จำเป็นต้องใช้รหัสซ้ำซ้อนทั้งหมด นี่เป็นวิธีที่ผมใช้ API การตั้งค่าในทางที่สามารถปรับได้อย่างสมบูรณ์

ข้อดี (เหนือสิ่งอื่นใด):

  • Settings API บังคับให้การล้างข้อมูลผู้ใช้ไม่น่าเชื่อถือ
  • การตั้งค่า API บังคับให้ตัวเลือกที่จะลงทะเบียนเป็นอาร์เรย์ตัวเลือกส่งผลให้รายการฐานข้อมูล wp_options เดียวแทนที่จะเป็นรายการฐานข้อมูลแยกสำหรับแต่ละตัวเลือก
  • API การตั้งค่าอำนวยความสะดวกในการเสริมความปลอดภัยของแบบฟอร์มการตั้งค่า
  • Settings API ช่วยอำนวยความสะดวกให้กับ UI ของผู้ดูแลระบบที่สอดคล้องกับ core UI ของผู้ดูแลระบบส่งผลให้ UX ดีขึ้น

ดังนั้นจึงบังคับให้มาตรฐานด้านความปลอดภัยและความงามที่ฉันได้ติดตามมาโดยไม่ได้รับความช่วยเหลือ ฉันจะอ่านบทช่วยสอนที่คุณเชื่อมโยงไว้ ถ้ามันทำให้ API การตั้งค่าเป็นเรื่องง่ายเหมือนการเข้ารหัสด้วยตนเองรูปแบบ (หรือง่ายขึ้น) แล้วฉันจะยอมรับคำตอบนี้
stevendesu

คุณทราบว่ารหัสที่มาที่คุณชี้ไปที่การดำเนินการการทำงานoenology_get_settings_by_tab()และoenology_get_default_optionsไม่เคยครั้งแรกกำหนดพวกเขา? ฉันคิดว่ามันไม่ดีพอที่รหัส 209 บรรทัด (หลังจากลบความคิดเห็นและบรรทัดว่าง) แต่เมื่อฟังก์ชั่นเหล่านั้นถูกกำหนดแล้วมันจะยิ่งนานขึ้น ... สำหรับสี่ตัวเลือก?
stevendesu

พวกมันถูกนิยามไว้ที่อื่น สิ่งที่oenology_get_settings_by_tab()ไม่เกี่ยวข้องกับสิ่งที่คุณกำลังทำอยู่จริงๆ แต่คุณต้องกำหนดมาร์กอัพ form-field ของคุณที่ไหนสักแห่งเช่นเดียวกับที่คุณต้องตรวจสอบ / ฆ่าเชื้อการป้อนข้อมูลของผู้ใช้อย่างใดดังนั้นถ้าคุณทำถูกต้องคุณจะมีรหัสเดียวกันทั้งหมด
Chip Bennett

0

ขอบคุณสำหรับการโพสต์สิ่งนี้ฉันสงสัยในสิ่งเดียวกัน ฟังก์ชั่นมากมาย

เพื่อลดพวกเขาคุณสามารถเก็บตัวเลือกของคุณเป็นอาร์เรย์ Wordpress จัดลำดับข้อมูลให้คุณ ซึ่งจะบันทึกในรหัส (หรือฟังก์ชั่นอยู่แล้ว) แต่ทำให้ข้อมูลแย่ลง ตัวอย่างเช่นหากคุณต้องการเรียงลำดับแก้ไขด้วยมือส่งออก ฯลฯ ตารางของคุณจะมีค่าลำดับเหล่านี้ ในทางตรงกันข้ามปลั๊กอินของคุณเพิ่มรายการน้อยลงในตารางตัวเลือกและพวกเขาจะง่ายต่อการทำความสะอาด

ดังนั้นนี่คือรหัสของคุณอีกครั้ง หมายเหตุเล็กน้อย:

  • ตัวอย่างของฉันสาธิตทั้งตัวเลือกอย่างง่าย (de_w, de_h) และตัวเลือกอาร์เรย์ (de_width_height)
  • ฆ่าเชื้ออินพุตของผู้ใช้เสมอ ฉันใช้จำนวนเต็มในตัวอย่างเพราะง่ายต่อการฆ่าเชื้อ
  • คุณไม่ต้องการ $ _POST, nonces, check_admin_referer (), update_option () ฯลฯ เมื่อใช้ API การตั้งค่า
  • การบันทึกเกิดขึ้นในการโหลดหน้าถัดไปไม่ใช่เมื่อปิดระบบ จากนั้น WP จะเปลี่ยนเส้นทางไปยังหน้าของคุณ หากต้องการดีบักให้พิมพ์เอาต์พุตและเรียกใช้ wp_die () ในหนึ่งในฟังก์ชันการตรวจสอบความถูกต้อง
  • การกระทำของฟอร์มจะเป็น "options.php" เสมอ นั่นคือการทำงานของการตั้งค่า API อย่าใช้อย่างอื่น คุณสามารถใช้ admin_url ('options.php') ได้หากต้องการ
  • WP จะพิมพ์ข้อความบันทึกสำหรับคุณ
  • ไม่รวมการปรับปรุงที่นี่: ใช้<label>สำหรับการเข้าถึง ใช้ add_settings_error (), settings_error () ซึ่งจัดการข้อความรวมถึงข้อผิดพลาด นั่นเป็นเหตุผลเดียวที่มีฟังก์ชั่นตรวจสอบความถูกต้องแยกต่างหากสำหรับแต่ละตัวเลือก คุณสามารถดูด้านล่าง validate_w () และ validate_h () อาจเป็นหนึ่งฟังก์ชัน ฉันดูที่พยายามสรุปข้อความ แต่คุณมีข้อมูลไม่เพียงพอในการโทรกลับเพื่อตรวจสอบความถูกต้องตามที่ฉันจำได้ เช่นเดียวกับเขตข้อมูลที่คุณกำลังทำงานอยู่
  • ฟังก์ชันการเรียกกลับการตรวจสอบความถูกต้องได้รับค่า $ _POST ดิบจาก API การตั้งค่า ฉันต้องการตั้งชื่อพารามิเตอร์เช่น $ raw สำหรับตัวเลือกอาร์เรย์คุณจะได้รับอาร์เรย์เช่นเดียวกับเวทมนตร์
  • แก้ไข: $ นี่ดีกว่า & $ นี่

รหัส:

<?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;
}
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.