Intereting Posts

Как исправить: метаданные родителя переопределяют метаданные детей

У меня есть несколько обменных ящиков, которые я генерирую из пользовательских плагинов, которые хранят собственные метаданные в базе данных. Один из них относится к отношениям между родителем и ребенком и menu_order сообщений для детей.

проблема

Каждый раз, когда я обновляю родительский пост, все его дети берут пользовательские метаданные этого родителя.

Код

<? function pcr_add_custom_metabox (){ // it is VERY IMPORTANT in order to reset the $post after a custom query in the admin page // because $wp_query->post is never defined in the admin load which wp_reset_postdata() // relies on to reset the original post data. // https://core.trac.wordpress.org/ticket/18408 global $post, $wp_query; $wp_query->post = $post; /////// add_meta_box( "pcr_meta" , "Hierarchie" , "pcr_meta_callback" , array( "lecture" , "post") ); } add_action( 'add_meta_boxes_lecture' , 'pcr_add_custom_metabox'); add_action( 'add_meta_boxes_post' , 'pcr_add_custom_metabox'); /** * Generates the HTML code that goes into the metabox * * @param object(WP_Post) $post */ function pcr_meta_callback ( $post ){ global $typenow; $current_post_id = $post->ID; wp_nonce_field( basename(__FILE__) , 'pcr_nonce' ); //For validation that the content came from the current site and not somewhere else $stored_meta = get_post_meta( $post->ID ); //Get all the metadata of the post ?> <div class="pcr-inner-div-container"> <div class="pcr-top"> <div class="pcr-parent-checkbox-container"> <select id="pcr-meta-select" name="pcr-meta"> <option value="iAmParent" <?php if( isset( $stored_meta['pcr-meta-isParent'] ) && $stored_meta['pcr-meta-isParent'] == "iAmParent" ){ echo 'selected="selected"'; }?> ><?php if ($typenow == 'post') { echo "Leitartikel"; } elseif ($typenow == 'lecture'){ echo "Vorlesungsreihe"; }?></option> <option value="" disabled="disabled" <?php if( ( isset( $stored_meta['pcr-meta-isParent'] ) && $stored_meta['pcr-meta-isParent'] == "" ) || !isset( $stored_meta['pcr-meta-isParent'] ) ){ echo 'selected="selected"'; } ?>>------</option> <?php $args = array( 'post_type' => $typenow, 'posts_per_page' => -1, //get all the post 'order' => 'ASC', 'orderby' => 'title', 'meta_query' => array( array( 'key' => 'pcr-meta-isParent', 'value' => 'iAmParent', 'compare' => 'LIKE' ) ) ); $the_query = new WP_Query( $args ); if( $the_query->have_posts() ){ while( $the_query->have_posts() ) : $the_query->the_post(); if ( get_the_ID() == $current_post_id ){ continue; //Skip the article that you are editing } ?> <option value="<?php the_ID(); ?>" <?php //check if there is already a saved value in the database and use it if ( wp_get_post_parent_id( $current_post_id ) == get_the_ID() ) { echo 'selected="selected"'; } ?> ><?php the_title(); ?></option> <?php endwhile; } wp_reset_postdata(); ?> </select> <?php $args = array( 'post_parent' => $current_post_id, 'post_type' => array('post', 'lecture'), 'posts_per_page' => -1, //get all the post 'orderby' => 'menu_order', 'order' => 'ASC' ); $children = get_children( $args, ARRAY_A ); if( $children ){ $menu_order_indexes = []; ?> <div class="pcr-children-list"> <ol id="pcr-sortable"> <?php foreach ( $children as $child ){ $menu_order_indexes[] = $child['menu_order']; ?> <li> <label class="pcr-child-label" for="pcr-meta-children-list[]"> <input type="hidden" name="pcr-meta-children-list[]" value="<?php echo $child['ID']; ?>"> <?php echo $child['post_title']; ?> </label> </li> <?php }?> </ol> </div> <?php if( !areConsecutive( $menu_order_indexes ) ){ ?> <div class="pcr-warning">Prüfe die Reihenfolge der Einträge, wenn sie richtig ist, klicke <strong>update</strong>. Andernfalls ändere die Reihenfolge direkt in der Liste.</div> <?php } } ?> </div> </div> <div class="pcr-bottom"> <p class="pcr-message">Wähle, ob <?php if ($typenow == 'post') { echo "der Artikel ein Leitartikel ist oder nicht. Falls nicht, wähle den entsprechenden Leitartikel."; } elseif ($typenow == 'lecture'){ echo "die Vorlesung eine Vorlesungsreihe ist oder nicht. Falls nicht, wähle die entsprechende Vorlesungsreihe."; }?></p> <p class="pcr-credits howto"><span class="madeby">Made by <a href="http://www.achilleasxydis.com" target="_blank">Achilleas Xydis</a> for Professur für Architektur und Bauprozess</span><span class="ver">ver 0.7.0</span></p> </div> </div> <?php } /** * Checks if the array elements are consecutive. * * If elements are consecutive, the function returns true, else returns false. * Based on code from Mayank Jaiswal * * @param array $array_to_check * @return bool */ function areConsecutive ($array_to_check ){ $atc_length = count($array_to_check); // if the array is empty if($atc_length < 1){ return false; } // get the min and max values in the array $atc_min = min( $array_to_check ); $atc_max = max( $array_to_check ); // check if they are sequential if ( $atc_max - $atc_min + 1 != $atc_length ) { // It means that they are sequential but NOT consecutive return false; } // if they are sequential, check also if they are consecutive else{ // Create a temp array to hold visited flags of all elements and fill it with 'false'. $checked = array_fill( 0, $atc_length, false ); for ($i = 0; $i < $atc_length; $i++){ // if the element gets checked twice, it means that there is a duplicate value if( $checked[ $array_to_check[$i] - $atc_min ] != false ){ return false; } // if checked for the first time, mark it as checked $checked[ $array_to_check[$i] - $atc_min ] = true; } // if all elements occur once, them it is also consecutive! return true; } } /** * Save the custom meta data * * @param integer $post_id */ function pcr_meta_save( $post_id ) { // Check save status $is_autosave = wp_is_post_autosave( $post_id ); $is_revision = wp_is_post_revision( $post_id ); $is_valid_nonce = ( isset( $_POST[ 'pcr_nonce' ] ) && wp_verify_nonce( $_POST[ 'pcr_nonce' ], basename( __FILE__ ) ) ); $previous_parent_state = get_post_meta( $post_id , 'pcr-meta-isParent' , true ); /* Exit script depending on save status OR when nonce is invalid (hacked!) */ if ( $is_autosave || $is_revision || !$is_valid_nonce ) { return; } // Check for input and save if( !$previous_parent_state ){ // it wasn't parent // yet not a parent if( isset( $_POST[ 'pcr-meta' ] ) && $_POST[ 'pcr-meta' ] !== "iAmParent" ){ // save or update who is the parent remove_action('save_post', 'pcr_meta_save' ); $args0 = array( 'ID' => $post_id, 'post_parent' => $_POST[ 'pcr-meta' ] ); wp_update_post( $args0 ); add_action( 'save_post', 'pcr_meta_save' ); } // became parent elseif( isset( $_POST[ 'pcr-meta' ] ) && $_POST[ 'pcr-meta' ] === "iAmParent" ){ // store that isParent update_post_meta( $post_id, 'pcr-meta-isParent', $_POST[ 'pcr-meta' ] ); // reset the menu_order and remove who used to be it's parent remove_action('save_post', 'pcr_meta_save' ); $args1 = array( 'ID' => $post_id, 'menu_order' => 0, 'post_parent' => 0 ); wp_update_post( $args1 ); add_action( 'save_post', 'pcr_meta_save' ); } } // it was a parent else{ // but it is not a parent any more if( isset( $_POST[ 'pcr-meta' ] ) && $_POST[ 'pcr-meta' ] !== "iAmParent" ){ // remove isParent update_post_meta( $post_id, 'pcr-meta-isParent', '' ); remove_action('save_post', 'pcr_meta_save' ); // store the new parent if there is one selected if( isset( $_POST[ 'pcr-meta' ] ) && $_POST[ 'pcr-meta' ] != "" ){ $args2 = array( 'ID' => $post_id, 'post_parent' => $_POST[ 'pcr-meta' ] ); wp_update_post( $args2 ); } // remove the post_parent and menu_order properties from all it's old children. if( isset( $_POST[ 'pcr-meta-children-list' ] ) ){ $children = $_POST[ 'pcr-meta-children-list' ]; $index = 0; foreach ($children as $child){ $args3 = array( 'ID' => $child, 'menu_order' => $index, 'post_parent' => 0 ); wp_update_post( $args3 ); $index++; } } add_action( 'save_post', 'pcr_meta_save' ); } // it is still a parent elseif( isset( $_POST[ 'pcr-meta' ] ) && $_POST[ 'pcr-meta' ] === "iAmParent" ){ if( isset( $_POST[ 'pcr-meta-children-list' ] ) ){ // update children's menu_order remove_action('save_post', 'pcr_meta_save' ); $children = $_POST[ 'pcr-meta-children-list' ]; $index = 0; foreach ($children as $child) { $args4 = array( 'ID' => $child, 'menu_order' => $index ); wp_update_post( $args4 ); $index++; } add_action( 'save_post', 'pcr_meta_save' ); } } } } add_action( 'save_post', 'pcr_meta_save' ); /** * Enqueue scripts and styles */ function pcr_enqueue_scripts( $hook ){ global $typenow; if( ($typenow == 'lecture' || $typenow == 'post' ) && ( $hook == 'post-new.php' || $hook == 'post.php' ) ) { wp_enqueue_style( 'pcr-metabox-styles', plugin_dir_url( __FILE__ ) . '/css/pcr.css' ); wp_enqueue_script( 'pcr-js' , plugin_dir_url( __FILE__ )."/js/pcr.js" , array('jquery'), null, true ); wp_enqueue_script( 'jquery-ui', plugin_dir_url( __FILE__ )."/js/jquery-ui.min.js", array('jquery'), null, true); } } add_action( 'admin_enqueue_scripts', 'pcr_enqueue_scripts', 10, 1 ); 

Извините за очень длинный текст кода.

Короче, что делает код. Я использую сборку parent и menu_order для определения этих отношений, но я не делаю этого со сборкой в ​​metoxox, потому что мне нужно больше функциональности. Для обратного вызова я получаю все сообщения с метаданными iAmParent и iAmParent список. Оттуда вы можете установить текущую должность в качестве родительской статьи (Leitartikel) или выбрать, кто является ее родителем. Когда вы редактируете родительский пост, вы также получаете список со всеми его дочерними элементами и с перетаскиванием вы можете изменить свой порядок в списке. После того, как вы нажмете обновление, плагин сравнивает предыдущий и текущий родительский статус и действует соответственно (подробнее см. Комментарии к коду).

Я также добавил

 global $post, $wp_query; $wp_query->post = $post; 

в начале, потому что wp_reset_postdata() не работал.

Я сузил проблему до функции wp_update_post() , которую я использую для обновления метаданных по сообщениям детей. Я повторил все метаданные ( get_post_meta() ) перед тем, как вызвать wp_update_post() и все в порядке. После wp_update_post() метаданные совпадают со своими родительскими метаданными !!! В wp_update_post() я отправляю только идентификатор, menu_order и post_parent, который, согласно коду внутри post.php , не должен влиять на meta_input сообщения.

Любая идея, почему это происходит и как я могу это исправить?

Solutions Collecting From Web of "Как исправить: метаданные родителя переопределяют метаданные детей"