Ouputs the form for making an attempt

@param quiz_attempt $attemptobj
@param int $page Current page number
@param array $slots Array of integers relating to questions
@param int $id ID of the attempt
@param int $nextpage Next page number
427904
public function attempt_form($attemptobj, $page, $slots, $id, $nextpage) {
        $output = '';

        // Start the form.
        $output .= html_writer::start_tag('form',
                array('action' => new moodle_url($attemptobj->processattempt_url(),
                array('cmid' => $attemptobj->get_cmid())), 'method' => 'post',
                'enctype' => 'multipart/form-data', 'accept-charset' => 'utf-8',
                'id' => 'responseform'));
        $output .= html_writer::start_tag('div');

        // Print all the questions.
        foreach ($slots as $slot) {
            $output .= $attemptobj->render_question($slot, false, $this,
                    $attemptobj->attempt_url($slot, $page), $this);
        }

        $navmethod = $attemptobj->get_quiz()->navmethod;
        $output .= $this->attempt_navigation_buttons($page, $attemptobj->is_last_page($page), $navmethod);

        // Some hidden fields to trach what is going on.
        $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'attempt',
                'value' => $attemptobj->get_attemptid()));
        $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'thispage',
                'value' => $page, 'id' => 'followingpage'));
        $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'nextpage',
                'value' => $nextpage));
        $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'timeup',
                'value' => '0', 'id' => 'timeup'));
        $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey',
                'value' => sesskey()));
        $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'scrollpos',
                'value' => '', 'id' => 'scrollpos'));

        // Add a hidden field with questionids. Do this at the end of the form, so
        // if you navigate before the form has finished loading, it does not wipe all
        // the student's answers.
        $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'slots',
                'value' => implode(',', $attemptobj->get_active_slots($page))));

        // Finish the form.
        $output .= html_writer::end_tag('div');
        $output .= html_writer::end_tag('form');

        $output .= $this->connection_warning();

        return $output;
    }
305994
public function setCurrentPageID($id)
    {
        $this->pageID = $id;
        $id = (int)$id;
        /** @deprecated */
        $this->getRequest()->getSession()->set($this->sessionNamespace() . ".currentPage", $id);
    }
853433
function next() {
		
		var data = new Object();
		// Submit content of all forms -- except those with class 'ignore-form' -- before going to next page.
		$('#container form:not(.ignore-form)').each(function(index) {
			//console.log("Form no. "+index + " with the ID #" + $(this).attr('id') );
			//console.log($( this ).serializeArray() );
			data[$(this).attr('id')] = $( this ).serializeArray(); // Add each form's data to the data object.
		});
		
		if(isEmpty(data)) 
			cloak.message('next');
		else
			cloak.message('next', data);
	}
1259478
public function summary_page($attemptobj, $displayoptions) {
        $output = '';
        $output .= $this->header();
        $output .= $this->heading(format_string($attemptobj->get_quiz_name()));
        $output .= $this->heading(get_string('summaryofattempt', 'quiz'), 3);
        $output .= $this->summary_table($attemptobj, $displayoptions);
        $output .= $this->summary_page_controls($attemptobj);
        $output .= $this->footer();
        return $output;
    }
