Skip to content

Commit 7c1347a

Browse files
committed
wip
1 parent 4c78586 commit 7c1347a

File tree

5 files changed

+66
-5
lines changed

5 files changed

+66
-5
lines changed

classes/constants.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class constants {
3636
public const QT_VAR_SCORING_STATE = '_scoringstate';
3737
/** @var string */
3838
public const QT_VAR_RESPONSE = 'qpy_response';
39+
/** @var string */
40+
public const QT_VAR_DRAFT_AREAS = 'qpy_draft_areas';
3941

4042
/** @var string */
4143
public const QPY_OPTIONS_URL_PATTERN = ';qpy://options/(?P<fileref>[a-zA-Z0-9\-_=]{1,64});';

classes/local/attempt_ui/question_ui_renderer.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
namespace qtype_questionpy\local\attempt_ui;
1818

1919
use coding_exception;
20+
use context;
2021
use core\di;
2122
use DOMAttr;
2223
use DOMDocument;
@@ -26,6 +27,7 @@
2627
use DOMProcessingInstruction;
2728
use DOMText;
2829
use DOMXPath;
30+
use form_filemanager;
2931
use moodle_exception;
3032
use qtype_questionpy\constants;
3133
use qtype_questionpy\local\files\qpy_url_resolver;
@@ -49,6 +51,9 @@ class question_ui_renderer {
4951
/** @var string $html resulting rendered html */
5052
public string $html;
5153

54+
/** @var array<string, int> Mapping of input names to draft item ids. */
55+
public array $draftareas = [];
56+
5257
/** @var invalid_option_warning[] $warnings warnings emitted during rendering */
5358
public array $warnings;
5459

@@ -152,10 +157,45 @@ public static function render(string $xml, array $placeholders, question_display
152157

153158
$warnings = $renderer->check_for_and_preserve_unknown_options($availableoptions, $attempt);
154159
$renderer->html = $renderer->xml->saveHTML();
160+
$renderer->html .= $renderer->render_file_manager($attempt, $question);
155161
$renderer->warnings = $warnings;
156162
return $renderer;
157163
}
158164

165+
/**
166+
* @throws moodle_exception
167+
* @throws coding_exception
168+
*/
169+
private function render_file_manager(question_attempt $attempt, qtype_questionpy_question $question): string {
170+
global $CFG, $PAGE;
171+
require_once($CFG->libdir . '/form/filemanager.php');
172+
173+
$context = context::instance_by_id($question->contextid);
174+
175+
$draftitemid = $attempt->prepare_response_files_draft_itemid('banana', $context->id);
176+
177+
// Adding a hidden input here that holds the draftarea would require us to separate it from the "proper" form data later on.
178+
// Instead, we save the draft area for.
179+
$this->draftareas['myupload'] = $draftitemid;
180+
181+
$id = uniqid();
182+
183+
$fm = new form_filemanager((object)[
184+
'itemid' => $draftitemid,
185+
'subdirs' => false,
186+
'context' => $context,
187+
'maxfiles' => 1,
188+
'maxbytes' => 1024 * 1024,
189+
'areamaxbytes' => 2 * 1024 * 1024,
190+
'clientid' => $id,
191+
]);
192+
193+
$filesrenderer = $PAGE->get_renderer('core', 'files');
194+
$html = $filesrenderer->render($fm);
195+
196+
return $html;
197+
}
198+
159199
/**
160200
* Hides elements marked with `qpy:feedback` if the type of feedback is disabled in {@see question_display_options}
161201
* or if it does not exist.

question.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ private function get_behaviour(): qbehaviour_questionpy {
235235
public function get_expected_data(): array|string {
236236
return [
237237
constants::QT_VAR_RESPONSE => PARAM_RAW_TRIMMED,
238+
constants::QT_VAR_DRAFT_AREAS => PARAM_RAW_TRIMMED,
238239
];
239240
}
240241

renderer.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,16 @@ public function formulation_and_controls(question_attempt $qa, question_display_
8383
}
8484

8585
try {
86+
/** @var array<string, int>|null $uploaddraftareas */
87+
$uploaddraftareas = null;
88+
8689
$questiondivid = $qa->get_outer_question_div_unique_id();
8790
$qpyresponseid = $questiondivid . '-qpy-response';
88-
$formulationcb = function (qtype_questionpy_renderer $renderer) use ($qa, $question, $options, $qpyresponseid) {
89-
return $renderer->formulation_controls_feedback_in_iframe($qa, $question->ui, $options, $qpyresponseid);
91+
$formulationcb = function (qtype_questionpy_renderer $renderer) use ($qa, $question, $options, $qpyresponseid, &$uploaddraftareas) {
92+
$quirenderer = question_ui_renderer::render($question->ui->formulation, $question->ui->placeholders, $options, $qa);
93+
$uploaddraftareas = $quirenderer->draftareas;
94+
95+
return $renderer->formulation_controls_feedback_in_iframe($qa, $question->ui, $quirenderer, $options, $qpyresponseid);
9096
};
9197
$iframesrc = $this->get_iframe_document($options->context, $question, $formulationcb);
9298

@@ -125,6 +131,17 @@ public function formulation_and_controls(question_attempt $qa, question_display_
125131
<iframe id="{$iframeid}" srcdoc="{$iframesrc}"></iframe>
126132
EOA;
127133

134+
if ($uploaddraftareas === null) {
135+
throw new coding_exception('$uploaddraftareas was not set');
136+
}
137+
if (count($uploaddraftareas) > 0) {
138+
$result .= html_writer::empty_tag('input', [
139+
'type' => 'hidden',
140+
'name' => $qa->get_field_prefix() . constants::QT_VAR_DRAFT_AREAS,
141+
'value' => json_encode($uploaddraftareas, JSON_FORCE_OBJECT),
142+
]);
143+
}
144+
128145
return $result;
129146
} catch (Throwable $t) {
130147
global $USER;
@@ -220,13 +237,11 @@ protected function get_iframe_document(context $context, qtype_questionpy_questi
220237
* @throws moodle_exception
221238
*/
222239
protected function formulation_controls_feedback_in_iframe(
223-
question_attempt $qa, attempt_ui $ui,
240+
question_attempt $qa, attempt_ui $ui, question_ui_renderer $renderer,
224241
question_display_options $options, string $qpyresponseid
225242
): string {
226243
global $CFG;
227244

228-
$renderer = question_ui_renderer::render($ui->formulation, $ui->placeholders, $options, $qa);
229-
230245
$warningshtml = '';
231246
if ($renderer->warnings) {
232247
global $USER;

styles.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
padding: 0;
3131
width: 100%;
3232
height: 0;
33+
/* TODO: Only set the min-height when the question uses a file picker and figure out the correct height.
34+
(The current value is arbitrary.) */
35+
min-height: 700px;
3336
display: block; /* Remove space that is reserved below inline elements for descender characters (y, q, g). */
3437
}
3538

0 commit comments

Comments
 (0)