Make WordPress Core

Opened 2 years ago

#57825 new defect (bug)

Something's wrong with the way the 'admin_init' hook and/or the wp_update_post function works

Reported by: lunule's profile lunule Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.1.1
Component: General Keywords: needs-patch dev-feedback needs-testing
Focuses: Cc:

Description

Hi,

(I'm not sure what's happening here, so I left the Component dropdown with its default value.)

The issue in a nutshell: when hooked to admin_init, the below function's wp_update_post() call is executed even when the wrapper if-else statement evaluates to false, and it updates all mac-submenus post type entries' status to 'draft' regardless of the fact that the $post_id variable doesn't even have a value in this case.

I don't know how is this even possible, but it's happening - and if another admin hook is used ( for instance in_admin_header ), the function works perfectly, just as expected.

<?php
function cpt_mac_submenus_create_delete_check_menu_items() {

        // Get all submenu posts
        $spq_Arr                        = array(
                'posts_per_page'        => -1,
                'post_type'             => 'mac-submenus',
                // We only check published submenu posts
                'post_status'           => array('publish'),
                'fields'                        => 'ids',
        ); 
        $submenu_post_ids_Arr   = get_posts( $spq_Arr );

        // Get the custom item array of the menu associated with the 'primary_menu' location
        global $new_menu_Arr;

        // Get all menu items that are top-level and parent
        $parent_menu_items_Arr          = mac_helper_search( 
                $new_menu_Arr, 
                'has_children', 
                true                    
        );
        $top_level_menu_items_Arr       = mac_helper_search( 
                $new_menu_Arr, 
                'is_top_level', 
                true                    
        );
        $tlp_items_Arr                          = array_uintersect( 
                                                                        $parent_menu_items_Arr, 
                                                                        $top_level_menu_items_Arr,
                                                                        function( $val1, $val2 ) {
                                                                                return strcmp($val1['has_children'], $val2['has_children']);
                                                                        } 
                                                                  );

        // Check if all 'mac-submenus' entries have their respective top-level & parent menu 
        // item in the menu associated with the 'primary_menu' location.
        // 
        // If a submenu entry DOESN'T have such corresponding menu item:
        //              - check if it has a top-level BUT NOT PARENT corresponding menu item
        //              - if it has, change the submenu post status to 'draft'
        // --------------------------------------------------------------------------------------------

        // 1. Get submenu posts having a corresponding top-level parent menu item. 
        $posts_with_tlp_Arr = array();  

        foreach ( $submenu_post_ids_Arr as $post_id ) :

                $post_has_tlp = false;
 
                foreach ( $tlp_items_Arr as $menu_item ) :

                        $mi_title       = html_entity_decode( $menu_item['title'] );
                        $p_title        = html_entity_decode( get_the_title( $post_id ) );

                        if ( $mi_title == $p_title ) :

                                $post_has_tlp = true;
                                break;

                        endif;

                endforeach;

                if ( $post_has_tlp )
                        $posts_with_tlp_Arr[] = $post_id;

        endforeach;

        // 2. Get posts that don't have a corresponding top-level parent menu item, and
        //        change their status to 'draft';
        $posts_with_no_tlp_Arr = array_diff( $submenu_post_ids_Arr, $posts_with_tlp_Arr );

        if ( !empty($posts_with_no_tlp_Arr) ) :

                foreach( $posts_with_no_tlp_Arr as $post_id ) :

                        $update_args_Arr = array(
                        'ID'                    => $post_id,
                        'post_type'     => 'mac-submenus',
                        'post_status'   => 'draft',
                        );
                        wp_update_post( $update_args_Arr );                             

                endforeach;

        endif;

}
add_action( 'admin_init', 'cpt_mac_submenus_create_delete_check_menu_items' );

I spent an hour with testing code variations, but couldn't find a problem with the above code or a fix of the issue.

Change History (0)

Note: See TracTickets for help on using tickets.