Skip to content

Instantly share code, notes, and snippets.

@ArrayIterator
Last active February 12, 2020 17:54
Show Gist options
  • Save ArrayIterator/9d179cdf7adedaca3e90dbb5d73e43d2 to your computer and use it in GitHub Desktop.
Save ArrayIterator/9d179cdf7adedaca3e90dbb5d73e43d2 to your computer and use it in GitHub Desktop.
PHP Response Generator , Simple Token Generator & User-Agent Helper
{
"require": {
"php": "^7.2",
"ext-json": "*",
"ext-openssl": "*",
"psr/http-message": "^1.0"
}
}
<?php
declare(strict_types=1);
namespace ArrayIterator\Library\Source\Generator;
use InvalidArgumentException;
use RangeException;
use TypeError;
/**
* Class DesktopUserAgent
* @package ArrayIterator\Library\Source\Generator
*
* Generate Desktop User Agent By Random
*/
class DesktopUserAgent
{
const VERSION_LATEST = 'latest';
const MAX_ITERATION = 20;
const MIN_ITERATION = 3;
const DEFAULT_ITERATION = 5;
const MOZ_COMPAT = 'Mozilla/5.0';
const OS_LINUX = 'linux';
const OS_WIN = 'win';
const OS_MAC = 'mac';
const BROWSER_CHROME = 'chrome';
const BROWSER_IE = 'ie';
const BROWSER_EDGE = 'edge';
const BROWSER_FIREFOX = 'firefox';
const BROWSER_SAFARI = 'safari';
const BROWSER_OPERA = 'opera';
/* -----------------------------------------------
* BROWSER MINIMUM & MAXIMUM VERSION
* @link https://updatemybrowser.org/
* -----------------------------------------------
*/
// max IE is version 11
const MAX_VERSION_IE = 11;
const MIN_VERSION_IE = 9;
// EDGE
const MAX_VERSION_EDGE = 18;
const MIN_VERSION_EDGE = 12;
// CHROME
const MAX_VERSION_CHROME = 80;
const MIN_VERSION_CHROME = 60;
// FIREFOX
const MAX_VERSION_FIREFOX = 72;
const MIN_VERSION_FIREFOX = 50;
// OPERA
const MAX_VERSION_OPERA = 66;
const MIN_VERSION_OPERA = 40;
// https://www.whatismybrowser.com/guides/the-latest-version/safari
const MAX_VERSION_SAFARI_WINDOWS = 5.17;
const MAX_VERSION_SAFARI = 13;
const MIN_VERSION_SAFARI = 6;
/* -----------------------------------------------
* MAC OS VERSION
* https://support.apple.com/en-au/HT201260
* -----------------------------------------------
*/
const VERSION_MAC_OS_CHEETAH = '10.0';
const VERSION_MAC_OS_PUMA = '10.1';
const VERSION_MAC_OS_JAGUAR = '10.2';
const VERSION_MAC_OS_PANTHER = '10.3';
const VERSION_MAC_OS_TIGER = '10.4';
const VERSION_MAC_OS_LEOPARD = '10.5';
const VERSION_MAC_OS_SNOW_LEOPARD = '10.6';
const VERSION_MAC_OS_LION = '10.7';
const VERSION_MAC_OS_MOUNTAIN_LION = '10.8';
const VERSION_MAC_OS_MAVERICKS = '10.9';
const VERSION_MAC_OS_YOSEMITE = '10.10';
const VERSION_MAC_OS_ELCAPITAN = '10.11';
const VERSION_MAC_OS_SIERRA = '10.12';
const VERSION_MAC_OS_HIGH_SIERRA = '10.13';
const VERSION_MAC_OS_MOJAVE = '10.14';
const VERSION_MAC_OS_CATALINA = '10.15';
const MAC_OS_DELIMITER = '_';
protected $minMacOSVersion = self::VERSION_MAC_OS_PANTHER;
protected $maxMacOSVersion = self::VERSION_MAC_OS_CATALINA;
/**
* MacOS version prefix 10
* @todo update regularly
* @link https://support.apple.com/en-au/HT201260
* @var array|int[]
*/
protected $macOSMaxVersionLists = [
self::VERSION_MAC_OS_CHEETAH => 4,
self::VERSION_MAC_OS_PUMA => 5,
self::VERSION_MAC_OS_JAGUAR => 5,
self::VERSION_MAC_OS_PANTHER => 8,
self::VERSION_MAC_OS_TIGER => 11,
self::VERSION_MAC_OS_LEOPARD => 8,
self::VERSION_MAC_OS_SNOW_LEOPARD => 8,
self::VERSION_MAC_OS_LION => 5,
self::VERSION_MAC_OS_MOUNTAIN_LION => 5,
self::VERSION_MAC_OS_MAVERICKS => 5,
self::VERSION_MAC_OS_YOSEMITE => 5,
self::VERSION_MAC_OS_ELCAPITAN => 6,
self::VERSION_MAC_OS_SIERRA => 6,
self::VERSION_MAC_OS_HIGH_SIERRA => 6,
self::VERSION_MAC_OS_MOJAVE => 6,
self::VERSION_MAC_OS_CATALINA => 2,
];
/**
* @var array
*/
private $versionMinMax = [
self::BROWSER_CHROME => [
self::MIN_VERSION_CHROME,
self::MAX_VERSION_CHROME
],
self::BROWSER_IE => [
// default is 9
self::MIN_VERSION_IE,
self::MAX_VERSION_IE
],
self::BROWSER_FIREFOX => [
self::MIN_VERSION_FIREFOX,
self::MAX_VERSION_FIREFOX
],
self::BROWSER_SAFARI => [
self::MIN_VERSION_SAFARI,
self::MAX_VERSION_SAFARI
],
self::BROWSER_OPERA => [
self::MIN_VERSION_OPERA,
self::MAX_VERSION_OPERA
],
self::BROWSER_EDGE => [
self::MIN_VERSION_EDGE,
self::MAX_VERSION_EDGE
],
];
/**
* Iteration for array rand
* @var int
*/
protected $randomizeIteration = 5;
/**
* @var array
*/
protected $processors = [
self::OS_LINUX => [
'i686',
'x86_64'
],
self::OS_MAC => [
'Intel',
'PPC',
'U; Intel',
'U; PPC'
],
self::OS_WIN => [
'',
'WOW64',
'Win64; x64'
]
];
/**
* @var array
*/
protected $lang = [
'AB', 'AF', 'AN', 'AR', 'AS', 'AZ', 'BE', 'BG', 'BN', 'BO', 'BR', 'BS', 'CA', 'CE', 'CO', 'CS',
'CU', 'CY', 'DA', 'DE', 'EL', 'EN', 'EO', 'ES', 'ET', 'EU', 'FA', 'FI', 'FJ', 'FO', 'FR', 'FY',
'GA', 'GD', 'GL', 'GV', 'HE', 'HI', 'HR', 'HT', 'HU', 'HY', 'ID', 'IS', 'IT', 'JA', 'JV', 'KA',
'KG', 'KO', 'KU', 'KW', 'KY', 'LA', 'LB', 'LI', 'LN', 'LT', 'LV', 'MG', 'MK', 'MN', 'MO', 'MS',
'MT', 'MY', 'NB', 'NE', 'NL', 'NN', 'NO', 'OC', 'PL', 'PT', 'RM', 'RO', 'RU', 'SC', 'SE', 'SK',
'SL', 'SO', 'SQ', 'SR', 'SV', 'SW', 'TK', 'TR', 'TY', 'UK', 'UR', 'UZ', 'VI', 'VO', 'YI', 'ZH'
];
/**
* @var array
*/
protected $versionString = [
'net' => null,
'nt' => null,
'ie' => null,
'trident' => null,
'mac' => null,
'chrome' => null,
'chromeedge' => null,
'edge' => null,
'safari' => null,
'default' => null,
];
/**
* @var string
*/
protected $currentRandom;
/**
* DesktopUserAgent constructor.
*
* @param int $iteration for array rand iteration
*/
public function __construct(int $iteration = self::DEFAULT_ITERATION)
{
$this->randomizeIteration = $iteration < 0
? self::MIN_ITERATION
: ($iteration > self::MAX_ITERATION ? self::MAX_ITERATION : $iteration);
$this->buildVersions();
}
/**
* Build Versions
*
* @return void
*/
protected function buildVersions() : void
{
$this->versionMinMax = [
self::BROWSER_CHROME => [
static::MIN_VERSION_CHROME,
static::MAX_VERSION_CHROME
],
self::BROWSER_IE => [
// default is 9
static::MIN_VERSION_IE,
static::MAX_VERSION_IE
],
self::BROWSER_FIREFOX => [
static::MIN_VERSION_FIREFOX,
static::MAX_VERSION_FIREFOX
],
self::BROWSER_SAFARI => [
static::MIN_VERSION_SAFARI,
static::MAX_VERSION_SAFARI
],
self::BROWSER_OPERA => [
static::MIN_VERSION_OPERA,
static::MAX_VERSION_OPERA
],
self::BROWSER_EDGE => [
static::MIN_VERSION_EDGE,
static::MAX_VERSION_EDGE
],
];
foreach ($this->versionString as $key => $value) {
$this->versionString[$key] = $this->getGenerateVersionString($key);
}
}
/**
* @param string $type
* @param string $macOSDelimiter
*
* @return string
*/
protected function getGenerateVersionString(
string $type,
string $macOSDelimiter = self::MAC_OS_DELIMITER
) : string {
$arrays = [];
$delimiter = '.';
$type = strtolower($type);
switch ($type) {
case 'osx':
case 'macos':
case 'mac':
// @link https://support.apple.com/en-au/HT201260
$minMacVersion = str_replace('.', '', (string) $this->minMacOSVersion);
$maxMacVersion = str_replace('.', '', (string) $this->maxMacOSVersion);
$arrayMac = [];
foreach ($this->macOSMaxVersionLists as $key => $v) {
$keyReplace = str_replace('.', '', $key);
if ($minMacVersion > $keyReplace
|| $maxMacVersion < $keyReplace
) {
continue;
}
$arrayMac[$key] = $v;
}
// if empty array mac
if (empty($arrayMac)) {
$arrayMac = $this->macOSMaxVersionLists;
}
$rand = array_rand($arrayMac);
$macOSDelimiter === null && $macOSDelimiter = '_';
$delimiter = trim($macOSDelimiter)?: $delimiter;
$arrays[] = str_replace('.', $macOSDelimiter, $rand);
$arrays[] = $arrayMac[$rand];
break;
case 'net':
$arrays[] = rand(1, 4);
$arrays[] = rand(0, 9);
$arrays[] = rand(10000, 99999);
$arrays[] = rand(0, 9);
break;
case 'nt':
$arrays[] = rand(5, 6);
$arrays[] = rand(0, 3);
break;
case 'ie':
$arrays[] = rand(7, 11);
break;
case 'trident':
$arrays[] = rand(3, 7);
$arrays[] = rand(0, 1);
break;
case 'chrome':
case 'chromeedge':
$min = isset($this->versionMinMax[self::BROWSER_CHROME])
? min($this->versionMinMax[self::BROWSER_CHROME])
: static::MIN_VERSION_CHROME;
$max = isset($this->versionMinMax[self::BROWSER_CHROME])
? max($this->versionMinMax[self::BROWSER_CHROME])
: static::MAX_VERSION_CHROME;
$min = $type === 'chromeedge' ? 39 : $min;
$max = $type === 'chromeedge' ? 80 : $max;
$arrays[] = rand($min, $max);
$arrays[] = 0;
$arrays[] = rand(800, 899);
$arrays[] = 0;
break;
case 'edge':
$min = isset($this->versionMinMax[self::BROWSER_EDGE])
? min($this->versionMinMax[self::BROWSER_EDGE])
: static::MIN_VERSION_EDGE;
$max = isset($this->versionMinMax[self::BROWSER_EDGE])
? max($this->versionMinMax[self::BROWSER_EDGE])
: static::MAX_VERSION_EDGE;
$major = rand($min, $max);
$minor = rand(40, 999);
$arrays[] = sprintf('%s.%s%s%s', $major, $major, $minor < 100 ? '0' : '', $minor);
break;
case 'safari':
$min = isset($this->versionMinMax[self::BROWSER_SAFARI])
? min($this->versionMinMax[self::BROWSER_SAFARI])
: static::MIN_VERSION_SAFARI;
$max = isset($this->versionMinMax[self::BROWSER_SAFARI])
? max($this->versionMinMax[self::BROWSER_SAFARI])
: static::MAX_VERSION_SAFARI;
$arrays[] = rand($min, $max);
$arrays[] = rand(0, 2);
$arrays[] = rand(0, 2);
break;
default:
$arrays[] = rand(1, 20);
$arrays[] = 0;
$arrays[] = rand(0, 99);
$macOSDelimiter === null && $macOSDelimiter = '_';
$delimiter = trim($macOSDelimiter)?: $delimiter;
}
return implode($delimiter, $arrays);
}
/**
* @param string $type
* @param int $min
* @param int $max
*
* @return bool|mixed
*/
public function setVersionRange(string $type, int $min, int $max)
{
$type = strtolower(trim($type));
if ($type === '') {
throw new InvalidArgumentException(
'Browser type could not be empty or white space only',
E_USER_WARNING
);
}
if (!isset($type, $this->osBrowserVersions)) {
throw new InvalidArgumentException(
sprintf(
'Browser type %s is not exists.',
$type
),
E_USER_WARNING
);
}
if ($min < 0) {
throw new RangeException(
'Minimum version could not be zero values',
E_USER_WARNING
);
}
if ($min > $max) {
throw new RangeException(
'Maximum version must be greater than minimum version',
E_USER_WARNING
);
}
/*switch ($type) {
case self::BROWSER_IE:
$minVersion = self::MIN_VERSION_IE;
$maxVersion = self::MAX_VERSION_IE;
break;
case self::BROWSER_CHROME:
$minVersion = self::MIN_VERSION_CHROME;
$maxVersion = self::MAX_VERSION_CHROME;
break;
case self::BROWSER_FIREFOX:
$minVersion = self::MIN_VERSION_FIREFOX;
$maxVersion = self::MAX_VERSION_FIREFOX;
break;
case self::BROWSER_SAFARI:
$minVersion = self::MIN_VERSION_SAFARI;
$maxVersion = self::MAX_VERSION_SAFARI;
break;
case self::BROWSER_EDGE:
$minVersion = self::MIN_VERSION_EDGE;
$maxVersion = self::MAX_VERSION_EDGE;
break;
case self::BROWSER_OPERA:
$minVersion = self::MIN_VERSION_OPERA;
$maxVersion = self::MAX_VERSION_OPERA;
break;
}
if (!isset($minVersion) || !isset($maxVersion)) {
return false;
}
// @todo validate
$min = $min <= $minVersion
? $minVersion
: $min;
$max = $max <= $maxVersion
? $maxVersion
: $max;
//if ($min === self::MAX_VERSION_IE) {
// $min -= 1;
//}*/
$max = $min === $max ? $max+1 : $max;
$this->versionMinMax[$type][0] = $min;
$this->versionMinMax[$type][1] = $max;
return $this->versionMinMax[$type];
}
/**
* Random array iteration
*
* @param array $array
* @param int $iteration
*
* @return mixed
*/
private function arrayRand(array $array, int $iteration = null)
{
$iteration = !is_int($iteration)
? $this->randomizeIteration
: ($iteration > self::MAX_ITERATION
? self::MAX_ITERATION
: (
$iteration < self::MIN_ITERATION
? self::MIN_ITERATION
: $iteration
)
);
do {
$rand = array_rand($array);
$iteration--;
} while ($iteration <= 0);
return $rand;
}
/**
* Get Random Revisions
*
* @param int $length
*
* @return string
*/
public function getRandomRevision(int $length) : string
{
$length = $length < 1 ? 1 : $length;
$returnValue = '';
while ($length > 0) {
$returnValue .= '.' .rand(0, 9);
$length--;
}
return $returnValue;
}
/**
* Get Random float between 0 - 0.9999...
*
* @return float
*/
public function getMathRandom() : float
{
return mt_rand() / mt_getrandmax();
}
/**
* @param $start
* @param null $end
*
* @return float|int|mixed
* @throws TypeError
*/
protected function randomize($start = null, $end = null)
{
// fallback default to range(0, 100)
if (func_num_args() === 0) {
$start = 0;
$end = 100;
}
if ($start === null && is_int($end)) {
$start = 0;
$end = $end === $start ? $start+1 : $end;
}
$start = is_numeric($start) && is_string($start)
? (strpos($start, '.') === false
? (int) $start
: (float) $start
) : $start;
$end = is_numeric($end) && is_string($end)
? (strpos($end, '.') === false
? (int) $end
: (float) $end
) : $end;
if (is_int($start) && is_int($end)) {
if ($start > $end) {
throw new RangeException(
'Start offset must be less or equal than end offset',
E_WARNING
);
}
return floor($this->getMathRandom() * ($start-$end+1)) + $start;
}
if (!is_array($start)) {
throw new TypeError(
sprintf(
'Invalid arguments passed to %1$s(%2$s)',
__FUNCTION__,
(func_num_args() > 1 ? '$start, $end' : '$start')
)
);
}
if (is_array($start) && is_int(key($start))) {
shuffle($start);
return current($start);
}
$rand = $this->randomize(0, 100) / 100;
$min = 0;
$key = null;
$returnValue = null;
foreach ($start as $key => $value) {
if (is_float($value)) {
$max = $value + $min;
$returnValue = $key;
if ($rand >= $min && $rand <= $max) {
break;
}
$min = $min + $value;
}
}
if ($returnValue === null) {
$returnValue = $start[$this->arrayRand($start)];
}
return $returnValue;
}
/**
* @return string
*/
public function getRandomBrowser() : string
{
return $this->arrayRand($this->versionMinMax);
}
/**
* @return string
*/
public function getRandomOS() : string
{
return $this->arrayRand($this->processors);
}
/**
* Get Random Processor
*
* @param string|null $os if invalid OS or not exists will be generated random
*
* @return string[] offset 0 is os and 1 is arch if
*/
public function getRandomProcessor(string $os = null) : array
{
$os = !is_string($os) || !isset($this->processors[$os])
? $this->getRandomOS()
: $os;
$selectedOS = $this->processors[$os];
$arch = $selectedOS[$this->arrayRand($selectedOS)];
return [
$os,
$arch
];
}
/**
* @param string $os
* @param string $versionString
* @param string $processor
* @param string|null $default
*
* @return string
*/
private function generateBrowserPrefix(
string $os,
string $versionString = '',
string $processor = '',
string $default = null
) : string {
$returnValue = '';
switch ($os) {
case self::OS_WIN:
$processor = $processor ? '; '.$processor : '';
$returnValue .= 'Windows NT '.$versionString.$processor;
break;
case self::OS_MAC:
$returnValue .= 'Macintosh; '.$processor.' Mac OS X '.$versionString;
break;
case self::OS_LINUX:
$versionString = $versionString ? " $versionString": '';
$returnValue .= "X11; Linux".$versionString;
break;
default:
if ($default) {
$default = stripos($default, 'win') !== false
? self::OS_WIN
: (
stripos($default, 'lin') !== false
? self::OS_LINUX
: (
stripos($default, 'mac') !== false
|| stripos($default, 'x') !== false
? self::OS_MAC
: null
)
);
}
if (!$default) {
$default = $this->getRandomOS();
}
$default = strtolower($default);
return $this->generateBrowserPrefix(
$default,
$versionString,
$processor,
// fallback to window to prevent infinite loop possibilities
self::OS_WIN
);
}
return $returnValue;
}
/**
* @param string|null $os
* @param string|null $processor
* @param string|null $firefoxVersion
* @param string|null $versionString
*
* @return string
*/
public function getFromFirefox(
string $os = null,
string $processor = null,
string $firefoxVersion = null,
string $versionString = null
) : string {
$os = !is_string($os) ? $this->getRandomOS() : $os;
if (!is_string($processor) || trim($processor) === '' && $os !== self::OS_WIN) {
$processorArray = $this->getRandomProcessor($os);
$os = array_shift($processorArray);
$processor = array_shift($processorArray);
}
if ($firefoxVersion === self::VERSION_LATEST && isset($this->versionMinMax[self::BROWSER_FIREFOX][1])) {
$firefoxVersion = $this->versionMinMax[self::BROWSER_FIREFOX][1]. $this->getRandomRevision(2);
} else {
/**
* see @link https://developer.mozilla.org/en-US/docs/Gecko_user_agent_string_reference
*/
$firefoxVersion = !is_string($firefoxVersion) || trim($firefoxVersion) === ''
? rand(
$this->versionMinMax[self::BROWSER_FIREFOX][0],
$this->versionMinMax[self::BROWSER_FIREFOX][1]
) . $this->getRandomRevision(2)
: trim($firefoxVersion);
}
if (!is_string($versionString) || trim($versionString) === '') {
$versionString = $os === self::OS_WIN
? $this->getGenerateVersionString('nt')
: ($os === self::OS_MAC ? $this->getGenerateVersionString(self::OS_MAC) : '');
}
$firefoxVersionSL = substr($firefoxVersion, 0, -2);
$versionString = trim($versionString);
$osVersion = $this->generateBrowserPrefix($os, $versionString, $processor);
return sprintf(
'%s (%s; rv:%s) Gecko/20100101 Firefox/%s"',
self::MOZ_COMPAT,
$osVersion,
$firefoxVersionSL,
$firefoxVersion
);
}
/**
* @param null $os
* @param null $version
* @param null $processor
* @param string|null $chromeVersion
* @param string|null $webkitVersion
* @param string $name
* @param string|null $lang
*
* @return string
* @access internal
*/
protected function generateByWebkit(
$os = null,
$version = null,
$processor = null,
string $chromeVersion = null,
string $webkitVersion = null,
string $name = '',
string $lang = null
) : string {
$os = !is_string($os) ? $this->getRandomOS() : $os;
$isEdge = false;
$isOpera = false;
$isSafari = false;
$type = self::BROWSER_CHROME;
$versionStringType = self::BROWSER_CHROME;
if ($name) {
if (stripos($name, self::BROWSER_EDGE) !== false) {
$os = self::OS_WIN;
$isEdge = true;
$versionStringType = 'chromeedge';
$type = self::BROWSER_EDGE;
} elseif (stripos($name, 'opr') !== false) {
$type = self::BROWSER_OPERA;
$isOpera = true;
} elseif (stripos($name, 'saf') !== false) {
$type = self::BROWSER_SAFARI;
$isSafari = true;
$versionStringType = self::OS_MAC;
}
}
if ($isSafari) {
$lang = !$lang ? $this->lang[$this->arrayRand($this->lang)] : strtoupper($lang);
}
$chromeType = $isSafari ? 'Version' : 'Chrome';
if (!is_string($processor) || trim($processor) === '' && $os !== self::OS_WIN) {
$processorArray = $this->getRandomProcessor($os);
$os = array_shift($processorArray);
$processor = array_shift($processorArray);
}
if ($version === self::VERSION_LATEST && isset($this->versionMinMax[$type][1])) {
$version = $this->versionMinMax[$type][1];
} else {
$version = !$version
|| !is_numeric($version)
|| !in_array(
intval($version),
range(
$this->versionMinMax[$type][0],
$this->versionMinMax[$type][1]
)
) ? $this->getGenerateVersionString(
$versionStringType,
$os === self::OS_MAC ? self::MAC_OS_DELIMITER : '.'
) : $version;
}
if ($isSafari && $os === self::OS_MAC) {
$version = trim(
str_replace(
'.',
self::MAC_OS_DELIMITER,
(string) $version
),
self::MAC_OS_DELIMITER
);
}
if (!is_string($processor) || trim($processor) === '') {
$processorArray = $this->getRandomProcessor($os);
$processor = array_pop($processorArray);
}
$chromeVersion = $chromeVersion && trim($chromeVersion) !== ''
? trim($chromeVersion)
: $this->getGenerateVersionString(self::BROWSER_CHROME);
$processor = $processor ? $processor : '';
$webkitVersion = !$webkitVersion || trim($webkitVersion)
? $this->getGenerateVersionString(self::BROWSER_SAFARI)
: trim($webkitVersion);
$osVersion = $this->generateBrowserPrefix(
$os,
$isEdge
? '10.0'
: ($isSafari
? sprintf(
"%s rv: %s.0 %s",
$version,
substr((string) $chromeVersion, 0, 2),
$lang
)
: $version
),
$processor
);
$returnValue = sprintf(
'%1$s (%2$s) AppleWebKit/%3$s (KHTML, like Gecko) %4$s/%1$s Safari/%5$s"',
self::MOZ_COMPAT,
$osVersion,
$webkitVersion,
$chromeType,
$chromeVersion
);
if ($isEdge) {
$returnValue .= 'Edge/'.$version;
} elseif ($isOpera) {
$returnValue .= 'OPR/'.$version;
}
return $returnValue;
}
/**
* @param string|null $os
* @param null $version
* @param null $processor
* @param string|null $chromeVersion
* @param string|null $webkitVersion
*
* @return string
*/
public function getFromOpera(
string $os = null,
$version = null,
$processor = null,
string $chromeVersion = null,
string $webkitVersion = null
) : string {
return $this->generateByWebkit(
$os,
$version,
$processor,
$chromeVersion,
$webkitVersion,
'opera'
);
}
/**
* @param string|null $os
* @param null $version
* @param null $processor
* @param string|null $chromeVersion
* @param string|null $webkitVersion
*
* @return string
*/
public function getFromChrome(
string $os = null,
$version = null,
$processor = null,
string $chromeVersion = null,
string $webkitVersion = null
) : string {
return $this->generateByWebkit(
$os,
$version,
$processor,
$chromeVersion,
$webkitVersion
);
}
/**
* @param string|null $os
* @param null $version
* @param null $processor
* @param string|null $chromeVersion
* @param string|null $webkitVersion
* @param string|null $lang
*
* @return string
*/
public function getFromSafari(
string $os = null,
$version = null,
$processor = null,
string $chromeVersion = null,
string $webkitVersion = null,
string $lang = null
) : string {
return $this->generateByWebkit(
$os,
$version,
$processor,
$chromeVersion,
$webkitVersion,
'safari',
$lang
);
}
/**
* Get edge Browser
*
* @param int|string|null $version
* @param string|null $processor
* @param string|null $chromeVersion
* @param string|null $webkitVersion
*
* @return string
*/
public function getFromEdge(
$version = null,
$processor = null,
string $chromeVersion = null,
string $webkitVersion = null
) : string {
return $this->generateByWebkit(
self::OS_WIN,
$version,
$processor,
$chromeVersion,
$webkitVersion,
'edge'
);
}
/**
* Generate from Internet Explorer
*
* @param mixed|null $version
* @param string|null $ntVersion
* @param bool $touch
* @param string|null $tridentVersion
* @param string|null $netVersion
*
* @return string
*/
public function getFromIE(
$version = null,
string $ntVersion = null,
$touch = null,
string $tridentVersion = null,
$netVersion = null
) : string {
$latest = $version;
if ($version === self::VERSION_LATEST && isset($this->versionMinMax[self::BROWSER_IE][1])) {
$version = $this->versionMinMax[self::BROWSER_IE][1];
} else {
$version = ! is_numeric($version)
|| ! in_array(intval($version), range(
$this->versionMinMax[self::BROWSER_IE][0],
$this->versionMinMax[self::BROWSER_IE][1]
)) ? $this->getGenerateVersionString('ie') : $version;
}
if (!$netVersion && $latest === self::VERSION_LATEST) {
$ntVersion = 3;
} else {
$ntVersion = !is_numeric($ntVersion) || trim($ntVersion) === ''
? rand(1, 3)
: $ntVersion;
}
$touch = $touch === null
? $this->arrayRand(['Touch; ' => null, '' => null])
: ($touch ? 'Touch; ': '');
if ($version >= 11) {
/**
* see @link http://msdn.microsoft.com/en-us/library/ie/hh869301(v=vs.85).aspx
*/
return sprintf(
'%s (Windows NT 6.%s; Trident/7.0; %srv:11.0) like Gecko"',
self::MOZ_COMPAT,
$ntVersion,
$touch
);
}
$tridentVersion = ! $tridentVersion || trim($tridentVersion) === ''
? $this->getGenerateVersionString('trident')
: trim($tridentVersion);
$netVersion = ! is_bool($netVersion) && !is_string($netVersion)
? rand(0, 1) == 1
: $netVersion;
if (is_bool($netVersion)) {
$netVersion = is_bool($netVersion)
? (!$netVersion ? '' : $this->getGenerateVersionString('net'))
: (trim($netVersion) ?: '');
}
$netVersion = $netVersion !== '' ? sprintf("; .NET CLR %s", $netVersion) : '';
return self::MOZ_COMPAT
. sprintf(
" (compatible; MSIE %s.0; Windows NT %s; Trident/%s%s)",
$version,
$ntVersion,
$tridentVersion,
$netVersion
);
}
/**
* Firefox support OS and version
*
* @param string|null $version
* @param string|null $os
*
* @return string
*/
public function firefox($version = null, string $os = null) : string
{
return $this->getFromFirefox($os, null, $version);
}
/**
* Opera support OS and version
*
* @param string|null $version
* @param string|null $os
*
* @return string
*/
public function opera($version = null, string $os = null) : string
{
return $this->getFromOpera($os, null, $version);
}
/**
* Chrome support OS and version
*
* @param string|null $version
* @param string|null $os
*
* @return string
*/
public function chrome($version = null, string $os = null) : string
{
return $this->getFromChrome($os, null, $version);
}
/**
* Safari support OS and version
*
* @param string|null $version
* @param string|null $os
* @param string $lang
*
* @return string
*/
public function safari($version = null, string $os = null, string $lang = null) : string
{
return $this->getFromSafari($os, null, $version, $lang);
}
/**
* @param string $version
*
* @return string
*/
public function ie($version = null) : string
{
return $this->getFromIE($version);
}
/**
* @param string $version
*
* @return string
*/
public function edge($version = null) : string
{
return $this->getFromEdge($version);
}
/**
* Get Random
*
* @param bool $useIE use internet Explorer or edge
*
* @return string
*/
public function getRandomUserAgent(bool $useIE = true) : string
{
$os = $this->getRandomOS();
if (!$useIE) {
$array = $this->versionMinMax;
unset($array[self::BROWSER_IE], $array[self::BROWSER_EDGE]);
$browser = $this->arrayRand($array);
} else {
$browser = $this->getRandomBrowser();
}
if ($useIE && in_array($browser, [self::BROWSER_IE, self::BROWSER_EDGE])) {
$random = call_user_func([$this, self::BROWSER_IE]);
} else {
$method = sprintf('getFrom%s', ucfirst($browser));
$random = call_user_func([$this, $method], $os);
}
if (!isset($this->currentRandom)) {
$this->currentRandom = $random;
}
return $random;
}
/**
* @return string
*/
public function getCurrentRandomUserAgent(): string
{
if (!isset($this->currentRandom)) {
$this->currentRandom = $this->getRandomUserAgent();
}
return $this->currentRandom;
}
/**
* @param bool $useIE
* @return string
*/
public static function generateRandom(bool $useIE = true) : string
{
return (new self())->getRandomUserAgent($useIE);
}
/**
* @return string
*/
public function __toString() : string
{
return $this->getCurrentRandomUserAgent();
}
}
<?php
declare(strict_types=1);
namespace ArrayIterator\Library\Source\Generator;
/**
* Class HttpCode
* @package ArrayIterator\Library\Source\Generator
*
* Common HTTP Code Lists
*/
final class HttpCode
{
const CONTINUE = 100;
const SWITCHING_PROTOCOLS = 101;
const PROCESSING = 102;
const OK = 200;
const CREATED = 201;
const ACCEPTED = 202;
const NON_AUTHORITATIVE_INFORMATION = 203;
const NO_CONTENT = 204;
const RESET_CONTENT = 205;
const PARTIAL_CONTENT = 206;
const MULTI_STATUS = 207;
const ALREADY_REPORTED = 208;
const MULTIPLE_CHOICES = 300;
const MOVED_PERMANENTLY = 301;
const FOUND = 302;
const SEE_OTHER = 303;
const NOT_MODIFIED = 304;
const USE_PROXY = 305;
const SWITCH_PROXY = 306;
const TEMPORARY_REDIRECT = 307;
const BAD_REQUEST = 400;
const UNAUTHORIZED = 401;
const PAYMENT_REQUIRED = 402;
const FORBIDDEN = 403;
const NOT_FOUND = 404;
const METHOD_NOT_ALLOWED = 405;
const NOT_ACCEPTABLE = 406;
const PROXY_AUTHENTICATION_REQUIRED = 407;
const REQUEST_TIME_OUT = 408;
const CONFLICT = 409;
const GONE = 410;
const LENGTH_REQUIRED = 411;
const PRECONDITION_FAILED = 412;
const REQUEST_ENTITY_TOO_LARGE = 413;
const REQUEST_URI_TOO_LARGE = 414;
const UNSUPPORTED_MEDIA_TYPE = 415;
const REQUESTED_RANGE_NOT_SATISFIABLE = 416;
const EXPECTATION_FAILED = 417;
const IM_A_TEAPOT = 418;
const UNPROCESSABLE_ENTITY = 422;
const LOCKED = 423;
const FAILED_DEPENDENCY = 424;
const UNORDERED_COLLECTION = 425;
const UPGRADE_REQUIRED = 426;
const PRECONDITION_REQUIRED = 428;
const TOO_MANY_REQUESTS = 429;
const REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
const UNAVAILABLE_FOR_LEGAL_REASONS = 451;
const INTERNAL_SERVER_ERROR = 500;
const NOT_IMPLEMENTED = 501;
const BAD_GATEWAY = 502;
const SERVICE_UNAVAILABLE = 503;
const GATEWAY_TIME_OUT = 504;
const HTTP_VERSION_NOT_SUPPORTED = 505;
const VARIANT_ALSO_NEGOTIATES = 506;
const INSUFFICIENT_STORAGE = 507;
const LOOP_DETECTED = 508;
const NETWORK_AUTHENTICATION_REQUIRED = 511;
/**
* @var array
*/
protected static $phrases = [
self::CONTINUE => 'Continue',
self::SWITCHING_PROTOCOLS => 'Switching Protocols',
self::PROCESSING => 'Processing',
self::OK => 'OK',
self::CREATED => 'Created',
self::ACCEPTED => 'Accepted',
self::NON_AUTHORITATIVE_INFORMATION => 'Non-Authoritative Information',
self::NO_CONTENT => 'No Content',
self::RESET_CONTENT => 'Reset Content',
self::PARTIAL_CONTENT => 'Partial Content',
self::MULTI_STATUS => 'Multi-status',
self::ALREADY_REPORTED => 'Already Reported',
self::MULTIPLE_CHOICES => 'Multiple Choices',
self::MOVED_PERMANENTLY => 'Moved Permanently',
self::FOUND => 'Found',
self::SEE_OTHER => 'See Other',
self::NOT_MODIFIED => 'Not Modified',
self::USE_PROXY => 'Use Proxy',
self::SWITCH_PROXY => 'Switch Proxy',
self::TEMPORARY_REDIRECT => 'Temporary Redirect',
self::BAD_REQUEST => 'Bad Request',
self::UNAUTHORIZED => 'Unauthorized',
self::PAYMENT_REQUIRED => 'Payment Required',
self::FORBIDDEN => 'Forbidden',
self::NOT_FOUND => 'Not Found',
self::METHOD_NOT_ALLOWED => 'Method Not Allowed',
self::NOT_ACCEPTABLE => 'Not Acceptable',
self::PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required',
self::REQUEST_TIME_OUT => 'Request Time-out',
self::CONFLICT => 'Conflict',
self::GONE => 'Gone',
self::LENGTH_REQUIRED => 'Length Required',
self::PRECONDITION_FAILED => 'Precondition Failed',
self::REQUEST_ENTITY_TOO_LARGE => 'Request Entity Too Large',
self::REQUEST_URI_TOO_LARGE => 'Request-URI Too Large',
self::UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type',
self::REQUESTED_RANGE_NOT_SATISFIABLE => 'Requested range not satisfiable',
self::EXPECTATION_FAILED => 'Expectation Failed',
self::IM_A_TEAPOT => 'I\'m a teapot',
self::UNPROCESSABLE_ENTITY => 'Unprocessable Entity',
self::LOCKED => 'Locked',
self::FAILED_DEPENDENCY => 'Failed Dependency',
self::UNORDERED_COLLECTION => 'Unordered Collection',
self::UPGRADE_REQUIRED => 'Upgrade Required',
self::PRECONDITION_REQUIRED => 'Precondition Required',
self::TOO_MANY_REQUESTS => 'Too Many Requests',
self::REQUEST_HEADER_FIELDS_TOO_LARGE => 'Request Header Fields Too Large',
self::UNAVAILABLE_FOR_LEGAL_REASONS => 'Unavailable For Legal Reasons',
self::INTERNAL_SERVER_ERROR => 'Internal Server Error',
self::NOT_IMPLEMENTED => 'Not Implemented',
self::BAD_GATEWAY => 'Bad Gateway',
self::SERVICE_UNAVAILABLE => 'Service Unavailable',
self::GATEWAY_TIME_OUT => 'Gateway Time-out',
self::HTTP_VERSION_NOT_SUPPORTED => 'HTTP Version not supported',
self::VARIANT_ALSO_NEGOTIATES => 'Variant Also Negotiates',
self::INSUFFICIENT_STORAGE => 'Insufficient Storage',
self::LOOP_DETECTED => 'Loop Detected',
self::NETWORK_AUTHENTICATION_REQUIRED => 'Network Authentication Required',
];
/**
* @return array
*/
public static function getPhrases(): array
{
return self::$phrases;
}
/**
* Convert StatusCode
*
* @param int $code
* @return string|null
*/
public static function statusMessage(int $code) : ?string
{
return self::$phrases[$code]??null;
}
}
<?php
declare(strict_types=1);
namespace ArrayIterator\Library\Source\Generator;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;
/**
* Class Json
* @package ArrayIterator\Library\Source\Generator
* @mixin JsonPatent
* Json Helper for JsonPatent
*/
class Json
{
/**
* @var ResponseInterface
*/
protected static $response;
/**
* @var ServerRequestInterface
*/
protected static $request = null;
/**
* @var JsonPatent
*/
protected static $jsonPatent;
/**
* @return JsonPatent
*/
public static function getJsonPatent() : JsonPatent
{
if (!static::$jsonPatent) {
static::$jsonPatent = new JsonPatent(static::$request);
}
return static::$jsonPatent;
}
/**
* @param JsonPatent|string $jsonPatent
*/
public static function setJsonPatent($jsonPatent)
{
if (is_string($jsonPatent)) {
if (is_subclass_of($jsonPatent, JsonPatent::class)) {
$jsonPatent = new JsonPatent(static::$request);
}
}
if (!is_object($jsonPatent) || !$jsonPatent instanceof JsonPatent) {
return;
}
static::$jsonPatent = $jsonPatent;
}
/**
* @param ResponseInterface $response
*
* @return ResponseInterface
*/
public static function setResponse(ResponseInterface $response) : ResponseInterface
{
return static::$response = $response;
}
/**
* @param ServerRequestInterface $request
*
* @return ServerRequestInterface
*/
public static function setRequest(ServerRequestInterface $request) : ServerRequestInterface
{
return static::$request = $request;
}
/**
* @return ResponseInterface
*/
public static function getResponse() : ResponseInterface
{
return static::$response;
}
/**
* @return ServerRequestInterface
*/
public static function getRequest() : ServerRequestInterface
{
return static::$request;
}
/**
* @param string|null $string
* @return string
*/
public static function setRootDir(string $string = null)
{
$args = func_get_args();
return static::getJsonPatent()->setRootDirectory(...$args);
}
/**
* @return string|null
*/
public static function getRootDir()
{
return static::getJsonPatent()->getRootDirectory();
}
/**
* @param $data
* @param int $options
* @param int $depth
*
* @return false|string
*/
public static function encode($data, int $options = 0, int $depth = 512)
{
$args = func_get_args();
return json_encode(...$args);
}
/**
* @param string $data
* @param bool $assoc
* @param int $depth
* @param int $options
*
* @return mixed
*/
public static function decode(string $data, bool $assoc = false, int $depth = 512, int $options = 0)
{
$args = func_get_args();
return json_decode(...$args);
}
/**
* @param $data
* @param ResponseInterface|null $response
*
* @return ResponseInterface
*/
public static function success($data, ResponseInterface $response = null) : ResponseInterface
{
return static::getJsonPatent()->success($response?? static::getResponse(), $data);
}
/**
* @param $data
* @param int $statusCode
* @param ResponseInterface|null $response
*
* @return ResponseInterface
*/
public static function successCode(
$data,
int $statusCode = 200,
ResponseInterface $response = null
) : ResponseInterface {
$args = [
$response?? static::getResponse(),
$data
];
unset($data);
if ($statusCode !== null) {
$args[] = $statusCode;
}
return static::getJsonPatent()->successCode(...$args);
}
/**
* @param mixed $message
* @param int $statusCode
* @param ResponseInterface|null $response
*
* @return ResponseInterface
*/
public static function errorCode(
$message = null,
int $statusCode = null,
ResponseInterface $response = null
) : ResponseInterface {
$args = [
$response?? static::getResponse(),
$message
];
unset($message);
if ($statusCode !== null) {
$args[] = $statusCode;
}
return static::getJsonPatent()->errorCode(...$args);
}
/**
* @param Throwable $e
* @param ResponseInterface|null $response
* @param int $code
* @return ResponseInterface
*/
public static function exception(
Throwable $e,
ResponseInterface $response = null,
int $code = null
) : ResponseInterface {
$args = [
$response?? static::getResponse(),
$e
];
if ($code !== null) {
$args[] = $code;
}
return static::getJsonPatent()->exceptionCode(...$args);
}
/**
* @param mixed $message
* @param ResponseInterface|null $response
*
* @return ResponseInterface
*/
public static function error(
$message = null,
ResponseInterface $response = null
) : ResponseInterface {
$args = [$response?? static::getResponse()];
if (func_num_args() > 0) {
$args[] = $message;
}
return static::getJsonPatent()->error(...$args);
}
/**
* @param mixed $message
* @param ResponseInterface $response
* @return ResponseInterface
*/
public static function notFound(
$message = null,
ResponseInterface $response = null
) : ResponseInterface {
$args = [
$response?? static::getResponse(),
$message,
404
];
return static::getJsonPatent()->errorCode(...$args);
}
/**
* @param mixed $message
* @param ResponseInterface $response
* @return ResponseInterface
*/
public static function preconditionFailed(
$message = null,
ResponseInterface $response = null
) : ResponseInterface {
$args = [
$response?? static::getResponse(),
$message,
412
];
return static::getJsonPatent()->errorCode(...$args);
}
/**
* @param $name
* @param array $arguments
* @return mixed
*/
public static function __callStatic($name, array $arguments)
{
return call_user_func_array([static::getJsonPatent(), $name], $arguments);
}
/**
* @param $name
* @param $arguments
* @return mixed
*/
public function __call($name, array $arguments)
{
return static::__callStatic($name, $arguments);
}
}
<?php
declare(strict_types=1);
namespace ArrayIterator\Library\Source\Generator;
use ArrayAccess;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;
use UnexpectedValueException;
/**
* Class JsonPatent
* @package ArrayIterator\Library\Source\Generator
*
* Json Helper Standard For Http-Message Library
*/
class JsonPatent
{
const REGEX_UTF8_CHECK = '/(
[\xC0-\xC1] # Invalid UTF-8 Bytes
| [\xF5-\xFF] # Invalid UTF-8 Bytes
| \xE0[\x80-\x9F] # Overlong encoding of prior code point
| \xF0[\x80-\x8F] # Overlong encoding of prior code point
| [\xC2-\xDF](?![\x80-\xBF]) # Invalid UTF-8 Sequence Start
| [\xE0-\xEF](?![\x80-\xBF]{2}) # Invalid UTF-8 Sequence Start
| [\xF0-\xF4](?![\x80-\xBF]{3}) # Invalid UTF-8 Sequence Start
| (?<=[\x00-\x7F\xF5-\xFF])[\x80-\xBF] # Invalid UTF-8 Sequence Middle
| (?<![\xC2-\xDF]
|[\xE0-\xEF]
|[\xE0-\xEF][\x80-\xBF]
|[\xF0-\xF4]
|[\xF0-\xF4][\x80-\xBF]
|[\xF0-\xF4][\x80-\xBF]{2}
)[\x80-\xBF] # Overlong Sequence
| (?<=[\xE0-\xEF])[\x80-\xBF](?![\x80-\xBF]) # Short 3 byte sequence
| (?<=[\xF0-\xF4])[\x80-\xBF](?![\x80-\xBF]{2}) # Short 4 byte sequence
| (?<=[\xF0-\xF4][\x80-\xBF])[\x80-\xBF](?![\x80-\xBF]) # Short 4 byte sequence (2)
)/x';
/**
* @var bool
*/
protected $debugMode = null;
/**
* @var string for debug mode (this usually for exception)
*/
protected $debugKey = 'debug';
/**
* @var string in compression or not
*/
protected $compressKey = 'compress';
/**
* @var string for root key
*/
protected $rootKey = 'data';
/**
* @var string for error default key
*/
protected $errorMessageKey = 'message';
/**
* @var string for error exception default key
*/
protected $exceptionKey = 'exception';
/**
* @var int default error code
*/
protected $defaultErrorCode = HttpCode::INTERNAL_SERVER_ERROR;
/**
* @var string default json header value field
*/
protected $defaultJsonHeaderValue = 'application/json; charset=utf-8';
/**
* @var string default message for exception error
*/
protected $defaultExceptionErrorMessage = 'Exception Error';
/**
* @var string default message for error message
*/
protected $defaultErrorMessage = 'Internal Server Error';
/**
* @var string
*/
protected $rootDirectoryPlaceholder = '{ROOT}';
/**
* @var string[]
*/
protected $defaultActiveTrueArray = ['true', '1', 'on', 'yes'];
/**
* @var bool
*/
protected $useSafeUtf8 = true;
/**
* @var string
*/
protected $rootDirectory = null;
/**
* @var ServerRequestInterface
*/
protected $request;
/**
* JsonPatent constructor.
* @param ServerRequestInterface|null $request
* @param bool|null $debugMode
*/
public function __construct(
?ServerRequestInterface $request = null,
?bool $debugMode = null
) {
$this->request = $request;
$this->debugMode = $debugMode;
}
/**
* @return bool
*/
public function isUseSafeUtf8(): bool
{
return $this->useSafeUtf8;
}
/**
* @param bool $useSafeUtf8
*/
public function setUseSafeUtf8(bool $useSafeUtf8): void
{
$this->useSafeUtf8 = $useSafeUtf8;
}
/**
* @return ServerRequestInterface|null
*/
public function getRequest(): ?ServerRequestInterface
{
//ServerRequestCreatorFactory::create()
// ->createServerRequestFromGlobals();
return $this->request;
}
/**
* @param ServerRequestInterface $request
*/
public function setRequest(ServerRequestInterface $request)
{
$this->request = $request;
}
/**
* @return string
*/
public function getRootKey(): string
{
return $this->rootKey;
}
/**
* @param string $rootKey
*/
public function setRootKey(string $rootKey)
{
$this->rootKey = $rootKey;
}
/**
* @return string
*/
public function getDefaultJsonHeaderValue(): string
{
return $this->defaultJsonHeaderValue;
}
/**
* @param string $defaultJsonHeaderValue
*/
public function setDefaultJsonHeaderValue(string $defaultJsonHeaderValue)
{
$this->defaultJsonHeaderValue = $defaultJsonHeaderValue;
}
/**
* @return string
*/
public function getRootDirectoryPlaceholder() : string
{
return $this->rootDirectoryPlaceholder;
}
/**
* @param string $rootDirectoryPlaceholder
*/
public function setRootDirectoryPlaceholder(string $rootDirectoryPlaceholder)
{
$this->rootDirectoryPlaceholder = $rootDirectoryPlaceholder;
}
/**
* @param string $string
* @return string|null
*/
public function setRootDirectory(string $string = null)
{
if ($string === null) {
return $this->rootDirectory = null;
}
$string = realpath($string)?: $string;
return $this->rootDirectory = $string;
}
/**
* @return string|null
*/
public function getRootDirectory()
{
return $this->rootDirectory;
}
/**
* @return string[]
*/
public function getDefaultActiveTrueArray() : array
{
return $this->defaultActiveTrueArray;
}
/**
* @param string[] $defaultActiveTrueArray
*/
public function setDefaultActiveTrueArray(array $defaultActiveTrueArray)
{
$this->defaultActiveTrueArray = $defaultActiveTrueArray;
}
/**
* @return string[]
*/
public function getPhrases(): array
{
return HttpCode::getPhrases();
}
/**
* @param int $code
* @param string|null $default
* @return string|null
*/
public function getPhrase(int $code, string $default = null)
{
return HttpCode::statusMessage($code)?:$default;
}
/**
* @return string
*/
public function getRootDirPlaceholder() : string
{
return $this->rootDirectoryPlaceholder;
}
/**
* @return int
*/
public function getDefaultErrorCode() : int
{
return $this->defaultErrorCode;
}
/**
* @return string
*/
public function getSuccessRootKey() : string
{
return $this->rootKey;
}
/**
* @return string
*/
public function getErrorMessageKey() : string
{
return $this->errorMessageKey;
}
/**
* @return string
*/
public function getExceptionKey() : string
{
return $this->exceptionKey;
}
/**
* @return string
*/
public function getCompressKey() : string
{
return $this->compressKey;
}
/**
* @return string
*/
public function getDebugKey() : string
{
return $this->debugKey;
}
/**
* @return string
*/
public function getDefaultExceptionErrorMessage() : string
{
return $this->defaultExceptionErrorMessage;
}
/**
* @return string
*/
public function getDefaultErrorMessage() : string
{
return $this->defaultErrorMessage;
}
/**
* @return string
*/
public function getJsonHeaderValue() : string
{
return $this->defaultJsonHeaderValue;
}
/**
* @return array
*/
public function getActiveTrueArray() : array
{
return ['true', '1', 'on', 'yes'];
}
/**
* @return array
*/
public function getQueryParams() : array
{
$request = $this->getRequest();
if ($request) {
$params = $request->getQueryParams();
} else {
parse_str($_SERVER['QUERY_STRING']??'', $params);
}
return $params;
}
/**
* @return bool
*/
public function isCompressed() : bool
{
$params = $this->getQueryParams();
$compressKey = $this->getCompressKey();
return isset($params[$compressKey])
&& is_string($params[$compressKey])
&& in_array($params[$compressKey], $this->getActiveTrueArray());
}
/**
* @param bool $debugMode
*/
public function setDebugMode(bool $debugMode): void
{
$this->debugMode = $debugMode;
}
/**
* @param string $debugKey
*/
public function setDebugKey(string $debugKey): void
{
$this->debugKey = $debugKey;
}
/**
* @param string $compressKey
*/
public function setCompressKey(string $compressKey): void
{
$this->compressKey = $compressKey;
}
/**
* @param string $errorMessageKey
*/
public function setErrorMessageKey(string $errorMessageKey): void
{
$this->errorMessageKey = $errorMessageKey;
}
/**
* @param string $exceptionKey
*/
public function setExceptionKey(string $exceptionKey): void
{
$this->exceptionKey = $exceptionKey;
}
/**
* @param string $defaultErrorMessage
*/
public function setDefaultErrorMessage(string $defaultErrorMessage): void
{
$this->defaultErrorMessage = $defaultErrorMessage;
}
/**
* @param string $defaultExceptionErrorMessage
*/
public function setDefaultExceptionErrorMessage(string $defaultExceptionErrorMessage): void
{
$this->defaultExceptionErrorMessage = $defaultExceptionErrorMessage;
}
/**
* @return bool
*/
public function isDebugMode() : bool
{
if (is_bool($this->debugMode)) {
return $this->debugMode;
}
$params = $this->getQueryParams();
$debugKey = $this->getDebugKey();
return $this->debugMode = isset($params[$debugKey])
&& is_string($params[$debugKey])
&& in_array($params[$debugKey], $this->getActiveTrueArray());
}
/**
* @param int $code
* @return string
*/
public function getErrorInternal(int $code = null) : string
{
$code = $code ?: $this->getDefaultErrorCode();
return $this->getPhrase($code, $this->getDefaultErrorMessage());
}
/**
* @param ResponseInterface $response
* @param array $data
* @return ResponseInterface
*/
protected function serveResponse(
ResponseInterface $response,
array $data
) : ResponseInterface {
$body = $response->getBody();
// $body = ! $body->getSize() ? $response->getBody() : new RequestBody();
$body->rewind(); // rewind
$body->write($this->encodeJson($data, $this->isCompressed()));
return $response
->withBody($body)
->withHeader(
'Content-Type',
$this->getJsonHeaderValue()
);
}
/**
* @param mixed $data
* @return mixed
*/
protected function sanitizeUtf8Encode($data)
{
static $existsUtf8 = null;
if ($existsUtf8 === null) {
$existsUtf8 = function_exists('utf8_encode');
}
if (!$existsUtf8) {
return $data;
}
if (is_string($data)) {
return preg_replace_callback(self::REGEX_UTF8_CHECK, function ($e) {
return utf8_encode($e[1]);
}, $data);
}
if (is_array($data)) {
foreach ($data as $key => $item) {
$data[$key] = $this->sanitizeUtf8Encode($item);
}
return $data;
}
if (is_object($data)) {
if ($data instanceof ArrayAccess) {
foreach ($data as $key => $item) {
if ($item) {
$data->offsetSet($key, $this->sanitizeUtf8Encode($item));
}
}
return $data;
}
foreach ($data as $key => $item) {
$data->$key = $this->sanitizeUtf8Encode($item);
}
return $data;
}
return $data;
}
/**
* @param mixed $data
* @param bool $compress
* @return string
*/
public function encodeJson($data, bool $compress = null) : string
{
$compress = $compress === null ? $this->isCompressed() : $compress;
$options = JSON_UNESCAPED_SLASHES;
! $compress && $options |= JSON_PRETTY_PRINT;
$option = json_encode(
($this->isUseSafeUtf8() ? $this->sanitizeUtf8Encode($data) : $data),
$options
);
if (!is_string($option) && json_last_error()) {
throw new UnexpectedValueException(
sprintf('Can not encode json data with error : %s', json_last_error_msg()),
E_WARNING
);
}
return $option;
}
/**
* @param ResponseInterface $response
* @param mixed $data
* @param int|null $statusCode
* @return ResponseInterface
*/
public function successCode(
ResponseInterface $response,
$data = null,
int $statusCode = HttpCode::OK
) : ResponseInterface {
$args = func_get_args();
array_shift($args);
if ($statusCode) {
$response = $response->withStatus($statusCode);
}
return $this->serveResponse(
$response,
$this->generateSuccessCode(...$args)
);
}
/**
* @param mixed $data
* @param int $statusCode
* @return array
*/
public function generateSuccessCode(
$data = null,
int $statusCode = null
) {
$countArgs = func_num_args();
if ($countArgs < 1) {
$data = 200;
}
$phrase = $this->getPhrases();
if (is_int($data) && isset($phrase[$data]) && $countArgs < 2) {
$statusCode = $data;
$statusCode = $statusCode ?: 200;
$data = sprintf('%s %s', $statusCode, $this->getErrorInternal($statusCode));
}
$messageKey = $this->getSuccessRootKey();
$data = [$messageKey => $data];
return $data;
}
/**
* @param null $message
* @param int|null $statusCode
* @return array
*/
public function generateErrorCode(
$message = null,
int $statusCode = null
) : array {
$countArgs = func_num_args();
$phrase = $this->getPhrases();
if (is_int($message) && isset($phrase[$message]) && $countArgs < 2) {
$statusCode = $message;
$message = null;
}
$statusCode = $statusCode ?: $this->getDefaultErrorCode();
$message = $message?:$this->getErrorInternal($statusCode);
$messageKey = $this->getErrorMessageKey();
$data = [$messageKey => sprintf('%s %s', $statusCode, $message)];
if (is_array($message) && array_key_exists($messageKey, $message)) {
$data = $message;
}
return $data;
}
/**
* @param ResponseInterface $response
* @param null $message
* @param int $statusCode
* @return ResponseInterface
*/
public function errorCode(
ResponseInterface $response,
$message = null,
int $statusCode = null
) : ResponseInterface {
$args = func_get_args();
array_shift($args);
if ($statusCode) {
$response = $response->withStatus($statusCode);
}
return $this->serveResponse(
$response,
$this->generateErrorCode(...$args)
);
}
/**
* @param string $message
* @param int $code
* @param int $line
* @param string $file
* @param array $trace
* @return array
*/
public function generateResultExceptionCode(
string $message = '',
int $code = 0,
int $line = 0,
string $file = '',
array $trace = []
) : array {
return [
$this->getErrorMessageKey() => $this->getDefaultExceptionErrorMessage(),
$this->getExceptionKey() => [
[
'type' => 'Exception',
'message' => $message,
'code' => $code,
'line' => $line,
'file' => $this->hidePathException($file),
'trace' => $trace
]
]
];
}
/**
* @param ResponseInterface $response
* @param string $message
* @param int $code
* @param int $line
* @param string $file
* @param array $trace
* @return ResponseInterface
*/
public function withManualResultException(
ResponseInterface $response,
string $message = '',
int $code = 0,
int $line = 0,
string $file = '',
array $trace = []
) : ResponseInterface {
return $this->errorCode(
$response,
$this->generateResultExceptionCode(
$message,
$code,
$line,
$file,
$trace
),
HttpCode::INTERNAL_SERVER_ERROR
);
}
/**
* @param Throwable $e
* @param string|null $message
* @return array
*/
public function generateExceptionCode(Throwable $e, string $message = null) : array
{
$message = $message ?: $this->getDefaultExceptionErrorMessage();
$messageKey = $this->getErrorMessageKey();
$exceptionKey = $this->getExceptionKey();
$message = [
$messageKey => $message,
$exceptionKey => []
];
$isDebug = $this->isDebugMode();
do {
$m = [
'type' => get_class($e),
'code' => $e->getCode(),
'message' => $e->getMessage(),
];
if ($isDebug) {
$m['file'] = $this->hidePathException($e->getFile());
$m['line'] = $e->getLine();
$m['trace'] = preg_split(
"~(?:(?:[\r]+)?[\n]+)+~",
$this->sanitizePathTrace($e)
);
}
$message[$exceptionKey][] = $m;
} while ($e = $e->getPrevious());
unset($m);
return $message;
}
/**
* Determine Trace String
*
* @param Throwable $e
* @return string
*/
protected function sanitizePathTrace(Throwable $e) : string
{
if (!($rootDir = $this->getRootDirectory()) || !is_string($rootDir)) {
return $e->getTraceAsString();
}
$regex = DIRECTORY_SEPARATOR === '\\'
? '~([A-Z]+:[\\\].+)~i'
: '~(/.+)~';
return preg_replace_callback(
$regex,
function ($e) {
return $this->hidePathException($e[1]);
},
$e->getTraceAsString()
);
}
/**
* @param string $file
* @return string
*/
public function hidePathException(string $file) : string
{
if (!($rootDir = $this->getRootDirectory()) || !is_string($rootDir)) {
return $file;
}
$sub = preg_quote($rootDir, '/');
$rootDirPlaceHolder = $this->getRootDirPlaceholder();
return (string) preg_replace_callback(
'/(.+)([^\/]+)$/',
function ($m) use ($sub, $rootDirPlaceHolder) {
$sub = sprintf("/^%s/", $sub);
return preg_replace($sub, $rootDirPlaceHolder, $m[1]).$m[2];
},
$file
);
}
/**
* Generate 500 Exception
*
* @param ResponseInterface $response
* @param Throwable $e
* @return ResponseInterface
*/
public function exception(
ResponseInterface $response,
Throwable $e
) : ResponseInterface {
return $this->exceptionCode($response, $e, HttpCode::INTERNAL_SERVER_ERROR);
}
/**
* @param ResponseInterface $response
* @param Throwable $e
* @param int $code
* @return ResponseInterface
*/
public function exceptionCode(
ResponseInterface $response,
Throwable $e,
int $code = HttpCode::INTERNAL_SERVER_ERROR
) : ResponseInterface {
return $this->errorCode(
$response,
$this->generateExceptionCode($e),
$code
);
}
/**
* @param ResponseInterface $response
* @param mixed $data
* @return ResponseInterface
*/
public function success(
ResponseInterface $response,
$data = null
) : ResponseInterface {
$args = func_get_args();
array_shift($args);
if (count($args) > 0) {
$args[] = HttpCode::OK;
}
return $this->successCode($response, ...$args);
}
/**
* @param ResponseInterface $response
* @param mixed $message
* @return ResponseInterface
*/
public function error(
ResponseInterface $response,
$message = null
) : ResponseInterface {
$args = func_get_args();
array_shift($args);
if (count($args) > 0) {
$args[] = HttpCode::INTERNAL_SERVER_ERROR;
}
return $this->errorCode($response, ...$args);
}
/**
* @param ResponseInterface $response
* @param mixed $message
* @return ResponseInterface
*/
public function unauthorized(
ResponseInterface $response,
$message = null
) : ResponseInterface {
return $this->errorCode($response, $message, HttpCode::UNAUTHORIZED);
}
/**
* @param ResponseInterface $response
* @param mixed $message
* @return ResponseInterface
*/
public function forbidden(
ResponseInterface $response,
$message = null
) : ResponseInterface {
return $this->errorCode($response, $message, HttpCode::FORBIDDEN);
}
/**
* Generate 404 Http Status Code
*
* @param ResponseInterface $response
* @param mixed $message
* @return ResponseInterface
*/
public function notFound(
ResponseInterface $response,
$message = null
) : ResponseInterface {
return $this->errorCode($response, $message, HttpCode::NOT_FOUND);
}
/**
* @param ResponseInterface $response
* @param mixed $message
* @return ResponseInterface
*/
public function preconditionFailed(
ResponseInterface $response,
$message = null
) : ResponseInterface {
return $this->errorCode($response, $message, HttpCode::PRECONDITION_FAILED);
}
}
<?php
declare(strict_types=1);
namespace ArrayIterator\Library\Source\Generator;
/**
* Class TokenGen
* @package ArrayIterator\Library\Source\Generator
*/
class TokenGen
{
const DEFAULT_KEY = 'token_gen';
/**
* 8600
*/
const A_DAY_IN_SECOND = 0x15180;
/**
* 96
*/
const TOKEN_LENGTH = 0x60;
/**
* @var int
*/
protected static $time;
/**
* @var string[]
*/
protected static $token = [];
/**
* @param string $token
* @return bool
*/
public static function validate($token) : bool
{
return !static::isExpired(static::getExpire($token));
}
/**
* @param int $time
* @return bool
*/
public static function isExpired($time) : bool
{
if (!is_numeric($time)) {
return true;
}
return !($time !== false && ($time + self::A_DAY_IN_SECOND) > self::$time);
}
/**
* @param string $token
* @return array|bool
*/
public static function parseData(string $token)
{
if (!preg_match('~^([0-9a-f]+)([0-9a-f]{32})$~', $token, $match)
|| empty($match[1])
) {
return false;
}
return [
'data' => $match[1],
'iv' => $match[2]
];
}
/**
* @param string $token
* @param null $secretKey
* @param bool $rehash
*
* @return bool|float|int
*/
public static function getExpire($token, $secretKey = null, $rehash = true)
{
if (!is_string($token)
|| strlen($token) <> self::TOKEN_LENGTH
|| ($m = self::parseData($token)) === false
) {
return false;
}
$hasError = false;
set_error_handler(function () use (&$hasError) {
$hasError = true;
if (error_get_last()) {
error_clear_last();
}
});
$data = hex2bin($m['data']);
$iv = hex2bin($m['iv']);
if ($hasError || !is_string($data) || !$iv || strlen($iv) <> 0x10) {
restore_error_handler();
return false;
}
$secretKey = $secretKey
? ($rehash ? static::hashKey($secretKey) : $secretKey)
: static::hashKey(self::DEFAULT_KEY);
$decrypt = openssl_decrypt(
$data,
'AES-128-CBC',
$secretKey,
OPENSSL_RAW_DATA,
$iv
);
restore_error_handler();
if ($hasError) {
return false;
}
if (!isset(self::$time)) {
self::$time = time();
}
$time = self::$time;
if (is_string($decrypt) && preg_match(
'/^([0-9]+)\|(.*)/sm',
$decrypt,
$match
) && !empty($match[1])
&& !empty($match[2])
&& is_numeric($match[1])
&& $match[1] > 0
&& is_int(abs($match[1]))
&& $time >= $match[1]
) {
$secretHex = hex2bin(sha1($secretKey.$iv));
return ($match[2] === $secretHex)
? abs($match[1])
: false;
}
return false;
}
/**
* @param string $key
*
* @return string
*/
public static function create($key = self::DEFAULT_KEY)
{
$secretKey = self::hashKey($key);
$iv = openssl_random_pseudo_bytes(0x10);
$secretHex = hex2bin(sha1($secretKey.$iv));
if (!isset(self::$time)) {
self::$time = time();
}
$time = self::$time;
$data = "{$time}|{$secretHex}";
return static::$token[$secretKey] = bin2hex(
openssl_encrypt(
$data,
'AES-128-CBC',
$secretKey,
OPENSSL_RAW_DATA,
$iv
).$iv
);
}
/**
* @param string $key
*
* @return string
*/
public static function hashKey($key = self::DEFAULT_KEY)
{
$secretKey = !is_string($key)?self::DEFAULT_KEY : $key;
return hash_hmac('sha1', $secretKey, self::DEFAULT_KEY);
}
/**
* @param string $key
*
* @return null|string
*/
public static function getToken($key = self::DEFAULT_KEY)
{
$secretKey = self::hashKey($key);
return isset(static::$token[$secretKey]) ? static::$token[$secretKey] : null;
}
/**
* @param string $key
*
* @return string
*/
public static function get($key = self::DEFAULT_KEY) : string
{
$token = self::getToken($key);
if (!$token) {
$token = static::create();
}
return $token;
}
}
@dellal9h
Copy link

dellal9h commented Jun 4, 2019

You can help me find a solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment