'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\choose_handler',
'GuzzleHttp\\describe_type' => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\choose_handler',
'GuzzleHttp\\headers_from_lines' => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\choose_handler',
'GuzzleHttp\\debug_resource' => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\choose_handler',
'GuzzleHttp\\choose_handler' => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\choose_handler',
'GuzzleHttp\\default_user_agent' => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\choose_handler',
'GuzzleHttp\\default_ca_bundle' => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\choose_handler',
'GuzzleHttp\\normalize_header_keys' => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\choose_handler',
'GuzzleHttp\\is_host_in_noproxy' => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\choose_handler',
'GuzzleHttp\\json_decode' => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\choose_handler',
'GuzzleHttp\\json_encode' => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\choose_handler',
\GuzzleHttp\LoadGuzzleFunctionsForFrdl::class => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\LoadGuzzleFunctionsForFrdl',
// 'GuzzleHttp\\Psr7\\uri_for' => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\Psr7\uri_for',
'GuzzleHttp\\Psr7\\uri_for' => 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=GuzzleHttp\Psr7\uri_for',
\Wehowski\Gist\Http\Response\Helper::class =>
'https://gist.githubusercontent.com/wehowski/d762cc34d5aa2b388f3ebbfe7c87d822/raw/5c3acdab92e9c149082caee3714f0cf6a7a9fe0b/Wehowski%255CGist%255CHttp%255CResponse%255CHelper.php?cache_bust=${salt}',
\webfan\hps\Format\DataUri::class => 'https://03.webfan.de/install/?salt=${salt}&source=webfan\hps\Format\DataUri',
'frdl\\Proxy\\' => 'https://raw.githubusercontent.com/frdl/proxy/master/src/${class}.php?cache_bust=${salt}',
\frdlweb\Thread\ShutdownTasks::class => 'https://raw.githubusercontent.com/frdl/shutdown-helper/master/src/ShutdownTasks.php?cache_bust=${salt}',
'Fusio\\Adapter\\Webfantize\\' => 'https://raw.githubusercontent.com/frdl/fusio-adapter-webfantize/master/src/${class}.php?cache_bust=${salt}',
//frdl\implementation\psr4
//Nette\Loaders\FrdlRobotLoader
'@frdl\\implementation\\Load\\ClassMap' => 'Nette\\Loaders\\FrdlRobotLoader',
'@frdl\\implementation\\Load\\RemoteClass' => __CLASS__,
// NAMESPACES
// Zend Framework components
'@Zend\\AuraDi\\Config' => 'Laminas\\AuraDi\\Config',
'@Zend\\Authentication' => 'Laminas\\Authentication',
'@Zend\\Barcode' => 'Laminas\\Barcode',
'@Zend\\Cache' => 'Laminas\\Cache',
'@Zend\\Captcha' => 'Laminas\\Captcha',
'@Zend\\Code' => 'Laminas\\Code',
'@ZendCodingStandard\\Sniffs' => 'LaminasCodingStandard\\Sniffs',
'@ZendCodingStandard\\Utils' => 'LaminasCodingStandard\\Utils',
'@Zend\\ComponentInstaller' => 'Laminas\\ComponentInstaller',
'@Zend\\Config' => 'Laminas\\Config',
'@Zend\\ConfigAggregator' => 'Laminas\\ConfigAggregator',
'@Zend\\ConfigAggregatorModuleManager' => 'Laminas\\ConfigAggregatorModuleManager',
'@Zend\\ConfigAggregatorParameters' => 'Laminas\\ConfigAggregatorParameters',
'@Zend\\Console' => 'Laminas\\Console',
'@Zend\\ContainerConfigTest' => 'Laminas\\ContainerConfigTest',
'@Zend\\Crypt' => 'Laminas\\Crypt',
'@Zend\\Db' => 'Laminas\\Db',
'@ZendDeveloperTools' => 'Laminas\\DeveloperTools',
'@Zend\\Di' => 'Laminas\\Di',
'@Zend\\Diactoros' => 'Laminas\\Diactoros',
'@ZendDiagnostics\\Check' => 'Laminas\\Diagnostics\\Check',
'@ZendDiagnostics\\Result' => 'Laminas\\Diagnostics\\Result',
'@ZendDiagnostics\\Runner' => 'Laminas\\Diagnostics\\Runner',
'@Zend\\Dom' => 'Laminas\\Dom',
'@Zend\\Escaper' => 'Laminas\\Escaper',
'@Zend\\EventManager' => 'Laminas\\EventManager',
'@Zend\\Feed' => 'Laminas\\Feed',
'@Zend\\File' => 'Laminas\\File',
'@Zend\\Filter' => 'Laminas\\Filter',
'@Zend\\Form' => 'Laminas\\Form',
'@Zend\\Http' => 'Laminas\\Http',
'@Zend\\HttpHandlerRunner' => 'Laminas\\HttpHandlerRunner',
'@Zend\\Hydrator' => 'Laminas\\Hydrator',
'@Zend\\I18n' => 'Laminas\\I18n',
'@Zend\\InputFilter' => 'Laminas\\InputFilter',
'@Zend\\Json' => 'Laminas\\Json',
'@Zend\\Ldap' => 'Laminas\\Ldap',
'@Zend\\Loader' => 'Laminas\\Loader',
'@Zend\\Log' => 'Laminas\\Log',
'@Zend\\Mail' => 'Laminas\\Mail',
'@Zend\\Math' => 'Laminas\\Math',
'@Zend\\Memory' => 'Laminas\\Memory',
'@Zend\\Mime' => 'Laminas\\Mime',
'@Zend\\ModuleManager' => 'Laminas\\ModuleManager',
'@Zend\\Mvc' => 'Laminas\\Mvc',
'@Zend\\Navigation' => 'Laminas\\Navigation',
'@Zend\\Paginator' => 'Laminas\\Paginator',
'@Zend\\Permissions' => 'Laminas\\Permissions',
'@Zend\\Pimple\\Config' => 'Laminas\\Pimple\\Config',
'@Zend\\ProblemDetails' => 'Mezzio\\ProblemDetails',
'@Zend\\ProgressBar' => 'Laminas\\ProgressBar',
'@Zend\\Psr7Bridge' => 'Laminas\\Psr7Bridge',
'@Zend\\Router' => 'Laminas\\Router',
'@Zend\\Serializer' => 'Laminas\\Serializer',
'@Zend\\Server' => 'Laminas\\Server',
'@Zend\\ServiceManager' => 'Laminas\\ServiceManager',
'@ZendService\\ReCaptcha' => 'Laminas\\ReCaptcha',
'@ZendService\\Twitter' => 'Laminas\\Twitter',
'@Zend\\Session' => 'Laminas\\Session',
'@Zend\\SkeletonInstaller' => 'Laminas\\SkeletonInstaller',
'@Zend\\Soap' => 'Laminas\\Soap',
'@Zend\\Stdlib' => 'Laminas\\Stdlib',
'@Zend\\Stratigility' => 'Laminas\\Stratigility',
'@Zend\\Tag' => 'Laminas\\Tag',
'@Zend\\Test' => 'Laminas\\Test',
'@Zend\\Text' => 'Laminas\\Text',
'@Zend\\Uri' => 'Laminas\\Uri',
'@Zend\\Validator' => 'Laminas\\Validator',
'@Zend\\View' => 'Laminas\\View',
'@ZendXml' => 'Laminas\\Xml',
'@Zend\\Xml2Json' => 'Laminas\\Xml2Json',
'@Zend\\XmlRpc' => 'Laminas\\XmlRpc',
'@ZendOAuth' => 'Laminas\\OAuth',
//https://raw.githubusercontent.com/elastic/elasticsearch-php/v7.12.0/src/autoload.php
'Elasticsearch\\' => 'https://raw.githubusercontent.com/elastic/elasticsearch-php/v7.12.0/src/${class}.php?cache_bust=${salt}',
\WeidDnsConverter::class =>
'https://raw.githubusercontent.com/frdl/oid2weid/master/src/WeidDnsConverter.php?cache_bust=${salt}',
\WeidHelper::class =>
'https://raw.githubusercontent.com/frdl/oid2weid/master/src/WeidHelper.php?cache_bust=${salt}',
\WeidOidConverter::class =>
'https://raw.githubusercontent.com/frdl/oid2weid/master/src/WeidOidConverter.php?cache_bust=${salt}',
];
public static $__SVLCCLASS_UPDATE_RACE__ = [
'https://cdn.frdl.io/@webfan3/stubs-and-fixtures/classes/frdl/implementation/psr4/RemoteAutoloader',
'https://raw.githubusercontent.com/frdl/remote-psr4/master/src/implementations/autoloading/RemoteAutoloader.php',
'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=${class}',
'https://cdn.frdl.io/@webfan3/stubs-and-fixtures/classes/${class}?salt=${salt}&version=${version}',
];
protected $salted = false;
protected $selfDomain;
protected $server;
protected $domain;
protected $version;
protected $allowFromSelfOrigin = false;
protected $prefixes = [];
protected $cacheDir;
protected $cacheLimit = 0;
protected static $instances = [];
protected $alias = [];
protected static $classmap = [];
protected $_currentClassToAutoload = null;
public static function getInstance(
$server = 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=${class}',
$register = true,
$version = 'latest',
$allowFromSelfOrigin = false,
$salted = false,
$classMap = null,
$cacheDirOrAccessLevel = self::ACCESS_LEVEL_SHARED,
$cacheLimit = null,
$password = null,
) {
if(!is_array($classMap)){
$classMap = self::CLASSMAP_DEFAULTS;
}else{
$classMap = array_merge(self::CLASSMAP_DEFAULTS, $classMap);
}
$classMap = array_merge([
'@frdl\\implementation\\Load\\ClassMap' => 'Nette\\Loaders\\FrdlRobotLoader',
'@frdl\\implementation\\Load\\RemoteClass' => static::class,
SVLClassInterface::class=>
'https://cdn.frdl.io/@webfan3/stubs-and-fixtures/classes/frdl/implementation/psr4/RemoteAutoloader',
SVLClassTrait::class =>
'https://cdn.frdl.io/@webfan3/stubs-and-fixtures/classes/frdl/implementation/psr4/RemoteAutoloader',
], $classMap);
if(is_array($server)){
$instance = [];
foreach($server as $indexOrServer => $_s){
$s=array_merge($_s, [
'server' => (is_string($indexOrServer))?$indexOrServer:$server,
'register'=>$register,
'version'=>$version,
'allowFromSelfOrigin'=>$allowFromSelfOrigin,
'salted'=>$salted,
'classmap'=>(is_string($indexOrServer)&&is_string($_s))?[$indexOrServer=>$_s]:$classmap,
'cacheDirOrAccessLevel'=>$cacheDirOrAccessLevel,
'cacheLimit'=>$cacheLimit,
'password'=>$password,
]);
$instance[(is_string($indexOrServer))?$indexOrServer:$_s] = self::getInstance(
$s['server'],
$s['register'],
$s['version'],
$s['allowFromSelfOrigin'],
$s['salted'],
$s['classmap'],
$s['cacheDirOrAccessLevel'],
$s['cacheLimit'],
$s['password']);
}
//$server = 'file://'.getcwd().\DIRECTORY_SEPARATOR;
}elseif(is_string($server)){
$key = static::ik($server, $classMap);
if(!isset(self::$instances[$key])){
self::$instances[$key] = new self($server,
$register,
$version,
$allowFromSelfOrigin,
$salted,
$classMap,
$cacheDirOrAccessLevel,
$cacheLimit,
$password);
}
$instance = self::$instances[$key];
//$instance::__FRDL_SVLC_UPDATE();
}elseif(0===count(func_get_args())){
return self::$instances;
}
return $instance;
}
public function onShutdown()
{
return call_user_func_array($this->_getShutdowner(), func_get_args());
}
public function pruneCache()
{
if($this->cacheLimit !== 0
&& $this->cacheLimit !== -1){
$this->onShutdown(function($CacheDir, $maxCacheTime){
\webfan\hps\patch\Fs::pruneDir($CacheDir, $maxCacheTime, true, 'tmp' !== basename($CacheDir));
}, $this->cacheDir, $this->cacheLimit);
}
}
public function get(string $class)
{
$that = &$this;
$r = new \stdclass;
$r->name = $class;
$r->class = [
'aliasOf'=>isset($this->alias[$class]) ? $this->alias[$class] : null,
'loaded'=>class_exists($class, false),
];
$r->remote = (isset($that->alias[$class]) ) ? false :[
'link' => $that->resolve($class),
'exists' => $that->exists($this->resolve($class)),
];
$r->local = (isset($that->alias[$class]) ) ? false :[
'link' =>$that->file($class),
'cache' => (object)[
'hit'=> file_exists($this->file($class)),
'expired'=> !file_exists($this->file($class))
|| ($interval >= 0 && (false === filemtime($this->file($class)) > time() - $interval)),
'filemtime' => (!file_exists($this->file($class))) ? 0 : filemtime($this->file($class)),
]
];
$make = function(array $options = null) use (&$that, &$make, &$r, $class){
if(!is_array($options))$options=[];
$options['class']=$class;
if(!isset($options['interval'])){
$options['interval']=-1;
}
extract($options);
if(isset($classMap)){
$that->withClassmap($classMap);
}
$r->class = array_merge($r->class, [
'autoload' => $that->Autoload($class),
'aliasOf'=>isset($that->alias[$class]) ? $that->alias[$class] : null,
'loaded'=>class_exists($class, true),
]);
$r->remote = (isset($that->alias[$class]) ) ? false : [
'link' => $that->resolve($class),
'exists' => $that->exists($this->resolve($class)),
];
$r->local = (isset($that->alias[$class]) ) ? false :[
'link' =>$that->file($class),
'cache' => (object)[
'hit'=> file_exists($this->file($class)),
'expired'=> !file_exists($this->file($class))
|| ($interval >= 0 && (false === filemtime($this->file($class)) > time() - $interval)),
'filemtime' => (!file_exists($this->file($class))) ? 0 : filemtime($this->file($class)),
],
];
return $r;
};
$r->load = $make;
$r->__construct = function() use (&$r){
return call_user_func_array($r->name().'::__construct', func_get_args());
};
return $r;
}
public function has(string $class): bool
{
return isset($this->alias[$class]) || file_exists($this->file($class)) || is_string($this->urlTemplate($class));
}
public function getCacheDir()
{
return $this->cacheDir;
}
public function file($class)
{
return rtrim($this->getCacheDir(),\DIRECTORY_SEPARATOR.'/\\ '). \DIRECTORY_SEPARATOR
. str_replace('\\', \DIRECTORY_SEPARATOR, $class). '.php';
}
public function str_contains($haystack, $needle, $ignoreCase = false)
{
if ($ignoreCase) {
$haystack = strtolower($haystack);
$needle = strtolower($needle);
}
$needlePos = strpos($haystack, $needle);
return ($needlePos === false ? false : ($needlePos+1));
}
public function str_parse_vars($string, $start = '[', $end = '/]', $variableDelimiter = '=')
{
preg_match_all('/' . preg_quote($start, '/') . '(.*?)'. preg_quote($end, '/').'/i', $string, $m);
$out = [];
foreach($m[1] as $key => $value){
$type = explode($variableDelimiter,$value);
if(sizeof($type)>1){
if(!is_array($out[$type[0]]))
$out[$type[0]] = [];
$out[$type[0]][] = $type[1];
} else {
$out[] = $value;
}
}
return $out;
}
public function resolve($class, $salt = null)
{
return $this->url($class, $salt, false);
}
public function url($class, $salt = null, $skipCheck = true)
{
if(true===$salt){
$salt = sha1(mt_rand(1000,99999999).time());
}
$url = $this->replaceUrlVars($this->urlTemplate($class, null, $skipCheck), $salt, $class, $this->version);
return $url;
}
public function urlTemplate($class, $salt = null, $skipCheck = true)
{
return $this->loadClass($class, $salt, $skipCheck);
}
public function Autoload($class)
{
$this->_currentClassToAutoload=$class;
$cacheFile =$this->file($class);
//$cacheFile = realpath($cacheFile);
if(file_exists($cacheFile)
&& ($this->cacheLimit !== 0
&& $this->cacheLimit !== -1
&& (filemtime($cacheFile) < time() - $this->cacheLimit)
)){
if($class!==\frdlweb\Thread\ShutdownTasks::class){
$this->onShutdown(function($cacheFile){
if(file_exists($cacheFile)){
unlink($cacheFile);
clearstatcache(true, $cacheFile);
}
}, $cacheFile);
}else{
unlink($cacheFile);
clearstatcache(true, $cacheFile);
}
}
if(!file_exists($cacheFile)
|| (
$this->cacheLimit !== 0
&& $this->cacheLimit !== -1
&& (filemtime($cacheFile) < time() - $this->cacheLimit)
)
){
$code = $this->fetchCode($class, null);
if(true === $code){
return true;
}elseif(false !==$code){
if(!is_dir(dirname($cacheFile))){
mkdir(dirname($cacheFile), 0775, true);
}
if(!file_put_contents($cacheFile, $code)){
throw new \Exception('Cannot write source for class '.$class.' to '.$cacheFile);
}
}else/*if(false ===$code || !file_exists($cacheFile))*/{
// die($cacheFile);
return false;
}
}
if(file_exists($cacheFile) ){
try{
if(false === ($this->requireFile($cacheFile)) ){
if(file_exists($cacheFile)){
unlink($cacheFile);
}
return false;
}
}catch(\Exception $e){
unlink($cacheFile);
throw new \Exception($e->getMessage());
}
//return true;
return class_exists($class, false);
}elseif(isset($code) && is_string($code)){
/*
$code =ltrim($code, '');
eval($code);
*/
//$tmpfile = tmpfile();
$tmpfile = tempnam($this->cacheDir, 'autoloaded-file.'.sha1($code));
file_put_contents($tmpfile, $code);
if($class!==\frdlweb\Thread\ShutdownTasks::class){
$this->onShutdown(function($tmpfile){
if(file_exists($tmpfile)){
unlink($tmpfile);
}
}, $tmpfile);
}
if(false === ($this->requireFile($tmpfile)) ){
return false;
}else{
return class_exists($class, false);
}
}else{
throw new \Exception('Cannot write/load source for class '.$class.' in '.$cacheFile);
}
}
public static function ik($server, $classMap)
{
if(is_array($classMap)){
ksort($classMap);
}
$hashingData=[$server, $classMap];
return sha1(var_export( $hashingData , true));
}
protected function __construct(
$server = 'https://03.webfan.de/install/?salt=${salt}&version=${version}&source=${class}',
$register = true,
$version = 'latest',
$allowFromSelfOrigin = false,
$salted = false,
$classMap = null,
$cacheDirOrAccessLevel = self::ACCESS_LEVEL_SHARED,
$cacheLimit = null,
$password = null,
) {
$defauoltcacheLimit = -1;
$bucketHash = $this->generateHash([
self::class//,
// $version
],
'',
self::HASH_ALGO,
'-');
switch($cacheDirOrAccessLevel){
case self::ACCESS_LEVEL_PUBLIC :
$bucket = \get_current_user().\DIRECTORY_SEPARATOR.'shared';
break;
case self::ACCESS_LEVEL_OWNER :
$bucket = \get_current_user().\DIRECTORY_SEPARATOR
.$this->generateHash([
$bucketHash,
$version,
\get_current_user ( ),
//$_SERVER['SERVER_NAME']
// $_SERVER['SERVER_ADDR']
],
$password,
self::HASH_ALGO,
'-');
break;
case self::ACCESS_LEVEL_PROJECT :
$bucket = \get_current_user ( ).\DIRECTORY_SEPARATOR
.$this->generateHash([
$bucketHash,
$version,
\get_current_user ( ),
$_SERVER['SERVER_NAME'],
$_SERVER['SERVER_ADDR'],
basename(getcwd()),
realpath(getcwd()),
],
$password,
self::HASH_ALGO,
'-');
break;
case self::ACCESS_LEVEL_BUCKET :
$bucket = \get_current_user ( ).\DIRECTORY_SEPARATOR .$this->generateHash([
$bucketHash,
$version
],
$password,
self::HASH_ALGO,
'-');
break;
case self::ACCESS_LEVEL_CONTEXT :
$bucket = \get_current_user ( ).\DIRECTORY_SEPARATOR
.$this->generateHash([
$bucketHash,
$version,
\get_current_user ( ),
$_SERVER['SERVER_NAME'],
$_SERVER['SERVER_ADDR'],
$_SERVER['REMOTE_ADDR'],
basename(getcwd()),
realpath(getcwd())
],
$password,
self::HASH_ALGO,
'-');
break;
case self::ACCESS_LEVEL_SHARED :
default:
$bucket = '_'.\DIRECTORY_SEPARATOR.'shared';
break;
}
$this->cacheLimit = (is_int($cacheLimit)) ? $cacheLimit : ((isset($_ENV['FRDL_HPS_PSR4_CACHE_LIMIT']))? $_ENV['FRDL_HPS_PSR4_CACHE_LIMIT'] : $defauoltcacheLimit);
$this->cacheDir = (is_string($cacheDirOrAccessLevel) && is_dir($cacheDirOrAccessLevel) && is_readable($cacheDirOrAccessLevel) && is_writeable($cacheDirOrAccessLevel) )
? $cacheDirOrAccessLevel
: \sys_get_temp_dir().\DIRECTORY_SEPARATOR
// .'.frdl'.\DIRECTORY_SEPARATOR
.$bucket.\DIRECTORY_SEPARATOR
.'lib'.\DIRECTORY_SEPARATOR
.'php'.\DIRECTORY_SEPARATOR
.'src'.\DIRECTORY_SEPARATOR
.'psr4'.\DIRECTORY_SEPARATOR;
/* */
$valCacheDir;
$valCacheDir = (function($CacheDir, $checkAccessable = true, $checkNotIsSysTemp = true, $r = null) use(&$valCacheDir){
if(null ===$r)$r=dirname($CacheDir);
$checkRoot = substr($r, 0, strlen($CacheDir) );
$checkSame = $r === $CacheDir;
$checked = false === $checkNotIsSysTemp
|| false === $checkSame
|| (
(
rtrim($CacheDir, \DIRECTORY_SEPARATOR.'/\\ ') !== rtrim(\sys_get_temp_dir(),\DIRECTORY_SEPARATOR.'/\\ ')
&& 'tmp' !== basename($CacheDir)
// && 'tmp' !== basename(dirname($CacheDir))
)
);
return (
$checkAccessable === false
||
(
// (//is_dir($CacheDir)
// || is_dir(dirname($CacheDir))
//|| is_dir(dirname(dirname($CacheDir)))
// ||
// $valCacheDir($r, false, false, $CacheDir)
// )
//&&
is_writable($CacheDir)
&& is_readable($CacheDir)
)
)
&& true === $checked
? true
: false
;
});
if(!$valCacheDir($this->cacheDir,false,false) ){
throw new \Exception('Bootstrap error in '.basename(__FILE__).' '.__LINE__.' for '.$this->cacheDir);
}
if(!is_dir($this->cacheDir)){
mkdir($this->cacheDir, 0777,true);
}
//die($this->cacheDir);
if(!is_array($classMap)){
$classMap = self::CLASSMAP_DEFAULTS;
}
$this->withSalt($salted);
$this->withClassmap($classMap);
$this->allowFromSelfOrigin = $allowFromSelfOrigin;
$this->version=$version;
$this->server = $server;
$_self = (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'];
$h = explode('.', $_self);
$dns = array_reverse($h);
$this->selfDomain = $dns[1].'.'.$dns[0];
$h = explode('.', $this->server);
$dns = array_reverse($h);
$this->domain = $dns[1].'.'.$dns[0];
if(!$this->allowFromSelfOrigin && $this->domain === $this->selfDomain){
$register = false;
}
if(true === $register){
$this->register();
}
}
public function generateHash(array $chunks = [], $key = null, $algo = 'sha1', $delimiter = '-', &$ctx = null)
{
$size = count($chunks);
$initial = null === $ctx;
$asString = serialize($chunks);//implode($delimiter, $chunks);
$buffer = '';
$l = 0;
$c = $size + ($initial);
if(null===$key || empty($key)){
$c++;
$key = \hash( $algo , serialize([$delimiter, [$algo,$size, $delimiter, $c, $asString]]) );
}
$MetaCtx = \hash_init ( $algo , \HASH_HMAC, $key ) ;
\hash_update($MetaCtx, $key);
if( true === $initial || null === $ctx){
$ctx = \hash_init ( $algo , \HASH_HMAC, $key ) ;
}
while(count($chunks) > 0 && $data = array_shift($chunks)){
$buffer .=$data;
$l += strlen($data);
$c += count($chunks);
\hash_update($ctx, $data);
\hash_update($MetaCtx, $buffer);
\hash_update($MetaCtx, $l);
\hash_update($MetaCtx, $c);
}
$c++;
//$h2 = $this->generateHash([$algo,count($chunks),$l,$asString, $delimiter, $key, $c], $key, 'sha1', $delimiter, $ctx);
$h2 = \hash( $algo , $size .'.'. $l. '.' . $c. '.' . strlen($buffer.$asString) );
\hash_update($ctx, $h2);
\hash_update($MetaCtx, $h2);
$c++;
$h3 = hash_final($MetaCtx);
\hash_update($ctx, $h3);
$hash = hash_final($ctx);
return implode($delimiter, [$size .'.'. $l. '.' . $c. '.' . (strlen($h2.$buffer.$asString) * $c) % 20,
$h3,
$hash,
$h2]);
}
public function withNamespace($prefix, $server, $prepend = false)
{
$prefix = trim($prefix, '\\') . '\\';
// normalize the base directory with a trailing separator
// $base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/';
// initialize the namespace prefix array
if (isset($this->prefixes[$prefix]) === false) {
$this->prefixes[$prefix] = [];
}
// retain the base directory for the namespace prefix
if ($prepend) {
array_unshift($this->prefixes[$prefix], $server);
} else {
array_push($this->prefixes[$prefix], $server);
}
}
public function getUrl($class, $server, $salt = null, $parseVars = false)
{
if(!is_string($salt))$salt=mt_rand(1000,9999);
$url = false;
if(is_string($server) ){
if(substr($server, 0, strlen('http://')) === 'http://' || substr($server, 0, strlen('https://')) === 'https://'){
// $url = str_replace(['${salt}', '${class}', '${version}'], [$salt, $class, $this->version], $server);
$url = $server;
}elseif('~' === substr($server, 0, 1) || is_string($server) && '.' === substr($server, 0, 1) || substr($server, 0, strlen('file://')) === 'file://'){
$url = \DIRECTORY_SEPARATOR.str_replace('\\', \DIRECTORY_SEPARATOR,
getcwd() .str_replace(['file://', '~'/*, '${salt}', '${class}', '${version}'*/],
['', (!empty(getenv('FRDL_HOME'))) ? getenv('FRDL_HOME') : getenv('HOME')/*, $salt, $class, $this->version*/],
$server). '.php');
}elseif(preg_match("/^([a-z0-9]+)\.webfan\.de$/", $server, $m) && false === strpos($server, '/') ){
$url = 'https://'.$m[1].'.webfan.de/install/?salt=${salt}&source=${class}&version=${version}';
}elseif(preg_match("/^([\w\.^\/]+)(\/[.*]+)?$/", $server, $m) && false !== strpos($server, '.') ){
$url = 'https://'.$m[1].((isset($m[2])) ? $m[2] : '/');
}//else{
// $url = 'https://'.$server.'/install/?salt='.$salt.'&source='. $class.'&version='.$this->version;
//$url = 'https://'.$server.'/install/?salt=${salt}&source=${class}&version=${version}';
// }
if(!$this->str_contains($url, '${class}', false) && '.php' !== substr(explode('?', $url)[0], -4)){
$url = rtrim($url, '/').'/${class}';
}
if(!$this->str_contains($url, '${salt}', false)){
$url .= (( $this->str_contains($url, '?', false) ) ? '&' : '?').'salt=${salt}';
}
}elseif(is_callable($server)){
$url = call_user_func_array($server, [$class, $this->version, $salt]);
}elseif(is_object($server) && is_callable([$server, 'has']) && is_callable([$server, 'get']) && true === call_user_func_array([$server, 'has'], [$class]) ){
$url = call_user_func_array([$server, 'get'], [$class, $this->version, $salt]);
}elseif(is_object($server) && is_callable([$server, 'get']) ){
$url = call_user_func_array([$server, 'get'], [$class, $this->version, $salt]);
}
return (true === $parseVars && is_string($url)) ? $this->replaceUrlVars($url, $salt, $class, $version) : $url;
}
public function replaceUrlVars($_url, $salt, $class, $version)
{
$url = str_replace(['${salt}', '${class}', '${version}'], [$salt, $class, $version], $_url);
if(substr($_url,0, strlen('http'))==='http'
&& (
!$this->str_contains($_url, '=${class}', false)
|| !preg_match("/".preg_quote('=${class}')."/",$_url)
)
){
$url = preg_replace('/\\\\/', '/', $url);
}
return $url;
}
/**
* Loads the class file for a given class name.
*
* @param string $class The fully-qualified class name.
* @return mixed The mapped file name on success, or boolean false on
* failure.
*/
public function loadClass($class, $salt = null, $skipCheck = false)
{
$prefix = $class;
// work backwards through the namespace names of the fully-qualified
// class name to find a mapped file name
while (false !== $pos = strrpos($prefix, '\\')) {
// retain the trailing namespace separator in the prefix
$prefix = substr($class, 0, $pos + 1);
// the rest is the relative class name
$relative_class = substr($class, $pos + 1);
// try to load a mapped file for the prefix and relative class
$mapped_file = $this->loadMappedSource($prefix, $relative_class, $salt, $skipCheck);
if ($mapped_file) {
return $mapped_file;
}
// remove the trailing namespace separator for the next iteration
// of strrpos()
$prefix = rtrim($prefix, '\\');
}
// never found a mapped file
return $this->loadMappedSource('', $class, $salt, $skipCheck);
}
/**
* Load the mapped file for a namespace prefix and relative class.
*
* @param string $prefix The namespace prefix.
* @param string $relative_class The relative class name.
* @return mixed Boolean false if no mapped file can be loaded, or the
* name of the mapped file that was loaded.
*/
protected function loadMappedSource($prefix, $relative_class, $salt = null, $skipCheck = false)
{
$url = false;
$class = $prefix.$relative_class;
//if(isset($this->alias[$class]) ){
// \webfan\hps\Format\DataUri
// die(__LINE__.$class.' Alias: '.$this->alias[$class]);
// }
$pfx = !isset($this->alias[$prefix]) && substr($prefix,-1) === '\\' ? substr($prefix, 0, -1) : $prefix;
if(isset($this->alias[$pfx]) ){
// \webfan\hps\Format\DataUri
$originalClass = substr($this->alias[$pfx],-1) === '\\' ? substr($this->alias[$pfx], 0, -1) : $this->alias[$pfx];
$originalClass .= '\\'.$relative_class;
$alias = $class;
// die($classOrInterfaceExists.'
'.$alias.'
rc: '.$originalClass.'
'.$datUri);
$classOrInterfaceExistsAndNotEqualsAlias =(
class_exists($originalClass, $originalClass !== $alias)
|| interface_exists($originalClass, $originalClass !== $alias)
|| (function_exists('trait_exists') && trait_exists($originalClass, $originalClass !== $alias))
) && $originalClass !== $alias;
if($classOrInterfaceExistsAndNotEqualsAlias){
\class_alias($originalClass, $alias);
}
return true;
//return $classOrInterfaceExistsAndNotEqualsAlias;
}
if (isset($this->prefixes[$prefix]) ) {
// look through base directories for this namespace prefix
foreach ($this->prefixes[$prefix] as $server) {
$url = $this->getUrl($relative_class, $server, $salt);
if(is_string($url)
&& (false === $skipCheck || $this->exists($url) )
// && '\\' !== substr($class, -1)
&& '\\' !== substr(self::$classmap[$class], -1)
){
$url = $this->replaceUrlVars($url, $salt, $relative_class, $this->version);
return $url;
}
}
}
if(
isset(self::$classmap[$class])
&& is_string(self::$classmap[$class])
// && '\\' !== substr($class, -1)
&& '\\' !== substr(self::$classmap[$class], -1)
){
return $this->getUrl($class, self::$classmap[$class], $salt);
// return self::$classmap[$class];
}
// never found it
return $this->getUrl($class, $this->server, $salt);
}
/**
* If a file exists, require it from the file system.
*
* @param string $file The file to require.
* @return bool True if the file exists, false if not.
*/
protected function requireFile($file)
{
if (file_exists($file)) {
try{
require $file;
}catch(\Exception $e){
trigger_error($e->getMessage(), \E_USER_ERROR);
return false;
}
return true;
}
return false;
}
public function withClassmap(array $classMap = null)
{
if(null !== $classMap){
foreach($classMap as $class => $server){
if('@' === substr($class, 0, 1) && is_string($server)){
$this->withAlias($class, $server);
}elseif('\\' === substr($class, -1)){
$this->withNamespace($class, $server, is_string($server));
}else{
self::$classmap[$class] = $server;
}
}
}
return self::$classmap;
}
public function withAlias(string $alias, string $rewrite)
{
$this->alias[ltrim($alias, '@')] = $rewrite;
}
public function withSalt(bool $salted = null)
{
if(null !== $salted){
$this->salted = $salted;
}
return $this->salted;
}
public static function __callStatic($name, $arguments)
{
$me = (count(self::$instances)) ? self::$instances[0] : self::getInstance();
return call_user_func_array([$me, $name], $arguments);
}
public function __call($name, $arguments)
{
if(!in_array($name, ['fetch', 'fetchCode', '__invoke', 'register', 'getLoader', 'Autoload'])){
throw new \Exception('Method '.$name.' not allowed in '.__METHOD__);
}
return call_user_func_array([$this, $name], $arguments);
}
protected function fetch()
{
return call_user_func_array([$this, 'fetchCode'], func_get_args());
}
protected function exists($source)
{
if('http://'!==substr($source, 0, strlen('http://'))
&& 'https://'!==substr($source, 0, strlen('https://'))
&& is_file($source) && file_exists($source) && is_readable($source)){
return true;
}
$options = [
'https' => [
'method' => 'HEAD',
'ignore_errors' => true,
]
];
$context = stream_context_create($options);
$res = @file_get_contents($source, false, $context);
return false !== $res;
}
protected function fetchCode($class, $salt = null)
{
if(!is_string($salt)
//&& true === $this->withSalt()
){
$salt = mt_rand(10000000,99999999);
}
// $url = $this->loadClass($class, $salt, false);
$url = $this->resolve($class, $salt);
if(is_bool($url)){
return $url;
}
$withSaltedUrl = (true === $this->str_contains($url, '${salt}', false)) ? true : false;
// $url = $this->replaceUrlVars($url, $salt, $class, $this->version);
// print_r($url.'
');
$options = [
'https' => [
'method' => 'GET',
'ignore_errors' => true,
]
];
$context = stream_context_create($options);
$code = @file_get_contents($url, false, $context);
$statusCode = 0;
//$code = file_get_contents($url);
if(isset($http_response_header) && is_array($http_response_header)){
foreach($http_response_header as $i => $header){
if(0===$i){
preg_match('{HTTP\/\S*\s(\d{3})}', $header, $match);
$statusCode = intval($match[1]);
}
$h = explode(':', $header);
if('x-content-hash' === strtolower(trim($h[0]))){
$hash = trim($h[1]);
}
if('x-user-hash' === strtolower(trim($h[0]))){
$userHash = trim($h[1]);
}
}
} else{
}
if( 200!==$statusCode
|| false===$code
|| !is_string($code)
|| (true === $withSaltedUrl && true === $this->withSalt() && (!isset($hash) || !isset($userHash)))
){
// throw new \Exception('Missing checksums while fetching source code for '.$class.' from '.$url);
return false;
}
$oCode =$code;
if(is_string($salt) && true === $withSaltedUrl && true === $this->withSalt() ){
$hash_check = strlen($oCode).'.'.sha1($oCode);
$userHash_check = sha1($salt .$hash_check);
if($hash_check !== $hash || $userHash_check !== $userHash){
throw new \Exception('Invalid checksums while fetching source code for '.$class.' from '.$url);
}
}
$code = trim($code);
if(!$this->str_contains($code, '', false)){
throw new \Exception('Invalid source code for '.$class.' from '.$url.': '.base64_encode($code));
}
if(' ');
$codeWithStartTags = "getLoader(), func_get_args());
}
public function register($throw = true, $prepend = false)
{
$res = false;
if(!$this->allowFromSelfOrigin && $this->domain === $this->selfDomain){
throw new \Exception('You should not autoload from remote where you have local access to the source (remote server = host)');
}
$aFuncs = \spl_autoload_functions();
if(!is_array($aFuncs) || !in_array($this->getLoader(), $aFuncs) ){
$res = \spl_autoload_register($this->getLoader(), $throw, $prepend);
}
if( false !== $res ){
$this->pruneCache();
}else{
throw new \Exception(sprintf('Cannot register Autoloader of "%s" with cachedir "%s"', __METHOD__, $this->cacheDir));
}
return $res;
}
protected function getLoader()
{
return [$this, 'Autoload'];
}
protected function _getShutdowner()
{
$load = $this->_currentClassToAutoload !== \frdlweb\Thread\ShutdownTasks::class;
return (class_exists(\frdlweb\Thread\ShutdownTasks::class, $load ))
? \frdlweb\Thread\ShutdownTasks::mutex()
: function(){
call_user_func_array('register_shutdown_function', func_get_args());
register_shutdown_function(function(){
$t = class_exists(\frdlweb\Thread\ShutdownTasks::class, $load);
});
};
}
}
__halt_compiler();----SIGNATURE:----EFZN+RuTVDDe8bu4bzJC03XF3FxSvXyqrvqQF1qCJz4A3iK4fj8tpIk3oG5yfcj/bxYPPdsdUKMoyeskdi9s3GONciy9VTiOc0bOvN/mCEN/MUztHjmrvv9Rtid2rsEG8muYGO1gBRGEGt6g7G6b8bBtWaMbk+QwWBSxdsp5C//8Oq+GcH0uqBeMgJbzRLhJ3N139DGyoYnII9Nk/aB0xhvOLM1wKFexU8Fe5tE5pkR/LAWLmdSy+tNXcunsZpfm1e2Elu2Waumknx4c2fpA5sjQKNxk8ZcA8YbUKodPJUgLjycf5iAFxDa1ApT0KstemdU5hSpw2pcKLwBqRYoHy4k9nFuQZIDjzBtmPZ7PyvNX1rcld8a//4/Wrnlk8hDNPZBVyvCkt2yu2pc1A25m2IdN3KXRxqU2FfcAFBmQlw0QnG3OVf6Ob2tL2GPxKKm/V623kZaqKGP4AS5+I0UHVlM+oSQ35yAeN3xrh5ZZegMwvOTu1sfTI+a4yBf5nQDp9B5CQoIE03oa7WEeu4yiCAEdqPQZEA0+EeVDrK7//FtT8wGTploTIsdkONuhCbjs/2lFXPNeEVlA9lLS4YrXpS7bg8on3+LjEOBT0ssW9292FE3Rh3VqW7Amu8W1z5z1D37gc19TeKLGxVHt+kSaN4p8bAg1Sou30t1TtlgcglE=----ATTACHMENT:----MzY5NDY2NTI2NzY3NzU2MSAyMzMwNzU0MTc5MzgwMDA5IDc5MDQ0ODg5MDMwODMxMjI=