957857
public function process_redo_question($slot, $timestamp) {
        global $DB;

        if (!$this->can_question_be_redone_now($slot)) {
            throw new coding_exception('Attempt to restart the question in slot ' . $slot .
                    ' when it is not in a state to be restarted.');
        }

        $qubaids = new \mod_quiz\question\qubaids_for_users_attempts(
                $this->get_quizid(), $this->get_userid());

        $transaction = $DB->start_delegated_transaction();

        // Choose the replacement question.
        $questiondata = $DB->get_record('question',
                array('id' => $this->slots[$slot]->questionid));
        if ($questiondata->qtype != 'random') {
            $newqusetionid = $questiondata->id;
        } else {
            $tagids = quiz_retrieve_slot_tag_ids($this->slots[$slot]->id);

            $randomloader = new \core_question\bank\random_question_loader($qubaids, array());
            $newqusetionid = $randomloader->get_next_question_id($questiondata->category,
                    (bool) $questiondata->questiontext, $tagids);
            if ($newqusetionid === null) {
                throw new moodle_exception('notenoughrandomquestions', 'quiz',
                        $this->quizobj->view_url(), $questiondata);
            }
        }

        // Add the question to the usage. It is important we do this before we choose a variant.
        $newquestion = question_bank::load_question($newqusetionid);
        $newslot = $this->quba->add_question_in_place_of_other($slot, $newquestion);

        // Choose the variant.
        if ($newquestion->get_num_variants() == 1) {
            $variant = 1;
        } else {
            $variantstrategy = new core_question\engine\variants\least_used_strategy(
                    $this->quba, $qubaids);
            $variant = $variantstrategy->choose_variant($newquestion->get_num_variants(),
                    $newquestion->get_variants_selection_seed());
        }

        // Start the question.
        $this->quba->start_question($slot, $variant);
        $this->quba->set_max_mark($newslot, 0);
        $this->quba->set_question_attempt_metadata($newslot, 'originalslot', $slot);
        question_engine::save_questions_usage_by_activity($this->quba);

        $transaction->allow_commit();
    }
1287248
protected function make_blocked_question_placeholder($slot) {
        $replacedquestion = $this->get_question_attempt($slot)->get_question();

        question_bank::load_question_definition_classes('description');
        $question = new qtype_description_question();
        $question->id = $replacedquestion->id;
        $question->category = null;
        $question->parent = 0;
        $question->qtype = question_bank::get_qtype('description');
        $question->name = '';
        $question->questiontext = get_string('questiondependsonprevious', 'quiz');
        $question->questiontextformat = FORMAT_HTML;
        $question->generalfeedback = '';
        $question->defaultmark = $this->quba->get_question_max_mark($slot);
        $question->length = $replacedquestion->length;
        $question->penalty = 0;
        $question->stamp = '';
        $question->version = 0;
        $question->hidden = 0;
        $question->timecreated = null;
        $question->timemodified = null;
        $question->createdby = null;
        $question->modifiedby = null;

        $placeholderqa = new question_attempt($question, $this->quba->get_id(),
                null, $this->quba->get_question_max_mark($slot));
        $placeholderqa->set_slot($slot);
        $placeholderqa->start($this->get_quiz()->preferredbehaviour, 1);
        $placeholderqa->set_flagged($this->is_question_flagged($slot));
        return $placeholderqa;
    }
1219381
public function set_currentpage($page) {
        global $DB;

        if ($this->check_page_access($page)) {
            $DB->set_field('quiz_attempts', 'currentpage', $page, array('id' => $this->get_attemptid()));
            return true;
        }
        return false;
    }
1355174
public boolean showNextPage(AbstractWizardPage nextPage) {
		if (nextPage == null) {
			// Next page is null. Updating buttons and ignoring request.
			updateButtons();
			return false;
		}
		if (currentPage != null) {
			pageHistory.push(currentPage);
		}
		setPage(nextPage);
		return true;
	}
469775
protected function render_mod_scorm_attempt_bar(mod_scorm_attempt_bar $attemptbar) {
        $output = '';
        $attemptbar = clone($attemptbar);
        $attemptbar->prepare($this, $this->page, $this->target);

        if (count($attemptbar->attemptids) > 1) {
            $output .= get_string('attempt', 'scorm') . ':';

            if (!empty($attemptbar->previouslink)) {
                $output .= '&#160;(' . $attemptbar->previouslink . ')&#160;';
            }

            foreach ($attemptbar->attemptlinks as $link) {
                $output .= "&#160;&#160;$link";
            }

            if (!empty($attemptbar->nextlink)) {
                $output .= '&#160;&#160;(' . $attemptbar->nextlink . ')';
            }
        }

        return html_writer::tag('div', $output, array('class' => 'paging'));
    }
