| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- <?php
- /**
- * The model file of backup module of ZenTaoPMS.
- *
- * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
- * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
- * @author Yidong Wang <yidong@cnezsoft.com>
- * @package backup
- * @version $Id$
- * @link https://www.zentao.net
- */
- class backupModel extends model
- {
- /**
- * Backup SQL.
- *
- * @param string $backupFile
- * @access public
- * @return object
- */
- public function backSQL($backupFile)
- {
- $zdb = $this->app->loadClass('zdb');
- return $zdb->dump($backupFile);
- }
- /**
- * Backup file.
- *
- * @param string $backupFile
- * @access public
- * @return object
- */
- public function backFile($backupFile)
- {
- $zfile = $this->app->loadClass('zfile');
- $return = new stdclass();
- $return->result = true;
- $return->error = '';
- if(!is_dir($backupFile)) mkdir($backupFile, 0777, true);
- $tmpLogFile = $this->getTmpLogFile($backupFile);
- $dataDir = $this->app->getAppRoot() . 'www/data/';
- $count = $zfile->getCount($dataDir, array('course'));
- file_put_contents($tmpLogFile, json_encode(array('allCount' => $count)));
- $result = $zfile->copyDir($dataDir, $backupFile, $logLevel = false, $tmpLogFile, array('course'));
- $this->processSummary($backupFile, $result['count'], $result['size'], $result['errorFiles'], $count);
- unlink($tmpLogFile);
- return $return;
- }
- /**
- * Backup code.
- *
- * @param string $backupFile
- * @access public
- * @return object
- */
- public function backCode($backupFile)
- {
- $zfile = $this->app->loadClass('zfile');
- $return = new stdclass();
- $return->result = true;
- $return->error = '';
- $tmpLogFile = $this->getTmpLogFile($backupFile);
- $appRoot = $this->app->getAppRoot();
- $fileList = glob($appRoot . '*');
- $wwwFileList = glob($appRoot . 'www/*');
- $tmpFile = array_search($appRoot . 'tmp', $fileList);
- $wwwFile = array_search($appRoot . 'www', $fileList);
- $dataFile = array_search($appRoot . 'www/data', $wwwFileList);
- unset($fileList[$tmpFile]);
- unset($fileList[$wwwFile]);
- unset($wwwFileList[$dataFile]);
- $fileList = array_merge($fileList, $wwwFileList);
- if(!is_dir($backupFile)) mkdir($backupFile, 0777, true);
- $allCount = 0;
- foreach($fileList as $codeFile) $allCount += $zfile->getCount($codeFile);
- file_put_contents($tmpLogFile, json_encode(array('allCount' => $allCount)));
- $copiedCount = 0;
- $copiedSize = 0;
- $errorFiles = array();
- foreach($fileList as $codeFile)
- {
- $file = trim(str_replace($appRoot, '', $codeFile), DS);
- if(is_dir($codeFile))
- {
- if(!is_dir($backupFile . DS . $file)) mkdir($backupFile . DS . $file, 0777, true);
- $result = $zfile->copyDir($codeFile, $backupFile . DS . $file, $logLevel = false, $tmpLogFile);
- $copiedCount += $result['count'];
- $copiedSize += $result['size'];
- $errorFiles += $result['errorFiles'];
- }
- else
- {
- $dirName = dirname($file);
- if(!is_dir($backupFile . DS . $dirName)) mkdir($backupFile . DS . $dirName, 0777, true);
- if($zfile->copyFile($codeFile, $backupFile . DS . $file))
- {
- $copiedCount += 1;
- $copiedSize += filesize($codeFile);
- }
- else
- {
- $errorFiles[] = $codeFile;
- }
- }
- }
- $this->processSummary($backupFile, $copiedCount, $copiedSize, $errorFiles, $allCount);
- unlink($tmpLogFile);
- return $return;
- }
- /**
- * Restore SQL.
- *
- * @param string $backupFile
- * @access public
- * @return object
- */
- public function restoreSQL($backupFile)
- {
- $zdb = $this->app->loadClass('zdb');
- $allTables = $zdb->getAllTables();
- foreach($allTables as $tableName => $tableType)
- {
- try
- {
- $this->dbh->exec("DROP $tableType IF EXISTS `$tableName`");
- }
- catch(PDOException $e){}
- }
- $this->dao->clearCache();
- return $zdb->import($backupFile);
- }
- /**
- * Restore File.
- *
- * @param string $backupFile
- * @access public
- * @return object
- */
- public function restoreFile($backupFile)
- {
- $return = new stdclass();
- $return->result = true;
- $return->error = '';
- if(is_dir($backupFile))
- {
- $zfile = $this->app->loadClass('zfile');
- $zfile->copyDir($backupFile, $this->app->getAppRoot() . 'www/data/', $showDetails = false);
- }
- return $return;
- }
- /**
- * Add file header.
- *
- * @param string $fileName
- * @access public
- * @return bool
- */
- public function addFileHeader($fileName)
- {
- $die = "<?php die();?" . ">\n";
- $tmpFile = $fileName . '.tmp';
- rename($fileName, $tmpFile);
- file_put_contents($fileName, $die);
- $fh = fopen($tmpFile, 'r');
- $length = 2 * 1024 * 1024;
- while(!feof($fh))
- {
- $buff = fread($fh, $length);
- file_put_contents($fileName, $buff, FILE_APPEND);
- }
- fclose($fh);
- unlink($tmpFile);
- return true;
- }
- /**
- * Remove file header.
- *
- * @param string $fileName
- * @access public
- * @return bool
- */
- public function removeFileHeader($fileName)
- {
- $tmpFile = $fileName . '.tmp';
- $fh = fopen($fileName, 'r');
- $length = 2 * 1024 * 1024;
- $readedFirstLine = false;
- while(!feof($fh))
- {
- if(!$readedFirstLine)
- {
- fgets($fh);
- $readedFirstLine = true;
- continue;
- }
- $buff = fread($fh, $length);
- file_put_contents($tmpFile, $buff, FILE_APPEND);
- }
- fclose($fh);
- rename($tmpFile, $fileName);
- return true;
- }
- /**
- * Get dir size.
- *
- * @param string $backup
- * @access public
- * @return array
- */
- public function getBackupSummary($backup)
- {
- $zfile = $this->app->loadClass('zfile');
- if(is_file($backup))
- {
- $summary = array();
- $summary['allCount'] = 1;
- $summary['count'] = 1;
- $summary['size'] = $zfile->getFileSize($backup);
- return $summary;
- }
- $summaryFile = dirname($backup) . DS . 'summary';
- if(!file_exists($summaryFile)) return array();
- $summary = json_decode(file_get_contents(dirname($backup) . DS . 'summary'), true);
- return zget($summary, basename($backup), array());
- }
- /**
- * Get backup path.
- *
- * @access public
- * @return string
- */
- public function getBackupPath()
- {
- $backupPath = empty($this->config->backup->settingDir) ? $this->app->getTmpRoot() . 'backup' . DS : $this->config->backup->settingDir;
- return rtrim(str_replace(DS, '/', $backupPath), '/') . '/';
- }
- /**
- * Get backup file.
- *
- * @param string $name
- * @param string $type sql|file|code
- * @access public
- * @return string|false
- */
- public function getBackupFile($name, $type)
- {
- $backupPath = $this->getBackupPath();
- if($type == 'sql')
- {
- if(file_exists($backupPath . $name . ".{$type}")) return $backupPath . $name . ".{$type}";
- if(file_exists($backupPath . $name . ".{$type}.php")) return $backupPath . $name . ".{$type}.php";
- }
- if(file_exists($backupPath . $name . ".{$type}")) return $backupPath . $name . ".{$type}";
- return false;
- }
- /**
- * Get tmp log file.
- *
- * @param string $backupFile
- * @access public
- * @return string
- */
- public function getTmpLogFile($backupFile)
- {
- return $backupFile . '.tmp.summary';
- }
- /**
- * Get backup dir progress.
- *
- * @param string $backup
- * @access public
- * @return array
- */
- public function getBackupDirProgress($backup)
- {
- $tmpLogFile = $this->getTmpLogFile($backup);
- if(file_exists($tmpLogFile))
- {
- $log = json_decode(file_get_contents($tmpLogFile), true);
- return empty($log) ? array() : $log;
- }
- return array('allCount' => 0, 'count' => 0);
- }
- /**
- * Process filesize.
- *
- * @param int $fileSize
- * @access public
- * @return string
- */
- public function processFileSize($fileSize)
- {
- $bit = 'KB';
- $fileSize = round($fileSize / 1024, 2);
- if($fileSize >= 1024)
- {
- $bit = 'MB';
- $fileSize = round($fileSize / 1024, 2);
- }
- if($fileSize >= 1024)
- {
- $bit = 'GB';
- $fileSize = round($fileSize / 1024, 2);
- }
- return $fileSize . $bit;
- }
- /**
- * Process backup summary.
- *
- * @param string $file
- * @param int $count
- * @param int $size
- * @param array $errorFiles
- * @param int $allCount
- * @param string $action add|delete
- * @access public
- * @return bool
- */
- public function processSummary($file, $count, $size, $errorFiles = array(), $allCount = 0, $action = 'add')
- {
- $backupPath = dirname($file);
- $fileName = basename($file);
- $summaryFile = $backupPath . DS . 'summary';
- if(!file_exists($summaryFile) and !touch($summaryFile)) return false;
- $summary = json_decode(file_get_contents($summaryFile), true);
- if(empty($summary)) $summary = array();
- if($action == 'add')
- {
- $summary[$fileName]['allCount'] = $allCount;
- $summary[$fileName]['errorFiles'] = $errorFiles;
- $summary[$fileName]['count'] = $count;
- $summary[$fileName]['size'] = $size;
- }
- else
- {
- unset($summary[$fileName]);
- }
- if(file_put_contents($summaryFile, json_encode($summary))) return true;
- return false;
- }
- /**
- * Get disk space.
- *
- * @param string $backupPath
- * @access public
- * @return string
- */
- public function getDiskSpace($backupPath)
- {
- $nofile = strpos($this->config->backup->setting, 'nofile') !== false;
- $diskFreeSpace = disk_free_space($backupPath);
- $backFileSize = 0;
- if(!$nofile)
- {
- $appRoot = $this->app->getAppRoot();
- $appRootSize = $this->getDirSize($appRoot);
- $backFileSize = $appRootSize - $this->getDirSize($appRoot . 'tmp') - $this->getDirSize($appRoot . 'www/data/course');
- }
- $backSqlSize = $this->dao->select('sum(data_length+index_length) as size')
- ->from('information_schema.tables')
- ->where('TABLE_SCHEMA')->eq($this->config->db->name)
- ->groupBy('TABLE_SCHEMA')
- ->fetch('size');
- return $diskFreeSpace . ',' . ($backFileSize + $backSqlSize);
- }
- /**
- * Get directory size.
- *
- * @param string $dir
- * @access public
- * @return int
- */
- public function getDirSize($dir)
- {
- if(!file_exists($dir)) return 0;
- if(!is_readable($dir)) return 0;
- $totalSize = 0;
- $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::LEAVES_ONLY, RecursiveIteratorIterator::CATCH_GET_CHILD);
- foreach($iterator as $file) $totalSize += $file->getSize();
- return $totalSize;
- }
- }
|