: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
else if ($currentVulnerable && !$patchVulnerable) { //Non-edge branch, current version is vulnerable but patch version is not
$longMsg = sprintf(/* translators: Software version. */ __("WordPress version %s is now available for your site's current branch. Please upgrade immediately to get the latest security updates from WordPress.", 'wordfence'), esc_html($updateVersion));
//keep existing $severity already set
else { //Non-edge branch, unpatched vulnerability -- shift recommendation from patch update to edge update
$updateVersion = $this->updateCheck->getCoreUpdateVersion();
//keep existing $severity and $longMsg already set
else { //Edge branch or newest version of an older branch
if (!$currentVulnerable && !$edgeVulnerable) { //Neither the current version or edge version have a known vulnerability
if ($this->updateCheck->getCoreEarlierBranch()) { //Update available on the edge branch, but the older branch in current use is up-to-date for its patches
$severity = wfIssues::SEVERITY_LOW;
$severity = wfIssues::SEVERITY_MEDIUM;
$longMsg = sprintf(/* translators: Software version. */ __("WordPress version %s is now available. Please upgrade immediately to get the latest fixes and compatibility updates from WordPress.", 'wordfence'), esc_html($updateVersion));
//else vulnerability fixed or unpatched vulnerability, keep the existing values already set
$longMsg .= ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_CORE_UPGRADE) . '" target="_blank" rel="noopener noreferrer">' . esc_html__('Learn more', 'wordfence') . '<span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a>';
$added = $this->addIssue(
'wfUpgrade' . $updateVersion,
'wfUpgrade' . $updateVersion,
'currentVersion' => $this->wp_version,
'newVersion' => $updateVersion,
if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
$haveIssues = wfIssues::STATUS_PROBLEM;
} else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
$haveIssues = wfIssues::STATUS_IGNORED;
$allPlugins = $this->updateCheck->getAllPlugins();
if (count($this->updateCheck->getPluginUpdates()) > 0) {
foreach ($this->updateCheck->getPluginUpdates() as $plugin) {
$severity = wfIssues::SEVERITY_CRITICAL;
if (isset($plugin['vulnerable'])) {
if (!$plugin['vulnerable']) {
$severity = wfIssues::SEVERITY_MEDIUM;
$key = 'wfPluginUpgrade' . ' ' . $plugin['pluginFile'] . ' ' . $plugin['newVersion'] . ' ' . $plugin['Version'];
/* translators: 1. Plugin name. 2. Software version. 3. Software version. */
__('The Plugin "%1$s" needs an upgrade (%2$s -> %3$s).', 'wordfence'),
empty($plugin['Name']) ? $plugin['pluginFile'] : $plugin['Name'],
$added = $this->addIssue('wfPluginUpgrade', $severity, $key, $key, $shortMsg,
__("You need to upgrade \"%s\" to the newest version to ensure you have any security fixes the developer has released.", 'wordfence'),
empty($plugin['Name']) ? $plugin['pluginFile'] : $plugin['Name']
if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
$haveIssues = wfIssues::STATUS_PROBLEM;
} else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
$haveIssues = wfIssues::STATUS_IGNORED;
if (isset($plugin['slug'])) {
unset($allPlugins[$plugin['slug']]);
if (count($this->updateCheck->getThemeUpdates()) > 0) {
foreach ($this->updateCheck->getThemeUpdates() as $theme) {
$severity = wfIssues::SEVERITY_CRITICAL;
if (isset($theme['vulnerable'])) {
if (!$theme['vulnerable']) {
$severity = wfIssues::SEVERITY_MEDIUM;
$key = 'wfThemeUpgrade' . ' ' . $theme['Name'] . ' ' . $theme['version'] . ' ' . $theme['newVersion'];
/* translators: 1. Theme name. 2. Software version. 3. Software version. */
__('The Theme "%1$s" needs an upgrade (%2$s -> %3$s).', 'wordfence'),
$added = $this->addIssue('wfThemeUpgrade', $severity, $key, $key, $shortMsg, sprintf(
/* translators: Theme name. */
__("You need to upgrade \"%s\" to the newest version to ensure you have any security fixes the developer has released.", 'wordfence'),
if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
$haveIssues = wfIssues::STATUS_PROBLEM;
} else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
$haveIssues = wfIssues::STATUS_IGNORED;
if ($this->isFullScan()) {
foreach ($this->pluginRepoStatus as $slug => $status) {
if ($status !== false && !is_wp_error($status) && ((is_object($status) && property_exists($status, 'last_updated')) || (is_array($status) && array_key_exists('last_updated', $status)))) {
$statusArray = (array) $status;
$hasVersion = array_key_exists('version', $statusArray);
$statusArray['version'] = null;
wordfence::status(3, 'error', "Unable to determine version for plugin $slug");
if (array_key_exists('last_updated', $statusArray) &&
is_string($statusArray['last_updated']) &&
($lastUpdateTimestamp = strtotime($statusArray['last_updated'])) &&
(time() - $lastUpdateTimestamp) > 63072000 /* ~2 years */) {
$statusArray['dateUpdated'] = wfUtils::formatLocalTime(get_option('date_format'), $lastUpdateTimestamp);
catch (Exception $e) { //DateMalformedStringException in PHP >= 8.3, Exception previously
wordfence::status(3, 'error', sprintf(
/* translators: 1. Plugin slug. 2. Malformed date string. */
__('Encountered bad date string for plugin "%s" in abandoned plugin check: %s', 'wordfence'),
$statusArray['last_updated']));
$severity = wfIssues::SEVERITY_MEDIUM;
$statusArray['abandoned'] = true;
$statusArray['vulnerable'] = false;
$vulnerable = $hasVersion && $this->updateCheck->isPluginVulnerable($slug, $statusArray['version']);
$severity = wfIssues::SEVERITY_CRITICAL;
$statusArray['vulnerable'] = true;
if (is_array($vulnerable) && isset($vulnerable['vulnerabilityLink'])) { $statusArray['vulnerabilityLink'] = $vulnerable['vulnerabilityLink']; }
if (is_array($vulnerable) && isset($vulnerable['cvssScore'])) { $statusArray['cvssScore'] = $vulnerable['cvssScore']; }
if (is_array($vulnerable) && isset($vulnerable['cvssVector'])) { $statusArray['cvssVector'] = $vulnerable['cvssVector']; }
if (isset($allPlugins[$slug]) && isset($allPlugins[$slug]['wpURL'])) {
$statusArray['wpURL'] = $allPlugins[$slug]['wpURL'];
$key = "wfPluginAbandoned {$slug} {$statusArray['version']}";
if (isset($statusArray['tested'])) {
/* translators: 1. Plugin name. 2. Software version. 3. Software version. */
__('The Plugin "%1$s" appears to be abandoned (updated %2$s, tested to WP %3$s).', 'wordfence'),
(empty($statusArray['name']) ? $slug : $statusArray['name']),
$statusArray['dateUpdated'],
/* translators: 1. Plugin name. 2. Software version. */
__('It was last updated %1$s ago and tested up to WordPress %2$s.', 'wordfence'),
wfUtils::makeTimeAgo(time() - $lastUpdateTimestamp),
esc_html($statusArray['tested'])
/* translators: 1. Plugin name. 2. Software version. */
__('The Plugin "%1$s" appears to be abandoned (updated %2$s).', 'wordfence'),
(empty($statusArray['name']) ? $slug : $statusArray['name']),
$statusArray['dateUpdated']
/* translators: Time duration. */
__('It was last updated %s ago.', 'wordfence'),
wfUtils::makeTimeAgo(time() - $lastUpdateTimestamp)
if ($statusArray['vulnerable']) {
$longMsg .= ' ' . __('It has unpatched security issues and may have compatibility problems with the current version of WordPress.', 'wordfence');
$longMsg .= ' ' . __('It may have compatibility problems with the current version of WordPress or unknown security issues.', 'wordfence');
$longMsg .= ' ' . sprintf(
/* translators: Support URL. */
__('<a href="%s" target="_blank" rel="noopener noreferrer">Get more information.<span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_PLUGIN_ABANDONED));
$added = $this->addIssue('wfPluginAbandoned', $severity, $key, $key, $shortMsg, $longMsg, $statusArray);
if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
$haveIssues = wfIssues::STATUS_PROBLEM;
} else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
$haveIssues = wfIssues::STATUS_IGNORED;
unset($allPlugins[$slug]);
} else if ($status !== false && is_wp_error($status) && isset($status->errors['plugins_api_failed'])) { //The plugin does not exist in the wp.org repo
$knownFiles = $this->getKnownFilesLoader()->getKnownFiles();
if (isset($knownFiles['status']) && is_array($knownFiles['status']) && isset($knownFiles['status']['plugins']) && is_array($knownFiles['status']['plugins'])) {
$requestedPlugins = $this->getPlugins();
foreach ($requestedPlugins as $key => $data) {
if ($data['ShortDir'] == $slug && isset($knownFiles['status']['plugins'][$slug]) && $knownFiles['status']['plugins'][$slug] == 'r') { //It existed in the repo at some point and was removed
$pluginFile = wfUtils::getPluginBaseDir() . $key;
$pluginData = get_plugin_data($pluginFile);
$pluginData['wpRemoved'] = true;
$pluginData['vulnerable'] = false;
$vulnerable = $this->updateCheck->isPluginVulnerable($slug, $pluginData['Version']);
$pluginData['vulnerable'] = true;
if (is_array($vulnerable) && isset($vulnerable['vulnerabilityLink'])) { $statusArray['vulnerabilityLink'] = $vulnerable['vulnerabilityLink']; }
if (is_array($vulnerable) && isset($vulnerable['cvssScore'])) { $statusArray['cvssScore'] = $vulnerable['cvssScore']; }
if (is_array($vulnerable) && isset($vulnerable['cvssVector'])) { $statusArray['cvssVector'] = $vulnerable['cvssVector']; }
$key = "wfPluginRemoved {$slug} {$pluginData['Version']}";
/* translators: Plugin name. */
__('The Plugin "%s" has been removed from wordpress.org but is still installed on your site.', 'wordfence'), (empty($pluginData['Name']) ? $slug : $pluginData['Name']));
if ($pluginData['vulnerable']) {
$longMsg = __('It has unpatched security issues and may have compatibility problems with the current version of WordPress.', 'wordfence');
$longMsg = __('Your site is still using this plugin, but it is not currently available on wordpress.org. Plugins can be removed from wordpress.org for various reasons. This can include benign issues like a plugin author discontinuing development or moving the plugin distribution to their own site, but some might also be due to security issues. In any case, future updates may or may not be available, so it is worth investigating the cause and deciding whether to temporarily or permanently replace or remove the plugin.', 'wordfence');
$longMsg .= ' ' . sprintf(
/* translators: Support URL. */
__('<a href="%s" target="_blank" rel="noopener noreferrer">Get more information.<span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_PLUGIN_REMOVED));
$added = $this->addIssue('wfPluginRemoved', wfIssues::SEVERITY_CRITICAL, $key, $key, $shortMsg, $longMsg, $pluginData);
if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
$haveIssues = wfIssues::STATUS_PROBLEM;
} else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
$haveIssues = wfIssues::STATUS_IGNORED;
unset($allPlugins[$slug]);
//Handle plugins that either do not exist in the repo or do not have updates available
foreach ($allPlugins as $slug => $plugin) {
if ($plugin['vulnerable']) {
$key = implode(' ', array('wfPluginVulnerable', $plugin['pluginFile'], $plugin['Version']));
$shortMsg = sprintf(__('The Plugin "%s" has a security vulnerability.', 'wordfence'), $plugin['Name']);
__('To protect your site from this vulnerability, the safest option is to deactivate and completely remove "%s" until a patched version is available. <a href="%s" target="_blank" rel="noopener noreferrer">Get more information.<span class="screen-reader-text"> (opens in new tab)</span></a>', 'wordfence'),
wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_PLUGIN_VULNERABLE)
if (is_array($plugin['vulnerable']) && isset($plugin['vulnerable']['vulnerabilityLink'])) { $statusArray['vulnerabilityLink'] = $plugin['vulnerable']['vulnerabilityLink']; }
if (is_array($plugin['vulnerable']) && isset($plugin['vulnerable']['cvssScore'])) { $statusArray['cvssScore'] = $plugin['vulnerable']['cvssScore']; }
if (is_array($plugin['vulnerable']) && isset($plugin['vulnerable']['cvssVector'])) { $statusArray['cvssVector'] = $plugin['vulnerable']['cvssVector']; }
$plugin['updatedAvailable'] = false;
$added = $this->addIssue('wfPluginVulnerable', wfIssues::SEVERITY_CRITICAL, $key, $key, $shortMsg, $longMsg, $plugin);
if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
unset($allPlugins[$slug]);
$this->updateCheck = false;
$this->pluginRepoStatus = array();
wfIssues::statusEnd($this->statusIDX['oldVersions'], $haveIssues);
$this->scanController->completeStage(wfScanner::STAGE_VULNERABILITY_SCAN, $haveIssues);
public function scan_suspiciousAdminUsers() {
$this->statusIDX['suspiciousAdminUsers'] = wfIssues::statusStart(__("Scanning for admin users not created through WordPress", 'wordfence'));
$this->scanController->startStage(wfScanner::STAGE_OPTIONS_AUDIT);
$haveIssues = wfIssues::STATUS_SECURE;
$adminUsers = new wfAdminUserMonitor();
if ($adminUsers->isEnabled()) {
$response = $this->api->call('suspicious_admin_usernames');
if (is_array($response) && isset($response['ok']) && wfUtils::truthyToBoolean($response['ok']) && !empty($response['patterns'])) {
wfConfig::set_ser('suspiciousAdminUsernames', $response['patterns']);
// Let the rest of the scan continue
$suspiciousAdmins = $adminUsers->checkNewAdmins();
if (is_array($suspiciousAdmins)) {
foreach ($suspiciousAdmins as $userID) {
$this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_USERS);
$user = new WP_User($userID);
$key = 'suspiciousAdminUsers' . $userID;
$added = $this->addIssue('suspiciousAdminUsers', wfIssues::SEVERITY_HIGH, $key, $key,
sprintf(/* translators: WordPress username. */ __("An admin user with the username %s was created outside of WordPress.", 'wordfence'), esc_html($user->user_login)),
sprintf(/* translators: WordPress username. */ __("An admin user with the username %s was created outside of WordPress. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it.", 'wordfence'), esc_html($user->user_login)),
if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
$haveIssues = wfIssues::STATUS_PROBLEM;
} else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
$haveIssues = wfIssues::STATUS_IGNORED;
$admins = $adminUsers->getCurrentAdmins();
* @var WP_User $adminUser
foreach ($admins as $userID => $adminUser) {
$key = 'suspiciousAdminUsers' . $userID;
// Check against user name list here.
$suspiciousAdminUsernames = wfConfig::get_ser('suspiciousAdminUsernames');
if (is_array($suspiciousAdminUsernames)) {
foreach ($suspiciousAdminUsernames as $usernamePattern) {
if (preg_match($usernamePattern, $adminUser->user_login)) {
$added = $this->addIssue('suspiciousAdminUsers', wfIssues::SEVERITY_HIGH, $key, $key,
sprintf(/* translators: WordPress username. */ __("An admin user with a suspicious username %s was found.", 'wordfence'), esc_html($adminUser->user_login)),
sprintf(/* translators: WordPress username. */ __("An admin user with a suspicious username %s was found. Administrators accounts with usernames similar to this are commonly seen created by hackers. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it.", 'wordfence'), esc_html($adminUser->user_login)),
if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
$haveIssues = wfIssues::STATUS_PROBLEM;
} else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
$haveIssues = wfIssues::STATUS_IGNORED;
wfIssues::statusEnd($this->statusIDX['suspiciousAdminUsers'], $haveIssues);
$this->scanController->completeStage(wfScanner::STAGE_OPTIONS_AUDIT, $haveIssues);
public function scan_suspiciousOptions() {
$this->statusIDX['suspiciousOptions'] = wfIssues::statusStart(__("Scanning for suspicious site options", 'wordfence'));
$this->scanController->startStage(wfScanner::STAGE_OPTIONS_AUDIT);
$haveIssues = wfIssues::STATUS_SECURE;
$blogsToScan = self::getBlogsToScan('options');
$this->hoover = new wordfenceURLHoover($this->apiKey, $this->wp_version);
foreach ($blogsToScan as $blog) {
$excludedHosts = array();
$homeURL = get_home_url($blog['blog_id']);
$host = parse_url($homeURL, PHP_URL_HOST);
$excludedHosts[$host] = 1;
$siteURL = get_site_url($blog['blog_id']);
$host = parse_url($siteURL, PHP_URL_HOST);
$excludedHosts[$host] = 1;
$excludedHosts = array_keys($excludedHosts);
if (defined('TD_THEME_OPTIONS_NAME')) {
$q = $wfdb->querySelect("SELECT option_name, option_value FROM " . $blog['table'] . " WHERE option_name REGEXP '^td_[0-9]+$' OR option_name = '%s'", TD_THEME_OPTIONS_NAME);
$q = $wfdb->querySelect("SELECT option_name, option_value FROM " . $blog['table'] . " WHERE option_name REGEXP '^td_[0-9]+$'");
$found = $this->hoover->hoover($blog['blog_id'] . '-' . $row['option_name'], $row['option_value'], $excludedHosts);
$this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, $found);
$this->status(2, 'info', __("Examining URLs found in the options we scanned for dangerous websites", 'wordfence'));
$hooverResults = $this->hoover->getBaddies();
$this->status(2, 'info', __("Done examining URLs", 'wordfence'));
if ($this->hoover->errorMsg) {
wfIssues::statusEndErr();
throw new Exception($this->hoover->errorMsg);
$this->hoover->cleanup();
foreach ($hooverResults as $idString => $hresults) {
$arr = explode('-', $idString);
foreach ($hresults as $result) {
if ($result['badList'] != 'goog-malware-shavar' && $result['badList'] != 'googpub-phish-shavar' && $result['badList'] != 'wordfence-dbl') {
continue; //A list type that may be new and the plugin has not been upgraded yet.
$blogs = self::getBlogsToScan('options', $blogID);
$blog = array_shift($blogs);
if ($result['badList'] == 'goog-malware-shavar') {
$shortMsg = sprintf(/* translators: URL. */ __("Option contains a suspected malware URL: %s", 'wordfence'), esc_html($optionKey));
$longMsg = sprintf(/* translators: URL. */ __("This option contains a suspected malware URL listed on Google's list of malware sites. It may indicate your site is infected with malware. The URL is: %s", 'wordfence'), esc_html($result['URL']));
} else if ($result['badList'] == 'googpub-phish-shavar') {
$shortMsg = sprintf(/* translators: URL. */ __("Option contains a suspected phishing site URL: %s", 'wordfence'), esc_html($optionKey));
$longMsg = sprintf(/* translators: URL. */ __("This option contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. It may indicate your site is infected with malware. The URL is: %s", 'wordfence'), esc_html($result['URL']));
} else if ($result['badList'] == 'wordfence-dbl') {
$shortMsg = sprintf(/* translators: URL. */ __("Option contains a suspected malware URL: %s", 'wordfence'), esc_html($optionKey));
$longMsg = sprintf(/* translators: URL. */ __("This option contains a URL that is currently listed on Wordfence's domain blocklist. It may indicate your site is infected with malware. The URL is: %s", 'wordfence'), esc_html($result['URL']));
//A list type that may be new and the plugin has not been upgraded yet.
$longMsg .= ' - ' . sprintf(/* translators: Support URL. */ __('<a href="%s" target="_blank" rel="noopener noreferrer">Get more information.<span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_OPTION_MALWARE_URL));
$this->status(2, 'info', sprintf(/* translators: Scan result description. */ __("Adding issue: %s", 'wordfence'), $shortMsg));
$ignoreC = $idString . md5(serialize(get_option($optionKey, '')));
$added = $this->addIssue('optionBadURL', wfIssues::SEVERITY_HIGH, $ignoreP, $ignoreC, $shortMsg, $longMsg, array(
'optionKey' => $optionKey,
'badURL' => $result['URL'],
'isMultisite' => $blog['isMultisite'],
'domain' => $blog['domain'],
if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
$haveIssues = wfIssues::STATUS_PROBLEM;
} else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
$haveIssues = wfIssues::STATUS_IGNORED;
wfIssues::statusEnd($this->statusIDX['suspiciousOptions'], $haveIssues);
$this->scanController->completeStage(wfScanner::STAGE_OPTIONS_AUDIT, $haveIssues);
public function scan_geoipSupport() {
$this->statusIDX['geoipSupport'] = wfIssues::statusStart(__("Checking for future GeoIP support", 'wordfence'));
$this->scanController->startStage(wfScanner::STAGE_SERVER_STATE);
$haveIssues = wfIssues::STATUS_SECURE;
if (version_compare(phpversion(), '5.4') < 0 && wfConfig::get('isPaid') && wfBlock::hasCountryBlock()) {
$shortMsg = __('PHP Update Needed for Country Blocking', 'wordfence');
$longMsg = sprintf(/* translators: Software version. */ __('The GeoIP database that is required for country blocking has been updated to a new format. This new format requires sites to run PHP 5.4 or newer, and this site is on PHP %s. To ensure country blocking continues functioning, please update PHP.', 'wordfence'), wfUtils::cleanPHPVersion());
$longMsg .= ' ' . sprintf(/* translators: Support URL. */ __('<a href="%s" target="_blank" rel="noopener noreferrer">Get more information.<span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_GEOIP_UPDATE));
$this->status(2, 'info', sprintf(/* translators: Scan result description. */ __("Adding issue: %s", 'wordfence'), $shortMsg));
$ignoreP = 'geoIPPHPDiscontinuing';
$added = $this->addIssue('geoipSupport', wfIssues::SEVERITY_MEDIUM, $ignoreP, $ignoreC, $shortMsg, $longMsg, array());
if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
$haveIssues = wfIssues::STATUS_PROBLEM;
} else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
$haveIssues = wfIssues::STATUS_IGNORED;
wfIssues::statusEnd($this->statusIDX['geoipSupport'], $haveIssues);
$this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, $haveIssues);
public function status($level, $type, $msg) {
wordfence::status($level, $type, $msg);
public function addIssue($type, $severity, $ignoreP, $ignoreC, $shortMsg, $longMsg, $templateData, $alreadyHashed = false) {
wfIssues::updateScanStillRunning();
return $this->i->addIssue($type, $severity, $ignoreP, $ignoreC, $shortMsg, $longMsg, $templateData, $alreadyHashed);