1123275
function deletePage(req, res, next) {
    var that = this, db = that.getDB(), DBActions = that.getDBActionsLib(),
        dbAction = DBActions.getAuthInstance(req, PAGE_SCHEMA, PAGE_PERMISSION_SCHEMA_ENTRY);
    var params = req.params;
    var pageId = params.id;
    if (!pageId) {
        that.setErrorMessage(req, "No page is selected");
        return next(null);
    }
    var redirect = req.params.page + "/" + req.params.plugin;
    dbAction.get("findByPageId", pageId, function (err, page) {
        if (err) {
            return next(err);
        }
        page && (page = page.toObject());
        if (page && (that.getAppProperty("DEFAULT_INDEX_PAGE") == page.friendlyURL)) {
            that.setErrorMessage(req, "Cannot delete index page.");
            that.setRedirect(req, redirect);
            return next(null);
        }
        PageManager.hasChildren(dbAction, pageId, function (err, pages) {
            if (pages.length > 0) {
                that.setRedirect(req, redirect);
                that.setErrorMessage(req, "Delete all child pages.");
                next(err);
            } else {
                var aboveSiblings;
                async.series([
                    function (n) {
                        dbAction.authorizedRemove(pageId, n);
                    },
                    function (n) {
                        PageManager.getAboveSiblings(dbAction, page, function (err, pages) {
                            if (pages) {
                                aboveSiblings = pages;
                            }
                            n(err, pages);
                        });
                    },
                    function (n) {
                        if (!aboveSiblings || aboveSiblings.length == 0) {
                            return n(null, true);
                        }

                        var dbAction1 = DBActions.getInstance(req, PAGE_SCHEMA);
                        var decrementPageOrder = function (page, n) {
                            var order = page.order;
                            --order;
                            dbAction1.update({
                                pageId: page.pageId,
                                order: order
                            }, n);
                        };

                        async.each(aboveSiblings, decrementPageOrder, n);
                    }
                ], function (err, result) {
                    if (!err) {
                        that.setRedirect(req, redirect);
                        that.setSuccessMessage(req, "Page deleted successfully.");
                    }
                    next(err);
                });
            }
        });
    })
}
217652
public function duplicate_page($pageid) {
        global $PAGE;
        $cm = get_coursemodule_from_instance('lesson', $this->properties->id, $this->properties->course);
        $context = context_module::instance($cm->id);
        // Load the page.
        $page = $this->load_page($pageid);
        $properties = $page->properties();
        // The create method checks to see if these properties are set and if not sets them to zero, hence the unsetting here.
        if (!$properties->qoption) {
            unset($properties->qoption);
        }
        if (!$properties->layout) {
            unset($properties->layout);
        }
        if (!$properties->display) {
            unset($properties->display);
        }

        $properties->pageid = $pageid;
        // Add text and format into the format required to create a new page.
        $properties->contents_editor = array(
            'text' => $properties->contents,
            'format' => $properties->contentsformat
        );
        $answers = $page->get_answers();
        // Answers need to be added to $properties.
        $i = 0;
        $answerids = array();
        foreach ($answers as $answer) {
            // Needs to be rearranged to work with the create function.
            $properties->answer_editor[$i] = array(
                'text' => $answer->answer,
                'format' => $answer->answerformat
            );

            $properties->response_editor[$i] = array(
              'text' => $answer->response,
              'format' => $answer->responseformat
            );
            $answerids[] = $answer->id;

            $properties->jumpto[$i] = $answer->jumpto;
            $properties->score[$i] = $answer->score;

            $i++;
        }
        // Create the duplicate page.
        $newlessonpage = lesson_page::create($properties, $this, $context, $PAGE->course->maxbytes);
        $newanswers = $newlessonpage->get_answers();
        // Copy over the file areas as well.
        $this->copy_page_files('page_contents', $pageid, $newlessonpage->id, $context->id);
        $j = 0;
        foreach ($newanswers as $answer) {
            if (isset($answer->answer) && strpos($answer->answer, '@@PLUGINFILE@@') !== false) {
                $this->copy_page_files('page_answers', $answerids[$j], $answer->id, $context->id);
            }
            if (isset($answer->response) && !is_array($answer->response) && strpos($answer->response, '@@PLUGINFILE@@') !== false) {
                $this->copy_page_files('page_responses', $answerids[$j], $answer->id, $context->id);
            }
            $j++;
        }
    }
