Lỗi Lỗi: Không tìm thấy Trang Tùy chọn Đặt tên trên Trang cài đặt Gửi cho Trình cắm OOP


19

Tôi đang phát triển một plugin sử dụng kho lưu trữ Boiler khắc của Tom McFarlin làm mẫu, sử dụng các thực tiễn OOP. Tôi đã cố gắng tìm ra chính xác lý do tại sao tôi không thể gửi chính xác cài đặt của mình. Tôi đã thử đặt thuộc tính hành động thành một chuỗi trống như được đề xuất cho một câu hỏi khác quanh đây, nhưng điều đó không giúp ...

Dưới đây là thiết lập mã chung tôi đang sử dụng ...

Biểu mẫu (/view/admin.php):

<div class="wrap">
    <h2><?php echo esc_html( get_admin_page_title() ); ?></h2>
    <form action="options.php" method="post">
        <?php
        settings_fields( $this->plugin_slug );
        do_settings_sections( $this->plugin_slug );
        submit_button( 'Save Settings' );
        ?>
    </form>
</div>

Đối với mã sau đây, giả sử tất cả các cuộc gọi lại cho add_sinstall_field () và add_sinstall_section (), ngoại trừ 'tùy chọn_list_selection'.

Lớp quản trị bổ trợ (/ {plugin_name}-class-admin.php):

namespace wp_plugin_name;

class Plugin_Name_Admin
{
    /**
     * Note: Some portions of the class code and method functions are missing for brevity
     * Let me know if you need more information...
     */

    private function __construct()
    {
        $plugin              = Plugin_Name::get_instance();

        $this->plugin_slug   = $plugin->get_plugin_slug();
        $this->friendly_name = $plugin->get_name(); // Get "Human Friendly" presentable name

        // Adds all of the options for the administrative settings
        add_action( 'admin_init', array( $this, 'plugin_options_init' ) );

        // Add the options page and menu item
        add_action( 'admin_menu', array( $this, 'add_plugin_admin_menu' ) );


    }

    public function add_plugin_admin_menu()
    {

        // Add an Options Page
        $this->plugin_screen_hook_suffix =
        add_options_page(
            __( $this->friendly_name . " Options", $this->plugin_slug ),
            __( $this->friendly_name, $this->plugin_slug ),
            "manage_options", 
            $this->plugin_slug,
            array( $this, "display_plugin_admin_page" )
        );

    }

    public function display_plugin_admin_page()
    {
        include_once( 'views/admin.php' );
    }

    public function plugin_options_init()
    {
        // Update Settings
        add_settings_section(
            'maintenance',
            'Maintenance',
            array( $this, 'maintenance_section' ),
            $this->plugin_slug
        );

        // Check Updates Option
        register_setting( 
            'maintenance',
            'plugin-name_check_updates',
            'wp_plugin_name\validate_bool'
        );

        add_settings_field(
            'check_updates',
            'Should ' . $this->friendly_name . ' Check For Updates?',
            array( $this, 'check_updates_field' ),
            $this->plugin_slug,
            'maintenance'
        );

        // Update Period Option
        register_setting(
            'maintenance',
            'plugin-name_update_period',
            'wp_plugin_name\validate_int'
        );

        add_settings_field(
            'update_frequency',
            'How Often Should ' . $this->friendly_name . ' Check for Updates?',
            array( $this, 'update_frequency_field' ),
            $this->plugin_slug,
            'maintenance'
        );

        // Plugin Option Configurations
        add_settings_section(
            'category-option-list', 'Widget Options List',
            array( $this, 'option_list_section' ),
            $this->plugin_slug
        );
    }
}

Một số cập nhật được yêu cầu:

Thay đổi thuộc tính hành động thành:

<form action="../../options.php" method="post">

... chỉ đơn giản là dẫn đến Lỗi 404. Dưới đây là đoạn trích của Nhật ký Apache. Lưu ý rằng các tập lệnh WordPress và hàng đợi CSS mặc định đã bị xóa:

