Differences Between: [Versions 310 and 311] [Versions 39 and 311]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body