MDL-71134 course: fix format get_output_classname

The get_output_classname method is used to invoke overridden output
components from course_formats. Now the method does not accept null
output names anymore, and it controls the format class is extending
the core one.
This commit is contained in:
Ferran Recio
2021-06-10 16:08:39 +02:00
parent e6779782dc
commit ee3547306e
3 changed files with 113 additions and 6 deletions
+11 -2
View File
@@ -33,6 +33,7 @@ use section_info;
use context_course;
use editsection_form;
use moodle_exception;
use coding_exception;
use moodle_url;
use lang_string;
use completion_info;
@@ -1074,16 +1075,24 @@ abstract class course_format {
/**
* Returns instance of output compornent used by this plugin
*
* @throws coding_exception if the format class does not extends the original core one.
* @param string $outputname the element to render (section, activity...)
* @return string the output component classname
*/
public function get_output_classname(?string $outputname): string {
public function get_output_classname(string $outputname): string {
// The core output class.
$baseclass = "core_course\\output\\$outputname";
// Check if there is a specific format class.
$component = 'format_'. $this->get_format();
$outputclass = "$component\\output\\$outputname";
if (class_exists($outputclass)) {
// Check that the outputclass is a subclass of the base class.
if (!is_subclass_of($outputclass, $baseclass)) {
throw new coding_exception("The \"$outputclass\" must extend \"$baseclass\"");
}
return $outputclass;
}
return "core_course\\output\\$outputname";
return $baseclass;
}
/**
+59 -4
View File
@@ -24,11 +24,19 @@
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/course/lib.php');
require_once($CFG->dirroot . '/course/tests/fixtures/format_theunittest.php');
class courseformat_test extends advanced_testcase {
/**
* Setup to ensure that fixtures are loaded.
*/
public static function setupBeforeClass(): void {
global $CFG;
require_once($CFG->dirroot . '/course/lib.php');
require_once($CFG->dirroot . '/course/tests/fixtures/format_theunittest.php');
require_once($CFG->dirroot . '/course/tests/fixtures/format_theunittest_output_course_format_state.php');
require_once($CFG->dirroot . '/course/tests/fixtures/format_theunittest_output_course_format_invalidoutput.php');
}
class core_course_courseformat_testcase extends advanced_testcase {
public function test_available_hook() {
global $DB;
$this->resetAfterTest();
@@ -200,6 +208,53 @@ class core_course_courseformat_testcase extends advanced_testcase {
$this->assertNotEmpty($format->get_view_url(1, ['navigation' => 1]));
$this->assertNotEmpty($format->get_view_url(0, ['navigation' => 1]));
}
/**
* Test for get_output_classname method.
*
* @dataProvider get_output_classname_provider
* @param string $find the class to find
* @param string $result the expected result classname
* @param bool $exception if the method will raise an exception
*/
public function test_get_output_classname($find, $result, $exception) {
$this->resetAfterTest();
$course = $this->getDataGenerator()->create_course(['format' => 'theunittest']);
$courseformat = course_get_format($course);
if ($exception) {
$this->expectException(coding_exception::class);
}
$courseclass = $courseformat->get_output_classname($find);
$this->assertEquals($result, $courseclass);
}
/**
* Data provider for test_get_output_classname.
*
* @return array the testing scenarios
*/
public function get_output_classname_provider(): array {
return [
'overridden class' => [
'find' => 'course_format\\state',
'result' => 'format_theunittest\\output\\course_format\\state',
'exception' => false,
],
'original class' => [
'find' => 'section_format\\state',
'result' => 'core_course\\output\\section_format\\state',
'exception' => false,
],
'invalid overridden class' => [
'find' => 'course_format\\invalidoutput',
'result' => '',
'exception' => true,
],
];
}
}
/**
@@ -0,0 +1,43 @@
<?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 format_theunittest\output\course_format;
use renderable;
use templatable;
use stdClass;
/**
* Fixture for an invalid output for testing get_output_classname.
*
* @package core_course
* @copyright 2021 Ferran Recio ([email protected])
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class invalidoutput implements renderable, templatable {
/**
* Export some data.
*
* @param renderer_base $output typically, the renderer that's calling this function
* @return stdClass data context for a mustache template
*/
public function export_for_template(\renderer_base $output): stdClass {
return (object)[
'something' => 'invalid',
];
}
}