/**
  * Import products
  */
 public function actionImport()
 {
     $this->pageName = Yii::t('CsvModule.admin', 'IMPORT_PRODUCTS');
     $importer = new CsvImporter();
     $importer->deleteDownloadedImages = Yii::app()->request->getPost('remove_images');
     if (Yii::app()->request->isPostRequest && isset($_FILES['file'])) {
         $importer->file = $_FILES['file']['tmp_name'];
         if ($importer->validate() && !$importer->hasErrors()) {
             // Create db backup
             if (isset($_POST['create_dump']) && $_POST['create_dump']) {
                 //Yii::import('application.components.DatabaseDumper');
                 $dumper = new DatabaseDumper();
                 $file = Yii::getPathOfAlias('webroot.protected.backups') . DIRECTORY_SEPARATOR . 'dump_' . date('Y-m-d_H_i_s') . '.sql';
                 if (is_writable(Yii::getPathOfAlias('webroot.protected.backups'))) {
                     if (function_exists('gzencode')) {
                         file_put_contents($file . '.gz', gzencode($dumper->getDump()));
                     } else {
                         file_put_contents($file, $dumper->getDump());
                     }
                 } else {
                     throw new CHttpException(503, Yii::t('CsvModule.admin', 'ERROR_WRITE_BACKUP'));
                 }
             }
             $importer->import();
         }
     }
     $this->render('import', array('importer' => $importer));
 }
