Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * A report to display the all backup files on the site.
19
 *
20
 * @package    report_allbackups
21
 * @copyright  2020 Catalyst IT
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
use ZipStream\Option\Archive;
25
use ZipStream\ZipStream;
26
 
27
require_once('../../config.php');
28
require_once($CFG->libdir . '/adminlib.php');
29
 
30
$delete = optional_param('delete', '', PARAM_TEXT);
31
$filename = optional_param('filename', '', PARAM_TEXT);
32
$deleteselected = optional_param('deleteselectedfiles', '', PARAM_TEXT);
33
$downloadselected = optional_param('downloadallselectedfiles', '', PARAM_TEXT);
34
$fileids = optional_param('fileids', '', PARAM_TEXT);
35
$currenttab = optional_param('tab', 'core', PARAM_TEXT);
36
 
37
admin_externalpage_setup('reportallbackups', '', array('tab' => $currenttab), '', array('pagelayout' => 'report'));
38
 
39
$backupdest = get_config('backup', 'backup_auto_destination');
40
if (empty($backupdest) && $currenttab == 'autobackup') {
41
    throw new moodle_exception("autobackupnotset", "report_allbackups");
42
}
43
 
44
$context = context_system::instance();
45
if (has_capability('report/allbackups:delete', $context)) {
46
 
47
    if (!empty($deleteselected) || !empty($delete)) { // Delete action.
48
 
49
        if (empty($fileids)) {
50
            $fileids = array();
51
            // First time form submit - get list of ids from checkboxes or from single delete action.
52
            if (!empty($delete)) {
53
                // This is a single delete action.
54
                $fileids[] = $delete;
55
            } else {
56
                // Get list of ids from checkboxes.
57
                $post = data_submitted();
58
                if ($currenttab == "autobackup") {
59
                    foreach ($post as $k => $v) {
60
                        if (preg_match('/^item(.*)/', $k, $m)) {
61
                            $fileids[] = $v; // Use value (filename) in array.
62
                        }
63
                    }
64
                } else {
65
                    foreach ($post as $k => $v) {
66
                        if (preg_match('/^item(\d+)$/', $k, $m)) {
67
                            $fileids[] = $m[1];
68
                        }
69
                    }
70
                }
71
            }
72
            // Display confirmation box - are you really sure you want to delete this file?
73
            echo $OUTPUT->header();
74
            $params = array('deleteselectedfiles' => 1, 'confirm' => 1, 'fileids' => implode(',', $fileids), 'tab' => $currenttab);
75
            $deleteurl = new moodle_url($PAGE->url, $params);
76
            $numfiles = count($fileids);
77
            echo $OUTPUT->confirm(get_string('areyousurebulk', 'report_allbackups', $numfiles),
78
                $deleteurl, $CFG->wwwroot . '/report/allbackups/index.php');
79
 
80
            echo $OUTPUT->footer();
81
            exit;
82
        } else if (optional_param('confirm', false, PARAM_BOOL) && confirm_sesskey()) {
83
            $count = 0;
84
            $fileids = explode(',', $fileids);
85
            foreach ($fileids as $id) {
86
                if ($currenttab == 'autobackup') {
87
                    // Check nothing weird passed in filename - protect against directory traversal etc.
88
                    // Check to make sure this is an mbz file.
89
                    if ($id == clean_param($id, PARAM_FILE) &&
90
                        pathinfo($id, PATHINFO_EXTENSION) == 'mbz' &&
91
                        is_readable($backupdest .'/'. $id)) {
92
                        unlink($backupdest .'/'. $id);
93
                        $event = \report_allbackups\event\autobackup_deleted::create(array(
94
                            'context' => context_system::instance(),
95
                            'objectid' => null,
96
                            'other' => array('filename' => $id)));
97
                        $event->trigger();
98
                        $count++;
99
                    } else {
100
                        \core\notification::add(get_string('couldnotdeletefile', 'report_allbackups', $id));
101
                    }
102
                } else {
103
                    $fs = new file_storage();
104
                    $file = $fs->get_file_by_id((int)$id);
105
                    $fileext = pathinfo($file->get_filename(), PATHINFO_EXTENSION);
106
                    // Make sure the file exists, and it is a backup file we are deleting.
107
                    if (!empty($file) && $fileext == 'mbz') {
108
                        $file->delete();
109
                        $event = \report_allbackups\event\backup_deleted::create(array(
110
                            'context' => context::instance_by_id($file->get_contextid()),
111
                            'objectid' => $file->get_id(),
112
                            'other' => array('filename' => $file->get_filename())));
113
                        $event->trigger();
114
                        $count++;
115
                    } else {
116
                        \core\notification::add(get_string('couldnotdeletefile', 'report_allbackups', $id));
117
                    }
118
 
119
                }
120
            }
121
            \core\notification::add(get_string('filesdeleted', 'report_allbackups', $count), \core\notification::SUCCESS);
122
        }
123
    }
124
}
125
 
