$GLOBALS["pnkit_mode"] = "online";$GLOBALS["pnkit_version"] = "2024-11-20T19:08:45+01:00"; /******************************************************************************/ // PORTABLE NKIT // // Usage online: eval (file_get_contents ("https://pnkit.fastsimple.com")); // Usage offline: include "pnkit_main.php"; /******************************************************************************/ // START // Less warnings PHP 8.1+ if (@!$_SERVER["REMOTE_ADDR"]) $_SERVER["REMOTE_ADDR"] = null; if (@!$GLOBALS["pnkit_data_dir"]) $GLOBALS["pnkit_data_dir"] = null; if (@!$GLOBALS["pnkit_public_cache_dir_internal"]) $GLOBALS["pnkit_public_cache_dir_internal"] = null; if (@!$GLOBALS["pnkit_owner_ip"]) $GLOBALS["pnkit_owner_ip"] = null; if (!function_exists("puuse")) { // Allow multiple loadings $GLOBALS["MS_start"] = microtime(true); register_shutdown_function (function(){register_shutdown_function (function(){ // Executing this code should be the last thing to do $elapsed = microtime(true) - $GLOBALS["MS_start"]; file_put_contents ($GLOBALS['pnkit_data_dir'] . '/profile'.date ("H", time()).'.html', time()." ".$elapsed." ".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']."\n", FILE_APPEND); if (!rand (0, 100)) @unlink ($GLOBALS['pnkit_data_dir'] . '/profile'.date ("H", time() - 6*3600).'.html'); });}); if (@exec('date +%Z')) date_default_timezone_set (timezone_name_from_abbr (exec('date +%Z'))); // Use the Linux OS timezone as PHP timezone /******************************************************************************/ // MODULES function file_get_contents_classic ($url) { $content = @file_get_contents ($url); if (!$content) $content = @file_get_contents (str_replace ("https", "http", $url)); // E.g. Synology PHP does not do https return $content; } function puuse() { global $PUUSE_Modules; $modules = func_get_args(); if (!$modules || $modules==[""]) { if ($PUUSE_Modules["all"] == 'loaded') return; $PUUSE_Modules["all"] = 'loaded'; if ($GLOBALS['pnkit_mode'] == 'online') { $all = unserialize(file_get_contents_classic("https://www.fastsimple.com/pnkit/pnkitweb_loader.php?allmodules=show")); foreach ($all as $module => $php) { if ($PUUSE_Modules[$module] != 'loaded') { $PUUSE_Modules[$module] = 'loaded'; eval($php); } } return; } else { $modules = puuse_allmodules(); } } foreach ($modules as $module) { $module = strtolower($module); if ($PUUSE_Modules[$module] != 'loaded') { $PUUSE_Modules[$module] = 'loaded'; if ($GLOBALS['pnkit_mode'] == 'online') { $php = file_get_contents_classic("https://fastsimple.com/pnkit/pnkitweb_loader.php?module=$module"); eval($php); } else { $pathinfo = pathinfo(__FILE__); include $pathinfo['dirname'] . "/puuse_$module.php"; } } } } function puuse_allmodules() { if ($GLOBALS['pnkit_mode'] == 'online') { $list = unserialize(file_get_contents_classic("https://www.fastsimple.com/pnkit/pnkitweb_loader.php?modulelist=show")); return $list; } else { $pathinfo = pathinfo(__FILE__); $d = dir($pathinfo["dirname"]); while (false !== ($entry = $d->read())) { if (strstr($entry, "puuse_")) { $list[] = N_KeepAfter(N_KeepBefore($entry, ".php"), "puuse_"); } } $d->close(); return $list; } } function muuse_register ($module, $relative_path) { if (!strlen (file_get_contents ($_SERVER['DOCUMENT_ROOT'].$relative_path))) die ("muuse_register: Fatal Error: Cannot find ".$_SERVER['DOCUMENT_ROOT'].$relative_path); PMB_Save ("pnkit_modules", $module, $relative_path); muuse_show (); } function muuse_remove ($module) { PMB_Delete ("pnkit_modules", $module); muuse_show (); } function muuse_show ($as_title=false) { foreach (PMB_AllKeys ("pnkit_modules") as $module) { if ($as_title) { $content .= "[$module] ".PMB_Load ("pnkit_modules", $module)."\n"; } else { $content .= "$module ".PMB_Load ("pnkit_modules", $module)."
"; } } $content .= 'Add modules with muuse_register ($module, $relative_path)'."\n".'Remove with muuse_remove ($module)'; if (!$as_title) echo $content; else return $content; } function muuse () { global $MUUSE_Modules; $modules = func_get_args(); if (!$modules || $modules==[""]) { puuse(); // One call to load absolutely everything $modules = PMB_AllKeys ("pnkit_modules"); } foreach ($modules as $module) { $module = strtolower($module); if ($MUUSE_Modules[$module] != 'loaded') { $MUUSE_Modules[$module] = 'loaded'; include $_SERVER['DOCUMENT_ROOT'].PMB_Load ("pnkit_modules", $module); } } } /******************************************************************************/ // BACKGROUND PROCESSING function N_MultiExec ($code, $input=array()) { $handle = N_GUID(); PMB_Save ("exec_now_code", $handle, $code); PMB_Save ("exec_now_input", $handle, $input); $GLOBALS["N_MultiExec"][$handle]["code"] = $code; $GLOBALS["N_MultiExec"][$handle]["input"] = $input; return $handle; } function N_MultiResult ($handle, $timeout = 5) { foreach ($GLOBALS["N_MultiExec"] as $h => $state) { if (!$state["executed"]) { $urls[] = ($_SERVER["REQUEST_SCHEME"] ? $_SERVER["REQUEST_SCHEME"] : "http") . "://" . $_SERVER["HTTP_HOST"] . $_SERVER["SCRIPT_NAME"] . "?pnkitexecnow=$h"; $GLOBALS["N_MultiExec"][$h]["executed"] = true; } } if ($urls) foreach (N_MultiGetPage ($urls, $timeout) as $url => $response) { $h = N_KeepAfter ($url, "now="); $result = unserialize ($response["content"]); if ($result["status"]=="ok") { $GLOBALS["N_MultiExec"][$h]["completed"] = true; $GLOBALS["N_MultiExec"][$h]["output"] = $result["output"]; } } if (!$GLOBALS["N_MultiExec"][$handle]["completed"]) { $input = $GLOBALS["N_MultiExec"][$handle]["input"]; eval ($GLOBALS["N_MultiExec"][$handle]["code"]); $GLOBALS["N_MultiExec"][$handle]["completed"] = true; $GLOBALS["N_MultiExec"][$handle]["output"] = $output; } return $GLOBALS["N_MultiExec"][$handle]["output"]; } function N_MultiGetPage ($urls, $timeout = 5) { $multiHandle = curl_multi_init(); $curlHandles = []; $headers = array(); $headers[] = "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"; // $headers[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"; $headers[] = "Cache-Control: max-age=0"; $headers[] = "Connection: keep-alive"; $headers[] = "Keep-Alive: 300"; $headers[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7"; $headers[] = "Accept-Language: en-us,en;q=0.5"; $headers[] = "Pragma: "; foreach ($urls as $url) { $handle = curl_init(); curl_setopt($handle, CURLOPT_URL, $url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); curl_setopt($handle, CURLOPT_TIMEOUT, $timeout); curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, min (5, $timeout)); curl_setopt($handle, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"); // curl_setopt($handle, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"); curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($handle, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($handle, CURLOPT_AUTOREFERER, true); curl_setopt($handle, CURLOPT_COOKIESESSION, true); curl_setopt($handle, CURLOPT_HTTPHEADER, $headers); curl_multi_add_handle ($multiHandle, $handle); $curlHandles[] = $handle; } $active = null; do { $mrc = curl_multi_exec ($multiHandle, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM || $active); $results = []; foreach ($curlHandles as $handle) { $url = curl_getinfo ($handle, CURLINFO_EFFECTIVE_URL); $results[$url] = [ 'content' => curl_multi_getcontent ($handle), 'response_code' => curl_getinfo ($handle, CURLINFO_HTTP_CODE), ]; curl_multi_remove_handle ($multiHandle, $handle); curl_close ($handle); } curl_multi_close($multiHandle); return $results; } function N_HandleExecNow ($exec_now_key) { $code = PMB_Load("exec_now_code", $exec_now_key); $input = PMB_Load("exec_now_input", $exec_now_key); eval ($code); PMB_Flush(); echo serialize (array ("status"=>"ok", "output"=>$output)); PMB_Delete("exec_now_code", $exec_now_key); PMB_Delete("exec_now_input", $exec_now_key); } function N_ExecInBackground ($code, $input = NULL) { global $exec_in_background_code, $exec_in_background_input; if (!$exec_in_background_code) register_shutdown_function('N_FlushExecInBackground'); $exec_in_background_code[] = $code; $exec_in_background_input[] = $input; } function N_FlushExecInBackground() { global $exec_in_background_code, $exec_in_background_input; if ($exec_in_background_code) { $key = N_GUID(); PMB_Save("exec_in_background_code", $key, $exec_in_background_code); PMB_Save("exec_in_background_input", $key, $exec_in_background_input); $url = ($_SERVER["REQUEST_SCHEME"] ? $_SERVER["REQUEST_SCHEME"] : "http") . "://" . $_SERVER["HTTP_HOST"] . $_SERVER["SCRIPT_NAME"] . "?pnkitexec&key=$key"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100); // optimized value is 50, we use 100 to reduce chance of failure curl_exec($ch); $exec_in_background_code = $exec_in_background_input = array(); } } function N_HandleExecInBackground ($exec_in_background_key) { ignore_user_abort(true); $exec_in_background_codes = PMB_Load("exec_in_background_code", $exec_in_background_key); $exec_in_background_inputs = PMB_Load("exec_in_background_input", $exec_in_background_key); if ($exec_in_background_codes) foreach ($exec_in_background_codes as $exec_in_background_index => $code) { $input = $exec_in_background_inputs[$exec_in_background_index]; eval($code); PMB_Flush(); } PMB_Delete("exec_in_background_code", $exec_in_background_key); PMB_Delete("exec_in_background_input", $exec_in_background_key); } function N_ExecInBackgroundBacklog() { $now = time(); $keys = PMB_Query("exec_in_background_code"); foreach ($keys as $key) { N_HandleExecInBackground($key); if (time() - $now > 300) break; } } /******************************************************************************/ // ASSETS function N_MimeMap() { return array('css' => 'text/css', 'js' => 'text/javascript', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', 'woff' => 'font/woff', 'woff2' => 'font/woff2', 'webp' => 'image/webp'); } function N_ImageEmbedURL ($filename, $content) { $mimetype = N_MimeMap()[pathinfo($filename, PATHINFO_EXTENSION)]; return "data:$mimetype;base64,".base64_encode ($content); } function N_AssetContent ($subpath) { return N_Cache (24, "file_get_contents", "https://fastsimple.com/pnkit/$subpath"); } function N_Asset($subpath = '') { if ($GLOBALS["N_AssetRelPath"]) { return $GLOBALS["N_AssetRelPath"].$subpath; } if ($GLOBALS['pnkit_mode'] == 'online') { $v = "v".PMB_Load ("pnkit", "last_pnkit_code_save"); $rp = $_SERVER['SCRIPT_NAME'] . "?v=$v&pnkitassets=/"; } else { $pathinfo = pathinfo(str_replace('./', '/', N_getRelativePath($_SERVER['DOCUMENT_ROOT'], __FILE__))); $rp = $pathinfo['dirname'] . '/'; } return "$rp$subpath"; } function N_DynAsset($mime, $asset_data) { if (strlen($asset_data) > 1024) { $ext = array_search($mime, N_MimeMap()); if (!$ext) $ext = "txt"; $asset_id = md5($asset_data) . ".$ext"; if (!N_CacheAssetExists($asset_id)) N_CacheAssetSave($asset_id, $asset_data); return N_CacheAsset($asset_id); } else { return $_SERVER['SCRIPT_NAME'] . '?pnkitdynasset&mime=' . urlencode($mime) . '&b64_data=' . urlencode(base64_encode($asset_data)); } } function N_CacheAsset($asset_id) { return $GLOBALS["pnkit_public_cache_dir_external"] . "/$asset_id"; } function N_CacheAssetExists($asset_id) { return @file_exists($GLOBALS["pnkit_public_cache_dir_internal"] . "/$asset_id"); } function N_CacheAssetSave($asset_id, $asset_data) { file_put_contents($GLOBALS["pnkit_public_cache_dir_internal"] . "/$asset_id", $asset_data); } function N_CacheAssetLoad($asset_id) { return file_get_contents($GLOBALS["pnkit_public_cache_dir_internal"] . "/$asset_id"); } function N_CacheAssetDelete($asset_id) { @unlink($GLOBALS["pnkit_public_cache_dir_internal"] . "/$asset_id"); } function N_PNFavIcon($minilabel = 'PN', $back="rgb(0,0,128)", $front = "white") { if ($minilabel=="|") { return ''; } else if ($minilabel=="cube") { return ''; } puuse("ui"); $icon = ''; $icon .= ''; return $icon; } /******************************************************************************/ // PORTABLE NKIT DATABASE FUNCTIONS function PMB_Merge ($table, $key, $merge) { $object = PMB_Load ($table, $key); if (is_array ($object) && is_array ($merge)) { foreach ($merge as $k => $v) { $object[$k] = $v; } } else { $object = $merge; } PMB_Save ($table, $key, $object); } function PMB_LoadTable ($table, $sort = '$key') { $result = array(); $keys = PMB_Query($table, '1==1', $sort); foreach ($keys as $key => $dummy) { $result[$key] = PMB_Load ($table, $key); } return $result; } function &PMB_Ref($table, $key) { if (!$table) trigger_error ("PMB_Ref($table, $key) needs a table ($table)", E_USER_ERROR); if (!$key) trigger_error ("PMB_Ref($table, $key) needs a key ($key)", E_USER_ERROR); global $PMB_FlushOnExit; if (!$PMB_FlushOnExit) { register_shutdown_function('PMB_FlushOnExit'); $PMB_FlushOnExit = true; } global $pmb_inmemorycache, $pmb_inmemorycopy; if ($pmb_inmemorycache[$table][$key]) return $pmb_inmemorycache[$table][$key]; $pmb_inmemorycache[$table][$key] = PMB_Load($table, $key); $pmb_inmemorycopy[$table][$key] = $pmb_inmemorycache[$table][$key]; return $pmb_inmemorycache[$table][$key]; } function PMB_Flush() { global $pmb_inmemorycache, $pmb_inmemorycopy; if (is_array($pmb_inmemorycache)) { foreach ($pmb_inmemorycache as $table => $allrecords) { foreach ($allrecords as $key => $object) { if ($object != $pmb_inmemorycopy[$table][$key]) { PMB_Save($table, $key, $object); $pmb_inmemorycopy[$table][$key] = $object; } } } } } function PMB_FlushOnExit () { PMB_Flush(); } function PMB_FlushAndClean() { global $pmb_inmemorycache, $pmb_inmemorycopy; PMB_Flush(); $pmb_inmemorycache = $pmb_inmemorycopy = array(); } function PMB_Query($table, $constraint = '1==1', $sort = '$key') { if (!$constraint) $constraint = '1==1'; if (!$sort) $sort = '$key'; $GLOBALS["calls"]["PMB_Query"]++; $GLOBALS["calllog"][] = "PMB_Query($table, $constraint, $sort)"; $result = array(); $keys = PMB_AllKeys($table); foreach ($keys as $key) { $record = PMB_Load($table, $key); $match = false; eval('$match = ' . $constraint . ';'); if ($match) { eval('$result[$key] = ' . $sort . ';'); } } asort($result); return $result; } function PMB_Save($table, $key, $object) { if (!$table) die("Fatal Error: PMB_Save needs a table ($key)"); if (!$key) die("Fatal Error: PMB_Save needs a key ($table)"); $GLOBALS["calls"]["PMB_Save"]++; $GLOBALS["calllog"][] = "PMB_Save($table, $key, ...)"; $gz = function_exists("gzuncompress") && (substr($table, -3) == "_gz"); $ig = function_exists("igbinary_unserialize") && (substr($table, -3) == "_ig"); $key = N_Encode64(strtolower($key)); if (!file_exists($GLOBALS['pnkit_data_dir'] . "/$table")) { mkdir($GLOBALS['pnkit_data_dir'] . "/$table"); } $fd = fopen($GLOBALS['pnkit_data_dir'] . "/$table/{$key}_tmp", 'w'); if ($ig) { fwrite($fd, igbinary_serialize($object)); } else { if ($gz) { fwrite($fd, gzcompress(serialize($object))); } else { fwrite($fd, serialize($object)); } } fclose($fd); @rename($GLOBALS['pnkit_data_dir'] . "/$table/{$key}_tmp", $GLOBALS['pnkit_data_dir'] . "/$table/$key"); } function PMB_TimeStamp($table, $key) { $GLOBALS["calls"]["PMB_TimeStamp"]++; $GLOBALS["calllog"][] = "PMB_TimeStamp($table, $key)"; $key = N_Encode64(strtolower($key)); return filemtime($GLOBALS['pnkit_data_dir'] . "/$table/$key"); } function PMB_Exists($table, $key) { $GLOBALS["calls"]["PMB_Exists"]++; $GLOBALS["calllog"][] = "PMB_Exists($table, $key)"; $key = N_Encode64(strtolower($key)); return file_exists($GLOBALS['pnkit_data_dir'] . "/$table/$key"); } function PMB_LastUpdate($table, $key) { $file = $GLOBALS['pnkit_data_dir'] . "/$table/" . N_Encode64(strtolower($key)); if (filesize($file)) { return filemtime($file); } return false; } function PMB_Load($table, $key) { $GLOBALS["calls"]["PMB_Load"]++; $GLOBALS["calllog"][] = "PMB_Load($table, $key)"; $gz = function_exists("gzuncompress") && (substr($table, -3) == "_gz"); $ig = function_exists("igbinary_unserialize") && (substr($table, -3) == "_ig"); global $PMB_Load; $thekey = $key; ++$PMB_Load; $key = N_Encode64(strtolower($key)); @$fd = fopen($GLOBALS['pnkit_data_dir'] . "/$table/$key", 'r'); if (!$fd) { return null; } if (filesize($GLOBALS['pnkit_data_dir'] . "/$table/$key")) { $rawdata = fread($fd, filesize($GLOBALS['pnkit_data_dir'] . "/$table/$key")); fclose($fd); if (strlen($rawdata)) { if ($ig) { $object = igbinary_unserialize($rawdata); } else { if ($gz) { $object = unserialize(gzuncompress($rawdata)); } else { $object = unserialize($rawdata); } } } return $object; } else { return null; } } function PMB_DeleteTable($table, $please="") { if ($please!="please") throw new Error("PMB_DeleteTable requires 'please' as second parameter"); $keys = PMB_AllKeys ($table); foreach ($keys as $key) { PMB_Delete ($table, $key); } @rmdir($GLOBALS['pnkit_data_dir'] . "/$table"); } function PMB_Delete($table, $key) { $GLOBALS["calls"]["PMB_Delete"]++; $GLOBALS["calllog"][] = "PMB_Delete($table, $key)"; $key = N_Encode64(strtolower($key)); @unlink($GLOBALS['pnkit_data_dir'] . "/$table/$key"); } function PMB_AllKeys($table) { $GLOBALS["calls"]["PMB_AllKeys"]++; $GLOBALS["calllog"][] = "PMB_AllKeys($table)"; $dir = $GLOBALS['pnkit_data_dir'] . "/$table/"; $result = array(); if (is_dir($dir)) { if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { if (is_file($dir . $file) && !strstr ($file, "_tmp")) { $result[] = N_Decode64($file); } } closedir($dh); } } sort($result); return $result; } function PMB_TableBytes($table) { $GLOBALS["calls"]["PMB_TableBytes"]++; $GLOBALS["calllog"][] = "PMB_TableBytes($table)"; $dir = $GLOBALS['pnkit_data_dir'] . "/$table/"; if (is_dir($dir)) { if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { if (is_file($dir . $file)) { $result += filesize($dir . $file); } } closedir($dh); } } return $result; } function PMB_AllTables() { $GLOBALS["calls"]["PMB_AllTables"]++; $GLOBALS["calllog"][] = "PMB_AllTables()"; $dir = $GLOBALS['pnkit_data_dir'] . "/"; $result = array(); if (is_dir($dir)) { if ($dh = opendir($dir)) { while (($subdir = readdir($dh)) !== false) { if (is_dir($dir . $subdir) && $subdir != "." && $subdir != ".." && substr($subdir, 0, 4) != "int_") { $result[] = $subdir; } } closedir($dh); } } sort($result); return $result; } function PMB_Check($type = "all") { if ($type == "all" || $type == "gz") { $tables = PMB_AllTables(); foreach ($tables as $table) { if (substr($table, -3) == "_gz") { $keys = PMB_AllKeys($table); $ctr = 0; echo "
$table: " . N_Count ($keys) . "
"; echo str_pad('', 4096); flush(); foreach ($keys as $key) { $file = N_Encode64(strtolower($key)); @$fd = fopen($GLOBALS['pnkit_data_dir'] . "/$table/$file", 'r'); if (!$fd) { echo "ERROR: No file for key: $key ($file)
"; } else { if (!filesize($GLOBALS['pnkit_data_dir'] . "/$table/$file")) { echo "ERROR: No data (empty file) for key: $key ($file)
"; } else { $rawdata = fread($fd, filesize($GLOBALS['pnkit_data_dir'] . "/$table/$file")); fclose($fd); if (!N_ValidGZ($rawdata)) { echo "ERROR: No valid data (gzuncompress data error) for key: $key ($file)
"; } } } ++$ctr; if ($ctr % 1000 == 0) { echo "Progress $ctr/" . N_Count ($keys) . "
"; echo str_pad('', 4096); flush(); } } echo "Progress $ctr/" . N_Count ($keys) . "
"; } } } if ($type == "all" || $type == "ig") { $tables = PMB_AllTables(); foreach ($tables as $table) { if (substr($table, -3) == "_ig") { $keys = PMB_AllKeys($table); $ctr = 0; echo "
$table: " . N_Count ($keys) . "
"; echo str_pad('', 4096); flush(); foreach ($keys as $key) { $file = N_Encode64(strtolower($key)); @$fd = fopen($GLOBALS['pnkit_data_dir'] . "/$table/$file", 'r'); if (!$fd) { echo "ERROR: No file for key: $key ($file)
"; } else { if (!filesize($GLOBALS['pnkit_data_dir'] . "/$table/$file")) { echo "ERROR: No data (empty file) for key: $key ($file)
"; } else { $rawdata = fread($fd, filesize($GLOBALS['pnkit_data_dir'] . "/$table/$file")); fclose($fd); if (!igbinary_unserialize($rawdata)) { echo "WARNING: No data for key: $key ($file)
"; } } } ++$ctr; if ($ctr % 1000 == 0) { echo "Progress $ctr/" . N_Count ($keys) . "
"; echo str_pad('', 4096); flush(); } } echo "Progress $ctr/" . N_Count ($keys) . "
"; } } } if ($type == "all" || $type == "std") { $tables = PMB_AllTables(); foreach ($tables as $table) { if (substr($table, -3) != "_ig" && substr($table, -3) != "_gz") { $keys = PMB_AllKeys($table); $ctr = 0; echo "
$table: " . N_Count ($keys) . "
"; echo str_pad('', 4096); flush(); foreach ($keys as $key) { $file = N_Encode64(strtolower($key)); @$fd = fopen($GLOBALS['pnkit_data_dir'] . "/$table/$file", 'r'); if (!$fd) { echo "ERROR: No file for key: $key ($file)
"; } else { if (!filesize($GLOBALS['pnkit_data_dir'] . "/$table/$file")) { echo "ERROR: No data (empty file) for key: $key ($file)
"; } else { $rawdata = fread($fd, filesize($GLOBALS['pnkit_data_dir'] . "/$table/$file")); fclose($fd); if (!unserialize($rawdata)) { echo "WARNING: No data for key: $key ($file)
"; } } } ++$ctr; if ($ctr % 1000 == 0) { echo "Progress $ctr/" . N_Count ($keys) . "
"; echo str_pad('', 4096); flush(); } } echo "Progress $ctr/" . N_Count ($keys) . "
"; } } } } /******************************************************************************/ // PHP 5.4 support if (!function_exists("array_key_last")){ function array_key_last ($array) { $array = NA ($array); end ($array); return key ($array); } } /******************************************************************************/ // 1001 USEFUL SMALL FUNCTIONS function N_AccurateTime () { foreach (["time.cloudflare.com", "pool.ntp.org", "time.google.com", "time.apple.com"] as $timehost) { if ($socket = @fsockopen("udp://$timehost", 123, $errno, $errstr, 1)) { stream_set_timeout ($socket, 1); fwrite ($socket, "\010" . str_repeat("\0", 47)); $response = fread ($socket, 48); fclose($socket); if ($response && strlen($response) === 48) { $data = unpack('N12', $response); $timestamp = sprintf('%u', $data[9]); $timestamp -= 2208988800; // Convert NTP time to Unix timestamp (1900-01-01) if ($timestamp > 1730000000) return $timestamp; } } } $response = @json_decode (@file_get_contents ("https://timeapi.io/api/time/current/zone?timeZone=Europe/Amsterdam"), true); if ($response && isset($response['dateTime'])) { $dateTime = new DateTime($response['dateTime'], new DateTimeZone('Europe/Amsterdam')); $timestamp = $dateTime->getTimestamp(); if ($timestamp > 1730000000) return $timestamp; } return time(); } function N_SemaClaim ($sema, $wait=15, $seconds=7200) { for ($i=0; $i<=$wait*10; $i++) { if (PMB_Load ("semaphores", $sema) + $seconds < time()) { PMB_Save ("semaphores", $sema, time()); return true; } usleep (100000); } return false; } function N_SemaRelease ($sema) { PMB_Save ("semaphores", $sema, 0); } function N_SemaPulse ($sema) { PMB_Save ("semaphores", $sema, time()); } function N_ReplaceDiacritics ($string) { $originalCharacters = array( 'ä', 'ë', 'ï', 'ö', 'ü', 'á', 'é', 'í', 'ó', 'ú', 'ý', 'à', 'è', 'ì', 'ò', 'ù', 'â', 'ê', 'î', 'ô', 'û', 'ã', 'ñ', 'õ', 'å', 'æ', 'ç', 'œ', 'Ä', 'Ë', 'Ï', 'Ö', 'Ü', 'Á', 'É', 'Í', 'Ó', 'Ú', 'Ý', 'À', 'È', 'Ì', 'Ò', 'Ù', 'Â', 'Ê', 'Î', 'Ô', 'Û', 'Ã', 'Ñ', 'Õ', 'Å', 'Æ', 'Ç', 'Œ' ); $replacementCharacters = array( 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u', 'y', 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u', 'a', 'n', 'o', 'a', 'ae', 'c', 'oe', 'A', 'E', 'I', 'O', 'U', 'A', 'E', 'I', 'O', 'U', 'Y', 'A', 'E', 'I', 'O', 'U', 'A', 'E', 'I', 'O', 'U', 'A', 'N', 'O', 'A', 'AE', 'C', 'OE' ); return str_replace($originalCharacters, $replacementCharacters, $string); } function N_SecureMultiRand ($amount, $min, $max, $type="test") { $microtime = microtime(true); $slot = (int)($microtime/(24*3600)); $seed_index = 1 + NN (PMB_Load ("multi_rand", "seed_index")); PMB_Save ("multi_rand", "seed_index", $seed_index); $mt_seed = ((int)$microtime * $amount * $seed_index) % 2147483647; mt_srand ($mt_seed, MT_RAND_MT19937); for ($i = 0; $i < $amount; $i++) $result[$i] = mt_rand($min, $max); $result ["type"] = $type; $result ["min"] = $min; $result ["max"] = $max; $result ["seed_index"] = $seed_index; $result ["microtime"] = $microtime; $result ["mt_seed"] = $mt_seed; $log = PMB_Load ("multi_rand", $slot); $log[] = $result; PMB_Save ("multi_rand", $slot, $log); return $result; } function N_ContainsAny ($haystack, $needle) { // https://www.fastsimple.com/pnkit/example_online.php?pnkit=eval&saved_code=684c346e5f98dfbad845ef9a8b5ffdaa if (is_array ($haystack)) { foreach ($haystack as $h) if (N_ContainsAny ($h, $needle)) return true; return false; } if (is_array ($needle)) { foreach ($needle as $n) if (false !== stripos($haystack, $n)) return true; return false; } else { return false !== stripos($haystack,$needle); } } function N_ArrayToTable ($array, $table_spacing ='cellpadding="5" cellspacing="0"', $table_cell_properties='style="border: 1px solid; border-color:#eee;"') { if (!is_array($array)) return N_ArrayToTable ([NS($array)=>""]); $table = "\n"; foreach ($array as $key => $value) { $table .= "\n"; } $table .= "
".htmlentities ($key).""; if (is_array($value)) { $table .= N_ArrayToTable ($value, $table_spacing, $table_cell_properties); } else { $table .= "".str_replace ([" ", "\n"], [" ", "
"], htmlentities ($value))."
"; } $table .= "
\n"; return $table; } function N_Ping ($host) { if (gethostbyname($host) == gethostbyname ("does.not.exist")) return false; $output = shell_exec("ping -c 1 -w 3 ".gethostbyname($host)); if (strpos($output, '1 packets transmitted, 1 received') !== false) return true; return false; } function N_SafeEval ($code_aesvrun, $inputvars_aesvrun=array(), $outputvar_aesvrun=null) { extract ($inputvars_aesvrun, EXTR_SKIP); eval ("$code_aesvrun;"); return $$outputvar_aesvrun; } function N_ShowMS ($ms) { if ($ms > 2999) { return number_format(round ($ms / 1000))." s"; } else if ($ms > 999) { return number_format($ms / 1000, 1)." s"; } else { return number_format(round ($ms))." ms"; } } function N_ParseURL ($url) { $result = parse_url ($url); if ($result["query"]) { parse_str ($result["query"], $query); $result["query"] = $query; } return $result; } function N_GenerateURL ($parts) { if (is_array ($parts["query"])) $parts["query"] = http_build_query ($parts["query"]); return (isset($parts['scheme']) ? "{$parts['scheme']}:" : '') . ((isset($parts['user']) || isset($parts['host'])) ? '//' : '') . (isset($parts['user']) ? "{$parts['user']}" : '') . (isset($parts['pass']) ? ":{$parts['pass']}" : '') . (isset($parts['user']) ? '@' : '') . (isset($parts['host']) ? "{$parts['host']}" : '') . (isset($parts['port']) ? ":{$parts['port']}" : '') . (isset($parts['path']) ? "{$parts['path']}" : '') . (isset($parts['query']) ? "?{$parts['query']}" : '') . (isset($parts['fragment']) ? "#{$parts['fragment']}" : ''); } function N_Setting ($default=NULL, $o1=NULL, $o2=NULL, $o3=NULL, $o4=NULL, $o5=NULL) { $setting = $default; if ($o5) $setting = $o5; if ($o4) $setting = $o4; if ($o3) $setting = $o3; if ($o2) $setting = $o2; if ($o1) $setting = $o1; return $setting; } function N_Expand ($old, $separator, $new, $prefix="") { if ($old) { if ($prefix && substr ($old, 0, strlen($prefix)) != $prefix) $old = "$prefix$old"; return "$old$separator$prefix$new"; } return $new; } function N_First ($old, $new) { if ($old) return $old; return $new; } function N_Last ($old, $new) { if ($new) return $new; return $old; } function N_BlankPNG () { return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII="; } function N_RemoveEmptyValues ($array) { foreach ($array as $key => $value) { if (is_array ($value)) { $array[$key] = N_RemoveEmptyValues ($value); } if (empty ($value)) { unset ($array[$key]); } } return $array; } function N_FastMD5File ($file) { $file = realpath ($file); if (file_exists ($file)) { $fm = filemtime ($file); $data = NA (PMB_Load ("fast_md5_file", $file)); if ($fm != $data["filemtime"]) { $data["filemtime"] = $fm; $data["md5"] = md5_file ($file); if ($data["md5"] != md5("")) PMB_Save ("fast_md5_file", $file, $data); } return $data["md5"]; } else { return md5 (""); } } function N_RecursiveKeySort (&$array) { if (!is_array ($array)) return $array; foreach ($array as &$value) { if (is_array($value)) N_RecursiveKeySort ($value); } return ksort($array); } function N_ValidGZ($x) { return @gzuncompress($x) !== false; } if (!function_exists("NN")) { function NN ($me) { if (is_numeric ($me) || floatval($me)) { if (($theint = intval($me)) != ($thefloat = floatval($me))) { return $thefloat; } else { return $theint; } } return 0; } function NS ($me) { if (is_scalar ($me)) return "".$me; return ""; } function NA ($me) { if (is_array($me)) return $me; return array(); } function NZ ($value, $alt, $prefix="", $postfix="") { if (!is_scalar ($value)) if ($value) return $value; else return $alt; if ($value) return "$prefix$value$postfix"; else return $alt; } } if (!function_exists("TN")) { function TN (&$me) { $me = NN ($me); return $me; } function TS (&$me) { $me = NS ($me); return $me; } function TA (&$me) { $me = NA ($me); return $me; } } if (!function_exists("N_Count")) { function N_Count ($me) { if (is_array ($me)) return count ($me); if ($me instanceof Countable) return count ($me); return null; } } function N_2MB($from) { /* $testCases = ["13", "13B", "13KB", "10.5KB", "123MB", "287GB", "1.1TB", "123M", "287G", "1.1T", "123 M", "287 G", "1.1 T", "123 QQ", "1.23 M", "", null, 0, array()]; T_EO (array_map('N_2MB', $testCases)); */ $from = NS ($from); $from = str_replace(" ", "", $from); if (substr($from, -1) != "B") $from = "$from" . "B"; $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB'); $number = substr($from, 0, -2); $suffix = strtoupper(substr($from, -2)); if (is_numeric(substr($suffix, 0, 1))) return preg_replace('/[^\d]/', '', $from) / 1024 / 1024; $units = array_flip($units); $exponent = $units[$suffix]; if ($exponent === null) return 0; return NN ($number) * pow(1024, NN ($exponent)) / 1024 / 1024; } function N_Safe($html) { $html = str_replace("<", "<", $html); return $html; } function N_T($input = true) { if (strpos($_SERVER["HTTP_USER_AGENT"], "Firefox")) return null; if (strpos($_SERVER["HTTP_USER_AGENT"], "OS X")) return null; if ($_SERVER["REMOTE_ADDR"] != $GLOBALS["pnkit_owner_ip"] && $_SERVER["REMOTE_ADDR"] != "127.0.0.1") return null; return $input; } function N_ForceSSL() { header("strict-transport-security: max-age=31536000"); if ($_SERVER["HTTPS"] != "on") { header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"], true, 301); exit(); } } function N_CLI() { $sapi_type = php_sapi_name(); if (substr($sapi_type, 0, 3) == 'cli') { return true; } else { return false; } } function N_Once($func) { static $cache; ini_set('memory_limit', '10240M'); if (memory_get_usage() > 750000000) { $cache = array(); // Prevent too much memory usage $GLOBALS["calls"]["#N_Once Cache Wipes#"]++; } $args = func_get_args(); $cachekey = md5(serialize($args)); if (is_array ($cache) && array_key_exists ($cachekey, $cache)) return $cache[$cachekey]; array_shift($args); $cache[$cachekey] = call_user_func_array($func, $args); return $cache[$cachekey]; } function N_DFC($func) // Extreme high speed caching of deterministic function calls. Parameters and results should be relatively small. Becomes even faster if https://github.com/igbinary/igbinary is installed. { global $n_dfc, $n_flushdfc_shutdown, $n_flushdfc_functions; ini_set('memory_limit', '10240M'); if (strpos($func, "#")) { $funcarr = explode("#", $func); $truefunc = $funcarr[0]; } else { $truefunc = $func; } if (!$n_dfc[$func]) { $n_dfc[$func] = PMB_Load("n_dfc_ig", $func); if (@N_Count ($n_dfc[$func]) > 26000) { // keep at most 25000 - 26000 elements $rnd = array_rand($n_dfc[$func], N_Count ($n_dfc[$func]) - 25000); // randomly delete elements until there are 25000 left $GLOBALS["calls"]["#N_DFC Removed Elements#"] += N_Count ($rnd); foreach ($rnd as $key) unset($n_dfc[$func][$key]); } } $args = func_get_args(); $cachekey = md5(serialize($args)); if ($n_dfc[$func][$cachekey]["valid"]) { return $n_dfc[$func][$cachekey]["value"]; } array_shift($args); if ($funcarr) { array_shift($funcarr); $trueargs = array_merge($funcarr, $args); } else { $trueargs = $args; } $n_dfc[$func][$cachekey]["value"] = call_user_func_array($truefunc, $trueargs); $n_dfc[$func][$cachekey]["valid"] = true; if (!$n_flushdfc_shutdown) { $n_flushdfc_shutdown = true; register_shutdown_function('N_FlushDFC'); } $n_flushdfc_functions[$func] = $func; return $n_dfc[$func][$cachekey]["value"]; } function N_FlushDFC() { global $n_dfc, $n_flushdfc_functions; foreach ($n_flushdfc_functions as $func) { PMB_Save("n_dfc_ig", $func, $n_dfc[$func]); } } function N_WipeDFC($func) { PMB_Delete("n_dfc_ig", $func); } function N_ResetGlobalProfiler () { for ($i=0; $i<25; $i++) unlink ($GLOBALS['pnkit_data_dir'] . '/profile'.date ("H", time() - $i*3600).'.html'); } function N_GlobalProfiler ($seconds=3600) { if ($seconds > 4 * 3600) $seconds = 4 * 3600; echo "N_GlobalProfiler ($seconds seconds)
"; $profileraw = @file_get_contents ($GLOBALS['pnkit_data_dir'] . '/profile'.date ("H", time()).'.html') . @file_get_contents ($GLOBALS['pnkit_data_dir'] . '/profile'.date ("H", time() - 3600).'.html') . @file_get_contents ($GLOBALS['pnkit_data_dir'] . '/profile'.date ("H", time() - 2 * 3600).'.html') . @file_get_contents ($GLOBALS['pnkit_data_dir'] . '/profile'.date ("H", time() - 3 * 3600).'.html') . @file_get_contents ($GLOBALS['pnkit_data_dir'] . '/profile'.date ("H", time() - 4 * 3600).'.html'); $profile = explode ("\n", $profileraw); foreach ($profile as $line) { if (preg_match ("#([0-9]*) ([0-9.]*) ([^/]*)(.*)#", $line, $matches)) { if (NN($matches[1]) + $seconds > time()) { parse_str ($matches[4], $query); $gurl = $matches[3].implode ("&", array_keys ($query)); $stats[$gurl]["calls"]++; $stats[$gurl]["time"] += NN($matches[2]); $totaltime += NN($matches[2]); } } } $stats = N_SortBy ($stats, '-$record["time"]'); foreach ($stats as $gurl => $stat) { if (($per = round($stat["time"]/$totaltime*1000)/10) == 0) break; echo N_ShowMS ($stat["time"]*1000) ." ($per %) --- $gurl (".$stat["calls"]." calls; ".N_ShowMS ($stat["time"]*1000/$stat["calls"])."/call)
"; } } function MS ($what="") { static $last = 0; $elapsed = microtime(true) - $GLOBALS["MS_start"]; $time_ms = round($elapsed * 1000000) / 1000; if ($what) { if ($last) { $time_ms_last = round((microtime(true) - $last) * 1000000) / 1000; echo "MS $what $time_ms ms ($time_ms_last ms)
"; } else { echo "MS $what $time_ms ms
"; } $last = microtime(true); } return $time_ms; } function NP($func) /* PROFILER, use T_EO ($GLOBALS["np"]); for results */ { $args = func_get_args(); array_shift($args); $start = microtime(true); $result = call_user_func_array($func, $args); $elapsed = microtime(true) - $start; $time_ms = round($elapsed * 1000000) / 1000; $GLOBALS["np"][$func]["calls"]++; $GLOBALS["np"][$func]["time_ms"] += $time_ms; if ($time_ms > 1) { $GLOBALS["np"]["slow"][] = array( "func" => $func, "time_ms" => $time_ms, "args" => $args, ); usort($GLOBALS["np"]["slow"], function ($a, $b) { return -strnatcmp($a["time_ms"], $b["time_ms"]); }); $GLOBALS["np"]["slow"] = array_slice($GLOBALS["np"]["slow"], 0, 10); } return $result; } /* PROFILER, auto reports results */ function P1($tag) { if (!$GLOBALS["pnkit_profiler"]["init"]) { register_shutdown_function("P_Report"); $GLOBALS["pnkit_profiler"]["init"] = true; $GLOBALS["pnkit_profiler"]["start"] = microtime(true); } $GLOBALS["pnkit_profiler"]["tag"][$tag]["calls"]++; $GLOBALS["pnkit_profiler"]["tag"][$tag]["start"] = microtime(true); } function P2($tag) { if (!$GLOBALS["pnkit_profiler"]["init"]) { register_shutdown_function("P_Report"); $GLOBALS["pnkit_profiler"]["init"] = true; $GLOBALS["pnkit_profiler"]["start"] = microtime(true); } $GLOBALS["pnkit_profiler"]["tag"][$tag]["elapsed"] += microtime(true) - $GLOBALS["pnkit_profiler"]["tag"][$tag]["start"]; } function P_Report() { if ($_SERVER["REMOTE_ADDR"] != $GLOBALS["pnkit_owner_ip"] && $_SERVER["REMOTE_ADDR"] != "127.0.0.1") return; // For developer's eyes only $GLOBALS["pnkit_profiler"]["tag"] = N_SortBy($GLOBALS["pnkit_profiler"]["tag"], '$object["elapsed"]', SORT_DESC); echo "
Portable NKIT Profiler Statistics (" . ((int) (1000 * (microtime(true) - $GLOBALS["MS_start"]))) . " ms)
"; if ($GLOBALS["pnkit_profiler"]["tag"]) { foreach ($GLOBALS["pnkit_profiler"]["tag"] as $tag => $d) { echo "$tag: "; echo "" . round(1000 * $d["elapsed"]) . "ms "; echo "(" . $d["calls"] . "x)
"; } } } function N_MustMatch($match, $func) // T_EO (N_MustMatch ("q", "substr", "q1q2q3", 2, 3), N_MustMatch ("w", "substr", "q1q2q3", 2, 3)); { $args = func_get_args(); array_shift($args); array_shift($args); $result = call_user_func_array($func, $args); if (stristr ($result, $match)) return $result; return NULL; } function N_MustHaveMinSize($minsize, $func) // T_EO (N_MustHaveMinSize (2, "substr", "q1q2q3", 2, 3), N_MustHaveMinSize (4, "substr", "q1q2q3", 2, 3)); { $args = func_get_args(); array_shift($args); array_shift($args); $result = call_user_func_array($func, $args); if (strlen($result) >= $minsize) return $result; return NULL; } function N_CacheLimitExecutionTime ($seconds) { global $N_CacheLimitExecutionTime; $N_CacheLimitExecutionTime = $seconds; } function N_Cache ($specs, $func) /* What we try to achieve here: - often faster results, especially if called often (as it's caching) - minimize load on whatever we are using, especially if it's not working - always return the last non empty result (so this function is NOT usable to check if something is still working) Manual cleanup example: find /var/www/fastsimple.com/pnkit_data_dir/local_n_cache/ -type f -mtime +30 -exec rm -f {} \; Test code: https://www.fastsimple.com/pnkit/example_online.php?pnkit=eval&saved_code=89e6d9be9debf20ca728b15978c3f35b function failingdate ($p) { $result = date ($p); return NULL; return $result; } T_EO (N_Cache (["cached_hours"=>10, "precise"=>true, "debug"=>true, "maxfail_hours"=>20], "failingdate", "Y-m-d H:i:s"), date ("Y-m-d H:i:s")); T_EO (N_Cache (["cached_seconds"=>10, "precise"=>true, "debug"=>true, "maxfail_seconds"=>20], "failingdate", "Y-m-d H:i:s"), date ("Y-m-d H:i:s")); T_EO (N_Cache (["maxfail_seconds"=>10], "failingdate", "Y-m-d H:i:s"), date ("Y-m-d H:i:s")); T_EO (N_Cache (-1, "failingdate", "Y-m-d H:i:s"), date ("Y-m-d H:i:s")); N_CacheLimitExecutionTime (1); for ($i=1; $i<=25; $i++) echo N_Cache (0, "TEST_Strlen", str_repeat ("*", $i))." "; function TEST_Strlen ($str) { $result = strlen ($str); echo "[$result] "; usleep (100000); return $result; } */ { global $N_CacheLimitExecutionTime; $maxfail_hours = 999999999; $cached_hours = -1; if (is_array($specs)) { if (isset($specs["cached_hours"])) $cached_hours = $specs["cached_hours"]; if (isset($specs["cached_seconds"])) $cached_hours = $specs["cached_seconds"] / 3600.0; if (isset($specs["maxfail_hours"])) $maxfail_hours = $specs["maxfail_hours"]; if (isset($specs["maxfail_seconds"])) $maxfail_hours = $specs["maxfail_seconds"] / 3600.0; } else { if ($specs) $cached_hours = $specs; $specs = []; } if ($N_CacheLimitExecutionTime) { if (MS() > 1000 * $N_CacheLimitExecutionTime) { $maxfail_hours = 999999999; $cached_hours = 999999999; } } $specs["calculated_hours"] = $cached_hours; $specs["calculated_maxfail_hours"] = $maxfail_hours; $args = func_get_args(); array_shift($args); $cachekey = md5(serialize($args)); $cacheentry1 = PMB_Load('local_n_cache', $cachekey); $random = mt_rand (100, 115); if ($specs["precise"]) $random = 100; if ($cacheentry1 && $cacheentry1['result'] && time() - $cacheentry1['time'] < ($random * $cached_hours * 36)) { // Randomly add 0% - 15% to spread actual actions array_shift($args); if ($specs["debug"]) T_EO ("N_Cache FETCH", $specs, $func, $args, $cacheentry1); $GLOBALS["N_Cache_state"] = "cache"; return $cacheentry1['result']; } array_shift($args); $result = call_user_func_array($func, $args); $cacheentry2 = array(); $cacheentry2['time'] = time(); if ($result) { $GLOBALS["N_Cache_state"] = "fresh"; $cacheentry2['result'] = $result; PMB_Save('local_n_cache', $cachekey, $cacheentry2); if ($specs["debug"]) T_EO ("N_Cache STORE", $specs, $func, $args, $cacheentry1, $cacheentry2); return $cacheentry2['result']; } else if ($cacheentry1 && $cacheentry1['result']) { if (time() - $cacheentry1['time'] > 3600 * $maxfail_hours) { if ($specs["debug"]) T_EO ("N_Cache VISIBLE FAIL", $specs, $func, $args, $cacheentry1); return NULL; } else { if ($specs["debug"]) T_EO ("N_Cache HIDDEN FAIL", $specs, $func, $args, $cacheentry1); $GLOBALS["N_Cache_state"] = "old"; return $cacheentry1['result']; } } else { if ($specs["debug"]) T_EO ("N_Cache NOT CACHED FAIL", $specs, $func, $args, $cacheentry1); return NULL; } } function N_WipeCache($func) { $args = func_get_args(); $cachekey = md5(serialize($args)); PMB_Delete('local_n_cache', $cachekey, $cachekey); } function N_ObjectToArray($data) { if (is_object($data)) { $data = get_object_vars($data); } if (is_array($data)) { return array_map('N_ObjectToArray_LL', $data); } else { if ($data) { return array($data); } else { return array(); } } } function N_ObjectToArray_LL($data) { if (is_object($data)) { $data = get_object_vars($data); } if (is_array($data)) { return array_map('N_ObjectToArray_LL', $data); } else { return $data; } } function N_ObjectWithHiddenToArray ($me, $maxdepth=5, $recursion=false) // does not understand XML { $result = []; if (is_object ($me)) { if ($maxdepth < 1) return "***RECURSION***"; $reflectedObject = new ReflectionObject ($me); $properties = $reflectedObject->getProperties(); foreach($properties as $property){ $property->setAccessible (true); // Note: As of PHP 8.1.0, calling this method has no effect; all properties are accessible by default. $result[$property->getName()] = N_ObjectWithHiddenToArray ($property->getValue($me), $maxdepth - 1, true); } } else if (is_array ($me)) { foreach ($me as $id => $val) $result[$id] = N_ObjectWithHiddenToArray ($val, $maxdepth, true); } else if ($recursion) { return $me; } else { return [$me]; } return $result; } function N_XMLToArray ($xml) { return NA (N_XMLToArray_LL (simplexml_load_string ($xml))); } function N_XMLToArray_LL ($xml) { // https://gist.github.com/jobrieniii/92df79811f62b444b39f $options = array( 'namespaceSeparator' => ':', //you may want this to be something other than a colon 'attributePrefix' => '@', //to distinguish between attributes and nodes with the same name 'alwaysArray' => array(), //array of xml tag names which should always become arrays 'autoArray' => true, //only create arrays for tags which appear more than once 'textContent' => '$', //key used for the text content of elements 'autoText' => true, //skip textContent key if node has no attributes or child nodes 'keySearch' => false, //optional search and replace on tag and attribute names 'keyReplace' => false //replace values for above search values (as passed to str_replace()) ); $namespaces = $xml->getDocNamespaces(); $namespaces[''] = null; //add base (empty) namespace //get attributes from all namespaces $attributesArray = array(); foreach ($namespaces as $prefix => $namespace) { foreach ($xml->attributes($namespace) as $attributeName => $attribute) { //replace characters in attribute name if ($options['keySearch']) $attributeName = str_replace($options['keySearch'], $options['keyReplace'], $attributeName); $attributeKey = $options['attributePrefix'] . ($prefix ? $prefix . $options['namespaceSeparator'] : '') . $attributeName; $attributesArray[$attributeKey] = (string)$attribute; } } //get child nodes from all namespaces $tagsArray = array(); foreach ($namespaces as $prefix => $namespace) { foreach ($xml->children($namespace) as $childXml) { //recurse into child nodes $childArray = N_XMLToArray_LL ($childXml); list ($childTagName, $childProperties) = N_Each ($childArray); //replace characters in tag name if ($options['keySearch']) $childTagName = str_replace($options['keySearch'], $options['keyReplace'], $childTagName); //add namespace prefix, if any if ($prefix) $childTagName = $prefix . $options['namespaceSeparator'] . $childTagName; if (!isset($tagsArray[$childTagName])) { //only entry with this key //test if tags of this type should always be arrays, no matter the element count $tagsArray[$childTagName] = in_array ($childTagName, $options['alwaysArray']) || !$options['autoArray'] ? array($childProperties) : $childProperties; } elseif ( is_array($tagsArray[$childTagName]) && array_keys($tagsArray[$childTagName]) === range(0, count($tagsArray[$childTagName]) - 1) ) { //key already exists and is integer indexed array $tagsArray[$childTagName][] = $childProperties; } else { //key exists so convert to integer indexed array with previous value in position 0 $tagsArray[$childTagName] = array($tagsArray[$childTagName], $childProperties); } } } //get text content of node $textContentArray = array(); $plainText = trim((string)$xml); if ($plainText !== '') $textContentArray[$options['textContent']] = $plainText; //stick it all together $propertiesArray = !$options['autoText'] || $attributesArray || $tagsArray || ($plainText === '') ? array_merge($attributesArray, $tagsArray, $textContentArray) : $plainText; //return node as array return array( $xml->getName() => $propertiesArray ); } function N_Each ($array){ $key = key ($array); $value = current ($array); $each = is_null($key) ? false : [ 1 => $value, 'value' => $value, 0 => $key, 'key' => $key, ]; next ($array); return $each; } function N_Encode64($string) { return strtr(base64_encode($string), '+/', '-_'); } function N_Decode64($string) { return base64_decode(strtr($string, '-_', '+/')); } function N_SecureEncode ($string) { $key = md5 ($string); PMB_Save ("pnkit_secureencoded", $key, $string); return "pnsecenc_$key"; } function N_SecureDecode ($key) { if (substr ($key, 0, 9)=="pnsecenc_") { return PMB_Load ("pnkit_secureencoded", substr ($key, 9)); } else { return $key; } } function N_QuickLog ($me) { $tr = debug_backtrace(); $tr[0]["args"] = []; static $ctr=20000, $pid; $ctr++; if (!$pid) $pid=getmypid(); $logid = microtime(true).$ctr.sprintf ("%010d", crc32 (rand ().$pid)); $class = "NewQuickLog"; $function = $tr[1]["function"]; if ($function=="eval") $function .= " - ".$tr[2]["function"]; PMB_Save ("ulog_lines", $logid, [ "line" => $me, "class" => $class, "function" => $function, "line_number" => $tr[0]["line"], "BID" => $_COOKIE['pnkit_bid_v11'], "REMOTE_ADDR" => $_SERVER["REMOTE_ADDR"], "preserve_details" => false ]); PMB_Save ("ulog_details", $logid, [ "has_details" => false, "details" => [], "PID" => $pid, "HTTP_HOST" => $_SERVER['HTTP_HOST'], "SCRIPT_NAME" => $_SERVER['SCRIPT_NAME'], "REMOTE_PORT" => $_SERVER["REMOTE_PORT"], "REQUEST_SCHEME" => $_SERVER["REQUEST_SCHEME"], "HTTP_REFERER " => $_SERVER["HTTP_REFERER"], "HTTP_USER_AGENT" => $_SERVER["HTTP_USER_AGENT"], "stack_arr" => $tr, ]); } // $line can be (single line) safe HTML. // The standard retention period for details is 1-2 weeks. function ULOG ($line, $details = NULL, $preserve_details = false, $class = NULL, $logid = NULL) { $tr = debug_backtrace(); $tr[0]["args"] = []; foreach ($tr as $index1 => $data1) { foreach ($data1["args"] as $index2 => $data2) { if (strlen (serialize ($data2)) > 250) { $tr[$index1]["args"][$index2] = "*** LARGE *** SIZE: " . strlen (serialize ($data2)); } } } /* $logid */ static $ctr=10000, $pid; $ctr++; if (!$pid) $pid=getmypid(); if (!$logid) $logid = microtime(true).$ctr.sprintf ("%010d", crc32 (rand ().$pid)); /* $class */ if (!$class) $class = $_SERVER['HTTP_HOST']." - ".basename ($_SERVER['SCRIPT_NAME']); /* $function */ $function = $tr[1]["function"]; if ($function=="eval") $function .= " - ".$tr[2]["function"]; PMB_Save ("ulog_lines", $logid, [ "line" => $line, "class" => $class, "function" => $function, "line_number" => $tr[0]["line"], "ms" => MS(), "mem" => round (memory_get_usage()/(1024*1024)), "peak" => round (memory_get_peak_usage()/(1024*1024)), "BID" => $_COOKIE['pnkit_bid_v11'], "REMOTE_ADDR" => $_SERVER["REMOTE_ADDR"], "preserve_details" => $preserve_details, ]); PMB_Save ("ulog_details", $logid, [ "has_details" => !!$details, "details" => $details, "PID" => $pid, "HTTP_HOST" => $_SERVER['HTTP_HOST'], "SCRIPT_NAME" => $_SERVER['SCRIPT_NAME'], "REMOTE_PORT" => $_SERVER["REMOTE_PORT"], "REQUEST_SCHEME" => $_SERVER["REQUEST_SCHEME"], "HTTP_REFERER " => $_SERVER["HTTP_REFERER"], "HTTP_USER_AGENT" => $_SERVER["HTTP_USER_AGENT"], "stack_arr" => $tr, ]); } function N_BR() { if (N_CLI()) { return "\r\n"; } else { return "
\r\n"; } } function N_Human() { $known = array('msie', 'firefox', 'safari', 'webkit', 'opera', 'netscape', 'konqueror', 'gecko'); $agent = strtolower($_SERVER['HTTP_USER_AGENT']); $pattern = '#(?' . implode('|', $known) . ')[/ ]+(?[0-9]+(?:\.[0-9]+)?)#'; if (!preg_match_all($pattern, $agent, $matches)) { return false; } return true; } function N_TimeElapsedString ($datetime, $full = false) { // stackoverflow.com/questions/1416697 $now = new DateTime; $ago = new DateTime($datetime); $diff = $now->diff($ago); $diff->w = floor($diff->d / 7); $diff->d -= $diff->w * 7; $string = array( 'y' => 'year', 'm' => 'month', 'w' => 'week', 'd' => 'day', 'h' => 'hour', 'i' => 'minute', 's' => 'second', ); foreach ($string as $k => &$v) { if ($diff->$k) { $v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : ''); } else { unset($string[$k]); } } if (!$full) $string = array_slice($string, 0, 1); return $string ? implode(', ', $string) . ' ago' : 'just now'; } function N_getRelativePath ($from, $to) // Source: https://stackoverflow.com/questions/2637945/getting-relative-path-from-absolute-path-in-php { $from = is_dir($from) ? rtrim($from, '\/') . '/' : $from; $to = is_dir($to) ? rtrim($to, '\/') . '/' : $to; $from = str_replace('\\', '/', $from); $to = str_replace('\\', '/', $to); $from = explode('/', $from); $to = explode('/', $to); $relPath = $to; foreach ($from as $depth => $dir) { if ($dir === $to[$depth]) { array_shift($relPath); } else { $remaining = N_Count ($from) - $depth; if ($remaining > 1) { $padLength = (N_Count ($relPath) + $remaining - 1) * -1; $relPath = array_pad($relPath, $padLength, '..'); break; } else { $relPath[0] = './' . $relPath[0]; } } } return implode('/', $relPath); } if (!function_exists ("N_SortBy")) { function N_SortBy() // $data, $expression1, $sort_order1, $sort_flags1, $expression2, $sort_order2, $sort_flags2, ... { $data = NA ($data); $args = func_get_args(); $data_in = array_shift($args); if (!is_array($data_in)) return array(); foreach ($data_in as $key => $value) $data[serialize($key)] = $value; foreach ($args as $n => $expression) { if (is_string($expression)) { $tmp = array(); foreach ($data as $key => $value) { $record = $rec = $object = $obj = $row = $value; $sortvalue = NULL; eval("\$sortvalue = $expression;"); $tmp[$key] = $sortvalue; } $args[$n] = $tmp; } } $args[] = &$data; call_user_func_array('array_multisort', $args); $data = array_pop($args); foreach ($data as $key => $value) $data_out[unserialize($key)] = $value; return $data_out; } function T_EO () // TEST: https://www.fastsimple.com/pnkit/example_online.php?pnkit=eval&saved_code=4d3d4009dd906f52fa633dc39458a3a1 { $tr = debug_backtrace(); for ($i = N_Count ($tr) - 1; $i >= 0; $i--) { $stack .= $tr[$i]["function"] . ":{$tr[$i]["line"]}"; if (N_CLI()) $stack .= " -> "; else $stack .= " → "; } $stack = preg_replace('/(T_EO)[^A-Z0-9_].*/i', '$1', $stack); echo "T_EO [$stack]"; if (N_CLI()) echo "\n"; else echo "
"; $args = func_get_args(); if (count ($args) > 1) echo ""; foreach ($args as $object) { if (count ($args) > 1) echo ""; } if (count ($args) > 1) echo "
"; if (N_CLI()) { if (is_array($object)) { echo '(arr: ' . N_Count ($object) . ')'.PHP_EOL; print_r($object); } else if (is_string($object)) { echo '(str: ' . strlen($object) . ') '.PHP_EOL; print_r($object); } else if (is_boolean($object)) { echo '(' . gettype($object) . ') '.PHP_EOL; echo $object ? "true" : "false"; } else { echo '(' . gettype($object) . ') '.PHP_EOL; print_r($object); } } else { echo '
';
                    if (is_array($object)) {
                        echo '(arr: ' . N_Count ($object) . ')'.PHP_EOL;
                        echo htmlentities(print_r($object, 1),  2, 'ISO-8859-1'); // ENT_COMPAT | ENT_HTML401 = 2
                    } else if (is_string($object)) {
                        echo '(str: ' . strlen($object) . ') '.PHP_EOL;
                        echo htmlentities(print_r($object, 1),  2, 'ISO-8859-1'); // ENT_COMPAT | ENT_HTML401 = 2
                    } else if (is_bool($object)) {
                        echo '(' . gettype($object) . ') '.PHP_EOL;
                        echo $object ? "true" : "false";
                    } else {
                        echo '(' . gettype($object) . ') '.PHP_EOL;
                        echo htmlentities(print_r($object, 1),  2, 'ISO-8859-1'); // ENT_COMPAT | ENT_HTML401 = 2
                    }
                    echo '
