Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]

   1  <?php
   2  
   3  // This file is part of Moodle - http://moodle.org/
   4  //
   5  // Moodle is free software: you can redistribute it and/or modify
   6  // it under the terms of the GNU General Public License as published by
   7  // the Free Software Foundation, either version 3 of the License, or
   8  // (at your option) any later version.
   9  //
  10  // Moodle is distributed in the hope that it will be useful,
  11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  // GNU General Public License for more details.
  14  //
  15  // You should have received a copy of the GNU General Public License
  16  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  17  
  18  /**
  19   * This file is responsible for producing the downloadable versions of a survey
  20   * module.
  21   *
  22   * @package   mod_survey
  23   * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  24   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  require_once ("../../config.php");
  28  
  29  // Check that all the parameters have been provided.
  30  
  31  $id    = required_param('id', PARAM_INT);    // Course Module ID
  32  $type  = optional_param('type', 'xls', PARAM_ALPHA);
  33  $group = optional_param('group', 0, PARAM_INT);
  34  
  35  if (! $cm = get_coursemodule_from_id('survey', $id)) {
  36      throw new \moodle_exception('invalidcoursemodule');
  37  }
  38  
  39  if (! $course = $DB->get_record("course", array("id"=>$cm->course))) {
  40      throw new \moodle_exception('coursemisconf');
  41  }
  42  
  43  $context = context_module::instance($cm->id);
  44  
  45  $PAGE->set_url('/mod/survey/download.php', array('id'=>$id, 'type'=>$type, 'group'=>$group));
  46  
  47  require_login($course, false, $cm);
  48  require_capability('mod/survey:download', $context) ;
  49  
  50  if (! $survey = $DB->get_record("survey", array("id"=>$cm->instance))) {
  51      throw new \moodle_exception('invalidsurveyid', 'survey');
  52  }
  53  
  54  $params = array(
  55      'objectid' => $survey->id,
  56      'context' => $context,
  57      'courseid' => $course->id,
  58      'other' => array('type' => $type, 'groupid' => $group)
  59  );
  60  $event = \mod_survey\event\report_downloaded::create($params);
  61  $event->trigger();
  62  
  63  /// Check to see if groups are being used in this survey
  64  
  65  $groupmode = groups_get_activity_groupmode($cm);   // Groups are being used
  66  
  67  if ($groupmode and $group) {
  68      $users = get_users_by_capability($context, 'mod/survey:participate', '', '', '', '', $group, null, false);
  69  } else {
  70      $users = get_users_by_capability($context, 'mod/survey:participate', '', '', '', '', '', null, false);
  71      $group = false;
  72  }
  73  
  74  // The order of the questions
  75  $order = explode(",", $survey->questions);
  76  
  77  // Get the actual questions from the database
  78  $questions = $DB->get_records_list("survey_questions", "id", $order);
  79  
  80  // Get an ordered array of questions
  81  $orderedquestions = array();
  82  
  83  $virtualscales = false;
  84  foreach ($order as $qid) {
  85      $orderedquestions[$qid] = $questions[$qid];
  86      // Check if this question is using virtual scales
  87      if (!$virtualscales && $questions[$qid]->type < 0) {
  88          $virtualscales = true;
  89      }
  90  }
  91  $nestedorder = array();//will contain the subquestions attached to the main questions
  92  $preparray = array();
  93  
  94  foreach ($orderedquestions as $qid=>$question) {
  95      //$orderedquestions[$qid]->text = get_string($question->text, "survey");
  96      if (!empty($question->multi)) {
  97          $actualqids = explode(",", $questions[$qid]->multi);
  98          foreach ($actualqids as $subqid) {
  99              if (!empty($orderedquestions[$subqid]->type)) {
 100                  $orderedquestions[$subqid]->type = $questions[$qid]->type;
 101              }
 102          }
 103      } else {
 104          $actualqids = array($qid);
 105      }
 106      if ($virtualscales && $questions[$qid]->type < 0) {
 107          $nestedorder[$qid] = $actualqids;
 108      } else if (!$virtualscales && $question->type >= 0) {
 109          $nestedorder[$qid] = $actualqids;
 110      } else {
 111          //todo andrew this was added by me. Is it correct?
 112          $nestedorder[$qid] = array();
 113      }
 114  }
 115  
 116  $reversednestedorder = array();
 117  foreach ($nestedorder as $qid=>$subqidarray) {
 118      foreach ($subqidarray as $subqui) {
 119          $reversednestedorder[$subqui] = $qid;
 120      }
 121  }
 122  
 123  //need to get info on the sub-questions from the db and merge the arrays of questions
 124  $allquestions = array_merge($questions, $DB->get_records_list("survey_questions", "id", array_keys($reversednestedorder)));
 125  
 126  //array_merge() messes up the keys so reinstate them
 127  $questions = array();
 128  foreach($allquestions as $question) {
 129      $questions[$question->id] = $question;
 130  
 131      //while were iterating over the questions get the question text
 132      $questions[$question->id]->text = get_string($questions[$question->id]->text, "survey");
 133  }
 134  unset($allquestions);
 135  
 136  // Get and collate all the results in one big array
 137  if (! $surveyanswers = $DB->get_records("survey_answers", array("survey"=>$survey->id), "time ASC")) {
 138      throw new \moodle_exception('cannotfindanswer', 'survey');
 139  }
 140  
 141  $results = array();
 142  
 143  foreach ($surveyanswers as $surveyanswer) {
 144      if (!$group || isset($users[$surveyanswer->userid])) {
 145          //$questionid = $reversednestedorder[$surveyanswer->question];
 146          $questionid = $surveyanswer->question;
 147          if (!array_key_exists($surveyanswer->userid, $results)) {
 148              $results[$surveyanswer->userid] = array('time'=>$surveyanswer->time);
 149          }
 150          $results[$surveyanswer->userid][$questionid]['answer1'] = $surveyanswer->answer1;
 151          $results[$surveyanswer->userid][$questionid]['answer2'] = $surveyanswer->answer2;
 152      }
 153  }
 154  
 155  // Output the file as a valid ODS spreadsheet if required
 156  $coursecontext = context_course::instance($course->id);
 157  $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext));
 158  
 159  if ($type == "ods") {
 160      require_once("$CFG->libdir/odslib.class.php");
 161  
 162  /// Calculate file name
 163      $downloadfilename = clean_filename(strip_tags($courseshortname.' '.format_string($survey->name, true))).'.ods';
 164  /// Creating a workbook
 165      $workbook = new MoodleODSWorkbook("-");
 166  /// Sending HTTP headers
 167      $workbook->send($downloadfilename);
 168  /// Creating the first worksheet
 169      $myxls = $workbook->add_worksheet(core_text::substr(strip_tags(format_string($survey->name,true)), 0, 31));
 170  
 171      $header = array("surveyid","surveyname","userid","firstname","lastname","email","idnumber","time", "notes");
 172      $col=0;
 173      foreach ($header as $item) {
 174          $myxls->write_string(0,$col++,$item);
 175      }
 176  
 177      foreach ($nestedorder as $key => $nestedquestions) {
 178          foreach ($nestedquestions as $key2 => $qid) {
 179              $question = $questions[$qid];
 180              if ($question->type == "0" || $question->type == "1" || $question->type == "3" || $question->type == "-1")  {
 181                  $myxls->write_string(0,$col++,"$question->text");
 182              }
 183              if ($question->type == "2" || $question->type == "3")  {
 184                  $myxls->write_string(0,$col++,"$question->text (preferred)");
 185              }
 186          }
 187      }
 188  
 189  //      $date = $workbook->addformat();
 190  //      $date->set_num_format('mmmm-d-yyyy h:mm:ss AM/PM'); // ?? adjust the settings to reflect the PHP format below
 191  
 192      $row = 0;
 193      foreach ($results as $user => $rest) {
 194          $col = 0;
 195          $row++;
 196          if (! $u = $DB->get_record("user", array("id"=>$user))) {
 197              throw new \moodle_exception('invaliduserid');
 198          }
 199          if ($n = $DB->get_record("survey_analysis", array("survey"=>$survey->id, "userid"=>$user))) {
 200              $notes = $n->notes;
 201          } else {
 202              $notes = "No notes made";
 203          }
 204          $myxls->write_string($row,$col++,$survey->id);
 205          $myxls->write_string($row,$col++,strip_tags(format_text($survey->name,true)));
 206          $myxls->write_string($row,$col++,$user);
 207          $myxls->write_string($row,$col++,$u->firstname);
 208          $myxls->write_string($row,$col++,$u->lastname);
 209          $myxls->write_string($row,$col++,$u->email);
 210          $myxls->write_string($row,$col++,$u->idnumber);
 211          $myxls->write_string($row,$col++, userdate($results[$user]["time"], "%d-%b-%Y %I:%M:%S %p") );
 212  //          $myxls->write_number($row,$col++,$results[$user]["time"],$date);
 213          $myxls->write_string($row,$col++,$notes);
 214  
 215          foreach ($nestedorder as $key => $nestedquestions) {
 216              foreach ($nestedquestions as $key2 => $qid) {
 217                  $question = $questions[$qid];
 218                  if ($question->type == "0" || $question->type == "1" || $question->type == "3" || $question->type == "-1")  {
 219                      $myxls->write_string($row,$col++, $results[$user][$qid]["answer1"] );
 220                  }
 221                  if ($question->type == "2" || $question->type == "3")  {
 222                      $myxls->write_string($row, $col++, $results[$user][$qid]["answer2"] );
 223                  }
 224              }
 225          }
 226      }
 227      $workbook->close();
 228  
 229      exit;
 230  }
 231  
 232  // Output the file as a valid Excel spreadsheet if required
 233  
 234  if ($type == "xls") {
 235      require_once("$CFG->libdir/excellib.class.php");
 236  
 237  /// Calculate file name
 238      $downloadfilename = clean_filename(strip_tags($courseshortname.' '.format_string($survey->name,true))).'.xls';
 239  /// Creating a workbook
 240      $workbook = new MoodleExcelWorkbook("-");
 241  /// Sending HTTP headers
 242      $workbook->send($downloadfilename);
 243  /// Creating the first worksheet
 244      $myxls = $workbook->add_worksheet(core_text::substr(strip_tags(format_string($survey->name,true)), 0, 31));
 245  
 246      $header = array("surveyid","surveyname","userid","firstname","lastname","email","idnumber","time", "notes");
 247      $col=0;
 248      foreach ($header as $item) {
 249          $myxls->write_string(0,$col++,$item);
 250      }
 251  
 252      foreach ($nestedorder as $key => $nestedquestions) {
 253          foreach ($nestedquestions as $key2 => $qid) {
 254              $question = $questions[$qid];
 255  
 256              if ($question->type == "0" || $question->type == "1" || $question->type == "3" || $question->type == "-1")  {
 257                  $myxls->write_string(0,$col++,"$question->text");
 258              }
 259              if ($question->type == "2" || $question->type == "3")  {
 260                  $myxls->write_string(0,$col++,"$question->text (preferred)");
 261              }
 262          }
 263      }
 264  
 265  //      $date = $workbook->addformat();
 266  //      $date->set_num_format('mmmm-d-yyyy h:mm:ss AM/PM'); // ?? adjust the settings to reflect the PHP format below
 267  
 268      $row = 0;
 269      foreach ($results as $user => $rest) {
 270          $col = 0;
 271          $row++;
 272          if (! $u = $DB->get_record("user", array("id"=>$user))) {
 273              throw new \moodle_exception('invaliduserid');
 274          }
 275          if ($n = $DB->get_record("survey_analysis", array("survey"=>$survey->id, "userid"=>$user))) {
 276              $notes = $n->notes;
 277          } else {
 278              $notes = "No notes made";
 279          }
 280          $myxls->write_string($row,$col++,$survey->id);
 281          $myxls->write_string($row,$col++,strip_tags(format_text($survey->name,true)));
 282          $myxls->write_string($row,$col++,$user);
 283          $myxls->write_string($row,$col++,$u->firstname);
 284          $myxls->write_string($row,$col++,$u->lastname);
 285          $myxls->write_string($row,$col++,$u->email);
 286          $myxls->write_string($row,$col++,$u->idnumber);
 287          $myxls->write_string($row,$col++, userdate($results[$user]["time"], "%d-%b-%Y %I:%M:%S %p") );
 288  //          $myxls->write_number($row,$col++,$results[$user]["time"],$date);
 289          $myxls->write_string($row,$col++,$notes);
 290  
 291          foreach ($nestedorder as $key => $nestedquestions) {
 292              foreach ($nestedquestions as $key2 => $qid) {
 293                  $question = $questions[$qid];
 294                  if (($question->type == "0" || $question->type == "1" || $question->type == "3" || $question->type == "-1")
 295                      && array_key_exists($qid, $results[$user]) ){
 296                  $myxls->write_string($row,$col++, $results[$user][$qid]["answer1"] );
 297              }
 298                  if (($question->type == "2" || $question->type == "3")
 299                      && array_key_exists($qid, $results[$user]) ){
 300                  $myxls->write_string($row, $col++, $results[$user][$qid]["answer2"] );
 301              }
 302          }
 303      }
 304      }
 305      $workbook->close();
 306  
 307      exit;
 308  }
 309  
 310  // Otherwise, return the text file.
 311  
 312  // Print header to force download
 313  
 314  header("Content-Type: application/download\n");
 315  
 316  $downloadfilename = clean_filename(strip_tags($courseshortname.' '.format_string($survey->name,true)));
 317  header("Content-Disposition: attachment; filename=\"$downloadfilename.txt\"");
 318  
 319  // Print names of all the fields
 320  
 321  echo "surveyid    surveyname    userid    firstname    lastname    email    idnumber    time    ";
 322  
 323  foreach ($nestedorder as $key => $nestedquestions) {
 324      foreach ($nestedquestions as $key2 => $qid) {
 325          $question = $questions[$qid];
 326      if ($question->type == "0" || $question->type == "1" || $question->type == "3" || $question->type == "-1")  {
 327          echo "$question->text    ";
 328      }
 329      if ($question->type == "2" || $question->type == "3")  {
 330           echo "$question->text (preferred)    ";
 331      }
 332  }
 333  }
 334  echo "\n";
 335  
 336  // Print all the lines of data.
 337  foreach ($results as $user => $rest) {
 338      if (! $u = $DB->get_record("user", array("id"=>$user))) {
 339          throw new \moodle_exception('invaliduserid');
 340      }
 341      echo $survey->id."\t";
 342      echo strip_tags(format_string($survey->name,true))."\t";
 343      echo $user."\t";
 344      echo $u->firstname."\t";
 345      echo $u->lastname."\t";
 346      echo $u->email."\t";
 347      echo $u->idnumber."\t";
 348      echo userdate($results[$user]["time"], "%d-%b-%Y %I:%M:%S %p")."\t";
 349  
 350      foreach ($nestedorder as $key => $nestedquestions) {
 351          foreach ($nestedquestions as $key2 => $qid) {
 352              $question = $questions[$qid];
 353  
 354              if ($question->type == "0" || $question->type == "1" || $question->type == "3" || $question->type == "-1")  {
 355                  echo $results[$user][$qid]["answer1"]."    ";
 356              }
 357              if ($question->type == "2" || $question->type == "3")  {
 358                  echo $results[$user][$qid]["answer2"]."    ";
 359              }
 360          }
 361      }
 362      echo "\n";
 363  }
 364  
 365  exit;