1

WordPress 4.5 broke my plugin and there are no obvious clues why in the change log

The plugin controls the visibility of menu items. Users select one or more countries and whether to show or hide the menu item.

The setting to show or hide still works:

add_action( 'wp_update_nav_menu_item', array( $this, 'csmi_update_visibility' ), 10, 3 );
...
<input
type="radio"
id="edit-menu-item-visibility-<?php echo $item_id;?>"
name="menu-item-show-hide[<?php echo $item_id; ?>]" 
value="hide" <?php checked( get_post_meta( $item_id, 'hide_show', true ), 'hide', true ); ?>
/>Hide from these countries.</br>
<input
type="radio"
id="edit-menu-item-visibility-<?php echo $item_id; ?>"
name="menu-item-show-hide[<?php echo $item_id; ?>]"
value="show" <?php checked( get_post_meta( $item_id, 'hide_show', true ), 'show', true ); ?>
/>Only show to these countries.</br>
...
/* Put visibility settings in the database. */
function csmi_update_visibility( $menu_id, $menu_item_db_id, $args ) {
    $meta_value = get_post_meta( $menu_item_db_id, 'hide_show', true );
    if ( isset( $_POST[ 'menu-item-show-hide' ][ $menu_item_db_id ] ) ) {
        $new_meta_value = $_POST[ 'menu-item-show-hide' ][ $menu_item_db_id ];
    }
    if ( $meta_value !== $new_meta_value ) {
        update_post_meta( $menu_item_db_id, 'hide_show', $new_meta_value );
    }
}

But location(s) are not being saved:

add_action( 'wp_update_nav_menu_item', array( $this, 'csmi_update_locations' ), 10, 3 );
...
<select name="menu-item-visibility[<?php echo $item_id; ?>][]" id="edit-menu-item-visibility-<?php echo $item_id; ?>" class="chzn-select" multiple="true">
<?php
$vals = get_post_meta( $item_id, 'locations', true );
foreach( $countries as $key => $value ) { 
?>
    <option value="<?php echo $key;?>"<?php echo is_array( $vals ) && in_array( $key, $vals ) ? "selected='selected'" : ''; ?>> <?php echo $value;?> </option>
<?php
}
?>
</select>
...
/* Put locations in the database. */
function csmi_update_locations( $menu_id, $menu_item_db_id, $args ) {
    $meta_value = get_post_meta( $menu_item_db_id, 'locations', true );
    if ( isset( $_POST[ 'menu-item-visibility' ][ $menu_item_db_id ] ) ) { 
        $new_meta_value = $_POST[ 'menu-item-visibility' ][ $menu_item_db_id ];
    }
    if ( !isset($new_meta_value ) ) {
        delete_post_meta( $menu_item_db_id, 'locations', $meta_value );
    }
    elseif ( $meta_value !== $new_meta_value ) {
        update_post_meta( $menu_item_db_id, 'locations', $new_meta_value );
    }
}

Any ideas how WP 4.5 might have broken it? I'm about at my wits end.

Source code available here: https://plugins.trac.wordpress.org/browser/location-specific-menu-items-by-country/tags/1.0.3

1 Answer 1

1

This is probably the root cause - https://core.trac.wordpress.org/changeset/36510. Core have moved from saving menus in $_POST to sending them as json encoded and then decode it into $_POST. I am not very familiar with how menus are sent to the server, but you probably either use the wrong hook, use the right hook but too early, or there is a bug in core.

1
  • Good catch. I changed those files back to the previous versions and the plugin works again. Now to figure out a work around...
    – j8d
    Apr 26, 2016 at 8:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.