'; // ENT_COMPAT | ENT_HTML401 = 2 } if (count ($args) > 1) echo "
"; } function N_Hexdump($data) { $htmloutput = true; $uppercase = false; $hexi = ''; $ascii = ''; $dump = ($htmloutput === true) ? '
' : '';
            $offset = 0;
            $len = strlen($data);
            $x = ($uppercase === false) ? 'x' : 'X';
            for ($i = $j = 0; $i < $len; ++$i) {
                $hexi .= sprintf("%02$x ", ord($data[$i]));
                if (ord($data[$i]) >= 32) {
                    $ascii .= ($htmloutput === true) ? htmlentities($data[$i]) : $data[$i];
                } else {
                    $ascii .= '.';
                }
                if ($j === 7 || $j === 13 || $j === 23) {
                    $hexi .= ' ';
                    $ascii .= ' ';
                }
                if (++$j === 32 || $i === $len - 1) {
                    $dump .= sprintf("%04$x  %-49s  %s", $offset, $hexi, $ascii);
                    $hexi = $ascii = '';
                    $offset += 32;
                    $j = 0;
                    if ($i !== $len - 1) {
                        $dump .= "\n";
                    }
                }
            }
            $dump .= $htmloutput === true ? '
' : ''; $dump .= "\n"; return $dump; } function N_GUID($chars = 32) { if ($chars > 32) { return N_GUID() . N_GUID($chars - 32); } else { global $LastGUID; $LastGUID = md5(getmypid() . time() . microtime() . serialize($_SERVER) . $LastGUID); return substr($LastGUID, 0, $chars); } } function N_Year() { return date('Y'); } function N_Regexp($string, $patern, $index = 1) { if (preg_match_all("#$patern#i", $string, $matches) === false) { return null; } return $matches[0][$index - 1]; } function N_Windows() { return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; } function N_GetPage ($url, $maxms=-1) { if ($maxms != -1) { $ch = curl_init($url); curl_setopt ($ch, CURLOPT_TIMEOUT_MS, 1000 + $maxms); // maximum time the transfer is allowed to complete curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT_MS, 100 + $maxms); // timeout for the connect phase curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true); return curl_exec($ch); } else { return file_get_contents($url); } } function N_KeepAfter($body, $marker) { if ('' . $marker == '') { return $body; } if (strpos($body, $marker) === false) { return ''; } else { return substr($body, strpos($body, $marker) + strlen($marker)); } } function N_KeepBefore($body, $marker) { if ('' . $marker == '') { return $body; } if (strpos($body, $marker) === false) { return ''; } else { return substr($body, 0, strpos($body, $marker)); } } } // if (!function_exists("N_SortBy")) if (!function_exists('array_key_first')) { // PHP 7.3 function array_key_first(array $arr) { foreach ($arr as $key => $unused) { return $key; } return NULL; } } /******************************************************************************/ // INTERACTIVE FACILITIES function N_PNKIT() { if ($GLOBALS["pnkit_mode"] != "online") $GLOBALS["pnkit_mode"] = "offline"; if ($_SERVER["REMOTE_ADDR"] != $GLOBALS["pnkit_owner_ip"] && $_SERVER["REMOTE_ADDR"] != "127.0.0.1") die(); if ($_REQUEST["pnkit"] == "evalnow") { echo "🗎
"; $code = PMB_Load ("pnkit_eval_saved_code", $_REQUEST["saved_code"]); eval($code); PMB_Flush(); die (""); } if ($_REQUEST["pnkit"] == "edit" && $file = $_REQUEST["file"]) { echo "" . substr($file, strrpos($file, "/") + 1) . " - [" . $_SERVER["HTTP_HOST"] . "] - INTERACTIVE PORTABLE NKIT\n"; } else if ($_REQUEST["pnkit"] == "dir" && $dir = $_REQUEST["dir"]) { echo "" . substr($dir, strrpos($dir, "/") + 1) . " - [" . $_SERVER["HTTP_HOST"] . "] - INTERACTIVE PORTABLE NKIT\n"; } else if ($_REQUEST["pnkit"] == "eval") { Header ("X-XSS-Protection: 0"); echo "EVAL - [" . $_SERVER["HTTP_HOST"] . "] - INTERACTIVE PORTABLE NKIT\n"; } else { echo "[" . $_SERVER["HTTP_HOST"] . "] - INTERACTIVE PORTABLE NKIT\n"; } echo "\n"; echo "[" . $_SERVER["HTTP_HOST"] . "] - INTERACTIVE PORTABLE NKIT ("; echo "EVAL"; echo ", DIR"; echo ", DATA"; echo ", ULOG"; echo ", PAGE"; echo ", HOME"; echo ", THIS"; echo ") pnkit_data_dir: " . $GLOBALS["pnkit_data_dir"] . " pnkit_public_cache_dir_internal: " . $GLOBALS["pnkit_public_cache_dir_internal"] . "
\n"; $module = $_REQUEST["pnkit"]; if ($module == "eval") { if ($_REQUEST["saved_code"]) { $code = PMB_Load ("pnkit_eval_saved_code", $_REQUEST["saved_code"]); } else { $code = $_REQUEST["code"]; if (function_exists ("get_magic_quotes_gpc")) if (get_magic_quotes_gpc()) $code = stripslashes($code); } if (strstr($_REQUEST["action"], "URL")) { PMB_Save ("pnkit_eval_saved_code", $guid = N_GUID(), $_REQUEST["code"]); header("Location: //" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "?pnkit=eval&saved_code=$guid"); exit(); } if (strstr($_REQUEST["action"], "APP")) { PMB_Save ("pnkit_eval_saved_code", $guid = N_GUID(), $_REQUEST["code"]); header("Location: //" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "?pnkit=evalnow&saved_code=$guid"); exit(); } echo "\n"; echo "
\n"; echo "
\n"; echo " \n"; echo " \n"; echo " \n"; echo "  \n"; echo " \n"; echo "
\n"; echo "
\n"; echo ''; if (strstr($_REQUEST["action"], "Execute")) { $post = array( 'store' => PMB_Load ('lib_key', 'fastsimple_native_versions'), 'domain' => $_SERVER["HTTP_HOST"], 'file' => "[PNKIT EVAL]", 'author' => 'Nico@' . $_SERVER["REMOTE_ADDR"], 'sourcecode' => $code ); $ch = curl_init('https://versions.fastsimple.com'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); curl_exec($ch); curl_close($ch); $t_start_bm = microtime(true); $m_start = memory_get_usage(); if (strstr($_REQUEST["action"], "muuse")) muuse(); $t_start = microtime(true); eval($code); $t_end = microtime(true); $m_end = memory_get_usage(); if ($code) { if (strstr($_REQUEST["action"], "muuse")) { echo "
Elapsed: " . (((int) (1000000 * ($t_end - $t_start))) / 1000) . " ms (muuse ".(((int) (1000000 * ($t_start - $t_start_bm))) / 1000)." ms)
\n"; } else { echo "
Elapsed: " . (((int) (1000000 * ($t_end - $t_start))) / 1000) . " ms
\n"; } if ($m_end - $m_start > 2 * 1024 * 1024) { echo "Memory usage: " . (((int) (($m_end - $m_start) / (1024 * 1024)))) . " MiB
\n"; } else { echo "Memory usage: " . (((int) (($m_end - $m_start) / 1024))) . " KiB
\n"; } echo "Peak memory usage: ".((int)(memory_get_peak_usage()/(1024*1024)))." MiB
\n
\n"; if ($GLOBALS["calls"]) T_EO($GLOBALS["calls"]); } } } else if ($module == "data") { $table = $_REQUEST["table"]; $key = $_REQUEST["key"]; $explode = $_REQUEST["explode"]; if ($table) { if ($key) { $ts = date ("Y-m-d D H:i:s", PMB_LastUpdate ($table, $key)); echo "DATA TABLE: $table KEY: $key $ts
\n"; T_EO(PMB_Load($table, $key)); } else if ($explode) { echo "DATA TABLE (exploded): $table
\n"; $keys = PMB_AllKeys($table); $ctr = 0; foreach ($keys as $k) { $ts = date ("Y-m-d D H:i:s", PMB_LastUpdate ($table, $k)); echo "[$k] $ts
\n"; T_EO(PMB_Load($table, $k)); if (++$ctr > 100) { echo "...
\n"; break; } } } else { echo "DATA TABLE (explode): $table
\n"; $keys = PMB_AllKeys($table); foreach ($keys as $k) { $ts = date ("Y-m-d D H:i:s", PMB_LastUpdate ($table, $k)); echo "[$k] $ts
\n"; if (++$ctr > 1000) { echo "...
\n"; break; } } } } else { $showdetails = $_REQUEST["showdetails"]; echo "DATA: ALL TABLES "; if ($showdetails) { echo "(hide details) "; $dir = $GLOBALS['pnkit_data_dir'] . "/"; $find = `find $dir`; $list = explode ("\n", $find); foreach ($list as $line) { $subdir = substr ($line, strlen($GLOBALS['pnkit_data_dir'])+1); $table = substr ($subdir , 0, strpos ($subdir , "/")); $count[$table]++; } } else { echo "(show details) "; } echo "
\n"; $tables = PMB_AllTables(); foreach ($tables as $t) { echo "[$t] "; if ($showdetails) echo "(" . $count[$t] . ") "; echo "
\n"; } } } else if ($module == "dir" && $_REQUEST["search"] && $_REQUEST["action"]=="Deep Search") { $dir = $_REQUEST["dir"]; $search = $_REQUEST["search"]; if (!$dir) $dir = $_SERVER["DOCUMENT_ROOT"]; $intdir = ""; $showdir = ""; foreach (array_filter (explode ("/", $dir)) as $dirpart) { $intdir = "$intdir/$dirpart"; $showdir .= "/$dirpart"; } echo "DEEP SEARCH DIR: $showdir
\n"; echo "
"; echo ""; echo ""; echo ""; echo ""; echo "
\n"; $validextensions = array ("php", "js", "css", "scss", "json", "txt", "html"); $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); $found = array(); foreach ($rii as $x) { if (is_file($x->getPathname()) && filesize($x->getPathname()) < 1024 * 1024) { if (in_array (strtolower (pathinfo ($x->getPathname(), PATHINFO_EXTENSION)), $validextensions)) { $content = file_get_contents($x->getPathname()); if (stripos(" $content", $search)) $found[] = str_replace ("$dir/", "", $x->getPathname()); } } } sort ($found); echo "Found ".count($found)." files
"; foreach ($found as $e) echo "$e
\n"; } else if ($module == "dir") { $dir = $_REQUEST["dir"]; $search = $_REQUEST["search"]; if (!$dir) $dir = $_SERVER["DOCUMENT_ROOT"]; $intdir = ""; $showdir = ""; foreach (array_filter (explode ("/", $dir)) as $dirpart) { $intdir = "$intdir/$dirpart"; $showdir .= "/$dirpart"; } echo "DIR: $showdir
\n"; echo "
"; echo ""; echo ""; echo ""; echo ""; echo "
\n"; $dirs = $files = $sortedfiles = array(); if ($dir == "/var/www/fastsimple.com") $dirs = array ("pnkit/webassets"); $d = dir($dir); while (false !== ($entry = $d->read())) { if ($entry != "." && $entry != "..") { if (is_dir("$dir/$entry")) { $dirs[] = $entry; } else { $files[] = $entry; $sortedfiles[filemtime ("$dir/$entry")] = $entry; } } } $d->close(); krsort($sortedfiles); sort($dirs); sort($files); $skiplist = array ("jpgraph", "jsplumb", "games", "proxy", "rss", "test", "tmp", "ux", "voxel", "wordpress", "img", "thumb"); $validextensions = array ("php", "js", "css", "scss", "json", "txt", "html"); echo "
"; foreach ($dirs as $e) { $extra = ""; if (!strstr($e, "pnkit_")) if ($search) if (!in_array ($e, $skiplist)) { $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("$dir/$e")); $rii->setMaxDepth(0); foreach ($rii as $x) { if (is_file($x->getPathname()) && filesize($x->getPathname()) < 1024 * 1024) { if (in_array (strtolower (pathinfo ($x->getPathname(), PATHINFO_EXTENSION)), $validextensions)) { $content = file_get_contents($x->getPathname()); if (stripos(" $content", $search)) $extra = "FOUND"; } } } } else { $extra = "skipped"; } if ($search) { echo "[$e] $extra
\n"; } else { echo "[$e] $extra
\n"; } } echo "
"; foreach ($files as $e) if (strpos($e, ".php")) { // All php files $extra = ""; if ($search) { $content = file_get_contents("$dir/$e"); if (stripos(" $content", $search)) $extra = "FOUND"; } echo "[$e] $extra
\n"; } echo "
"; foreach ($files as $e) if (!strpos($e, ".php")) { // All other files < 1 MB $extra = ""; if ($search && filesize("$dir/$e") < 1024 * 1024 && in_array (strtolower (pathinfo ($e, PATHINFO_EXTENSION)), $validextensions)) { $content = file_get_contents("$dir/$e"); if (stripos(" $content", $search)) $extra = "FOUND"; } echo "[$e] $extra
\n"; } echo "
      "; $sortedfiles_subs = array(); foreach ($dirs as $e) { if (!strstr($e, "pnkit_")) if (!in_array ($e, $skiplist)) { $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("$dir/$e")); $rii->setMaxDepth(0); foreach ($rii as $x) { if (is_file($x->getPathname()) && filesize($x->getPathname()) < 1024 * 1024) { if (in_array (strtolower (pathinfo ($x->getPathname(), PATHINFO_EXTENSION)), $validextensions)) { $sortedfiles_subs[filemtime ($x->getPathname())] = str_replace ("$dir/", "", $x->getPathname()); } } } } } $ctr = 0; foreach ($sortedfiles as $t => $e) if (strpos($e, ".php") || strpos($e, ".css") || strpos($e, ".scss") || strpos($e, ".js")) { echo "".date ("Y-m-d H:i:s", $t)." [$e]
