Je ne suis pas tout à fait sûr que ce soit la faute de Wordpress, mais je pense que je demanderais quand même et que quelqu'un d'autre a déjà rencontré des problèmes de ce type.
J'essaie de sauvegarder un tableau sur une ligne de la table wp_options. Les données proviennent d'une métabox personnalisée et sont en cours de sauvegarde lorsque le hook save_post est déclenché. J'ai supposé que cela devrait faire l'affaire:
update_option("myOptionName", $myArray);
J'ai commencé à obtenir 4 (?!) De chaque valeur sauvegardée. Par exemple:
$myArray = array("option1");
update_option("myOptionName", $myArray);
get_option("myOptionName");
// array([0]=>"option1", [1]=>"option1", [2]=>"option1", [3]=>"option1");
Inutile de dire que ce comportement est extrêmement agaçant. Cela fonctionne parfaitement avec les chaînes, mais jamais les tableaux. J'ai essayé de contourner cela en essayant json_encode de le stocker en tant qu'entité string-y, mais même cela ne fonctionne pas. Le problème pourrait très bien être le code hérité dont j'ai hérité en prenant ce projet, mais je ne vois rien qui pointe vers save_post.
Est-ce que quelqu'un a déjà vu une telle situation auparavant?
EDIT: Comme demandé ... la fonction de sauvegarde:
# 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 );
}
J'ai eu quelque chose de similaire lorsque j'ai essayé d'utiliser la fonction wp_editor()
dans une métabox personnalisée. Il voulait sauver plusieurs fois.
Regarde ça.
// 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');
}
}
}
Regardez la ligne 43. Voyez comment j'ai dû remove_action
la fonction d'origine ... lancer la mise à jour ... puis add_action
à nouveau?
C'est peut-être ce que vous devez faire aussi.
Voici un "exemple" de code rapide:
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');
}
Au fur et à mesure que vous recréez le tableau entier à chaque lecture, je voudrais simplement effacer l'option avant de la recréer:
$newView[] = $_REQUEST['postID'];
delete_option( 'ci_guidesbrick_posts' );
update_option('ci_guidesbrick_posts', $newView );
save_post est appelé plusieurs fois lors de la modification d'une publication (sauvegarde automatique). C'est un piège commun, mais ce serait bien si vous pouviez poster le code de votre fonction pour savoir ce qui se passait.
Comme MZAweb l'a dit, c'est (probablement) la sauvegarde automatique.
Vous devriez éditer votre code de sorte que, lorsque les crochets se déclenchent, il vérifie la sauvegarde automatique:
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
}