# Changed to ../../options.php
127.0.0.1 - - [01/Apr/2014:15:59:43 -0400] "GET /wp-admin/options-general.php?page=pluginname-widget HTTP/1.1" 200 18525
127.0.0.1 - - [01/Apr/2014:15:59:43 -0400] "GET /wp-content/plugins/PluginName/admin/assets/css/admin.css?ver=0.1.1 HTTP/1.1" 304 -
127.0.0.1 - - [01/Apr/2014:15:59:43 -0400] "GET /wp-content/plugins/PluginName/admin/assets/js/admin.js?ver=0.1.1 HTTP/1.1" 304 -
127.0.0.1 - - [01/Apr/2014:15:59:52 -0400] "POST /options.php HTTP/1.1" 404 1305
127.0.0.1 - - [01/Apr/2014:16:00:32 -0400] "POST /options.php HTTP/1.1" 404 1305

#Changed to options.php
127.0.0.1 - - [01/Apr/2014:16:00:35 -0400] "GET /wp-admin/options-general.php?page=pluginname-widget HTTP/1.1" 200 18519
127.0.0.1 - - [01/Apr/2014:16:00:35 -0400] "GET /wp-content/plugins/PluginName/admin/assets/css/admin.css?ver=0.1.1 HTTP/1.1" 304 -
127.0.0.1 - - [01/Apr/2014:16:00:35 -0400] "GET /wp-content/plugins/PluginName/admin/assets/js/admin.js?ver=0.1.1 HTTP/1.1" 304 -
127.0.0.1 - - [01/Apr/2014:16:00:38 -0400] "POST /wp-admin/options.php HTTP/1.1" 500 2958

Cả tệp php-error.log và tệp debug.log khi WP_DEBUG đều trống.

Lớp bổ trợ (/ nbplugin-name Bolog- class.php)

namespace wp_plugin_name;

class Plugin_Name
{
    const VERSION = '1.1.2';
    const TABLE_VERSION = 1;
    const CHECK_UPDATE_DEFAULT = 1;
    const UPDATE_PERIOD_DEFAULT = 604800;

    protected $plugin_slug = 'pluginname-widget';
    protected $friendly_name = 'PluginName Widget';

    protected static $instance = null;

    private function __construct()
    {

        // Load plugin text domain
        add_action( 'init',
                    array(
            $this,
            'load_plugin_textdomain' ) );

        // Activate plugin when new blog is added
        add_action( 'wpmu_new_blog',
                    array(
            $this,
            'activate_new_site' ) );

        // Load public-facing style sheet and JavaScript.
        add_action( 'wp_enqueue_scripts',
                    array(
            $this,
            'enqueue_styles' ) );
        add_action( 'wp_enqueue_scripts',
                    array(
            $this,
            'enqueue_scripts' ) );

        /* Define custom functionality.
         * Refer To http://codex.wordpress.org/Plugin_API#Hooks.2C_Actions_and_Filters
         */

    }

    public function get_plugin_slug()
    {
        return $this->plugin_slug;
    }

    public function get_name()
    {
        return $this->friendly_name;
    }

    public static function get_instance()
    {

        // If the single instance hasn't been set, set it now.
        if ( null == self::$instance )
        {
            self::$instance = new self;
        }

        return self::$instance;

    }

    /**
     * The member functions activate(), deactivate(), and update() are very similar.
     * See the Boilerplate plugin for more details...
     *
     */

    private static function single_activate()
    {
        if ( !current_user_can( 'activate_plugins' ) )
            return;

        $plugin_request = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';

        check_admin_referer( "activate-plugin_$plugin_request" );

        /**
         *  Test to see if this is a fresh installation
         */
        if ( get_option( 'plugin-name_version' ) === false )
        {
            // Get the time as a Unix Timestamp, and add one week
            $unix_time_utc = time() + Plugin_Name::UPDATE_PERIOD_DEFAULT;

            add_option( 'plugin-name_version', Plugin_Name::VERSION );
            add_option( 'plugin-name_check_updates',
                        Plugin_Name::CHECK_UPDATE_DEFAULT );
            add_option( 'plugin-name_update_frequency',
                        Plugin_Name::UPDATE_PERIOD_DEFAULT );
            add_option( 'plugin-name_next_check', $unix_time_utc );

            // Create options table
            table_update();

            // Let user know PluginName was installed successfully
            is_admin() && add_filter( 'gettext', 'finalization_message', 99, 3 );
        }
        else
        {
            // Let user know PluginName was activated successfully
            is_admin() && add_filter( 'gettext', 'activate_message', 99, 3 );
        }

    }

