";echo $result;}function print_embedded_as_is($key) {global $external;if(!array_key_exists($key, $external)) {// throw new Exception('Key missing in external: ' . key);echo "";return;}$result = base64_decode("$external[$key]");return $result;}function get_favicon($key) {global $external;if(!array_key_exists($key, $external)) {// throw new Exception('Key missing in external: ' . key);echo "";return;}$result = "$external[$key]";echo $result;}/** * Verify CSRF TOKEN and remove after cerify * @param string $token * @return bool */function verifyToken($token) {if (hash_equals($_SESSION['token'], $token)) { return true;}return false;}/** * Deletefile or folder (recursively) * @param string $path * @return bool */function fm_rdelete($path){if (is_link($path)) {return unlink($path);} elseif (is_dir($path)) {$objects = scandir($path);$ok = true;if (is_array($objects)) {foreach ($objects as $file) {if ($file != '.' && $file != '..') {if (!fm_rdelete($path . '/' . $file)) {$ok = false;}}}}return ($ok) ? rmdir($path) : false;} elseif (is_file($path)) {return unlink($path);}return false;}/** * Recursive chmod * @param string $path * @param int $filemode * @param int $dirmode * @return bool * @todo Will use in mass chmod */function fm_rchmod($path, $filemode, $dirmode){if (is_dir($path)) {if (!chmod($path, $dirmode)) {return false;}$objects = scandir($path);if (is_array($objects)) {foreach ($objects as $file) {if ($file != '.' && $file != '..') {if (!fm_rchmod($path . '/' . $file, $filemode, $dirmode)) {return false;}}}}return true;} elseif (is_link($path)) {return true;} elseif (is_file($path)) {return chmod($path, $filemode);}return false;}/** * Check the file extension which is allowed or not * @param string $filename * @return bool */function fm_is_valid_ext($filename){$allowed = (FM_FILE_EXTENSION) ? explode(',', FM_FILE_EXTENSION) : false;$ext = pathinfo($filename, PATHINFO_EXTENSION);$isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true;return ($isFileAllowed) ? true : false;}/** * Safely rename * @param string $old * @param string $new * @return bool|null */function fm_rename($old, $new){$isFileAllowed = fm_is_valid_ext($new);if(!is_dir($old)) {if (!$isFileAllowed) return false;}return (!file_exists($new) && file_exists($old)) ? rename($old, $new) : null;}/** * Copy file or folder (recursively). * @param string $path * @param string $dest * @param bool $upd Update files * @param bool $force Create folder with same names instead file * @return bool */function fm_rcopy($path, $dest, $upd = true, $force = true){if (is_dir($path)) {if (!fm_mkdir($dest, $force)) {return false;}$objects = scandir($path);$ok = true;if (is_array($objects)) {foreach ($objects as $file) {if ($file != '.' && $file != '..') {if (!fm_rcopy($path . '/' . $file, $dest . '/' . $file)) {$ok = false;}}}}return $ok;} elseif (is_file($path)) {return fm_copy($path, $dest, $upd);}return false;}/** * Safely create folder * @param string $dir * @param bool $force * @return bool */function fm_mkdir($dir, $force){if (file_exists($dir)) {if (is_dir($dir)) {return $dir;} elseif (!$force) {return false;}unlink($dir);}return mkdir($dir, 0777, true);}/** * Safely copy file * @param string $f1 * @param string $f2 * @param bool $upd Indicates if file should be updated with new content * @return bool */function fm_copy($f1, $f2, $upd){$time1 = filemtime($f1);if (file_exists($f2)) {$time2 = filemtime($f2);if ($time2 >= $time1 && $upd) {return false;}}$ok = copy($f1, $f2);if ($ok) {touch($f2, $time1);}return $ok;}/** * Get mime type * @param string $file_path * @return mixed|string */function fm_get_mime_type($file_path){if (function_exists('finfo_open')) {$finfo = finfo_open(FILEINFO_MIME_TYPE);$mime = finfo_file($finfo, $file_path);finfo_close($finfo);return $mime;} elseif (function_exists('mime_content_type')) {return mime_content_type($file_path);} elseif (!stristr(ini_get('disable_functions'), 'shell_exec')) {$file = escapeshellarg($file_path);$mime = shell_exec('file -bi ' . $file);return $mime;} else {return '--';}}/** * HTTP Redirect * @param string $url * @param int $code */function fm_redirect($url, $code = 302){header('Location: ' . $url, true, $code);exit;}/** * Path traversal prevention and clean the url * It replaces (consecutive) occurrences of / and \\ with whatever is in DIRECTORY_SEPARATOR, and processes /. and /.. fine. * @param $path * @return string */function get_absolute_path($path) {$path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path);$parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen');$absolutes = array();foreach ($parts as $part) {if ('.' == $part) continue;if ('..' == $part) {array_pop($absolutes);} else {$absolutes[] = $part;}}return implode(DIRECTORY_SEPARATOR, $absolutes);}/** * Clean path * @param string $path * @return string */function fm_clean_path($path, $trim = true){$path = $trim ? trim($path) : $path;$path = trim($path, '\\/');$path = str_replace(array('../', '..\\'), '', $path);$path =get_absolute_path($path);if ($path == '..') {$path = '';}return str_replace('\\', '/', $path);}/** * Get parent path * @param string $path * @return bool|string */function fm_get_parent_path($path){$path = fm_clean_path($path);if ($path != '') {$array = explode('/', $path);if (count($array) > 1) {$array = array_slice($array, 0, -1);return implode('/', $array);}return '';}return false;}function fm_get_display_path($file_path){global $path_display_mode, $root_path, $root_url;switch ($path_display_mode) {case 'relative':return array('label' => 'Path','path' => fm_enc(fm_convert_win(str_replace($root_path, '', $file_path))));case 'host':$relative_path = str_replace($root_path, '', $file_path);return array('label' => 'Host Path','path' => fm_enc(fm_convert_win('/' . $root_url . '/' . ltrim(str_replace('\\', '/', $relative_path), '/'))));case 'full':default:return array('label' => 'Full Path','path' => fm_enc(fm_convert_win($file_path)));}}/** * Check file is in exclude list * @param string $file * @return bool */function fm_is_exclude_items($file) {$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));if (isset($exclude_items) and sizeof($exclude_items)) {unset($exclude_items);}$exclude_items = FM_EXCLUDE_ITEMS;if (version_compare(PHP_VERSION, '7.0.0', '<')) {$exclude_items = unserialize($exclude_items);}if (!in_array($file, $exclude_items) && !in_array("*.$ext", $exclude_items)) {return true;}return false;}/** * get language translations from json file * @param int $tr * @return array */function fm_get_translations($tr) {try {$content = print_embedded_as_is('config-translation-file');if($content !== FALSE) {$lng = json_decode($content, TRUE);global $lang_list;foreach ($lng["language"] as $key => $value){$code = $value["code"];$lang_list[$code] = $value["name"];if ($tr)$tr[$code] = $value["translation"];}return $tr;}}catch (Exception $e) {echo $e;}}/** * @param string $file * Recover all file sizes larger than > 2GB. * Works on php 32bits and 64bits and supports linux * @return int|string */function fm_get_size($file){static $iswin;static $isdarwin;if (!isset($iswin)) {$iswin = (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN');}if (!isset($isdarwin)) {$isdarwin = (strtoupper(substr(PHP_OS, 0)) == "DARWIN");}static $exec_works;if (!isset($exec_works)) {$exec_works = (function_exists('exec') && !ini_get('safe_mode') && @exec('echo EXEC') == 'EXEC');}// try a shell commandif ($exec_works) {$arg = escapeshellarg($file);$cmd = ($iswin) ? "for %F in (\"$file\") do @echo %~zF" : ($isdarwin ? "stat -f%z $arg" : "stat -c%s $arg");@exec($cmd, $output);if (is_array($output) && ctype_digit($size = trim(implode("\n", $output)))) {return $size;}}// try the Windows COM interfaceif ($iswin && class_exists("COM")) {try {$fsobj = new COM('Scripting.FileSystemObject');$f = $fsobj->GetFile( realpath($file) );$size = $f->Size;} catch (Exception $e) {$size = null;}if (ctype_digit($size)) {return $size;}}// if all else failsreturn filesize($file);}/** * Get nice filesize * @param int $size * @return string */function fm_get_filesize($size){$size = (float) $size;$units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');$power = ($size > 0) ? floor(log($size, 1024)) : 0;$power = ($power > (count($units) - 1)) ? (count($units) - 1) : $power;return sprintf('%s %s', round($size / pow(1024, $power), 2), $units[$power]);}/** * Get total size of directory tree. * * @paramstring $directory Relative or absolute directory name. * @return int Total number of bytes. */function fm_get_directorysize($directory) {$bytes = 0;$directory = realpath($directory);if ($directory !== false && $directory != '' && file_exists($directory)){foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS)) as $file){$bytes += $file->getSize();}}return $bytes;}/** * Get info about zip archive * @param string $path * @return array|bool */function fm_get_zif_info($path, $ext) {if ($ext == 'zip' && function_exists('zip_open')) {$arch = @zip_open($path);if ($arch) {$filenames = array();while ($zip_entry = @zip_read($arch)) {$zip_name = @zip_entry_name($zip_entry);$zip_folder = substr($zip_name, -1) == '/';$filenames[] = array('name' => $zip_name,'filesize' => @zip_entry_filesize($zip_entry),'compressed_size' => @zip_entry_compressedsize($zip_entry),'folder' => $zip_folder//'compression_method' => zip_entry_compressionmethod($zip_entry),);}@zip_close($arch);return $filenames;}} elseif($ext == 'tar' && class_exists('PharData')) {$archive = new PharData($path);$filenames = array();foreach(new RecursiveIteratorIterator($archive) as $file) {$parent_info = $file->getPathInfo();$zip_name = str_replace("phar://".$path, '', $file->getPathName());$zip_name = substr($zip_name, ($pos = strpos($zip_name, '/')) !== false ? $pos + 1 : 0);$zip_folder = $parent_info->getFileName();$zip_info = new SplFileInfo($file);$filenames[] = array('name' => $zip_name,'filesize' => $zip_info->getSize(),'compressed_size' => $file->getCompressedSize(),'folder' => $zip_folder);}return $filenames;}return false;}/** * Encode html entities * @param string $text * @return string */function fm_enc($text){return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');}/** * Prevent XSS attacks * @param string $text * @return string */function fm_isvalid_filename($text) {return (strpbrk($text, '/?%*:|"<>') === FALSE) ? true : false;}/** * Save message in session * @param string $msg * @param string $status */function fm_set_msg($msg, $status = 'ok'){$_SESSION[FM_SESSION_ID]['message'] = $msg;$_SESSION[FM_SESSION_ID]['status'] = $status;}/** * Check if string is in UTF-8 * @param string $string * @return int */function fm_is_utf8($string){return preg_match('//u', $string);}/** * Convert file name to UTF-8 in Windows * @param string $filename * @return string */function fm_convert_win($filename){if (FM_IS_WIN && function_exists('iconv')) {$filename = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $filename);}return $filename;}/** * @param $obj * @return array */function fm_object_to_array($obj){if (!is_object($obj) && !is_array($obj)) {return $obj;}if (is_object($obj)) {$obj = get_object_vars($obj);}return array_map('fm_object_to_array', $obj);}/** * Get CSS classname for file * @param string $path * @return string */function fm_get_file_icon_class($path){// get extension$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));switch ($ext) {case 'ico':case 'gif':case 'jpg':case 'jpeg':case 'jpc':case 'jp2':case 'jpx':case 'xbm':case 'wbmp':case 'png':case 'bmp':case 'tif':case 'tiff':case 'webp':case 'avif':case 'svg':$img = 'fa fa-picture-o';break;case 'passwd':case 'ftpquota':case 'sql':case 'js':case 'ts':case 'jsx':case 'tsx':case 'hbs':case 'json':case 'sh':case 'config':case 'twig':case 'tpl':case 'md':case 'gitignore':case 'c':case 'cpp':case 'cs':case 'py':case 'rs':case 'map':case 'lock':case 'dtd':$img = 'fa fa-file-code-o';break;case 'txt':case 'ini':case 'conf':case 'log':case 'htaccess':case 'yaml':case 'yml':case 'toml':case 'tmp':case 'top':case 'bot':case 'dat':case 'bak':case 'htpasswd':case 'pl':$img = 'fa fa-file-text-o';break;case 'css':case 'less':case 'sass':case 'scss':$img = 'fa fa-css3';break;case 'bz2':case 'zip':case 'rar':case 'gz':case 'tar':case '7z':case 'xz':$img = 'fa fa-file-archive-o';break;case 'php':case 'php4':case 'php5':case 'phps':case 'phtml':$img = 'fa fa-code';break;case 'htm':case 'html':case 'shtml':case 'xhtml':$img = 'fa fa-html5';break;case 'xml':case 'xsl':$img = 'fa fa-file-excel-o';break;case 'wav':case 'mp3':case 'mp2':case 'm4a':case 'aac':case 'ogg':case 'oga':case 'wma':case 'mka':case 'flac':case 'ac3':case 'tds':$img = 'fa fa-music';break;case 'm3u':case 'm3u8':case 'pls':case 'cue':case 'xspf':$img = 'fa fa-headphones';break;case 'avi':case 'mpg':case 'mpeg':case 'mp4':case 'm4v':case 'flv':case 'f4v':case 'ogm':case 'ogv':case 'mov':case 'mkv':case '3gp':case 'asf':case 'wmv':case 'webm':$img = 'fa fa-file-video-o';break;case 'eml':case 'msg':$img = 'fa fa-envelope-o';break;case 'xls':case 'xlsx':case 'ods':$img = 'fa fa-file-excel-o';break;case 'csv':$img = 'fa fa-file-text-o';break;case 'bak':case 'swp':$img = 'fa fa-clipboard';break;case 'doc':case 'docx':case 'odt':$img = 'fa fa-file-word-o';break;case 'ppt':case 'pptx':$img = 'fa fa-file-powerpoint-o';break;case 'ttf':case 'ttc':case 'otf':case 'woff':case 'woff2':case 'eot':case 'fon':$img = 'fa fa-font';break;case 'pdf':$img = 'fa fa-file-pdf-o';break;case 'psd':case 'ai':case 'eps':case 'fla':case 'swf':$img = 'fa fa-file-image-o';break;case 'exe':case 'msi':$img = 'fa fa-file-o';break;case 'bat':$img = 'fa fa-terminal';break;default:$img = 'fa fa-info-circle';}return $img;}/** * Get image files extensions * @return array */function fm_get_image_exts(){return array('ico', 'gif', 'jpg', 'jpeg', 'jpc', 'jp2', 'jpx', 'xbm', 'wbmp', 'png', 'bmp', 'tif', 'tiff', 'psd', 'svg', 'webp', 'avif');}/** * Get video files extensions * @return array */function fm_get_video_exts(){return array('avi', 'webm', 'wmv', 'mp4', 'm4v', 'ogm', 'ogv', 'mov', 'mkv');}/** * Get audio files extensions * @return array */function fm_get_audio_exts(){return array('wav', 'mp3', 'ogg', 'm4a');}/** * Get text file extensions * @return array */function fm_get_text_exts(){return array('txt', 'css', 'ini', 'conf', 'log', 'htaccess', 'passwd', 'ftpquota', 'sql', 'js', 'ts', 'jsx', 'tsx', 'mjs', 'json', 'sh', 'config','php', 'php4', 'php5', 'phps', 'phtml', 'htm', 'html', 'shtml', 'xhtml', 'xml', 'xsl', 'm3u', 'm3u8', 'pls', 'cue', 'bash', 'vue','eml', 'msg', 'csv', 'bat', 'twig', 'tpl', 'md', 'gitignore', 'less', 'sass', 'scss', 'c', 'cpp', 'cs', 'py', 'go', 'zsh', 'swift','map', 'lock', 'dtd', 'svg', 'asp', 'aspx', 'asx', 'asmx', 'ashx', 'jsp', 'jspx', 'cgi', 'dockerfile', 'ruby', 'yml', 'yaml', 'toml','vhost', 'scpt', 'applescript', 'csx', 'cshtml', 'c++', 'coffee', 'cfm', 'rb', 'graphql', 'mustache', 'jinja', 'http', 'handlebars','java', 'es', 'es6', 'markdown', 'wiki', 'tmp', 'top', 'bot', 'dat', 'bak', 'htpasswd', 'pl');}/** * Get mime types of text files * @return array */function fm_get_text_mimes(){return array('application/xml','application/javascript','application/x-javascript','image/svg+xml','message/rfc822','application/json',);}/** * Get file names of text files w/o extensions * @return array */function fm_get_text_names(){return array('license','readme','authors','contributors','changelog',);}/** * Get online docs viewer supported files extensions * @return array */function fm_get_onlineViewer_exts(){return array('doc', 'docx', 'xls', 'xlsx', 'pdf', 'ppt', 'pptx', 'ai', 'psd', 'dxf', 'xps', 'rar', 'odt', 'ods');}/** * It returns the mime type of a file based on its extension. * @param extension The file extension of the file you want to get the mime type for. * @return string|string[] The mime type of the file. */function fm_get_file_mimes($extension){$fileTypes['swf'] = 'application/x-shockwave-flash';$fileTypes['pdf'] = 'application/pdf';$fileTypes['exe'] = 'application/octet-stream';$fileTypes['zip'] = 'application/zip';$fileTypes['doc'] = 'application/msword';$fileTypes['xls'] = 'application/vnd.ms-excel';$fileTypes['ppt'] = 'application/vnd.ms-powerpoint';$fileTypes['gif'] = 'image/gif';$fileTypes['png'] = 'image/png';$fileTypes['jpeg'] = 'image/jpg';$fileTypes['jpg'] = 'image/jpg';$fileTypes['webp'] = 'image/webp';$fileTypes['avif'] = 'image/avif';$fileTypes['rar'] = 'application/rar';$fileTypes['ra'] = 'audio/x-pn-realaudio';$fileTypes['ram'] = 'audio/x-pn-realaudio';$fileTypes['ogg'] = 'audio/x-pn-realaudio';$fileTypes['wav'] = 'video/x-msvideo';$fileTypes['wmv'] = 'video/x-msvideo';$fileTypes['avi'] = 'video/x-msvideo';$fileTypes['asf'] = 'video/x-msvideo';$fileTypes['divx'] = 'video/x-msvideo';$fileTypes['mp3'] = 'audio/mpeg';$fileTypes['mp4'] = 'audio/mpeg';$fileTypes['mpeg'] = 'video/mpeg';$fileTypes['mpg'] = 'video/mpeg';$fileTypes['mpe'] = 'video/mpeg';$fileTypes['mov'] = 'video/quicktime';$fileTypes['swf'] = 'video/quicktime';$fileTypes['3gp'] = 'video/quicktime';$fileTypes['m4a'] = 'video/quicktime';$fileTypes['aac'] = 'video/quicktime';$fileTypes['m3u'] = 'video/quicktime';$fileTypes['php'] = ['application/x-php'];$fileTypes['html'] = ['text/html'];$fileTypes['txt'] = ['text/plain'];//Unknown mime-types should be 'application/octet-stream'if(empty($fileTypes[$extension])) {$fileTypes[$extension] = ['application/octet-stream'];}return $fileTypes[$extension];}/** * This function scans the files and folder recursively, and return matching files * @param string $dir * @param string $filter * @return array|null */ function scan($dir = '', $filter = '') {$path = FM_ROOT_PATH.'/'.$dir; if($path) { $ite = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); $rii = new RegexIterator($ite, "/(" . $filter . ")/i"); $files = array(); foreach ($rii as $file) { if (!$file->isDir()) { $fileName = $file->getFilename(); $location = str_replace(FM_ROOT_PATH, '', $file->getPath()); $files[] = array( "name" => $fileName, "type" => "file", "path" => $location, ); } } return $files; }}/*** Parameters: downloadFile(File Location, File Name,* max speed, is streaming* If streaming - videos will show as videos, images as images* instead of download prompt* https://stackoverflow.com/a/13821992/1164642*/function fm_download_file($fileLocation, $fileName, $chunkSize= 1024){if (connection_status() != 0)return (false);$extension = pathinfo($fileName, PATHINFO_EXTENSION);$contentType = fm_get_file_mimes($extension);if(is_array($contentType)) {$contentType = implode(' ', $contentType);}$size = filesize($fileLocation);if ($size == 0) {fm_set_msg(lng('Zero byte file! Aborting download'), 'error');$FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH));return (false);}@ini_set('magic_quotes_runtime', 0);$fp = fopen("$fileLocation", "rb");if ($fp === false) {fm_set_msg(lng('Cannot open file! Aborting download'), 'error');$FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH));return (false);}// headersheader('Content-Description: File Transfer');header('Expires: 0');header('Cache-Control: must-revalidate, post-check=0, pre-check=0');header('Pragma: public');header("Content-Transfer-Encoding: binary");header("Content-Type: $contentType");$contentDisposition = 'attachment';if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) {$fileName = preg_replace('/\./', '%2e', $fileName, substr_count($fileName, '.') - 1);header("Content-Disposition: $contentDisposition;filename=\"$fileName\"");} else {header("Content-Disposition: $contentDisposition;filename=\"$fileName\"");}header("Accept-Ranges: bytes");$range = 0;if (isset($_SERVER['HTTP_RANGE'])) {list($a, $range) = explode("=", $_SERVER['HTTP_RANGE']);str_replace($range, "-", $range);$size2 = $size - 1;$new_length = $size - $range;header("HTTP/1.1 206 Partial Content");header("Content-Length: $new_length");header("Content-Range: bytes $range$size2/$size");} else {$size2 = $size - 1;header("Content-Range: bytes 0-$size2/$size");header("Content-Length: " . $size);}$fileLocation = realpath($fileLocation);while (ob_get_level()) ob_end_clean();readfile($fileLocation);fclose($fp);return ((connection_status() == 0) and !connection_aborted());}/** * If the theme is dark, return the text-white and bg-dark classes. * @return string the value of thevariable. */function fm_get_theme() {$result = '';if(FM_THEME == "dark") {$result = "text-white bg-dark";}return $result;}/** * Class to work with zip files (using ZipArchive) */class FM_Zipper{private $zip;public function __construct(){$this->zip = new ZipArchive();}/** * Create archive with name $filename and files $files (RELATIVE PATHS!) * @param string $filename * @param array|string $files * @return bool */public function create($filename, $files){$res = $this->zip->open($filename, ZipArchive::CREATE);if ($res !== true) {return false;}if (is_array($files)) {foreach ($files as $f) {$f = fm_clean_path($f);if (!$this->addFileOrDir($f)) {$this->zip->close();return false;}}$this->zip->close();return true;} else {if ($this->addFileOrDir($files)) {$this->zip->close();return true;}return false;}}/** * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS) * @param string $filename * @param string $path * @return bool */public function unzip($filename, $path){$res = $this->zip->open($filename);if ($res !== true) {return false;}if ($this->zip->extractTo($path)) {$this->zip->close();return true;}return false;}/** * Add file/folder to archive * @param string $filename * @return bool */private function addFileOrDir($filename){if (is_file($filename)) {return $this->zip->addFile($filename);} elseif (is_dir($filename)) {return $this->addDir($filename);}return false;}/** * Add folder recursively * @param string $path * @return bool */private function addDir($path){if (!$this->zip->addEmptyDir($path)) {return false;}$objects = scandir($path);if (is_array($objects)) {foreach ($objects as $file) {if ($file != '.' && $file != '..') {if (is_dir($path . '/' . $file)) {if (!$this->addDir($path . '/' . $file)) {return false;}} elseif (is_file($path . '/' . $file)) {if (!$this->zip->addFile($path . '/' . $file)) {return false;}}}}return true;}return false;}}/** * Class to work with Tar files (using PharData) */class FM_Zipper_Tar{private $tar;public function __construct(){$this->tar = null;}/** * Create archive with name $filename and files $files (RELATIVE PATHS!) * @param string $filename * @param array|string $files * @return bool */public function create($filename, $files){$this->tar = new PharData($filename);if (is_array($files)) {foreach ($files as $f) {$f = fm_clean_path($f);if (!$this->addFileOrDir($f)) {return false;}}return true;} else {if ($this->addFileOrDir($files)) {return true;}return false;}}/** * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS) * @param string $filename * @param string $path * @return bool */public function unzip($filename, $path){$res = $this->tar->open($filename);if ($res !== true) {return false;}if ($this->tar->extractTo($path)) {return true;}return false;}/** * Add file/folder to archive * @param string $filename * @return bool */private function addFileOrDir($filename){if (is_file($filename)) {try {$this->tar->addFile($filename);return true;} catch (Exception $e) {return false;}} elseif (is_dir($filename)) {return $this->addDir($filename);}return false;}/** * Add folder recursively * @param string $path * @return bool */private function addDir($path){$objects = scandir($path);if (is_array($objects)) {foreach ($objects as $file) {if ($file != '.' && $file != '..') {if (is_dir($path . '/' . $file)) {if (!$this->addDir($path . '/' . $file)) {return false;}} elseif (is_file($path . '/' . $file)) {try {$this->tar->addFile($path . '/' . $file);} catch (Exception $e) {return false;}}}}return true;}return false;}}/** * Save Configuration */ class FM_Config{ var $data;function __construct(){global $root_path, $root_url, $CONFIG;$fm_url = $root_url.$_SERVER["PHP_SELF"];$this->data = array('lang' => 'en','error_reporting' => true,'show_hidden' => true);$data = false;if (strlen($CONFIG)) {$data = fm_object_to_array(json_decode($CONFIG));} else {$msg = 'Tiny File Manager [WH1Z-Edition] Error: Cannot load configuration';if (substr($fm_url, -1) == '/') {$fm_url = rtrim($fm_url, '/');$msg .= ' ';$msg .= ' Seems like you have a trailing slash on the URL.';$msg .= ' Try this link: ' . $fm_url . ' ';}die($msg);}if (is_array($data) && count($data)) $this->data = $data;else $this->save();}function save(){$fm_file = __FILE__;$var_name = '$CONFIG';$var_value = var_export(json_encode($this->data), true);$config_string = " ";$sep = '
/ ';if ($path != '') {$exploded = explode('/', $path);$count = count($exploded);$array = array();$parent = '';for ($i = 0; $i < $count; $i++) {$parent = trim($parent . '/' . $exploded[$i], '/');$parent_enc = urlencode($parent);$array[] = "
" . fm_enc(fm_convert_win($exploded[$i])) . " ";}$root_url .= $sep . implode($sep, $array);}echo '
' . $root_url . $editFile . '
';?>
' . $_SESSION[FM_SESSION_ID]['message'] . '
';unset($_SESSION[FM_SESSION_ID]['message']);unset($_SESSION[FM_SESSION_ID]['status']);}}/** * Show page header in Login Form */function fm_show_header_login(){$sprites_ver = '20160315';header("Content-Type: text/html; charset=utf-8");header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");header("Pragma: no-cache");global $lang, $root_url;?> ">
">
.label-new.menu-item > a:after{content:"New";}.label-hot.menu-item > a:after{content:"Hot";}.label-sale.menu-item > a:after{content:"Sale";}.label-popular.menu-item > a:after{content:"Popular";}
Skip to content
The newest nuts symbols commonly another giving, nevertheless they create come in handy by substituting for other icons to your reels. Anything attract more fascinating if a few head features start searching. The foremost is the newest wall bonus game function, and that kicks inside whenever all the symbol to the three times step 3 reel set suits. All of the payline receives a fast 3x multiplier, rather raising the payouts, particularly when the newest highest-spending money icon lands. Conclusion regarding it on line position would be the fact it’s the fresh adventure of a modern-day slot machine if you are dealing with to maintain you to definitely vintage Las vegas search one pulls participants of all of the kind.
Our very own Favorite Casinos
To automate the method a little more, find the autospin games function and the reels usually spin on the their own freely, position your choice immediately. Once we care for the issue, here are some this type of similar online game you could enjoy. Fruits icons may give of 10 in order to 31 profits, a good bell – 40, big 7 and you will a celebrity – 80, a sunshine – 400 and you may a vintage money – 800. It must be said, there try a classic type of that it slot, however, this time around Wazdan made a decision to eliminate the games, including new features. The new creators utilized an easy structure which have greatest image, evaluating the previous kind of that it position. Talking about image and you will structure, Fenix Play is very healthy with regards to colours, molds and you can animated graphics.
Fenix Gamble 27 Totally free • Gambling establishment Harbors • Wazdan
To provide one uncommon evaluate between old and you may the brand new, Wazdan have made the fresh reels, and you can vintage signs, stick out if you can. According to the amount of people looking for they, Fenix Gamble 27 is not a hugely popular position. You can learn much more about slot machines and just how it works within online slots games guide. Fenix gamble try an immersive antique slot with a few recent video clips slot that have vibes.
As often representative responses precisely, because the bigger the brand new earn might possibly be. People, regardless of how have a glance at this web link knowledgeable he could be, should never head to the new not familiar and you may explore a real income in the a-game they never ever starred before. It’s our very own fulfillment to create you which name and many more for free use 777spinslot.
We all know, the brand new fiery bird is considered a strange creature – it’s immortal, get rise on the discomfort. Phoenix will assist you to earn honors and you will secure normally a real income as you possibly can. Don’t spend time and be because the bird – increase each and every time, when you get rid of, continue your own online game right up until a huge winnings have been in their hand. Totally free top-notch academic programs to own internet casino group geared towards world recommendations, boosting user experience, and you may fair way of betting. Whatsoever, it’s the a question of Arbitrary Amount Generator and just for example a boiling hot container when watched, a position does not spend a lot more for many who continue lingering desire. Then listed below are some all of our over book, in which i as well as score an educated betting internet sites to own 2025.
Slotsspot.com will be your go-to support to possess what you online gambling. Of in the-breadth recommendations and you can helpful information for the most recent information, we’re also right here to help you find the best networks to make informed decisions each step of your own means. You will find multiplier and enjoy characteristics, and therefore boost your stake.
Fenix Play 27 Position Review & 100 percent free Trial Enjoy
A position with plenty of adventure and you may action, a spin for the Fenix Play 27 Deluxe is highly impractical so you can let you down perhaps the really educated professionals. The fresh slot keeps massive attract both retro players, and those that search by far the most exciting games features around. On the theme getting very well make, you will find little not to ever take pleasure in that have Fenix Play 27 Deluxe. For those who have manged to get to the top the fresh mountain successfully, then you are happy to deal with the brand new fun game has in the the newest free Fenix Play 27 Luxury position.
Ready to possess VSO Coins?
Now let’s find in our very own second section what exactly is the brand new here in regards to gameplay. The backdrop out of Fenix Gamble 27 ends up a blue air with some fluffy clouds and departs floating regarding the snap. The brand new reels are quite classic, having an excellent phoenix perched on the top of your own monitor. If you use particular advertising clogging software, delight consider the setup. Speak about some thing linked to Fenix Gamble 27 along with other professionals, display their advice, otherwise score solutions to the questions you have. Certain organization could possibly get processes your research according to legitimate attention.
Whilst the identity enables you to consider the legendary bird one goes up from the own ashes, this unique on the web position doesn’t need perish in order to be reborn and you may effective. Whatever the device you’lso are to play out of, you may enjoy all of your favorite slots to the mobile. That it symbol is obviously the new phoenix, it immortal bird which are reborn from its ashes.
The brand new gamble ability try a risky but satisfying addition, but like most parts of Fenix Play 27 Luxury, this is simply not as you would expect. Usually while using the enjoy element, participants would need to pick the along with otherwise fit away from an excellent credit, however, right here they find ranging from a couple of phoenix eggs. Hatching a phoenix from the egg often double the win, however, getting some cigarette have a tendency to catapult players back into the main screen. Concurrently, the video game has been somewhat minimal in just 3 reels and you can repaired paylines that do not allow it to be any type of adjustment. The brand new crazy phoenix symbols obviously probably the most intriguing and fulfilling symbol of your own whole games, so sit aware and don’t give it time to fly away undetected. Fenix Enjoy 27 is in fact an enthusiastic ameliorated form of Fenix Gamble.