~xibo-maintainers/xibo/tempel

« back to all changes in this revision

Viewing changes to lib/data/maintenance.data.class.php

  • Committer: Dan Garner
  • Date: 2015-03-26 14:08:33 UTC
  • Revision ID: git-v1:70d14044444f8dc5d602b99890d59dea46d9470c
Moved web servable files to web folder

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/*
 
3
 * Xibo - Digital Signage - http://www.xibo.org.uk
 
4
 * Copyright (C) 2012 Daniel Garner
 
5
 *
 
6
 * This file is part of Xibo.
 
7
 *
 
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
 
11
 * any later version.
 
12
 *
 
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.
 
17
 *
 
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/>.
 
20
 */
 
21
use Xibo\Helper\Log;
 
22
 
 
23
defined('XIBO') or die("Sorry, you are not allowed to directly access this page.<br /> Please press the back button in your browser.");
 
24
 
 
25
class Maintenance extends Data
 
26
{
 
27
    /**
 
28
     * Backup the Database
 
29
     * @param <string> $saveAs file|string
 
30
     */
 
31
    public function BackupDatabase($saveAs = "string")
 
32
    {
 
33
        // Check we can run mysql
 
34
        if (!function_exists('exec'))
 
35
            return $this->SetError(__('Exec is not available.'));
 
36
        
 
37
        // Global database variables to seed into exec
 
38
        global $dbhost;
 
39
        global $dbuser;
 
40
        global $dbpass;
 
41
        global $dbname;
 
42
 
 
43
        // get temporary file
 
44
        $fileNameStructure = Config::GetSetting('LIBRARY_LOCATION') . 'structure.dump';
 
45
        $fileNameData = Config::GetSetting('LIBRARY_LOCATION') . 'data.dump';
 
46
        $zipFile = 'database.tar.gz';
 
47
 
 
48
        // Run mysqldump structure to a temporary file
 
49
        $command = 'mysqldump --opt --host=' . $dbhost . ' --user=' . $dbuser . ' --password=' . addslashes($dbpass) . ' ' . $dbname . ' --no-data > ' . escapeshellarg($fileNameStructure) . ' ';
 
50
        exec($command);
 
51
        
 
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) . ' ';
 
54
        exec($command);
 
55
 
 
56
        // Check it worked
 
57
        if (!file_exists($fileNameStructure) || !file_exists($fileNameData))
 
58
            return $this->SetError(__('Database dump failed.'));
 
59
 
 
60
        // Zippy
 
61
        Log::Audit($zipFile);
 
62
        $zip = new ZipArchive();
 
63
        $zip->open($zipFile, ZIPARCHIVE::OVERWRITE);
 
64
        $zip->addFile($fileNameStructure, 'structure.dump');
 
65
        $zip->addFile($fileNameData, 'data.dump');
 
66
        $zip->close();
 
67
 
 
68
        // Remove the dump file
 
69
        unlink($fileNameStructure);
 
70
        unlink($fileNameData);
 
71
 
 
72
        // Uncomment only if you are having permission issues
 
73
        // chmod($zipFile, 0777);
 
74
 
 
75
        // Push file back to browser
 
76
        if (ini_get('zlib.output_compression')) {
 
77
            ini_set('zlib.output_compression', 'Off');
 
78
        }
 
79
 
 
80
        $size = filesize($zipFile);
 
81
 
 
82
        header('Content-Type: application/octet-stream');
 
83
        header("Content-Transfer-Encoding: Binary"); 
 
84
        header("Content-disposition: attachment; filename=\"" . basename($zipFile) . "\"");
 
85
 
 
86
        //Output a header
 
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);
 
91
        
 
92
        // Send via Apache X-Sendfile header?
 
93
        if (Config::GetSetting('SENDFILE_MODE') == 'Apache') {
 
94
            header("X-Sendfile: $zipFile");
 
95
            exit();
 
96
        }
 
97
        
 
98
        // Return the file with PHP
 
99
        // Disable any buffering to prevent OOM errors.
 
100
        @ob_end_clean();
 
