ConLite/conlite/classes/class.cl_db_backup.php

337 Zeilen
12 KiB
PHP

<?php
/**
*
* @package ConLite
* @subpackage DB-Backup
* @version $Rev$
* @author Ortwin Pinke <o.pinke@conlite.org>
* @copyright (c) 2012, conlite.org
*
* $Id$
*/
/* @var $sess Contenido_Session */
/* @var $perm Contenido_Perm */
/* @var $auth Contenido_Challenge_Crypt_Auth */
/* @var $notification Contenido_Notification */
// security check
defined('CON_FRAMEWORK') or die('Illegal call');
class clDbBackup {
protected $_oDb;
protected $_sDumpFile = null;
protected $_bCompress = false;
protected $_sTmpData = null;
protected $_aUsedExt = array('sql', 'gz');
protected $_aTableContent = array('_code', '_inuse', '_phplib_active_sessions');
protected $_sLogFile;
/**
* Constructor
*/
public function __construct() {
$this->_oDb = new DB_ConLite();
$this->_sLogFile = CL_BACKUP_LOGFILE;
if (isset($_SESSION['dump']['file']) && !empty($_SESSION['dump']['file'])) {
$this->_sDumpFile = $_SESSION['dump']['file'];
}
if (isset($_SESSION['dump']['compress']) && is_bool($_SESSION['dump']['compress'])) {
$this->_bCompress = ($_SESSION['dump']['compress']) ? true : false;
}
}
/**
* Builds and returns an array of dump files for a given dir
*
* @param string $sPath server path to dump files
* @param string $sOrder sort order by
* @param string $sDirection sort direction
* @return array|boolean returns array of files or false
*/
public function getDumpFiles($sPath, $sOrder = 'date', $sDirection = 'DESC') {
$oDirHandle = dir($sPath);
$aFiles = array();
if (is_object($oDirHandle)) {
$iLoop = 0;
while (false !== ($sFile = $oDirHandle->read())) {
if ($sFile == '..' || $sFile == '.' || $sFile == '.svn')
continue;
$info = new SplFileInfo($sPath . $sFile); // pathinfo($file->getFilename(), PATHINFO_EXTENSION)
if ($info->isFile()) {
$sExtension = '';
if (version_compare(phpversion(), "5.3.6", ">=")) {
$sExtension = $info->getExtension();
} else {
$sExtension = pathinfo($info->getFilename(), PATHINFO_EXTENSION);
}
if (!in_array($sExtension, $this->_aUsedExt))
continue;
$aFiles[$iLoop]['ext'] = $sExtension;
$aFiles[$iLoop]['size'] = $info->getSize();
$aFiles[$iLoop]['readable'] = $info->isReadable();
$aFiles[$iLoop]['atime'] = $info->getATime();
$aFiles[$iLoop]['ctime'] = $info->getCTime();
$aFiles[$iLoop]['mtime'] = $info->getMTime();
}
$aFiles[$iLoop]['filename'] = $sFile;
$iLoop++;
}
$oDirHandle->close();
}
if (count($aFiles) > 0) {
// Hole eine Liste von Spalten
foreach ($aFiles as $key => $row) {
$time[$key] = $row['ctime'];
}
array_multisort($time, (($sDirection == 'DESC') ? SORT_DESC : SORT_ASC), $aFiles);
}
return (count($aFiles) > 0) ? $aFiles : false;
}
/**
* Write data to dump file
*
* @todo make this func protected and give a public wrapper
* @param string $sData
* @return boolean
*/
public function _writeToDumpFile($sData = null) {
if (!is_null($sData))
$this->_sTmpData = $sData;
if (!is_null($this->_sDumpFile)) {
if (!is_null($this->_sTmpData) && !empty($this->_sTmpData)) {
if ($this->_bCompress) {
$fp = gzopen($this->_sDumpFile, 'ab');
gzwrite($fp, $this->_sTmpData, strlen($this->_sTmpData));
gzclose($fp);
} else {
$fp = fopen($this->_sDumpFile, 'ab');
fwrite($fp, $this->_sTmpData);
fclose($fp);
}
$this->_sTmpData = null;
return true;
}
}
$this->_sTmpData = null;
return false;
}
/**
* Write table header to dump and return dataset count
*
* @param string $sTable
* @return array
*/
public function _writeTableHeader($sTable) {
$data = "DROP TABLE IF EXISTS `$sTable`;\n";
$this->_oDb->query('SHOW CREATE TABLE `' . $sTable . '`');
$this->_oDb->next_record();
$row = $this->_oDb->toArray();
$data .= $row[1] . ';' . "\n\n";
if (!$this->_noTableData($sTable)) {
$data .= "/*!40000 ALTER TABLE `$sTable` DISABLE KEYS */;\n";
}
$this->_writeToDumpFile($data);
$sql = "SELECT count(*) as `count_records` FROM `" . $sTable . "`";
$this->_oDb->query($sql);
$this->_oDb->next_record();
$res_array = $this->_oDb->toArray();
return $res_array['count_records'];
}
/**
* Write table data to dump file
*
* @global array $dump
* @param string $sTable
* @return void
*/
public function _writeTableData($sTable) {
global $dump;
if ($this->_noTableData($sTable)) {
$dump['nr'] ++;
$dump['table_offset'] = 0;
return;
}
$table_list = array();
$this->_oDb->query("SHOW COLUMNS FROM " . $sTable);
while($this->_oDb->next_record()) {
$aResult = $this->_oDb->toArray();
$table_list[] = $aResult['Field'];
}
$this->_oDb->query('select `' . implode('`,`', $table_list) . '` from ' . $sTable . ' limit ' . $dump['zeilen_offset'] . ',' . ($dump['anzahl_zeilen']));
$ergebnisse = $this->_oDb->num_rows();
$data = '';
if ($ergebnisse !== false) {
if (($ergebnisse + $dump['zeilen_offset']) < $dump['table_records']) {
//noch nicht fertig - neuen Startwert festlegen
$dump['zeilen_offset']+= $dump['anzahl_zeilen'];
} else {
//Fertig - naechste Tabelle
$dump['nr'] ++;
$dump['table_offset'] = 0;
}
//BOF Complete Inserts ja/nein
if ($_SESSION['dump']['complete_inserts'] == 'yes') {
while ($this->_oDb->next_record()) {
$rows = $this->_oDb->toArray();
$insert = 'INSERT INTO `' . $sTable . '` (`' . implode('`, `', $table_list) . '`) VALUES (';
foreach ($table_list as $column) {
//EOF NEW TABLE STRUCTURE - LIKE MYSQLDUMPER -functions_dump.php line 186
if (!isset($rows[$column])) {
$insert.='NULL,';
} else if ($rows[$column] != '') {
$insert.='\'' . $this->_oDb->escape($rows[$column]) . '\',';
} else {
$insert.='\'\',';
}
//BOF NEW TABLE STRUCTURE - LIKE MYSQLDUMPER
}
$data .=substr($insert, 0, -1) . ');' . "\n";
}
} else {
$lines = array();
while ($this->_oDb->next_record()) {
$rows = $this->_oDb->toArray();
$values = array();
foreach ($table_list as $column) {
//EOF NEW TABLE STRUCTURE - LIKE MYSQLDUMPER
if (!isset($rows[$column])) {
$values[] = 'NULL';
} else if ($rows[$column] != '') {
$values[] = '\'' . $this->_oDb->escape($rows[$column]) . '\'';
} else {
$values[] = '\'\'';
}
//BOF NEW TABLE STRUCTURE - LIKE MYSQLDUMPER
}
$lines[] = implode(', ', $values);
}
$tmp = trim(implode("),\n (", $lines));
if ($tmp != '') {
$data = 'INSERT INTO `' . $sTable . '` (`' . implode('`, `', $table_list) . '`) VALUES' . "\n" . ' (' . $tmp . ");\n";
}
}
//EOF Complete Inserts ja/nein
if ($dump['table_offset'] == 0)
$data.= "/*!40000 ALTER TABLE `$sTable` ENABLE KEYS */;\n\n";
$this->_writeToDumpFile($data);
}
}
/**
* send a file to browser (download) and exit
*
* @param string $sFileName
*/
public function sendFile($sFileName) {
if (is_file($sFileName)) {
$path_parts = pathinfo($sFileName);
$file_name = $path_parts['basename'];
$file_ext = $path_parts['extension'];
$file_size = filesize($sFileName);
$rTmpFile = @fopen($sFileName, "rb");
if ($rTmpFile) {
set_time_limit(0);
ob_end_clean();
// set the headers, prevent caching
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: private", false); // required for certain browsers
header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");
header("Content-Disposition: attachment; filename=\"$file_name\"");
// set the mime type based on extension, add yours if needed.
$ctype_default = "application/octet-stream";
$content_types = array(
"sql" => "application/x-sql",
"gz" => "application/x-gzip"
);
$ctype = isset($content_types[$file_ext]) ? $content_types[$file_ext] : $ctype_default;
header("Content-Type: $ctype");
header("Content-Transfer-Encoding: binary");
header("Content-Length: $file_size");
while (!feof($rTmpFile)) {
print(@fread($rTmpFile, 1024 * 8));
ob_flush();
flush();
if (connection_status() != 0) {
@fclose($rTmpFile);
exit;
}
}
// file save was a success
@fclose($rTmpFile);
$this->_writeLogEntry("Downloaded File: " . basename($sFileName));
exit;
} else {
// file couldn't be opened
header("HTTP/1.0 500 Internal Server Error");
exit;
}
} else {
// file does not exist
header("HTTP/1.0 404 Not Found");
exit;
}
}
/**
* Write a log entry
*/
public function writeLog() {
$this->_writeLogEntry("Backup generated: " . $this->_sDumpFile);
}
/**
* Check against table exclude array for writing table data
*
* @param string $sTable
* @return boolean
*/
protected function _noTableData($sTable) {
foreach ($this->_aTableContent as $sExTable) {
if (strstr($sTable, $sExTable))
return true;
}
return false;
}
/**
* Write to log file
*
* @global Contenido_Challenge_Crypt_Auth $auth
* @param string $sMessage
*/
protected function _writeLogEntry($sMessage) {
/* @var $auth Contenido_Challenge_Crypt_Auth */
global $auth;
if (!empty($auth->auth['uname'])) {
$sMessage = "User " . $auth->auth['uname'] . " - " . $sMessage;
}
$f = @fopen($this->_sLogFile, 'a+');
if (is_resource($f)) {
@fputs($f, date("d.m.Y g:ia") . " " . $_SERVER['REMOTE_ADDR'] . " " . $sMessage . "\n");
@fclose($f);
}
}
}
?>