    private static function single_update()
    {
        if ( !current_user_can( 'activate_plugins' ) )
            return;

        $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';

        check_admin_referer( "activate-plugin_{$plugin}" );

        $cache_plugin_version         = get_option( 'plugin-name_version' );
        $cache_table_version          = get_option( 'plugin-name_table_version' );
        $cache_deferred_admin_notices = get_option( 'plugin-name_admin_messages',
                                                    array() );

        /**
         * Find out what version of our plugin we're running and compare it to our
         * defined version here
         */
        if ( $cache_plugin_version > self::VERSION )
        {
            $cache_deferred_admin_notices[] = array(
                'error',
                "You seem to be attempting to revert to an older version of " . $this->get_name() . ". Reverting via the update feature is not supported."
            );
        }
        else if ( $cache_plugin_version === self::VERSION )
        {
            $cache_deferred_admin_notices[] = array(
                'updated',
                "You're already using the latest version of " . $this->get_name() . "!"
            );
            return;
        }

        /**
         * If we can't determine what version the table is at, update it...
         */
        if ( !is_int( $cache_table_version ) )
        {
            update_option( 'plugin-name_table_version', TABLE_VERSION );
            table_update();
        }

        /**
         * Otherwise, we'll just check if there's a needed update
         */
        else if ( $cache_table_version < TABLE_VERSION )
        {
            table_update();
        }

        /**
         * The table didn't need updating.
         * Note we cannot update any other options because we cannot assume they are still
         * the defaults for our plugin... ( unless we stored them in the db )
         */

    }

    private static function single_deactivate()
    {

        // Determine if the current user has the proper permissions
        if ( !current_user_can( 'activate_plugins' ) )
            return;

        // Is there any request data?
        $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';

        // Check if the nonce was valid
        check_admin_referer( "deactivate-plugin_{$plugin}" );

        // We'll, technically the plugin isn't included when deactivated so...
        // Do nothing

    }

    public function load_plugin_textdomain()
    {

        $domain = $this->plugin_slug;
        $locale = apply_filters( 'plugin_locale', get_locale(), $domain );

        load_textdomain( $domain,
                         trailingslashit( WP_LANG_DIR ) . $domain . '/' . $domain . '-' . $locale . '.mo' );
        load_plugin_textdomain( $domain, FALSE,
                                basename( plugin_dir_path( dirname( __FILE__ ) ) ) . '/languages/' );

    }

    public function activate_message( $translated_text, $untranslated_text,
                                      $domain )
    {
        $old = "Plugin <strong>activated</strong>.";
        $new = FRIENDLY_NAME . " was  <strong>successfully activated</strong> ";

        if ( $untranslated_text === $old )
            $translated_text = $new;

        return $translated_text;

    }

    public function finalization_message( $translated_text, $untranslated_text,
                                          $domain )
    {
        $old = "Plugin <strong>activated</strong>.";
        $new = "Captain, The Core is stable and PluginName was <strong>successfully installed</strong> and ready for Warp speed";

        if ( $untranslated_text === $old )
            $translated_text = $new;

        return $translated_text;

    }

}

Tài liệu tham khảo:


Báo cáo mô tả tiền thưởng: "Vui lòng cung cấp một số thông tin về thực tiễn tốt nhất " . Sử dụng singletons với các nhà xây dựng tư nhân và một loạt các hành động bên trong chúng: tuy nhiên thực tiễn tồi và khó kiểm tra, không phải lỗi của bạn.
gmazzap

1
sử dụng ../../options.php sau khi kiểm tra mã của bạn.
ravi patel

Bạn có thể vui lòng hiển thị get_plugin_slug ().
vancoder

@vancoder Tôi đã chỉnh sửa bài đăng ở trên với thông tin liên quan ...
gate_engineer

Tại sao có dấu gạch chéo ngược trong các cuộc gọi lại vệ sinh trong register_sinstall của bạn? Tôi không nghĩ rằng nó sẽ làm việc.
Bjorn

Câu trả lời:


21

Lỗi "Không tìm thấy trang tùy chọn"

