$backups = array();
    $handle = opendir($backup_dir);
    while (false !== ($item = readdir($handle))) {
        if ($item === '.' || $item === '..' || !is_file($backup_dir . $item)) {
            continue;
        }
        $backups[] = $item;
    }
    // serazeni a vypis
    if (!empty($backups)) {
        natsort($backups);
        $output .= "<table class='list'>\n<thead><tr><td>" . $_lang['admin.other.backup.restore.item'] . "</td><td>" . $_lang['global.type'] . "</td><td>" . $_lang['global.time'] . "</td><td>" . $_lang['global.note'] . "</td><td>" . $_lang['global.size'] . "</td><td>" . $_lang['global.extra'] . "</td></tr></thead>\n<tbody>\n";
        foreach ($backups as $file) {
            // info o archivu
            $file_err = false;
            $file_vars = _backupCheckFile($backup_dir . $file, array(_backup_db, _backup_partial), true);
            if (!is_array($file_vars)) {
                $file_err = true;
            }
            $file_h = _htmlStr($file);
            // polozka
            $output .= "<tr>\n<td><label><input type='radio' name='fname' value='" . $file_h . "'" . ($file_err ? " disabled='disabled'" : '') . " /> " . $file_h . "</label></td>\n<td>" . ($file_err ? '-' : $_lang['admin.other.backup.backup.' . ($file_vars['type'] === _backup_db ? 'db' : 'partial')]) . "</td>\n<td>" . ($file_err ? '-' : _formatTime($file_vars['time'])) . "</td>\n<td>" . ($file_err ? "<img src='images/icons/warn.png' alt='err' /> " . $_lang['global.error'] : (empty($file_vars['note']) ? '-' : _htmlStr(_cutStr($file_vars['note'], 48, false)))) . "</td>\n<td>" . number_format(filesize($backup_dir . $file) / 1024, 0, '.', ' ') . "kB</td>\n<td><a href='" . $backup_dir . $file_h . "'>" . $_lang['global.download'] . "</a></td>\n</tr>\n";
        }
        $output .= "</tbody></table><br />\n\n<p><strong>" . $_lang['global.action'] . ":</strong> &nbsp;\n<select name='sub_action'>\n    <option value='-1'>...</option>\n    <option value='1'>" . $_lang['admin.other.backup.restore.do'] . "</option>\n    <option value='2'>" . $_lang['global.delete'] . "</option>\n</select> &nbsp;\n<input type='submit' value='" . $_lang['global.do'] . "' onclick='return _sysConfirm();' />&nbsp;\n<a href='index.php?p=fman&amp;dir=" . urlencode('../data/backup/') . "'><img src='images/icons/list.png' class='icon' alt='fman' />" . $_lang['admin.other.backup.restore.fman'] . "</a>\n</p>\n\n" . _admin_smallNote($_lang['admin.other.backup.restore.warning'], true, 'warn');
    } else {
        $output .= '<p>' . $_lang['admin.other.backup.restore.none'] . '</p>';
    }
    $output .= "\n</fieldset>\n" . _xsrfProtect() . "</form>\n";
} else {
    /* ----- volba akce ----- */
    $output .= (_loginright_adminbackup ? "\n<fieldset>\n<legend>" . $_lang['admin.other.backup.backup'] . "</legend>\n<form action='index.php?p=other-backup' method='post'>\n<p>" . $_lang['admin.other.backup.backup.p'] . "</p>\n\n<input type='hidden' name='do_backup' value='1' />\n<p><input type='submit' value='" . $_lang['admin.other.backup.backup.db'] . "' name='type_db' />&nbsp; <small class='note'>(" . $_lang['admin.other.backup.backup.db.hint'] . ")</small></p>\n<p><input type='submit' value='" . $_lang['admin.other.backup.backup.partial'] . "' name='type_partial' />&nbsp; <small class='note'>(" . $_lang['admin.other.backup.backup.partial.hint'] . ")</small></p>\n<p><input type='submit' value='" . $_lang['admin.other.backup.backup.full'] . "' name='type_full' />&nbsp; <small class='note'>(" . $_lang['admin.other.backup.backup.full.hint'] . ")</small></p>\n\n" . _xsrfProtect() . "</form>\n</fieldset>" : '') . (_loginright_adminrestore ? "\n\n<fieldset>\n<legend>" . $_lang['admin.other.backup.restore'] . "</legend>\n<form class='cform' method='post'>\n<p>" . $_lang['admin.other.backup.restore.p'] . "</p>\n<p><input type='submit' name='do_restore' value='" . $_lang['global.continue'] . "' /></p>\n" . _xsrfProtect() . "</form>\n</fieldset>\n" : '');
/**
 * [ADMIN] Backup API - obnovit zalohu (castecnou nebo jen databaze)
 * @param string $path cesta k souboru
 * @return array|bool true pri uspechu, jinak array(err_msg, fatal 1/0)
 */
function _backupRestore($path)
{
    // priprava
    global $_lang;
    $fatal = false;
    $path = realpath($path);
    // proces obnovy
    do {
        /* ----- nacteni a kontroly ----- */
        // kontrola souboru
        if (($err = _backupCheckFile($path, array(_backup_db, _backup_partial))) !== true) {
            break;
        }
        // nacteni souboru
        $kzip = new KZip($path);
        if (!empty($kzip->error)) {
            $err = str_replace('*errstr*', _htmlStr($kzip->error), $_lang['admin.other.backup.restore.upload.err.load']);
            break;
        }
        $type = $kzip->vars['type'];
        // uprava merge pole
        if (isset($kzip->vars['merge'])) {
            $kzip->vars['merge'] = array_flip($kzip->vars['merge']);
        }
        // kontrola prava pro zapis
        if ($type === _backup_partial) {
            $a_files = '/files/';
            $dirs = $kzip->listFiles($a_files, true);
            $dirs = $dirs[0];
            for ($i = 0; isset($dirs[$i]); ++$i) {
                if (($err = _emptyDir(realpath(dirname($_SERVER['SCRIPT_FILENAME']) . '/' . _indexroot . $dirs[$i]) . '/')) !== true) {
                    $err = str_replace('*path*', _htmlStr($err), $_lang['admin.other.backup.restore.err.access']);
                    break 2;
                }
            }
        }
        /* ----- provedeni ----- */
        // chyby na teto urovni jsou j*z fatalni
        $fatal = true;
        // databaze
        $dbdump = new DBDump();
        // tabulky
        $tbl_import = $dbdump->importTables($kzip->getFile('/database/struct'));
        if (!$tbl_import[0]) {
            $err = $tbl_import[1] . ': <code>' . _htmlStr($tbl_import[2]) . '</code>';
            break;
        }
        // data
        $dbstream = $kzip->getFileStream('/database/data');
        $data_import = $dbdump->importData($dbstream);
        $dbstream->free();
        if (!$data_import[0]) {
            $err = $data_import[1];
            break;
        }
        // aktualizovat hlavni URL, vynutit kontrolu instalace
        if (($url = _getBaseUrl()) !== false) {
            DB::query('UPDATE `' . _mysql_prefix . '-settings` SET `val`=' . DB::val(rtrim($url, '/')) . ' WHERE `var`=\'url\'');
        }
        DB::query('UPDATE `' . _mysql_prefix . '-settings` SET `val`=\'1\' WHERE `var`=\'installcheck\'');
        // deaktivovat modrewrite, pokud neexistuje .htaccess
        if (!file_exists(_indexroot . '.htaccess')) {
            DB::query('UPDATE `' . _mysql_prefix . '-settings` SET `val`=\'0\' WHERE `var`=\'modrewrite\'');
        }
        // soubory
        if ($type === _backup_partial) {
            for ($i = 0; isset($dirs[$i]); ++$i) {
                echo "\n\n";
                $dirpath = realpath(dirname($_SERVER['SCRIPT_FILENAME']) . '/' . _indexroot . $dirs[$i]) . '/';
                if (!isset($kzip->vars['merge'], $kzip->vars['merge'][$dirs[$i]])) {
                    _emptyDir($dirpath, false);
                }
                $kzip->extractFiles($dirpath, $a_files . $dirs[$i] . '/', false, true, array($kzip->vars['void']));
            }
        }
        // hotovo
        $kzip->free();
        return true;
    } while (false);
    // chyba
    if (isset($kzip)) {
        $kzip->free();
    }
    return array($err, $fatal);
}