(I'm sorry for the long post, see conclusion below)
I have a WP multisite set up, with some sites in production mode (with domain aliases) and some still not "launched". At the moment there are five sites running.
However, I have a very strange problem: Some of the wp nav menu items are disappearing randomly. It is only page items that disappear - custom links, categories and so on are still there. The pages are still there, they are just removed from the menu. This happens about once a week. The first few times I had been working on the site, so I thought it was me who did something. But recently it's happened for example in the middle of the night during a weekend, when none of my customers nor me have even touched the site.
Often it seems like some kind of chain reaction - when the menus items disappear on one site it sometimes disappears on other, but not always - and not always at the same time. Today, for example, the menus disappeared on two of the sites (http://wasabicms.se) and (http://womenswellness.se), so i checked the other ones and they were ok. Then, a few minutes later, it disappeared on another site.
The server administrator have gone through the mysql, php and apache logs and can't find anything unusual. The menu items that disappeared are not in wp_posts anymore. Unfortunately we can't activate mysql query logs, so we can't know for sure how they are removed.
The plugins that are installed and activated are:
Advanced Custom Fields
Advanced Custom Fields: Options Page
Advanced Custom Fields: Repeater fields
Blog Copier
Contact Form 7
Jetpack
New User Approve
Redirection (the one by Urban Giraffe)
Simple 301 Redirects
Wordpress Importer
Wordpress MU Domain Mapping
Wordpress SEO (by Yoast)
WP Instagram Widget (by Code For The People)
However, I have been using all of them except for New User Approve and Wordpress MU Domain Mapping on other projects without any problems. I can't deactivate them since all sites use them and some are in production mode.
Conclusion
WP nav menu items (pages only) are disappearing from the menus on a multisite. The pages themselves are still there, only the nav menu links disappear. This happens randomly (~once a week), even when no one is working on the code or is logged in to admin. No errors logged from php, mysql or apache.
Im sorry for the long post, but I really think it has to be explained in detail. Anyone recognize this problem? Or can point me in the right direction? I feel like I've tried everything. Thank you so much in advance!
I have had this happen to me once with a newly setup custom theme and the issue was related to a typo/duplicate of sorts when I registered a couple of the menus in the functions file. I created menus and found that the menus were gone without explanation randomly at another time even when not working on the website. As a thought since it might be quick to try, consider exploring the same option and make sure that the menus are registered correctly and also rename them completely.
Finally solved it!
We have a few pages only logged in users can see. That is defined in a postmeta/custom field (generated by ACF). In the header.php
we had an if
statement like the following, so users would be prompted to log in instead of just facing a blank page or so:
if ( ! is_user_logged_in() && get_field( 'show_page_logged_in_user' ) ) {
// ... show login form
get_footer();
exit;
}
But to prevent the pages from appearing in i.e. search results and RSS feeds, we also added this code to functions.php
:
function pre_hide_if_not_logged_in( $query ) {
if ( ! is_user_logged_in() ) {
$query->set( 'meta_query',
array(
'relation' => 'OR',
array(
'key' => 'show_page_logged_in_user',
'value' => '%yes%',
'compare' => 'NOT LIKE'
),
array(
'key' => 'show_page_logged_in_user',
'compare' => 'NOT EXISTS',
)
) );
}
}
add_action( 'pre_get_posts', 'pre_hide_if_not_logged_in' );
After applying an SQL logger, we found out this applied on Wordpress cron jobs as well. But of course only when the cron jobs ran for non-logged in users which made it seem completely random and yet (almost) in sync. So we have removed the pre_hide_if_not_logged_in
action and everything seems to stay in place now. We replaced it with the following. It's not as secure, but it can't really interfere with the db queries.
function hide_if_not_logged_in( $content ) {
if ( get_field( 'show_page_logged_in_user' ) && ! is_user_logged_in() ) {
return '';
}
return $content;
}
add_filter( 'the_content', 'hide_if_not_logged_in' );
add_filter( 'the_excerpt', 'hide_if_not_logged_in' );
I really hope this can spare someone a few headaches.
I had the exact same behavior, menus disappearing during cron job because of a custom function hiding posts by altering a query using the 'pre_get_posts'
hook. I found an easier way out (at least for my setup), which is to check whether the running code is within a cron job before altering the query:
function pre_hide_if_not_logged_in( $query ) {
if (defined('DOING_CRON')) {
// we're running the cron, so return the query untouched
return $query;
}
// now, since we're not running the cron, proceed to alter the query
if ( ! is_user_logged_in() ) {
// alter query here
// ...
}
}
add_action( 'pre_get_posts', 'pre_hide_if_not_logged_in' );
Works like a charm!
From my understanding, this would also work for you.