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] [Versions 401 and 402] [Versions 401 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  /**
  18   * Survey external API
  19   *
  20   * @package    mod_survey
  21   * @category   external
  22   * @copyright  2015 Juan Leyva <juan@moodle.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   * @since      Moodle 3.0
  25   */
  26  
  27  use core_course\external\helper_for_get_mods_by_courses;
  28  
  29  defined('MOODLE_INTERNAL') || die;
  30  
  31  require_once($CFG->libdir . '/externallib.php');
  32  require_once($CFG->dirroot . '/mod/survey/lib.php');
  33  
  34  /**
  35   * Survey external functions
  36   *
  37   * @package    mod_survey
  38   * @category   external
  39   * @copyright  2015 Juan Leyva <juan@moodle.com>
  40   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41   * @since      Moodle 3.0
  42   */
  43  class mod_survey_external extends external_api {
  44  
  45      /**
  46       * Describes the parameters for get_surveys_by_courses.
  47       *
  48       * @return external_function_parameters
  49       * @since Moodle 3.0
  50       */
  51      public static function get_surveys_by_courses_parameters() {
  52          return new external_function_parameters (
  53              array(
  54                  'courseids' => new external_multiple_structure(
  55                      new external_value(PARAM_INT, 'course id'), 'Array of course ids', VALUE_DEFAULT, array()
  56                  ),
  57              )
  58          );
  59      }
  60  
  61      /**
  62       * Returns a list of surveys in a provided list of courses,
  63       * if no list is provided all surveys that the user can view will be returned.
  64       *
  65       * @param array $courseids the course ids
  66       * @return array of surveys details
  67       * @since Moodle 3.0
  68       */
  69      public static function get_surveys_by_courses($courseids = array()) {
  70          global $CFG, $USER, $DB;
  71  
  72          $returnedsurveys = array();
  73          $warnings = array();
  74  
  75          $params = self::validate_parameters(self::get_surveys_by_courses_parameters(), array('courseids' => $courseids));
  76  
  77          $mycourses = array();
  78          if (empty($params['courseids'])) {
  79              $mycourses = enrol_get_my_courses();
  80              $params['courseids'] = array_keys($mycourses);
  81          }
  82  
  83          // Ensure there are courseids to loop through.
  84          if (!empty($params['courseids'])) {
  85  
  86              list($courses, $warnings) = external_util::validate_courses($params['courseids'], $mycourses);
  87  
  88              // Get the surveys in this course, this function checks users visibility permissions.
  89              // We can avoid then additional validate_context calls.
  90              $surveys = get_all_instances_in_courses("survey", $courses);
  91              foreach ($surveys as $survey) {
  92                  $context = context_module::instance($survey->coursemodule);
  93                  if (empty(trim($survey->intro))) {
  94                      $tempo = $DB->get_field("survey", "intro", array("id" => $survey->template));
  95                      $survey->intro = get_string($tempo, "survey");
  96                  }
  97  
  98                  // Entry to return.
  99                  $surveydetails = helper_for_get_mods_by_courses::standard_coursemodule_element_values(
 100                          $survey, 'mod_survey', 'moodle/course:manageactivities', 'mod/survey:participate');
 101  
 102                  if (has_capability('mod/survey:participate', $context)) {
 103                      $surveydetails['template']  = $survey->template;
 104                      $surveydetails['days']      = $survey->days;
 105                      $surveydetails['questions'] = $survey->questions;
 106                      $surveydetails['surveydone'] = survey_already_done($survey->id, $USER->id) ? 1 : 0;
 107                  }
 108  
 109                  if (has_capability('moodle/course:manageactivities', $context)) {
 110                      $surveydetails['timecreated']   = $survey->timecreated;
 111                      $surveydetails['timemodified']  = $survey->timemodified;
 112                  }
 113                  $returnedsurveys[] = $surveydetails;
 114              }
 115          }
 116          $result = array();
 117          $result['surveys'] = $returnedsurveys;
 118          $result['warnings'] = $warnings;
 119          return $result;
 120      }
 121  
 122      /**
 123       * Describes the get_surveys_by_courses return value.
 124       *
 125       * @return external_single_structure
 126       * @since Moodle 3.0
 127       */
 128      public static function get_surveys_by_courses_returns() {
 129          return new external_single_structure(
 130              array(
 131                  'surveys' => new external_multiple_structure(
 132                      new external_single_structure(array_merge(
 133                         helper_for_get_mods_by_courses::standard_coursemodule_elements_returns(true),
 134                         [
 135                              'template' => new external_value(PARAM_INT, 'Survey type', VALUE_OPTIONAL),
 136                              'days' => new external_value(PARAM_INT, 'Days', VALUE_OPTIONAL),
 137                              'questions' => new external_value(PARAM_RAW, 'Question ids', VALUE_OPTIONAL),
 138                              'surveydone' => new external_value(PARAM_INT, 'Did I finish the survey?', VALUE_OPTIONAL),
 139                              'timecreated' => new external_value(PARAM_INT, 'Time of creation', VALUE_OPTIONAL),
 140                              'timemodified' => new external_value(PARAM_INT, 'Time of last modification', VALUE_OPTIONAL),
 141                          ]
 142                      ), 'Surveys')
 143                  ),
 144                  'warnings' => new external_warnings(),
 145              )
 146          );
 147      }
 148  
 149      /**
 150       * Returns description of method parameters
 151       *
 152       * @return external_function_parameters
 153       * @since Moodle 3.0
 154       */
 155      public static function view_survey_parameters() {
 156          return new external_function_parameters(
 157              array(
 158                  'surveyid' => new external_value(PARAM_INT, 'survey instance id')
 159              )
 160          );
 161      }
 162  
 163      /**
 164       * Trigger the course module viewed event and update the module completion status.
 165       *
 166       * @param int $surveyid the survey instance id
 167       * @return array of warnings and status result
 168       * @since Moodle 3.0
 169       * @throws moodle_exception
 170       */
 171      public static function view_survey($surveyid) {
 172          global $DB, $USER;
 173  
 174          $params = self::validate_parameters(self::view_survey_parameters(),
 175                                              array(
 176                                                  'surveyid' => $surveyid
 177                                              ));
 178          $warnings = array();
 179  
 180          // Request and permission validation.
 181          $survey = $DB->get_record('survey', array('id' => $params['surveyid']), '*', MUST_EXIST);
 182          list($course, $cm) = get_course_and_cm_from_instance($survey, 'survey');
 183  
 184          $context = context_module::instance($cm->id);
 185          self::validate_context($context);
 186          require_capability('mod/survey:participate', $context);
 187  
 188          $viewed = survey_already_done($survey->id, $USER->id) ? 'graph' : 'form';
 189  
 190          // Trigger course_module_viewed event and completion.
 191          survey_view($survey, $course, $cm, $context, $viewed);
 192  
 193          $result = array();
 194          $result['status'] = true;
 195          $result['warnings'] = $warnings;
 196          return $result;
 197      }
 198  
 199      /**
 200       * Returns description of method result value
 201       *
 202       * @return external_description
 203       * @since Moodle 3.0
 204       */
 205      public static function view_survey_returns() {
 206          return new external_single_structure(
 207              array(
 208                  'status' => new external_value(PARAM_BOOL, 'status: true if success'),
 209                  'warnings' => new external_warnings()
 210              )
 211          );
 212      }
 213  
 214      /**
 215       * Returns description of method parameters
 216       *
 217       * @return external_function_parameters
 218       * @since Moodle 3.0
 219       */
 220      public static function get_questions_parameters() {
 221          return new external_function_parameters(
 222              array(
 223                  'surveyid' => new external_value(PARAM_INT, 'survey instance id')
 224              )
 225          );
 226      }
 227  
 228      /**
 229       * Get the complete list of questions for the survey, including subquestions.
 230       *
 231       * @param int $surveyid the survey instance id
 232       * @return array of warnings and the question list
 233       * @since Moodle 3.0
 234       * @throws moodle_exception
 235       */
 236      public static function get_questions($surveyid) {
 237          global $DB, $USER;
 238  
 239          $params = self::validate_parameters(self::get_questions_parameters(),
 240                                              array(
 241                                                  'surveyid' => $surveyid
 242                                              ));
 243          $warnings = array();
 244  
 245          // Request and permission validation.
 246          $survey = $DB->get_record('survey', array('id' => $params['surveyid']), '*', MUST_EXIST);
 247          list($course, $cm) = get_course_and_cm_from_instance($survey, 'survey');
 248  
 249          $context = context_module::instance($cm->id);
 250          self::validate_context($context);
 251          require_capability('mod/survey:participate', $context);
 252  
 253          $mainquestions = survey_get_questions($survey);
 254  
 255          foreach ($mainquestions as $question) {
 256              if ($question->type >= 0) {
 257                  // Parent is used in subquestions.
 258                  $question->parent = 0;
 259                  $questions[] = survey_translate_question($question);
 260  
 261                  // Check if the question has subquestions.
 262                  if ($question->multi) {
 263                      $subquestions = survey_get_subquestions($question);
 264                      foreach ($subquestions as $sq) {
 265                          $sq->parent = $question->id;
 266                          $questions[] = survey_translate_question($sq);
 267                      }
 268                  }
 269              }
 270          }
 271  
 272          $result = array();
 273          $result['questions'] = $questions;
 274          $result['warnings'] = $warnings;
 275          return $result;
 276      }
 277  
 278      /**
 279       * Returns description of method result value
 280       *
 281       * @return external_description
 282       * @since Moodle 3.0
 283       */
 284      public static function get_questions_returns() {
 285          return new external_single_structure(
 286              array(
 287                  'questions' => new external_multiple_structure(
 288                      new external_single_structure(
 289                          array(
 290                              'id' => new external_value(PARAM_INT, 'Question id'),
 291                              'text' => new external_value(PARAM_RAW, 'Question text'),
 292                              'shorttext' => new external_value(PARAM_RAW, 'Question short text'),
 293                              'multi' => new external_value(PARAM_RAW, 'Subquestions ids'),
 294                              'intro' => new external_value(PARAM_RAW, 'The question intro'),
 295                              'type' => new external_value(PARAM_INT, 'Question type'),
 296                              'options' => new external_value(PARAM_RAW, 'Question options'),
 297                              'parent' => new external_value(PARAM_INT, 'Parent question (for subquestions)'),
 298                          ), 'Questions'
 299                      )
 300                  ),
 301                  'warnings' => new external_warnings()
 302              )
 303          );
 304      }
 305  
 306      /**
 307       * Describes the parameters for submit_answers.
 308       *
 309       * @return external_function_parameters
 310       * @since Moodle 3.0
 311       */
 312      public static function submit_answers_parameters() {
 313          return new external_function_parameters(
 314              array(
 315                  'surveyid' => new external_value(PARAM_INT, 'Survey id'),
 316                  'answers' => new external_multiple_structure(
 317                      new external_single_structure(
 318                          array(
 319                              'key' => new external_value(PARAM_RAW, 'Answer key'),
 320                              'value' => new external_value(PARAM_RAW, 'Answer value')
 321                          )
 322                      )
 323                  ),
 324              )
 325          );
 326      }
 327  
 328      /**
 329       * Submit the answers for a given survey.
 330       *
 331       * @param int $surveyid the survey instance id
 332       * @param array $answers the survey answers
 333       * @return array of warnings and status result
 334       * @since Moodle 3.0
 335       * @throws moodle_exception
 336       */
 337      public static function submit_answers($surveyid, $answers) {
 338          global $DB, $USER;
 339  
 340          $params = self::validate_parameters(self::submit_answers_parameters(),
 341                                              array(
 342                                                  'surveyid' => $surveyid,
 343                                                  'answers' => $answers
 344                                              ));
 345          $warnings = array();
 346  
 347          // Request and permission validation.
 348          $survey = $DB->get_record('survey', array('id' => $params['surveyid']), '*', MUST_EXIST);
 349          list($course, $cm) = get_course_and_cm_from_instance($survey, 'survey');
 350  
 351          $context = context_module::instance($cm->id);
 352          self::validate_context($context);
 353          require_capability('mod/survey:participate', $context);
 354  
 355          if (survey_already_done($survey->id, $USER->id)) {
 356              throw new moodle_exception("alreadysubmitted", "survey");
 357          }
 358  
 359          // Build the answers array. Data is cleaned inside the survey_save_answers function.
 360          $answers = array();
 361          foreach ($params['answers'] as $answer) {
 362              $key = $answer['key'];
 363              $answers[$key] = $answer['value'];
 364          }
 365  
 366          survey_save_answers($survey, $answers, $course, $context);
 367  
 368          $result = array();
 369          $result['status'] = true;
 370          $result['warnings'] = $warnings;
 371          return $result;
 372      }
 373  
 374      /**
 375       * Returns description of method result value
 376       *
 377       * @return external_description
 378       * @since Moodle 3.0
 379       */
 380      public static function submit_answers_returns() {
 381          return new external_single_structure(
 382              array(
 383                  'status' => new external_value(PARAM_BOOL, 'status: true if success'),
 384                  'warnings' => new external_warnings()
 385              )
 386          );
 387      }
 388  
 389  }