AutorÃa | Ultima modificación | Ver Log |
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace mod_questionnaire\output;
use mod_questionnaire\question\question;
/**
* Contains class mod_questionnaire\output\renderer
*
* @package mod_questionnaire
* @copyright 2016 Mike Churchward (mike.churchward@poetgroup.org)
* @author Mike Churchward
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class renderer extends \plugin_renderer_base {
/**
* Main view page.
* @param \templateable $page
* @return string | boolean
*/
public function render_viewpage($page) {
$data = $page->export_for_template($this);
return $this->render_from_template('mod_questionnaire/viewpage', $data);
}
/**
* Fill out the questionnaire (complete) page.
* @param \templateable $page
* @return string | boolean
*/
public function render_completepage($page) {
$data = $page->export_for_template($this);
return $this->render_from_template('mod_questionnaire/completepage', $data);
}
/**
* Fill out the report page.
* @param \templateable $page
* @return string | boolean
*/
public function render_reportpage($page) {
$data = $page->export_for_template($this);
return $this->render_from_template('mod_questionnaire/reportpage', $data);
}
/**
* Fill out the PDF report page.
* @param \templateable $page
* @return string | boolean
*/
public function render_reportpagepdf($page) {
$data = $page->export_for_template($this);
return $this->render_from_template('mod_questionnaire/reportpagepdf', $data);
}
/**
* Fill out the qsettings page.
* @param \templateable $page
* @return string | boolean
*/
public function render_qsettingspage($page) {
$data = $page->export_for_template($this);
return $this->render_from_template('mod_questionnaire/qsettingspage', $data);
}
/**
* Fill out the feedback page.
* @param \templateable $page
* @return string | boolean
*/
public function render_feedbackpage($page) {
$data = $page->export_for_template($this);
return $this->render_from_template('mod_questionnaire/qsettingspage', $data);
}
/**
* Fill out the questions page.
* @param \templateable $page
* @return string | boolean
*/
public function render_questionspage($page) {
$data = $page->export_for_template($this);
return $this->render_from_template('mod_questionnaire/questionspage', $data);
}
/**
* Fill out the preview page.
* @param \templateable $page
* @return string | boolean
*/
public function render_previewpage($page) {
$data = $page->export_for_template($this);
return $this->render_from_template('mod_questionnaire/previewpage', $data);
}
/**
* Fill out the non-respondents page.
* @param \templateable $page
* @return string | boolean
*/
public function render_nonrespondentspage($page) {
$data = $page->export_for_template($this);
return $this->render_from_template('mod_questionnaire/nonrespondentspage', $data);
}
/**
* Fill out the fbsections page.
* @param \templateable $page
* @return string | boolean
*/
public function render_fbsectionspage($page) {
$data = $page->export_for_template($this);
return $this->render_from_template('mod_questionnaire/fbsectionspage', $data);
}
/**
* Render the respondent information line.
* @param string $text The respondent information.
*/
public function respondent_info($text) {
return \html_writer::tag('span', $text, ['class' => 'respondentinfo']);
}
/**
* Render the completion form start HTML.
* @param string $action The action URL.
* @param array $hiddeninputs Name/value pairs of hidden inputs used by the form.
* @return string The output for the page.
*/
public function complete_formstart($action, $hiddeninputs=[]) {
$output = '';
$output .= \html_writer::start_tag('form', ['id' => 'phpesp_response', 'method' => 'post', 'action' => $action]) . "\n";
foreach ($hiddeninputs as $name => $value) {
$output .= \html_writer::empty_tag('input', ['type' => 'hidden', 'name' => $name, 'value' => $value]) . "\n";
}
return $output;
}
/**
* Render the completion form end HTML.
* @param array $inputs Type/attribute array of inputs and values used by the form.
* @return string The output for the page.
*/
public function complete_formend($inputs=[]) {
$output = '';
foreach ($inputs as $type => $attributes) {
$output .= \html_writer::empty_tag('input', array_merge(['type' => $type], $attributes)) . "\n";
}
$output .= \html_writer::end_tag('form') . "\n";
return $output;
}
/**
* Render the completion form control buttons.
* @param array|string $inputs Name/(Type/attribute) array of input types and values used by the form.
* @return string The output for the page.
*/
public function complete_controlbuttons($inputs=null) {
$output = '';
if (is_array($inputs)) {
foreach ($inputs as $name => $attributes) {
$output .= \html_writer::empty_tag('input', array_merge(['name' => $name], $attributes)) . ' ';
}
} else if (is_string($inputs)) {
$output .= \html_writer::tag('p', $inputs);
}
return $output;
}
/**
* Calculate the progress and return it.
* @param int $section
* @param array $questionsbysec
* @return float
*/
private function calculate_progress($section, $questionsbysec) {
$done = 0;
$todo = 0;
for ($i = 1; $i <= count($questionsbysec); $i++) {
if ($i < $section) {
$done += count($questionsbysec[$i]);
} else {
$todo += count($questionsbysec[$i]);
}
}
return round($done / ($done + $todo) * 100);
}
/**
* Render the progress bar and return it.
* @param int $section
* @param array $questionsbysec
* @return bool|string
*/
public function render_progress_bar($section, $questionsbysec) {
$templatecontext['percent'] = $this->calculate_progress($section, $questionsbysec);
$helpicon = new \help_icon('progresshelp', 'mod_questionnaire');
$templatecontext['progresshelp'] = $helpicon->export_for_template($this);
return $this->render_from_template('mod_questionnaire/progressbar', $templatecontext);
}
/**
* Render a question for a survey.
* @param \mod_questionnaire\question\question $question The question object.
* @param \mod_questionnaire\responsetype\response\response $response Any current response data.
* @param int $qnum The question number.
* @param boolean $blankquestionnaire Used for printing a blank one.
* @param array $dependants Array of all questions/choices depending on $question.
* @return string The output for the page.
*/
public function question_output($question, $response, $qnum, $blankquestionnaire, $dependants=[]) {
$pagetags = $question->question_output($response, $blankquestionnaire, $dependants, $qnum);
// If the question has a template, then render it from the 'qformelement' context. If no template, then 'qformelement'
// already contains HTML.
if (($template = $question->question_template())) {
$pagetags->qformelement = $this->render_from_template($template, $pagetags->qformelement);
}
// Calling "question_output" may generate per question notifications. If present, add them to the question output.
if (($notifications = $question->get_notifications()) !== false) {
foreach ($notifications as $notification) {
$pagetags->notifications = $this->notification($notification, \core\output\notification::NOTIFY_ERROR);
}
}
return $this->render_from_template('mod_questionnaire/question_container', $pagetags);
}
/**
* Render a question response.
* @param \mod_questionnaire\question\question $question The question object.
* @param \mod_questionnaire\responsetype\response\response $response The response object.
* @param int $qnum The question number.
* @param bool $pdf
* @return string The output for the page.
* @throws \moodle_exception
*/
public function response_output($question, $response, $qnum=null, $pdf=false) {
$pagetags = $question->response_output($response, $qnum);
// If the response has a template, then render it from the 'qformelement' context. If no template, then 'qformelement'
// already contains HTML.
if (($template = $question->response_template())) {
if ($pdf) {
$pagetags->qformelement->pdf = 1;
}
$pagetags->qformelement = $this->render_from_template($template, $pagetags->qformelement);
}
// Calling "question_output" may generate per question notifications. If present, add them to the question output.
if (($notifications = $question->get_notifications()) !== false) {
foreach ($notifications as $notification) {
$pagetags->notifications = $this->notification($notification, \core\output\notification::NOTIFY_ERROR);
}
}
if (!$pdf) {
return $this->render_from_template('mod_questionnaire/question_container', $pagetags);
} else {
return $this->render_from_template('mod_questionnaire/questionpdf_container', $pagetags);
}
}
/**
* Render all responses for a question.
* @param array|string $responses
* @param array $questions
* @return string The output for the page.
*/
public function all_response_output($responses, $questions = null) {
$output = '';
if (is_string($responses)) {
$output .= $responses;
} else {
$qnum = 1;
foreach ($questions as $question) {
if (empty($pagetags = $question->questionstart_survey_display($qnum))) {
continue;
}
foreach ($responses as $response) {
$resptags = $question->response_output($response);
// If the response has a template, then render it from the 'qformelement' context.
// If no template, then 'qformelement' already contains HTML.
if (($template = $question->response_template())) {
$resptags->qformelement = $this->render_from_template($template, $resptags->qformelement);
}
$resptags->respdate = userdate($response->submitted);
$pagetags->responses[] = $resptags;
}
$qnum++;
$output .= $this->render_from_template('mod_questionnaire/response_container', $pagetags);
}
}
return $output;
}
/**
* Render a question results summary.
* @param question $question The question object.
* @param array $rids The response ids.
* @param string $sort The sort order being used.
* @param string $anonymous The value of the anonymous setting.
* @param bool $pdf
* @return string The output for the page.
*/
public function results_output($question, $rids, $sort, $anonymous, $pdf = false) {
$pagetags = $question->display_results($rids, $sort, $anonymous);
// If the response has a template, then render it from $pagetags. If no template, then $pagetags already contains HTML.
if (($template = $question->results_template($pdf))) {
return $this->render_from_template($template, $pagetags);
} else {
return $pagetags;
}
}
/**
* Render the reporting navigation bar.
* @param array $navbar All of the data needed for the template.
* @return string The rendered HTML.
*/
public function navigationbar($navbar) {
return $this->render_from_template('mod_questionnaire/navbaralpha', $navbar);
}
/**
* Render the reporting navigation bar for one user.
* @param array $navbar All of the data needed for the template.
* @return string The rendered HTML.
*/
public function usernavigationbar($navbar) {
return $this->render_from_template('mod_questionnaire/navbaruser', $navbar);
}
/**
* Render the response list for a number of users.
* @param array $navbar All of the data needed for the template.
* @return string The rendered HTML.
*/
public function responselist($navbar) {
return $this->render_from_template('mod_questionnaire/responselist', $navbar);
}
/**
* Render a print/preview page number line.
* @param string $content The content to render.
* @return string The rendered HTML.
*/
public function print_preview_pagenumber($content) {
return \html_writer::tag('div', $content, ['class' => 'surveyPage']);
}
/**
* Render the print/preview completion form end HTML.
* @param string $url The url to call.
* @param string $submitstr The submit text.
* @param string $resetstr The reset text.
* @return string The output for the page.
*/
public function print_preview_formend($url, $submitstr, $resetstr) {
$output = '';
$output .= \html_writer::start_tag('div');
$output .= \html_writer::empty_tag('input', ['type' => 'submit', 'name' => 'submit', 'value' => $submitstr,
'class' => 'btn btn-primary']);
$output .= ' ';
$output .= \html_writer::tag('a', $resetstr, ['href' => $url, 'class' => 'btn btn-secondary mr-1']);
$output .= \html_writer::end_tag('div') . "\n";
$output .= \html_writer::end_tag('form') . "\n";
return $output;
}
/**
* Render the back to home link on the save page.
* @param string $url The url to link to.
* @param string $text The text to apply the link to.
* @return string The rendered HTML.
*/
public function homelink($url, $text) {
$output = '';
$output .= \html_writer::start_tag('div', ['class' => 'homelink']);
$output .= \html_writer::tag('a', $text, ['href' => $url, 'class' => 'btn btn-primary']);
$output .= \html_writer::end_tag('div');
return $output;
}
/**
* Generate and return any dependency warnings.
* @param array $children
* @param string $langstring
* @param int $strnum
* @return string
*/
public function dependency_warnings($children, $langstring, $strnum) {
$msg = '<div class="warning">' . get_string($langstring, 'questionnaire') . '</div><br />';
foreach ($children as $child) {
$loopindicator = array();
foreach ($child as $subchild) {
$childname = '';
if ($subchild->name) {
$childname = ' ('.$subchild->name.')';
}
// Add conditions.
switch ($subchild->dependlogic) {
case 0:
$logic = get_string('notset', 'questionnaire');
break;
case 1:
$logic = get_string('set', 'questionnaire');
break;
default:
$logic = '';
}
// Different colouring for and/or.
switch ($subchild->dependandor) {
case 'or':
$color = 'qdepend-or';
break;
case 'and':
$color = "qdepend";
break;
default:
$color = "";
}
if (!in_array($subchild->qdependquestion, $loopindicator)) {
$msg .= '<div class = "qn-container">'.$strnum.' '.$subchild->position.$childname.
'<br/><span class="'.$color.'"><strong>'.
get_string('dependquestion', 'questionnaire').'</strong>'.
' ('.$strnum.' '.$subchild->parentposition.') '.
' : '.$subchild->parent.' '.$logic.'</span>';
} else {
$msg .= '<br/><span class="'.$color.'"><strong>'.
get_string('dependquestion', 'questionnaire').'</strong>'.
' ('.$strnum.' '.$subchild->parentposition.') '.
' : '.$subchild->parent.' '.$logic.'</span>';
}
$loopindicator[] = $subchild->qdependquestion;
}
$msg .= '<div class="qn-question">'.
$subchild->content.
'</div></div>';
}
return $msg;
}
/**
* Get displayable list of parents for the question in questions_form.
* @param int $qid The question id.
* @param array $dependencies Array of dependency records for a question.
* @return string
*/
public function get_dependency_html($qid, $dependencies) {
$html = '';
foreach ($dependencies as $dependency) {
switch ($dependency->dependlogic) {
case 0:
$logic = get_string('notset', 'questionnaire');
break;
case 1:
$logic = get_string('set', 'questionnaire');
break;
default:
$logic = '';
}
// TODO - Move the HTML generation to the renderer.
if ($dependency->dependandor == "and") {
$html .= '<div id="qdepend_' . $qid . '_' . $dependency->dependquestionid . '_' .
$dependency->dependchoiceid . '" class="qdepend">' . '<strong>' .
get_string('dependquestion', 'questionnaire') . '</strong> : '. get_string('position', 'questionnaire') . ' ' .
$dependency->parentposition . ' (' . $dependency->parent . ') ' . $logic . '</div>';
} else {
$html .= '<div id="qdepend_or_' . $qid . '_' . $dependency->dependquestionid . '_' .
$dependency->dependchoiceid . '" class="qdepend-or">' . '<strong>' .
get_string('dependquestion', 'questionnaire') . '</strong> : '. get_string('position', 'questionnaire') . ' ' .
$dependency->parentposition . ' (' . $dependency->parent . ') ' . $logic . '</div>';
}
}
return $html;
}
/**
* Helper method dealing with the fact we can not just fetch the output of flexible_table
*
* @param flexible_table $table
* @param boolean $buffering True if already buffering.
* @return string HTML
*/
public function flexible_table(\flexible_table $table, $buffering = false) {
$o = '';
if (!$buffering) {
ob_start();
}
$table->finish_output();
$o = ob_get_contents();
ob_end_clean();
return $o;
}
/**
* Returns a dataformat selection and download form
*
* @param string $label A text label
* @param moodle_url|string $base The download page url
* @param string $name The query param which will hold the type of the download
* @param array $params Extra params sent to the download page
* @param string $extrafields HTML for extra form fields
* @return string HTML fragment
*/
public function download_dataformat_selector($label, $base, $name = 'dataformat', $params = array(), $extrafields = '') {
$formats = \core_plugin_manager::instance()->get_plugins_of_type('dataformat');
$options = array();
foreach ($formats as $format) {
if ($format->is_enabled()) {
$options[] = array(
'value' => $format->name,
'label' => get_string('dataformat', $format->component),
);
}
}
$hiddenparams = array();
foreach ($params as $key => $value) {
$hiddenparams[] = array(
'name' => $key,
'value' => $value,
);
}
$data = array(
'label' => $label,
'base' => $base,
'name' => $name,
'params' => $hiddenparams,
'options' => $options,
'extrafields' => $extrafields,
'sesskey' => sesskey(),
'submit' => get_string('download'),
'emailroleshelp' => $this->help_icon('emailroles', 'questionnaire'),
'emailextrahelp' => $this->help_icon('emailextra', 'questionnaire'),
'allowemailreporting' => get_config('questionnaire', 'allowemailreporting'),
);
return $this->render_from_template('mod_questionnaire/dataformat_selector', $data);
}
}