Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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) {
 156          echo "<table class=\"analysis itemtype_{$item->typ}\">";
 157          $analysed_item = $this->get_analysed($item, $groupid, $courseid);
 158          $data = $analysed_item->data;
 159          if (is_array($data)) {
 160              echo '<tr><th colspan="2" align="left">';
 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 colspan="2" 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  }