| Current Path : /home2/noxxprod/www/wp-content/plugins/cleantalk-spam-protect/lib/Cleantalk/Common/ |
| Current File : //home2/noxxprod/www/wp-content/plugins/cleantalk-spam-protect/lib/Cleantalk/Common/Helper.php |
<?php
namespace Cleantalk\Common;
use Cleantalk\Common\HTTP\Request;
use Cleantalk\Templates\Singleton;
use Cleantalk\ApbctWP\Variables\Server;
/**
* CleanTalk Helper class.
* Compatible with any CMS.
*
* @package PHP Anti-Spam by CleanTalk
* @subpackage Helper
* @Version 4.0
* @author Cleantalk team (welcome@cleantalk.org)
* @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
* @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
* @see https://github.com/CleanTalk/php-antispam
*/
class Helper
{
use Singleton;
/**
* Default user agent for HTTP requests
*/
const AGENT = 'Cleantalk-Helper/4.0';
/**
* @var array Set of private networks IPv4 and IPv6
*/
public static $private_networks = array(
'v4' => array(
'10.0.0.0/8',
'100.64.0.0/10',
'172.16.0.0/12',
'192.168.0.0/16',
'127.0.0.1/32',
),
'v6' => array(
'0:0:0:0:0:0:0:1/128', // localhost
'0:0:0:0:0:0:a:1/128', // ::ffff:127.0.0.1
),
);
/**
* @var array Stored IPs
* [
* [ type ] => IP,
* [ type ] => IP,
* ]
*/
private $ips_stored = array();
/**
* @var array Stored HTTP headers
*/
private $headers = array();
/**
* Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip)
*
* @param string $ip_type_to_get Type of IP you want to receive
* @param bool $v4_only
*
* @return string|null
*
* @psalm-suppress InvalidReturnStatement
* @psalm-suppress ComplexMethod
* @psalm-suppress FalsableReturnStatement
*/
public static function ipGet($ip_type_to_get = 'real', $v4_only = true, $headers = array())
{
// If return the IP of the current type if it already has been detected
$ips_stored = self::getInstance()->ips_stored;
if ( ! empty($ips_stored[ $ip_type_to_get ]) ) {
return $ips_stored[ $ip_type_to_get ];
}
$out = null;
switch ($ip_type_to_get) {
// Cloud Flare
case 'cloud_flare':
$headers = $headers ?: self::httpGetHeaders();
if (
isset($headers['Cf-Connecting-Ip']) &&
(isset($headers['Cf-Ray']) || isset($headers['X-Wpe-Request-Id'])) &&
! isset($headers['X-Gt-Clientip'])
) {
if (isset($headers['Cf-Pseudo-Ipv4'], $headers['Cf-Pseudo-Ipv6'])) {
$source = $headers['Cf-Pseudo-Ipv6'];
} else {
$source = $headers['Cf-Connecting-Ip'];
}
$tmp = strpos($source, ',') !== false
? explode(',', $source)
: (array)$source;
if ( isset($tmp[0]) ) {
$ip_version = self::ipValidate(trim($tmp[0]));
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only
? self::ipV6Normalize(trim($tmp[0]))
: trim($tmp[0]);
}
}
}
break;
// GTranslate
case 'gtranslate':
$headers = $headers ?: self::httpGetHeaders();
if (isset($headers['X-Gt-Clientip'], $headers['X-Gt-Viewer-Ip'])) {
$ip_version = self::ipValidate($headers['X-Gt-Viewer-Ip']);
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only ? self::ipV6Normalize(
$headers['X-Gt-Viewer-Ip']
) : $headers['X-Gt-Viewer-Ip'];
}
}
break;
// ezoic
case 'ezoic':
$headers = $headers ?: self::httpGetHeaders();
if (isset($headers['X-Middleton'], $headers['X-Middleton-Ip'])) {
$ip_version = self::ipValidate($headers['X-Middleton-Ip']);
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only ? self::ipV6Normalize(
$headers['X-Middleton-Ip']
) : $headers['X-Middleton-Ip'];
}
}
break;
// Sucury
case 'sucury':
$headers = $headers ?: self::httpGetHeaders();
if (isset($headers['X-Sucuri-Clientip'])) {
$ip_version = self::ipValidate($headers['X-Sucuri-Clientip']);
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only ? self::ipV6Normalize(
$headers['X-Sucuri-Clientip']
) : $headers['X-Sucuri-Clientip'];
}
}
break;
// X-Forwarded-By
case 'x_forwarded_by':
$headers = $headers ?: self::httpGetHeaders();
if (isset($headers['X-Forwarded-By'], $headers['X-Client-Ip'])) {
$ip_version = self::ipValidate($headers['X-Client-Ip']);
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only ? self::ipV6Normalize(
$headers['X-Client-Ip']
) : $headers['X-Client-Ip'];
}
}
break;
// Stackpath
case 'stackpath':
$headers = $headers ?: self::httpGetHeaders();
if (isset($headers['X-Sp-Edge-Host'], $headers['X-Sp-Forwarded-Ip'])) {
$ip_version = self::ipValidate($headers['X-Sp-Forwarded-Ip']);
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only ? self::ipV6Normalize(
$headers['X-Sp-Forwarded-Ip']
) : $headers['X-Sp-Forwarded-Ip'];
}
}
break;
// Ico-X-Forwarded-For
case 'ico_x_forwarded_for':
$headers = $headers ?: self::httpGetHeaders();
if (isset($headers['Ico-X-Forwarded-For'], $headers['X-Forwarded-Host'])) {
$ip_version = self::ipValidate($headers['Ico-X-Forwarded-For']);
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only ? self::ipV6Normalize(
$headers['Ico-X-Forwarded-For']
) : $headers['Ico-X-Forwarded-For'];
}
}
break;
// OVH
case 'ovh':
$headers = $headers ?: self::httpGetHeaders();
if (isset($headers['X-Cdn-Any-Ip'], $headers['Remote-Ip'])) {
$ip_version = self::ipValidate($headers['Remote-Ip']);
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only ? self::ipV6Normalize(
$headers['Remote-Ip']
) : $headers['Remote-Ip'];
}
}
break;
// Incapsula proxy
case 'incapsula':
$headers = $headers ?: self::httpGetHeaders();
if (isset($headers['Incap-Client-Ip'], $headers['X-Forwarded-For'])) {
$ip_version = self::ipValidate($headers['Incap-Client-Ip']);
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only ? self::ipV6Normalize(
$headers['Incap-Client-Ip']
) : $headers['Incap-Client-Ip'];
}
}
break;
// Incapsula proxy like "X-Clientside":"10.10.10.10:62967 -> 192.168.1.1:443"
case 'clientside':
$headers = $headers ?: self::httpGetHeaders();
if (
isset($headers['X-Clientside'])
&& (preg_match('/^([0-9a-f.:]+):\d+ -> ([0-9a-f.:]+):\d+$/', $headers['X-Clientside'], $matches)
&& isset($matches[1]))
) {
$ip_version = self::ipValidate($matches[1]);
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only ? self::ipV6Normalize($matches[1]) : $matches[1];
}
}
break;
// Remote addr
case 'remote_addr':
$ip_version = self::ipValidate(Server::getString('REMOTE_ADDR'));
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only ? self::ipV6Normalize(
Server::getString('REMOTE_ADDR')
) : Server::getString('REMOTE_ADDR');
}
break;
// X-Forwarded-For
case 'x_forwarded_for':
$headers = $headers ?: self::httpGetHeaders();
if (isset($headers['X-Forwarded-For'])) {
$tmp = explode(',', trim($headers['X-Forwarded-For']));
$tmp = trim($tmp[0]);
$ip_version = self::ipValidate($tmp);
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only ? self::ipV6Normalize($tmp) : $tmp;
}
}
break;
// X-Real-Ip
case 'x_real_ip':
$headers = $headers ?: self::httpGetHeaders();
if (isset($headers['X-Real-Ip'])) {
$tmp = explode(",", trim($headers['X-Real-Ip']));
$tmp = trim($tmp[0]);
$ip_version = self::ipValidate($tmp);
if ($ip_version) {
$out = $ip_version === 'v6' && ! $v4_only ? self::ipV6Normalize($tmp) : $tmp;
}
}
break;
// Real
// Getting real IP from REMOTE_ADDR or Cf_Connecting_Ip if set or from (X-Forwarded-For, X-Real-Ip) if REMOTE_ADDR is local.
case 'real':
// Detect IP type
$out = self::ipGet('cloud_flare', $v4_only, $headers);
$out = $out ?: self::ipGet('sucury', $v4_only, $headers);
$out = $out ?: self::ipGet('gtranslate', $v4_only, $headers);
$out = $out ?: self::ipGet('ezoic', $v4_only, $headers);
$out = $out ?: self::ipGet('stackpath', $v4_only, $headers);
$out = $out ?: self::ipGet('x_forwarded_by', $v4_only, $headers);
$out = $out ?: self::ipGet('ico_x_forwarded_for', $v4_only, $headers);
$out = $out ?: self::ipGet('ovh', $v4_only, $headers);
$out = $out ?: self::ipGet('incapsula', $v4_only, $headers);
$out = $out ?: self::ipGet('clientside', $v4_only, $headers);
$ip_version = self::ipValidate($out);
// Is private network
if (
! $out ||
(
is_string($ip_version) && (
self::ipIsPrivateNetwork($out, $ip_version) ||
(
$ip_version === self::ipValidate(Server::getString('SERVER_ADDR')) &&
self::ipMaskMatch($out, Server::getString('SERVER_ADDR') . '/24', $ip_version)
)
)
)
) {
//@todo Remove local IP from x-forwarded-for and x-real-ip
$out = $out ?: self::ipGet('x_forwarded_for', $v4_only, $headers);
$out = $out ?: self::ipGet('x_real_ip', $v4_only, $headers);
}
$out = $out ?: self::ipGet('remote_addr', $v4_only, $headers);
break;
default:
$out = self::ipGet('real', $v4_only, $headers);
}
if ( is_string($out) ) {
$ip_version = self::ipValidate($out);
if ( ! $ip_version ) {
$out = null;
}
if ( $ip_version === 'v6' && $v4_only ) {
$out = null;
}
}
// Store the IP of the current type to skip the work next time
self::getInstance()->ips_stored[ $ip_type_to_get ] = $out;
return $out;
}
/**
* Checks if the IP is in private range
*
* @param string $ip
* @param string $ip_type
*
* @return bool
*/
public static function ipIsPrivateNetwork($ip, $ip_type = 'v4')
{
return self::ipMaskMatch($ip, self::$private_networks[$ip_type], $ip_type);
}
/**
* Check if the IP belong to mask. Recursive.
* Octet by octet for IPv4
* Hextet by hextet for IPv6
*
* @param string $ip
* @param string|array $cidr work to compare with
* @param string $ip_type IPv6 or IPv4
* @param int $xtet_count Recursive counter. Determs current part of address to check.
*
* @return bool
* @psalm-suppress InvalidScalarArgument
*/
public static function ipMaskMatch($ip, $cidr, $ip_type = 'v4', $xtet_count = 0)
{
if (is_array($cidr)) {
foreach ($cidr as $curr_mask) {
if (self::ipMaskMatch($ip, $curr_mask, $ip_type)) {
return true;
}
}
return false;
}
if ( ! self::ipValidate($ip) || ! self::cidrValidate($cidr) ) {
return false;
}
$xtet_base = ($ip_type === 'v4') ? 8 : 16;
// Calculate mask
$exploded = explode('/', $cidr);
if ( ! isset($exploded[0], $exploded[1]) ) {
return false;
}
$net_ip = $exploded[0];
$mask = (int)$exploded[1];
// Exit condition
$xtet_end = ceil($mask / $xtet_base);
if ($xtet_count == $xtet_end) {
return true;
}
// Length of bits for comparison
$mask = $mask - $xtet_base * $xtet_count >= $xtet_base ? $xtet_base : $mask - $xtet_base * $xtet_count;
// Explode by octets/hextets from IP and Net
$net_ip_xtets = explode($ip_type === 'v4' ? '.' : ':', $net_ip);
$ip_xtets = explode($ip_type === 'v4' ? '.' : ':', $ip);
// Standartizing. Getting current octets/hextets. Adding leading zeros.
$net_xtet = str_pad(
decbin(
($ip_type === 'v4' && (int)$net_ip_xtets[$xtet_count]) ? $net_ip_xtets[$xtet_count] : @hexdec(
$net_ip_xtets[$xtet_count]
)
),
$xtet_base,
0,
STR_PAD_LEFT
);
$ip_xtet = str_pad(
decbin(
($ip_type === 'v4' && (int)$ip_xtets[$xtet_count]) ? $ip_xtets[$xtet_count] : @hexdec(
$ip_xtets[$xtet_count]
)
),
$xtet_base,
0,
STR_PAD_LEFT
);
// Comparing bit by bit
for ($i = 0, $result = true; $mask != 0; $mask--, $i++) {
if ($ip_xtet[$i] != $net_xtet[$i]) {
$result = false;
break;
}
}
// Recursing. Moving to next octet/hextet.
if ($result) {
$result = self::ipMaskMatch($ip, $cidr, $ip_type, $xtet_count + 1);
}
return $result;
}
/**
* Converts long mask like 4294967295 to number like 32
*
* @param int $long_mask
*
* @return int
* @psalm-suppress PossiblyUnusedMethod
*/
public static function ipMaskLongToNumber($long_mask)
{
$num_mask = strpos(decbin($long_mask), '0');
return $num_mask === false ? 32 : $num_mask;
}
/**
* Validating IPv4, IPv6
*
* @param string|null|false $ip
*
* @return string|bool
*/
public static function ipValidate($ip)
{
if ( ! $ip ) { // NULL || FALSE || '' || so on...
return false;
}
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && $ip != '0.0.0.0') { // IPv4
return 'v4';
}
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && self::ipV6Reduce($ip) != '0::0') { // IPv6
return 'v6';
}
return false; // Unknown
}
/**
* Validate CIDR
*
* @param string $cidr expects string like 1.1.1.1/32
*
* @return bool
*/
public static function cidrValidate($cidr)
{
$cidr = explode('/', $cidr);
return isset($cidr[0], $cidr[1]) && self::ipValidate($cidr[0]) && preg_match('@\d{1,2}@', $cidr[1]);
}
/**
* Expand IPv6
*
* @param string $ip
*
* @return string IPv6
*/
public static function ipV6Normalize($ip)
{
$ip = trim($ip);
// Searching for ::ffff:xx.xx.xx.xx patterns and turn it to IPv6
if (preg_match('/^::ffff:([0-9]{1,3}\.?){4}$/', $ip)) {
$ip = dechex((int)sprintf("%u", ip2long(substr($ip, 7))));
$ip = '0:0:0:0:0:0:' . (strlen($ip) > 4 ? substr('abcde', 0, -4) : '0') . ':' . substr($ip, -4, 4);
// Normalizing hextets number
} elseif (strpos($ip, '::') !== false) {
$ip = str_replace('::', str_repeat(':0', 8 - substr_count($ip, ':')) . ':', $ip);
$ip = strpos($ip, ':') === 0 ? '0' . $ip : $ip;
$ip = strpos(strrev($ip), ':') === 0 ? $ip . '0' : $ip;
}
// Simplifyng hextets
if (preg_match('/:0(?=[a-z0-9]+)/', $ip)) {
$ip = preg_replace('/:0(?=[a-z0-9]+)/', ':', strtolower($ip));
$ip = self::ipV6Normalize($ip);
}
return $ip;
}
/**
* Reduce IPv6
*
* @param string $ip
*
* @return string IPv6
*/
public static function ipV6Reduce($ip)
{
if (strpos($ip, ':') !== false) {
$ip = preg_replace('/:0{1,4}/', ':', $ip);
$ip = preg_replace('/:{2,}/', '::', $ip);
$ip = strpos($ip, '0') === 0 && substr($ip, 1) !== false ? substr($ip, 1) : $ip;
}
return $ip;
}
/**
* Get URL form IP
*
* @param $ip
*
* @return string
*/
public static function ipResolve($ip)
{
if (self::ipValidate($ip)) {
$url = gethostbyaddr($ip);
if ($url) {
return $url;
}
}
return $ip;
}
/**
* Resolve DNS to IP
*
* @param $host
* @param bool $out
*
* @return bool
* @psalm-suppress PossiblyUnusedMethod
*/
public static function dnsResolve($host, $out = false)
{
// Check if the $url is set and it is an url
if ( ! $host || ! filter_var($host, FILTER_VALIDATE_URL)) {
return $out;
}
// Get DNS records about URL
if (function_exists('dns_get_record')) {
$records = dns_get_record($host, DNS_A);
if ($records !== false && isset($records[0]['ip'])) {
$out = $records[0]['ip'];
}
}
// Another try if first failed
if ( ! $out && function_exists('gethostbynamel')) {
$records = gethostbynamel($host);
if ($records !== false && isset($records[0])) {
$out = $records[0];
}
}
return $out;
}
/**
* Function sends raw http request
*
* May use 4 presets(combining possible):
* get_code - getting only HTTP response code
* async - async requests
* get - GET-request
* ssl - use SSL
*
* @param string|array<string> $url URL
* @param array|string|int $data POST|GET indexed array with data to send
* @param string|array $presets String or Array with presets: get_code, async, get, ssl, dont_split_to_array
* @param array $opts Optional option for CURL connection
*
* @return array|bool|string (array || array('error' => true))
*/
public static function httpRequest($url, $data = array(), $presets = array(), $opts = array())
{
$http = new Request();
return $http->setUrl($url)
->setData($data)
->setPresets($presets)
->setOptions($opts)
->request();
}
/**
* Do multi curl requests.
*
* @param array $urls Array of URLs to requests
*
* @return array|bool
*/
public static function httpMultiRequest($urls, $write_to = '')
{
if ( ! is_array($urls) || empty($urls)) {
return array('error' => 'CURL_MULTI: Parameter is not an array.');
}
foreach ($urls as $url) {
if ( ! is_string($url)) {
return array('error' => 'CURL_MULTI: Parameter elements must be strings.');
}
}
$http = new Request();
$http->setUrl($urls)
->setPresets('get');
if ( $write_to ) {
$http->addCallback(
static function ($content, $url) use ($write_to) {
if ( is_dir($write_to) && is_writable($write_to) ) {
return file_put_contents($write_to . self::getFilenameFromUrl($url), $content)
? 'success'
: 'error';
}
return $content;
}
);
}
return $http->request();
}
/**
* Merging arrays without resetting numeric keys
*
* @param array $arr1 One-dimensional array
* @param array $arr2 One-dimensional array
*
* @return array Merged array
*/
public static function arrayMergeSaveNumericKeys($arr1, $arr2)
{
foreach ($arr2 as $key => $val) {
$arr1[$key] = $val;
}
return $arr1;
}
/**
* Merging arrays without reseting numeric keys recursive
*
* @param array $arr1 One-dimentional array
* @param array $arr2 One-dimentional array
*
* @return array Merged array
* @psalm-suppress PossiblyUnusedMethod
*/
public static function arrayMergeSaveNumericKeysRecursive($arr1, $arr2)
{
foreach ($arr2 as $key => $val) {
// Array | array => array
if (isset($arr1[$key]) && is_array($arr1[$key]) && is_array($val)) {
$arr1[$key] = self::arrayMergeSaveNumericKeysRecursive($arr1[$key], $val);
// Scalar | array => array
} elseif (isset($arr1[$key]) && ! is_array($arr1[$key]) && is_array($val)) {
$tmp = $arr1[$key] =
$arr1[$key] = $val;
$arr1[$key][] = $tmp;
// array | scalar => array
} elseif (isset($arr1[$key]) && is_array($arr1[$key]) && ! is_array($val)) {
$arr1[$key][] = $val;
// scalar | scalar => scalar
} else {
$arr1[$key] = $val;
}
}
return $arr1;
}
/**
* Compare two arrays keys to find if there are difference. Recursive.
* @param array $f_array First array
* @param array $s_array Second array
* @return bool True if arrays keys has difference, false otherwise.
*/
public static function arraysHasKeysDifferenceRecursive($f_array, $s_array)
{
$difference = array_diff_key($f_array, $s_array);
if ( !empty($difference) ) {
return true;
}
foreach ( $f_array as $f_key => $f_value ) {
if ( is_array($f_value) && is_array($s_array[$f_key]) ) {
$new_difference = self::arraysHasKeysDifferenceRecursive($f_value, $s_array[$f_key]);
if ( !empty($new_difference) ) {
return true;
}
}
}
return false;
}
/**
* Function removing non UTF8 characters from array|string|object
*
* @param array|object|string $data
*
* @return array|object|string
*/
public static function removeNonUTF8($data)
{
// Array || object
if (is_array($data) || is_object($data)) {
foreach ($data as $_key => &$val) {
$val = self::removeNonUTF8($val);
}
unset($val);
//String
} else {
if ( ! preg_match('//u', $data)) {
$data = 'Nulled. Not UTF8 encoded or malformed.';
}
}
return $data;
}
/**
* Function convert anything to UTF8 and removes non UTF8 characters
*
* @param array|object|string $obj
* @param null|string $data_codepage
*
* @return array|false|mixed|string|string[]|null
*/
public static function toUTF8($obj, $data_codepage = null)
{
// Array || object
if (is_array($obj) || is_object($obj)) {
foreach ($obj as $_key => &$val) {
$val = self::toUTF8($val, $data_codepage);
}
unset($val);
//String
} else {
if ( ! preg_match('//u', $obj) ) {
if ( function_exists('mb_detect_encoding') ) {
$encoding = mb_detect_encoding($obj);
$encoding = $encoding ?: $data_codepage;
} else {
$encoding = $data_codepage;
}
if ($encoding) {
if ( function_exists('mb_convert_encoding') ) {
$obj = mb_convert_encoding($obj, 'UTF-8', $encoding);
} elseif (version_compare(phpversion(), '8.3', '<')) {
$obj = @utf8_encode($obj);
}
}
}
}
return $obj;
}
/**
* Function convert from UTF8
*
* @param array|object|string $obj
* @param string $data_codepage
*
* @return mixed (array|object|string)
*/
public static function fromUTF8($obj, $data_codepage = null)
{
// Array || object
if (is_array($obj) || is_object($obj)) {
foreach ($obj as $_key => &$val) {
$val = self::fromUTF8($val, $data_codepage);
}
unset($val);
//String
} else {
if ($data_codepage !== null && preg_match('//u', $obj)) {
if ( function_exists('mb_convert_encoding') ) {
$obj = mb_convert_encoding($obj, $data_codepage, 'UTF-8');
} elseif (version_compare(phpversion(), '8.3', '<')) {
$obj = @utf8_decode($obj);
}
}
}
return $obj;
}
/**
* Checks if the string is JSON type
*
* @param string $string
*
* @return bool
* @psalm-suppress PossiblyUnusedMethod
*/
public static function isJson($string)
{
return is_string($string) && is_array(json_decode($string, true));
}
/**
* @param int $interval
*
* @return int
* @psalm-suppress PossiblyUnusedMethod
*/
public static function timeGetIntervalStart($interval = 300)
{
return time() - ((time() - strtotime(date('d F Y'))) % $interval);
}
/**
* Get mime type from file or data
*
* @param string $data Path to file or data
* @param string $type Default mime type. Returns if we failed to detect type
*
* @return string
* @psalm-suppress PossiblyUnusedMethod
*/
public static function getMimeType($data, $type = '')
{
$data = str_replace(chr(0), '', $data); // Clean input of null bytes
if ( ! empty($data) && @file_exists($data)) {
$type = mime_content_type($data);
} elseif (function_exists('finfo_open')) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$type = finfo_buffer($finfo, $data);
finfo_close($finfo);
}
// @ToDo the method must return comparison result: return $type === mime_content_type($data)
return $type;
}
public static function bufferTrimAndClearFromEmptyLines($buffer)
{
$buffer = (array)$buffer;
foreach ($buffer as $indx => &$line) {
$line = trim($line);
if ($line === '') {
unset($buffer[$indx]);
}
}
return $buffer;
}
/**
* @param $buffer
*
* @return array
* @psalm-suppress PossiblyUnusedMethod
*/
public static function bufferParseCsv($buffer)
{
$buffer = explode("\n", $buffer);
$buffer = self::bufferTrimAndClearFromEmptyLines($buffer);
foreach ($buffer as &$line) {
$line = str_getcsv($line, ',', '\'');
}
return $buffer;
}
/**
* Pops line from buffer without formatting
*
* @param string $csv
*
* @return string
*/
public static function bufferCsvPopLine(&$csv)
{
$pos = (int) strpos($csv, "\n");
$line = substr($csv, 0, $pos);
$csv = substr_replace($csv, '', 0, $pos + 1);
return $line;
}
/**
* Pops line from the csv buffer and format it by map to array
*
* @param string $csv
*
* @return array
* @psalm-suppress PossiblyUnusedMethod
*/
public static function bufferCsvGetMap(&$csv)
{
$line = static::bufferCsvPopLine($csv);
return explode(',', $line);
}
/**
* Pops line from the csv buffer and format it by map to array
*
* @param $csv
* @param array $map
*
* @return array
* @psalm-suppress PossiblyUnusedMethod
*/
public static function bufferCsvPopLineToArray(&$csv, $map = array())
{
$line = trim(static::bufferCsvPopLine($csv));
$line = strpos($line, '\'') === 0
? str_getcsv($line, ',', '\'')
: explode(',', $line);
if ($map) {
$line = array_combine($map, $line);
}
return $line;
}
/**
* Escapes MySQL params
*
* @param string|int|array $param
* @param string $quotes
*
* @return int|string|array
* @psalm-suppress PossiblyUnusedMethod
*/
public static function dbPrepareParam($param, $quotes = '\'')
{
global $wpdb;
if (is_array($param)) {
foreach ($param as &$par) {
$par = self::dbPrepareParam($par);
}
unset($par);
}
switch (true) {
case is_numeric($param):
$param = (int)$param;
break;
case is_string($param) && strtolower($param) === 'null':
$param = 'NULL';
break;
case is_string($param):
$param = $quotes . $wpdb->_real_escape($param) . $quotes;
break;
}
return $param;
}
/**
* Gets every HTTP_ headers from $_SERVER
*
* If Apache web server is missing then making
* Patch for apache_request_headers()
*
* returns array
*/
public static function httpGetHeaders()
{
// If headers already return them
$headers = self::getInstance()->headers;
if ( ! empty($headers) ) {
return $headers;
}
foreach ($_SERVER as $key => $val) {
if (0 === stripos($key, 'http_')) {
$server_key = preg_replace('/^http_/i', '', $key);
$key_parts = explode('_', $server_key);
if (strlen($server_key) > 2) {
foreach ($key_parts as $part_index => $part) {
if ($part === '') {
continue;
}
$key_parts[$part_index] = function_exists('mb_strtolower') ? mb_strtolower(
$part
) : strtolower(
$part
);
$key_parts[$part_index][0] = strtoupper($key_parts[$part_index][0]);
}
$server_key = implode('-', $key_parts);
}
$headers[$server_key] = $val;
}
}
// Store headers to skip the work next time
self::getInstance()->headers = $headers;
return $headers;
}
/**
* Its own implementation of the native method long2ip()
*
* @return string
* @psalm-suppress PossiblyUnusedMethod
*/
public static function ipLong2ip($ipl32)
{
$ip = [];
$ip[0] = ($ipl32 >> 24) & 255;
$ip[1] = ($ipl32 >> 16) & 255;
$ip[2] = ($ipl32 >> 8) & 255;
$ip[3] = $ipl32 & 255;
return implode('.', $ip);
}
/**
* @param $url string
*
* @return string
*/
protected static function getFilenameFromUrl($url)
{
$array = explode('/', $url);
return end($array);
}
/**
* Validate date format Y-m-d
*
* @return boolean
*/
public static function dateValidate($date)
{
$date_arr = explode('-', $date);
if (count($date_arr) === 3) {
if (checkdate((int)$date_arr[1], (int)$date_arr[2], (int)$date_arr[0])) {
return true;
}
}
return false;
}
}