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;
}
}
@ArrayIterator
Copy link
Author

ArrayIterator commented May 26, 2019

Note

Please Replace root dir on

And or override the the JsonPatent on child class.

Recommendation just use JsonPatent instead of Json. And or make the library more reusable.

<?php
use ArrayIterator\Library\Source\Generator\JsonPatent;
use Psr\Http\Message\ResponseInterface;

$jsonPatent = new JsonPatent($serverRequestInterface);
// @var ResponseInterface
$jsonPatent->successCode($response, $data, $statusCode);

Sample

Use Json::class as default response generator.

<?php
use ArrayIterator\Library\Source\Generator\Json;
// make sure set request & response first to easily use method without filling ResponseInterface for each calling method
Json::setRequest($serverRequestInterface);
Json::setResponse($responseInterface);
Json::setRootDirectory($pathOfRoot);
Json::success($data); // succeed
Json::errorCode($message, $intCode);
// or just Json::errorCode($intHttpCode);

Result

Succeed

{
    "data": "mixed dataType result"
}

Error

Please make sure http code header use 4xx or 5xx as Standard Error Code

{
    "message": "mixed or string recommended dataType result"
}

Reference

https://en.m.wikipedia.org/wiki/List_of_HTTP_status_codes

@ArrayIterator
Copy link
Author

TOKEN GEN

<?php
use ArrayIterator\Library\Source\Generator\TokenGen;
$secretKey = 'secretKet';
// get token
$token = TokenGen::create($secretKey);
// validate
$validate = TokenGen::validate($token);
// get expire time
$expired = TokenGen::getExpire($secretKey);
$isExpired = TokenGen::isExpired($expired);

@dellal9h
Copy link

dellal9h commented Jun 4, 2019

502 /504 gateway I want to put it in the site bls spain visa Algeria. https://algeria.blsspainvisa.com/book_appointment.php

@ArrayIterator
Copy link
Author

@dellal9h what mean?
This is just desktop user agent generator.

@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