| 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_info extends feedback_item_base {
 | 
        
           |  |  | 21 |     protected $type = "info";
 | 
        
           |  |  | 22 |   | 
        
           |  |  | 23 |     /** Mode recording response time (for non-anonymous feedbacks only) */
 | 
        
           |  |  | 24 |     const MODE_RESPONSETIME = 1;
 | 
        
           |  |  | 25 |     /** Mode recording current course */
 | 
        
           |  |  | 26 |     const MODE_COURSE = 2;
 | 
        
           |  |  | 27 |     /** Mode recording current course category */
 | 
        
           |  |  | 28 |     const MODE_CATEGORY = 3;
 | 
        
           |  |  | 29 |   | 
        
           |  |  | 30 |     /** Special constant to keep the current timestamp as value for the form element */
 | 
        
           |  |  | 31 |     const CURRENTTIMESTAMP = '__CURRENT__TIMESTAMP__';
 | 
        
           |  |  | 32 |   | 
        
           |  |  | 33 |     public function build_editform($item, $feedback, $cm) {
 | 
        
           |  |  | 34 |         global $DB, $CFG;
 | 
        
           |  |  | 35 |         require_once('info_form.php');
 | 
        
           |  |  | 36 |   | 
        
           |  |  | 37 |         //get the lastposition number of the feedback_items
 | 
        
           |  |  | 38 |         $position = $item->position;
 | 
        
           |  |  | 39 |         $lastposition = $DB->count_records('feedback_item', array('feedback'=>$feedback->id));
 | 
        
           |  |  | 40 |         if ($position == -1) {
 | 
        
           |  |  | 41 |             $i_formselect_last = $lastposition + 1;
 | 
        
           |  |  | 42 |             $i_formselect_value = $lastposition + 1;
 | 
        
           |  |  | 43 |             $item->position = $lastposition + 1;
 | 
        
           |  |  | 44 |         } else {
 | 
        
           |  |  | 45 |             $i_formselect_last = $lastposition;
 | 
        
           |  |  | 46 |             $i_formselect_value = $item->position;
 | 
        
           |  |  | 47 |         }
 | 
        
           |  |  | 48 |         //the elements for position dropdownlist
 | 
        
           |  |  | 49 |         $positionlist = array_slice(range(0, $i_formselect_last), 1, $i_formselect_last, true);
 | 
        
           |  |  | 50 |   | 
        
           |  |  | 51 |         $item->presentation = empty($item->presentation) ? self::MODE_COURSE : $item->presentation;
 | 
        
           |  |  | 52 |         $item->required = 0;
 | 
        
           |  |  | 53 |   | 
        
           |  |  | 54 |         //all items for dependitem
 | 
        
           |  |  | 55 |         $feedbackitems = feedback_get_depend_candidates_for_item($feedback, $item);
 | 
        
           |  |  | 56 |         $commonparams = array('cmid'=>$cm->id,
 | 
        
           |  |  | 57 |                              'id'=>isset($item->id) ? $item->id : null,
 | 
        
           |  |  | 58 |                              'typ'=>$item->typ,
 | 
        
           |  |  | 59 |                              'items'=>$feedbackitems,
 | 
        
           |  |  | 60 |                              'feedback'=>$feedback->id);
 | 
        
           |  |  | 61 |   | 
        
           |  |  | 62 |         // Options for the 'presentation' select element.
 | 
        
           |  |  | 63 |         $presentationoptions = array();
 | 
        
           |  |  | 64 |         if ($feedback->anonymous == FEEDBACK_ANONYMOUS_NO || $item->presentation == self::MODE_RESPONSETIME) {
 | 
        
           |  |  | 65 |             // "Response time" is hidden anyway in case of anonymous feedback, no reason to offer this option.
 | 
        
           |  |  | 66 |             // However if it was already selected leave it in the dropdown.
 | 
        
           |  |  | 67 |             $presentationoptions[self::MODE_RESPONSETIME] = get_string('responsetime', 'feedback');
 | 
        
           |  |  | 68 |         }
 | 
        
           |  |  | 69 |         $presentationoptions[self::MODE_COURSE]  = get_string('course');
 | 
        
           |  |  | 70 |         $presentationoptions[self::MODE_CATEGORY]  = get_string('coursecategory');
 | 
        
           |  |  | 71 |   | 
        
           |  |  | 72 |         //build the form
 | 
        
           |  |  | 73 |         $this->item_form = new feedback_info_form('edit_item.php',
 | 
        
           |  |  | 74 |                                                   array('item'=>$item,
 | 
        
           |  |  | 75 |                                                   'common'=>$commonparams,
 | 
        
           |  |  | 76 |                                                   'positionlist'=>$positionlist,
 | 
        
           |  |  | 77 |                                                   'position' => $position,
 | 
        
           |  |  | 78 |                                                   'presentationoptions' => $presentationoptions));
 | 
        
           |  |  | 79 |     }
 | 
        
           |  |  | 80 |   | 
        
           |  |  | 81 |     public function save_item() {
 | 
        
           |  |  | 82 |         global $DB;
 | 
        
           |  |  | 83 |   | 
        
           |  |  | 84 |         if (!$this->get_data()) {
 | 
        
           |  |  | 85 |             return false;
 | 
        
           |  |  | 86 |         }
 | 
        
           |  |  | 87 |         $item = $this->item;
 | 
        
           |  |  | 88 |   | 
        
           |  |  | 89 |         if (isset($item->clone_item) AND $item->clone_item) {
 | 
        
           |  |  | 90 |             $item->id = ''; //to clone this item
 | 
        
           |  |  | 91 |             $item->position++;
 | 
        
           |  |  | 92 |         }
 | 
        
           |  |  | 93 |   | 
        
           |  |  | 94 |         $item->hasvalue = $this->get_hasvalue();
 | 
        
           |  |  | 95 |         if (!$item->id) {
 | 
        
           |  |  | 96 |             $item->id = $DB->insert_record('feedback_item', $item);
 | 
        
           |  |  | 97 |         } else {
 | 
        
           |  |  | 98 |             $DB->update_record('feedback_item', $item);
 | 
        
           |  |  | 99 |         }
 | 
        
           |  |  | 100 |   | 
        
           |  |  | 101 |         return $DB->get_record('feedback_item', array('id'=>$item->id));
 | 
        
           |  |  | 102 |     }
 | 
        
           |  |  | 103 |   | 
        
           |  |  | 104 |     /**
 | 
        
           |  |  | 105 |      * Helper function for collected data, both for analysis page and export to excel
 | 
        
           |  |  | 106 |      *
 | 
        
           |  |  | 107 |      * @param stdClass $item the db-object from feedback_item
 | 
        
           |  |  | 108 |      * @param int|false $groupid
 | 
        
           |  |  | 109 |      * @param int $courseid
 | 
        
           |  |  | 110 |      * @return stdClass
 | 
        
           |  |  | 111 |      */
 | 
        
           |  |  | 112 |     protected function get_analysed($item, $groupid = false, $courseid = false) {
 | 
        
           |  |  | 113 |   | 
        
           |  |  | 114 |         $presentation = $item->presentation;
 | 
        
           |  |  | 115 |         $analysed_val = new stdClass();
 | 
        
           |  |  | 116 |         $analysed_val->data = null;
 | 
        
           |  |  | 117 |         $analysed_val->name = $item->name;
 | 
        
           |  |  | 118 |         $values = feedback_get_group_values($item, $groupid, $courseid);
 | 
        
           |  |  | 119 |         if ($values) {
 | 
        
           |  |  | 120 |             $data = array();
 | 
        
           |  |  | 121 |             foreach ($values as $value) {
 | 
        
           |  |  | 122 |                 $datavalue = new stdClass();
 | 
        
           |  |  | 123 |   | 
        
           |  |  | 124 |                 switch($presentation) {
 | 
        
           |  |  | 125 |                     case self::MODE_RESPONSETIME:
 | 
        
           |  |  | 126 |                         $datavalue->value = $value->value;
 | 
        
           |  |  | 127 |                         $datavalue->show = $value->value ? userdate($datavalue->value) : '';
 | 
        
           |  |  | 128 |                         break;
 | 
        
           |  |  | 129 |                     case self::MODE_COURSE:
 | 
        
           |  |  | 130 |                         $datavalue->value = $value->value;
 | 
        
           |  |  | 131 |                         $datavalue->show = $datavalue->value;
 | 
        
           |  |  | 132 |                         break;
 | 
        
           |  |  | 133 |                     case self::MODE_CATEGORY:
 | 
        
           |  |  | 134 |                         $datavalue->value = $value->value;
 | 
        
           |  |  | 135 |                         $datavalue->show = $datavalue->value;
 | 
        
           |  |  | 136 |                         break;
 | 
        
           |  |  | 137 |                 }
 | 
        
           |  |  | 138 |   | 
        
           |  |  | 139 |                 $data[] = $datavalue;
 | 
        
           |  |  | 140 |             }
 | 
        
           |  |  | 141 |             $analysed_val->data = $data;
 | 
        
           |  |  | 142 |         }
 | 
        
           |  |  | 143 |         return $analysed_val;
 | 
        
           |  |  | 144 |     }
 | 
        
           |  |  | 145 |   | 
        
           |  |  | 146 |     public function get_printval($item, $value) {
 | 
        
           |  |  | 147 |   | 
        
           |  |  | 148 |         if (strval($value->value) === '') {
 | 
        
           |  |  | 149 |             return '';
 | 
        
           |  |  | 150 |         }
 | 
        
           |  |  | 151 |         return $item->presentation == self::MODE_RESPONSETIME ?
 | 
        
           |  |  | 152 |                 userdate($value->value) : $value->value;
 | 
        
           |  |  | 153 |     }
 | 
        
           |  |  | 154 |   | 
        
           |  |  | 155 |     public function print_analysed($item, $itemnr = '', $groupid = false, $courseid = false) {
 | 
        
           | 1441 | ariadna | 156 |         echo "<table class=\"analysis itemtype_{$item->typ} table-reboot\">";
 | 
        
           | 1 | efrain | 157 |         $analysed_item = $this->get_analysed($item, $groupid, $courseid);
 | 
        
           |  |  | 158 |         $data = $analysed_item->data;
 | 
        
           |  |  | 159 |         if (is_array($data)) {
 | 
        
           | 1441 | ariadna | 160 |             echo '<tr><th class="text-start">';
 | 
        
           | 1 | efrain | 161 |             echo $itemnr . ' ';
 | 
        
           |  |  | 162 |             if (strval($item->label) !== '') {
 | 
        
           |  |  | 163 |                 echo '('. format_string($item->label).') ';
 | 
        
           |  |  | 164 |             }
 | 
        
           |  |  | 165 |             echo format_text($item->name, FORMAT_HTML, array('noclean' => true, 'para' => false));
 | 
        
           |  |  | 166 |             echo '</th></tr>';
 | 
        
           |  |  | 167 |             $sizeofdata = count($data);
 | 
        
           |  |  | 168 |             for ($i = 0; $i < $sizeofdata; $i++) {
 | 
        
           |  |  | 169 |                 $class = strlen(trim($data[$i]->show)) ? '' : ' class="isempty"';
 | 
        
           |  |  | 170 |                 echo '<tr'.$class.'><td class="singlevalue">';
 | 
        
           |  |  | 171 |                 echo str_replace("\n", '<br />', $data[$i]->show);
 | 
        
           |  |  | 172 |                 echo '</td></tr>';
 | 
        
           |  |  | 173 |             }
 | 
        
           |  |  | 174 |         }
 | 
        
           |  |  | 175 |         echo '</table>';
 | 
        
           |  |  | 176 |     }
 | 
        
           |  |  | 177 |   | 
        
           |  |  | 178 |     public function excelprint_item(&$worksheet, $row_offset,
 | 
        
           |  |  | 179 |                              $xls_formats, $item,
 | 
        
           |  |  | 180 |                              $groupid, $courseid = false) {
 | 
        
           |  |  | 181 |         $analysed_item = $this->get_analysed($item, $groupid, $courseid);
 | 
        
           |  |  | 182 |   | 
        
           |  |  | 183 |         $worksheet->write_string($row_offset, 0, $item->label, $xls_formats->head2);
 | 
        
           |  |  | 184 |         $worksheet->write_string($row_offset, 1, $item->name, $xls_formats->head2);
 | 
        
           |  |  | 185 |         $data = $analysed_item->data;
 | 
        
           |  |  | 186 |         if (is_array($data)) {
 | 
        
           |  |  | 187 |             $worksheet->write_string($row_offset, 2, $data[0]->show, $xls_formats->value_bold);
 | 
        
           |  |  | 188 |             $row_offset++;
 | 
        
           |  |  | 189 |             $sizeofdata = count($data);
 | 
        
           |  |  | 190 |             for ($i = 1; $i < $sizeofdata; $i++) {
 | 
        
           |  |  | 191 |                 $worksheet->write_string($row_offset, 2, $data[$i]->show, $xls_formats->default);
 | 
        
           |  |  | 192 |                 $row_offset++;
 | 
        
           |  |  | 193 |             }
 | 
        
           |  |  | 194 |         }
 | 
        
           |  |  | 195 |         $row_offset++;
 | 
        
           |  |  | 196 |         return $row_offset;
 | 
        
           |  |  | 197 |     }
 | 
        
           |  |  | 198 |   | 
        
           |  |  | 199 |     /**
 | 
        
           |  |  | 200 |      * Calculates the value of the item (time, course, course category)
 | 
        
           |  |  | 201 |      *
 | 
        
           |  |  | 202 |      * @param stdClass $item
 | 
        
           |  |  | 203 |      * @param stdClass $feedback
 | 
        
           |  |  | 204 |      * @param int $courseid
 | 
        
           |  |  | 205 |      * @return string
 | 
        
           |  |  | 206 |      */
 | 
        
           |  |  | 207 |     protected function get_current_value($item, $feedback, $courseid) {
 | 
        
           |  |  | 208 |         global $DB;
 | 
        
           |  |  | 209 |         switch ($item->presentation) {
 | 
        
           |  |  | 210 |             case self::MODE_RESPONSETIME:
 | 
        
           |  |  | 211 |                 if ($feedback->anonymous != FEEDBACK_ANONYMOUS_YES) {
 | 
        
           |  |  | 212 |                     // Response time is not allowed in anonymous feedbacks.
 | 
        
           |  |  | 213 |                     return time();
 | 
        
           |  |  | 214 |                 }
 | 
        
           |  |  | 215 |                 break;
 | 
        
           |  |  | 216 |             case self::MODE_COURSE:
 | 
        
           |  |  | 217 |                 $course = get_course($courseid);
 | 
        
           |  |  | 218 |                 return format_string($course->shortname, true,
 | 
        
           |  |  | 219 |                         array('context' => context_course::instance($course->id)));
 | 
        
           |  |  | 220 |                 break;
 | 
        
           |  |  | 221 |             case self::MODE_CATEGORY:
 | 
        
           |  |  | 222 |                 if ($courseid !== SITEID) {
 | 
        
           |  |  | 223 |                     $coursecategory = $DB->get_record_sql('SELECT cc.id, cc.name FROM {course_categories} cc, {course} c '
 | 
        
           |  |  | 224 |                             . 'WHERE c.category = cc.id AND c.id = ?', array($courseid));
 | 
        
           |  |  | 225 |                     return format_string($coursecategory->name, true,
 | 
        
           |  |  | 226 |                             array('context' => context_coursecat::instance($coursecategory->id)));
 | 
        
           |  |  | 227 |                 }
 | 
        
           |  |  | 228 |                 break;
 | 
        
           |  |  | 229 |         }
 | 
        
           |  |  | 230 |         return '';
 | 
        
           |  |  | 231 |     }
 | 
        
           |  |  | 232 |   | 
        
           |  |  | 233 |     /**
 | 
        
           |  |  | 234 |      * Adds an input element to the complete form
 | 
        
           |  |  | 235 |      *
 | 
        
           |  |  | 236 |      * @param stdClass $item
 | 
        
           |  |  | 237 |      * @param mod_feedback_complete_form $form
 | 
        
           |  |  | 238 |      */
 | 
        
           |  |  | 239 |     public function complete_form_element($item, $form) {
 | 
        
           |  |  | 240 |         if ($form->get_mode() == mod_feedback_complete_form::MODE_VIEW_RESPONSE) {
 | 
        
           |  |  | 241 |             $value = strval($form->get_item_value($item));
 | 
        
           |  |  | 242 |         } else {
 | 
        
           |  |  | 243 |             $value = $this->get_current_value($item,
 | 
        
           |  |  | 244 |                     $form->get_feedback(), $form->get_current_course_id());
 | 
        
           |  |  | 245 |         }
 | 
        
           |  |  | 246 |         $printval = $this->get_printval($item, (object)['value' => $value]);
 | 
        
           |  |  | 247 |   | 
        
           |  |  | 248 |         $class = '';
 | 
        
           |  |  | 249 |         switch ($item->presentation) {
 | 
        
           |  |  | 250 |             case self::MODE_RESPONSETIME:
 | 
        
           |  |  | 251 |                 $class = 'info-responsetime';
 | 
        
           |  |  | 252 |                 $value = $value ? self::CURRENTTIMESTAMP : '';
 | 
        
           |  |  | 253 |                 break;
 | 
        
           |  |  | 254 |             case self::MODE_COURSE:
 | 
        
           |  |  | 255 |                 $class = 'info-course';
 | 
        
           |  |  | 256 |                 break;
 | 
        
           |  |  | 257 |             case self::MODE_CATEGORY:
 | 
        
           |  |  | 258 |                 $class = 'info-category';
 | 
        
           |  |  | 259 |                 break;
 | 
        
           |  |  | 260 |         }
 | 
        
           |  |  | 261 |   | 
        
           |  |  | 262 |         $name = $this->get_display_name($item);
 | 
        
           |  |  | 263 |         $inputname = $item->typ . '_' . $item->id;
 | 
        
           |  |  | 264 |   | 
        
           |  |  | 265 |         $element = $form->add_form_element($item,
 | 
        
           |  |  | 266 |                 ['select', $inputname, $name,
 | 
        
           |  |  | 267 |                     array($value => $printval),
 | 
        
           |  |  | 268 |                     array('class' => $class)],
 | 
        
           |  |  | 269 |                 false,
 | 
        
           |  |  | 270 |                 false);
 | 
        
           |  |  | 271 |         $form->set_element_default($inputname, $value);
 | 
        
           |  |  | 272 |         $element->freeze();
 | 
        
           |  |  | 273 |         if ($form->get_mode() == mod_feedback_complete_form::MODE_COMPLETE) {
 | 
        
           |  |  | 274 |             $element->setPersistantFreeze(true);
 | 
        
           |  |  | 275 |         }
 | 
        
           |  |  | 276 |     }
 | 
        
           |  |  | 277 |   | 
        
           |  |  | 278 |     /**
 | 
        
           |  |  | 279 |      * Converts the value from complete_form data to the string value that is stored in the db.
 | 
        
           |  |  | 280 |      * @param mixed $value element from mod_feedback_complete_form::get_data() with the name $item->typ.'_'.$item->id
 | 
        
           |  |  | 281 |      * @return string
 | 
        
           |  |  | 282 |      */
 | 
        
           |  |  | 283 |     public function create_value($value) {
 | 
        
           |  |  | 284 |         if ($value === self::CURRENTTIMESTAMP) {
 | 
        
           |  |  | 285 |             return strval(time());
 | 
        
           |  |  | 286 |         }
 | 
        
           |  |  | 287 |         return parent::create_value($value);
 | 
        
           |  |  | 288 |     }
 | 
        
           |  |  | 289 |   | 
        
           |  |  | 290 |     public function can_switch_require() {
 | 
        
           |  |  | 291 |         return false;
 | 
        
           |  |  | 292 |     }
 | 
        
           |  |  | 293 |   | 
        
           |  |  | 294 |     public function get_data_for_external($item) {
 | 
        
           |  |  | 295 |         global $DB;
 | 
        
           |  |  | 296 |         $feedback = $DB->get_record('feedback', array('id' => $item->feedback), '*', MUST_EXIST);
 | 
        
           |  |  | 297 |         // Return the default value (course name, category name or timestamp).
 | 
        
           |  |  | 298 |         return $this->get_current_value($item, $feedback, $feedback->course);
 | 
        
           |  |  | 299 |     }
 | 
        
           |  |  | 300 |   | 
        
           |  |  | 301 |     /**
 | 
        
           |  |  | 302 |      * Return the analysis data ready for external functions.
 | 
        
           |  |  | 303 |      *
 | 
        
           |  |  | 304 |      * @param stdClass $item     the item (question) information
 | 
        
           |  |  | 305 |      * @param int      $groupid  the group id to filter data (optional)
 | 
        
           |  |  | 306 |      * @param int      $courseid the course id (optional)
 | 
        
           |  |  | 307 |      * @return array an array of data with non scalar types json encoded
 | 
        
           |  |  | 308 |      * @since  Moodle 3.3
 | 
        
           |  |  | 309 |      */
 | 
        
           |  |  | 310 |     public function get_analysed_for_external($item, $groupid = false, $courseid = false) {
 | 
        
           |  |  | 311 |   | 
        
           |  |  | 312 |         $externaldata = array();
 | 
        
           |  |  | 313 |         $data = $this->get_analysed($item, $groupid, $courseid);
 | 
        
           |  |  | 314 |   | 
        
           |  |  | 315 |         if (is_array($data->data)) {
 | 
        
           |  |  | 316 |             foreach ($data->data as $d) {
 | 
        
           |  |  | 317 |                 $externaldata[] = json_encode($d);
 | 
        
           |  |  | 318 |             }
 | 
        
           |  |  | 319 |         }
 | 
        
           |  |  | 320 |         return $externaldata;
 | 
        
           |  |  | 321 |     }
 | 
        
           |  |  | 322 | }
 |