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
 * Question type class for the simple calculated question type.
19
 *
20
 * @package    qtype
21
 * @subpackage calculatedsimple
22
 * @copyright  2009 Pierre Pichet
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
require_once($CFG->dirroot . '/question/type/calculated/questiontype.php');
30
 
31
 
32
/**
33
 * The simple calculated question type.
34
 *
35
 * @copyright  2009 Pierre Pichet
36
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37
 */
38
class qtype_calculatedsimple extends qtype_calculated {
39
 
40
    // Used by the function custom_generator_tools.
41
    public $wizard_pages_number = 1;
42
 
43
    public function save_question_options($question) {
44
        global $CFG, $DB;
45
        $context = $question->context;
46
 
47
        // Make it impossible to save bad formulas anywhere.
48
        $this->validate_question_data($question);
49
 
50
        // Get old versions of the objects.
51
        if (!$oldanswers = $DB->get_records('question_answers',
52
                array('question' => $question->id), 'id ASC')) {
53
            $oldanswers = array();
54
        }
55
 
56
        if (!$oldoptions = $DB->get_records('question_calculated',
57
                array('question' => $question->id), 'answer ASC')) {
58
            $oldoptions = array();
59
        }
60
 
61
        // Save the units.
62
        $virtualqtype = $this->get_virtual_qtype();
63
        $result = $virtualqtype->save_units($question);
64
        if (isset($result->error)) {
65
            return $result;
66
        } else {
67
            $units = &$result->units;
68
        }
69
        // Insert all the new answers.
70
        foreach ($question->answer as $key => $answerdata) {
71
            if (is_array($answerdata)) {
72
                $answerdata = $answerdata['text'];
73
            }
74
            if (trim($answerdata) == '') {
75
                continue;
76
            }
77
 
78
            // Update an existing answer if possible.
79
            $answer = array_shift($oldanswers);
80
            if (!$answer) {
81
                $answer = new stdClass();
82
                $answer->question = $question->id;
83
                $answer->answer   = '';
84
                $answer->feedback = '';
85
                $answer->id       = $DB->insert_record('question_answers', $answer);
86
            }
87
 
88
            $answer->answer   = trim($answerdata);
89
            $answer->fraction = $question->fraction[$key];
90
            $answer->feedback = $this->import_or_save_files($question->feedback[$key],
91
                    $context, 'question', 'answerfeedback', $answer->id);
92
            $answer->feedbackformat = $question->feedback[$key]['format'];
93
 
94
            $DB->update_record("question_answers", $answer);
95
 
96
            // Set up the options object.
97
            if (!$options = array_shift($oldoptions)) {
98
                $options = new stdClass();
99
            }
100
            $options->question            = $question->id;
101
            $options->answer              = $answer->id;
102
            $options->tolerance           = trim($question->tolerance[$key]);
103
            $options->tolerancetype       = trim($question->tolerancetype[$key]);
104
            $options->correctanswerlength = trim($question->correctanswerlength[$key]);
105
            $options->correctanswerformat = trim($question->correctanswerformat[$key]);
106
 
107
            // Save options.
108
            if (isset($options->id)) {
109
                // Reusing existing record.
110
                $DB->update_record('question_calculated', $options);
111
            } else {
112
                // New options.
113
                $DB->insert_record('question_calculated', $options);
114
            }
115
        }
116
 
117
        // Delete old answer records.
118
        if (!empty($oldanswers)) {
119
            foreach ($oldanswers as $oa) {
120
                $DB->delete_records('question_answers', array('id' => $oa->id));
121
            }
122
        }
123
 
124
        // Delete old answer records.
125
        if (!empty($oldoptions)) {
126
            foreach ($oldoptions as $oo) {
127
                $DB->delete_records('question_calculated', array('id' => $oo->id));
128
            }
129
        }
130
 
131
        if (isset($question->import_process) && $question->import_process) {
132
            $this->import_datasets($question);
133
        } else {
134
            // Save datasets and datatitems from form i.e in question.
135
            $question->dataset = $question->datasetdef;
136
 
137
            // Save datasets.
138
            $datasetdefinitions = $this->get_dataset_definitions($question->id, $question->dataset);
139
            $tmpdatasets = array_flip($question->dataset);
140
            $defids = array_keys($datasetdefinitions);
141
            $datasetdefs = array();
142
            foreach ($defids as $defid) {
143
                $datasetdef = &$datasetdefinitions[$defid];
144
                if (isset($datasetdef->id)) {
145
                    if (!isset($tmpdatasets[$defid])) {
146
                        // This dataset is not used any more, delete it.
147
                        $DB->delete_records('question_datasets', array('question' => $question->id,
148
                                'datasetdefinition' => $datasetdef->id));
149
                        $DB->delete_records('question_dataset_definitions',
150
                                array('id' => $datasetdef->id));
151
                        $DB->delete_records('question_dataset_items',
152
                                array('definition' => $datasetdef->id));
153
                    }
154
                    // This has already been saved or just got deleted.
155
                    unset($datasetdefinitions[$defid]);
156
                    continue;
157
                }
158
                $datasetdef->id = $DB->insert_record('question_dataset_definitions', $datasetdef);
159
                $datasetdefs[] = clone($datasetdef);
160
                $questiondataset = new stdClass();
161
                $questiondataset->question = $question->id;
162
                $questiondataset->datasetdefinition = $datasetdef->id;
163
                $DB->insert_record('question_datasets', $questiondataset);
164
                unset($datasetdefinitions[$defid]);
165
            }
166
            // Remove local obsolete datasets as well as relations
167
            // to datasets in other categories.
168
            if (!empty($datasetdefinitions)) {
169
                foreach ($datasetdefinitions as $def) {
170
                    $DB->delete_records('question_datasets', array('question' => $question->id,
171
                            'datasetdefinition' => $def->id));
172
                    if ($def->category == 0) { // Question local dataset.
173
                        $DB->delete_records('question_dataset_definitions',
174
                                array('id' => $def->id));
175
                        $DB->delete_records('question_dataset_items',
176
                                array('definition' => $def->id));
177
                    }
178
                }
179
            }
180
            $datasetdefs = $this->get_dataset_definitions($question->id, $question->dataset);
181
            // Handle adding and removing of dataset items.
182
            $i = 1;
183
            ksort($question->definition);
184
            foreach ($question->definition as $key => $defid) {
185
                $addeditem = new stdClass();
186
                $addeditem->definition = $datasetdefs[$defid]->id;
187
                $addeditem->value = $question->number[$i];
188
                $addeditem->itemnumber = ceil($i / count($datasetdefs));
189
                if (empty($question->makecopy) && $question->itemid[$i]) {
190
                    // Reuse any previously used record.
191
                    $addeditem->id = $question->itemid[$i];
192
                    $DB->update_record('question_dataset_items', $addeditem);
193
                } else {
194
                    $DB->insert_record('question_dataset_items', $addeditem);
195
                }
196
                $i++;
197
            }
198
            $maxnumber = -1;
199
            if (isset($addeditem->itemnumber) && $maxnumber < $addeditem->itemnumber) {
200
                $maxnumber = $addeditem->itemnumber;
201
                foreach ($datasetdefs as $key => $newdef) {
202
                    if (isset($newdef->id) && $newdef->itemcount <= $maxnumber) {
203
                        $newdef->itemcount = $maxnumber;
204
                        // Save the new value for options.
205
                        $DB->update_record('question_dataset_definitions', $newdef);
206
                    }
207
                }
208
            }
209
        }
210
 
211
        $this->save_hints($question);
212
 
213
        // Report any problems.
214
        if (!empty($question->makecopy) && !empty($question->convert)) {
215
            $DB->set_field('question', 'qtype', 'calculated', array('id' => $question->id));
216
        }
217
 
218
        $result = $virtualqtype->save_unit_options($question);
219
        if (isset($result->error)) {
220
            return $result;
221
        }
222
 
223
        if (!empty($result->notice)) {
224
            return $result;
225
        }
226
 
227
        return true;
228
    }
229
 
230
    public function finished_edit_wizard($form) {
231
        return true;
232
    }
233
 
234
    public function wizard_pages_number() {
235
        return 1;
236
    }
237
 
238
    public function custom_generator_tools_part($mform, $idx, $j) {
239
 
240
        $minmaxgrp = array();
241
        $minmaxgrp[] = $mform->createElement('float', "calcmin[{$idx}]",
242
                get_string('calcmin', 'qtype_calculated'));
243
        $minmaxgrp[] = $mform->createElement('float', "calcmax[{$idx}]",
244
                get_string('calcmax', 'qtype_calculated'));
245
        $mform->addGroup($minmaxgrp, 'minmaxgrp',
246
                get_string('minmax', 'qtype_calculated'), ' - ', false);
247
 
248
        $precisionoptions = range(0, 10);
249
        $mform->addElement('select', "calclength[{$idx}]",
250
                get_string('calclength', 'qtype_calculated'), $precisionoptions);
251
 
252
        $distriboptions = array('uniform' => get_string('uniform', 'qtype_calculated'),
253
                'loguniform' => get_string('loguniform', 'qtype_calculated'));
254
        $mform->addElement('hidden', "calcdistribution[{$idx}]", 'uniform');
255
        $mform->setType("calcdistribution[{$idx}]", PARAM_INT);
256
    }
257
 
258
    public function comment_header($answers) {
259
        $strheader = "";
260
        $delimiter = '';
261
 
262
        foreach ($answers as $key => $answer) {
263
            $ans = shorten_text($answer->answer, 17, true);
264
            $strheader .= $delimiter.$ans;
265
            $delimiter = '<br/><br/><br/>';
266
        }
267
        return $strheader;
268
    }
269
 
270
    public function tolerance_types() {
271
        return array(
272
            '1'  => get_string('relative', 'qtype_numerical'),
273
            '2'  => get_string('nominal', 'qtype_numerical'),
274
        );
275
    }
276
 
277
    public function dataset_options($form, $name, $mandatory = true, $renameabledatasets = false) {
278
        // Takes datasets from the parent implementation but
279
        // filters options that are currently not accepted by calculated.
280
        // It also determines a default selection
281
        // $renameabledatasets not implemented anywhere.
282
        list($options, $selected) = $this->dataset_options_from_database(
283
                $form, $name, '', 'qtype_calculated');
284
 
285
        foreach ($options as $key => $whatever) {
286
            if (!preg_match('~^1-~', $key) && $key != '0') {
287
                unset($options[$key]);
288
            }
289
        }
290
        if (!$selected) {
291
            if ($mandatory) {
292
                $selected =  "1-0-{$name}"; // Default.
293
            } else {
294
                $selected = "0"; // Default.
295
            }
296
        }
297
        return array($options, $selected);
298
    }
299
}