Đây là sự cố đã biết trong API Cài đặt WP. Có một vé được mở từ nhiều năm trước và được đánh dấu là đã được giải quyết - nhưng lỗi vẫn tồn tại trong các phiên bản mới nhất của WordPress. Đây là những gì trang Codex (hiện đã bị xóa) nói về điều này :

Trang "Lỗi: tùy chọn không tìm thấy." vấn đề (bao gồm giải pháp và giải thích):

Vấn đề sau đó là, bộ lọc 'whlistist_options' không có chỉ mục phù hợp với dữ liệu của bạn. Nó được áp dụng trên các tùy chọn.php # 98 (WP 3.4).

register_settings()thêm dữ liệu của bạn vào toàn cầu $new_whitelist_options. Điều này sau đó được hợp nhất với toàn cầu $whitelist_optionsbên trong option_update_filter()(các add_option_whitelist()) cuộc gọi lại ( resp. ). Những cuộc gọi lại thêm dữ liệu của bạn vào toàn cầu $new_whitelist_optionsvới $option_groupchỉ mục dưới dạng. Khi bạn gặp "Lỗi: không tìm thấy trang tùy chọn." nó có nghĩa là chỉ mục của bạn chưa được công nhận. Điều gây hiểu lầm là đối số đầu tiên được sử dụng làm chỉ mục và được đặt tên $options_group, khi kiểm tra thực tế trong tùy chọn.php # 112 xảy ra ngược lại $options_page, đó là $hook_suffixgiá trị mà bạn nhận được dưới dạng giá trị @return add_submenu_page().

Tóm lại, một giải pháp dễ dàng là làm cho $option_groupphù hợp $option_name. Một nguyên nhân khác gây ra lỗi này là có giá trị không hợp lệ cho $pagetham số khi gọi một trong hai add_settings_section( $id, $title, $callback, $page )hoặc add_settings_field( $id, $title, $callback, $page, $section, $args ).

Gợi ý: $pagephải khớp $menu_slugtừ trang Tham khảo chức năng / thêm chủ đề.

Sửa chữa đơn giản

Sử dụng tên trang tùy chỉnh (trong trường hợp của bạn $this->plugin_slug:) làm id phần của bạn sẽ giải quyết được vấn đề. Tuy nhiên, tất cả các tùy chọn của bạn sẽ phải được chứa trong một phần duy nhất.

Dung dịch

Để có giải pháp mạnh mẽ hơn, hãy thực hiện những thay đổi này cho Plugin_Name_Adminlớp của bạn :

Thêm vào hàm tạo:

// Tracks new sections for whitelist_custom_options_page()
$this->page_sections = array();
// Must run after wp's `option_update_filter()`, so priority > 10
add_action( 'whitelist_options', array( $this, 'whitelist_custom_options_page' ),11 );

Thêm các phương thức sau:

// White-lists options on custom pages.
// Workaround for second issue: http://j.mp/Pk3UCF
public function whitelist_custom_options_page( $whitelist_options ){
    // Custom options are mapped by section id; Re-map by page slug.
    foreach($this->page_sections as $page => $sections ){
        $whitelist_options[$page] = array();
        foreach( $sections as $section )
            if( !empty( $whitelist_options[$section] ) )
                foreach( $whitelist_options[$section] as $option )
                    $whitelist_options[$page][] = $option;
            }
    return $whitelist_options;
}

// Wrapper for wp's `add_settings_section()` that tracks custom sections
private function add_settings_section( $id, $title, $cb, $page ){
    add_settings_section( $id, $title, $cb, $page );
    if( $id != $page ){
        if( !isset($this->page_sections[$page]))
            $this->page_sections[$page] = array();
        $this->page_sections[$page][$id] = $id;
    }
}

Và thay đổi add_settings_section()cuộc gọi thành : $this->add_settings_section().


