diff --git a/lib/classes/output/activity_header.php b/lib/classes/output/activity_header.php index b2fa9522db1..84395b518a9 100644 --- a/lib/classes/output/activity_header.php +++ b/lib/classes/output/activity_header.php @@ -58,11 +58,10 @@ class activity_header implements \renderable, \templatable { public function __construct(moodle_page $page, \stdClass $user) { $this->page = $page; $this->user = $user; - $pageoptions = $this->page->theme->activityheaderconfig ?? []; $layoutoptions = $this->page->layout_options['activityheader'] ?? []; // Do a basic setup for the header based on theme/page options. if ($page->activityrecord) { - if (empty($pageoptions['notitle']) && empty($layoutoptions['notitle'])) { + if ($this->is_title_allowed()) { $this->title = format_string($page->activityrecord->name); } @@ -79,10 +78,22 @@ class activity_header implements \renderable, \templatable { /** * Checks if the theme has specified titles to be displayed. * + * First checks if the current layout has the notitle option set. If it is, uses that option to decide whether the title is + * displayed. If not, then checks whether the theme has the notitle option set and uses that. If neither is set, the title + * is allowed by default. + * * @return bool */ public function is_title_allowed(): bool { - return empty($this->page->theme->activityheaderconfig['notitle']); + $layoutoptions = $this->page->layout_options['activityheader'] ?? []; + $themeoptions = $this->page->theme->activityheaderconfig; + if (isset($layoutoptions['notitle'])) { + return !$layoutoptions['notitle']; + } else if (isset($themeoptions['notitle'])) { + return !$themeoptions['notitle']; + } else { + return true; + } } /** diff --git a/lib/pagelib.php b/lib/pagelib.php index cd649a39d7a..e2fc934c651 100644 --- a/lib/pagelib.php +++ b/lib/pagelib.php @@ -616,7 +616,7 @@ class moodle_page { */ protected function magic_get_layout_options() { if (!is_array($this->_layout_options)) { - $this->_layout_options = $this->_theme->pagelayout_options($this->pagelayout); + $this->_layout_options = $this->theme->pagelayout_options($this->pagelayout); } return $this->_layout_options; } diff --git a/lib/tests/output/activity_header_test.php b/lib/tests/output/activity_header_test.php index aa9717c2176..1092e3bf86c 100644 --- a/lib/tests/output/activity_header_test.php +++ b/lib/tests/output/activity_header_test.php @@ -156,4 +156,57 @@ class activity_header_test extends \advanced_testcase { $activityheaderstub->set_title($title); $this->assertEquals($expectedheadinglevel, $activityheaderstub->get_heading_level()); } + + /** + * Tests that is_title_allowed returns correctly based on the theme default and current layout options. + * + * The current layout has precedence, if the notitle option is set, otherwise the theme default is used if set. + * + * @param array $themeoptions The activityheader options array set in the theme. + * @param array $layoutoptions The activitityheader options array set in the layout. + * @param bool $allowed The expected return value of is_title_allowed. + * @covers ::is_title_allowed + * @dataProvider get_title_options + * @return void + */ + public function test_is_title_allowed(array $themeoptions, array $layoutoptions, bool $allowed): void { + $themeconfig = $this->getMockBuilder(\theme_config::class) + ->disableOriginalConstructor() + ->getMock(); + $themeconfig->activityheaderconfig = $themeoptions; + $page = $this->getMockBuilder(\moodle_page::class) + ->getMock(); + // Mocking the magic_get_layout_options() and magic_get_theme() methods directly doesn't work, + // so mock the whole magic __get() method and just return the test values for those properties. + $page->expects($this->any())->method('__get')->willReturnCallback(fn($name) => match($name) { + 'layout_options' => ['activityheader' => $layoutoptions], + 'theme' => $themeconfig, + default => null + }); + $user = new \stdClass(); + + $activityheader = new activity_header($page, $user); + $this->assertEquals($allowed, $activityheader->is_title_allowed()); + } + + /** + * Return scenarios for test_is_title_allowed. + * + * Test each combination of the 'notitle' option being unset, true and false in each of the theme and layout options. + * + * @return array[] + */ + public static function get_title_options(): array { + return [ + 'Undefined in theme, undefined in layout' => [[], [], true], + 'Undefined in theme, disallowed in layout' => [[], ['notitle' => true], false], + 'Undefined in theme, allowed in layout' => [[], ['notitle' => false], true], + 'Disallowed in theme, undefined in layout' => [['notitle' => true], [], false], + 'Disallowed in theme, disallowed in layout' => [['notitle' => true], ['notitle' => true], false], + 'Disallowed in theme, allowed in layout' => [['notitle' => true], ['notitle' => false], true], + 'Allowed in theme, undefined in layout' => [['notitle' => false], [], true], + 'Allowed in theme, disallowed in layout' => [['notitle' => false], ['notitle' => true], false], + 'Allowed in theme, allowed in layout' => [['notitle' => false], ['notitle' => false], true], + ]; + } }