3
* Xibo - Digital Signage - http://www.xibo.org.uk
4
* Copyright (C) 2012 Daniel Garner
6
* This file is part of Xibo.
8
* Xibo is free software: you can redistribute it and/or modify
9
* it under the terms of the GNU Affero General Public License as published by
10
* the Free Software Foundation, either version 3 of the License, or
13
* Xibo is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU Affero General Public License for more details.
18
* You should have received a copy of the GNU Affero General Public License
19
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
23
defined('XIBO') or die("Sorry, you are not allowed to directly access this page.<br /> Please press the back button in your browser.");
25
class Maintenance extends Data
29
* @param <string> $saveAs file|string
31
public function BackupDatabase($saveAs = "string")
33
// Check we can run mysql
34
if (!function_exists('exec'))
35
return $this->SetError(__('Exec is not available.'));
37
// Global database variables to seed into exec
44
$fileNameStructure = Config::GetSetting('LIBRARY_LOCATION') . 'structure.dump';
45
$fileNameData = Config::GetSetting('LIBRARY_LOCATION') . 'data.dump';
46
$zipFile = 'database.tar.gz';
48
// Run mysqldump structure to a temporary file
49
$command = 'mysqldump --opt --host=' . $dbhost . ' --user=' . $dbuser . ' --password=' . addslashes($dbpass) . ' ' . $dbname . ' --no-data > ' . escapeshellarg($fileNameStructure) . ' ';
52
// Run mysqldump data to a temporary file
53
$command = 'mysqldump --opt --host=' . $dbhost . ' --user=' . $dbuser . ' --password=' . addslashes($dbpass) . ' ' . $dbname . ' --ignore-table=' . $dbname . '.log --ignore-table=' . $dbname . '.oauth_log > ' . escapeshellarg($fileNameData) . ' ';
57
if (!file_exists($fileNameStructure) || !file_exists($fileNameData))
58
return $this->SetError(__('Database dump failed.'));
62
$zip = new ZipArchive();
63
$zip->open($zipFile, ZIPARCHIVE::OVERWRITE);
64
$zip->addFile($fileNameStructure, 'structure.dump');
65
$zip->addFile($fileNameData, 'data.dump');
68
// Remove the dump file
69
unlink($fileNameStructure);
70
unlink($fileNameData);
72
// Uncomment only if you are having permission issues
73
// chmod($zipFile, 0777);
75
// Push file back to browser
76
if (ini_get('zlib.output_compression')) {
77
ini_set('zlib.output_compression', 'Off');
80
$size = filesize($zipFile);
82
header('Content-Type: application/octet-stream');
83
header("Content-Transfer-Encoding: Binary");
84
header("Content-disposition: attachment; filename=\"" . basename($zipFile) . "\"");
87
header('Pragma: public');
88
header('Cache-Control: max-age=86400');
89
header('Expires: '. gmdate('D, d M Y H:i:s \G\M\T', time() + 86400));
90
header('Content-Length: ' . $size);
92
// Send via Apache X-Sendfile header?
93
if (Config::GetSetting('SENDFILE_MODE') == 'Apache') {
94
header("X-Sendfile: $zipFile");
98
// Return the file with PHP
99
// Disable any buffering to prevent OOM errors.
109
* @param <string> $fileName
111
public function RestoreDatabase($fileName)
118
// Push the file into msqldump
119
exec('mysql --user=' . $dbuser . ' --password=' . $dbpass . ' ' . $dbname . ' < ' . escapeshellarg($fileName) . ' ');
121
Log::notice('mysql --user=' . $dbuser . ' --password=' . $dbpass . ' ' . $dbname . ' < ' . escapeshellarg($fileName) . ' ' );
126
public function TidyLibrary($tidyOldRevisions, $cleanUnusedFiles)
128
// Also run a script to tidy up orphaned media in the library
129
$library = Config::GetSetting('LIBRARY_LOCATION');
130
$library = rtrim($library, '/') . '/';
131
$mediaObject = new Media();
133
Log::Audit('Library Location: ' . $library);
135
// Dump the files in the temp folder
136
foreach (scandir($library . 'temp') as $item) {
137
if ($item == '.' || $item == '..')
140
Log::Audit('Deleting temp file: ' . $item);
142
unlink($library . 'temp' . DIRECTORY_SEPARATOR . $item);
146
$unusedMedia = array();
147
$unusedRevisions = array();
149
// Run a query to get an array containing all of the media in the library
151
$dbh = \Xibo\Storage\PDOConnect::init();
153
$sth = $dbh->prepare('
154
SELECT media.mediaid, media.storedAs, media.type, media.isedited,
155
SUM(CASE WHEN IFNULL(lklayoutmedia.lklayoutmediaid, 0) = 0 THEN 0 ELSE 1 END) AS UsedInLayoutCount,
156
SUM(CASE WHEN IFNULL(lkmediadisplaygroup.id, 0) = 0 THEN 0 ELSE 1 END) AS UsedInDisplayCount
158
LEFT OUTER JOIN `lklayoutmedia`
159
ON lklayoutmedia.mediaid = media.mediaid
160
LEFT OUTER JOIN `lkmediadisplaygroup`
161
ON lkmediadisplaygroup.mediaid = media.mediaid
162
GROUP BY media.mediaid, media.storedAs, media.type, media.isedited ');
164
$sth->execute(array());
166
foreach ($sth->fetchAll() as $row) {
167
$media[$row['storedAs']] = $row;
169
// Ignore any module files or fonts
170
if ($row['type'] == 'module' || $row['type'] == 'font')
173
// Collect media revisions that aren't used
174
if ($tidyOldRevisions && $row['UsedInLayoutCount'] <= 0 && $row['UsedInDisplayCount'] <= 0 && $row['isedited'] > 0) {
175
$unusedRevisions[$row['storedAs']] = $row;
177
// Collect any files that aren't used
178
else if ($cleanUnusedFiles && $row['UsedInLayoutCount'] <= 0 && $row['UsedInDisplayCount'] <= 0) {
179
$unusedMedia[$row['storedAs']] = $row;
183
catch (Exception $e) {
185
Log::error($e->getMessage());
187
if (!$this->IsError())
188
$this->SetError(1, __('Unknown Error'));
193
//Debug::Audit(var_export($media, true));
194
//Debug::Audit(var_export($unusedMedia, true));
196
// Get a list of all media files
197
foreach(scandir($library) as $file) {
199
if ($file == '.' || $file == '..')
202
if (is_dir($library . $file))
206
if (strstr($file, 'tn_') || strstr($file, 'bg_'))
209
// Is this file in the system anywhere?
210
if (!array_key_exists($file, $media)) {
212
Log::Audit('Deleting file: ' . $file);
215
$mediaObject->DeleteMediaFile($file);
217
else if (array_key_exists($file, $unusedRevisions)) {
218
// It exists but isn't being used any more
219
Log::Audit('Deleting unused revision media: ' . $media[$file]['mediaid']);
220
$mediaObject->Delete($media[$file]['mediaid']);
222
else if (array_key_exists($file, $unusedMedia)) {
223
// It exists but isn't being used any more
224
Log::Audit('Deleting unused media: ' . $media[$file]['mediaid']);
225
$mediaObject->Delete($media[$file]['mediaid']);