'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, ' '); $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=