web-dev-qa-db-ja.com

Save_postの配列でwp_optionsを更新すると、エントリが重複する

これがWordpressのせいであるかどうかは完全にはわかりませんが、とにかく聞いてみて、他の誰かが以前にこのような問題を経験したことがあるかどうかを確認します。

配列をwp_optionsテーブルの行に保存しようとしています。データはカスタムメタボックスから取得され、save_postフックがトリガーされたときに保存されます。私はこれがトリックをするべきだと思いました:

update_option("myOptionName", $myArray);

私は保存した各値の4(?!)を取得し始めました。例えば:

$myArray = array("option1");
update_option("myOptionName", $myArray);
get_option("myOptionName"); 
// array([0]=>"option1", [1]=>"option1", [2]=>"option1", [3]=>"option1");

言うまでもなく、この動作は非常に面倒です。文字列では完全にうまく機能しますが、配列では絶対にうまくいきません。これを回避するためにjson_encodeを使って文字列yエンティティとして保存してみましたが、それでもうまくいきません。問題は、私がこのプロジェクトを引き継いで受け継いだ従来のコードかもしれませんが、save_postを指し示すものは何もありません。

誰かが前にこのような状況を見たことがありますか?

編集:要求どおり...保存機能:

# SAVE BRICK DATA
function brick_update() {

// Verify if this is an auto save routine.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
    return;
}

// Check permissions
if ( !current_user_can( 'publish_posts' ) ) { // Check for capabilities
    wp_die( 'Sorry, you do not have the capabilities access to this page. :(' );
}

if (!wp_verify_nonce($_REQUEST['brickupdate'], 'brickupdate')) {
    return;
}

$newView = array();
$currentView = get_option('ci_guidesbrick_posts');

if (!is_array($currentView)) {
    $currentView = (array)$currentView;
}

for (var i = 0, i < count($currentView), i++) {
    $newView[i] = $currentView[i];
}

$newView[] = $_REQUEST['postID'];

update_option('ci_guidesbrick_posts', $newView );   

}
3
akamaozu

カスタムメタボックス内でwp_editor()関数を使用しようとしたときにも、同様のことが起こっていました。何度も保存したいと思いました。

これをみて。

// SAVE Metabox for admin response
add_action('post_updated', 'display_jwl_wp_etickets_response_meta_box_save');
function display_jwl_wp_etickets_response_meta_box_save( $post_id ){


        if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
                return;
        if( !isset( $_POST['jwl_wp_etickets_editor_box_nonce_check'] ) || !wp_verify_nonce( $_POST['jwl_wp_etickets_editor_box_nonce_check'], 'jwl_wp_etickets_editor_box_nonce' ) )
                return;

        global $post;
        $post_type_object = get_post_type_object( $post->post_type );
        if ( !current_user_can( $post_type_object->cap->edit_post, $post->ID ) ) {
                return;
        }

        //$values = get_post_custom( $post_id );

        $editor_id = 'jwl_wp_etickets_response_editor';
        $meta_key = 'jwl_wp_etickets_response_box_select';

        $content_post = get_post($post_id);
        $old_content = $content_post->post_content;

        if(isset($_POST[$editor_id]) && !empty($_POST[$editor_id])) {
                if ( !wp_is_post_revision( $post_id ) ){ //IMPORTANT - Can cause infinite loop otherwise : codex - wp_update_post  (see note a few lines down)

                        $new_content = '<div class="eMember_admin_div"><p class="eMember_adminname_response"><strong>Admin</strong> on <strong>'.date('F j, Y @ g:i a').'</strong> said:</p>'.$_POST[$editor_id].'</div>';

                        $update_content = array(
                                'ID'           => $post_id,
                                'post_content' => $new_content.$old_content
                        );
                        // IMPORTANT!!!!
                        //*****
                        //*****  Apparently the 'post_updated' action likes to fire on every WP process while saving the content.
                        //*****  Since we are also firing on 'wp_update_post'; we are getting stuck in a loop.
                        //*****  To get around, unhook the function before sending the revised content with 'wp_update_post'.
                        //*****  This will prevent clashes between 'post_updated' and 'wp_update_post" firing at the same time.
                        //*****  DAMN YOU WORDPRESS!!
                        //*****
                        // Unhook this function so it doesn't loop infinitely
                        remove_action('post_updated', 'display_jwl_wp_etickets_response_meta_box_save');

                                // Update the post, which calls save_post again
                                wp_update_post( $update_content );
                                // Let's check the 'ticket state', and if queued... let's update it to 'in progress'
                                $terms_types = wp_get_post_terms( $post->ID, 'jwl_wp_etickets_states');
                                foreach ($terms_types as $term_type) {
                                        if ($term_type == 'Queued' || !empty($term_type)) {
                                                wp_set_post_terms( $post_id, __('In Progress','wp_etickets_lang'), 'jwl_wp_etickets_states' );
                                        }
                                }
                                // Do the same for post meta for cool admin filtering
                                update_post_meta( $post_id, 'jwl_wp_etickets_states_box_select', __('In Progress','wp_etickets_lang'), __('Queued','wp_etickets_lang') );

                        // Re-hook this function
                        add_action('post_updated', 'display_jwl_wp_etickets_response_meta_box_save');
                }
        }  

}

43行目を見てください。元の関数をremove_action、更新を実行してからadd_actionをもう一度元に戻す方法を見てください。

それはあなたがしなければならないことかもしれません。

これは簡単な「例」のコードです。

add_action('post_updated', 'my_metabox_save');
function my_metabox_save() {
    // Run checks

    // Unhook this function so it doesn't loop infinitely
    remove_action('post_updated', 'my_metabox_save');

    // Run your update stuff

    // Re-hook this function
    add_action('post_updated', 'my_metabox_save');
}
1
josh

あなたがそれを読むことから毎回全体の配列を作り直すので、私はそれを再び作成する前にただオプションを消すでしょう:

$newView[] = $_REQUEST['postID'];
delete_option( 'ci_guidesbrick_posts' );
update_option('ci_guidesbrick_posts', $newView ); 
0
Simon

投稿を編集するときにsave_postが複数回呼び出されます(自動保存)。これは一般的な問題ですが、関数のコードを投稿して何が起こっているのかを確認できれば、それは素晴らしいことです。

0
MZAweb

MZAwebが言ったように、それは(おそらく)自動保存だ。
フックが起動したときに自動保存をチェックするようにコードを編集する必要があります。

add_action('save_post', 'my_save_post', 10, 2);
function my_save_post($post_id, $post) {
    // stop on autosave
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ){
        return;
    }
    // do your magic
}
0
janw