'; if (is_array($t) || is_object($t)){ echo '
';
        print_r($t);
        echo '
'; }else echo $t; } } /** * Detect server protocol * * @return string 'https://' || 'http://' */ function getServerProtocol() { return (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? 'https://' : 'http://'; } /** * Build order array from string 'col1,A|col2,d' for function arfosort * * @param string $order Orderstring * * @return array */ function get_orderarray($order) { $order_arr = array(); $orders = explode('|', $order); foreach ($orders as $o){ $d = explode(',', $o); if (isset($d[0]) && isset($d[1])) $order_arr[] = array($d[0], $d[1]); } return $order_arr; } /** * Order multidimensial array * * @param array $a Array to sort * @param string $fl Order-string to define what keys should be sortet in what direction * * @return array Sorted array */ function arfsort($a, $fl) { $GLOBALS['__ARFSORT_LIST__'] = $fl; usort($a, 'arfsort_func'); return $a; } /** * Sort a multidimenional array no matter in which depth the key is * * @param array $a Array to sort * @param string $b Sortstring containing keys and kind of sorting * * @return mixed */ function arfsort_func($a, $b) { foreach ($GLOBALS['__ARFSORT_LIST__'] as $f){ if (isset($b[$f[0]]) && isset($a[$f[0]])){ switch ($f[1]){ // switch on ascending or descending value case 'd': $strc = strcmp(strtolower($b[$f[0]]), strtolower($a[$f[0]])); if ($strc != 0) return $strc; break; case 'a': $strc = strcmp(strtolower($a[$f[0]]), strtolower($b[$f[0]])); if ($strc != 0) return $strc; break; case 'D': $strc = (floatval($b[$f[0]]) < floatval($a[$f[0]])) ? -1 : 1; if ($b[$f[0]] != $a[$f[0]]) return $strc; break; case 'A': $strc = (floatval($b[$f[0]]) > floatval($a[$f[0]])) ? -1 : 1; if ($b[$f[0]] != $a[$f[0]]) return $strc; break; } } } return 0; } /** * Read table information about nr of records and more for given database name. * Return array with advsanced information. * * @param string $db The database name to read info from * @param string $table If set, only information for this table is filled * * @return array */ function getTableInfo($db, $table = '') { global $dbo, $config; $tableInfos=array(); $res = $dbo->selectDb($db); if ($res){ $query = 'SHOW TABLE STATUS FROM `' . $db . '`'; if ($table > '') { $query .= ' LIKE \'' . $table . '\''; } $res = $dbo->query($query, MsdDbFactory::ARRAY_ASSOC); // init index if not set if (!isset($tableInfos[$db])) $tableInfos[$db] = array(); if (!isset($tableInfos[$db]['tables'])) $tableInfos[$db]['tables'] = array(); $tableInfos[$db]['table_count'] = sizeof($res); $tableInfos[$db]['records_total'] = 0; $tableInfos[$db]['datasize_total'] = 0; $tableInfos[$db]['size_total'] = 0; if ($tableInfos[$db]['table_count'] > 0){ for ($i = 0, $max = $tableInfos[$db]['table_count']; $i < $max; $i++){ $row = $res[$i]; $n = $row['Name']; if (!isset($tableInfos[$db]['tables'][$n])) $tableInfos[$db]['tables'][$row['Name']] = array(); if (isset($row['Type'])) $row['Engine'] = $row['Type']; $tableInfos[$db]['tables'][$n]['name'] = $row['Name']; $tableInfos[$db]['tables'][$n]['engine'] = $row['Engine']; $tableInfos[$db]['tables'][$n]['dump_structure'] = 1; $tableInfos[$db]['tables'][$n]['dump_records'] = 1; // if we have a VIEW or a table of Type MEMORY -> don't save records if (strtoupper($row['Comment']) == 'VIEW' || (isset($row['Engine']) && in_array(strtoupper($row['Engine']), array( 'MEMORY')))){ $tableInfos[$db]['tables'][$n]['dump_records'] = 0; } if (!isset($row['Update_time'])) $row['Update_time'] = ''; $tableInfos[$db]['tables'][$n]['update_time'] = $row['Update_time']; $tableInfos[$db]['tables'][$n]['data_free'] = isset($row['Data_free']) ? $row['Data_free'] : 0; $tableInfos[$db]['tables'][$n]['collation'] = isset($row['Collation']) ? $row['Collation'] : ''; $tableInfos[$db]['tables'][$n]['comment'] = isset($row['Comment']) ? $row['Comment'] : ''; $tableInfos[$db]['tables'][$n]['auto_increment'] = isset($row['Auto_increment']) ? $row['Auto_increment'] : ''; $tableInfos[$db]['tables'][$n]['records'] = (int) $row['Rows']; $tableInfos[$db]['tables'][$n]['data_length'] = (float) $row['Data_length']; $tableInfos[$db]['tables'][$n]['index_length'] = $row['Index_length']; $tableInfos[$db]['records_total'] += (int) $row['Rows']; $tableInfos[$db]['datasize_total'] += (float) $row['Data_length']; $tableInfos[$db]['size_total'] += (float) $row['Data_length'] + (float) $row['Index_length']; } } } return $tableInfos; } /** * Returns microtime of now as float value * * @return float microtime */ function getMicrotime() { list ($usec, $sec) = explode(' ', microtime()); return ((float) $usec + (float) $sec); } /** * Detect free diskspace * * @return string Space in human readable Bytes or message if not available */ function getFreeDiskSpace() { global $lang; $dfs = @diskfreespace("../"); return ($dfs) ? byteOutput($dfs) : $lang['L_NOTAVAIL']; } /** * Extract timestamp informations from a filename and return formatted string YYYY.MM.DD HH:MM * * @param string $s Filename as input 'dbname_2009_10_18_16_22_part1_sql-gz' * * @return string Formated timestamp YYYY.MM.DD HH:MM */ function getTimestampFromFilename($s) { $i = strpos(strtolower($s), 'part'); if ($i > 0) $s = substr($s, 0, $i - 1); $i = strpos(strtolower($s), 'crondump'); if ($i > 0) $s = substr($s, 0, $i - 1); $i = strpos(strtolower($s), '.sql'); if ($i > 0) $s = substr($s, 0, $i); $sp = explode('_', $s); $anz = count($sp) - 1; if (strtolower($sp[$anz]) == 'perl') $anz--; if ($anz > 4){ return $sp[$anz - 2] . '.' . $sp[$anz - 3] . '.' . $sp[$anz - 4] . ' ' . $sp[$anz - 1] . ':' . $sp[$anz]; }else{ //no MySQLDumper file return ''; } } /** * Writes errors or notices to the corresponding error log * * @param string $db Affected database * @param string $sql The executed query * @param string $error The error message to log * @param int $art The kind of error (0=error, 1=notice) * * @return void */ function writeToErrorLog($db = '', $sql = '', $error = '', $art = 1) { global $config, $lang, $log; $sql = str_replace("\r", '', $sql); $sql = str_replace("\n\n", '
', $sql); $sql = str_replace("\n", '
', $sql); $sql = trim($sql); $error = str_replace("\r", '', $error); if ($art == 0) { $errormsg = $lang['L_ERROR'] . ': ' . $error; } else { $errormsg = $lang['L_NOTICE'] . ': ' . $error; } // append query if set if ($sql > '') { $errormsg .= '
SQL: ' . $sql; } $time = date('d.m.Y H:i:s') . ' '; if ($art == 0) { $_SESSION['log']['errors'][] = $time.$errormsg; } else { $_SESSION['log']['notices'][] = $time.$errormsg; } $log->write(Log::ERROR, $errormsg); } /** * Checks if the directories work, config, backup and log are writable * Returns concatenated string with warnings or empty string if every directory is writable * * @return string */ function checkDirectories() { global $config, $lang; $warn = ''; if (!is_writable($config['paths']['work'])) $warn .= sprintf($lang['L_WRONG_RIGHTS'], $config['paths']['work'], '0777'); if (!is_writable($config['paths']['config'])) $warn .= sprintf($lang['L_WRONG_RIGHTS'], $config['paths']['config'], '0777'); if (!is_writable($config['paths']['backup'])) $warn .= sprintf($lang['L_WRONG_RIGHTS'], $config['paths']['backup'], '0777'); if (!is_writable($config['paths']['log'])) $warn .= sprintf($lang['L_WRONG_RIGHTS'], $config['paths']['log'], '0777'); if ($warn != '') $warn = '' . $warn . ''; return $warn; } /** * Deletes every table or view in a database * * @param string $dbn Databasename * * @return void */ function truncateDb($dbn) { global $dbo; $t_sql = array(); $dbo->query('SET FOREIGN_KEY_CHECKS=0', MsdDbFactory::SIMPLE); $res = $dbo->query('SHOW TABLE STATUS FROM `' . $dbn . '`', MsdDbFactory::ARRAY_ASSOC); foreach ($res as $row){ if (substr(strtoupper($row['Comment']), 0, 4) == 'VIEW'){ $t_sql[] = 'DROP VIEW `' . $dbn . '``' . $row['Name'] . '`'; }else{ $t_sql[] = 'DROP TABLE `' . $dbn . '`.`' . $row['Name'] . '`'; } } if (sizeof($t_sql) > 0){ for ($i = 0; $i < count($t_sql); $i++){ try{ $dbo->query($t_sql[$i]); }catch (Excption $e){ //TODO create clean error handling depending on context writeToErrorLog($e->getMessage()); die($e->getMessage()); } } } $dbo->query('SET FOREIGN_KEY_CHECKS=1', MsdDbFactory::SIMPLE); } /** * Delete old backups from folder work/backup according to configuration * * @return string Outputstring with messages about deleted files */ function doAutoDelete() { global $config, $lang, $out; $out = ''; if ($config['auto_delete']['max_backup_files'] > 0){ //Files einlesen $dh = opendir($config['paths']['backup']); $files = array(); // Build assoc Array $db=>$timestamp=>$filenames if (!function_exists('ReadStatusline')) include ('./inc/functions/functions_files.php'); while (false !== ($filename = readdir($dh))){ if ($filename != '.' && $filename != '..' && !is_dir($config['paths']['backup'] . $filename)){ $statusline = readStatusline($filename); if ($statusline['dbname'] != 'unknown'){ $dbName = $statusline['dbname']; $datum = substr($filename, strlen($dbName) + 1); $timestamp = substr($datum, 0, 16); if (!isset($files[$dbName])) $files[$dbName] = array(); if (!isset($files[$dbName][$timestamp])) $files[$dbName][$timestamp] = array(); $files[$dbName][$timestamp][] = $filename; } } } $out = ''; // stores output messages // Backups per DB and Timestamp foreach ($files as $db => $val){ if (sizeof($val) > $config['auto_delete']['max_backup_files']){ $db_files = $val; krsort($db_files, SORT_STRING); //now latest backupfiles are on top -> delete all files with greater index $i = 0; foreach ($db_files as $timestamp => $filenames){ if ($i >= $config['auto_delete']['max_backup_files']){ // Backup too old -> delete files foreach ($filenames as $f){ if ($out == '') $out .= $lang['L_FM_AUTODEL1'] . '
'; if (@unlink('./' . $config['paths']['backup'] . $f)){ $out .= '' . sprintf($lang['L_DELETE_FILE_SUCCESS'], $f) . '
'; }else{ $out .= $lang['L_ERROR'] . ':

