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
 * Auto backups table.
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
 
25
namespace report_allbackups\output;
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
use moodle_url, html_writer, context_system, RecursiveDirectoryIterator, RecursiveIteratorIterator;
30
 
31
require_once($CFG->libdir . '/tablelib.php');
32
 
33
/**
34
 * Table to display automated backups stored on disk.
35
 *
36
 * @package    report_allbackups
37
 * @copyright  2020 Catalyst IT
38
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39
 */
40
class autobackups_table extends \flexible_table {
41
    /**
42
     * autobackups_table constructor.
43
     *
44
     * @param string $uniqueid
45
     * @throws \coding_exception
46
     */
47
    public function __construct($uniqueid) {
48
        global $PAGE, $OUTPUT;
49
        parent::__construct($uniqueid);
50
        $url = $PAGE->url;
51
        $url->param('tab', 'autobackup');
52
        $this->define_baseurl($url);
53
        $this->pageable(true);
54
        if (!optional_param('downloadallselectedfiles', 0, PARAM_ALPHA)) {
55
            // Set Download flag so we can check it before defining columns/headers to show.
56
            // Don't set if downloading files.
57
            $this->is_downloading(optional_param('download', '', PARAM_ALPHA), 'allbackups');
58
        }
59
 
60
        // Define the list of columns to show.
61
        $columns = array();
62
        $headers = array();
63
 
64
        // Add selector column if not downloading report.
65
        if (!$this->is_downloading()) {
66
            // Add selector column to report.
67
            $columns[] = 'selector';
68
 
69
            $options = [
70
                'id' => 'check-items',
71
                'name' => 'check-items',
72
                'value' => 1,
73
            ];
74
            $mastercheckbox = new \core\output\checkbox_toggleall('items', true, $options);
75
 
76
            $headers[] = $OUTPUT->render($mastercheckbox);
77
        }
78
        $columns = array_merge($columns, array('filename', 'size', 'timemodified'));
79
        $headers = array_merge($headers, array(get_string('name'), get_string('size'), get_string('date')));
80
 
81
        // Add actions column if not downloading this report.
82
        if (!$this->is_downloading()) {
83
            array_push($columns, 'action');
84
            array_push($headers, get_string('action'));
85
        }
86
 
87
        $this->define_columns($columns);
88
        $this->define_headers($headers);
89
        $this->sortable(true);
90
        $this->no_sorting('action');
91
        $this->no_sorting('selector');
92
        $this->setup();
93
    }
94
 
95
    /**
96
     * Helper function to add data to table.
97
     * Implements custom sort/pagination as we don't use sql to build this table.
98
     *
99
     * @throws \dml_exception
100
     */
101
    public function adddata() {
102
        global $SESSION;
103
 
104
        $rows = array();
105
        $backupdest = get_config('backup', 'backup_auto_destination');
106
        $directory = new RecursiveDirectoryIterator($backupdest);
107
        $iterator = new RecursiveIteratorIterator($directory);
108
 
109
        foreach ($iterator as $file) {
110
            // Sanity check and only include .mbz files.
111
            if ($file->isFile() && $file->getExtension() == 'mbz') {
112
                $filename = $file->getFilename();
113
 
114
                // Check against filename filters.
115
                if (!$this->filter_filename($filename)) {
116
                    continue;
117
                }
118
                $row = new \stdClass();
119
                $row->filename = $filename;
120
                $row->timemodified = $file->getMTime();
121
                $row->size = $file->getSize();
122
 
123
                // Check against timemodified filters.
124
                if (!$this->filter_timemodified($row->timemodified)) {
125
                    continue;
126
                }
127
 
128
                $rows[] = $row;
129
            }
130
        }
131
        // Sort based on fields.
132
        $tsort = optional_param('tsort', '', PARAM_TEXT);
133
        $tdir = optional_param('tdir', 0, PARAM_INT);
134
        if (!empty($tsort) && array_key_exists($tsort, $this->get_sort_columns())) {
135
            $sort = array_column($rows, $tsort);
136
            array_multisort($sort, $tdir, $rows);
137
        }
138
 
139
        $this->totalrows = count($rows);
140
 
141
        if (!$this->is_downloading()) {
142
            // Only add rows that we want based on page.
143
            $rowstoprint = array_slice($rows, $this->get_page_start(), $this->get_page_size());
144
        } else {
145
            $rowstoprint = $rows;
146
        }
147
        $this->format_and_add_array_of_rows($rowstoprint);
148
    }
149
 
150
    /**
151
     * Display action row.
152
     *
153
     * @param \stdClass $row
154
     * @return string
155
     */
156
    public function col_action($row) {
157
        global $USER;
158
        $context = \context_system::instance();
159
        $fileurl = moodle_url::make_pluginfile_url(
160
            $context->id,
161
            'report_allbackups',
162
            'autobackups',
163
            null,
164
            '/',
165
            $row->filename,
166
            true
167
        );
168
        $output = \html_writer::link($fileurl, get_string('download'));
169
 
170
        if (has_capability('moodle/restore:restorecourse', $context)) {
171
            $params = array();
172
            $params['filename'] = $row->filename;
173
            $restoreurl = new moodle_url('/report/allbackups/restorehandler.php', $params);
174
 
175
            $output .= ' | '. html_writer::link($restoreurl, get_string('restore'));
176
        }
177
 
178
        if (has_capability('report/allbackups:delete', $context)) {
179
            $params = array('delete' => $row->filename, 'filename' => $row->filename, 'tab' => 'autobackup');
180
            $deleteurl = new moodle_url('/report/allbackups/index.php', $params);
181
            $output .= ' | '. html_writer::link($deleteurl, get_string('delete'));
182
        }
183
        return $output;
184
 
185
    }
186
 
187
    /**
188
     * Display size row.
189
     *
190
     * @param \stdClass $row
191
     * @return \lang_string|string
192
     */
193
    public function col_size($row) {
194
        return display_size($row->size);
195
    }
196
 
197
    /**
198
     * Display timemodified.
199
     *
200
     * @param \stdClass $row
201
     * @return string
202
     */
203
    public function col_timemodified($row) {
204
        return userdate($row->timemodified);
205
    }
206
 
207
    /**
208
     * Function to display the checkbox for bulk actions.
209
     *
210
     * @param \stdClass $row the data from the db containing all fields from the current row.
211
     * @return string
212
     */
213
    public function col_selector($row) {
214
        global $OUTPUT;
215
        if ($this->is_downloading()) {
216
            return '';
217
        }
218
        $options = [
219
            'id' => 'item'.$row->filename,
220
            'name' => 'item'.$row->filename,
221
            'value' => $row->filename,
222
        ];
223
        $itemcheckbox = new \core\output\checkbox_toggleall('items', false, $options);
224
        return $OUTPUT->render($itemcheckbox);
225
    }
226
 
227
 
228
    /**
229
     * Function to filter results using the filename.
230
     *
231
     * @param string $filename
232
     * @return bool|int
233
     */
234
    private function filter_filename($filename) {
235
        global $SESSION;
236
        $found = true;
237
 
238
        if (!empty($SESSION->user_filtering['filename'])) {
239
            foreach ($SESSION->user_filtering['filename'] as $filter) {
240
                $found = $this->filter_filename_helper($filter['operator'], $filter['value'], $filename);
241
            }
242
        }
243
        return $found;
244
    }
245
 
246
    /**
247
     * Helper function to select appropriate regex for filter.
248
     *
249
     * @param string $operator
250
     * @param string $value
251
     * @param string $filename
252
     * @return false|int
253
     */
254
    private function filter_filename_helper($operator, $value, $filename) {
255
        // Filter rows based on any filters set.
256
        switch ($operator) {
257
            case 0: // Contains.
258
                $regex = "/" . $value . "/";
259
                break;
260
            case 1: // Does not contain.
261
                $regex = "/^((?!" . $value . ").)*$/";
262
                break;
263
            case 2: // Equal to.
264
                $regex = "/^" . $value . "$/";
265
                break;
266
            case 3: // Starts with.
267
                $regex = "/^" . $value . "/";
268
                break;
269
            case 4: // Ends with.
270
                $regex = "/" . $value . "$/";
271
                break;
272
            case 5: // Empty.
273
                $regex = "/^$/";
274
                break;
275
        }
276
        return preg_match($regex, $filename);
277
    }
278
 
279
    /**
280
     * Filter for timemodified.
281
     *
282
     * @param int $timemodified
283
     * @return bool
284
     */
285
    private function filter_timemodified($timemodified) {
286
        global $SESSION;
287
        $found = true;
288
        if (!empty($SESSION->user_filtering['timecreated'])) {
289
            foreach ($SESSION->user_filtering['timecreated'] as $filter) {
290
                $found = $this->filter_timemodified_helper($filter['before'], $filter['after'], $timemodified);
291
            }
292
        }
293
 
294
        return $found;
295
    }
296
 
297
    /**
298
     * Helper function for filter_timemodified.
299
     *
300
     * @param int $before
301
     * @param int $after
302
     * @param int $timemodified
303
     * @return bool
304
     */
305
    private function filter_timemodified_helper($before, $after, $timemodified) {
306
        $found = true;
307
        if (!empty($before)) { // Only if the before value is not empty.
308
            if ($before < $timemodified) {
309
                $found = false;
310
            }
311
        }
312
        if (!empty($after)) {
313
            if ($after > $timemodified) {
314
                $found = false;
315
            }
316
        }
317
        return $found;
318
    }
319
}