diff --git a/classes/question/question.php b/classes/question/question.php
index b8049ab1a..7526889d7 100644
--- a/classes/question/question.php
+++ b/classes/question/question.php
@@ -181,20 +181,39 @@ public function __construct($id = 0, $question = null, $context = null, $params
}
/**
- * Short name for this question type - no spaces, etc..
+ * Short name for this question type - no spaces, etc.
* @return string
*/
abstract public function helpname();
/**
- * Build a question from data.
+ * Build a question from id.
* @param int $qtype
* @param int|array $qdata
* @param \stdClass $context
* @return mixed
*/
public static function question_builder($qtype, $qdata = null, $context = null) {
- $qclassname = '\\mod_questionnaire\\question\\'.self::qtypename($qtype);
+ $qclassname = '\\mod_questionnaire\\question\\' . self::qtypename($qtype);
+ $qid = 0;
+ if (!empty($qdata) && is_array($qdata)) {
+ $qdata = (object)$qdata;
+ } else if (!empty($qdata) && is_int($qdata)) {
+ $qid = $qdata;
+ }
+ return new $qclassname($qid, $qdata, $context, ['type_id' => $qtype]);
+ }
+
+ /**
+ * Build a question from FQCN.
+ * @param string $qtypefqcn
+ * @param int $qtype
+ * @param int|array $qdata
+ * @param \stdClass $context
+ * @return mixed
+ */
+ public static function question_builder_fqcn($qtypefqcn, $qtype, $qdata = null, $context = null) {
+ $qclassname = (string) $qtypefqcn;
$qid = 0;
if (!empty($qdata) && is_array($qdata)) {
$qdata = (object)$qdata;
diff --git a/db/install.php b/db/install.php
index 2e630363c..4b8cea3c0 100644
--- a/db/install.php
+++ b/db/install.php
@@ -35,6 +35,7 @@ function xmldb_questionnaire_install() {
$questiontype->type = 'Yes/No';
$questiontype->has_choices = 'n';
$questiontype->response_table = 'response_bool';
+ $questiontype->fqcn = '\\mod_questionnaire\\question\\yesno';
$id = $DB->insert_record('questionnaire_question_type', $questiontype);
$questiontype = new stdClass();
@@ -42,6 +43,7 @@ function xmldb_questionnaire_install() {
$questiontype->type = 'Text Box';
$questiontype->has_choices = 'n';
$questiontype->response_table = 'response_text';
+ $questiontype->fqcn = '\\mod_questionnaire\\question\\text';
$id = $DB->insert_record('questionnaire_question_type', $questiontype);
$questiontype = new stdClass();
@@ -49,6 +51,7 @@ function xmldb_questionnaire_install() {
$questiontype->type = 'Essay Box';
$questiontype->has_choices = 'n';
$questiontype->response_table = 'response_text';
+ $questiontype->fqcn = '\\mod_questionnaire\\question\\essay';
$id = $DB->insert_record('questionnaire_question_type', $questiontype);
$questiontype = new stdClass();
@@ -56,6 +59,7 @@ function xmldb_questionnaire_install() {
$questiontype->type = 'Radio Buttons';
$questiontype->has_choices = 'y';
$questiontype->response_table = 'resp_single';
+ $questiontype->fqcn = '\\mod_questionnaire\\question\\radio';
$id = $DB->insert_record('questionnaire_question_type', $questiontype);
$questiontype = new stdClass();
@@ -63,6 +67,7 @@ function xmldb_questionnaire_install() {
$questiontype->type = 'Check Boxes';
$questiontype->has_choices = 'y';
$questiontype->response_table = 'resp_multiple';
+ $questiontype->fqcn = '\\mod_questionnaire\\question\\check';
$id = $DB->insert_record('questionnaire_question_type', $questiontype);
$questiontype = new stdClass();
@@ -70,6 +75,7 @@ function xmldb_questionnaire_install() {
$questiontype->type = 'Dropdown Box';
$questiontype->has_choices = 'y';
$questiontype->response_table = 'resp_single';
+ $questiontype->fqcn = '\\mod_questionnaire\\question\\drop';
$id = $DB->insert_record('questionnaire_question_type', $questiontype);
$questiontype = new stdClass();
@@ -77,6 +83,7 @@ function xmldb_questionnaire_install() {
$questiontype->type = 'Rate (scale 1..5)';
$questiontype->has_choices = 'y';
$questiontype->response_table = 'response_rank';
+ $questiontype->fqcn = '\\mod_questionnaire\\question\\rate';
$id = $DB->insert_record('questionnaire_question_type', $questiontype);
$questiontype = new stdClass();
@@ -84,6 +91,7 @@ function xmldb_questionnaire_install() {
$questiontype->type = 'Date';
$questiontype->has_choices = 'n';
$questiontype->response_table = 'response_date';
+ $questiontype->fqcn = '\\mod_questionnaire\\question\\date';
$id = $DB->insert_record('questionnaire_question_type', $questiontype);
$questiontype = new stdClass();
@@ -91,6 +99,7 @@ function xmldb_questionnaire_install() {
$questiontype->type = 'Numeric';
$questiontype->has_choices = 'n';
$questiontype->response_table = 'response_text';
+ $questiontype->fqcn = '\\mod_questionnaire\\question\\numerical';
$id = $DB->insert_record('questionnaire_question_type', $questiontype);
$questiontype = new stdClass();
@@ -98,6 +107,7 @@ function xmldb_questionnaire_install() {
$questiontype->type = 'Page Break';
$questiontype->has_choices = 'n';
$questiontype->response_table = '';
+ $questiontype->fqcn = '\\mod_questionnaire\\question\\pagebreak';
$id = $DB->insert_record('questionnaire_question_type', $questiontype);
$questiontype = new stdClass();
@@ -105,6 +115,7 @@ function xmldb_questionnaire_install() {
$questiontype->type = 'Section Text';
$questiontype->has_choices = 'n';
$questiontype->response_table = '';
+ $questiontype->fqcn = '\\mod_questionnaire\\question\\sectiontext';
$id = $DB->insert_record('questionnaire_question_type', $questiontype);
}
diff --git a/db/install.xml b/db/install.xml
index a1b7af0b6..109849781 100644
--- a/db/install.xml
+++ b/db/install.xml
@@ -105,6 +105,7 @@
+
diff --git a/db/upgrade.php b/db/upgrade.php
index daf754d28..51f4988a9 100644
--- a/db/upgrade.php
+++ b/db/upgrade.php
@@ -983,6 +983,67 @@ function xmldb_questionnaire_upgrade($oldversion=0) {
upgrade_mod_savepoint(true, 2020062301, 'questionnaire');
}
+ if ($oldversion < 2022121501) {
+ // Add new FQCN configuration for question types.
+ $table = new xmldb_table('questionnaire_question_type');
+ $field = new xmldb_field('fqcn', XMLDB_TYPE_CHAR, '256', null, XMLDB_NOTNULL, null, 'fqcn', null);
+
+ // Conditionally launch add field.
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ $qtypes = $DB->get_recordset('questionnaire_question_type', null);
+
+ foreach ($qtypes as $questiontype) {
+ $questiontype->fqcn = '\\mod_questionnaire\\question\\';
+ switch ($questiontype->typeid) {
+ case 1:
+ $questiontype->fqcn .= 'yesno';
+ break;
+ case 2:
+ $questiontype->fqcn .= 'text';
+ break;
+ case 3:
+ $questiontype->fqcn .= 'essay';
+ break;
+ case 4:
+ $questiontype->fqcn .= 'radio';
+ break;
+ case 5:
+ $questiontype->fqcn .= 'check';
+ break;
+ case 6:
+ $questiontype->fqcn .= 'drop';
+ break;
+ case 8:
+ $questiontype->fqcn .= 'rate';
+ break;
+ case 9:
+ $questiontype->fqcn .= 'date';
+ break;
+ case 10:
+ $questiontype->fqcn .= 'numerical';
+ break;
+ case 99:
+ $questiontype->fqcn .= 'pagebreak';
+ break;
+ case 100:
+ $questiontype->fqcn .= 'sectiontext';
+ break;
+ default:
+ $unknowntype = true;
+ }
+
+ if (!$unknowntype) {
+ $DB->update_record('questionnaire_question_type', $questiontype);
+ }
+ }
+
+ // Questionnaire savepoint reached.
+ upgrade_mod_savepoint(true, 2022121501, 'questionnaire');
+ }
+
return $result;
}
diff --git a/lang/en/questionnaire.php b/lang/en/questionnaire.php
index d904e11b9..919b70528 100644
--- a/lang/en/questionnaire.php
+++ b/lang/en/questionnaire.php
@@ -149,6 +149,7 @@
$string['downloadtextformat_link'] = 'mod/questionnaire/report#Download_in_text_format';
$string['downloadtypes'] = 'Report type';
$string['dropdown'] = 'Dropdown Box';
+$string['dropdownbox'] = 'Dropdown Box';
$string['dropdown_help'] = 'There is no real advantage to using the Dropdown Box over using the Radio Buttons
except perhaps for longish lists of options, to save screen space.';
$string['dropdown_link'] = 'mod/questionnaire/questions#Dropdown_Box';
@@ -386,6 +387,8 @@
$string['overviewnumrespvw1'] = 'response';
$string['owner'] = 'Owner';
$string['page'] = 'Page';
+$string['pagebreak'] = '----- Page Break -----';
+$string['pagebreak_help'] = '----- Page Break -----';
$string['pageof'] = 'Page {$a->page} of {$a->totpages}';
$string['parent'] = 'Parent';
$string['participant'] = 'Participant';
diff --git a/locallib.php b/locallib.php
index 24f365e04..a62b2b309 100644
--- a/locallib.php
+++ b/locallib.php
@@ -466,34 +466,62 @@ function questionnaire_get_survey_select($courseid=0, $type='') {
* @param int $id
* @return lang_string|mixed|string
* @throws coding_exception
+ * @deprecated Please use questionnaire_get_type_name() instead.
*/
-function questionnaire_get_type ($id) {
- switch ($id) {
- case 1:
- return get_string('yesno', 'questionnaire');
- case 2:
- return get_string('textbox', 'questionnaire');
- case 3:
- return get_string('essaybox', 'questionnaire');
- case 4:
- return get_string('radiobuttons', 'questionnaire');
- case 5:
- return get_string('checkboxes', 'questionnaire');
- case 6:
- return get_string('dropdown', 'questionnaire');
- case 8:
- return get_string('ratescale', 'questionnaire');
- case 9:
- return get_string('date', 'questionnaire');
- case 10:
- return get_string('numeric', 'questionnaire');
- case 100:
- return get_string('sectiontext', 'questionnaire');
- case 99:
- return get_string('sectionbreak', 'questionnaire');
- default:
- return $id;
+function questionnaire_get_type($id) {
+ return questionnaire_get_type_name($id);
+}
+
+/**
+ * Return the language string for the specified question type.
+ * @param int $id
+ * @return lang_string|mixed|string
+ * @throws coding_exception
+ */
+function questionnaire_get_type_name($id) {
+ global $DB;
+
+ if ($qtypeobject = $DB->get_record('questionnaire_question_type', ['typeid' => $id], '*', MUST_EXIST)) {
+ $qtype = preg_replace("/[^a-zA-Z]+/", "", strtolower($qtypeobject->type));
+
+ $qtypeobjectnamespace = explode('\\', questionnaire_get_question_type_object($id)->fqcn)[1];
+
+ return get_string($qtype, $qtypeobjectnamespace);
+ } else {
+ return '';
+ }
+}
+
+/**
+ * Return the language string for all question types.
+ * @return array
+ * @throws coding_exception
+ */
+function questionnaire_get_all_question_types() {
+ global $DB;
+
+ $qtypes = $DB->get_records('questionnaire_question_type', [], 'typeid',
+ 'typeid, type, has_choices, response_table');
+
+ foreach ($qtypes as $qtype) {
+ $qtypenames[$qtype->typeid] = $qtype->type;
}
+
+ return $qtypenames;
+}
+
+/**
+ * Return an object of the specified question type.
+ * @param int $id
+ * @return stdClass
+ * @throws coding_exception
+ */
+function questionnaire_get_question_type_object($id) {
+ global $DB;
+
+ $qtypeobject = $DB->get_record('questionnaire_question_type', ['typeid' => $id], '*', MUST_EXIST);
+
+ return $qtypeobject;
}
/**
@@ -876,7 +904,8 @@ function questionnaire_prep_for_questionform($questionnaire, $qid, $qtype) {
}
}
} else {
- $question = \mod_questionnaire\question\question::question_builder($qtype);
+ $question = questionnaire_get_question_type_object($qtype);
+ $question = \mod_questionnaire\question\question::question_builder_fqcn($question->fqcn, $qtype);
$question->sid = $questionnaire->survey->id;
$question->id = $questionnaire->cm->id;
$question->type_id = $qtype;
@@ -890,7 +919,7 @@ function questionnaire_prep_for_questionform($questionnaire, $qid, $qtype) {
}
/**
- * Get the standard page contructs and check for validity.
+ * Get the standard page constructs and check for validity.
* @param int $id The coursemodule id.
* @param int $a The module instance id.
* @return array An array with the $cm, $course, and $questionnaire records in that order.
diff --git a/questionnaire.class.php b/questionnaire.class.php
index 0a2da7985..46f3cff1a 100644
--- a/questionnaire.class.php
+++ b/questionnaire.class.php
@@ -141,9 +141,9 @@ public function add_questions($sid = false) {
$sec = 1;
$isbreak = false;
foreach ($records as $record) {
-
- $this->questions[$record->id] = \mod_questionnaire\question\question::question_builder($record->type_id,
- $record, $this->context);
+ $qtypeobject = questionnaire_get_question_type_object($record->type_id);
+ $this->questions[$record->id] = \mod_questionnaire\question\question::question_builder_fqcn($qtypeobject->fqcn,
+ $record->type_id, $record, $this->context);
if ($record->type_id != QUESPAGEBREAK) {
$this->questionsbysec[$sec][] = $record->id;
@@ -3020,7 +3020,8 @@ protected function get_survey_all_responses($rid = '', $userid = '', $groupid =
}
foreach ($uniquetypes as $type) {
- $question = \mod_questionnaire\question\question::question_builder($type);
+ $qtypeobject = questionnaire_get_question_type_object($type);
+ $question = \mod_questionnaire\question\question::question_builder_fqcn($qtypeobject->fqcn, $type);
if (!isset($question->responsetype)) {
continue;
}
diff --git a/questions.php b/questions.php
index 464b7e92a..3bcadb26a 100644
--- a/questions.php
+++ b/questions.php
@@ -120,7 +120,7 @@
// Log question deleted event.
$context = context_module::instance($questionnaire->cm->id);
- $questiontype = \mod_questionnaire\question\question::qtypename($questionnaire->questions[$qid]->type_id);
+ $questiontype = questionnaire_get_all_question_types()[$questionnaire->questions[$qid]->type_id];
$params = array(
'context' => $context,
'courseid' => $questionnaire->course->id,
@@ -220,7 +220,8 @@
$questionrec->surveyid = $qformdata->sid;
$questionrec->type_id = QUESPAGEBREAK;
$questionrec->content = 'break';
- $question = \mod_questionnaire\question\question::question_builder(QUESPAGEBREAK);
+ $qtypeobject = questionnaire_get_question_type_object(QUESPAGEBREAK);
+ $question = \mod_questionnaire\question\question::question_builder_fqcn($qtypeobject->fqcn, QUESPAGEBREAK);
$question->add($questionrec);
$reload = true;
} else {
@@ -296,7 +297,7 @@
// Log question created event.
if (isset($qformdata)) {
$context = context_module::instance($questionnaire->cm->id);
- $questiontype = \mod_questionnaire\question\question::qtypename($qformdata->type_id);
+ $questiontype = questionnaire_get_all_question_types()[$qformdata->type_id];
$params = array(
'context' => $context,
'courseid' => $questionnaire->course->id,
@@ -413,5 +414,6 @@
} else {
$questionnaire->page->add_to_page('formarea', $questionsform->render());
}
+
echo $questionnaire->renderer->render($questionnaire->page);
echo $questionnaire->renderer->footer();