' . sprintf($lang['L_DELETE_FILE_ERROR'], $f) . '


'; } } } $i++; } } } } return $out; } /** * Analyzes the first line of a MSD-Backup. Expects it as string parameter. * * @param string $line The statusline from the backup to analyze * * @return array Extracted information as array */ function readStatusline($filename) { global $config; /*AUFBAU der Statuszeile: -- Status:nr of tables:records:Multipart:Databasename:script:scriptversion:Comment: MySQL-Version:flags (unused):SQLCommandBeforeBackup:SQLCommandAfterBackup:Charset:EXTINFO */ $gz = substr($filename, -3) == '.gz' ? true : false; $fh = $gz ? gzopen($config['paths']['backup'] . $filename, 'r') : fopen($config['paths']['backup'] . $filename, 'r'); if (!$fh){ v(debug_backtrace()); die(); } $line = $gz ? gzgets($fh) : fgets($fh); $gz ? gzclose($fh) : fclose($fh); $statusline = array(); $line = removeBom($line); if ((substr($line, 0, 8) != "# Status" && substr($line, 0, 9) != "-- Status") || substr($line, 0, 10) == '-- StatusC'){ //Fremdfile $statusline['tables'] = -1; $statusline['records'] = -1; $statusline['part'] = 'MP_0'; $statusline['dbname'] = 'unknown'; $statusline['script'] = ''; $statusline['scriptversion'] = ''; $statusline['comment'] = ''; $statusline['mysqlversion'] = 'unknown'; $statusline['flags'] = '2222222'; $statusline['sqlbefore'] = ''; $statusline['sqlafter'] = ''; $statusline['charset'] = '?'; }else{ // MySQLDumper-File - Informationen extrahieren $s = explode(':', $line); if (count($s) < 12){ //fehlenden Elemente auffüllen $c = count($s); array_pop($s); for ($i = $c - 1; $i < 12; $i++){ $s[] = ''; } } $statusline['tables'] = $s[1]; $statusline['records'] = $s[2]; $statusline['part'] = ($s[3] == '' || $s[3] == 'MP_0') ? 'MP_0' : $s[3]; $statusline['dbname'] = $s[4]; $statusline['script'] = $s[5]; $statusline['scriptversion'] = $s[6]; $statusline['comment'] = $s[7]; $statusline['mysqlversion'] = $s[8]; if ((isset($s[12])) && trim($s[12]) != 'EXTINFO'){ $statusline['charset'] = $s[12]; }else{ $statusline['charset'] = '?'; } } return $statusline; } /** * Reads Head-Information about tables from MSD-Backup and returns it as array * * @param string $filename Filename of MSD-Backup to analyze * * @return array Detailed information about tables n MSD-Backup */ function getTableHeaderInfoFromBackup($filename) { global $config; // Get Tableinfo from file header $tabledata = array(); $i = 0; $gz = substr($filename, -3) == '.gz' ? true : false; $fh = $gz ? gzopen($config['paths']['backup'] . $filename, 'r') : fopen($config['paths']['backup'] . $filename, 'r'); $eof = false; WHILE (!$eof){ $line = $gz ? gzgets($fh, 40960) : fgets($fh, 40960); $line = trim($line); if (substr($line, 0, 9) == '-- TABLE|'){ $d = explode('|', $line); $tabledata[$i]['name'] = $d[1]; $tabledata[$i]['records'] = $d[2]; $tabledata[$i]['size'] = $d[3]; $tabledata[$i]['update'] = $d[4]; $tabledata[$i]['engine'] = isset($d[5]) ? $d[5] : ''; $i++; }elseif (substr($line, 0, 6) == '-- EOF') $eof = true; // End of Table-Info - >done elseif (substr(strtolower($line), 0, 6) == 'create') $eof = true; // we have found the first CREATE-Query -> done } $gz ? gzclose($fh) : fclose($fh); return $tabledata; } /** * Calculate next Multipart-Filename * * @param string $filename The filename to calculate the next name from * * @return string Filename of next Multipart-File */ function getNextPart($filename) { $nf = explode('_', $filename); $i = array_search('part', $nf) + 1; $part = substr($nf[$i], 0, strpos($nf[$i], '.')); $ext = substr($nf[$i], strlen($part)); $nf[$i] = ++$part . $ext; $filename = implode('_', $nf); return $filename; } /** * Formats seconds to human readable output * * @param integer $time Time in seconds * * @return string Time as human readable formatted string */ function getTimeFormat($time) { global $lang; $d = floor($time / 86400); $h = floor(($time - $d * 86400) / 3600); $m = floor(($time - $d * 86400 - $h * 3600) / 60); $s = $time - $d * 86400 - $h * 3600 - $m * 60; $ret = sprintf('%02d', $s) . ' ' . ($s == 1 ? $lang['L_SECOND'] : $lang['L_SECONDS']); if ($m > 0){ $ret = $m . ' ' . ($m == 1 ? $lang['L_MINUTE'] : $lang['L_MINUTES']) . ' ' . $ret; } if ($h > 0){ $ret = $h . ' ' . ($h == 1 ? $lang['L_HOUR'] : $lang['L_HOURS']) . ' ' . $ret; } if ($d > 0){ $ret = $d . ' ' . ($d == 1 ? $lang['L_DAY'] : $lang['L_DAYS']) . ' ' . $ret; } return $ret; } /** * Tests a ftp-connection and returns messages about uccess or failure * * @param integer $i The index of the connection profile to test * * @return array Array with messages */ function testFTP($i) { global $lang, $config; if (!isset($config['ftp'][$i]['timeout'])) $config['ftp'][$i]['timeout'][$i] = 30; $ret = array(); if ($config['ftp'][$i]['port'] == '' || $config['ftp'][$i]['port'][$i] == 0) $config['ftp'][$i]['port'] = 21; $pass = -1; if (!extension_loaded("ftp")){ $ret[] = '' . $lang['L_NOFTPPOSSIBLE'] . ''; }else $pass = 0; if ($pass == 0){ if ($config['ftp'][$i]['server'] == '' || $config['ftp'][$i]['user'] == ''){ $ret[] = '' . $lang['L_WRONGCONNECTIONPARS'] . ''; }else $pass = 1; } if ($pass == 1){ if ($config['ftp'][$i]['ssl'] == 0) $conn_id = @ftp_connect($config['ftp'][$i]['server'], $config['ftp'][$i]['port'], $config['ftp'][$i]['timeout']); else $conn_id = @ftp_ssl_connect($config['ftp'][$i]['server'], $config['ftp'][$i]['port'], $config['ftp'][$i]['timeout']); if (is_resource($conn_id)){ $ret[] = sprintf($lang['L_FTP_CONNECTION_SUCCESS'], $config['ftp'][$i]['server'], $config['ftp'][$i]['port']); }else $ret[] = sprintf($lang['L_FTP_CONNECTION_ERROR'], $config['ftp'][$i]['server'], $config['ftp'][$i]['port']); if ($conn_id){ $login_result = @ftp_login($conn_id, $config['ftp'][$i]['user'], $config['ftp'][$i]['pass']); if ($login_result) $ret[] = sprintf($lang['L_FTP_LOGIN_SUCCESS'], $config['ftp'][$i]['user']); else $ret[] = sprintf($lang['L_FTP_LOGIN_ERROR'], $config['ftp'][$i]['user']); } if ($conn_id && $login_result){ $pass = 2; if ($config['ftp'][$i]['mode'] == 1){ if (ftp_pasv($conn_id, true)) $ret[] = $lang['L_FTP_PASV_SUCCESS']; else $ret[] = $lang['L_FTP_PASV_ERROR']; } } } if ($pass == 2){ $dirc = @ftp_chdir($conn_id, $config['ftp'][$i]['dir']); if (!$dirc){ $ret[] = $lang['L_CHANGEDIR'] . ' \'' . $config['ftp'][$i]['dir'] . '\' -> ' . $lang['L_CHANGEDIRERROR'] . ''; }else{ $pass = 3; $ret[] = $lang['L_CHANGEDIR'] . ' \'' . $config['ftp'][$i]['dir'] . '\' -> ' . $lang['L_OK'] . ''; } @ftp_close($conn_id); } if ($pass == 3) $ret[] = '' . $lang['L_FTP_OK'] . ''; return implode('
', $ret); } /** * Returns list of configuration profiles as HTML-Optionlist * * @param string $selected_config The actual configuration to pre-select in option list * * @return string HTML-option-string */ function getConfigFilelist($selected_config) { $configs = getConfigFilenames(); $options = Html::getOptionlist($configs, $selected_config); return $options; } /** * Returns list of installed themes as HTML-Optionlist * * @return string HTML-option-string */ function getThemes() { global $config; $themes = array(); $dh = opendir($config['paths']['root'] . "css/"); while (false !== ($filename = readdir($dh))){ if ($filename != '.' && $filename != '..' && is_dir($config['paths']['root'] . 'css/' . $filename) && substr($filename, 0, 1) != '.' && substr($filename, 0, 1) != '_'){ $themes[$filename] = $filename; } } @ksort($themes); $options = Html::getOptionlist($themes, $config['theme']); return $options; } /** * Detects all language-directories and builds HTML-Optionlist * * @return string HTML-option-string */ function getLanguageCombo() { global $config, $lang; $default = $config['language']; $dh = opendir('./language/'); $r = ""; $lang_files = array(); while (false !== ($filename = readdir($dh))){ if ($filename != '.' && $filename != '.svn' && $filename != '..' && $filename != 'flags' && is_dir('./language/' . $filename)){ if (isset($lang[$filename])) $lang_files[$lang[$filename]] = $filename; } } @ksort($lang_files); foreach ($lang_files as $filename){ $style = 'background:url(language/flags/width25/' . $filename . '.gif) 4px;background-repeat:no-repeat;padding:2px 6px 2px 36px !important;'; $r .= '