web-dev-qa-db-ja.com

Settings API以外のオプションも更新したい場合は、Settings APIのregister_settingsをどこでフックすればよいですか。

設定API は管理オプションを追加する便利な方法です。設定APIのチュートリアルでは、register_settingをadmin_initにフックします。しかし、Settings API以外で同じオプションをプログラム的に変更したい場合はどうしますか?

たとえば、設定APIを使用してオプションXの基本値を管理します。さらに、新しい投稿ごとに直接update_option関数呼び出しによってオプションXが自動的に増加します。残念ながら、オプションXが登録されている場合、update_optionはその登録された設定に関連した検証関数の呼び出しを引き起こします。検証は失敗します update_option引数が渡されないため オプション変更のさまざまなソースから必要とされるさまざまな検証を台無しにしているからです。

設定X以外でオプションXも更新できるようにするには、オプションXのregister_settingをどこにフックすればよいですか。あるいは、Settings APIのサニタイズ/検証関数を呼び出さずに直接update_option呼び出しを機能させるには、オプションXのunregister_settingをどこにフックすればよいですか。

更新日: t31os 以下に便利なコード例を示しました。これが彼のコードのちょっとした追加です。

    function __construct() {
        add_action( 'admin_init', array( $this, 'admin_init' ) );
        add_action( 'admin_menu', array( $this, 'admin_menu' ) );
        add_action('add_meta_boxes', array( &$this, 'add_regtest_box' )); //added hook
        }   

//added functions
    function add_regtest_box() {
            global $post;
            add_meta_box( 'regtest_box', 'Registered Setting Test', array( &$this, 'regtest_box_contents'), 'post' , 'side' , 'high' );
        }   
    function regtest_box_contents() {
            update_option( 'test-option', array('fieldone'=>-11,'fieldtwo'=>8) );
            $new_vals = get_option( 'test-option' );
            print_r( $new_vals );
        }

ダッシュボードから「新しい投稿を追加」すると、右上のメタボックスにはfieldoneが-11ではなく11の値で表示されていることがわかります。これは、regtest_box_contentsのupdate_option関数呼び出しが、登録されたサニタイズ/検証関数(register_setting)を介してオプション値をオプションに渡すためです。この場合は、t31osのupdate_option関数で、渡されたオプション値にabsint()を適用します。問題は、その関数呼び出しをどのように回避するかです。オプションを-11に更新してください。

3
BigToe

今私はそれについて考えてきました(Markは私です、私は他の場所にいるとき私は別のアカウントを使います)設定の登録はすべて有効なnonceがあるときあなたの入ってくるフォームデータを受け入れるためのprepare options.phpですまた、サニタイズ方法をそのデータの送信に結び付ける手段も提供します。これはプラグインにとって本当に便利なことです。

サイトのフロントエンドからupdate_optionを呼び出してそれを実行するだけで十分です。管理ページの場合のようにoptions.phpにフォームデータを送信していないため、フロントエンドで登録する必要はありません。

私はあなたの問題を再現しようとしました、しかし、私はすることができませんでした、オプションを保存することができる簡単な登録ページを作成するための私の醜いテストコードはここにあります。

class RegisteredSettingsTest {
    private $page;
    private $name = 'test-option';
    private $options;
    function __construct() {
        add_action( 'admin_init', array( $this, 'admin_init' ) );
        add_action( 'admin_menu', array( $this, 'admin_menu' ) );
    }
    function admin_init() {
        register_setting( 'setting_ref', $this->name, array( $this, 'update_option' ) );
        $this->options = get_option( $this->name );
    }
    function admin_menu() {
        $this->page = add_dashboard_page( 'Test','Test','manage_options','translatable_demo', array( &$this , 'load' ) );
    }
    function update_option( $data ) {
        $clean = array_map( 'absint', $data );
        unset($data);
        return $clean;
    }
    function load() {
        ?>
        <div class="wrap">
            <?php screen_icon('index'); ?>
            <h2>Test</h2>
            <form action="options.php" method="post">
                <?php settings_fields( 'setting_ref' ); ?>
                <p><label for="<?php $this->field_name( 'fieldone') ?>">Field one <input value="<?php $this->get_option( 'fieldone') ?>" name="<?php $this->field_name( 'fieldone') ?>" type="text" /></label></p>
                <p><label for="<?php $this->field_name( 'fieldtwo') ?>">Field two <input value="<?php $this->get_option( 'fieldtwo') ?>" name="<?php $this->field_name( 'fieldtwo') ?>" type="text" /></label></p>
                <p class="submit"><input type="submit" name="Submit" class="button-secondary action" value="Save" /></p>
            </form>
            <!-- Output options data, so we can see how it currently looks -->
            <pre><?php print_r( $this->options ) ?></pre>
        </div>
        <?php
    }
    function field_name( $name, $echo = true ) {
        $name = "{$this->name}[$name]";
        if( $echo )
            echo $name;
        else
            return $name;
    }
    function get_option( $name, $echo = true ) {
        $val = '';
        if( is_array( $this->options ) && isset( $this->options[$name] ) )
            $val = $this->options[$name];

        if( $echo )
            echo $val;
        else
            return $val;
    }
}
$r = new RegisteredSettingsTest;

私はページをロードし、フィールドに値12を入力してSaveを押しました(もちろんうまくいき、値は12になります)。数値を使用しています。これは単純なテストです。

私が思い付くことができた最も簡単なフロントエンドテストは私のsingle.phpの中でupdate_optionを呼び出すことでした(私は他のどんなテンプレートファイルを使用することもできますが)。

update_option( 'test-option', array('fieldone'=>3,'fieldtwo'=>4) );

問題があったとしても、私が自分のテスト管理ページをロードしたときに私はまだ値12を見るべきです。残念ながらそうではありません、新しい値34が表示されます。

フロントエンドからオプションを更新するために使用しているコードを投稿できますか。それがコールバックの中にある場合は、関数全体を投稿し、それにフックされているアクション/フィルタを投稿してください、.. :)

UPDATE:

オプションを更新する前に、サニタイズコールバックを削除してください。

remove_all_filters( 'sanitize_option_test-option', 10 );

そして、あなたの値はもはやコールバック関数によって束縛されることはありません、それはフックされないでしょう.. :)

0
t31os

Initの代わりにアクションを起動しないでください。

オプションを更新するための要件は同じです(管理者だけがmanage_optionsできます)、それでそれは理論的に動作するはずです、あなたはそれを試しましたか、彼らの問題でしたか?

今のところ私のメインのPCにはありませんが、そうでなければ自分で試してみることにします。

ここではどういう意味ですか。

Update_option引数が渡されていないため、検証は失敗します。

私はコメントを求めましたが、私はまだこのアカウントの担当者の要件を満たしていません。

1
Mark Duncan

傍注には...関連する投稿を数えてから、合計を取得するためにあなたのオプションから基本値を追加する方が良いでしょうか?フロントエンドから利用可能な設定インターフェースを構築したいのでなければ、これはあなたが別の方法でそれを行うべきであることを示しているように聞こえます。自分の「設定」を自分で変更すると、ユーザーを混乱させるかもしれません。

0
wyrfel