Beispiel #2
0
 /**
  * dumpSQL
  *
  * @param SplFileInfo $backupSQLFile
  *
  * @return  void
  */
 protected function dumpSQL(\SplFileInfo $backupSQLFile)
 {
     // Delete old file
     if (is_file($backupSQLFile->getPathname())) {
         unlink($backupSQLFile->getPathname());
     }
     try {
         $sql = DatabaseDumper::dump($this->getOption('database', array()));
     } catch (RuntimeException $e) {
         $this->close($e->getMessage());
     }
     file_put_contents($backupSQLFile->getPathname(), $sql);
 }
 /**
  * @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);
         }
     }
 }
 /**
  * @see Action::execute()
  */
 public function execute()
 {
     parent::execute();
     // get session data
     $sessionData = WCF::getSession()->getVar('databaseImportData');
     $filesize = $sessionData['filesize'];
     $isGzip = $sessionData['isGzip'];
     $extendedCommand = $sessionData['extendedCommand'];
     $offset = $sessionData['offset'];
     $charset = $sessionData['importCharset'];
     $ignoreErrors = $sessionData['ignoreErrors'];
     $importErrors = '';
     $stepInfo = array();
     // start export operations
     $loopStart = time();
     $importFile = $sessionData['importFile'];
     if ($isGzip) {
         $file = new ZipFile($importFile, 'rb');
     } else {
         $file = new File($importFile, 'rb');
     }
     // import database operations (only up to $this->limit)
     $loopInfo = DatabaseDumper::import($file, $filesize, $isGzip, $this->limit, $loopStart, $offset, $charset, $extendedCommand, $ignoreErrors);
     $file->close();
     // store charset
     if (!empty($loopInfo['charset']) && $loopInfo['charset'] != $sessionData['wcfCharset']) {
         $sessionData['importCharset'] = $loopInfo['charset'];
     }
     // delete aftereffected erros (no insert errors will be displayed if the table caused an error before)
     $tableErrors = $sessionData['tableErrors'];
     foreach ($loopInfo['errors']['messages'] as $key => $message) {
         if (preg_match("/CREATE TABLE `?(\\w+)`?/i", $message, $match)) {
             $tableErrors[] = $match[1];
         } elseif (preg_match("/(INSERT|REPLACE).*?INTO `?(\\w+)`?/i", $message, $match)) {
             if (in_array($match[1], $tableErrors)) {
                 unset($loopInfo['errors']['messages'][$key]);
                 unset($loopInfo['errors']['errorDescriptions'][$key]);
             } else {
                 $tableErrors[] = $match[1];
             }
         }
     }
     // save errors
     $errors = array('messages' => array_merge($sessionData['errors']['messages'], $loopInfo['errors']['messages']), 'errorDescriptions' => array_merge($sessionData['errors']['errorDescriptions'], $loopInfo['errors']['errorDescriptions']));
     $sessionData['errors'] = $errors;
     $sessionData['tableErrors'] = $tableErrors;
     // refresh session data
     $sessionData['extendedCommand'] = $loopInfo['extendedCommand'];
     $sessionData['offset'] = $loopInfo['offset'];
     $sessionData['remain'] -= $loopInfo['done'];
     $sessionData['commandCount'] += $loopInfo['commandCount'];
     // calculate progressbar
     $this->calcProgress($sessionData['count'] - $sessionData['remain'], $sessionData['count']);
     // show finish
     if ($sessionData['remain'] <= 0) {
         // reset charset for database connection
         if (!empty($sessionData['importCharset'])) {
             WCF::getDB()->setCharset($sessionData['wcfCharset']);
         }
         // cleanup session data
         WCF::getSession()->unregister('databaseImportData');
         // delete imported upload/remote file
         if ($sessionData['isTmpFile']) {
             @unlink($importFile);
         }
         // clear all standalone caches
         // get standalone package directories
         $sql = "SELECT\tpackageDir \n\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\tWHERE\tstandalone = 1\n\t\t\t\t\tAND packageDir <> ''";
         $result = WCF::getDB()->sendQuery($sql);
         while ($row = WCF::getDB()->fetchArray($result)) {
             // check if standalone package got cache directory
             $realPackageDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR . $row['packageDir']));
             if (file_exists($realPackageDir . 'cache')) {
                 // delete all cache files
                 WCF::getCache()->clear($realPackageDir . 'cache', '*.php', true);
             }
         }
         // clear wcf cache
         WCF::getCache()->clear(WCF_DIR . 'cache', '*.php', true);
         // delete all language files
         LanguageEditor::updateAll();
         // set data for template
         WCF::getTPL()->assign(array('import' => true, 'success' => empty($errors['messages']) && $sessionData['commandCount'] > 0, 'commandCount' => $sessionData['commandCount'], 'errors' => $errors));
         WCF::getTPL()->append('message', WCF::getTPL()->fetch('dbMessage'));
         // show finish template
         $title = 'wcf.acp.db.progress.finish';
         $this->finish($title, 'index.php?form=DatabaseImport&packageID=' . PACKAGE_ID . SID_ARG_2ND_NOT_ENCODED);
     }
     WCF::getSession()->register('databaseImportData', $sessionData);
     // next loop
     $title = 'wcf.acp.db.import.progress.working';
     $this->nextLoop($title);
 }
 /**
  * @see Form::save()
  */
 public function save()
 {
     parent::save();
     // build session data array
     $sessionData = array();
     $sessionData['loopTimeLimit'] = $this->loopTimeLimit;
     $sessionData['isGzip'] = $this->isGzip;
     $sessionData['tableName'] = '';
     $tablecount = 0;
     $rowCount = 0;
     $sessionData['offset'] = -1;
     // get all tables
     if ($this->exportAll) {
         $this->readLoggedTables();
         $this->exportTables = $this->loggedTables;
     }
     // prepare session data
     $sessionData['limit'] = $this->limit;
     $sessionData['backupFile'] = FileUtil::getRealPath(WCF_DIR . 'acp/backup/' . $this->backupFileName);
     $sessionData['tables'] = $this->exportTables;
     // calculate total steps
     $tableCount = count($this->exportTables);
     $tables = DatabaseDumper::getTableStates($this->exportTables);
     $rowCount = 0;
     foreach ($tables as $table) {
         $rowCount += $table['Rows'];
     }
     $sessionData['tableCount'] = $tableCount;
     $sessionData['rowCount'] = $rowCount;
     $sessionData['count'] = $sessionData['remain'] = $tableCount + $rowCount;
     WCF::getSession()->register('databaseExportData', $sessionData);
     $this->saved();
     WCF::getTPL()->assign(array('pageTitle' => WCF::getLanguage()->get('wcf.acp.db.export.pageHeadline'), 'url' => 'index.php?action=DatabaseExport&packageID=' . PACKAGE_ID . SID_ARG_2ND_NOT_ENCODED, 'progress' => 0));
     WCF::getTPL()->display('worker');
     exit;
 }
 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);
 }