126
// Triggers when "Download all select files" is clicked.
127
if (!empty($downloadselected) && confirm_sesskey()) {
128
    if (empty($fileids)) {
129
 
130
        $fileids = array();
131
        // Raise memory limit - each file is loaded in PHP memory, so this much be larger than the largest backup file.
132
        raise_memory_limit(MEMORY_HUGE);
133
 
134
        // Initialize zip for saving multiple selected files at once.
135
        $options = new Archive();
136
        $options->setSendHttpHeaders(true);
137
        $zip = new ZipStream('all_backups.zip', $options);
138
 
139
        // Get list of ids from the checked checkboxes.
140
        $post = data_submitted();
141
 
142
        if ($currenttab == 'autobackup') {
143
            // Get list of names from the checked backups.
144
            foreach ($post as $k => $v) {
145
                if (preg_match('/^item(.*)/', $k, $m)) {
146
                    $fileids[] = $v; // Use value (filename) in array.
147
                }
148
            }
149
 
150
            // Check nothing weird passed in filename - protect against directory traversal etc.
151
            // Check to make sure this is an mbz file.
152
            foreach ($fileids as $filename) {
153
 
154
                if ($filename == clean_param($filename, PARAM_FILE) &&
155
                    pathinfo($filename, PATHINFO_EXTENSION) == 'mbz' &&
156
                    is_readable($backupdest .'/'. $filename)) {
157
 
158
                        $file = $backupdest.'/'.$filename;
159
                        $filecontents = file_get_contents($file, FILE_USE_INCLUDE_PATH);
160
                        $zip->addFile($filename, $filecontents);
161
                } else {
162
                    \core\notification::add(get_string('couldnotdownloadfile', 'report_allbackups'));
163
                }
164
            }
165
        } else {
166
            // Get list of ids from the checked backups.
167
            foreach ($post as $k => $v) {
168
                if (preg_match('/^item(\d+)$/', $k, $m)) {
169
                    $fileids[] = $m[1];
170
                }
171
            }
172
 
173
            // Check nothing weird passed in filename - protect against directory traversal etc.
174
            // Check to make sure this is an mbz file.
175
            foreach ($fileids as $id) {
176
 
177
                // Translate the file id into file name / contents.
178
                $fs = new file_storage();
179
                $file = $fs->get_file_by_id((int)$id);
180
                $fileext = pathinfo($file->get_filename(), PATHINFO_EXTENSION);
181
 
182
                // Make sure the file exists, and it is a backup file we are downloading.
183
                if (!empty($file) && $fileext == 'mbz') {
184
                    $zip->addFile($file->get_filename(), $file->get_content());
185
                } else {
186
                    \core\notification::add(get_string('couldnotdownloadfile', 'report_allbackups'));
187
                }
188
            }
189
        }
190
        $zip->finish();
191
        exit;
192
    }
193
}
194
 
195
if ($currenttab == 'autobackup') {
196
    $filters = array('filename' => 0, 'timecreated' => 0);
197
} else {
198
    $filters = array('filename' => 0, 'realname' => 0, 'coursecategory' => 0, 'filearea' => 0, 'timecreated' => 0);
199
}
200
if ($currenttab == 'autobackup') {
201
    $table = new \report_allbackups\output\autobackups_table('autobackups');
202
} else {
203
    $table = new \report_allbackups\output\allbackups_table('allbackups');
204
    $table->define_baseurl($PAGE->url);
205
}
206
 
