public function controls(question_attempt $qa, question_display_options $options) { $question = $qa->get_question(); $output = parent::controls($qa, $options); // Submit button. $penalty = $question->penalty; if ($penalty != 0) { $output .= $this->button_cost('withpossiblepenalty', $penalty, $options); } $output .= html_writer::empty_tag('br'); // Render buttons that should be rendered by behaviour. foreach ($question->hints_available_for_student() as $hintkey) { $behaviour = $qa->get_behaviour(); $hintkey = $behaviour->adjust_hintkey($hintkey); $hintobj = $question->hint_object($hintkey); if (!$hintobj->button_rendered_by_question()) { // Button(s) isn't rendered by the question, so behaviour must render it. // Check whether button should be rendered at all. $laststep = $qa->get_last_step(); if ($hintobj->hint_response_based()) { $showhintbtn = $laststep->has_behaviour_var('_resp_hintbtns'); } else { $showhintbtn = $laststep->has_behaviour_var('_nonresp_hintbtns'); } // Hide hint button if such hint buttons should not shown at all or hint unavailable or hint already rendered. if (!$showhintbtn || !$hintobj->hint_available() || $laststep->has_behaviour_var('_render_' . $hintkey) && $hintobj->hint_type() !== qtype_poasquestion\hint::SEQENTIAL_MULTIPLE_INSTANCE_HINT) { // Should not pass $response to hint_available, since response could be changed in adaptive. continue; } $output .= $this->render_hint_button($qa, $options, $hintobj); $output .= html_writer::empty_tag('br'); } } return $output; }