1

I'm working on a site where some of the nav menu items disappear (from the front end, the back end, and the database). However, debugging is extremely difficult since they don't disappear immediately! As a result, I'm unable to figure out what's triggering the deletion.

More info:

  • It seems as though nav menu items that are of the 'custom' variety (e.g. to an arbitrary url, rather than a post/page/category etc.) might be safe. I'm not 100% sure about that yet.
  • At one point, new nav menu items were not being saved - I'd add several to a menu, click "Save Menu", and the menu would be saved with no menu items.

Any suggestions on how to debug this particularly frustrating problem?

This is on 3.4.1. I've just updated to 3.4.2, but I can't verify yet today that it's still happening (although I've no reason to believe it won't).

Edit: I have confirmed that "custom" nav items (links to arbitrary url, vs. a WP page/category/etc.) do not get deleted.

  • 1
    Checked Ticket #14134? – fuxia Sep 7 '12 at 15:46
  • Unfortunately it's not that bug - this happens with just a few menu items. – Travis Northcutt Sep 7 '12 at 16:08
  • does it happen with javascript off? – ifdion Sep 8 '12 at 1:36
  • @ifdion - what would javascript have to do with items being deleted from the database? – Travis Northcutt Sep 12 '12 at 18:56
  • my bad, thought it was disappearing from the front end only – ifdion Sep 12 '12 at 22:24
1

Log queries

As the question says "it doesn't happen always", it's hard to tell what's really going on. When you can't see what happens (query in background) and don't know when it happens, then it's best to log it.

The logger

On activation, the plugin will try to create a log directory named 'nav_log' in the temp folder - it will throw and print an error, when this doesn't work.

It will then try to write to a file named 'nav_log.txt' inside the temp dir. You should get a log entry each time, a query for a nav_menu_item is triggered. The logs will be prefixed by the date (Y-m-d g:i:s). So, as long as you keep your eyes open and try to catch changes in the UI, you should be able to tell when and it happens. I also added the $hook_suffix global to (maybe) help determining when this happens.

Disclaimer: The plugin needs some love and won't work out of the box. Filesystem stuff is complicated and the plugin is just a sketch/an idea.

<?php
! defined( 'ABSPATH' ) AND exit;
/** Plugin Name: (#64487) »kaiser« log nav menu query */
# Version: 2012-09-17.0924

if ( ! class_exists( 'wpse64487_query_logger' ) )
{
    register_activation_hook( __FILE__, array( 'wpse64487_query_logger', 'create_log_dir' ) );
    add_action( 'plugins_loaded', array( 'wpse64487_query_logger', 'init' ), 5 );

class wpse64487_query_logger
{
    public static $instance;
    public $name = 'nav_log';

    public static function init()
    {
        null === self :: $instance AND self :: $instance = new self;
        return self :: $instance;
    }

    public function __construct()
    {
        add_filter( 'posts_where', array( $this, 'ask_where' ) );
    }

    public function create_log_dir()
    {
        $output = true;
        // Relative to the Temp Dir
        if ( ! wp_mkdir_p( $this->get_log_loc() ) )
            $output = new WP_Error( __CLASS__, 'Log Dir creation failed.' );

        is_wp_error( $output ) AND print $output->get_error_message( __CLASS__ );
    }

    public function get_log_loc( $full = false )
    {
        $output = trailingslashit( get_temp_dir()."{$this->name}" );
        $full AND $output .= "{$this->name}.txt";
        return $output;
    }

    public function ask_where( $where )
    {
        if ( "`post_type` = 'nav_menu_item'" === $where )
        {
            add_filter( 'posts_clauses', array( $this, 'catch_query' ) );
        }
        return $where;
    }

    public function catch_query( $pieces )
    {
        global $wp_filesystem, $hook_suffix;
        $file = $this->get_log_loc( true );
        $contents  = $wp_filesystem->get_contents( $file );
        // Append current query
        $contents .= "\n\n@".date( "Y-m-d g:i:s" );
        $contents .= "\n Query: ".implode( ' ', $pieces );
        $contents .= "\n Page: {$hook_suffix}";
        $wp_filesystem->put_contents(
             $file
            ,$contents
            ,FS_CHMOD_FILE
        );
        return $pieces;
    }
} // END Class wpse64487_query_logger

} // endif;
0

Have you de-activated any plugins you may have installed?

If you've already tried that and it's still happening then I can't recommend a simple fix with this install, but have you tried, or even considered, backing up your existing install, exporting your content to an xml file and re-installing with a clean database and no plugins activated to begin with, just you're desired theme? The new install should have standard (non-custom code) in the core files. Before importing your content back in, try setting up a menu and see if it still happens. If it does, you can rule out a corrupted database and I think it'd be safe to say the problem lies somewhere in your theme files.

Just remember to make a note of your current core options values before wiping them out with a clean install.

  • I only have a few plugins installed, and they're all "safe" plugins. However, I have plenty of custom code in my theme and mu-plugins directories. My challenge is to figure out how to debug the issue, given the random/intermittent nature of the problem. – Travis Northcutt Sep 12 '12 at 21:11
  • Ok but I wouldn't rule out the possibility of a corrupted database. I'm not sure how it could happen or entirely sure how it could affect the menus, but the transient settings in the options table might be one possible cause. Maybe they've been changed at some point? – Ben Sep 13 '12 at 5:41
  • As this doesn’t answer the question … it should be a comment, right? – fuxia Sep 16 '12 at 14:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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