: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
private static function _site_url_nofilter($path = '', $scheme = null) { //A version of the native get_site_url and get_option without the filter calls
global $pagenow, $wpdb, $blog_id;
static $cached_url = null;
if ($cached_url !== null) {
if (defined('WP_SITEURL') && WORDFENCE_PREFER_WP_HOME_FOR_WPML) {
$cached_url = WP_SITEURL;
if ( empty( $blog_id ) || !is_multisite() ) {
$url = $wpdb->get_var("SELECT option_value FROM {$wpdb->options} WHERE option_name = 'siteurl' LIMIT 1");
else if (is_multisite()) {
$current_network = get_network();
if ( 'relative' == $scheme )
$url = rtrim($current_network->path, '/');
$url = 'http://' . rtrim($current_network->domain, '/') . '/' . trim($current_network->path, '/');
if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) {
if ( is_ssl() && ! is_admin() && 'wp-login.php' !== $pagenow )
$scheme = parse_url( $url, PHP_URL_SCHEME );
$url = set_url_scheme( $url, $scheme );
if ( $path && is_string( $path ) )
$url .= '/' . ltrim( $path, '/' );
public static function refreshCachedSiteURL() {
$pullDirectly = class_exists('WPML_URL_Filters');
//A version of the native get_home_url without the filter call
$siteurl = self::_site_url_nofilter();
if (function_exists('get_bloginfo') && empty($siteurl)) {
$siteurl = network_site_url();
$siteurl = rtrim($siteurl, '/'); //Because previously we used get_bloginfo and it returns http://example.com without a '/' char.
if (wfConfig::get('wp_site_url') !== $siteurl) {
wfConfig::set('wp_site_url', $siteurl);
* Equivalent to network_site_url but uses the cached value for the URL if we have it
* to avoid breaking on sites that define it based on the requesting hostname.
* @param null|string $scheme
public static function wpSiteURL($path = '', $scheme = null) {
$siteurl = wfConfig::get('wp_site_url', '');
if (function_exists('get_bloginfo') && empty($siteurl)) {
$siteurl = network_site_url($path, $scheme);
$siteurl = site_url($path, $scheme);
$siteurl = rtrim($siteurl, '/'); //Because previously we used get_bloginfo and it returns http://example.com without a '/' char.
$siteurl = set_url_scheme($siteurl, $scheme);
if ($path && is_string($path)) {
$siteurl .= '/' . ltrim($path, '/');
* Equivalent to network_admin_url but uses the cached value for the URL if we have it
* to avoid breaking on sites that define it based on the requesting hostname.
* @param null|string $scheme
public static function wpAdminURL($path = '', $scheme = null) {
$adminURL = self::wpSiteURL('wp-admin/', $scheme);
$adminURL = self::wpSiteURL('wp-admin/network/', $scheme);
if ($path && is_string($path)) {
$adminURL .= ltrim($path, '/');
return apply_filters('admin_url', $adminURL, $path, null);
return apply_filters('network_admin_url', $adminURL, $path);
public static function wafInstallationType() {
if (defined('WFWAF_STORAGE_ENGINE')) { $storage = WFWAF_STORAGE_ENGINE; }
$status = (defined('WFWAF_ENABLED') && !WFWAF_ENABLED) ? 'disabled' : wfWaf::getInstance()->getStorageEngine()->getConfig('wafStatus');
if (defined('WFWAF_ENABLED') && !WFWAF_ENABLED) {
return "{$status}|const|{$storage}";
else if (defined('WFWAF_SUBDIRECTORY_INSTALL') && WFWAF_SUBDIRECTORY_INSTALL) {
return "{$status}|subdir|{$storage}";
else if (defined('WFWAF_AUTO_PREPEND') && WFWAF_AUTO_PREPEND) {
return "{$status}|extended|{$storage}";
return "{$status}|basic|{$storage}";
public static function hex2bin($string) { //Polyfill for PHP < 5.4
if (!is_string($string)) { return false; }
if (strlen($string) % 2 == 1) { return false; }
return pack('H*', $string);
* Returns whether or not the site should be treated as if it's full-time SSL.
public static function isFullSSL() {
return is_ssl() && parse_url(self::wpHomeURL(), PHP_URL_SCHEME) === 'https'; //It's possible for only wp-admin to be SSL so we check the home URL too
* Identical to the same functions in wfWAFUtils.
* Set the mbstring internal encoding to a binary safe encoding when func_overload
* When mbstring.func_overload is in use for multi-byte encodings, the results from
* strlen() and similar functions respect the utf8 characters, causing binary data
* to return incorrect lengths.
* This function overrides the mbstring encoding to a binary-safe encoding, and
* resets it to the users expected encoding afterwards through the
* `reset_mbstring_encoding` function.
* It is safe to recursively call this function, however each
* `mbstring_binary_safe_encoding()` call must be followed up with an equal number
* of `reset_mbstring_encoding()` calls.
* @see wfWAFUtils::reset_mbstring_encoding
* @staticvar array $encodings
* @staticvar bool $overloaded
* @param bool $reset Optional. Whether to reset the encoding back to a previously-set encoding.
public static function mbstring_binary_safe_encoding($reset = false) {
static $encodings = array();
static $overloaded = null;
if (is_null($overloaded)) {
// phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated
$overloaded = function_exists('mb_internal_encoding') && (ini_get('mbstring.func_overload') & 2);
if (false === $overloaded) { return; }
$encoding = mb_internal_encoding();
array_push($encodings, $encoding);
mb_internal_encoding('ISO-8859-1');
if ($reset && $encodings) {
$encoding = array_pop($encodings);
mb_internal_encoding($encoding);
* Reset the mbstring internal encoding to a users previously set encoding.
* @see wfWAFUtils::mbstring_binary_safe_encoding
public static function reset_mbstring_encoding() {
self::mbstring_binary_safe_encoding(true);
* @param callable $function
protected static function callMBSafeStrFunction($function, $args) {
self::mbstring_binary_safe_encoding();
$return = call_user_func_array($function, $args);
self::reset_mbstring_encoding();
public static function strlen($binary) {
return self::callMBSafeStrFunction('strlen', $args);
public static function stripos($haystack, $needle, $offset = 0) {
return self::callMBSafeStrFunction('stripos', $args);
public static function strtolower($string) {
return self::callMBSafeStrFunction('strtolower', $args);
public static function substr($string, $start, $length = null) {
if ($length === null) { $length = self::strlen($string); }
return self::callMBSafeStrFunction('substr', array(
public static function strpos($haystack, $needle, $offset = 0) {
return self::callMBSafeStrFunction('strpos', $args);
* @param string $haystack
public static function substr_count($haystack, $needle, $offset = 0, $length = null) {
if ($length === null) { $length = self::strlen($haystack); }
return self::callMBSafeStrFunction('substr_count', array(
$haystack, $needle, $offset, $length
public static function strtoupper($string) {
return self::callMBSafeStrFunction('strtoupper', $args);
* @param string $haystack
public static function strrpos($haystack, $needle, $offset = 0) {
return self::callMBSafeStrFunction('strrpos', $args);
public static function sets_equal($a1, $a2) {
if (!is_array($a1) || !is_array($a2)) {
if (count($a1) != count($a2)) {
public static function array_first($array) {
$values = array_values($array);
public static function array_last($array) {
$values = array_values($array);
return $values[count($values) - 1];
public static function array_strtolower($array) {
$result[] = strtolower($a);
* Convenience function to return the value in an array or the given default if not present.
public static function array_choose($array, $key, $default = null) {
if (isset($array[$key])) {
public static function array_column($input = null, $columnKey = null, $indexKey = null) { //Polyfill from https://github.com/ramsey/array_column/blob/master/src/array_column.php
$params = func_get_args();
trigger_error("array_column() expects at least 2 parameters, {$argc} given", E_USER_WARNING);
if (!is_array($params[0])) {
'array_column() expects parameter 1 to be array, ' . gettype($params[0]) . ' given',
if (!is_int($params[1]) && !is_float($params[1]) && !is_string($params[1]) && $params[1] !== null && !(is_object($params[1]) && method_exists($params[1], '__toString'))) {
trigger_error('array_column(): The column key should be either a string or an integer', E_USER_WARNING);
if (isset($params[2]) && !is_int($params[2]) && !is_float($params[2]) && !is_string($params[2]) && !(is_object($params[2]) && method_exists($params[2], '__toString'))) {
trigger_error('array_column(): The index key should be either a string or an integer', E_USER_WARNING);
$paramsInput = $params[0];
$paramsColumnKey = ($params[1] !== null) ? (string) $params[1] : null;
if (is_float($params[2]) || is_int($params[2])) {
$paramsIndexKey = (int) $params[2];
$paramsIndexKey = (string) $params[2];
foreach ($paramsInput as $row) {
$keySet = $valueSet = false;
if ($paramsIndexKey !== null && array_key_exists($paramsIndexKey, $row)) {
$key = (string) $row[$paramsIndexKey];
if ($paramsColumnKey === null) {
elseif (is_array($row) && array_key_exists($paramsColumnKey, $row)) {
$value = $row[$paramsColumnKey];
$resultArray[$key] = $value;
* Returns $string if it isn't empty, $ifEmpty if it is.
public static function string_empty($string, $ifEmpty) {
* Returns the current timestamp, adjusted as needed to get close to what we consider a true timestamp. We use this
* because a significant number of servers are using a drastically incorrect time.
public static function normalizedTime($base = false) {
$offset = (int) wfConfig::get('timeoffset_wf', 0);
* Returns what we consider a true timestamp, adjusted as needed to match the local server's drift. We use this
* because a significant number of servers are using a drastically incorrect time.
public static function denormalizedTime($base) {
$offset = (int) wfConfig::get('timeoffset_wf', 0);
* Returns the number of minutes for the time zone offset from UTC. If $timestamp and using a named time zone,
* it will be adjusted automatically to match whether or not the server's time zone is in Daylight Savings Time.
* @param bool|int $timestamp Assumed to be in UTC. If false, defaults to the current timestamp.
public static function timeZoneMinutes($timestamp = false) {
if ($timestamp === false) {
$tz = get_option('timezone_string');