I recently updated a WordPress instance from 5.4 to 5.5 to end up with an annoying margin-top in the admin area, above the menu directly.
I deactivated all plugins, switched themes, did some inspection, and I ended up with some findings.
The CSS class causing the margin-top is .php-error
, which is appended to #adminmenuwrap
when a php error is supposed to be displayed.
/* in load-styles.php */
.php-error #adminmenuback, .php-error #adminmenuwrap {
margin-top: 2em;
}
/* the menu wrapper */
<div id="adminmenuwrap"></div>
/* the php script in /wp-admin/admin-header.php line 201 */
// Print a CSS class to make PHP errors visible.
if ( error_get_last() && WP_DEBUG && WP_DEBUG_DISPLAY && ini_get( 'display_errors' ) ) {
$admin_body_class .= ' php-error';
}
/* print_r(error_get_last()) outputs */
Array (
[type] => 8
[message] => unserialize(): Error at offset 11857 of 11895 bytes
[file] => .../wp-includes/functions.php
[line] => 624
)
/**
* Unserialize data only if it was serialized.
*
* @since 2.0.0
*
* @param string $data Data that might be unserialized.
* @return mixed Unserialized data can be any type.
*/
function maybe_unserialize( $data ) {
if ( is_serialized( $data ) ) { // Don't attempt to unserialize data that wasn't serialized going in.
return @unserialize( trim( $data ) );
}
return $data;
}
It is perfectly normal that WP_DEBUG && WP_DEBUG_DISPLAY && ini_get( 'display_errors' )
be true (because I’m actually debugging), but the problem is that no php error is being displayed.
This instance (with bug) is running on an online hosted server.
But I also have the exact same copy of this instance running on localhost, except it does not have this bug.
Did anyone encounter this scenario? What do you suggest?
——- EDIT (Fix) ——–
The following manipulation did solve the problem but I’m still not sure about the origin or “real” cause behind the bug. This been said, it was a calculation error in serialized data, more precisely, in my case it came from the contents of Privacy Policy page sample (tutorial by WordPress).
Here’s how I went about it:
// Edit the function in /wp-includes/functions.php on line 624 and include some
// error logging.
// DO NOT FORGET TO REVERT BACK TO THE ORIGINAL CODE ONCE DONE DEBUGGING!
/**
* Unserialize data only if it was serialized.
*
* @since 2.0.0
*
* @param string $data Data that might be unserialized.
* @return mixed Unserialized data can be any type.
*/
function maybe_unserialize( $data ) {
if ( is_serialized( $data ) ) { // Don't attempt to unserialize data that wasn't serialized going in.
error_log( "DATA DEBUGGING START ---------- \r");
error_log( "TRIMED: ");
error_log( trim( $data ) );
error_log( "UNSERIALIZED: ");
error_log( print_r(unserialize( trim( $data ) ), true));
error_log( "DATA DEBUGGING END ---------- \r\n");
return unserialize( trim( $data ) );
}
return $data;
}
This will log all serialized and unserialized values in your debug.log or error.log depending which method you are using. I’m using the default WordPress define( 'WP_DEBUG_LOG', true );
in w-config.php, which logs errors in the file debug.log under /wp-content/.
Doing this allowed me to detect the exact row in database causing the problem.
The problem comes from a wrong count calculation.
a:3:{s:11:"plugin_name";s:9:"WordPress";s:11:"policy_text";s:11789:".....
I did a characters/bytes count of the contents of that key and it turned out to be 11799 instead of 11789.
The value in s:11789
must be s:11799
in my case. So I changed it in the database and everything worked fine. I also edited the page in the Editor and saved it then rechecked and everything still work fine.
This fixed the issue but I guess something went wrong at some point. Most probably when I imported the local database to a different instance.
I hope this helps!