Have you upgraded to WordPress 3.8 and received the following error?
Fatal error: Call to undefined function wp_get_current_user() in \wp-includes\capabilities.php on line 1344
If so, and you want to understand one reason why you got this message, and how to recover from it, then read on.
Code that worked in a previous version of WordPress doesn’t work any more.
What you should have done
Whenever you upgrade WordPress, you are advised to
- take a backup of your database and files
- deactivate your plugins
The reason for deactivating your plugins is to avoid getting fatal errors with code that no longer works. The theory being that you will discover which plugin doesn’t work when you come to reactivating them.
This process is not fail safe. It’s possible that a broken plugin can be activated but it will cause a fatal error soon after.
In this scenario you are then stuck; you will need to resort to using the control panel or FTP in order to fix the site. No matter what you try to do with WordPress you won’t get anywhere.
The generally accepted process involves deactivating plugins by renaming their folders or the main plugin file itself.
Recover from a Fatal error using your site’s control panel (cpanel)
wp_get_current_user() is a pluggable function, defined in pluggable.php. Pluggable functions are routines that plugins may override. To allow this to happen pluggable.php is loaded AFTER the plugins.
Extract from wp-settings.php:
// Load active plugins.
foreach ( wp_get_active_and_valid_plugins() as $plugin )
include_once( $plugin );
unset( $plugin );
// Load pluggable functions.
require( ABSPATH . WPINC . '/pluggable.php' );
require( ABSPATH . WPINC . '/pluggable-deprecated.php' );
If a plugin wants to use a pluggable function, OR any function that will call a pluggable function, then it should wait until they’ve been defined before calling them. The recommendation is that a plugin should not actually do much when the first loaded, but should wait until the ‘init’ action hook (or a later hook).
What actually went wrong?
The site being updated was at a very old version of WordPress ( 3.4.1 ) and was running old versions of plugins. During the loading of a plugin’s main file the following code was encountered and executed.
if ( ! defined( 'PCLZIP_TEMPORARY_DIR' ) )
define( 'PCLZIP_TEMPORARY_DIR', trailingslashit( hmbkp_path() ) );
This seemingly innocent code eventually calls the get_allowed_mime_types() function, and this calls current_user_can() which attempts to call wp_get_current_user().
But wp_get_current_user() doesn’t exist and so a Fatal error occurs.
So why didn’t it fail in WordPress 3.4.1?
get_allowed_mime_types() was changed in WordPress 3.6.1 to fix a security flaw. The call to current_user_can() was added as part of this change.
Had the site been upgraded with each new version of WordPress then it might have failed after the upgrade to 3.6.1
Fixes for this specific problem, which was actually found in backupwordpress v1.6.8, are:
Either rename the plugin folder
OR rename the plugin’s main file
OR comment out the two lines of code defining
In this instance, the solution is to upgrade the plugin BEFORE upgrading WordPress.
Other people have reported the problem and issues have been raised on WordPress.org.
While the specific scenario in this post may not apply, you can still use the general workaround approach to deactivate plugins by removing them one by one from the plugins folder.
Another way of actually finding the offending code is to get a callback trace. This method may be quicker than deactivating the plugins one by one.
How to find the offending code?
Although hacking core is frowned upon, when a site doesn’t work then you need to resort to drastic measures.
- Using FTP or control panel, edit the file reported in the Fatal error message.
- Before the call to the missing function add:
var_dump( debug_backtrace() );
- Try accessing the site again.
- Use the generated call stack to determine which plugin to deactivate.
- Rename the plugin’s folder and try again. There may be more than one problem.
- When your site’s working again remove the line of code you added.
- Then go about finding the real solution to the problem