: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
echo '<div id="wafConfigNeedsFixedNotice" class="fade error"><p><strong>' . __('The Wordfence Web Application Firewall needs a configuration update.', 'wordfence') . '</strong> ' .
/* translators: 1. WordPress admin panel URL. 2. Support URL. */
__('It is not currently in extended protection mode but was configured to use an older version of PHP and may have become deactivated when PHP was updated. You may perform the configuration update automatically by <a href="%1$s">clicking here</a> or use the "Optimize the Wordfence Firewall" button on the Firewall Options page. <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="%2$s"><span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a>', 'wordfence'),
wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_WAF_MOD_PHP_FIX)
public static function wafReadOnlyNotice() {
echo '<div id="wordfenceWAFReadOnlyNotice" class="fade error"><p><strong>' . __('The Wordfence Web Application Firewall is in read-only mode.', 'wordfence') . '</strong> ' . sprintf('PHP is currently running as a command line user and to avoid file permission issues, the WAF is running in read-only mode. It will automatically resume normal operation when run normally by a web server. <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="%s"><span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a>', wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_WAF_READ_ONLY_WARNING)) . '</p></div>';
public static function misconfiguredHowGetIPsNotice() {
$url = network_admin_url('admin.php?page=Wordfence&subpage=global_options');
$existing = wfConfig::get('howGetIPs', '');
$recommendation = wfConfig::get('detectProxyRecommendation', '');
if ($existing == 'REMOTE_ADDR') {
$existingMsg = __('This site is currently using PHP\'s built in REMOTE_ADDR.', 'wordfence');
else if ($existing == 'HTTP_X_FORWARDED_FOR') {
$existingMsg = __('This site is currently using the X-Forwarded-For HTTP header, which should only be used when the site is behind a front-end proxy that outputs this header.', 'wordfence');
else if ($existing == 'HTTP_X_REAL_IP') {
$existingMsg = __('This site is currently using the X-Real-IP HTTP header, which should only be used when the site is behind a front-end proxy that outputs this header.', 'wordfence');
else if ($existing == 'HTTP_CF_CONNECTING_IP') {
$existingMsg = __('This site is currently using the Cloudflare "CF-Connecting-IP" HTTP header, which should only be used when the site is behind Cloudflare.', 'wordfence');
if ($recommendation == 'REMOTE_ADDR') {
$recommendationMsg = __('For maximum security use PHP\'s built in REMOTE_ADDR.', 'wordfence');
else if ($recommendation == 'HTTP_X_FORWARDED_FOR') {
$recommendationMsg = __('This site appears to be behind a front-end proxy, so using the X-Forwarded-For HTTP header will resolve to the correct IPs.', 'wordfence');
else if ($recommendation == 'HTTP_X_REAL_IP') {
$recommendationMsg = __('This site appears to be behind a front-end proxy, so using the X-Real-IP HTTP header will resolve to the correct IPs.', 'wordfence');
else if ($recommendation == 'HTTP_CF_CONNECTING_IP') {
$recommendationMsg = __('This site appears to be behind Cloudflare, so using the Cloudflare "CF-Connecting-IP" HTTP header will resolve to the correct IPs.', 'wordfence');
echo '<div id="wordfenceMisconfiguredHowGetIPsNotice" class="fade error"><p><strong>' .
__('Your \'How does Wordfence get IPs\' setting is misconfigured.', 'wordfence')
. '</strong> ' . $existingMsg . ' ' . $recommendationMsg . ' <a href="#" onclick="wordfenceExt.misconfiguredHowGetIPsChoice(\'yes\'); return false;" role="button">' .
__('Click here to use the recommended setting', 'wordfence')
. ' <a href="' . $url . '">' .
__('visit the options page', 'wordfence')
__('to manually update it.', 'wordfence')
<a class="wf-btn wf-btn-default wf-btn-sm wf-dismiss-link" href="#" onclick="wordfenceExt.misconfiguredHowGetIPsChoice(\'no\'); return false;" role="button">' .
__('Dismiss', 'wordfence')
. '</a> <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_MISCONFIGURED_HOW_GET_IPS) . '"><span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a></p></div>';
public static function autoUpdateNotice(){
echo '<div id="wordfenceAutoUpdateChoice" class="fade error"><p><strong>' .
__('Do you want Wordfence to stay up-to-date automatically?', 'wordfence')
. '</strong> <a href="#" onclick="wordfenceExt.autoUpdateChoice(\'yes\'); return false;" role="button">'.
__('Yes, enable auto-update.', 'wordfence')
. '</a> | <a href="#" onclick="wordfenceExt.autoUpdateChoice(\'no\'); return false;" role="button">' .
__('No thanks.', 'wordfence')
private static function getNoticeHideKey($id) {
return "wordfence_dismiss_$id";
private static function hideNoticeForUser($id) {
$user = get_current_user_id();
update_user_meta($user, self::getNoticeHideKey($id), true);
private static function hasHiddenNotice($id) {
$user = get_current_user_id();
return get_user_meta($user, self::getNoticeHideKey($id), true);
public static function showUnitedStatesBlockedNotice() {
$id = "wordfenceUnitedStatesBlocked";
if (self::hasHiddenNotice($id))
<div id="<?php echo esc_attr($id) ?>" class="notice notice-warning">
<?php esc_html_e('Wordfence country blocking is currently set to block the United States. We recommend allowing access from the United States for Google and other benign crawlers, unless you choose to only block the login page.', 'wordfence') ?>
<a target="_blank" rel="noopener noreferrer" href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_BLOCKING_FULL_SITE) ?>"><?php esc_html_e('Learn More', 'wordfence') ?></a>
<a class="wf-btn wf-btn-default wf-btn-sm wf-dismiss-link" href="#" onclick="<?php echo esc_attr('wordfenceExt.hideNoticeForUser(' . json_encode($id) . '); return false;') ?>"><?php esc_html_e('Dismiss', 'wordfence') ?></a>
public static function isWordfenceAdminPage() {
if (isset($_GET['page']) && is_string($_GET['page'])) {
foreach (array('Wordfence', 'WFLS') as $prefix) {
if (strpos($_GET['page'], $prefix) === 0)
public static function getDashboardNotificationCountIcon() {
$notificationCount = count(wfNotification::notifications());
$updatingNotifications = get_site_transient('wordfence_updating_notifications');
$hidden = ($notificationCount == 0 || $updatingNotifications ? ' wf-hidden' : '');
$formattedCount = number_format_i18n($notificationCount);
return " <span class=\"update-plugins wf-menu-badge wf-notification-count-container{$hidden}\" title=\"" . esc_attr($formattedCount) . '"><span class="update-count wf-notification-count-value">' . esc_html($formattedCount) . '</span></span>';
public static function isWordfenceInstallPage() {
return self::isPage('WordfenceInstall');
public static function isWordfenceSupportPage() {
return self::isPage('WordfenceSupport');
public static function admin_menus(){
if(! wfUtils::isAdmin()){ return; }
$warningAdded = self::isWordfenceInstallPage();
if(get_option('wf_plugin_act_error', false)){
if(wfUtils::isAdminPageMU()){
add_action('network_admin_notices', 'wordfence::activation_warning');
add_action('admin_notices', 'wordfence::activation_warning');
if(!wfConfig::get('apiKey') && !wfOnboardingController::shouldShowAnyAttempt()){
if(wfUtils::isAdminPageMU()){
add_action('network_admin_notices', 'wordfence::noKeyError');
add_action('admin_notices', 'wordfence::noKeyError');
$firewall = new wfFirewall();
if (!empty($_GET['page']) && preg_match('/^Wordfence/i', $_GET['page'])) {
if (!$firewall->testConfig()) {
if (wfUtils::isAdminPageMU()) {
add_action('network_admin_notices', 'wordfence::wafConfigInaccessibleNotice');
add_action('admin_notices', 'wordfence::wafConfigInaccessibleNotice');
else if (!$warningAdded && method_exists('wfWAF', 'hasFallbackStorageEngine') && wfWAF::hasFallbackStorageEngine()) {
add_action(wfUtils::isAdminPageMU()?'network_admin_notices':'admin_notices', 'wordfence::wafStorageEngineFallbackNotice');
if (!$warningAdded && !WFWAF_SUBDIRECTORY_INSTALL && !wfWAFAutoPrependHelper::verifyHtaccessMod_php()) {
if (WFWAF_AUTO_PREPEND) { //Active, running PHP 5 only mod_php block
if (wfUtils::isAdminPageMU()) {
add_action('network_admin_notices', 'wordfence::wafConfigNeedsUpdate_mod_php');
add_action('admin_notices', 'wordfence::wafConfigNeedsUpdate_mod_php');
else if (PHP_MAJOR_VERSION > 5) { //Inactive, probably deactivated by updating from PHP 5 -> 7 due to no PHP 7 mod_php block
if (wfUtils::isAdminPageMU()) {
add_action('network_admin_notices', 'wordfence::wafConfigNeedsFixed_mod_php');
add_action('admin_notices', 'wordfence::wafConfigNeedsFixed_mod_php');
if (wfOnboardingController::shouldShowAttempt3() || wfConfig::get('touppPromptNeeded')) { //Both top banners
$firewall = new wfFirewall();
if ($firewall->firewallMode() != wfFirewall::FIREWALL_MODE_DISABLED) {
$lastChecked = (int) wfWAF::getInstance()->getStorageEngine()->getConfig('lastRuleUpdateCheck', null, 'transient');
$lastUpdated = (int) wfWAF::getInstance()->getStorageEngine()->getConfig('rulesLastUpdated', null, 'transient');
$threshold = time() - (86400 * (wfConfig::get('isPaid') ? 2.5 : 9)); //Refresh rate + 2 days
if ($lastChecked > 0 && $lastUpdated > 0 && $lastChecked < $threshold) {
$nextUpdate = PHP_INT_MAX;
$cron = (array) wfWAF::getInstance()->getStorageEngine()->getConfig('cron', null, 'livewaf');
/** @var wfWAFCronEvent $event */
foreach ($cron as $index => $event) {
if ($event instanceof wfWAFCronFetchRulesEvent) {
$event->setWaf(wfWAF::getInstance());
if (!$event->isInPast()) {
$nextUpdate = min($nextUpdate, $event->getFireTime());
/* translators: Localized date. */
__('The last rules update for the Wordfence Web Application Firewall was unsuccessful. The last successful update check was %s, so this site may be missing new rules added since then.', 'wordfence'),
wfUtils::formatLocalTime(get_option('date_format') . ' ' . get_option('time_format'), $lastChecked)
if (!$firewall->isSubDirectoryInstallation()) {
if ($nextUpdate < PHP_INT_MAX) {
$message .= ' ' . sprintf(
/* translators: 1. Localized date. 2. WordPress admin panel URL. */
__('You may wait for the next automatic attempt at %1$s or try to <a href="%2$s">Manually Update</a> by clicking the "Manually Refresh Rules" button below the Rules list.', 'wordfence'),
wfUtils::formatLocalTime(get_option('date_format') . ' ' . get_option('time_format'), $nextUpdate),
esc_url(network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options#wf-option-wafRules'))
$message .= ' ' . sprintf(/* translators: WordPress admin panel URL. */ __('You may wait for the next automatic attempt or try to <a href="%s">Manually Update</a> by clicking the "Manually Refresh Rules" button below the Rules list.', 'wordfence'), esc_url(network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options#waf-rules-next-update')));
if ($nextUpdate < PHP_INT_MAX) {
$message .= ' ' . sprintf(/* translators: WordPress admin panel URL. */ __('You may wait for the next automatic attempt at %s or log into the parent site to manually update by clicking the "Manually Refresh Rules" button below the Rules list.', 'wordfence'), wfUtils::formatLocalTime(get_option('date_format') . ' ' . get_option('time_format'), $nextUpdate));
$message .= ' ' . __('You may wait for the next automatic attempt or log into the parent site to manually update by clicking the "Manually Refresh Rules" button below the Rules list.', 'wordfence');
wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_CRITICAL, $message, 'waf-rules-failed');
wfAdminNoticeQueue::removeAdminNotice(false, 'waf-rules-failed');
catch (wfWAFStorageFileException $e) {
error_log($e->getMessage());
wfAdminNoticeQueue::removeAdminNotice(false, 'waf-rules-failed');
if (wfAdminNoticeQueue::enqueueAdminNotices()) {
if (!$warningAdded && self::isWordfencePage() && wfCentral::isCentralSiteUrlMismatched() && !wfUtils::truthyToBoolean(wfConfig::get('centralUrlMismatchChoice'))) {
if (wfUtils::isAdminPageMU()) {
add_action('network_admin_notices', 'wfCentral::mismatchedCentralUrlNotice');
add_action('admin_notices', 'wfCentral::mismatchedCentralUrlNotice');
$existing = wfConfig::get('howGetIPs', '');
$recommendation = wfConfig::get('detectProxyRecommendation', '');
$canDisplayMisconfiguredHowGetIPs = true;
if (empty($existing) || empty($recommendation) || $recommendation == 'UNKNOWN' || $recommendation == 'DEFERRED' || $existing == $recommendation) {
$canDisplayMisconfiguredHowGetIPs = false;
if (!$warningAdded && $canDisplayMisconfiguredHowGetIPs && !wfUtils::truthyToBoolean(wfConfig::get('misconfiguredHowGetIPsChoice' . WORDFENCE_VERSION)) && !(defined('WORDFENCE_DISABLE_MISCONFIGURED_HOWGETIPS') && WORDFENCE_DISABLE_MISCONFIGURED_HOWGETIPS)) {
if (wfUtils::isAdminPageMU()) {
add_action('network_admin_notices', 'wordfence::misconfiguredHowGetIPsNotice');
add_action('admin_notices', 'wordfence::misconfiguredHowGetIPsNotice');
if (!$warningAdded && method_exists(wfWAF::getInstance(), 'isReadOnly') && wfWAF::getInstance()->isReadOnly()) {
if (wfUtils::isAdminPageMU()) {
add_action('network_admin_notices', 'wordfence::wafReadOnlyNotice');
add_action('admin_notices', 'wordfence::wafReadOnlyNotice');
if (!wfConfig::get('autoUpdate') && !wfConfig::get('autoUpdateChoice')) {
if (wfUtils::isAdminPageMU()) {
add_action('network_admin_notices', 'wordfence::autoUpdateNotice');
add_action('admin_notices', 'wordfence::autoUpdateNotice');
if (!empty($_GET['page']) && $_GET['page'] === 'WordfenceWAF' && !empty($_GET['wafconfigrebuild']) && !WFWAF_SUBDIRECTORY_INSTALL) {
check_admin_referer('wafconfigrebuild', 'waf-nonce');
wfWAF::getInstance()->uninstall();
if (function_exists('network_admin_url') && is_multisite()) {
$wafMenuURL = network_admin_url('admin.php?page=WordfenceWAF');
$wafMenuURL = admin_url('admin.php?page=WordfenceWAF');
wp_redirect($wafMenuURL);
if (!empty($_GET['page']) && $_GET['page'] === 'WordfenceWAF' && !empty($_GET['wafconfigfixmodphp']) && !WFWAF_SUBDIRECTORY_INSTALL) {
check_admin_referer('wafconfigfixmodphp', 'waf-nonce');
wfWAFAutoPrependHelper::fixHtaccessMod_php();
if (function_exists('network_admin_url') && is_multisite()) {
$wafMenuURL = network_admin_url('admin.php?page=WordfenceWAF');
$wafMenuURL = admin_url('admin.php?page=WordfenceWAF');
wp_redirect($wafMenuURL);
foreach (wfBlock::countryBlocks() as $block) {
if ($block->parameters['blockSite']) {
foreach ($block->parameters['countries'] as $country) {
if (strtoupper($country) === 'US') {
add_action(wfUtils::isAdminPageMU() ? 'network_admin_notices' : 'admin_notices', 'wordfence::showUnitedStatesBlockedNotice');
if (!$warningAdded && wfSupportController::shouldShowSatisfactionPrompt()) {
add_action('network_admin_notices', 'wfSupportController::satisfactionPromptNotice');
add_action('admin_notices', 'wfSupportController::satisfactionPromptNotice');
if (self::isWordfenceAdminPage()) {
$dashboardExtra = self::getDashboardNotificationCountIcon();
add_menu_page('Wordfence', "Wordfence{$dashboardExtra}", 'activate_plugins', 'Wordfence', 'wordfence::menu_dashboard', 'none');
//These are split to allow our module plugins to insert their menu item(s) at any point in the hierarchy
public static function admin_menus_20() {
$dashboardExtra = self::getDashboardNotificationCountIcon();
add_submenu_page("Wordfence", __("Wordfence Dashboard", 'wordfence'), __("Dashboard", 'wordfence') . $dashboardExtra, "activate_plugins", "Wordfence", 'wordfence::menu_dashboard');
public static function admin_menus_30() {
add_submenu_page("Wordfence", __("Firewall", 'wordfence'), __("Firewall", 'wordfence'), "activate_plugins", "WordfenceWAF", 'wordfence::menu_firewall');
if (wfConfig::get('displayTopLevelBlocking')) {
add_submenu_page("Wordfence", __("Blocking", 'wordfence'), __("Blocking", 'wordfence'), "activate_plugins", "WordfenceBlocking", 'wordfence::menu_blocking');
public static function admin_menus_40() {
add_submenu_page("Wordfence", __("Scan", 'wordfence'), __("Scan", 'wordfence'), "activate_plugins", "WordfenceScan", 'wordfence::menu_scan');
public static function admin_menus_50() {
add_submenu_page('Wordfence', __('Tools', 'wordfence'), __('Tools', 'wordfence'), 'activate_plugins', 'WordfenceTools', 'wordfence::menu_tools');
if (wfConfig::get('displayTopLevelLiveTraffic')) {
add_submenu_page("Wordfence", __("Live Traffic", 'wordfence'), __("Live Traffic", 'wordfence'), "activate_plugins", "WordfenceLiveTraffic", 'wordfence::menu_tools');
public static function admin_menus_60() {
if (wfConfig::get('displayTopLevelOptions')) {
add_submenu_page("Wordfence", __("All Options", 'wordfence'), __("All Options", 'wordfence'), "activate_plugins", "WordfenceOptions", 'wordfence::menu_options');
public static function admin_menus_70() {
add_submenu_page('Wordfence', __('Help', 'wordfence'), __('Help', 'wordfence'), 'activate_plugins', 'WordfenceSupport', 'wordfence::menu_support');
public static function admin_menus_80() {
if (wfCentral::isSupported() && self::isPage('WordfenceCentral')) {
add_submenu_page('Wordfence', __('Wordfence Central', 'wordfence'), __('Wordfence Central', 'wordfence'), 'activate_plugins', 'WordfenceCentral', 'wordfence::menu_wordfence_central');
public static function admin_menus_85() {
if (wfOnboardingController::shouldShowAnyAttempt() || self::isWordfenceInstallPage()) {
add_submenu_page('Wordfence', __('Install Wordfence', 'wordfence'), __('Install', 'wordfence'), 'activate_plugins', 'WordfenceInstall', 'wordfence::menu_install');
public static function admin_menus_90() {
switch (wfLicense::current()->getType()) {
case wfLicense::TYPE_FREE:
$message = __('Upgrade to Premium', 'wordfence');
$slug = 'WordfenceUpgradeToPremium';
case wfLicense::TYPE_PREMIUM:
$message = __('Upgrade to Care', 'wordfence');
$slug = 'WordfenceUpgradeToCare';
case wfLicense::TYPE_CARE:
$message = __('Upgrade to Response', 'wordfence');
$slug = 'WordfenceUpgradeToResponse';
$message = __('Protect More Sites', 'wordfence');
$slug = 'WordfenceProtectMoreSites';
add_submenu_page("Wordfence", $message, "<strong id=\"wfMenuCallout\" style=\"color: #FCB214;\">" . $message . "</strong>", "activate_plugins", $slug, 'wordfence::_menu_noop');
add_filter('clean_url', 'wordfence::_patchWordfenceSubmenuCallout', 10, 3);
private static function isPage($page) {
return array_key_exists('page', $_GET) && $_GET['page'] === $page;
public static function _patchWordfenceSubmenuCallout($url, $original_url, $_context){
if (preg_match('/(?:WordfenceUpgradeTo(Premium|Care|Response))$/i', $url, $matches)) {
remove_filter('clean_url', 'wordfence::_patchWordfenceSubmenuCallout', 10);
return wfLicense::current()->getUpgradeUrl("menuUpgrade$matches[1]");
else if (preg_match('/(?:WordfenceProtectMoreSites)$/i', $url)) {
remove_filter('clean_url', 'wordfence::_patchWordfenceSubmenuCallout', 10);
return 'https://www.wordfence.com/zz10/licenses?purchase';
public static function _menu_noop() {
public static function _retargetWordfenceSubmenuCallout() {
<script type="text/javascript">
jQuery(document).ready(function($) {
$('#wfMenuCallout').closest('a').attr('target', '_blank').attr('rel', 'noopener noreferrer');
public static function admin_bar_menu() {
if (wfUtils::isAdmin() && wfConfig::get('showAdminBarMenu')) {
$title = '<div id="wf-adminbar-icon" class="ab-item"></div>';
$count = count(wfNotification::notifications());
$sinceCount = count(wfNotification::notifications((int) get_user_meta(get_current_user_id(), 'wordfence-notifications', true)));
$counter = '<span id="wf-notification-popover" data-toggle="popover" data-trigger="focus" data-content="' .
esc_attr(/* translators: Number of notifications. */ _n('You have %d new Wordfence notification.', 'You have %d new Wordfence notifications.', $sinceCount, 'wordfence'))
. '" data-container="body" data-placement="wf-bottom"> </span>';
update_user_meta(get_current_user_id(), 'wordfence-notifications', time());
$badge = '<div class="wp-core-ui wp-ui-notification wf-notification-counter wf-notification-count-container' . ($count == 0 ? ' wf-hidden' : '') . '"><span class="wf-count wf-notification-count-value">' . $count . '</span></div>';
$wp_admin_bar->add_menu( array(
'id' => 'wordfence-menu',
'title' => $title . $counter,
'href' => network_admin_url('admin.php?page=Wordfence'),
$wp_admin_bar->add_menu( array(
'parent' => 'wordfence-menu',
'id' => 'wordfence-notifications',
'title' => '<div id="wordfence-notifications-display" class="wf-adminbar-submenu-title">' . __('Notifications', 'wordfence') . '</div>' . $badge,
'href' => network_admin_url('admin.php?page=Wordfence'),
$wp_admin_bar->add_menu( array(
'parent' => 'wordfence-menu',
'id' => 'wordfence-javascripterror',
'title' => '<div id="wordfence-javascripterror-display" class="wf-adminbar-submenu-title">' . __('JavaScript Errors', 'wordfence') . '</div><div class="wf-adminbar-status wf-adminbar-status-good">•</div>',
'href' => 'javascript:void(0)',
$wp_admin_bar->add_menu( array(
'parent' => 'wordfence-menu',
'id' => 'wordfence-malwareurl',
'title' => '<div id="wordfence-malwareurl-display' . (is_admin() ? '-skip' : '') . '" class="wf-adminbar-submenu-title">' . __('Malware URLs', 'wordfence') . '</div><div class="wf-adminbar-status wf-adminbar-status-neutral">•</div>',
'href' => network_admin_url('admin.php?page=WordfenceScan'),
public static function menu_tools() {
wp_enqueue_style('wordfence-select2-css');
wp_enqueue_script('wordfence-select2-js');
$subpage = filter_input(INPUT_GET, 'subpage');