无法获取插件设置页面以保存数据

时间:2012-12-13 作者:Morgan Kay

有一个简单的插件,可以在一篇文章的内容中间插入文本(谷歌广告)。我正在尝试创建一个设置页面,允许用户更改广告代码,并更改广告出现的段落。

我花了一整天的时间阅读教程和代码,我有一个可爱的设置页面,但我不知道如何让它真正保存数据。我主要遵循专业WordPress插件开发的示例。

以下是我所拥有的:

<?php
// add plugin options
add_option( \'wpa_ad_insert_paragraph\', \'2\' );
add_option( \'wpa_ad_insert_adcode\', \'ad code goes here\');

// update options
update_option( \'wpa_ad_insert_paragraph\', $_POST[\'wpa_ad_insert_paragraph\'] );
update_option( \'wpa_ad_insert_adcode\', $_POST[\'wpa_ad_insert_adcode\'] );

// Add a menu for our option page
add_action(\'admin_menu\', \'wpa_ad_insert_add_page\');
function wpa_ad_insert_add_page() {
    add_options_page( \'Ad Insertion\', \'Ad Insertion\', \'manage_options\', \'wpa_ad_insert\', \'wpa_ad_insert_option_page\' );
}

// Draw the option page
function wpa_ad_insert_option_page() {
    ?>
    <div class="wrap">
        <?php screen_icon(); ?>
        <h2>Ad Insertion</h2>
        <form action="options.php" method="post">
            <?php settings_fields(\'wpa_ad_insert_options\'); ?>
            <?php do_settings_sections(\'wpa_ad_insert\'); ?>
            <input name="Submit" type="submit" value="Save Changes" />
        </form>
    </div>
    <?php
}

// Register and define the settings
add_action(\'admin_init\', \'wpa_ad_insert_admin_init\');
function wpa_ad_insert_admin_init(){
    register_setting(
        \'wpa_ad_insert_options\',
        \'wpa_ad_insert_options\',
        \'wpa_ad_insert_validate_options\'
    );
    add_settings_section(
        \'wpa_ad_insert_main\',
        \'Ad Insertion Settings\',
        \'wpa_ad_insert_section_text\',
        \'wpa_ad_insert\'
    );
    add_settings_field(
        \'wpa_ad_insert_paragraph\',
        \'Ad will appear after paragraph number:\',
        \'wpa_ad_insert_paragraph_setting\',
        \'wpa_ad_insert\',
        \'wpa_ad_insert_main\'
    );
    add_settings_field(
        \'wpa_ad_insert_adcode\',
        \'Ad code:\',
        \'wpa_ad_insert_adcode_setting\',
        \'wpa_ad_insert\',
        \'wpa_ad_insert_main\'
    );
}

function wpa_ad_insert_paragraph_setting() {
    $options = get_option(\'wpa_ad_insert_paragraph\');
    $items = array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20");
    echo "<select id=\'wpa_ad_insert_paragraph\' name=\'plugin_options[wpa_ad_insert_paragraph]\'>";
    foreach($items as $item) {
        $selected = ($options[\'wpa_ad_insert_paragraph\']==$item) ? \'selected="selected"\' : \'\';
        echo "<option value=\'$item\' $selected>$item</option>";
    }
    echo "</select>";
}

function wpa_ad_insert_adcode_setting() {
    $options = get_option(\'wpa_ad_insert_adcode\');
    echo "<textarea id=\'wpa_ad_insert_adcode\' name=\'plugin_options[wpa_ad_insert_adcode]\' rows=\'7\' cols=\'50\' type=\'textarea\'>{$options[\'wpa_ad_insert_adcode\']}</textarea>";
}


function wpa_insert_ad($content) {
    $paragraphAfter = get_option(\'wpa_ad_insert_paragraph\');
    $ad = get_option(\'wpa_ad_insert_adcode\');
    if( is_single() && is_main_query() ) {
        $content = explode("</p>", $content);
        for ($i = 0; $i <count($content); $i++ ) {
            if ($i == $paragraphAfter)   
            echo $content[$i] . "</p>";
        }
    }   
    return $content;
}
add_filter(\'the_content\', \'wpa_insert_ad\');
?>
这段代码创建了一个设置页面,但当我保存设置页面时,什么都没有发生(我得到的黄色条表示我的设置已保存,但信息肯定不会保存在数据库中)。

我错过了什么?

4 个回复
SO网友:Saikat

当您使用Settins API时,这就是为什么您不需要使用update_optionadd_option 功能。设置API将自行处理该问题。

这就是为什么您的代码不起作用的原因。

1.

add_settings_section(
    \'wpa_ad_insert_main\',
    \'Ad Insertion Settings\',
    \'wpa_ad_insert_section_text\',
    \'wpa_ad_insert\'
);
第三个参数是回调函数。因为,你不需要这个函数,所以只需添加__return false 作为回调。然后,此函数的代码如下所示:

add_settings_section(
    \'wpa_ad_insert_main\',
    \'Ad Insertion Settings\',
    \'__return_false\',
    \'wpa_ad_insert\'
);

2.

register_setting(
    \'wpa_ad_insert_options\',
    \'wpa_ad_insert_options\',
    \'wpa_ad_insert_validate_options\'
);
请看上面的代码。由于第二个参数是选项名,所以当您要从数据库检索选项时,必须使用此选项名。您没有调用该选项名称,而是调用了下面列出的两个选项名称:

$options = get_option(\'wpa_ad_insert_paragraph\');
$options = get_option(\'wpa_ad_insert_adcode\');
因为您在register_setting 函数,这就是您未能将选项检索到数据库中的原因。你应该打电话get_option 使用您注册的选项名称的函数register_setting 作用这就像:

$options = get_option(\'wpa_ad_insert_options\');
3.但数据仍然没有保存到数据库中,对吗?因为你曾经plugin_options 作为表单输入和文本区域的名称。因为您使用的是wordpress设置API,所以您应该使用与注册时相同的名称option_nameregister_setting 作用

因此,您需要修复一些事情才能使此代码可用。我修改了几行代码,这很有效。替换您的register_setting 此功能:

register_setting(
    \'wpa_ad_insert_options\',
    \'plugin_options\',
    \'wpa_ad_insert_validate_options\'
);
替换您的add_settings_section 此功能:

add_settings_section(
    \'wpa_ad_insert_main\',
    \'Ad Insertion Settings\',
    \'__return_false\',
    \'wpa_ad_insert\'
);
全部替换get_option 函数:$options=wpa\\u options(\'plugin\\u options\');

最后添加以下新代码:

function wpa_options() {
    $default = array(
        \'wpa_ad_insert_paragraph\' => 1,
        \'wpa_ad_insert_adcode\' => \'\'
        );
    return get_option(\'plugin_options\', $default);
}
Put it all together:

// Add a menu for our option page
add_action(\'admin_menu\', \'wpa_ad_insert_add_page\');
function wpa_ad_insert_add_page() {
    add_options_page( \'Ad Insertion\', \'Ad Insertion\', \'manage_options\', \'wpa_ad_insert\', \'wpa_ad_insert_option_page\' );
}

// Draw the option page
function wpa_ad_insert_option_page() {
    ?>
    <div class="wrap">
        <?php screen_icon(); ?>
        <h2>Ad Insertion</h2>
        <form action="options.php" method="post">
            <?php settings_fields(\'wpa_ad_insert_options\'); ?>
            <?php do_settings_sections(\'wpa_ad_insert\'); ?>
            <input name="Submit" type="submit" value="Save Changes" />
        </form>
    </div>
    <?php
}

// Register and define the settings
add_action(\'admin_init\', \'wpa_ad_insert_admin_init\');
function wpa_ad_insert_admin_init(){
    register_setting(
        \'wpa_ad_insert_options\',
        \'plugin_options\',
        \'wpa_ad_insert_validate_options\'
    );
    add_settings_section(
        \'wpa_ad_insert_main\',
        \'Ad Insertion Settings\',
        // \'wpa_ad_insert_section_text\',
        \'__return_false\',
        \'wpa_ad_insert\'
    );
    add_settings_field(
        \'wpa_ad_insert_paragraph\',
        \'Ad will appear after paragraph number:\',
        \'wpa_ad_insert_paragraph_setting\',
        \'wpa_ad_insert\',
        \'wpa_ad_insert_main\'
    );
    add_settings_field(
        \'wpa_ad_insert_adcode\',
        \'Ad code:\',
        \'wpa_ad_insert_adcode_setting\',
        \'wpa_ad_insert\',
        \'wpa_ad_insert_main\'
    );
}

register_setting(
    \'wpa_ad_insert_options\',
    \'plugin_options\',
    \'wpa_ad_insert_validate_options\'
);

function wpa_ad_insert_paragraph_setting() {
    $options = wpa_options(\'plugin_options\');
    $items = array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20");
    echo "<select id=\'wpa_ad_insert_paragraph\' name=\'plugin_options[wpa_ad_insert_paragraph]\'>";
    foreach($items as $item) {
        $selected = ($options[\'wpa_ad_insert_paragraph\']==$item) ? \'selected="selected"\' : \'\';
        echo "<option value=\'$item\' $selected>$item</option>";
    }
    echo "</select>";
}

function wpa_ad_insert_adcode_setting() {
    $options = wpa_options(\'plugin_options\');
    echo "<textarea id=\'wpa_ad_insert_adcode\' name=\'plugin_options[wpa_ad_insert_adcode]\' rows=\'7\' cols=\'50\' type=\'textarea\'>{$options[\'wpa_ad_insert_adcode\']}</textarea>";
}


function wpa_insert_ad($content) {
    $paragraphAfter = get_option(\'wpa_ad_insert_paragraph\');
    $ad = get_option(\'wpa_ad_insert_adcode\');
    if( is_single() && is_main_query() ) {
        $content = explode("</p>", $content);
        for ($i = 0; $i <count($content); $i++ ) {
            if ($i == $paragraphAfter)   
            echo $content[$i] . "</p>";
        }
    }   
    return $content;
}
add_filter(\'the_content\', \'wpa_insert_ad\');

function wpa_options() {
    $default = array(
        \'wpa_ad_insert_paragraph\' => 1,
        \'wpa_ad_insert_adcode\' => \'\'
        );
    return get_option(\'plugin_options\', $default);
}

SO网友:Morgan Kay

我开始使用插件选项初学者工具包插件-http://www.presscoders.com/plugins/plugin-options-starter-kit/. 这是一个很好的插件。它实际上根本不是一个插件,它只是一个插件设置页面,包含了您可能想要使用的所有选项,因此很容易复制/粘贴/剪切/配置它来完成您想要的操作。我仍然不知道为什么我上面的代码不起作用(除了上面粘贴的版本没有验证功能,但添加它并不能解决问题),所以如果有人想告诉我我还需要做些什么才能让它起作用,我很想知道。

SO网友:Mark Kaplun

问题是您在代码中编码更新的位置。

提交表单后,将显示选项。php正在加载,你的插件也在加载中。此时,将根据post数据更新选项。然后,您被重定向回设置页面,代码再次执行,但这一次中没有值$_POST 因此,您的选项中填充了一些空值。

如果您使用设置API,则应该将选项的更新留给它,即使不是,您的更新代码也应该

if (isset($_POST[\'wpa_ad_insert_paragraph\'] )) {
  pdate_option( \'wpa_ad_insert_paragraph\', $_POST[\'wpa_ad_insert_paragraph\'] );
  update_option( \'wpa_ad_insert_adcode\', $_POST[\'wpa_ad_insert_adcode\'] );
}
现在,add\\u选项几乎是update\\u选项的别名,如果该选项存在,它的行为将类似于update\\u选项,如果在该选项不存在时调用update\\u选项,则将添加该选项。因此,您需要在初始化之前检查该选项是否不存在。

if (!get_option(\'wpa_ad_insert_paragraph\')) {
  add_option( \'wpa_ad_insert_paragraph\', \'2\' );
  add_option( \'wpa_ad_insert_adcode\', \'ad code goes here\');
}
当该选项不存在时,get\\u option返回false(但如果false是选项可以具有的值之一,则需要小心)

SO网友:Nick Young

你似乎有一些问题。第一个问题是您应该将输出与逻辑分开。基本上admin_init 您正在调用的操作可能没有正确执行,因为它在时间线中太晚了。请参见此处的类似问题和答案:Can't output do_settings_sections . Can't understand why

第二个问题是register_setting() 函数实际上并不在数据库中创建设置选项。您需要这样做:

    // Register and define the settings
    add_action(\'admin_init\', \'wpa_ad_insert_admin_init\');
function wpa_ad_insert_admin_init(){

    // This will make sure your options are created in the database
    if( false === get_option( \'wpa_ad_insert_options\' ) ) {
        add_option( \'wpa_ad_insert_options\' );
    }

    register_setting(
        \'wpa_ad_insert_options\',
        \'wpa_ad_insert_options\',
        \'wpa_ad_insert_validate_options\'
    );

    ...
该函数开头的检查将确保您正在创建将设置保存到的选项。这里有一个类似的问题:Why won't register_setting() create a setting?

正如@MarkKaplen在回答中所说的,您还应该删除update_option 塞满东西,让WordPress帮你处理。

当您使用register_setting() 第二个参数是要保存到的数据库中的选项,这就是为什么在注册设置之前需要确保该选项存在的原因。

乍一看,我上面提到的问题似乎是最大的问题,但在你解决这些问题之后,可能还有其他问题,我们可以从那里着手。

结束