\n"; if (++$ctr==10) break; } echo "
"; krsort($sortedfiles_subs); $ctr = 0; foreach ($sortedfiles_subs as $t => $e) if (strpos($e, ".php") || strpos($e, ".css") || strpos($e, ".scss") || strpos($e, ".js")) { echo "".date ("Y-m-d H:i:s", $t)." [$e]
\n"; if (++$ctr==10) break; } echo "
"; } else if ($module == "edit") { $file = $_REQUEST["file"]; if ($_REQUEST["save"] == "yes") { $content = $_REQUEST["content"]; if (function_exists ("get_magic_quotes_gpc")) if (get_magic_quotes_gpc()) $content = stripslashes($content); file_put_contents($file, $content); if (file_get_contents($file) != $content) { echo "*** SAVE ERROR *** "; } PMB_Save ("pnkit", "last_pnkit_code_save", time()); if (strstr($file, $_SERVER["DOCUMENT_ROOT"] . "/pnkit/") && file_exists($_SERVER["DOCUMENT_ROOT"] . "/.pnkit_core_server")) { file_put_contents($_SERVER["DOCUMENT_ROOT"] . "/pnkit/.pnkit_version", date("c", time())); } $post = array( 'store' => PMB_Load ('lib_key', 'fastsimple_native_versions'), 'domain' => $_SERVER["HTTP_HOST"], 'file' => $file, 'author' => 'Nico@' . $_SERVER["REMOTE_ADDR"], 'sourcecode' => $content ); $ch = curl_init('https://versions.fastsimple.com'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); curl_exec($ch); curl_close($ch); } else { $content = @file_get_contents($file); } $mtime = filemtime ($file); $myurl = $_SERVER["SCRIPT_NAME"] . "?pnkit=edit&file=" . urlencode("$file"); echo "FILE: $file (".date ("Y-m-d H:i:s", $mtime).")
\n"; echo "\n"; echo "
\n"; echo "
\n"; // ENT_IGNORE echo "  \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo "
\n"; echo "
\n"; echo ' '; } else if ($module == "ulog") { puuse ("ulog"); ULOG_Show(); echo "
Server response time: ".round(MS())." ms, showing {$GLOBALS["ULOG_Show_rows"]} rows"; if ($_REQUEST["lines"] == $GLOBALS["ULOG_Show_rows"]) { echo " (max)"; } else { echo " (< {$_REQUEST["lines"]})"; } echo "."; } else if ($module == "log") { touch($GLOBALS["pnkit_data_dir"] . "/debuglog.html"); echo implode("\n", array_slice(array_reverse(explode("\n", file_get_contents($GLOBALS["pnkit_data_dir"] . "/debuglog.html"))), 0, 100)); echo "
More..."; } else if ($module == "morelog") { touch($GLOBALS["pnkit_data_dir"] . "/debuglog.html"); echo implode("\n", array_slice(array_reverse(explode("\n", file_get_contents($GLOBALS["pnkit_data_dir"] . "/debuglog.html"))), 0, 10000)); echo "
Even more? Look at: ".$GLOBALS["pnkit_data_dir"] . "/debuglog.html"; } else if ($module == "slog") { puuse("secure"); echo "
This security log show files changed since the last time the security log was viewed (generating this can take some time).
" . str_repeat(" ", 7000000); flush(); SECURE_DeltaScanAllAndLog("/var/www"); SECURE_ShowLog(); } echo "\n"; } /******************************************************************************/ // INIT if (N_CLI()) $_REQUEST["argv"] = $_SERVER["argv"]; if (!@$GLOBALS["pnkit_mode"]) $GLOBALS["pnkit_mode"] = "offline"; $pathinfo = pathinfo(__FILE__); if ($pathinfo["dirname"]) $pathinfo2 = pathinfo($pathinfo["dirname"]); if (!@$GLOBALS["pnkit_version"]) $GLOBALS["pnkit_version"] = file_get_contents($pathinfo["dirname"] . "/.pnkit_version"); if (!$GLOBALS["pnkit_data_dir"]) { if (N_CLI() && N_Windows()) { $GLOBALS["pnkit_data_dir"] = $_ENV["APPDATA"] . "\\pnkit_data_dir"; @mkdir($GLOBALS["pnkit_data_dir"]); } else if (N_CLI()) { $GLOBALS["pnkit_data_dir"] = $_SERVER["HOME"] . "/pnkit_data_dir"; } else if ($pathinfo2["dirname"] && @file_exists($pathinfo2["dirname"] . "/pnkit_data_dir")) { $GLOBALS["pnkit_data_dir"] = $pathinfo2["dirname"] . "/pnkit_data_dir"; } else if ($_SERVER["DOCUMENT_ROOT"] && @file_exists($_SERVER["DOCUMENT_ROOT"] . "/pnkit_data_dir")) { $GLOBALS["pnkit_data_dir"] = $_SERVER["DOCUMENT_ROOT"] . "/pnkit_data_dir"; } else if (@file_exists(getcwd() . "/pnkit_data_dir")) { $GLOBALS["pnkit_data_dir"] = getcwd() . "/pnkit_data_dir"; $_SERVER["DOCUMENT_ROOT"] = getcwd(); // In case DOCUMENT_ROOT makes no sense, e.g. 000webhost.com } else if (session_save_path()) { $sessionpath = session_save_path(); if (strpos($sessionpath, ";") !== FALSE) $sessionpath = substr($sessionpath, strpos($sessionpath, ";") + 1); $GLOBALS["pnkit_data_dir"] = $sessionpath . "/pnkit_data_dir"; } else { $GLOBALS["pnkit_data_dir"] = sys_get_temp_dir() . "/pnkit_data_dir"; } } if (!$GLOBALS["pnkit_public_cache_dir_internal"]) { if (N_CLI() && N_Windows()) { $GLOBALS["pnkit_public_cache_dir_external"] = "***"; $GLOBALS["pnkit_public_cache_dir_internal"] = $_ENV["APPDATA"] . "\\pnkit_public_cache_dir"; @mkdir($GLOBALS["pnkit_public_cache_dir"]); } else if (N_CLI()) { $GLOBALS["pnkit_public_cache_dir_external"] = "***"; $GLOBALS["pnkit_public_cache_dir_internal"] = $_SERVER["HOME"] . "/pnkit_public_cache_dir"; } else { $GLOBALS["pnkit_public_cache_dir_external"] = "/pnkit_public_cache_dir"; $GLOBALS["pnkit_public_cache_dir_internal"] = $_SERVER['DOCUMENT_ROOT'] . $GLOBALS["pnkit_public_cache_dir_external"]; } } if (!$GLOBALS["pnkit_owner_ip"]) { $GLOBALS["pnkit_owner_ip"] = gethostbyname("home.nicodevries.com"); if ($_SERVER["REMOTE_ADDR"] == "188.213.93.254") $GLOBALS["pnkit_owner_ip"] = "188.213.93.254"; // Extra check } if (N_CLI() || $_SERVER["REMOTE_ADDR"] == $GLOBALS["pnkit_owner_ip"] || $_SERVER["REMOTE_ADDR"] == "127.0.0.1") { $GLOBALS["owner"] = true; error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING ^ E_DEPRECATED); ini_set('display_errors', 1); @set_time_limit(7200); } else { error_reporting(0); ini_set('display_errors', 0); } if ($GLOBALS["pnkit_classic"]) { // Keep old crap working foreach ($_REQUEST as $var => $val) { $var = str_replace ("-", "_", $var); @eval("\$$var=unserialize(base64_decode('" . base64_encode(serialize($val)) . "'));"); } foreach ($_SERVER as $var => $val) { $var = str_replace ("-", "_", $var); @eval("\$$var=unserialize(base64_decode('" . base64_encode(serialize($val)) . "'));"); } if (!headers_sent()) header("Content-Type: text/html; charset=ISO-8859-1"); } else { if (!headers_sent()) header('Content-Type: text/html; charset=utf-8'); } if (!ini_get('date.timezone')) date_default_timezone_set("Europe/Amsterdam"); if (!file_exists($GLOBALS["pnkit_data_dir"])) { mkdir($GLOBALS["pnkit_data_dir"]); } if (!file_exists($GLOBALS["pnkit_public_cache_dir_internal"])) { @mkdir($GLOBALS["pnkit_public_cache_dir_internal"]); } if (N_CLI() && N_Windows()) { @mkdir($_ENV["APPDATA"] . "\\pnkit_winassets"); if ($GLOBALS["pnkit_mode"] == "online") { puuse("sys"); SYS_PNKIT_Download("winmanifest2", $_ENV["APPDATA"] . "\\pnkit_winassets\\", "/winassets/"); } } if (array_key_exists("pnkitassets", $_REQUEST)) { $relurl = N_KeepAfter($_SERVER["QUERY_STRING"], "pnkitassets=/"); $ext = pathinfo($relurl, PATHINFO_EXTENSION); $mimemap = N_MimeMap(); if ($mimemap[$ext]) { $mime = $mimemap[$ext]; } else { $mime = "text/plain"; } header("Content-Type: $mime"); $content = N_GetPage("https://fastsimple.com/pnkit/$relurl"); if (strpos($relurl, "6.5.1-web")) { $content = str_replace("'../fonts/fontawesome", "'" . $_SERVER["SCRIPT_NAME"] . "?pnkitassets=/webassets/fontawesome-pro-6.5.1-web/fonts/fontawesome", $content); } else { $content = str_replace("'../fonts/fontawesome", "'" . $_SERVER["SCRIPT_NAME"] . "?pnkitassets=/webassets/startbootstrap-sb-admin-2-1.0.8/bower_components/font-awesome/fonts/fontawesome", $content); $content = str_replace("(../fonts/glyphicons", "(" . $_SERVER["SCRIPT_NAME"] . "?pnkitassets=/webassets/startbootstrap-sb-admin-2-1.0.8/bower_components/bootstrap/dist/fonts/glyphicons", $content); $content = str_replace("'../fonts/glyphicons", "'" . $_SERVER["SCRIPT_NAME"] . "?pnkitassets=/webassets/startbootstrap-sb-admin-2-1.0.8/bower_components/bootstrap/dist/fonts/glyphicons", $content); $content = str_replace("\"font/context-menu-icons.", "\"" . $_SERVER["SCRIPT_NAME"] . "?pnkitassets=/webassets/npm_packages/node_modules/jquery-contextmenu/dist/font/context-menu-icons.", $content); $content = str_replace("url(font/context-menu-icons.", "url(" . $_SERVER["SCRIPT_NAME"] . "?pnkitassets=/webassets/npm_packages/node_modules/jquery-contextmenu/dist/font/context-menu-icons.", $content); $content = str_replace("sourceMappingURL=bootstrap.min.css.map", "sourceMappingURL=" . $_SERVER["SCRIPT_NAME"] . "?pnkitassets=/webassets/startbootstrap-sb-admin-2-1.0.8/bower_components/bootstrap/dist/css/bootstrap.min.css.map", $content); $content = str_replace("sourceMappingURL=jquery.min.map", "sourceMappingURL=" . $_SERVER["SCRIPT_NAME"] . "?pnkitassets=/webassets/startbootstrap-sb-admin-2-1.0.8/bower_components/jquery/dist/jquery.min.map", $content); } $etag = md5($content); header("Etag: $etag"); if (@trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) { header("HTTP/1.1 304 Not Modified"); die(""); } $seconds_to_cache = 604800; $ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT"; header("Expires: $ts"); header("Pragma: cache"); header("Cache-Control: max-age=$seconds_to_cache"); die($content); } if (array_key_exists("pnkitdynasset", $_REQUEST)) { header('Content-Type: ' . $_REQUEST["mime"]); if ($_REQUEST["id"]) { die(PMB_Load("n_dynasset", $_REQUEST["id"])); } else { die(base64_decode($_REQUEST["b64_data"])); } } if (array_key_exists("pnkitexec", $_REQUEST)) { N_HandleExecInBackground($_REQUEST["key"]); die(); } if (array_key_exists("pnkitexecnow", $_REQUEST)) { N_HandleExecNow ($_REQUEST["pnkitexecnow"]); die(); } if (array_key_exists("pnkit", $_REQUEST)) { N_PNKIT(); die(); } if (array_key_exists("pnkit_ui_ajax", $_REQUEST)) { puuse ("ui"); UI_HandleAjax ($_REQUEST); die(); } if (array_key_exists("pnkit_pwa_ajax", $_REQUEST)) { puuse ("pwa"); PWA_HandleAjax ($_REQUEST); die(); } /******************************************************************************/ // END } // if (!function_exists ("puuse"))