/**
  * @see Action::execute()
  */
 public function execute()
 {
     parent::execute();
     // export is not finished. export further
     if (empty($this->downloadFile)) {
         // get session data
         $sessionData = WCF::getSession()->getVar('databaseExportData');
         $loopTimeLimit = $sessionData['loopTimeLimit'];
         $isGzip = $sessionData['isGzip'];
         $limit = $sessionData['limit'];
         $tableName = $sessionData['tableName'];
         $offset = $sessionData['offset'];
         $importErrors = '';
         $stepInfo = array();
         // start export operations
         $loopStart = time();
         $backupFile = $sessionData['backupFile'];
         $tables = $sessionData['tables'];
         // TODO: check if file could be opened (e.g. if directory exists)
         // open backupfile
         if ($isGzip) {
             $file = new ZipFile($backupFile, $offset == -1 ? 'wb' : 'ab');
         } else {
             $file = new File($backupFile, $offset == -1 ? 'wb' : 'ab');
         }
         // export database operations (only up to $limit)
         $stepInfo = DatabaseDumper::export($file, $tables, $limit, $loopTimeLimit, $loopStart, $offset, $tableName);
         // delete completed tables from session
         foreach ($stepInfo['completedTables'] as $table) {
             $key = array_search($table, $sessionData['tables']);
             if ($key !== false) {
                 unset($sessionData['tables'][$key]);
             }
         }
         $loopEnd = time();
         $duration = $loopEnd - $loopStart;
         // check if limit should be changed (more or less db-operations per loop)
         if ($stepInfo['resetLimit']) {
             $sessionData['limit'] = 250;
         } elseif ($duration != $loopTimeLimit) {
             // higher export step size
             if ($duration > 0) {
                 $sessionData['limit'] = round($limit * ($loopTimeLimit / $duration), 0);
             } else {
                 $sessionData['limit'] = $limit * 10;
             }
         }
         // refresh session data
         $sessionData['tableName'] = $stepInfo['tableName'];
         $sessionData['offset'] = $stepInfo['offset'];
         $sessionData['remain'] -= $stepInfo['done'];
         // show finish
         if ($sessionData['remain'] <= 0) {
             // cleanup session data. save backupFile to session
             WCF::getSession()->register('databaseExportData', $backupFile);
             WCF::getTPL()->assign(array('export' => true, 'success' => true, 'totalTables' => $sessionData['tableCount'], 'totalRecords' => $sessionData['rowCount'], 'backupFile' => $backupFile));
             WCF::getTPL()->append('message', WCF::getTPL()->fetch('dbMessage'));
             $title = 'wcf.acp.db.progress.finish';
             $this->calcProgress($sessionData['count'] - $sessionData['remain'], $sessionData['count']);
             $this->finish($title, 'index.php?form=DatabaseExport&packageID=' . PACKAGE_ID . SID_ARG_2ND_NOT_ENCODED);
         }
         WCF::getSession()->register('databaseExportData', $sessionData);
         // refresh progressbar and go to the next step
         $title = 'wcf.acp.db.export.progress.working';
         $this->calcProgress($sessionData['count'] - $sessionData['remain'], $sessionData['count']);
         $this->nextLoop($title);
     } else {
         $fileName = basename($this->downloadFile);
         $backupFile = WCF::getSession()->getVar('databaseExportData');
         WCF::getSession()->unregister('databaseExportData');
         if ($this->downloadFile == $backupFile) {
             // file type
             header('Content-Type: application/octet-stream');
             // file name
             header('Content-Disposition: attachment; filename="' . $fileName . '"');
             // send file size
             header('Content-Length: ' . filesize($this->downloadFile));
             // no cache headers
             header('Pragma: no-cache');
             header('Expires: 0');
             // send file
             readfile($this->downloadFile);
         } else {
             throw new SystemException("Expected parameter for download file: " . $this->downloadFile, 102000);
         }
     }
 }
 public function cronDbBackup()
 {
     require_once WCF_DIR . 'lib/system/database/DatabaseDumper.class.php';
     $allTables = WCF::getDB()->getTableNames();
     $tablesEx = DatabaseDumper::getTableStates($allTables);
     $rowCount = 0;
     $tables = array();
     foreach ($tablesEx as $table) {
         $rowCount += $table['Rows'];
         $tables[] = $table['Name'];
     }
     // comment buffer
     $limit = $rowCount + 10000;
     $offset = -1;
     $backupFile = WCF_DIR . 'acp/backup/' . date('YmdHis') . '.sql.gz';
     $file = new ZipFile($backupFile, 'wb');
     $loopTimeLimit = 3600;
     $loopStart = time();
     $tableName = '';
     // write header info
     $head = "-- WoltLab Community Framework\n";
     $head .= "-- database: " . WCF::getDB()->getDatabaseName() . "\n";
     $head .= "-- generated at " . date('r') . "\n\n";
     $head .= "-- DO NOT EDIT THIS FILE\n\n";
     $head .= "-- WCF DATABASE CHARSET\n";
     $head .= "SET NAMES  " . WCF::getDB()->getCharset() . ";\n\n";
     $file->write($head);
     @set_time_limit(3600);
     DatabaseDumper::export($file, $tables, $limit, $loopTimeLimit, $loopStart, 0, $tableName);
 }