633101
@Override
    public PageException execute(String id) {
	SpoolerTask task = getTaskById(openDirectory, id);
	if (task == null) task = getTaskById(closedDirectory, id);
	if (task != null) {
	    return execute(task);
	}
	return null;
    }
542785
public function initialize($page, $contexts, $currentcat, $defaultcategory, $todelete, $addcontexts) {
        $lastlist = null;
        foreach ($contexts as $context){
            $this->editlists[$context->id] = new question_category_list('ul', '', true, $this->pageurl, $page, 'cpage', QUESTION_PAGE_LENGTH, $context);
            $this->editlists[$context->id]->lastlist =& $lastlist;
            if ($lastlist!== null){
                $lastlist->nextlist =& $this->editlists[$context->id];
            }
            $lastlist =& $this->editlists[$context->id];
        }

        $count = 1;
        $paged = false;
        foreach ($this->editlists as $key => $list){
            list($paged, $count) = $this->editlists[$key]->list_from_records($paged, $count);
        }
        $this->catform = new question_category_edit_form($this->pageurl, compact('contexts', 'currentcat'));
        if (!$currentcat){
            $this->catform->set_data(array('parent'=>$defaultcategory));
        }
    }
207934
protected function updatePage($page_id)
    {
        if (!$this->isError() && !$this->page->update($page_id, $this->getSubmitted())) {
            $this->errorAndExit($this->text('Unexpected result'));
        }
    }
1133657
protected function field_from_extra_data($attempt, $slot, $field) {
        if (!isset($this->lateststeps[$attempt->usageid][$slot])) {
            return '-';
        }
        $stepdata = $this->lateststeps[$attempt->usageid][$slot];

        if (property_exists($stepdata, $field . 'full')) {
            $value = $stepdata->{$field . 'full'};
        } else {
            $value = $stepdata->$field;
        }
        return $value;
    }
929653
protected function hint(question_attempt $qa, question_hint $hint) {
        return html_writer::nonempty_tag('div',
                $qa->get_question()->format_hint($hint, $qa), array('class' => 'hint'));
    }
323571
public function insert($page) {
        global $DB;

        $slots = $DB->get_records('quiz_slots', array('quizid' => $this->record->quizid),
                'slot', 'id, slot, page');

        $trans = $DB->start_delegated_transaction();

        $maxpage = 1;
        $numonlastpage = 0;
        foreach ($slots as $slot) {
            if ($slot->page > $maxpage) {
                $maxpage = $slot->page;
                $numonlastpage = 1;
            } else {
                $numonlastpage += 1;
            }
        }

        if (is_int($page) && $page >= 1) {
            // Adding on a given page.
            $lastslotbefore = 0;
            foreach (array_reverse($slots) as $otherslot) {
                if ($otherslot->page > $page) {
                    $DB->set_field('quiz_slots', 'slot', $otherslot->slot + 1, array('id' => $otherslot->id));
                } else {
                    $lastslotbefore = $otherslot->slot;
                    break;
                }
            }
            $this->record->slot = $lastslotbefore + 1;
            $this->record->page = min($page, $maxpage + 1);

            quiz_update_section_firstslots($this->record->quizid, 1, max($lastslotbefore, 1));
        } else {
            $lastslot = end($slots);
            $quiz = $this->get_quiz();
            if ($lastslot) {
                $this->record->slot = $lastslot->slot + 1;
            } else {
                $this->record->slot = 1;
            }
            if ($quiz->questionsperpage && $numonlastpage >= $quiz->questionsperpage) {
                $this->record->page = $maxpage + 1;
            } else {
                $this->record->page = $maxpage;
            }
        }

        $this->record->id = $DB->insert_record('quiz_slots', $this->record);

        if (!empty($this->tags)) {
            $recordstoinsert = [];
            foreach ($this->tags as $tag) {
                $recordstoinsert[] = (object)[
                    'slotid' => $this->record->id,
                    'tagid' => $tag->id,
                    'tagname' => $tag->name
                ];
            }
            $DB->insert_records('quiz_slot_tags', $recordstoinsert);
        }

        $trans->allow_commit();
    }