Các ghi chú khác về mã của bạn

  • Mã hình thức của bạn là chính xác. Biểu mẫu của bạn phải gửi tới tùy chọn.php, như được chỉ ra cho tôi bởi @Chris_O và như được chỉ ra trong tài liệu API Cài đặt WP .
  • Không gian tên có ưu điểm của nó, nhưng nó có thể khiến việc gỡ lỗi trở nên phức tạp hơn và làm giảm tính tương thích của mã của bạn (yêu cầu PHP> = 5.3, các plugin / chủ đề khác sử dụng trình tải tự động, v.v.). Vì vậy, nếu không có lý do chính đáng để không gian tên tệp của bạn, đừng. Bạn đã tránh xung đột đặt tên bằng cách gói mã của bạn trong một lớp. Đặt tên lớp của bạn cụ thể hơn và đưa các validate()cuộc gọi lại của bạn vào lớp dưới dạng phương thức công khai.
  • So sánh bản tóm tắt plugin được trích dẫn của bạn với mã của bạn, có vẻ như mã của bạn thực sự dựa trên một ngã ba hoặc một phiên bản cũ của bản tóm tắt. Ngay cả tên tệp và đường dẫn cũng khác nhau. Bạn có thể di chuyển plugin của mình sang phiên bản mới nhất, nhưng lưu ý rằng bản tóm tắt plugin này có thể không phù hợp với nhu cầu của bạn. Nó sử dụng các singletons, thường không được khuyến khích . Có những trường hợp mô hình singleton là hợp lý , nhưng đây phải là quyết định có ý thức, không phải là giải pháp goto.

1
Thật tuyệt khi biết rằng có một lỗi trong api. Tôi luôn cố gắng xem qua mã tôi viết cho các lỗi tôi có thể giới thiệu. Tất nhiên, điều đó giả định rằng tôi biết một hoặc hai điều.
gate_engineer

Đối với bất kỳ ai gặp phải vấn đề này: hãy xem ví dụ OOP trong codex: codex.wordpress.org/Creating_Options_Pages#Example_.232
maysi

5

Tôi chỉ tìm thấy bài đăng này trong khi tìm kiếm cùng một vấn đề. Giải pháp đơn giản hơn nhiều so với vẻ ngoài của nó vì tài liệu bị sai lệch: trong register_setting () đối số đầu tiên có tên $option_grouplà sên trang của bạn, không phải là phần bạn muốn hiển thị cài đặt.

Trong đoạn mã trên bạn nên sử dụng

    // Update Settings
    add_settings_section(
        'maintenance', // section slug
        'Maintenance', // section title
        array( $this, 'maintenance_section' ), // section display callback
        $this->plugin_slug // page slug
    );

    // Check Updates Option
    register_setting( 
        $this->plugin_slug, // page slug, not the section slug
        'plugin-name_check_updates', // setting slug
        'wp_plugin_name\validate_bool' // invalid, should be an array of options, see doc for more info
    );

    add_settings_field(
        'plugin-name_check_updates', // setting slug
        'Should ' . $this->friendly_name . ' Check For Updates?', // setting title
        array( $this, 'check_updates_field' ), //setting display callback
        $this->plugin_slug, // page slug
        'maintenance' // section slug
    );

Điều này LAF không đúng. Vui lòng xem ví dụ hoạt động này (không phải của tôi) - gist.github.com/annalinneajohansson/5290405
Xdg

2

Trong khi đăng ký trang tùy chọn với:

add_submenu_page( string $parent_slug, string $page_title, string $menu_title, string $capability, string $menu_slug, callable $function = '' )

Và đăng ký cài đặt với

register_setting( string $option_group, string $option_name );

$option_group nên giống như $menu_slug


1

Tôi đã có cùng một lỗi nhưng đã nhận nó theo một cách khác:

// no actual code
// this failed
add_settings_field('id','title', /*callback*/ function($arguments) {
    // echo $htmlcode; 
    register_setting('option_group', 'option_name');
}), 'page', 'section');

Tôi không biết tại sao điều này xảy ra, nhưng dường như register_settingkhông nên trong cuộc gọi lại củaadd_settings_field

// no actual code
// this worked
add_settings_field('id','title', /*callback*/ function($arguments) {echo $htmlcode;}), 'page', 'section');
register_setting('option_group', 'option_name');

Tôi hi vọng cái này giúp được


0

Tôi đã phải đối mặt với vấn đề này trong một số ngày nay, lỗi này đã dừng lại khi tôi đưa ra nhận xét về dòng:

// settings_fields($this->plugin_slug);

sau đó tôi đang chuyển hướng đến tùy chọn.php nhưng tôi chưa thể giải quyết vấn đề này setting_fields.


tôi đã sửa nó từ chức năng xác nhận !! ;)
G.Karles
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.