: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$shortSiteURL = preg_replace('/^https?:\/\//i', '', site_url());
$content = $this->toEmailView()->__toString();
if (is_string($email_addresses)) { $email_addresses = explode(',', $email_addresses); }
foreach ($email_addresses as $email) {
$uniqueContent = str_replace('<!-- ##UNSUBSCRIBE## -->', wp_kses(sprintf(/* translators: URL to the WordPress admin panel. */ __('No longer an administrator for this site? <a href="%s" target="_blank">Click here</a> to stop receiving security alerts.', 'wordfence'), wfUtils::getSiteBaseURL() . '?_wfsf=removeAlertEmail&jwt=' . wfUtils::generateJWT(array('email' => $email))), array('a'=>array('href'=>array(), 'target'=>array()))), $content);
if (!wp_mail($email, sprintf(/* translators: 1. Site URL. 2. Localized date. */ __('Wordfence activity for %1$s on %2$s', 'wordfence'), date_i18n(get_option('date_format')), $shortSiteURL), $uniqueContent, 'Content-Type: text/html')) {
* @throws wfViewNotFoundException
public function render() {
public function __toString() {
public function getLimit() {
public function setLimit($limit) {
class wfRecentFirewallActivity {
private $activity = array();
private $max_fetch = 2000;
private $time_range = 604800;
public function __construct($max_fetch = null, $time_range = null) {
if ($max_fetch !== null) {
$this->max_fetch = $max_fetch;
if ($time_range !== null) {
$this->time_range = $time_range;
$table_wfHits = wfDB::networkTable('wfHits');
$results = $wpdb->get_results($wpdb->prepare(<<<SQL
SELECT attackLogTime, IP, URL, UA, actionDescription, actionData
WHERE action = 'blocked:waf' AND attackLogTime > (UNIX_TIMESTAMP() - %d)
ORDER BY attackLogTime DESC
, $this->time_range, $this->max_fetch));
foreach ($results as &$row) {
$actionData = json_decode($row->actionData, true);
if (!is_array($actionData) || !isset($actionData['paramKey']) || !isset($actionData['paramValue'])) {
if (isset($actionData['failedRules']) && $actionData['failedRules'] == 'blocked') {
$row->longDescription = __("Blocked because the IP is blocklisted", 'wordfence');
$row->longDescription = sprintf(__("Blocked for %s", 'wordfence'), $row->actionDescription);
$paramKey = base64_decode($actionData['paramKey']);
$paramValue = base64_decode($actionData['paramValue']);
if (strlen($paramValue) > 100) {
$paramValue = substr($paramValue, 0, 100) . '...';
if (preg_match('/([a-z0-9_]+\.[a-z0-9_]+)(?:\[(.+?)\](.*))?/i', $paramKey, $matches)) {
case 'request.queryString':
$row->longDescription = sprintf(__('Blocked for %1$s in query string: %2$s = %3$s', 'wordfence'), $row->actionDescription, $matches[2], $paramValue);
$row->longDescription = sprintf(__('Blocked for %1$s in POST body: %2$s = %3$s', 'wordfence'), $row->actionDescription, $matches[2], $paramValue);
$row->longDescription = sprintf(__('Blocked for %1$s in cookie: %2$s = %3$s', 'wordfence'), $row->actionDescription, $matches[2], $paramValue);
case 'request.fileNames':
$row->longDescription = sprintf(__('Blocked for %1$s in file: %2$s = %3$s', 'wordfence'), $row->actionDescription, $matches[2], $paramValue);
$this->activity = $results;
public function mostRecentActivity($limit, &$remainder = null) {
if ($remainder !== null) {
$remainder = count($this->activity) - $limit;
return array_slice($this->activity, 0, $limit);
class wfRecentlyModifiedFiles extends wfDirectoryIterator {
private $time_range = 604800;
private $files = array();
private $excluded_directories;
* @param string $directory
* @param int $max_files_per_directory
* @param int $max_iterations
public function __construct($directory = ABSPATH, $max_files_per_directory = 20000, $max_iterations = 250000, $time_range = 604800) {
parent::__construct($directory, $max_files_per_directory, $max_iterations);
$this->time_range = $time_range;
$excluded_directories = explode("\n", wfUtils::cleanupOneEntryPerLine(wfConfig::get('email_summary_excluded_directories', '')));
$this->excluded_directories = array();
foreach ($excluded_directories as $index => $path) {
if (($dir = realpath(ABSPATH . $path)) !== false) {
$this->excluded_directories[$dir] = 1;
protected function scan($dir) {
if (!array_key_exists(realpath($dir), $this->excluded_directories)) {
return parent::scan($dir);
public function file($file) {
$mtime = filemtime($file);
if (time() - $mtime < $this->time_range) {
$this->files[] = array($file, $mtime);
public function mostRecentFiles($limit = 300) {
usort($this->files, array(
return array_slice($this->files, 0, $limit);
* Sort in descending order.
private function _sortMostRecentFiles($a, $b) {
public function getFiles() {
class wfActivityReportView extends wfView {
public function displayFile($file) {
$realPath = realpath($file);
if (stripos($realPath, ABSPATH) === 0) {
return substr($realPath, strlen(ABSPATH));
public function modTime($unix_time = null) {
if ($unix_time === null) {
return wfUtils::formatLocalTime('F j, Y g:ia', $unix_time);
public function attackTime($unix_time = null) {
if ($unix_time === null) {
return wfUtils::formatLocalTime('F j, Y', $unix_time) . "<br>" . wfUtils::formatLocalTime('g:ia', $unix_time);
public function displayIP($binaryIP) {
$readableIP = wfUtils::inet_ntop($binaryIP);
$country = wfUtils::countryCode2Name(wfUtils::IP2Country($readableIP));
return "{$readableIP} (" . ($country ? $country : __('Unknown', 'wordfence')) . ")";