first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,101 @@
<?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/>.
/**
* Contains class mod_h5pactivity\output\result\choice
*
* @package mod_h5pactivity
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_h5pactivity\output\result;
defined('MOODLE_INTERNAL') || die();
use mod_h5pactivity\output\result;
use renderer_base;
/**
* Class to display H5P choice result.
*
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class choice extends result {
/**
* Return the options data structure.
*
* @return array of options
*/
protected function export_options(): ?array {
// Suppose H5P choices have only a single list of valid answers.
$correctpattern = reset($this->correctpattern);
if (empty($correctpattern)) {
$correctpattern = [];
}
$additionals = $this->additionals;
// H5P has a special extension for long choices.
$extensions = (array) $additionals->extensions ?? [];
$filter = isset($extensions['https://h5p.org/x-api/line-breaks']) ? true : false;
if (isset($additionals->choices)) {
$options = $this->get_descriptions($additionals->choices);
} else {
$options = [];
}
// Some H5P activities like Find the Words don't user the standard CMI format delimiter
// and don't use propper choice additionals. In those cases the report needs to fix this
// using the correct pattern as choices and using a non standard delimiter.
if (empty($options)) {
if (count($correctpattern) == 1) {
$correctpattern = explode(',', reset($correctpattern));
}
foreach ($correctpattern as $value) {
$option = (object)[
'id' => $value,
'description' => $value,
];
$options[$value] = $option;
}
}
foreach ($options as $key => $value) {
$correctstate = (in_array($key, $correctpattern)) ? parent::CHECKED : parent::UNCHECKED;
if (in_array($key, $this->response)) {
$answerstate = ($correctstate == parent::CHECKED) ? parent::PASS : parent::FAIL;
// In some cases, like Branching scenario H5P activity, no correct Pattern is provided
// so any answer is just a check.
if (empty($correctpattern)) {
$answerstate = parent::CHECKED;
}
$value->useranswer = $this->get_answer($answerstate);
}
$value->correctanswer = $this->get_answer($correctstate);
if ($filter && $correctstate == parent::UNCHECKED && !isset($value->useranswer)) {
unset($options[$key]);
}
}
return $options;
}
}
@@ -0,0 +1,127 @@
<?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/>.
/**
* Contains class mod_h5pactivity\output\result\fillin
*
* @package mod_h5pactivity
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_h5pactivity\output\result;
defined('MOODLE_INTERNAL') || die();
use mod_h5pactivity\output\result;
use renderer_base;
use stdClass;
/**
* Class to display H5P fill-in result.
*
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class fillin extends result {
/**
* Return the options data structure.
*
* @return array of options
*/
protected function export_options(): ?array {
$correctpatterns = $this->correctpattern;
$additionals = $this->additionals;
$extensions = (array) $additionals->extensions ?? [];
// There are two way in which H5P could force case sensitivity, with extensions
// or using options in the correctpatterns. By default it is case sensible.
$casesensitive = $extensions['https://h5p.org/x-api/case-sensitivity'] ?? true;
if ((!empty($this->result->correctpattern)
&& strpos($this->result->correctpattern, '{case_matters=false}') !== false)) {
$casesensitive = false;
}
$values = [];
// Add all possibilities from $additionals.
if (isset($extensions['https://h5p.org/x-api/alternatives'])) {
foreach ($extensions['https://h5p.org/x-api/alternatives'] as $key => $value) {
if (!is_array($value)) {
$value = [$value];
}
$values[$key] = ($casesensitive) ? $value : array_change_key_case($value);
}
}
// Add possibilities from correctpattern.
foreach ($correctpatterns as $correctpattern) {
foreach ($correctpattern as $key => $pattern) {
// The xAPI admits more params a part form values.
// For now this extra information is not used in reporting
// but it is posible future H5P types need them.
$value = preg_replace('/\{.+=.*\}/', '', $pattern);
$value = ($casesensitive) ? $value : strtolower($value);
if (!isset($values[$key])) {
$values[$key] = [];
}
if (!in_array($value, $values[$key])) {
array_unshift($values[$key], $value);
}
}
}
// Generate options.
$options = [];
$num = 1;
foreach ($values as $key => $value) {
$option = (object)[
'id' => $key,
'description' => get_string('result_fill-in_gap', 'mod_h5pactivity', $num),
];
$gapresponse = $this->response[$key] ?? null;
$gapresponse = ($casesensitive) ? $gapresponse : strtolower($gapresponse);
if ($gapresponse !== null && in_array($gapresponse, $value)) {
$state = parent::CORRECT;
} else {
$state = parent::INCORRECT;
}
$option->useranswer = $this->get_answer($state, $this->response[$key]);
$option->correctanswer = $this->get_answer(parent::TEXT, implode(' / ', $value));
$options[] = $option;
$num++;
}
return $options;
}
/**
* Return a label for result user options/choices
*
* Specific result types can override this method to customize
* the result options table header.
*
* @return string to use in options table
*/
protected function get_optionslabel(): string {
return get_string('result_matching', 'mod_h5pactivity');
}
}
@@ -0,0 +1,58 @@
<?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/>.
/**
* Contains class mod_h5pactivity\output\result\longfillin
*
* @package mod_h5pactivity
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_h5pactivity\output\result;
defined('MOODLE_INTERNAL') || die();
use mod_h5pactivity\output\result;
use renderer_base;
use stdClass;
/**
* Class to display H5P long fill in result.
*
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class longfillin extends result {
/**
* Export this data so it can be used as the context for a mustache template.
*
* @param renderer_base $output
* @return stdClass
*/
public function export_for_template(renderer_base $output): stdClass {
$data = parent::export_for_template($output);
$userresponse = reset($this->response);
$data->content = format_text($userresponse, FORMAT_PLAIN);
$data->track = true;
// Long fill-in is used for Essay type exercices. H5P adds
// extra characters to the description in all fill-in interactions
// but in the essay questions is unnecesary.
$data->description = preg_replace('/__________$/', '', $data->description);
return $data;
}
}
@@ -0,0 +1,139 @@
<?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/>.
/**
* Contains class mod_h5pactivity\output\result\matching
*
* @package mod_h5pactivity
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_h5pactivity\output\result;
defined('MOODLE_INTERNAL') || die();
use mod_h5pactivity\output\result;
/**
* Class to display H5P matching result.
*
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class matching extends result {
/**
* Return the options data structure.
*
* @return array|null of options
*/
protected function export_options(): ?array {
// Suppose H5P choices have only list of valid answers.
$correctpattern = reset($this->correctpattern);
$additionals = $this->additionals;
// Get sources (options).
if (isset($additionals->source)) {
$sources = $this->get_descriptions($additionals->source);
} else {
$sources = [];
}
// Get targets.
if (isset($additionals->target)) {
$targets = $this->get_descriptions($additionals->target);
} else {
$targets = [];
}
// Create original options array.
$options = array_map(function ($source) {
$cloneddraggable = clone $source;
$cloneddraggable->correctanswers = [];
return $cloneddraggable;
}, $sources);
// Fill options with correct answers flags if they exist.
foreach ($correctpattern as $pattern) {
if (!is_array($pattern) || count($pattern) != 2) {
continue;
}
// We assume here that the activity is following the convention sets in:
// https://github.com/h5p/h5p-php-report/blob/master/type-processors/matching-processor.class.php
// i.e. source is index 1 and dropzone is index 0.
if (isset($sources[$pattern[1]]) && isset($targets[$pattern[0]])) {
$target = $targets[$pattern[0]];
$source = $sources[$pattern[1]];
$currentoption = $options[$source->id];
$currentoption->correctanswers[$target->id] = $target->description;
}
}
// Fill in user responses.
foreach ($this->response as $response) {
if (!is_array($response) || count($response) != 2) {
continue;
}
if (isset($sources[$response[1]]) && isset($targets[$response[0]])) {
$source = $sources[$response[1]];
$target = $targets[$response[0]];
$answer = $response[0];
$option = $options[$source->id] ?? null;
if ($option) {
if (isset($option->correctanswers[$answer])) {
$state = parent::CORRECT;
} else {
$state = parent::INCORRECT;
}
$option->useranswer = $this->get_answer($state, $target->description);
}
}
}
// Fill in unchecked options.
foreach ($options as $option) {
if (!isset($option->useranswer)) {
if (!empty($option->correctanswers)) {
$option->useranswer = $this->get_answer(parent::INCORRECT,
get_string('answer_noanswer', 'mod_h5pactivity'));
} else {
$option->useranswer = $this->get_answer(parent::CORRECT,
get_string('answer_noanswer', 'mod_h5pactivity'));
}
}
}
// Now flattern correct answers.
foreach ($options as $option) {
$option->correctanswer = $this->get_answer( parent::TEXT, join(', ', $option->correctanswers));
unset($option->correctanswers);
}
return array_values($options);
}
/**
* Return a label for result user options/choices
*
* Specific result types can override this method to customize
* the result options table header.
*
* @return string to use in options table
*/
protected function get_optionslabel(): string {
return get_string('result_matching', 'mod_h5pactivity');
}
}
@@ -0,0 +1,54 @@
<?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/>.
/**
* Contains class mod_h5pactivity\output\result\other
*
* @package mod_h5pactivity
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_h5pactivity\output\result;
defined('MOODLE_INTERNAL') || die();
use mod_h5pactivity\output\result;
use renderer_base;
use stdClass;
/**
* Class to display H5P other result.
*
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class other extends result {
/**
* Export this data so it can be used as the context for a mustache template.
*
* @param renderer_base $output
* @return stdClass
*/
public function export_for_template(renderer_base $output): stdClass {
$data = parent::export_for_template($output);
if (empty($data->description)) {
$data->description = get_string('result_other', 'mod_h5pactivity');
}
return $data;
}
}
@@ -0,0 +1,102 @@
<?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/>.
/**
* Contains class mod_h5pactivity\output\result\sequencing
*
* @package mod_h5pactivity
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_h5pactivity\output\result;
defined('MOODLE_INTERNAL') || die();
use mod_h5pactivity\output\result;
use renderer_base;
/**
* Class to display H5P sequencing result.
*
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class sequencing extends result {
/**
* Return the options data structure.
*
* @return array of options
*/
protected function export_options(): ?array {
$correctpattern = reset($this->correctpattern);
$additionals = $this->additionals;
$response = $this->response;
if (isset($additionals->choices)) {
$choices = $this->get_descriptions($additionals->choices);
} else {
$choices = [];
}
$options = [];
$num = 1;
foreach ($correctpattern as $key => $pattern) {
if (!isset($choices[$pattern])) {
continue;
}
$option = (object)[
'id' => 'true',
'description' => get_string('result_sequencing_position', 'mod_h5pactivity', $num),
'correctanswer' => $this->get_answer(parent::TEXT, $choices[$pattern]->description),
'correctanswerid' => $key,
];
if (isset($response[$key])) {
$responseid = str_replace('item_', '', $response[$key]);
$answerstate = ($responseid == $option->correctanswerid) ? parent::PASS : parent::FAIL;
} else {
$answerstate = parent::FAIL;
}
$option->useranswer = $this->get_answer($answerstate);
$options[$key] = $option;
$num ++;
}
return $options;
}
/**
* Return a label for result user options/choices.
*
* @return string to use in options table
*/
protected function get_optionslabel(): string {
return get_string('result_sequencing_choice', 'mod_h5pactivity');
}
/**
* Return a label for result user correct answer.
*
* @return string to use in options table
*/
protected function get_correctlabel(): string {
return get_string('result_sequencing_answer', 'mod_h5pactivity');
}
}
@@ -0,0 +1,78 @@
<?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/>.
/**
* Contains class mod_h5pactivity\output\result\truefalse
*
* @package mod_h5pactivity
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_h5pactivity\output\result;
defined('MOODLE_INTERNAL') || die();
use mod_h5pactivity\output\result;
use renderer_base;
/**
* Class to display H5P choice result.
*
* @copyright 2020 Ferran Recio
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class truefalse extends result {
/**
* Return the options data structure.
*
* @return array of options
*/
protected function export_options(): ?array {
// This interaction type have only one entry which is the correct option.
$correctpattern = reset($this->correctpattern);
$correctpattern = filter_var(reset($correctpattern), FILTER_VALIDATE_BOOLEAN);
$correctpattern = $correctpattern ? 'true' : 'false';
$response = filter_var(reset($this->response), FILTER_VALIDATE_BOOLEAN);
$response = $response ? 'true' : 'false';
$options = [
(object)[
'id' => 'true',
'description' => get_string('true', 'mod_h5pactivity'),
],
(object)[
'id' => 'false',
'description' => get_string('false', 'mod_h5pactivity'),
],
];
foreach ($options as $value) {
$correctstate = ($value->id == $correctpattern) ? parent::CHECKED : parent::UNCHECKED;
if ($value->id == $response) {
$answerstate = ($correctstate == parent::CHECKED) ? parent::PASS : parent::FAIL;
$value->useranswer = $this->get_answer($answerstate);
}
$value->correctanswer = $this->get_answer($correctstate);
}
return $options;
}
}