Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | 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
 * Drag-and-drop onto image question renderer class.
19
 *
20
 * @package    qtype_ddimageortext
21
 * @copyright  2010 The Open University
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
 
26
defined('MOODLE_INTERNAL') || die();
27
 
28
/**
29
 * Generates the output for drag-and-drop onto image questions.
30
 *
31
 * @copyright  2010 The Open University
32
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33
 */
34
class qtype_ddtoimage_renderer_base extends qtype_with_combined_feedback_renderer {
35
 
36
    public function clear_wrong(question_attempt $qa) {
37
        $question = $qa->get_question();
38
        $response = $qa->get_last_qt_data();
39
 
40
        if (!empty($response)) {
41
            $cleanresponse = $question->clear_wrong_from_response($response);
42
        } else {
43
            $cleanresponse = $response;
44
        }
45
        $cleanresponsehtml = '';
46
        foreach ($cleanresponse as $fieldname => $value) {
47
            list (, $html) = $this->hidden_field_for_qt_var($qa, $fieldname, $value);
48
            $cleanresponsehtml .= $html;
49
        }
50
        return $cleanresponsehtml;
51
    }
52
 
53
    public function formulation_and_controls(question_attempt $qa,
54
            question_display_options $options) {
55
        $question = $qa->get_question();
56
        $response = $qa->get_last_qt_data();
57
 
58
        $questiontext = $question->format_questiontext($qa);
59
 
60
        $dropareaclass = 'droparea';
61
        $draghomesclass = 'draghomes';
1441 ariadna 62
        if ($question->dropzonevisibility) {
63
            $draghomesclass .= ' transparent';
64
            $dropareaclass .= ' transparent';
65
        }
1 efrain 66
        if ($options->readonly) {
67
            $dropareaclass .= ' readonly';
68
            $draghomesclass .= ' readonly';
69
        }
70
 
71
        $output = html_writer::div($questiontext, 'qtext');
72
 
73
        $output .= html_writer::start_div('ddarea');
74
        $output .= html_writer::start_div($dropareaclass);
75
        $output .= html_writer::img(self::get_url_for_image($qa, 'bgimage'), get_string('dropbackground', 'qtype_ddmarker'),
76
                ['class' => 'dropbackground img-fluid w-100']);
77
 
78
        $output .= html_writer::div('', 'dropzones');
79
        $output .= html_writer::end_div();
80
        $output .= html_writer::start_div($draghomesclass);
81
 
82
        $dragimagehomes = '';
83
        foreach ($question->choices as $groupno => $group) {
84
            $dragimagehomesgroup = '';
85
            $orderedgroup = $question->get_ordered_choices($groupno);
86
            foreach ($orderedgroup as $choiceno => $dragimage) {
87
                $dragimageurl = self::get_url_for_image($qa, 'dragimage', $dragimage->id);
88
                $classes = [
89
                        'group' . $groupno,
90
                        'draghome',
91
                        'user-select-none',
92
                        'choice' . $choiceno
93
                ];
94
                if ($dragimage->infinite) {
95
                    $classes[] = 'infinite';
96
                }
97
                if ($dragimageurl === null) {
1441 ariadna 98
                    $dragimage->text = question_utils::format_question_fragment($dragimage->text, $this->page->context);
1 efrain 99
                    $dragimagehomesgroup .= html_writer::div($dragimage->text, join(' ', $classes), ['src' => $dragimageurl]);
100
                } else {
101
                    $dragimagehomesgroup .= html_writer::img($dragimageurl, $dragimage->text, ['class' => join(' ', $classes)]);
102
                }
103
            }
104
            $dragimagehomes .= html_writer::div($dragimagehomesgroup, 'dragitemgroup' . $groupno);
105
        }
106
 
107
        $output .= $dragimagehomes;
108
        $output .= html_writer::end_div();
109
 
110
        // Note, the mobile app implementation of ddimageortext relies on extracting the
111
        // blob of places data out of the rendered HTML, which makes it impossible
112
        // to clean up this structure of otherwise unnecessary stuff.
113
        $placeinfoforjsandmobileapp = [];
114
        foreach ($question->places as $placeno => $place) {
115
            $varname = $question->field($placeno);
116
            [$fieldname, $html] = $this->hidden_field_for_qt_var($qa, $varname, null,
117
                    ['placeinput', 'place' . $placeno, 'group' . $place->group]);
118
            $output .= $html;
119
            $placeinfo = (object) (array) $place;
120
            $placeinfo->fieldname = $fieldname;
1441 ariadna 121
            $placeinfo->text = format_string($placeinfo->text);
1 efrain 122
            $placeinfoforjsandmobileapp[$placeno] = $placeinfo;
123
        }
124
 
125
        $output .= html_writer::end_div();
126
 
127
        $this->page->requires->string_for_js('blank', 'qtype_ddimageortext');
128
        $this->page->requires->js_call_amd('qtype_ddimageortext/question', 'init',
129
                [$qa->get_outer_question_div_unique_id(), $options->readonly, $placeinfoforjsandmobileapp]);
130
 
131
        if ($qa->get_state() == question_state::$invalid) {
132
            $output .= html_writer::div($question->get_validation_error($qa->get_last_qt_data()), 'validationerror');
133
        }
134
        return $output;
135
    }
136
 
137
    /**
138
     * Returns the URL for an image
139
     *
140
     * @param object $qa Question attempt object
141
     * @param string $filearea File area descriptor
142
     * @param int $itemid Item id to get
143
     * @return string Output url, or null if not found
144
     */
145
    protected static function get_url_for_image(question_attempt $qa, $filearea, $itemid = 0) {
146
        $question = $qa->get_question();
147
        $qubaid = $qa->get_usage_id();
148
        $slot = $qa->get_slot();
149
        $fs = get_file_storage();
150
        if ($filearea == 'bgimage') {
151
            $itemid = $question->id;
152
        }
153
        $componentname = $question->qtype->plugin_name();
154
        $draftfiles = $fs->get_area_files($question->contextid, $componentname,
155
                                                                        $filearea, $itemid, 'id');
156
        if ($draftfiles) {
157
            foreach ($draftfiles as $file) {
158
                if ($file->is_directory()) {
159
                    continue;
160
                }
161
                $url = moodle_url::make_pluginfile_url($question->contextid, $componentname,
162
                                            $filearea, "$qubaid/$slot/{$itemid}", '/',
163
                                            $file->get_filename());
164
                return $url->out();
165
            }
166
        }
167
        return null;
168
    }
169
 
170
    /**
171
     * Returns a hidden field for a qt variable
172
     *
173
     * @param object $qa Question attempt object
174
     * @param string $varname The hidden var name
175
     * @param string $value The hidden value
176
     * @param array $classes Any additional css classes to apply
177
     * @return array Array with field name and the html of the tag
178
     */
179
    protected function hidden_field_for_qt_var(question_attempt $qa, $varname, $value = null,
180
                                                $classes = null) {
181
        if ($value === null) {
182
            $value = $qa->get_last_qt_var($varname);
183
        }
184
        $fieldname = $qa->get_qt_field_name($varname);
185
        $attributes = array('type' => 'hidden',
186
                                'id' => str_replace(':', '_', $fieldname),
187
                                'name' => $fieldname,
188
                                'value' => $value);
189
        if ($classes !== null) {
190
            $attributes['class'] = join(' ', $classes);
191
        }
192
        return array($fieldname, html_writer::empty_tag('input', $attributes)."\n");
193
    }
194
 
195
    public function specific_feedback(question_attempt $qa) {
196
        return $this->combined_feedback($qa);
197
    }
198
 
199
    public function correct_response(question_attempt $qa) {
200
        return '';
201
    }
202
}