web-dev-qa-db-ja.com

カスタムフィールド入力を検証するための正しいアプローチ

いくつかのカスタムフィールドを持つカスタム投稿タイプがあります。これらのフィールドは他のサービスによってダウンストリームで使用されるため、これらのフィールドで検証を行うことを検討しています。そのため、正しく入力されるまで保存できないことが重要です。検証はかなり複雑で、カスタムロジックが必要です。

残念ながら、この特定のケースではプラグインを使用することもできません。

この場合に使用するのに理想的なフックはありますか?高レベルで - これに取り組むための最善の方法をいただきました。

3
Ethan Seifert

add_meta_box() ドキュメントのコード例では、( wp_insert_post() 関数の最後に)save_postフックを使用して、メタボックスからカスタムフィールドデータを追加しています。

あなたはすでにあなたのメタボックスでそのようなものを使っていなければなりません、それはあなたのデータを検証するのに適切な場所ではありませんか?..

4
Rarst

(私の回答から投稿された同様の質問への回答 はこちら

このメソッドには2つのステップがあります。1つはカスタムメタボックスフィールドデータを保存する関数(save_postにフック)、2つ目はその新しいpost_meta(先ほど保存したもの)を読み込み、それを検証して結果を変更する関数です必要に応じて保存します(save_postにフックしましたが、最初のものの後に)。検証が失敗した場合、バリデーター関数は実際にpost_statusを "pending"に戻し、事実上投稿が公開されるのを防ぎます。

Save_post関数は頻繁に呼び出されるので、各関数はユーザーが公開することを意味する場合にのみ実行するチェックを持ち、カスタム投稿タイプ(mycustomtype)に対してのみ実行されます。

私は通常、自分の投稿が公開されなかった理由をユーザーに知らせるためのカスタム通知メッセージも追加しますが、ここに含めるのは少し複雑になります...

add_action('save_post', 'save_my_fields', 10, 2);
add_action('save_post', 'completion_validator', 20, 2);

function save_my_fields($pid, $post) {
    // don't do on autosave or when new posts are first created
    if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $post->post_status == 'auto-draft' ) return $pid;
    // abort if not my custom type
    if ( $post->post_type != 'mycustomtype' ) return $pid;

    // save post_meta with contents of custom field
    update_post_meta($pid, 'mymetafield', $_POST['mymetafield']);
}


function completion_validator($pid, $post) {
    // don't do on autosave or when new posts are first created
    if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $post->post_status == 'auto-draft' ) return $pid;
    // abort if not my custom type
    if ( $post->post_type != 'mycustomtype' ) return $pid;

    // init completion marker (add more as needed)
    $meta_missing = false;

    // retrieve meta to be validated
    $mymeta = get_post_meta( $pid, 'mymetafield', true );
    // just checking it's not empty - you could do other tests...
    if ( empty( $mymeta ) ) {
        $meta_missing = true;
    }

    // on attempting to publish - check for completion and intervene if necessary
    if ( ( isset( $_POST['publish'] ) || isset( $_POST['save'] ) ) && $_POST['post_status'] == 'publish' ) {
        //  don't allow publishing while any of these are incomplete
        if ( $meta_missing ) {
            global $wpdb;
            $wpdb->update( $wpdb->posts, array( 'post_status' => 'pending' ), array( 'ID' => $pid ) );
            // filter the query URL to change the published message
            add_filter( 'redirect_post_location', create_function( '$location','return add_query_arg("message", "4", $location);' ) );
        }
    }
}

複数のメタボックスフィールドの場合は、補完マーカーを追加してpost_metaを取得し、テストを増やすだけです。

1
somatic