101
        @ob_end_flush();
 
102
        readfile($zipFile);
 
103
 
 
104
        exit;
 
105
    }
 
106
 
 
107
    /**
 
108
     * Restore Database
 
109
     * @param <string> $fileName
 
110
     */
 
111
    public function RestoreDatabase($fileName)
 
112
    {
 
113
        global $dbhost;
 
114
        global $dbuser;
 
115
        global $dbpass;
 
116
        global $dbname;
 
117
        
 
118
        // Push the file into msqldump
 
119
        exec('mysql --user=' . $dbuser . ' --password=' . $dbpass . ' ' . $dbname . ' < ' . escapeshellarg($fileName) . ' ');
 
120
 
 
121
        Log::notice('mysql --user=' . $dbuser . ' --password=' . $dbpass . ' ' . $dbname . ' < ' . escapeshellarg($fileName) . ' ' );
 
122
 
 
123
        return true;
 
124
    }
 
125
 
 
126
    public function TidyLibrary($tidyOldRevisions, $cleanUnusedFiles)
 
127
    {
 
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();
 
132
 
 
133
        Log::Audit('Library Location: ' . $library);
 
134
 
 
135
        // Dump the files in the temp folder
 
136
        foreach (scandir($library . 'temp') as $item) {
 
137
            if ($item == '.' || $item == '..')
 
138
                continue;
 
139
 
 
140
            Log::Audit('Deleting temp file: ' . $item);
 
141
 
 
142
            unlink($library . 'temp' . DIRECTORY_SEPARATOR . $item);
 
143
        }
 
144
 
 
145
        $media = array();
 
146
        $unusedMedia = array();
 
147
        $unusedRevisions = array();
 
148
 
 
149
        // Run a query to get an array containing all of the media in the library
 
150
        try {
 
151
            $dbh = \Xibo\Storage\PDOConnect::init();
 
152
        
 
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
 
157
                  FROM `media`
 
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 ');
 
163
 
 
164
            $sth->execute(array());
 
165
 
 
166
            foreach ($sth->fetchAll() as $row) {
 
167
                $media[$row['storedAs']] = $row;
 
168
 
 
169
                // Ignore any module files or fonts
 
170
                if ($row['type'] == 'module' || $row['type'] == 'font')
 
171
                    continue;
 
172
                
 
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;
 
176
                }
 
177
                // Collect any files that aren't used
 
178
                else if ($cleanUnusedFiles && $row['UsedInLayoutCount'] <= 0 && $row['UsedInDisplayCount'] <= 0) {
 
179
                    $unusedMedia[$row['storedAs']] = $row;
 
180
                }
 
181
            }
 
182
        }
 
183
        catch (Exception $e) {
 
184
            
 
185
            Log::error($e->getMessage());
 
186
        
 
187
            if (!$this->IsError())
 
188
                $this->SetError(1, __('Unknown Error'));
 
189
        
 
190
            return false;
 
191
        }
 
192
 
 
193
        //Debug::Audit(var_export($media, true));
 
194
        //Debug::Audit(var_export($unusedMedia, true));
 
195
 
 
196
        // Get a list of all media files
 
197
        foreach(scandir($library) as $file) {
 
198
 
 
199
            if ($file == '.' || $file == '..')
 
200
                continue;
 
201
 
 
202
            if (is_dir($library . $file))
 
203
                continue;
 
204
 
 
205
            // Ignore thumbnails
 
206
            if (strstr($file, 'tn_') || strstr($file, 'bg_'))
 
207
                continue;
 
208
            
 
209
            // Is this file in the system anywhere?
 
210
            if (!array_key_exists($file, $media)) {
 
211
                // Totally missing
 
212
                Log::Audit('Deleting file: ' . $file);
 
213
                
 
214
                // If not, delete it
 
215
                $mediaObject->DeleteMediaFile($file);
 
216
            }
 
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']);
 
221
            }
 
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']);
 
226
            }
 
227
        }
 
228
 
 
229
        return true;
 
230
    }
 
231
}