protected function response_survey_display($data) { static $uniquetag = 0; // To make sure all radios have unique names. if (!isset($data->{'q' . $this->id}) || !is_array($data->{'q' . $this->id})) { $data->{'q' . $this->id} = array(); } // Check if rate question has one line only to display full width columns of choices. $nocontent = false; foreach ($this->choices as $cid => $choice) { $content = $choice->content; if ($choice->content == '') { $nocontent = true; break; } } $width = $nocontent ? "50%" : "99.9%"; echo '<table class="individual" border="0" cellspacing="1" cellpadding="0" style="width:' . $width . '">'; echo '<tbody><tr>'; $osgood = $this->precise == 3; $bg = 'c0'; $nameddegrees = 0; $cidnamed = array(); $n = array(); // Max length of potential named degree in column head. $maxndlen = 0; foreach ($this->choices as $cid => $choice) { $content = $choice->content; if (preg_match("/^[0-9]{1,3}=/", $content, $ndd)) { $ndd = format_text(substr($content, strlen($ndd[0])), FORMAT_HTML); $n[$nameddegrees] = $ndd; if (strlen($ndd) > $maxndlen) { $maxndlen = strlen($ndd); } $cidnamed[$cid] = true; $nameddegrees++; } } if ($osgood) { if ($maxndlen < 4) { $sidecolwidth = '45%'; } else { if ($maxndlen < 13) { $sidecolwidth = '40%'; } else { $sidecolwidth = '30%'; } } echo '<td style="width: ' . $sidecolwidth . '; text-align: right;"></td>'; $nn = 100 - $sidecolwidth * 2; $colwidth = $nn / $this->length . '%'; $textalign = 'right'; } else { echo '<td style="width: 49%"></td>'; $colwidth = 50 / $this->length . '%'; $textalign = 'left'; } for ($j = 0; $j < $this->length; $j++) { if (isset($n[$j])) { $str = $n[$j]; } else { $str = $j + 1; } echo '<td style="width:' . $colwidth . '; text-align:center" class="' . $bg . ' smalltext">' . $str . '</td>'; if ($bg == 'c0') { $bg = 'c1'; } else { $bg = 'c0'; } } if ($this->precise == 1) { echo '<td style="width:' . $colwidth . '; text-align:center" class="' . $bg . '">' . get_string('notapplicable', 'questionnaire') . '</td>'; } if ($osgood) { echo '<td style="width:' . $sidecolwidth . '%;"></td>'; } echo '</tr>'; foreach ($this->choices as $cid => $choice) { // Do not print column names if named column exist. if (!array_key_exists($cid, $cidnamed)) { $str = 'q' . "{$this->id}_{$cid}"; echo '<tr>'; $content = $choice->content; $contents = questionnaire_choice_values($content); if ($contents->modname) { $content = $contents->text; } if ($osgood) { list($content, $contentright) = array_merge(preg_split('/[|]/', $content), array(' ')); } echo '<td style="text-align:' . $textalign . '">' . format_text($content, FORMAT_HTML) . ' </td>'; $bg = 'c0'; for ($j = 0; $j < $this->length; $j++) { $checked = isset($data->{$str}) && $j == $data->{$str} ? ' checked="checked"' : ''; // N/A column checked. $checkedna = isset($data->{$str}) && $data->{$str} == -1 ? ' checked="checked"' : ''; if ($checked) { echo '<td style="text-align:center;" class="selected">'; echo '<span class="selected">' . '<input type="radio" name="' . $str . $j . $uniquetag++ . '" checked="checked" /></span>'; } else { echo '<td style="text-align:center;" class="' . $bg . '">'; echo '<span class="unselected">' . '<input type="radio" disabled="disabled" name="' . $str . $j . $uniquetag++ . '" onclick="this.checked=false;" /></span>'; } echo '</td>'; if ($bg == 'c0') { $bg = 'c1'; } else { $bg = 'c0'; } } if ($this->precise == 1) { // N/A column. echo '<td style="width:auto; text-align:center;" class="' . $bg . '">'; if ($checkedna) { echo '<span class="selected">' . '<input type="radio" name="' . $str . $j . $uniquetag++ . 'na" checked="checked" /></span>'; } else { echo '<span class="unselected">' . '<input type="radio" name="' . $str . $uniquetag++ . 'na" onclick="this.checked=false;" /></span>'; } echo '</td>'; } if ($osgood) { echo '<td> ' . format_text($contentright, FORMAT_HTML) . '</td>'; } echo '</tr>'; } } echo '</tbody></table>'; }
public function generate_csv($rid = '', $userid = '', $choicecodes = 1, $choicetext = 0, $currentgroupid) { global $DB; raise_memory_limit('1G'); $output = array(); $stringother = get_string('other', 'questionnaire'); $config = get_config('questionnaire', 'downloadoptions'); $options = empty($config) ? array() : explode(',', $config); $columns = array(); $types = array(); foreach ($options as $option) { if (in_array($option, array('response', 'submitted', 'id'))) { $columns[] = get_string($option, 'questionnaire'); $types[] = 0; } else { $columns[] = get_string($option); $types[] = 1; } } $nbinfocols = count($columns); $idtocsvmap = array('0', '0', '1', '1', '0', '0', '0', '0', '0', '1', '0'); if (!($survey = $DB->get_record('questionnaire_survey', array('id' => $this->survey->id)))) { print_error('surveynotexists', 'questionnaire'); } // Get all responses for this survey in one go. $allresponsesrs = $this->get_survey_all_responses($rid, $userid); // Do we have any questions of type RADIO, DROP, CHECKBOX OR RATE? If so lets get all their choices in one go. $choicetypes = $this->choice_types(); // Get unique list of question types used in this survey. $uniquetypes = $this->get_survey_questiontypes(); if (count(array_intersect($choicetypes, $uniquetypes) > 0)) { $choiceparams = [$this->survey->id]; $choicesql = "\n SELECT DISTINCT c.id as cid, q.id as qid, q.precise AS precise, q.name, c.content\n FROM {questionnaire_question} q\n JOIN {questionnaire_quest_choice} c ON question_id = q.id\n WHERE q.survey_id = ? ORDER BY cid ASC\n "; $choicerecords = $DB->get_records_sql($choicesql, $choiceparams); $choicesbyqid = []; if (!empty($choicerecords)) { // Hash the options by question id. foreach ($choicerecords as $choicerecord) { if (!isset($choicesbyqid[$choicerecord->qid])) { // New question id detected, intialise empty array to store choices. $choicesbyqid[$choicerecord->qid] = []; } $choicesbyqid[$choicerecord->qid][$choicerecord->cid] = $choicerecord; } } } $num = 1; $questionidcols = []; foreach ($this->questions as $question) { // Skip questions that aren't response capable. if (!isset($question->response)) { continue; } // Establish the table's field names. $qid = $question->id; $qpos = $question->position; $col = $question->name; $type = $question->type_id; if (in_array($type, $choicetypes)) { /* single or multiple or rate */ if (!isset($choicesbyqid[$qid])) { throw new coding_exception('Choice question has no choices!', 'question id ' . $qid . ' of type ' . $type); } $choices = $choicesbyqid[$qid]; $subqnum = 0; switch ($type) { case QUESRADIO: // Single. // Single. case QUESDROP: $columns[][$qpos] = $col; $questionidcols[][$qpos] = $qid; array_push($types, $idtocsvmap[$type]); $thisnum = 1; foreach ($choices as $choice) { $content = $choice->content; // If "Other" add a column for the actual "other" text entered. if (preg_match('/^!other/', $content)) { $col = $choice->name . '_' . $stringother; $columns[][$qpos] = $col; $questionidcols[][$qpos] = null; array_push($types, '0'); } } break; case QUESCHECK: // Multiple. $thisnum = 1; foreach ($choices as $choice) { $content = $choice->content; $modality = ''; $contents = questionnaire_choice_values($content); if ($contents->modname) { $modality = $contents->modname; } else { if ($contents->title) { $modality = $contents->title; } else { $modality = strip_tags($contents->text); } } $col = $choice->name . '->' . $modality; $columns[][$qpos] = $col; $questionidcols[][$qpos] = $qid . '_' . $choice->cid; array_push($types, '0'); // If "Other" add a column for the "other" checkbox. Then add a column for the actual "other" text entered. if (preg_match('/^!other/', $content)) { $content = $stringother; $col = $choice->name . '->[' . $content . ']'; $columns[][$qpos] = $col; $questionidcols[][$qpos] = null; array_push($types, '0'); } } break; case QUESRATE: // Rate. foreach ($choices as $choice) { $nameddegrees = 0; $modality = ''; $content = $choice->content; $osgood = false; if ($choice->precise == 3) { $osgood = true; } if (preg_match("/^[0-9]{1,3}=/", $content, $ndd)) { $nameddegrees++; } else { if ($osgood) { list($contentleft, $contentright) = array_merge(preg_split('/[|]/', $content), array(' ')); $contents = questionnaire_choice_values($contentleft); if ($contents->title) { $contentleft = $contents->title; } $contents = questionnaire_choice_values($contentright); if ($contents->title) { $contentright = $contents->title; } $modality = strip_tags($contentleft . '|' . $contentright); $modality = preg_replace("/[\r\n\t]/", ' ', $modality); } else { $contents = questionnaire_choice_values($content); if ($contents->modname) { $modality = $contents->modname; } else { if ($contents->title) { $modality = $contents->title; } else { $modality = strip_tags($contents->text); $modality = preg_replace("/[\r\n\t]/", ' ', $modality); } } } $col = $choice->name . '->' . $modality; $columns[][$qpos] = $col; $questionidcols[][$qpos] = $qid . '_' . $choice->cid; array_push($types, $idtocsvmap[$type]); } } break; } } else { $columns[][$qpos] = $col; $questionidcols[][$qpos] = $qid; array_push($types, $idtocsvmap[$type]); } $num++; } array_push($output, $columns); $numrespcols = count($output[0]); // Number of columns used for storing question responses. // Flatten questionidcols. $tmparr = []; for ($c = 0; $c < $nbinfocols; $c++) { $tmparr[] = null; // Pad with non question columns. } foreach ($questionidcols as $i => $positions) { foreach ($positions as $position => $qid) { $tmparr[] = $qid; } } $questionidcols = $tmparr; // Create array of question positions hashed by question / question + choiceid. // And array of questions hashed by position. $questionpositions = []; $questionsbyposition = []; $p = 0; foreach ($questionidcols as $qid) { if ($qid === null) { // This is just padding, skip. $p++; continue; } $questionpositions[$qid] = $p; if (strpos($qid, '_') !== false) { $tmparr = explode('_', $qid); $questionid = $tmparr[0]; } else { $questionid = $qid; } $questionsbyposition[$p] = $this->questions[$questionid]; $p++; } $formatoptions = new stdClass(); $formatoptions->filter = false; // To prevent any filtering in CSV output. // Get textual versions of responses, add them to output at the correct col position. $prevresprow = false; // Previous response row. $row = []; foreach ($allresponsesrs as $responserow) { $rid = $responserow->rid; $qid = $responserow->question_id; $question = $this->questions[$qid]; $qtype = intval($question->type_id); $questionobj = $this->questions[$qid]; if ($prevresprow !== false && $prevresprow->rid !== $rid) { $output[] = $this->process_csv_row($row, $prevresprow, $currentgroupid, $questionsbyposition, $nbinfocols, $numrespcols); $row = []; } if ($qtype === QUESRATE || $qtype === QUESCHECK) { $key = $qid . '_' . $responserow->choice_id; $position = $questionpositions[$key]; if ($qtype === QUESRATE) { $choicetxt = $responserow->rank + 1; } else { $content = $choicesbyqid[$qid][$responserow->choice_id]->content; if (preg_match('/^!other/', $content)) { // If this is an "other" column, put the text entered in the next position. $row[$position + 1] = $responserow->response; $choicetxt = empty($responserow->choice_id) ? '0' : '1'; } else { if (!empty($responserow->choice_id)) { $choicetxt = '1'; } else { $choicetxt = '0'; } } } $responsetxt = $choicetxt; $row[$position] = $responsetxt; } else { $position = $questionpositions[$qid]; if ($questionobj->has_choices()) { // This is choice type question, so process as so. $c = 0; if (in_array(intval($question->type_id), $choicetypes)) { $choices = $choicesbyqid[$qid]; // Get position of choice. foreach ($choices as $choice) { $c++; if ($responserow->choice_id === $choice->cid) { break; } } } $content = $choicesbyqid[$qid][$responserow->choice_id]->content; if (preg_match('/^!other/', $content)) { // If this has an "other" text, use it. $responsetxt = get_string('other', 'questionnaire'); $responsetxt1 = $responserow->response; } else { if ($choicecodes == 1 && $choicetext == 1) { $responsetxt = $c . ' : ' . $content; } else { if ($choicecodes == 1) { $responsetxt = $c; } else { $responsetxt = $content; } } } } else { if (intval($qtype) === QUESYESNO) { // At this point, the boolean responses are returned as characters in the "response" // field instead of "choice_id" for csv exports (CONTRIB-6436). $responsetxt = $responserow->response === 'y' ? "1" : "0"; } else { // Strip potential html tags from modality name. $responsetxt = $responserow->response; if (!empty($responsetxt)) { $responsetxt = $responserow->response; $responsetxt = strip_tags($responsetxt); $responsetxt = preg_replace("/[\r\n\t]/", ' ', $responsetxt); } } } $row[$position] = $responsetxt; // Check for "other" text and set it to the next position if present. if (!empty($responsetxt1)) { $row[$position + 1] = $responsetxt1; unset($responsetxt1); } } $prevresprow = $responserow; } // Add final row to output. $output[] = $this->process_csv_row($row, $prevresprow, $currentgroupid, $questionsbyposition, $nbinfocols, $numrespcols); // Change table headers to incorporate actual question numbers. $numcol = 0; $numquestion = 0; $out = ''; $oldkey = 0; for ($i = $nbinfocols; $i < $numrespcols; $i++) { $sep = ''; $thisoutput = current($output[0][$i]); $thiskey = key($output[0][$i]); // Case of unnamed rate single possible answer (full stop char is used for support). if (strstr($thisoutput, '->.')) { $thisoutput = str_replace('->.', '', $thisoutput); } // If variable is not named no separator needed between Question number and potential sub-variables. if ($thisoutput == '' || strstr($thisoutput, '->.') || substr($thisoutput, 0, 2) == '->' || substr($thisoutput, 0, 1) == '_') { $sep = ''; } else { $sep = '_'; } if ($thiskey > $oldkey) { $oldkey = $thiskey; $numquestion++; } // Abbreviated modality name in multiple or rate questions (COLORS->blue=the color of the sky...). $pos = strpos($thisoutput, '='); if ($pos) { $thisoutput = substr($thisoutput, 0, $pos); } $other = $sep . $stringother; $out = 'Q' . sprintf("%02d", $numquestion) . $sep . $thisoutput; $output[0][$i] = $out; } return $output; }
protected function response_survey_display($data) { static $uniquetag = 0; // To make sure all radios have unique names. $horizontal = $this->length; $checked = isset($data->{'q' . $this->id}) ? $data->{'q' . $this->id} : ''; foreach ($this->choices as $id => $choice) { if ($horizontal) { echo ' <span style="white-space:nowrap;">'; } if (strpos($choice->content, '!other') !== 0) { $contents = questionnaire_choice_values($choice->content); $choice->content = $contents->text . $contents->image; if ($id == $checked) { echo '<span class="selected">' . '<input type="radio" name="' . $id . $uniquetag++ . '" checked="checked" /> ' . ($choice->content === '' ? $id : format_text($choice->content, FORMAT_HTML)) . '</span> '; } else { echo '<span class="unselected">' . '<input type="radio" disabled="disabled" name="' . $id . $uniquetag++ . '" onclick="this.checked=false;" /> ' . ($choice->content === '' ? $id : format_text($choice->content, FORMAT_HTML)) . '</span> '; } } else { $othertext = preg_replace(array("/^!other=/", "/^!other/"), array('', get_string('other', 'questionnaire')), $choice->content); $cid = 'q' . $this->id . '_' . $id; if (isset($data->{'q' . $this->id . '_' . $id})) { echo '<span class="selected">' . '<input type="radio" name="' . $id . $uniquetag++ . '" checked="checked" /> ' . $othertext . ' '; echo '<span class="response text">'; echo !empty($data->{$cid}) ? htmlspecialchars($data->{$cid}) : ' '; echo '</span></span>'; } else { echo '<span class="unselected"><input type="radio" name="' . $id . $uniquetag++ . '" onclick="this.checked=false;" /> ' . $othertext . '</span>'; } } if ($horizontal) { echo '</span>'; } else { echo '<br />'; } } }
protected function process_questionnaire_quest_choice($data) { global $CFG, $DB; $data = (object) $data; // Replace the = separator with :: separator in quest_choice content. // This fixes radio button options using old "value"="display" formats. require_once $CFG->dirroot . '/mod/questionnaire/locallib.php'; if (($data->value == null || $data->value == 'NULL') && !preg_match("/^([0-9]{1,3}=.*|!other=.*)\$/", $data->content)) { $content = questionnaire_choice_values($data->content); if ($pos = strpos($content->text, '=')) { $data->content = str_replace('=', '::', $content->text); } } $oldid = $data->id; $data->question_id = $this->get_new_parentid('questionnaire_question'); if (isset($data->dependquestion)) { // Dependquestion. $data->dependquestion = $this->get_mappingid('questionnaire_question', $data->dependquestion); // Dependchoice. // Only change mapping for RADIO and DROP question types, not for YESNO question. $dependquestion = $DB->get_record('questionnaire_question', array('id' => $data->dependquestion), $fields = 'type_id'); if (is_object($dependquestion)) { if ($dependquestion->type_id != 1) { $data->dependchoice = $this->get_mappingid('questionnaire_quest_choice', $data->dependchoice); } } } // Insert the questionnaire_quest_choice record. $newitemid = $DB->insert_record('questionnaire_quest_choice', $data); $this->set_mapping('questionnaire_quest_choice', $oldid, $newitemid); }
function questionnaire_get_parent($question) { global $DB; $qid = $question->id; $parent = array(); $dependquestion = $DB->get_record('questionnaire_question', array('id' => $question->dependquestion), $fields = 'id, position, name, type_id'); if (is_object($dependquestion)) { $qdependchoice = ''; switch ($dependquestion->type_id) { case QUESRADIO: case QUESDROP: $dependchoice = $DB->get_record('questionnaire_quest_choice', array('id' => $question->dependchoice), $fields = 'id,content'); $qdependchoice = $dependchoice->id; $dependchoice = $dependchoice->content; $contents = questionnaire_choice_values($dependchoice); if ($contents->modname) { $dependchoice = $contents->modname; } break; case QUESYESNO: switch ($question->dependchoice) { case 0: $dependchoice = get_string('yes'); $qdependchoice = 'y'; break; case 1: $dependchoice = get_string('no'); $qdependchoice = 'n'; break; } break; } // Qdependquestion, parenttype and qdependchoice fields to be used in preview mode. $parent[$qid]['qdependquestion'] = 'q' . $dependquestion->id; $parent[$qid]['qdependchoice'] = $qdependchoice; $parent[$qid]['parenttype'] = $dependquestion->type_id; // Other fields to be used in Questions edit mode. $parent[$qid]['position'] = $question->position; $parent[$qid]['name'] = $question->name; $parent[$qid]['content'] = $question->content; $parent[$qid]['parentposition'] = $dependquestion->position; $parent[$qid]['parent'] = $dependquestion->name . '->' . $dependchoice; } return $parent; }
public function generate_csv($rid = '', $userid = '', $choicecodes = 1, $choicetext = 0, $currentgroupid) { global $SESSION, $DB; $output = array(); $nbinfocols = 9; // Change this if you want more info columns. $stringother = get_string('other', 'questionnaire'); $columns = array(get_string('response', 'questionnaire'), get_string('submitted', 'questionnaire'), get_string('institution'), get_string('department'), get_string('course'), get_string('group'), get_string('id', 'questionnaire'), get_string('fullname'), get_string('username')); $types = array(0, 0, 1, 1, 1, 1, 0, 1, 1); $arr = array(); $idtocsvmap = array('0', '0', '1', '1', '0', '0', '0', '0', '0', '1', '0'); if (!($survey = $DB->get_record('questionnaire_survey', array('id' => $this->survey->id)))) { print_error('surveynotexists', 'questionnaire'); } $select = 'survey_id = ' . $this->survey->id . ' AND deleted = \'n\' AND type_id < 50'; $fields = 'id, name, type_id, position'; if (!($records = $DB->get_records_select('questionnaire_question', $select, null, 'position', $fields))) { $records = array(); } $num = 1; foreach ($records as $record) { // Establish the table's field names. $qid = $record->id; $qpos = $record->position; $col = $record->name; $type = $record->type_id; if ($type == QUESRADIO || $type == QUESCHECK || $type == QUESRATE) { /* single or multiple or rate */ $sql = "SELECT c.id as cid, q.id as qid, q.precise AS precise, q.name, c.content\n FROM {questionnaire_question} q " . "LEFT JOIN {questionnaire_quest_choice} c ON question_id = q.id " . 'WHERE q.id = ' . $qid . ' ORDER BY cid ASC'; if (!($records2 = $DB->get_records_sql($sql))) { $records2 = array(); } $subqnum = 0; switch ($type) { case QUESRADIO: // Single. $columns[][$qpos] = $col; array_push($types, $idtocsvmap[$type]); $thisnum = 1; foreach ($records2 as $record2) { $content = $record2->content; if (preg_match('/^!other/', $content)) { $col = $record2->name . '_' . $stringother; $columns[][$qpos] = $col; array_push($types, '0'); } } break; case QUESCHECK: // Multiple. $thisnum = 1; foreach ($records2 as $record2) { $content = $record2->content; $modality = ''; if (preg_match('/^!other/', $content)) { $content = $stringother; $col = $record2->name . '->[' . $content . ']'; $columns[][$qpos] = $col; array_push($types, '0'); } $contents = questionnaire_choice_values($content); if ($contents->modname) { $modality = $contents->modname; } else { if ($contents->title) { $modality = $contents->title; } else { $modality = strip_tags($contents->text); } } $col = $record2->name . '->' . $modality; $columns[][$qpos] = $col; array_push($types, '0'); } break; case QUESRATE: // Rate. foreach ($records2 as $record2) { $nameddegrees = 0; $modality = ''; $content = $record2->content; $osgood = false; if ($record2->precise == 3) { $osgood = true; } if (preg_match("/^[0-9]{1,3}=/", $content, $ndd)) { $nameddegrees++; } else { if ($osgood) { list($contentleft, $contentright) = preg_split('/[|]/', $content); $contents = questionnaire_choice_values($contentleft); if ($contents->title) { $contentleft = $contents->title; } $contents = questionnaire_choice_values($contentright); if ($contents->title) { $contentright = $contents->title; } $modality = strip_tags($contentleft . '|' . $contentright); $modality = preg_replace("/[\r\n\t]/", ' ', $modality); } else { $contents = questionnaire_choice_values($content); if ($contents->modname) { $modality = $contents->modname; } else { if ($contents->title) { $modality = $contents->title; } else { $modality = strip_tags($contents->text); $modality = preg_replace("/[\r\n\t]/", ' ', $modality); } } } $col = $record2->name . '->' . $modality; $columns[][$qpos] = $col; array_push($types, $idtocsvmap[$type]); } } break; } } else { $columns[][$qpos] = $col; array_push($types, $idtocsvmap[$type]); } $num++; } array_push($output, $columns); $numcols = count($output[0]); if ($rid) { // Send e-mail for a unique response ($rid). $select = 'survey_id = ' . $this->survey->id . ' AND complete=\'y\' AND id = ' . $rid; $fields = 'id,submitted,username'; if (!($records = $DB->get_records_select('questionnaire_response', $select, null, 'submitted', $fields))) { $records = array(); } } else { if ($userid) { // Download CSV for one user's own responses'. $sql = "SELECT R.id, R.survey_id, R.submitted, R.username\n FROM {questionnaire_response} R\n WHERE R.survey_id='{$this->survey->id}' AND\n R.complete='y' AND\n R.username='******'\n ORDER BY R.id"; if (!($records = $DB->get_records_sql($sql))) { $records = array(); } } else { // Download CSV for all participants (or groups if enabled). $castsql = $DB->sql_cast_char2int('R.username'); if ($currentgroupid == 0) { // All participants. $sql = "SELECT R.id, R.survey_id, R.submitted, R.username\n FROM {questionnaire_response} R\n WHERE R.survey_id='{$this->survey->id}' AND\n R.complete='y'\n ORDER BY R.id"; } else { // Members of a specific group. $sql = "SELECT R.id, R.survey_id, R.submitted, R.username\n FROM {questionnaire_response} R,\n {groups_members} GM\n WHERE R.survey_id='{$this->survey->id}' AND\n R.complete='y' AND\n GM.groupid=" . $currentgroupid . " AND\n " . $castsql . "=GM.userid\n ORDER BY R.id"; } if (!($records = $DB->get_records_sql($sql))) { $records = array(); } } } $isanonymous = $this->respondenttype == 'anonymous'; $formatoptions = new Object(); $formatoptions->filter = false; // To prevent any filtering in CSV output. foreach ($records as $record) { // Get the response. $response = $this->response_select_name($record->id, $choicecodes, $choicetext); $qid = $record->id; // For better compabitility & readability with Excel. $submitted = date(get_string('strfdateformatcsv', 'questionnaire'), $record->submitted); $institution = ''; $department = ''; $username = $record->username; if ($user = $DB->get_record('user', array('id' => $username))) { $institution = $user->institution; $department = $user->department; } // Moodle: // Get the course name that this questionnaire belongs to. if ($survey->realm != 'public') { $courseid = $this->course->id; $coursename = $this->course->fullname; } else { // For a public questionnaire, look for the course that used it. $sql = 'SELECT q.id, q.course, c.fullname ' . 'FROM {questionnaire} q, {questionnaire_attempts} qa, {course} c ' . 'WHERE qa.rid = ? AND q.id = qa.qid AND c.id = q.course'; if ($record = $DB->get_record_sql($sql, array($qid))) { $courseid = $record->course; $coursename = $record->fullname; } else { $courseid = $this->course->id; $coursename = $this->course->fullname; } } // Moodle: // If the username is numeric, try it as a Moodle user id. if (is_numeric($username)) { if ($user = $DB->get_record('user', array('id' => $username))) { $uid = $username; $fullname = fullname($user); $username = $user->username; } } // Moodle: // Determine if the user is a member of a group in this course or not. $groupname = ''; if ($this->cm->groupmode > 0) { if ($currentgroupid > 0) { $groupname = groups_get_group_name($currentgroupid); } else { if ($uid) { if ($groups = groups_get_all_groups($courseid, $uid)) { foreach ($groups as $group) { $groupname .= $group->name . ', '; } $groupname = substr($groupname, 0, strlen($groupname) - 2); } else { $groupname = ' (' . get_string('groupnonmembers') . ')'; } } } } if ($isanonymous) { $fullname = get_string('anonymous', 'questionnaire'); $username = ''; $uid = ''; } $arr = array(); array_push($arr, $qid); array_push($arr, $submitted); array_push($arr, $institution); array_push($arr, $department); array_push($arr, $coursename); array_push($arr, $groupname); array_push($arr, $uid); array_push($arr, $fullname); array_push($arr, $username); // Merge it. for ($i = $nbinfocols; $i < $numcols; $i++) { $qpos = key($columns[$i]); $qname = current($columns[$i]); if (isset($response[$qpos][$qname]) && $response[$qpos][$qname] != '') { $thisresponse = $response[$qpos][$qname]; } else { $thisresponse = ''; } switch ($types[$i]) { case 1: // String // Excel seems to allow "\n" inside a quoted string, but // "\r\n" is used as a record separator and so "\r" may // not occur within a cell. So if one would like to preserve // new-lines in a response, remove the "\n" from the // regex below. // Email format text is plain text for being displayed in Excel, etc. // But it must be stripped of carriage returns. if ($thisresponse) { $thisresponse = format_text($thisresponse, FORMAT_HTML, $formatoptions); $thisresponse = preg_replace("/[\r\n\t]/", ' ', $thisresponse); $thisresponse = preg_replace('/"/', '""', $thisresponse); } // Fall through. // Fall through. case 0: // Number. break; } array_push($arr, $thisresponse); } array_push($output, $arr); } // Change table headers to incorporate actual question numbers. $numcol = 0; $numquestion = 0; $out = ''; $nbrespcols = count($output[0]); $oldkey = 0; for ($i = $nbinfocols; $i < $nbrespcols; $i++) { $sep = ''; $thisoutput = current($output[0][$i]); $thiskey = key($output[0][$i]); // Case of unnamed rate single possible answer (full stop char is used for support). if (strstr($thisoutput, '->.')) { $thisoutput = str_replace('->.', '', $thisoutput); } // If variable is not named no separator needed between Question number and potential sub-variables. if ($thisoutput == '' || strstr($thisoutput, '->.') || substr($thisoutput, 0, 2) == '->' || substr($thisoutput, 0, 1) == '_') { $sep = ''; } else { $sep = '_'; } if ($thiskey > $oldkey) { $oldkey = $thiskey; $numquestion++; } // Abbreviated modality name in multiple or rate questions (COLORS->blue=the color of the sky...). $pos = strpos($thisoutput, '='); if ($pos) { $thisoutput = substr($thisoutput, 0, $pos); } $other = $sep . $stringother; $out = 'Q' . sprintf("%02d", $numquestion) . $sep . $thisoutput; $output[0][$i] = $out; } return $output; }
protected function display_response_choice_results($rows, $rids, $sort) { if (is_array($rids)) { $prtotal = 1; } else { if (is_int($rids)) { $prtotal = 0; } } if ($rows) { foreach ($rows as $idx => $row) { if (strpos($idx, 'other') === 0) { $answer = $row->response; $ccontent = $row->content; $content = preg_replace(array('/^!other=/', '/^!other/'), array('', get_string('other', 'questionnaire')), $ccontent); $content .= ' ' . clean_text($answer); $textidx = $content; $this->counts[$textidx] = !empty($this->counts[$textidx]) ? $this->counts[$textidx] + 1 : 1; } else { $contents = questionnaire_choice_values($row->content); $this->choice = $contents->text . $contents->image; $textidx = $this->choice; $this->counts[$textidx] = !empty($this->counts[$textidx]) ? $this->counts[$textidx] + 1 : 1; } } \mod_questionnaire\response\display_support::mkrespercent($this->counts, count($rids), $this->question->precise, $prtotal, $sort); } else { echo '<p class="generaltable"> ' . get_string('noresponsedata', 'questionnaire') . '</p>'; } }
protected function response_survey_display($data) { global $OUTPUT; static $uniquetag = 0; // To make sure all radios have unique names. $output = ''; $options = array(); foreach ($this->choices as $id => $choice) { $contents = questionnaire_choice_values($choice->content); $options[$id] = format_text($contents->text, FORMAT_HTML); } $output .= '<div class="response drop">'; $output .= html_writer::select($options, 'q' . $this->id . $uniquetag++, isset($data->{'q' . $this->id}) ? $data->{'q' . $this->id} : ''); if (isset($data->{'q' . $this->id})) { $output .= ': <span class="selected">' . $options[$data->{'q' . $this->id}] . '</span></div>'; } return $output; }
function xmldb_questionnaire_upgrade($oldversion = 0) { global $CFG, $DB; $dbman = $DB->get_manager(); // Loads ddl manager and xmldb classes. $result = true; if ($oldversion < 2007120101) { $result &= questionnaire_upgrade_2007120101(); // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2007120101, 'questionnaire'); } if ($oldversion < 2007120102) { // Change enum values to lower case for all tables using them. $enumvals = array('y', 'n'); $table = new xmldb_table('questionnaire_question'); $field = new xmldb_field('required'); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, false, null, 'n'); $dbman->change_field_enum($table, $field); $DB->set_field('questionnaire_question', 'required', 'y', array('required' => 'Y')); $DB->set_field('questionnaire_question', 'required', 'n', array('required' => 'N')); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, XMLDB_ENUM, array('y', 'n'), 'n'); $dbman->change_field_enum($table, $field); $dbman->change_field_default($table, $field); unset($field); $field = new xmldb_field('deleted'); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, false, null, 'n'); $dbman->change_field_enum($table, $field); $DB->set_field('questionnaire_question', 'deleted', 'y', array('deleted' => 'Y')); $DB->set_field('questionnaire_question', 'deleted', 'n', array('deleted' => 'N')); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, XMLDB_ENUM, array('y', 'n'), 'n'); $dbman->change_field_enum($table, $field); $dbman->change_field_default($table, $field); unset($field); $field = new xmldb_field('public'); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, false, null, 'n'); $dbman->change_field_enum($table, $field); $DB->set_field('questionnaire_question', 'public', 'y', array('public' => 'Y')); $DB->set_field('questionnaire_question', 'public', 'n', array('public' => 'N')); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, XMLDB_ENUM, array('y', 'n'), 'y'); $dbman->change_field_enum($table, $field); $dbman->change_field_default($table, $field); unset($field); unset($table); $table = new xmldb_table('questionnaire_question_type'); $field = new xmldb_field('has_choices'); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, false, null, 'n'); $dbman->change_field_enum($table, $field); $DB->set_field('questionnaire_question_type', 'has_choices', 'y', array('has_choices' => 'Y')); $DB->set_field('questionnaire_question_type', 'has_choices', 'n', array('has_choices' => 'N')); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, XMLDB_ENUM, array('y', 'n'), 'y'); $dbman->change_field_enum($table, $field); $dbman->change_field_default($table, $field); unset($field); unset($table); $table = new xmldb_table('questionnaire_response'); $field = new xmldb_field('complete'); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, false, null, 'n'); $dbman->change_field_enum($table, $field); $DB->set_field('questionnaire_response', 'complete', 'y', array('complete' => 'Y')); $DB->set_field('questionnaire_response', 'complete', 'n', array('complete' => 'N')); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, XMLDB_ENUM, array('y', 'n'), 'n'); $dbman->change_field_enum($table, $field); $dbman->change_field_default($table, $field); unset($field); unset($table); $table = new xmldb_table('questionnaire_response_bool'); $field = new xmldb_field('choice_id'); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, false, null, 'n'); $dbman->change_field_enum($table, $field); $DB->set_field('questionnaire_response_bool', 'choice_id', 'y', array('choice_id' => 'Y')); $DB->set_field('questionnaire_response_bool', 'choice_id', 'n', array('choice_id' => 'N')); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, XMLDB_ENUM, array('y', 'n'), 'y'); $dbman->change_field_enum($table, $field); $dbman->change_field_default($table, $field); unset($field); unset($table); $table = new xmldb_table('questionnaire_survey'); $field = new xmldb_field('public'); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, false, null, 'n'); $dbman->change_field_enum($table, $field); $DB->set_field('questionnaire_survey', 'public', 'y', array('public' => 'Y')); $DB->set_field('questionnaire_survey', 'public', 'n', array('public' => 'N')); $field->set_attributes(XMLDB_TYPE_CHAR, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, XMLDB_ENUM, array('y', 'n'), 'y'); $dbman->change_field_enum($table, $field); $dbman->change_field_default($table, $field); unset($field); // Upgrade question_type table with corrected 'response_table' fields. $DB->set_field('questionnaire_question_type', 'response_table', 'resp_single', array('response_table' => 'response_single')); $DB->set_field('questionnaire_question_type', 'response_table', 'resp_multiple', array('response_table' => 'response_multiple')); // Questionnaire savepoint reached.. upgrade_mod_savepoint(true, 2007120102, 'questionnaire'); } if ($oldversion < 2008031902) { $table = new xmldb_table('questionnaire'); $field = new xmldb_field('grade'); $field->set_attributes(XMLDB_TYPE_INTEGER, '10', false, true, false, false, null, 0, 'navigate'); $dbman->add_field($table, $field); unset($field); unset($table); $table = new xmldb_table('questionnaire_response'); $field = new xmldb_field('grade'); $field->set_attributes(XMLDB_TYPE_INTEGER, '10', false, true, false, false, null, 0, 'complete'); $dbman->add_field($table, $field); // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2008031902, 'questionnaire'); } if ($oldversion < 2008031904) { $sql = "SELECT q.id, q.resp_eligible, q.resp_view, cm.id as cmid\n FROM {questionnaire} q, {course_modules} cm, {modules} m\n WHERE m.name='questionnaire' AND m.id=cm.module AND cm.instance=q.id"; if ($rs = $DB->get_recordset_sql($sql)) { $studentroleid = $DB->get_field('role', 'id', array('shortname' => 'student')); $editteacherroleid = $DB->get_field('role', 'id', array('shortname' => 'editingteacher')); $teacherroleid = $DB->get_field('role', 'id', array('shortname' => 'teacher')); $capview = 'mod/questionnaire:view'; $capsubmit = 'mod/questionnaire:submit'; foreach ($rs as $questionnaire) { $context = get_context_instance(CONTEXT_MODULE, $questionnaire->cmid); // Convert questionnaires with resp_eligible = 'all' so that students & teachers have view and submit. if ($questionnaire->resp_eligible == 'all') { assign_capability($capsubmit, CAP_ALLOW, $editteacherroleid, $context->id, true); assign_capability($capsubmit, CAP_ALLOW, $teacherroleid, $context->id, true); // Convert questionnaires with resp_eligible = 'students' so that just students have view and submit. } else { if ($questionnaire->resp_eligible == 'teachers') { assign_capability($capsubmit, CAP_ALLOW, $editteacherroleid, $context->id, true); assign_capability($capsubmit, CAP_ALLOW, $teacherroleid, $context->id, true); assign_capability($capview, CAP_PREVENT, $studentroleid, $context->id, true); assign_capability($capsubmit, CAP_PREVENT, $studentroleid, $context->id, true); } } } $rs->close(); } // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2008031904, 'questionnaire'); } if ($oldversion < 2008031905) { $table = new xmldb_table('questionnaire_survey'); $field = new xmldb_field('changed'); $dbman->drop_field($table, $field); // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2008031905, 'questionnaire'); } if ($oldversion < 2008031906) { $table = new xmldb_table('questionnaire_response_rank'); $field = new xmldb_field('rank'); $field->set_attributes(XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null, null, '0', 'choice_id'); $field->setUnsigned(false); $dbman->change_field_unsigned($table, $field); // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2008031906, 'questionnaire'); } if ($oldversion < 2008060401) { $table = new xmldb_table('questionnaire_question'); $field = new xmldb_field('name'); $field->set_attributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null, 'survey_id'); $field->setNotnull(false); $dbman->change_field_notnull($table, $field); // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2008060401, 'questionnaire'); } if ($oldversion < 2008070702) { $table = new xmldb_table('questionnaire_question_type'); $field = new xmldb_field('response_table'); $field->set_attributes(XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, null, null, 'has_choices'); $field->setNotnull(false); $dbman->change_field_notnull($table, $field); // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2008070702, 'questionnaire'); } if ($oldversion < 2008070703) { $table = new xmldb_table('questionnaire_resp_multiple'); $index = new xmldb_index('response_question'); $index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('response_id', 'question_id', 'choice_id')); if (!$dbman->index_exists($table, $index)) { $dbman->add_index($table, $index); } // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2008070703, 'questionnaire'); } if ($oldversion < 2008070704) { // CONTRIB-1542. $table = new xmldb_table('questionnaire_survey'); $field = new xmldb_field('email'); $field->set_attributes(XMLDB_TYPE_CHAR, '64', null, XMLDB_NOTNULL, null, null, null, null, 'title'); $field->setLength('255'); $dbman->change_field_precision($table, $field); // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2008070704, 'questionnaire'); } if ($oldversion < 2008070705) { // Rename summary field to 'intro' to adhere to new Moodle standard. $table = new xmldb_table('questionnaire'); $field = new xmldb_field('summary'); $field->set_attributes(XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null, 'name'); $dbman->rename_field($table, $field, 'intro'); // Add 'introformat' to adhere to new Moodle standard. $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'intro'); $dbman->add_field($table, $field); // Set all existing records to HTML format. $DB->set_field('questionnaire', 'introformat', 1); // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2008070705, 'questionnaire'); } if ($oldversion < 2008070706) { // CONTRIB-1153. $table = new xmldb_table('questionnaire_survey'); $field = new xmldb_field('public'); if ($dbman->field_exists($table, $field)) { $dbman->drop_field($table, $field); } $table = new xmldb_table('questionnaire_question'); $field = new xmldb_field('public'); if ($dbman->field_exists($table, $field)) { $dbman->drop_field($table, $field); } // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2008070706, 'questionnaire'); } if ($oldversion < 2010110100) { // Drop list of values (enum) from field has_choices on table questionnaire_question_type. $table = new xmldb_table('questionnaire_question_type'); $field = new xmldb_field('has_choices', XMLDB_TYPE_CHAR, '1', null, XMLDB_NOTNULL, null, 'y', 'type'); // Launch drop of list of values from field has_choices. $dbman->drop_enum_from_field($table, $field); // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2010110100, 'questionnaire'); } if ($oldversion < 2010110101) { // Drop list of values (enum) from field respondenttype on table questionnaire. $table = new xmldb_table('questionnaire'); $field = new xmldb_field('respondenttype', XMLDB_TYPE_CHAR, '9', null, XMLDB_NOTNULL, null, 'fullname', 'qtype'); // Launch drop of list of values from field respondenttype. $dbman->drop_enum_from_field($table, $field); // Drop list of values (enum) from field resp_eligible on table questionnaire. $field = new xmldb_field('resp_eligible', XMLDB_TYPE_CHAR, '8', null, XMLDB_NOTNULL, null, 'all', 'respondenttype'); // Launch drop of list of values from field resp_eligible. $dbman->drop_enum_from_field($table, $field); // Drop list of values (enum) from field required on table questionnaire_question. $table = new xmldb_table('questionnaire_question'); $field = new xmldb_field('required', XMLDB_TYPE_CHAR, '1', null, XMLDB_NOTNULL, null, 'n', 'content'); // Launch drop of list of values from field required. $dbman->drop_enum_from_field($table, $field); // Drop list of values (enum) from field deleted on table questionnaire_question. $field = new xmldb_field('deleted', XMLDB_TYPE_CHAR, '1', null, XMLDB_NOTNULL, null, 'n', 'required'); // Launch drop of list of values from field deleted. $dbman->drop_enum_from_field($table, $field); // Drop list of values (enum) from field complete on table questionnaire_response. $table = new xmldb_table('questionnaire_response'); $field = new xmldb_field('complete', XMLDB_TYPE_CHAR, '1', null, XMLDB_NOTNULL, null, 'n', 'submitted'); // Launch drop of list of values from field complete. $dbman->drop_enum_from_field($table, $field); // Drop list of values (enum) from field choice_id on table questionnaire_response_bool. $table = new xmldb_table('questionnaire_response_bool'); $field = new xmldb_field('choice_id', XMLDB_TYPE_CHAR, '1', null, XMLDB_NOTNULL, null, 'y', 'question_id'); // Launch drop of list of values from field choice_id. $dbman->drop_enum_from_field($table, $field); // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2010110101, 'questionnaire'); } if ($oldversion < 2012100800) { // Changing precision of field name on table questionnaire_survey to (255). // First drop the index. $table = new xmldb_table('questionnaire_survey'); $index = new xmldb_index('name'); $index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('name')); $dbman->drop_index($table, $index); // Launch change of precision for field name. $field = new xmldb_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'id'); $dbman->change_field_precision($table, $field); // Add back in the index. $table = new xmldb_table('questionnaire_survey'); $index = new xmldb_index('name'); $index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('name')); $dbman->add_index($table, $index); // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2012100800, 'questionnaire'); } if ($oldversion < 2013062302) { // Adding completionsubmit field to table questionnaire. $table = new xmldb_table('questionnaire'); $field = new xmldb_field('completionsubmit', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'timemodified'); // Conditionally launch add field. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2013062302, 'questionnaire'); } if ($oldversion < 2013062501) { // Skip logic new feature. // Define field dependquestion to be added to questionnaire_question table. $table = new xmldb_table('questionnaire_question'); $field = new xmldb_field('dependquestion', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'deleted'); // Conditionally launch add field. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } $table = new xmldb_table('questionnaire_question'); $field = new xmldb_field('dependchoice', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'dependquestion'); // Conditionally launch add field. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Replace the = separator with :: separator in quest_choice content. // This fixes radio button options using old "value"="display" formats. require_once $CFG->dirroot . '/mod/questionnaire/locallib.php'; $choices = $DB->get_recordset('questionnaire_quest_choice', $conditions = null); $total = $DB->count_records('questionnaire_quest_choice'); if ($total > 0) { $pbar = new progress_bar('convertchoicevalues', 500, true); $i = 1; foreach ($choices as $choice) { if (($choice->value == null || $choice->value == 'NULL') && !preg_match("/^([0-9]{1,3}=.*|!other=.*)\$/", $choice->content)) { $content = questionnaire_choice_values($choice->content); if ($pos = strpos($content->text, '=')) { $newcontent = str_replace('=', '::', $content->text); $choice->content = $newcontent; $DB->update_record('questionnaire_quest_choice', $choice); } } $pbar->update($i, $total, "Convert questionnaire choice value separator - {$i}/{$total}."); $i++; } } // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2013062501, 'questionnaire'); } if ($oldversion < 2013100500) { // Add autonumbering option for questions and pages. $table = new xmldb_table('questionnaire'); $field = new xmldb_field('autonum', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '3', 'completionsubmit'); // Conditionally launch add field. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2013100500, 'questionnaire'); } if ($oldversion < 2013122202) { // Personality test feature. $table = new xmldb_table('questionnaire_survey'); $field = new xmldb_field('feedbacksections', XMLDB_TYPE_INTEGER, '2', null, null, null, null, null); // Conditionally launch add field. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } unset($field); $field = new xmldb_field('feedbacknotes', XMLDB_TYPE_TEXT, null, null, null, null, null); if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } unset($table); unset($field); // Define table questionnaire_fb_sections to be created. $table = new xmldb_table('questionnaire_fb_sections'); $table->add_field('id', XMLDB_TYPE_INTEGER, '18', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('survey_id', XMLDB_TYPE_INTEGER, '18', null, XMLDB_NOTNULL, null, null); $table->add_field('section', XMLDB_TYPE_INTEGER, '2', null, null, null, null); $table->add_field('scorecalculation', XMLDB_TYPE_TEXT, null, null, null, null, null); $table->add_field('sectionlabel', XMLDB_TYPE_CHAR, '50', null, null, null, null); $table->add_field('sectionheading', XMLDB_TYPE_TEXT, null, null, null, null, null); $table->add_field('sectionheadingformat', XMLDB_TYPE_INTEGER, '2', null, null, null, '1'); // Adding keys to table questionnaire_fb_sections. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Conditionally launch create table for assign_user_mapping. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } unset($table); // Define table questionnaire_feedback to be created. $table = new xmldb_table('questionnaire_feedback'); $table->add_field('id', XMLDB_TYPE_INTEGER, '18', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('section_id', XMLDB_TYPE_INTEGER, '18', null, XMLDB_NOTNULL, null, null); $table->add_field('feedbacklabel', XMLDB_TYPE_CHAR, '30', null, null, null, null); $table->add_field('feedbacktext', XMLDB_TYPE_TEXT, null, null, null, null, null); $table->add_field('feedbacktextformat', XMLDB_TYPE_INTEGER, '2', null, null, null, '1'); $table->add_field('minscore', XMLDB_TYPE_NUMBER, '10,5', null, null, null, '0.00000'); $table->add_field('maxscore', XMLDB_TYPE_NUMBER, '10,5', null, null, null, '101.00000'); // Adding keys to table questionnaire_fb_sections. $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); // Conditionally launch create table for assign_user_mapping. if (!$dbman->table_exists($table)) { $dbman->create_table($table); } // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2013122202, 'questionnaire'); } if ($oldversion < 2014010300) { // Personality test with chart. $table = new xmldb_table('questionnaire_survey'); $field = new xmldb_field('chart_type', XMLDB_TYPE_CHAR, '64', null, null, null, null, null); // Conditionally launch add field. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } $field = new xmldb_field('feedbackscores', XMLDB_TYPE_INTEGER, '1', null, null, null, '0'); // Conditionally launch add field. if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2014010300, 'questionnaire'); } if ($oldversion < 2015051101) { // Move the global config value for 'usergraph' to the plugin config setting instead. if (isset($CFG->questionnaire_usergraph)) { set_config('usergraph', $CFG->questionnaire_usergraph, 'questionnaire'); unset_config('questionnaire_usergraph'); } upgrade_mod_savepoint(true, 2015051101, 'questionnaire'); } // Add index to reduce load on the questionnaire_quest_choice table. if ($oldversion < 2015051102) { // Conditionally add an index to the question_id field. $table = new xmldb_table('questionnaire_quest_choice'); $index = new xmldb_index('quest_choice_quesidx', XMLDB_INDEX_NOTUNIQUE, array('question_id')); // Only add the index if it does not exist. if (!$dbman->index_exists($table, $index)) { $dbman->add_index($table, $index); } // Questionnaire savepoint reached. upgrade_mod_savepoint(true, 2015051102, 'questionnaire'); } return $result; }
protected function response_survey_display($data) { static $uniquetag = 0; // To make sure all radios have unique names. $output = ''; if (!isset($data->{'q' . $this->id}) || !is_array($data->{'q' . $this->id})) { $data->{'q' . $this->id} = array(); } $output .= '<div class="response check">'; foreach ($this->choices as $id => $choice) { if (strpos($choice->content, '!other') !== 0) { $contents = questionnaire_choice_values($choice->content); $choice->content = $contents->text . $contents->image; if (in_array($id, $data->{'q' . $this->id})) { $output .= '<span class="selected">' . '<input type="checkbox" name="' . $id . $uniquetag++ . '" checked="checked" onclick="this.checked=true;" /> ' . ($choice->content === '' ? $id : format_text($choice->content, FORMAT_HTML)) . '</span><br />'; } else { $output .= '<span class="unselected">' . '<input type="checkbox" name="' . $id . $uniquetag++ . '" onclick="this.checked=false;" /> ' . ($choice->content === '' ? $id : format_text($choice->content, FORMAT_HTML)) . '</span><br />'; } } else { $othertext = preg_replace(array("/^!other=/", "/^!other/"), array('', get_string('other', 'questionnaire')), $choice->content); $cid = 'q' . $this->id . '_' . $id; if (isset($data->{$cid})) { $output .= '<span class="selected">' . '<input type="checkbox" name="' . $id . $uniquetag++ . '" checked="checked" onclick="this.checked=true;" /> ' . ($othertext === '' ? $id : $othertext) . ' '; $output .= '<span class="response text">'; $output .= !empty($data->{$cid}) ? htmlspecialchars($data->{$cid}) : ' '; $output .= '</span></span><br />'; } else { $output .= '<span class="unselected">' . '<input type="checkbox" name="' . $id . $uniquetag++ . '" onclick="this.checked=false;" /> ' . ($othertext === '' ? $id : $othertext) . '</span><br />'; } } } $output .= '</div>'; return $output; }
public static function mkrescount($counts, $rids, $rows, $question, $precision, $length, $sort) { // Display number of responses to Rate questions - see http://moodle.org/mod/forum/discuss.php?d=185106. global $DB; $nbresponses = count($rids); // Prepare data to be displayed. $isrestricted = $length < count($question->choices) && $precision == 2; $rsql = ''; if (!empty($rids)) { list($rsql, $params) = $DB->get_in_or_equal($rids); $rsql = ' AND response_id ' . $rsql; } array_unshift($params, $question->id); // This is question_id. $sql = 'SELECT r.id, c.content, r.rank, c.id AS choiceid ' . 'FROM {questionnaire_quest_choice} c , ' . '{questionnaire_response_rank} r ' . 'WHERE c.question_id = ?' . ' AND r.question_id = c.question_id' . ' AND r.choice_id = c.id ' . $rsql . ' ORDER BY choiceid, rank ASC'; $choices = $DB->get_records_sql($sql, $params); // Sort rows (results) by average value. if ($sort != 'default') { $sortarray = array(); foreach ($rows as $row) { foreach ($row as $key => $value) { if (!isset($sortarray[$key])) { $sortarray[$key] = array(); } $sortarray[$key][] = $value; } } $orderby = "average"; switch ($sort) { case 'ascending': array_multisort($sortarray[$orderby], SORT_ASC, $rows); break; case 'descending': array_multisort($sortarray[$orderby], SORT_DESC, $rows); break; } } $nbranks = $length; $ranks = array(); foreach ($rows as $row) { $choiceid = $row->id; foreach ($choices as $choice) { if ($choice->choiceid == $choiceid) { $n = 0; for ($i = 0; $i < $nbranks; $i++) { if ($choice->rank == $i) { $n++; if (!isset($ranks[$choice->content][$i])) { $ranks[$choice->content][$i] = 0; } $ranks[$choice->content][$i] += $n; } } } } } // Psettings for display. $strtotal = '<strong>' . get_string('total', 'questionnaire') . '</strong>'; $isna = $precision == 1; $isnahead = ''; $osgood = false; if ($precision == 3) { // Osgood's semantic differential. $osgood = true; } if ($isna) { $isnahead = get_string('notapplicable', 'questionnaire') . '<br />(#)'; } if ($precision == 1) { $na = get_string('notapplicable', 'questionnaire'); } else { $na = ''; } $nameddegrees = 0; $n = array(); foreach ($question->choices as $cid => $choice) { $content = $choice->content; // Check for number from 1 to 3 digits, followed by the equal sign = (to accomodate named degrees). if (preg_match("/^([0-9]{1,3})=(.*)\$/", $content, $ndd)) { $n[$nameddegrees] = format_text($ndd[2], FORMAT_HTML); $nameddegrees++; } else { $contents = questionnaire_choice_values($content); if ($contents->modname) { $choice->content = $contents->text; } } } $headings = array('<span class="smalltext">' . get_string('responses', 'questionnaire') . '</span>'); if ($osgood) { $align = array('right'); } else { $align = array('left'); } // Display the column titles. for ($j = 0; $j < $length; $j++) { if (isset($n[$j])) { $str = $n[$j]; } else { $str = $j + 1; } array_push($headings, '<span class="smalltext">' . $str . '</span>'); array_push($align, 'center'); } if ($osgood) { array_push($headings, ''); array_push($align, 'left'); } array_push($headings, $strtotal); if ($isrestricted) { array_push($headings, get_string('notapplicable', 'questionnaire')); array_push($align, 'center'); } array_push($align, 'center'); if ($na) { array_push($headings, $na); array_push($align, 'center'); } $table = new html_table(); $table->head = $headings; $table->align = $align; $table->attributes['class'] = 'generaltable'; // Now display the responses. foreach ($ranks as $content => $rank) { $data = array(); // Eliminate potential named degrees on Likert scale. if (!preg_match("/^[0-9]{1,3}=/", $content)) { // First display the list of degrees (named or un-named) // number of NOT AVAILABLE responses for this possible answer. $nbna = $counts[$content]->nbna; // TOTAL number of responses for this possible answer. $total = $counts[$content]->num; $nbresp = '<strong>' . $total . '<strong>'; if ($osgood) { // Ensure there are two bits of content. list($content, $contentright) = array_merge(preg_split('/[|]/', $content), array(' ')); $data[] = format_text($content, FORMAT_HTML); } else { // Eliminate potentially short-named choices. $contents = questionnaire_choice_values($content); if ($contents->modname) { $content = $contents->text; } $data[] = format_text($content, FORMAT_HTML); } // Display ranks/rates numbers. $maxrank = max($rank); for ($i = 0; $i <= $length - 1; $i++) { $percent = ''; if (isset($rank[$i])) { $str = $rank[$i]; if ($total !== 0 && $str !== 0) { $percent = ' (<span class="percent">' . number_format($str * 100 / $total) . '%</span>)'; } // Emphasize responses with max rank value. if ($str == $maxrank) { $str = '<strong>' . $str . '</strong>'; } } else { $str = 0; } $data[] = $str . $percent; } if ($osgood) { $data[] = format_text($contentright, FORMAT_HTML); } $data[] = $nbresp; if ($isrestricted) { $data[] = $nbresponses - $total; } if (!$osgood) { if ($na) { $data[] = $nbna; } } } // End named degrees. $table->data[] = $data; } return html_writer::table($table); }