From d176fe36c9d93e2d5fa8368c467e4e1144feb149 Mon Sep 17 00:00:00 2001 From: ferran Date: Thu, 31 Jul 2025 23:25:11 +0200 Subject: [PATCH] MDL-85598 course: new other purpose feature --- .../classes/local/entity/content_item.php | 12 +++++++ .../course_content_item_exporter.php | 7 ++++ .../content_item_readonly_repository.php | 4 +++ public/course/tests/content_item_test.php | 34 +++++++++++++++++++ .../tests/exporters_content_item_test.php | 25 +++++++++----- public/lib/moodlelib.php | 2 ++ 6 files changed, 75 insertions(+), 9 deletions(-) diff --git a/public/course/classes/local/entity/content_item.php b/public/course/classes/local/entity/content_item.php index 229eb46c4ea..d34c43a9059 100644 --- a/public/course/classes/local/entity/content_item.php +++ b/public/course/classes/local/entity/content_item.php @@ -47,6 +47,7 @@ class content_item { * @param string $purpose the purpose type of this component. * @param bool $branded whether or not this item is branded. * @param bool $gradable whether or not this item is gradable. + * @param string|null $otherpurpose the alternative purpose type of this component. */ public function __construct( /** @var int $id the id. */ @@ -71,6 +72,8 @@ class content_item { private bool $branded = false, /** @var bool $gradable whether or not this component is gradable. */ private bool $gradable = false, + /** @var string|null $otherpurpose the alternative purpose type of this component. */ + private ?string $otherpurpose = null, ) { } @@ -154,6 +157,15 @@ class content_item { return $this->purpose; } + /** + * Get alternative purpose for this item. + * + * @return string|null + */ + public function get_other_purpose(): ?string { + return $this->otherpurpose; + } + /** * Whether this item is branded. * diff --git a/public/course/classes/local/exporters/course_content_item_exporter.php b/public/course/classes/local/exporters/course_content_item_exporter.php index 0c59955a059..4fd90058b9c 100644 --- a/public/course/classes/local/exporters/course_content_item_exporter.php +++ b/public/course/classes/local/exporters/course_content_item_exporter.php @@ -71,6 +71,12 @@ class course_content_item_exporter extends exporter { 'purpose' => ['type' => PARAM_TEXT, 'description' => 'The purpose of the component exposing the content item'], 'branded' => ['type' => PARAM_BOOL, 'description' => ' Whether this content item is branded or not'], 'gradable' => ['type' => PARAM_BOOL, 'description' => 'Whether this content item is gradable or not'], + 'otherpurpose' => [ + 'type' => PARAM_TEXT, + 'null' => NULL_ALLOWED, + 'default' => null, + 'description' => 'The alternative purpose of the component exposing the content item', + ], ]; } @@ -143,6 +149,7 @@ class course_content_item_exporter extends exporter { 'purpose' => $this->contentitem->get_purpose(), 'branded' => $this->contentitem->is_branded(), 'gradable' => $this->contentitem->is_gradable(), + 'otherpurpose' => $this->contentitem->get_other_purpose(), ]; return $properties; diff --git a/public/course/classes/local/repository/content_item_readonly_repository.php b/public/course/classes/local/repository/content_item_readonly_repository.php index 119f28e209b..e613e8a560e 100644 --- a/public/course/classes/local/repository/content_item_readonly_repository.php +++ b/public/course/classes/local/repository/content_item_readonly_repository.php @@ -147,6 +147,7 @@ class content_item_readonly_repository implements content_item_readonly_reposito $help = $this->get_core_module_help_string($mod->name); $archetype = plugin_supports('mod', $mod->name, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); $purpose = plugin_supports('mod', $mod->name, FEATURE_MOD_PURPOSE, MOD_PURPOSE_OTHER); + $otherpurpose = plugin_supports('mod', $mod->name, FEATURE_MOD_OTHERPURPOSE); $isbranded = component_callback('mod_' . $mod->name, 'is_branded', [], false); $gradable = plugin_supports('mod', $mod->name, FEATURE_GRADE_HAS_GRADE, false); @@ -162,6 +163,7 @@ class content_item_readonly_repository implements content_item_readonly_reposito purpose: $purpose, branded: $isbranded, gradable: $gradable, + otherpurpose: $otherpurpose, ); $modcontentitemreference = clone($contentitem); @@ -215,6 +217,7 @@ class content_item_readonly_repository implements content_item_readonly_reposito $help = $this->get_core_module_help_string($mod->name); $archetype = plugin_supports('mod', $mod->name, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); $purpose = plugin_supports('mod', $mod->name, FEATURE_MOD_PURPOSE, MOD_PURPOSE_OTHER); + $otherpurpose = plugin_supports('mod', $mod->name, FEATURE_MOD_OTHERPURPOSE); $isbranded = component_callback('mod_' . $mod->name, 'is_branded', [], false); $gradable = plugin_supports('mod', $mod->name, FEATURE_GRADE_HAS_GRADE, false); @@ -238,6 +241,7 @@ class content_item_readonly_repository implements content_item_readonly_reposito purpose: $purpose, branded: $isbranded, gradable: $gradable, + otherpurpose: $otherpurpose, ); $modcontentitemreference = clone($contentitem); diff --git a/public/course/tests/content_item_test.php b/public/course/tests/content_item_test.php index f1ddaa3c60c..72090144f0d 100644 --- a/public/course/tests/content_item_test.php +++ b/public/course/tests/content_item_test.php @@ -51,6 +51,7 @@ final class content_item_test extends \advanced_testcase { purpose: MOD_PURPOSE_CONTENT, branded: true, gradable: true, + otherpurpose: MOD_PURPOSE_INTERACTIVECONTENT, ); $this->assertEquals(22, $contentitem->get_id()); @@ -64,6 +65,39 @@ final class content_item_test extends \advanced_testcase { $this->assertEquals('content', $contentitem->get_purpose()); $this->assertTrue($contentitem->is_branded()); $this->assertTrue($contentitem->is_gradable()); + $this->assertEquals(MOD_PURPOSE_INTERACTIVECONTENT, $contentitem->get_other_purpose()); + } + + /** + * Test class when only the mandatory fields are set. + */ + public function test_content_item_without_optional_params(): void { + $this->resetAfterTest(); + + $contentitem = new content_item( + id: 22, + name: 'Item name', + title: new lang_string_title('modulename', 'mod_assign'), + link: new \moodle_url('mod_edit.php'), + icon: '', + help: 'Description of the module', + archetype: MOD_ARCHETYPE_RESOURCE, + componentname: 'mod_page', + purpose: MOD_PURPOSE_CONTENT, + ); + + $this->assertEquals(22, $contentitem->get_id()); + $this->assertEquals('Item name', $contentitem->get_name()); + $this->assertEquals('Assignment', $contentitem->get_title()->get_value()); + $this->assertEquals(new \moodle_url('mod_edit.php'), $contentitem->get_link()); + $this->assertEquals('', $contentitem->get_icon()); + $this->assertEquals('Description of the module', $contentitem->get_help()); + $this->assertEquals(MOD_ARCHETYPE_RESOURCE, $contentitem->get_archetype()); + $this->assertEquals('mod_page', $contentitem->get_component_name()); + $this->assertEquals('content', $contentitem->get_purpose()); + $this->assertFalse($contentitem->is_branded()); + $this->assertFalse($contentitem->is_gradable()); + $this->assertNull($contentitem->get_other_purpose()); } /** diff --git a/public/course/tests/exporters_content_item_test.php b/public/course/tests/exporters_content_item_test.php index 7676f641202..d654366ed1d 100644 --- a/public/course/tests/exporters_content_item_test.php +++ b/public/course/tests/exporters_content_item_test.php @@ -86,16 +86,19 @@ final class exporters_content_item_test extends \advanced_testcase { $course = $this->getDataGenerator()->create_course(); $contentitem = new \core_course\local\entity\content_item( - -1, - 'test_name', - new \core_course\local\entity\string_title('test_title'), - new \moodle_url(''), - '', - '* First point + id: -1, + name: 'test_name', + title: new \core_course\local\entity\string_title('test_title'), + link: new \moodle_url(''), + icon: '', + help: '* First point * Another point', - MOD_ARCHETYPE_OTHER, - 'core_test', - MOD_PURPOSE_CONTENT + archetype: MOD_ARCHETYPE_OTHER, + componentname: 'core_test', + purpose: MOD_PURPOSE_CONTENT, + branded: false, + gradable: false, + otherpurpose: MOD_PURPOSE_INTERACTIVECONTENT, ); $ciexporter = new course_content_item_exporter($contentitem, ['context' => \context_course::instance($course->id)]); @@ -118,6 +121,10 @@ final class exporters_content_item_test extends \advanced_testcase { $this->assertEquals($exporteditem->archetype, $contentitem->get_archetype()); $this->assertObjectHasProperty('componentname', $exporteditem); $this->assertEquals($exporteditem->componentname, $contentitem->get_component_name()); + $this->assertEquals($exporteditem->purpose, $contentitem->get_purpose()); + $this->assertEquals($exporteditem->branded, $contentitem->is_branded()); + $this->assertEquals($exporteditem->gradable, $contentitem->is_gradable()); + $this->assertEquals($exporteditem->otherpurpose, $contentitem->get_other_purpose()); // Most important, is this a legacy item? $this->assertObjectHasProperty('legacyitem', $exporteditem); $this->assertTrue($exporteditem->legacyitem); diff --git a/public/lib/moodlelib.php b/public/lib/moodlelib.php index d11fa76bcb0..c140d575667 100644 --- a/public/lib/moodlelib.php +++ b/public/lib/moodlelib.php @@ -484,6 +484,8 @@ define('MOD_ARCHETYPE_SYSTEM', 3); /** Type of module */ define('FEATURE_MOD_PURPOSE', 'mod_purpose'); +/** Type of module alternative purpose */ +define('FEATURE_MOD_OTHERPURPOSE', 'mod_otherpurpose'); /** Module purpose administration */ define('MOD_PURPOSE_ADMINISTRATION', 'administration'); /** Module purpose assessment */