Nav menu items disappearing (but not immediately)

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;

Leave a Comment