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
 * Save and load draft text while a user is still editing a form.
19
 *
20
 * @package    editor_atto
21
 * @copyright  2014 Damyon Wiese
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
define('AJAX_SCRIPT', true);
26
 
27
require_once(__DIR__ . '/../../../config.php');
28
require_once($CFG->libdir . '/filestorage/file_storage.php');
29
 
30
// Clean up actions.
31
$actions = array_map(function($actionparams) {
32
    $action = isset($actionparams['action']) ? $actionparams['action'] : null;
33
    $params = [];
34
    $keys = [
35
        'action' => PARAM_ALPHA,
36
        'contextid' => PARAM_INT,
37
        'elementid' => PARAM_ALPHANUMEXT,
38
        'pagehash' => PARAM_ALPHANUMEXT,
39
        'pageinstance' => PARAM_ALPHANUMEXT
40
    ];
41
 
42
    if ($action == 'save') {
43
        $keys['drafttext'] = PARAM_RAW;
44
    } else if ($action == 'resume') {
45
        $keys['draftid'] = PARAM_INT;
46
    }
47
 
48
    foreach ($keys as $key => $type) {
49
        // Replicate required_param().
50
        if (!isset($actionparams[$key])) {
51
            throw new \moodle_exception('missingparam', '', '', $key);
52
        }
53
        $params[$key] = clean_param($actionparams[$key], $type);
54
    }
55
 
56
    return $params;
57
}, isset($_REQUEST['actions']) ? $_REQUEST['actions'] : []);
58
 
59
$now = time();
60
// This is the oldest time any autosave text will be recovered from.
61
// This is so that there is a good chance the draft files will still exist (there are many variables so
62
// this is impossible to guarantee).
63
$before = $now - 60*60*24*4;
64
 
65
$context = context_system::instance();
66
$PAGE->set_url('/lib/editor/atto/autosave-ajax.php');
67
$PAGE->set_context($context);
68
 
69
require_login();
70
if (isguestuser()) {
71
    throw new \moodle_exception('accessdenied', 'admin');
72
}
73
require_sesskey();
74
 
75
if (!in_array('atto', explode(',', get_config('core', 'texteditors')))) {
76
    throw new \moodle_exception('accessdenied', 'admin');
77
}
78
 
79
$responses = array();
80
foreach ($actions as $actionparams) {
81
 
82
    $action = $actionparams['action'];
83
    $contextid = $actionparams['contextid'];
84
    $elementid = $actionparams['elementid'];
85
    $pagehash = $actionparams['pagehash'];
86
    $pageinstance = $actionparams['pageinstance'];
87
 
88
    if ($action === 'save') {
89
        $drafttext = $actionparams['drafttext'];
90
        $params = array('elementid' => $elementid,
91
                        'userid' => $USER->id,
92
                        'pagehash' => $pagehash,
93
                        'contextid' => $contextid);
94
 
95
        $record = $DB->get_record('editor_atto_autosave', $params);
96
        if ($record && $record->pageinstance != $pageinstance) {
97
            throw new \moodle_exception('concurrent access from the same user is not supported');
98
            die();
99
        }
100
 
101
        if (!$record) {
102
            $record = new stdClass();
103
            $record->elementid = $elementid;
104
            $record->userid = $USER->id;
105
            $record->pagehash = $pagehash;
106
            $record->contextid = $contextid;
107
            $record->drafttext = $drafttext;
108
            $record->pageinstance = $pageinstance;
109
            $record->timemodified = $now;
110
 
111
            $DB->insert_record('editor_atto_autosave', $record);
112
 
113
            // No response means no error.
114
            $responses[] = null;
115
            continue;
116
        } else {
117
            $record->drafttext = $drafttext;
118
            $record->timemodified = time();
119
            $DB->update_record('editor_atto_autosave', $record);
120
 
121
            // No response means no error.
122
            $responses[] = null;
123
            continue;
124
        }
125
 
126
    } else if ($action == 'resume') {
127
        $params = array('elementid' => $elementid,
128
                        'userid' => $USER->id,
129
                        'pagehash' => $pagehash,
130
                        'contextid' => $contextid);
131
 
132
        $newdraftid = $actionparams['draftid'];
133
 
134
        $record = $DB->get_record('editor_atto_autosave', $params);
135
 
136
        if (!$record) {
137
            $record = new stdClass();
138
            $record->elementid = $elementid;
139
            $record->userid = $USER->id;
140
            $record->pagehash = $pagehash;
141
            $record->contextid = $contextid;
142
            $record->pageinstance = $pageinstance;
143
            $record->pagehash = $pagehash;
144
            $record->draftid = $newdraftid;
145
            $record->timemodified = time();
146
            $record->drafttext = '';
147
 
148
            $DB->insert_record('editor_atto_autosave', $record);
149
 
150
            // No response means no error.
151
            $responses[] = null;
152
            continue;
153
 
154
        } else {
155
            // Copy all draft files from the old draft area.
156
            $usercontext = context_user::instance($USER->id);
157
            $stale = $record->timemodified < $before;
158
            require_once($CFG->libdir . '/filelib.php');
159
 
160
            $fs = get_file_storage();
161
            $files = $fs->get_directory_files($usercontext->id, 'user', 'draft', $newdraftid, '/', true, true);
162
 
163
            $lastfilemodified = 0;
164
            foreach ($files as $file) {
165
                $lastfilemodified = max($lastfilemodified, $file->get_timemodified());
166
            }
167
            if ($record->timemodified < $lastfilemodified) {
168
                $stale = true;
169
            }
170
 
171
            if (!$stale) {
172
                // This function copies all the files in one draft area, to another area (in this case it's
173
                // another draft area). It also rewrites the text to @@PLUGINFILE@@ links.
174
                $newdrafttext = file_save_draft_area_files($record->draftid,
175
                                                           $usercontext->id,
176
                                                           'user',
177
                                                           'draft',
178
                                                           $newdraftid,
179
                                                           array(),
180
                                                           $record->drafttext);
181
 
182
                // Final rewrite to the new draft area (convert the @@PLUGINFILES@@ again).
183
                $newdrafttext = file_rewrite_pluginfile_urls($newdrafttext,
184
                                                             'draftfile.php',
185
                                                             $usercontext->id,
186
                                                             'user',
187
                                                             'draft',
188
                                                             $newdraftid);
189
                $record->drafttext = $newdrafttext;
190
 
191
                $record->pageinstance = $pageinstance;
192
                $record->draftid = $newdraftid;
193
                $record->timemodified = time();
194
                $DB->update_record('editor_atto_autosave', $record);
195
 
196
                // A response means the draft has been restored and here is the auto-saved text.
197
                $response = ['result' => $record->drafttext];
198
                $responses[] = $response;
199
 
200
            } else {
201
                $DB->delete_records('editor_atto_autosave', array('id' => $record->id));
202
 
203
                // No response means no error.
204
                $responses[] = null;
205
            }
206
            continue;
207
        }
208
 
209
    } else if ($action == 'reset') {
210
        $params = array('elementid' => $elementid,
211
                        'userid' => $USER->id,
212
                        'pagehash' => $pagehash,
213
                        'contextid' => $contextid);
214
 
215
        $DB->delete_records('editor_atto_autosave', $params);
216
        $responses[] = null;
217
        continue;
218
    }
219
}
220
 
221
echo json_encode($responses);