/** * Called via pluginfile.php -> question_pluginfile to serve files belonging to * a question in a question_attempt when that attempt is a preview. * * @param object $course course settings object * @param object $context context object * @param string $component the name of the component we are serving files for. * @param string $filearea the name of the file area. * @param array $args the remaining bits of the file path. * @param bool $forcedownload whether the user must be forced to download the file. * @return bool false if file not found, does not return if found - justsend the file */ function question_preview_question_pluginfile($course, $context, $component, $filearea, $attemptid, $questionid, $args, $forcedownload) { global $USER, $SESSION, $DB, $CFG; require_once $CFG->dirroot . '/mod/quiz/locallib.php'; if (!($question = $DB->get_record('question', array('id' => $questionid)))) { return send_file_not_found(); } if (!question_has_capability_on($question, 'use', $question->category)) { send_file_not_found(); } if (!isset($SESSION->quizpreview->states) || $SESSION->quizpreview->questionid != $questionid) { send_file_not_found(); } $states = end($SESSION->quizpreview->states); if (!array_key_exists($question->id, $states)) { send_file_not_found(); } $state = $states[$question->id]; // Build fake cmoptions $quiz = new cmoptions(); $quiz->id = 0; $quiz->review = get_config('quiz', 'review'); if (empty($course->id)) { $quiz->course = SITEID; } else { $quiz->course = $course->id; } $quiz->decimalpoints = get_config('quiz', 'decimalpoints'); $questions[$question->id] = $question; get_question_options($questions); // Build fake attempt $timenow = time(); $attempt = new stdClass(); $attempt->quiz = $quiz->id; $attempt->userid = $USER->id; $attempt->attempt = 0; $attempt->sumgrades = 0; $attempt->timestart = $timenow; $attempt->timefinish = 0; $attempt->timemodified = $timenow; $attempt->uniqueid = 0; $attempt->id = 0; $attempt->layout = $question->id; $options = quiz_get_renderoptions($quiz, $attempt, $context, $state); $options->noeditlink = true; // XXX: mulitichoice type needs quiz id to get maxgrade $options->quizid = 0; if (!question_check_file_access($question, $state, $options, $context->id, $component, $filearea, $args, $forcedownload)) { send_file_not_found(); } $fs = get_file_storage(); $relativepath = implode('/', $args); $fullpath = "/{$context->id}/{$component}/{$filearea}/{$relativepath}"; if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } send_stored_file($file, 0, 0, $forcedownload); }
print_heading(get_string('noscript', 'quiz')); ?> </div> </noscript> <?php } echo '<div>'; /// Print the navigation panel if required $numpages = quiz_number_of_pages($attempt->layout); if ($numpages > 1) { quiz_print_navigation_panel($page, $numpages); } /// Print all the questions $number = quiz_first_questionnumber($attempt->layout, $pagelist); foreach ($pagequestions as $i) { $options = quiz_get_renderoptions($quiz->review, $states[$i]); // Print the question print_question($questions[$i], $states[$i], $number, $quiz, $options); save_question_session($questions[$i], $states[$i]); $number += $questions[$i]->length; } /// Print the submit buttons $strconfirmattempt = addslashes(get_string("confirmclose", "quiz")); $onclick = "return confirm('{$strconfirmattempt}')"; echo "<div class=\"submitbtns mdl-align\">\n"; echo "<input type=\"submit\" name=\"saveattempt\" value=\"" . get_string("savenosubmit", "quiz") . "\" />\n"; if ($quiz->optionflags & QUESTION_ADAPTIVE) { echo "<input type=\"submit\" name=\"markall\" value=\"" . get_string("markall", "quiz") . "\" />\n"; } echo "<input type=\"submit\" name=\"finishattempt\" value=\"" . get_string("finishattempt", "quiz") . "\" onclick=\"{$onclick}\" />\n"; echo "</div>";
print_error('errorprocessingresponses', 'question', $url->out()); } if (!$curstate->changed) { // Update the current state rather than creating a new one $historylength--; unset($states[$historylength]); $states = array_values($states); $curstate =& $states[$historylength][$id]; } } } else { $submitted = false; $curstate =& $states[$historylength][$id]; } // TODO: should not use quiz-specific function here $options = quiz_get_renderoptions($quiz->review, $curstate); // Fill in the correct responses (unless the question is in readonly mode) if ($fillcorrect && !$options->readonly) { $curstate->responses = $QTYPES[$questions[$id]->qtype]->get_correct_responses($questions[$id], $curstate); } $strpreview = get_string('preview', 'quiz') . ' ' . format_string($questions[$id]->name); $questionlist = array($id); $headtags = get_html_head_contributions($questionlist, $questions, $states[$historylength]); print_header($strpreview, '', '', '', $headtags); print_heading($strpreview); if (!empty($quizid)) { echo '<p class="quemodname">' . get_string('modulename', 'quiz') . ': '; p(format_string($quiz->name)); echo "</p>\n"; } $number = 1;
print_error('errorprocessingresponses', 'question', $url->out()); } if (!$curstate->changed) { // Update the current state rather than creating a new one $historylength--; unset($states[$historylength]); $states = array_values($states); $curstate =& $states[$historylength][$id]; } } } else { $submitted = false; $curstate =& $states[$historylength][$id]; } // TODO: should not use quiz-specific function here $options = quiz_get_renderoptions($quiz, $attempt, $context, $curstate); $options->noeditlink = true; // Fill in the correct responses (unless the question is in readonly mode) if ($fillcorrect && !$options->readonly) { $curstate->responses = $QTYPES[$questions[$id]->qtype]->get_correct_responses($questions[$id], $curstate); } $strpreview = get_string('preview', 'quiz') . ' ' . format_string($questions[$id]->name); $questionlist = array($id); $headtags = get_html_head_contributions($questionlist, $questions, $states[$historylength]); print_header($strpreview, '', '', '', $headtags); echo $OUTPUT->heading($strpreview); if (!empty($quizid)) { echo '<p class="quemodname">' . get_string('modulename', 'quiz') . ': '; p(format_string($quiz->name)); echo "</p>\n"; }
/** * Wrapper that calls get_render_options with the appropriate arguments. * * @param integer questionid the quetsion to get the render options for. * @return object the render options for this user on this attempt. */ public function get_render_options($questionid) { return quiz_get_renderoptions($this->quiz, $this->attempt, $this->context, $this->get_question_state($questionid)); }
/** * Wrapper that calls get_render_options with the appropriate arguments. * * @return object the render options for this user on this attempt. */ public function get_render_options($state) { return quiz_get_renderoptions($this->quiz, $this->attempt, $this->context, $state); }
/** * * Creates a new PDF with the questions of a quiz's attempt. * * @param unknown_type $attempt record with the attempt info * @param unknown_type $quiz * @param unknown_type $pdf1 * @param unknown_type $blended * @param unknown_type $options array with formatting options * @param unknown_type $pdfFile * @throws PDFError */ function blended_generate_quiz($attempt, $quiz, $pdf1, $blended, $options, $pdfFile) { global $QTYPES; global $CFG; global $COURSE; $uniqueid = $attempt->id; $activity_code = $uniqueid; $identifyLabel = $options['identifyLabel']; /* switch($identifyLabel) { case 'id': $idText= $activity_code; break; case 'none': $idText=''; break; } */ $markSize = 3; $quizname = $quiz->name; $images->ok_marks = '<img src="' . $CFG->wwwroot . '/mod/blended/images/ok_marks.png" height="10" />'; $images->ko_marks = '<img src="' . $CFG->wwwroot . '/mod/blended/images/ko_marks.png" height="10" />'; // $images->ok_marks='<img src="mod/blended/images/ok_marks.png" height="10" />'; // $images->ko_marks='<img src="mod/blended/images/ko_marks.png" height="10"/>'; $howToMark = get_string('howToMarkInstructions', 'blended', $images); $instructions = $quiz->intro . ' ' . $howToMark; $fullname = "nombre persona"; $style = array('position' => 'S', 'border' => false, 'padding' => 1, 'fgcolor' => array(0, 0, 0), 'bgcolor' => false, 'text' => true, 'font' => 'courier', 'fontsize' => $options['fontsize'], 'stretchtext' => 4); $headeroptions = new stdClass(); $headeroptions->rowHeight = 6; $headeroptions->logoWidth = 30; $headeroptions->codebarWidth = 40; $headeroptions->textStyle = $style; if (isset($options['logourl'])) { $headeroptions->logo_url = $options['logourl']; } else { $headeroptions->logo_url = $CFG->dirroot . '/mod/blended/pix/UVa_logo.jpg'; } $headeroptions->cellHtmlText = get_string('modulename', 'quiz') . ':' . $quizname; //Nombre: $headeroptions->cellHtmlDate = ''; $headeroptions->cellHtmlUser = get_string('Student', 'blended') . ':'; // Alumno: $headeroptions->cellCourseName = $COURSE->fullname; $headeroptions->evaluationmarksize = 3; // if null evaluation marks are not included in header $headeroptions->marksName = 'EVAL'; $headeroptions->codebarType = $blended->codebartype; $headeroptions->identifyLabel = $identifyLabel; // show readable text for codebars 'none' if not to be shown $headeroptions->instructions = $instructions; /** * Give precedence to the selected number of columns in the $options */ if (isset($options['columns'])) { $numcols = $options['columns']; } else { if (!isset($blended->numcols) || $blended->numcols == 0) { $numcols = 2; } else { $numcols = $blended->numcols; } } unset($quiz->questionsinuse); unset($QTYPES["random"]->catrandoms); $pagelist = quiz_questions_on_page($attempt->layout, 0); $pagequestions = explode(',', $pagelist); $questionlist = quiz_questions_in_quiz($attempt->layout); if (!$questionlist) { throw new PDFError("Quiz layout is empty", PDFError::QUIZ_IS_EMPTY); } $sql = "SELECT q.*, i.grade AS maxgrade, i.id AS instance" . " FROM {$CFG->prefix}question q," . " {$CFG->prefix}quiz_question_instances i" . " WHERE i.quiz = '{$quiz->id}' AND q.id = i.question" . " AND q.id IN ({$questionlist})"; if (!($questions = get_records_sql($sql))) { throw new PDFError("Questions not found. ", PDFError::QUESTIONS_NOT_FOUND); } //Carga las preguntas con sus opciones if (!get_question_options($questions)) { throw new PDFError("Could not load question options", PDFError::COULD_NOT_LOAD_QUESTION_OPTIONS); } $quiz_userid = 4; $acode = $attempt->id; if (!($attemptnumber = (int) get_field_sql('SELECT MAX(attempt)+1 FROM ' . "{$CFG->prefix}quiz_attempts WHERE quiz = '{$quiz->id}' AND " . "userid = '{$quiz_userid}' AND timefinish > 0 AND preview != 1"))) { $attemptnumber = 1; } $quiz_uniqueid = $attempt->attempt; $timenow = time(); $quiz_attempt = create_new_attempt($quiz, $attemptnumber, $quiz_userid, $acode, $quiz_uniqueid, $timenow); // Save the attempt // if (!insert_record('quiz_attempts', $quiz_attempt)) { // error('Could not create new attempt'); //} if (!($states = get_question_states($questions, $quiz, $quiz_attempt, false))) { throw new PDFError("Could not restore question sessions", PDFError::COULD_NOT_RESTORE_QUESTION_SESSIONS); } // TODO save question states someway in question_states foreach ($questions as $i => $question) { save_question_session($questions[$i], $states[$i]); } // global $QTYPES; //$question = reset($questions); //print("state answer question $question->id: ".$QTYPES[$question->qtype]->get_question_options($question)); $quests = new stdClass(); $quests = array(); foreach ($pagequestions as $i) { $options = quiz_get_renderoptions($quiz->review, $states[$i]); $quest = blended_get_question_formulation_and_controls($questions[$i], $states[$i], $quiz, $options); if (isset($quest->answers)) { foreach ($quest->answers as $c => $v) { $text = $v->answer; $quest->answers[$c]->answer = blended_image_path($text); } } $quests[] = $quest; } $idText = ''; $original = new stdClass(); $original->question = array(); $question = $quests; $num = 0; $a = 0; //foreach ($questions as $m)//esto es redundante: crea un array igual foreach ($pagequestions as $i) { $questions[$i]->questiontext = $quests[$a]->questiontext; if (isset($questions[$i]->questiontext)) { $questions[$i]->questiontext = blended_image_path($questions[$i]->questiontext); } $question[$a] = $questions[$i]; if ($question[$a]->qtype == "multichoice") { $question[$a]->anss = array(); foreach ($states[$questions[$i]->id]->options->order as $j => $aid) { $question[$a]->anss[$j] = $questions[$i]->options->answers[$aid]; $num++; } } $question[$a]->id = "q" . $question[$a]->id; $a++; } foreach ($question as $quest) { $original->question[] = $quest; } /** * Start PDF printing */ // create new PDF document $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); blended_new_page($pdf); $margins = $pdf->getMargins(); $columnsWidth = ($pdf->getPageWidth() - $margins['left'] - $margins['right']) / $numcols; /** * Print all questions with TPDF to calculate exact dimensions of each block */ $pdf->SetFont($headeroptions->textStyle['font'], '', $headeroptions->textStyle['fontsize']); for ($key = 0; $key < count($original->question); $key++) { $dims_borrador = new stdClass(); $dims_borrador->coords = array(); $original->question[$key]->height = blended_print_draft($pdf, $key, $original, $dims_borrador, $columnsWidth, $markSize, $headeroptions); } /** * Print final PDF */ // Array to hold sizes of elements $dimsn = array(); // Print content starting at abscisa $y $pdf1 = blended_print_quiz($pdf1, $numcols, $columnsWidth, $margins, $original, $dimsn, $markSize, $headeroptions, $uniqueid, $pdfFile); unset($pdf); return $pdf1; }