设置API表单中的某些字段正在保存,其他字段则不保存

时间:2019-04-04 作者:Jonathan Stegall

我有一个用于插件管理表单的类,使用设置API。它有很多字段,其中一些字段依赖于中已有的值wp_options.

现有选项确定渲染字段的频率(在本例中,是MailChimp API集成为API中的每个列表渲染字段,该列表是存储的API数据的几层)。

在管理界面中,我显示了九个字段。这是应该的。但只有前三个将保存任何数据。我试着改变前三个字段的类型,它们总是有效的,我也试着改变后六个字段的类型,但它们都不起作用。

我尝试的另一件事是硬编码大嵌套外最后六个字段的完整ID值foreach. 然后字段保存其数据。

代码如下:

add_action( \'admin_init\', array( $this, \'admin_settings_form\' ) );

/**
* Register items for the settings api
* @return void
*
*/
public function admin_settings_form() {

    $get_data = filter_input_array( INPUT_GET, FILTER_SANITIZE_STRING );
    $page     = isset( $get_data[\'tab\'] ) ? sanitize_key( $get_data[\'tab\'] ) : \'minnpost_mailchimp_settings\';
    $section  = isset( $get_data[\'tab\'] ) ? sanitize_key( $get_data[\'tab\'] ) : \'minnpost_mailchimp_settings\';

    $this->form_settings( \'form_settings\', \'form_settings\' );

}

private function form_settings( $page, $section ) {
    $form_sections = $this->setup_form_sections();
    $settings      = array();
    if ( ! empty( $form_sections ) ) {
        foreach ( $form_sections as $key => $value ) {
            $section = $key;
            // translators: 1 is the name of the shortcode
            $title = sprintf( \'Shortcode: [%1$s]\',
                esc_attr( strtolower( $value ) )
            );

            $page = $section;
            add_settings_section( $section, $title, null, $page );

            $settings[ $section . \'_resource_type\' ] = array(
                \'title\'    => __( \'Resource type\'),
                \'callback\' => \'display_select\',
                \'page\'     => $page,
                \'section\'  => $section,
                \'args\'     => array(
                    \'type\'     => \'select\',
                    \'items\'    => $this->get_resource_types(),
                ),
            );
            $resource_type                           = get_option( $this->option_prefix . \'newsletter_form_resource_type\', \'\' );
            $settings[ $section . \'_resource_id\' ]   = array(
                \'title\'    => __( \'Resource name\' ),
                \'callback\' => \'display_select\',
                \'page\'     => $page,
                \'section\'  => $section,
                \'args\'     => array(
                    \'type\'     => \'select\',
                    \'items\'    => $this->get_resource_ids( $resource_type ),
                ),
            );
            $resource_id                             = get_option( $this->option_prefix . \'newsletter_form_resource_id\', \'\' );

            if ( \'lists\' === $resource_type ) {
                $settings[ $section . \'_\' . $resource_type . \'_default_member_status\' ] = array(
                    \'title\'    => __( \'Default member status\' ),
                    \'callback\' => \'display_select\',
                    \'page\'     => $page,
                    \'section\'  => $section,
                    \'args\'     => array(
                        \'type\'     => \'select\',
                        \'items\'    => $this->get_member_statuses(),
                    ),
                );
            }

            $item_keys = array();

            $subresource_types = get_option( $this->parent_option_prefix . \'subresource_types_\' . $resource_type, array() );

            if ( ! empty( $subresource_types[ $resource_type ] ) ) {
                $subresource_types = $subresource_types[ $resource_type ];

                foreach ( $subresource_types as $subresource_type ) {

                    $items = get_option( $this->parent_option_prefix . \'subresources_\' . $resource_id . \'_\' . $subresource_type, array() );

                    if ( ! empty( $items[ $resource_type ][ $resource_id ][ $subresource_type ] ) ) {

                        $subresources = $items[ $resource_type ][ $resource_id ][ $subresource_type ];

                        $methods = get_option( $this->parent_option_prefix . \'subresource_methods\', array() );

                        if ( ! empty( $methods[ $resource_type ][ $resource_id ][ $subresource_type ] ) ) {

                            $methods = $methods[ $resource_type ][ $resource_id ][ $subresource_type ];

                            foreach ( $subresources as $subresource ) {

                                foreach ( $methods as $method ) {

                                    $test_all_items = $this->get_all_items( $resource_type, $resource_id, $subresource_type, $subresource, $method );

                                    if ( ! empty( $test_all_items ) ) {

                                        foreach ( $test_all_items as $test_item ) {

                                            $settings[ $section . \'_\' . $subresource_type . \'_\' . $subresource . \'_\' . $method . \'_\' . $test_item[\'id\'] . \'_title\' ] = array(
                                                \'title\'    => __( \'Title\' ),
                                                \'callback\' => \'display_input_field\',
                                                \'page\'     => $page,
                                                \'section\'  => $section,
                                                \'args\'     => array(
                                                    \'type\'     => \'text\',
                                                ),
                                            );

                                        } // End foreach().

                                    }

                                } // End foreach().

                            } // End foreach().

                        } // End if().

                    } // End if().

                } // End foreach().

            }  // End if().

        } // End foreach().

    } // End if().

    foreach ( $settings as $key => $attributes ) {

        $id       = $this->option_prefix . $key;
        $name     = $this->option_prefix . $key;
        $title    = $attributes[\'title\'];
        $callback = $attributes[\'callback\'];
        $page     = $attributes[\'page\'];
        $section  = $attributes[\'section\'];
        $args     = array_merge(
            $attributes[\'args\'],
            array(
                \'title\'     => $title,
                \'id\'        => $id,
                \'label_for\' => $id,
                \'name\'      => $name,
                \'class\'     => $class,
            )
        );

        add_settings_field( $id, $title, $callback, $page, $section, $args );
        register_setting( $section, $id );

    }  // End foreach().
}

/**
* Default display for <input> fields
*
* @param array $args
*/
public function display_input_field( $args ) {
    $type    = $args[\'type\'];
    $id      = $args[\'label_for\'];
    $name    = $args[\'name\'];
    $checked = \'\';

    $class = \'regular-text\';

    $value = esc_attr( get_option( $id, \'\' ) );
    if ( \'checkbox\' === $type ) {
        $value = filter_var( get_option( $id, false ), FILTER_VALIDATE_BOOLEAN );
        if ( true === $value ) {
            $checked = \'checked \';
        }
        $value = 1;
    }
    if ( \'\' === $value && isset( $args[\'default\'] ) && \'\' !== $args[\'default\'] ) {
        $value = $args[\'default\'];
    }

    echo sprintf( \'<input type="%1$s" value="%2$s" name="%3$s" id="%4$s" class="%5$s"%6$s>\',
        esc_attr( $type ),
        esc_attr( $value ),
        esc_attr( $name ),
        esc_attr( $id ),
        sanitize_html_class( $class, esc_html( \' code\' ) ),
        esc_html( $checked )
    );
}

/**
* Display for a dropdown
*
* @param array $args
*/
public function display_select( $args ) {
    $type = $args[\'type\'];
    $id   = $args[\'label_for\'];
    $name = $args[\'name\'];
    $desc = $args[\'desc\'];
    if ( ! isset( $args[\'constant\'] ) || ! defined( $args[\'constant\'] ) ) {
        $current_value = get_option( $name );

        echo sprintf( \'<div class="select"><select id="%1$s" name="%2$s"><option value="">- Select one -</option>\',
            esc_attr( $id ),
            esc_attr( $name )
        );

        foreach ( $args[\'items\'] as $key => $value ) {
            $text     = $value[\'text\'];
            $value    = $value[\'value\'];
            $selected = \'\';
            if ( $key === $current_value || $value === $current_value ) {
                $selected = \' selected\';
            }

            echo sprintf( \'<option value="%1$s"%2$s>%3$s</option>\',
                esc_attr( $value ),
                esc_attr( $selected ),
                esc_html( $text )
            );

        }
        echo \'</select>\';
        if ( \'\' !== $desc ) {
            echo sprintf( \'<p class="description">%1$s</p>\',
                esc_html( $desc )
            );
        }
        echo \'</div>\';
    } else {
        echo sprintf( \'<p><code>%1$s</code></p>\',
            esc_html__( \'Defined in wp-config.php\', \'minnpost-form-processor-mailchimp\' )
        );
    }
}
我可以运行错误日志,其中register_settingadd_settings_field 方法被调用,并且所有值都匹配它们应该匹配的值。在这种情况下,节显示为“newsletter\\u form”。HTML模板(之前通过add_options_page) 如下所示:

<div id="main">
    <form method="post" action="options.php">
        <?php
        settings_fields( \'newsletter_form\' ) . do_settings_sections( \'newsletter_form\' );
        ?>
        <?php submit_button( __( \'Save settings\', \'minnpost-form-processor-settings\' ) ); ?>
    </form>
</div>
我很难弄清楚嵌套选项为什么不保存。我进入wp-includes/option.php 尝试一些调试。

我跑了error_log( \'post is \' . print_r( $_POST, true ) ); 在里面,它确实有丢失的数据。然后我去了foreach ( $options as $option ) { 线路和ranerror_log( \'option is \' . $option ); 而且它没有丢失的数据。

所以有些东西阻止我丢失的字段添加到$options 大堆

下一步我该怎么做?

1 个回复
最合适的回答,由SO网友:Jonathan Stegall 整理而成

我想出来了。它实际上根本不在上面的代码中,而是在我用来生成$settings.

问题是,在其他方法中,我有以下代码:

if ( ! isset( $_GET[\'page\'] ) || $this->slug !== $_GET[\'page\'] ) {
    return $options;
}
我经常使用它来避免在用户在管理员内部执行其他操作时进行不必要的API调用。但在这种情况下,当数据发布到Core的options.php, 当然是因为options.php 没有$_GET[\'page\'] 此插件所需的值。

我仍然需要做一些调查,以确保我只在需要时调用这些东西,但至少对于这个问题来说,这就是问题所在,并因此得到解决。

相关推荐

WP-ADMIN ERR_CONNECTION_TIMED_OUT仅在某些网络上

好吧,两天以来我的WordPress博客出现了一个奇怪的问题。该网站在我的办公网络(Wi-Fi)上运行良好,我可以通过笔记本电脑或手机登录仪表板并发布内容。但是,当我回到家尝试登录时,wp admin页面会显示ERR\\u CONNECTION\\u TIMED\\u OUT error,或者有时会重定向到登录。php页面,并显示404未找到错误。我联系了我的主机,他们说服务器没有问题。奇怪的是,当我尝试在我的移动网络上登录网站时,这是一个不同的ISP,两天后我就面临着同样的问题。我清除了缓存,刷新了DN