207
$ufiltering = new \report_allbackups\output\filtering($filters, $PAGE->url);
208
if (!$table->is_downloading()) {
209
    // Only print headers if not asked to download data
210
    // Print the page header.
211
    $PAGE->set_title(get_string('pluginname', 'report_allbackups'));
212
    echo $OUTPUT->header();
213
    if (!empty(get_config('backup', 'backup_auto_destination'))) {
214
        $row = $tabs = array();
215
        $row[] = new tabobject('core',
216
            $CFG->wwwroot.'/report/allbackups',
217
            get_string('standardbackups', 'report_allbackups'));
218
        $row[] = new tabobject('autobackup',
219
            $CFG->wwwroot.'/report/allbackups/index.php?tab=autobackup',
220
            get_string('autobackup', 'report_allbackups'));
221
        $tabs[] = $row;
222
        print_tabs($tabs, $currenttab);
223
    }
224
    if ($currenttab == 'autobackup') {
225
        echo $OUTPUT->box(get_string('autobackup_description', 'report_allbackups'));
226
    } else {
227
        echo $OUTPUT->box(get_string('plugindescription', 'report_allbackups'));
228
    }
229
    $ufiltering->display_add();
230
    $ufiltering->display_active();
231
 
232
    echo '<form action="index.php" method="post" id="allbackupsform">';
233
    echo html_writer::start_div();
234
    echo html_writer::tag('input', '', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
235
    echo html_writer::tag('input', '', array('type' => 'hidden', 'name' => 'returnto', 'value' => s($PAGE->url->out(false))));
236
    echo html_writer::tag('input', '', array('type' => 'hidden', 'name' => 'tab', 'value' => $currenttab));
237
} else {
238
    // Trigger downloaded event.
239
    $event = \report_allbackups\event\report_downloaded::create();
240
    $event->trigger();
241
}
242
if ($currenttab == 'autobackup') {
243
    // Get list of files from backup.
244
    $table->adddata($ufiltering);
245
} else {
246
    list($extrasql, $params) = $ufiltering->get_sql_filter();
247
    $fields = 'f.id, f.contextid, f.component, f.filearea, f.filename, f.userid, f.filesize, f.timecreated, f.filepath, f.itemid';
248
    $fields .= \core_user\fields::for_name()->get_sql('u')->selects;
249
 
250
    $from = '{files} f JOIN {user} u on u.id = f.userid';
251
    if (strpos($extrasql, 'c.category') !== false) {
252
        // Category filter included, Join with course table.
253
        $from .= ' JOIN {context} cx ON cx.id = f.contextid AND cx.contextlevel = '.CONTEXT_COURSE .
254
                 ' JOIN {course} c ON c.id = cx.instanceid';
255
    }
256
    $where = "f.filename like '%.mbz' and f.component <> 'tool_recyclebin' and f.filearea <> 'draft'";
257
    if (!empty($extrasql)) {
258
        $where .= " and ".$extrasql;
259
    }
260
 
261
    $table->set_sql($fields, $from, $where, $params);
262
    $table->out(40, true);
263
}
264
 
265
if (!$table->is_downloading()) {
266
 
267
    echo html_writer::tag('input', "", array('name' => 'deleteselectedfiles', 'type' => 'submit',
268
        'id' => 'deleteallselected', 'class' => 'btn btn-secondary',
269
        'value' => get_string('deleteselectedfiles', 'report_allbackups')));
270
    echo html_writer::tag('input', "", array('name' => 'downloadallselectedfiles', 'style' => 'margin: 10px', 'type' => 'submit',
271
        'id' => 'downloadallselected', 'class' => 'btn btn-secondary',
272
        'value' => get_string('downloadallselectedfiles', 'report_allbackups')));
273
 
274
    echo html_writer::end_div();
275
    echo html_writer::end_tag('form');
276
    $event = \report_allbackups\event\report_viewed::create();
277
    $event->trigger();
278
    echo $OUTPUT->footer();
279
}