-
Notifications
You must be signed in to change notification settings - Fork 148
/
textdownload.php
128 lines (109 loc) · 4.52 KB
/
textdownload.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php
// This file is part of Stack - http://stack.maths.ed.ac.uk/
//
// Stack is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Stack is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Stack. If not, see <http://www.gnu.org/licenses/>.
/**
* This script serves text files generated on demand by rendering CASText
* of a given question with a given seed. For generated data transfer needs.
*
* @copyright 2021 Aalto University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../../config.php');
require_once(__DIR__ . '/vle_specific.php');
global $CFG;
require_once($CFG->libdir . '/questionlib.php');
require_login();
// Start by checking that we have what we need.
if (!(isset($_GET['qaid']) && isset($_GET['id']) && isset($_GET['name']))) {
header('HTTP/1.0 404 Not Found');
header('Content-Type: text/plain;charset=UTF-8');
echo 'Incomplete request';
die();
}
// Extract the details we need for this action.
$qaid = $_GET['qaid'];
$tdid = $_GET['id'];
$name = $_GET['name'];
// Check that they are of the correct type.
if (!is_numeric($qaid) || !is_numeric($tdid)) {
header('HTTP/1.0 404 Not Found');
header('Content-Type: text/plain;charset=UTF-8');
echo 'Incomplete request';
die();
}
// So what we are doing is that we need to instanttiate the question
// of that attempt to have correct seed and then we need to render
// that specific td-file and serve it out with a specific name.
$dm = new question_engine_data_mapper();
$qa = $dm->load_question_attempt($qaid);
$question = $qa->get_question();
$question->apply_attempt_state($qa->get_step(0));
// We have a slight problem accessing the user connected to that attempt and
// therefore this will only work with `quiz` type activities for now.
$params = [$qa->get_usage_id(), 'mod_quiz'];
$tmp = $DB->get_record_sql('SELECT qas.userid FROM {quiz_attempts} qas, {question_usages} qu ' .
'WHERE qu.id = ? AND qu.component = ? AND qu.id = qas.uniqueid;', $params, IGNORE_MISSING);
$usageuser = -1;
if ($tmp !== false) {
$usageuser = $tmp->userid;
}
if (!(stack_user_can_view_question($question) || $USER->id === $usageuser)) {
header('HTTP/1.0 403 Forbidden');
header('Content-Type: text/plain;charset=UTF-8');
echo 'This question is not accessible for the active user';
die();
}
// Unlock session during instantiation.
\core\session\manager::write_close();
// Make sure that the cache is good, as this is one of those places where
// the identifier for the cached item comes from outside and we cannot
// cannot directly ask for it as that would allow people to force the cache
// to be regenerated.
// This will generate the cache if it is missing, which is highly unlikely.
$question->get_cached('units');
if (!isset($question->compiledcache['castext-td-' . $tdid])) {
header('HTTP/1.0 404 Not Found');
header('Content-Type: text/plain;charset=UTF-8');
echo 'No such textdownload object in this question';
die();
}
require_once(__DIR__ . '/stack/cas/castext2/castext2_evaluatable.class.php');
$ct = castext2_evaluatable::make_from_compiled($question->compiledcache['castext-td-' .
$tdid], $name, new castext2_static_replacer($question->get_cached('static-castext-strings')));
// Get the context from the question.
$ses = new stack_cas_session2([], $question->options, $question->seed);
$question->add_question_vars_to_session($ses);
$ses->add_statement($ct);
// Is it valid?
if (!$ses->get_valid()) {
header('HTTP/1.0 500 Internal Server Error');
header('Content-Type: text/plain;charset=UTF-8');
echo 'Unknown issue related to the generation of this data.';
die();
}
// Render it.
$ses->instantiate();
$content = $ct->get_rendered();
// It might in theory use the holder.
$content = $ct->apply_placeholder_holder($content);
// Now pick some sensible headers.
header('HTTP/1.0 200 OK');
header("Content-Disposition: attachment; filename=\"$name\"");
if (strripos($name, '.csv') === strlen($name) - 4) {
header('Content-Type: text/csv;charset=UTF-8');
} else {
header('Content-Type: text/plain;charset=UTF-8');
}
echo($content);