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
defined('MOODLE_INTERNAL') OR die('not allowed');
18
require_once($CFG->dirroot.'/mod/feedback/item/feedback_item_class.php');
19
 
20
class feedback_item_numeric extends feedback_item_base {
21
    protected $type = "numeric";
22
 
23
    public function build_editform($item, $feedback, $cm) {
24
        global $DB, $CFG;
25
        require_once('numeric_form.php');
26
 
27
        //get the lastposition number of the feedback_items
28
        $position = $item->position;
29
        $lastposition = $DB->count_records('feedback_item', array('feedback'=>$feedback->id));
30
        if ($position == -1) {
31
            $i_formselect_last = $lastposition + 1;
32
            $i_formselect_value = $lastposition + 1;
33
            $item->position = $lastposition + 1;
34
        } else {
35
            $i_formselect_last = $lastposition;
36
            $i_formselect_value = $item->position;
37
        }
38
        //the elements for position dropdownlist
39
        $positionlist = array_slice(range(0, $i_formselect_last), 1, $i_formselect_last, true);
40
 
41
        $item->presentation = empty($item->presentation) ? '' : $item->presentation;
42
 
43
        $range_from_to = explode('|', $item->presentation);
44
        if (isset($range_from_to[0]) AND is_numeric($range_from_to[0])) {
45
            $range_from = $this->format_float($range_from_to[0]);
46
        } else {
47
            $range_from = '-';
48
        }
49
 
50
        if (isset($range_from_to[1]) AND is_numeric($range_from_to[1])) {
51
            $range_to = $this->format_float($range_from_to[1]);
52
        } else {
53
            $range_to = '-';
54
        }
55
 
56
        $item->rangefrom = $range_from;
57
        $item->rangeto = $range_to;
58
 
59
        //all items for dependitem
60
        $feedbackitems = feedback_get_depend_candidates_for_item($feedback, $item);
61
        $commonparams = array('cmid'=>$cm->id,
62
                             'id'=>isset($item->id) ? $item->id : null,
63
                             'typ'=>$item->typ,
64
                             'items'=>$feedbackitems,
65
                             'feedback'=>$feedback->id);
66
 
67
        //build the form
68
        $customdata = array('item' => $item,
69
                            'common' => $commonparams,
70
                            'positionlist' => $positionlist,
71
                            'position' => $position);
72
 
73
        $this->item_form = new feedback_numeric_form('edit_item.php', $customdata);
74
    }
75
 
76
    public function save_item() {
77
        global $DB;
78
 
79
        if (!$this->get_data()) {
80
            return false;
81
        }
82
        $item = $this->item;
83
 
84
        if (isset($item->clone_item) AND $item->clone_item) {
85
            $item->id = ''; //to clone this item
86
            $item->position++;
87
        }
88
 
89
        $item->hasvalue = $this->get_hasvalue();
90
        if (!$item->id) {
91
            $item->id = $DB->insert_record('feedback_item', $item);
92
        } else {
93
            $DB->update_record('feedback_item', $item);
94
        }
95
 
96
        return $DB->get_record('feedback_item', array('id'=>$item->id));
97
    }
98
 
99
    /**
100
     * Helper function for collected data, both for analysis page and export to excel
101
     *
102
     * @param stdClass $item the db-object from feedback_item
103
     * @param int $groupid
104
     * @param int $courseid
105
     * @return stdClass
106
     */
107
    protected function get_analysed($item, $groupid = false, $courseid = false) {
108
        global $DB;
109
 
110
        $analysed = new stdClass();
111
        $analysed->data = array();
112
        $analysed->name = $item->name;
113
        $values = feedback_get_group_values($item, $groupid, $courseid);
114
 
115
        $avg = 0.0;
116
        $counter = 0;
117
        if ($values) {
118
            $data = array();
119
            foreach ($values as $value) {
120
                if (is_numeric($value->value)) {
121
                    $data[] = $value->value;
122
                    $avg += $value->value;
123
                    $counter++;
124
                }
125
            }
126
            $avg = $counter > 0 ? $avg / $counter : null;
127
            $analysed->data = $data;
128
            $analysed->avg = $avg;
129
        }
130
        return $analysed;
131
    }
132
 
133
    public function get_printval($item, $value) {
134
        if (!isset($value->value)) {
135
            return '';
136
        }
137
 
138
        return $value->value;
139
    }
140
 
141
    public function print_analysed($item, $itemnr = '', $groupid = false, $courseid = false) {
142
 
143
        $values = $this->get_analysed($item, $groupid, $courseid);
144
 
145
        if (isset($values->data) AND is_array($values->data)) {
146
            echo "<table class=\"analysis itemtype_{$item->typ}\">";
147
            echo '<tr><th class="text-left">';
148
            echo $itemnr . ' ';
149
            if (strval($item->label) !== '') {
150
                echo '('. format_string($item->label).') ';
151
            }
152
            echo format_text($item->name, FORMAT_HTML, array('noclean' => true, 'para' => false));
153
            echo '</th></tr>';
154
 
155
            foreach ($values->data as $value) {
156
                echo '<tr><td class="singlevalue">';
157
                echo $this->format_float($value);
158
                echo '</td></tr>';
159
            }
160
 
161
            if (isset($values->avg)) {
162
                $avg = format_float($values->avg, 2);
163
            } else {
164
                $avg = '-';
165
            }
166
            echo '<tr><td><b>';
167
            echo get_string('average', 'feedback').': '.$avg;
168
            echo '</b></td></tr>';
169
            echo '</table>';
170
        }
171
    }
172
 
173
    public function excelprint_item(&$worksheet, $row_offset,
174
                             $xls_formats, $item,
175
                             $groupid, $courseid = false) {
176
 
177
        $analysed_item = $this->get_analysed($item, $groupid, $courseid);
178
 
179
        $worksheet->write_string($row_offset, 0, $item->label, $xls_formats->head2);
180
        $worksheet->write_string($row_offset, 1, $item->name, $xls_formats->head2);
181
        $data = $analysed_item->data;
182
        if (is_array($data)) {
183
 
184
            // Export average.
185
            $worksheet->write_string($row_offset,
186
                                     2,
187
                                     get_string('average', 'feedback'),
188
                                     $xls_formats->value_bold);
189
 
190
            if (isset($analysed_item->avg)) {
191
                $worksheet->write_number($row_offset + 1,
192
                                         2,
193
                                         $analysed_item->avg,
194
                                         $xls_formats->value_bold);
195
            } else {
196
                $worksheet->write_string($row_offset + 1,
197
                                         2,
198
                                         '',
199
                                         $xls_formats->value_bold);
200
            }
201
            $row_offset++;
202
        }
203
        $row_offset++;
204
        return $row_offset;
205
    }
206
 
207
    /**
208
     * Prints the float nicely in the localized format
209
     *
210
     * Similar to format_float() but automatically calculates the number of decimal places
211
     *
212
     * @param float $value The float to print
213
     * @return string
214
     */
215
    protected function format_float($value) {
216
        if (!is_numeric($value)) {
217
            return null;
218
        }
219
        $decimal = is_int($value) ? 0 : strlen(substr(strrchr($value, '.'), 1));
220
        return format_float($value, $decimal);
221
    }
222
 
223
    /**
224
     * Returns human-readable boundaries (min - max)
225
     * @param stdClass $item
226
     * @return string
227
     */
228
    protected function get_boundaries_for_display($item) {
229
        list($rangefrom, $rangeto) = explode('|', $item->presentation);
230
        if (!isset($rangefrom) || !is_numeric($rangefrom)) {
231
            $rangefrom = null;
232
        }
233
        if (!isset($rangeto) || !is_numeric($rangeto)) {
234
            $rangeto = null;
235
        }
236
 
237
        if (is_null($rangefrom) && is_numeric($rangeto)) {
238
            return ' (' . get_string('maximal', 'feedback') .
239
                        ': ' . $this->format_float($rangeto) . ')';
240
        }
241
        if (is_numeric($rangefrom) && is_null($rangeto)) {
242
            return ' (' . get_string('minimal', 'feedback') .
243
                        ': ' . $this->format_float($rangefrom) . ')';
244
        }
245
        if (is_null($rangefrom) && is_null($rangeto)) {
246
            return '';
247
        }
248
        return ' (' . $this->format_float($rangefrom) .
249
                ' - ' . $this->format_float($rangeto) . ')';
250
    }
251
 
252
    /**
253
     * Returns the postfix to be appended to the display name that is based on other settings
254
     *
255
     * @param stdClass $item
256
     * @return string
257
     */
258
    public function get_display_name_postfix($item) {
259
        return html_writer::span($this->get_boundaries_for_display($item), 'boundaries');
260
    }
261
 
262
    /**
263
     * Adds an input element to the complete form
264
     *
265
     * @param stdClass $item
266
     * @param mod_feedback_complete_form $form
267
     */
268
    public function complete_form_element($item, $form) {
269
        $name = $this->get_display_name($item);
270
        $inputname = $item->typ . '_' . $item->id;
271
        $form->add_form_element($item,
272
                ['text', $inputname, $name],
273
                true,
274
                false
275
                );
276
        $form->set_element_type($inputname, PARAM_NOTAGS);
277
        $tmpvalue = $this->format_float($form->get_item_value($item));
278
        $form->set_element_default($inputname, $tmpvalue);
279
 
280
        // Add form validation rule to check for boundaries.
281
        $form->add_validation_rule(function($values, $files) use ($item) {
282
            $inputname = $item->typ . '_' . $item->id;
283
            list($rangefrom, $rangeto) = explode('|', $item->presentation);
284
            if (!isset($values[$inputname]) || trim($values[$inputname]) === '') {
285
                return $item->required ? array($inputname => get_string('required')) : true;
286
            }
287
            $value = unformat_float($values[$inputname], true);
288
            if ($value === false) {
289
                return array($inputname => get_string('invalidnum', 'error'));
290
            }
291
            if ((is_numeric($rangefrom) && $value < floatval($rangefrom)) ||
292
                    (is_numeric($rangeto) && $value > floatval($rangeto))) {
293
                return array($inputname => get_string('numberoutofrange', 'feedback'));
294
            }
295
            return true;
296
        });
297
    }
298
 
299
    public function create_value($data) {
300
        $data = unformat_float($data, true);
301
 
302
        if (is_numeric($data)) {
303
            $data = floatval($data);
304
        } else {
305
            $data = '';
306
        }
307
        return $data;
308
    }
309
 
310
    /**
311
     * Return the analysis data ready for external functions.
312
     *
313
     * @param stdClass $item     the item (question) information
314
     * @param int      $groupid  the group id to filter data (optional)
315
     * @param int      $courseid the course id (optional)
316
     * @return array an array of data with non scalar types json encoded
317
     * @since  Moodle 3.3
318
     */
319
    public function get_analysed_for_external($item, $groupid = false, $courseid = false) {
320
 
321
        $externaldata = array();
322
        $data = $this->get_analysed($item, $groupid, $courseid);
323
 
324
        if (is_array($data->data)) {
325
            return $data->data; // No need to json, scalar type.
326
        }
327
        return $externaldata;
328
    }
329
}