function getTableList()
{
    global $TABLE_PREFIX, $APP;
    // get table names
    $mysqlTables = getMysqlTablesWithPrefix();
    $schemaTables = getSchemaTables();
    // create multi query
    $tables = array();
    $tableRowCounts = array();
    foreach ($schemaTables as $tableName) {
        $tableNameWithPrefix = getTableNameWithPrefix($tableName);
        if (in_array($tableNameWithPrefix, $mysqlTables)) {
            $rowCount = mysql_count($tableNameWithPrefix);
        }
        $localTableSchema = loadSchema($tableName);
        array_push($tables, array('tableName' => $tableName, 'menuName' => @$localTableSchema['menuName'], 'menuType' => @$localTableSchema['menuType'], 'menuOrder' => @$localTableSchema['menuOrder'], 'menuHidden' => @$localTableSchema['menuHidden'], 'tableHidden' => @$localTableSchema['tableHidden'], '_indent' => @$localTableSchema['_indent'], 'recordCount' => $rowCount));
    }
    // sort table list
    uasort($tables, '_sortMenusByOrder');
    //
    return $tables;
}
function backupDatabase($filenameOrPath = '', $selectedTable = '')
{
    global $TABLE_PREFIX;
    $prefixPlaceholder = '#TABLE_PREFIX#_';
    set_time_limit(60 * 5);
    // v2.51 - allow up to 5 minutes to backup/restore database
    session_write_close();
    // v2.51 - End the current session and store session data so locked session data doesn't prevent concurrent access to CMS by user while backup in progress
    // error checking
    if ($selectedTable != '') {
        $schemaTables = getSchemaTables();
        if (preg_match("/[^\\w\\d\\-\\.]/", $selectedTable)) {
            die(__FUNCTION__ . " : \$selectedTable contains invalid chars! " . htmlencode($selectedTable));
        }
        if (!in_array($selectedTable, $schemaTables)) {
            die("Unknown table selected '" . htmlencode($selectedTable) . "'!");
        }
    }
    // open backup file
    $hostname = preg_replace('/[^\\w\\d\\-\\.]/', '', @$_SERVER['HTTP_HOST']);
    if (!$filenameOrPath) {
        $filenameOrPath = "{$hostname}-v{$GLOBALS['APP']['version']}-" . date('Ymd-His');
        if ($selectedTable) {
            $filenameOrPath .= "-{$selectedTable}";
        }
        $filenameOrPath .= ".sql.php";
    }
    $outputFilepath = isAbsPath($filenameOrPath) ? $filenameOrPath : DATA_DIR . "/backups/{$filenameOrPath}";
    // v2.60 if only filename provided, use /data/backup/ as the basedir
    $fp = @fopen($outputFilepath, 'x');
    if (!$fp) {
        // file already exists - avoid race condition
        session_start();
        return false;
    }
    // create no execute php header
    fwrite($fp, "-- <?php die('This is not a program file.'); exit; ?>\n\n");
    # prevent file from being executed
    // get tablenames to backup
    if ($selectedTable) {
        $tablenames = array(getTableNameWithPrefix($selectedTable));
    } else {
        $skippedTables = array('_cron_log', '_error_log', '_outgoing_mail', '_nlb_log');
        // don't backup these table names
        $skippedTables = applyFilters('backupDatabase_skippedTables', $skippedTables);
        // let users skip tables via plugins
        $skippedTables = array_map('getTableNameWithPrefix', $skippedTables);
        // add table_prefix to all table names (if needed)
        $allTables = getMysqlTablesWithPrefix();
        $tablenames = array_diff($allTables, $skippedTables);
        // remove skipped tables from list
    }
    // backup database
    foreach ($tablenames as $unescapedTablename) {
        $escapedTablename = mysql_escape($unescapedTablename);
        $tablenameWithFakePrefix = $prefixPlaceholder . getTableNameWithoutPrefix($escapedTablename);
        // create table
        fwrite($fp, "\n--\n");
        fwrite($fp, "-- Table structure for table `{$tablenameWithFakePrefix}`\n");
        fwrite($fp, "--\n\n");
        fwrite($fp, "DROP TABLE IF EXISTS `{$tablenameWithFakePrefix}`;\n\n");
        $result = mysql_query("SHOW CREATE TABLE `{$escapedTablename}`");
        list(, $createStatement) = mysql_fetch_row($result) or die("MySQL Error: " . htmlencode(mysql_error()));
        $createStatement = str_replace("TABLE `{$TABLE_PREFIX}", "TABLE `{$prefixPlaceholder}", $createStatement);
        fwrite($fp, "{$createStatement};\n\n");
        if (is_resource($result)) {
            mysql_free_result($result);
        }
        // create rows
        fwrite($fp, "\n--\n");
        fwrite($fp, "-- Dumping data for table `{$tablenameWithFakePrefix}`\n");
        fwrite($fp, "--\n\n");
        $result = mysql_query("SELECT * FROM `{$escapedTablename}`") or die("MySQL Error: " . htmlencode(mysql_error()));
        while ($row = mysql_fetch_row($result)) {
            $values = '';
            foreach ($row as $value) {
                if (is_null($value)) {
                    $values .= 'NULL,';
                } else {
                    $values .= '"' . mysql_real_escape_string($value) . '",';
                }
            }
            $values = chop($values, ',');
            // remove trailing comma
            fwrite($fp, "INSERT INTO `{$tablenameWithFakePrefix}` VALUES({$values});\n");
        }
        if (is_resource($result)) {
            mysql_free_result($result);
        }
    }
    //
    fwrite($fp, "\n");
    $result = fwrite($fp, "-- Dump completed on " . date('Y-m-d H:i:s O') . "\n\n");
    if ($result === false) {
        die(__FUNCTION__ . ": Error writing backup file! {$php_errormsg}");
    }
    fclose($fp) || die(__FUNCTION__ . ": Error closing backup file! {$php_errormsg}");
    //
    @session_start();
    // hide error: E_WARNING: session_start(): Cannot send session cache limiter - headers already sent
    return $outputFilepath;
}