diff --git a/report/log/classes/renderable.php b/report/log/classes/renderable.php index 738b5e94b4e..1064edae65a 100644 --- a/report/log/classes/renderable.php +++ b/report/log/classes/renderable.php @@ -103,6 +103,9 @@ class report_log_renderable implements renderable { */ public $grouplist; + /** @var bool if the page is activity page */ + public $isactivitypage; + /** * Constructor. * @@ -123,10 +126,30 @@ class report_log_renderable implements renderable { * @param int $page (optional) page number. * @param int $perpage (optional) number of records to show per page. * @param string $order (optional) sortorder of fetched records + * @param string $origin (optional) origin of the event. + * @param bool $isactivitypage (optional) if the page is activity page. */ - public function __construct($logreader = "", $course = 0, $userid = 0, $modid = 0, $action = "", $groupid = 0, $edulevel = -1, - $showcourses = false, $showusers = false, $showreport = true, $showselectorform = true, $url = "", $date = 0, - $logformat='showashtml', $page = 0, $perpage = 100, $order = "timecreated ASC", $origin ='') { + public function __construct( + $logreader = "", + $course = 0, + $userid = 0, + $modid = 0, + $action = "", + $groupid = 0, + $edulevel = -1, + $showcourses = false, + $showusers = false, + $showreport = true, + $showselectorform = true, + $url = "", + $date = 0, + $logformat='showashtml', + $page = 0, + $perpage = 100, + $order = "timecreated ASC", + $origin ='', + bool $isactivitypage = false, + ) { global $PAGE; @@ -171,6 +194,7 @@ class report_log_renderable implements renderable { $this->showselectorform = $showselectorform; $this->logformat = $logformat; $this->origin = $origin; + $this->isactivitypage = $isactivitypage; } /** diff --git a/report/log/classes/renderer.php b/report/log/classes/renderer.php index b8ff1aea173..f99bb97fc8f 100644 --- a/report/log/classes/renderer.php +++ b/report/log/classes/renderer.php @@ -95,29 +95,7 @@ class report_log_renderer extends plugin_renderer_base { $selectedcourseid = empty($reportlog->course) ? 0 : $reportlog->course->id; - // Add course selector. - $sitecontext = context_system::instance(); - $courses = $reportlog->get_course_list(); - if (!empty($courses) && $reportlog->showcourses) { - echo html_writer::label(get_string('selectacourse'), 'menuid', false, array('class' => 'accesshide')); - echo html_writer::select($courses, "id", $selectedcourseid, null, ['class' => 'me-2 mb-2']); - } else { - $courses = array(); - $courses[$selectedcourseid] = get_course_display_name_for_list($reportlog->course) . (($selectedcourseid == SITEID) ? - ' (' . get_string('site') . ') ' : ''); - echo html_writer::label(get_string('selectacourse'), 'menuid', false, array('class' => 'accesshide')); - echo html_writer::select($courses, "id", $selectedcourseid, false, ['class' => 'me-2 mb-2']); - // Check if user is admin and this came because of limitation on number of courses to show in dropdown. - if (has_capability('report/log:view', $sitecontext)) { - $a = new stdClass(); - $a->url = new moodle_url('/report/log/index.php', array('chooselog' => 0, - 'group' => $reportlog->get_selected_group(), 'user' => $reportlog->userid, - 'id' => $selectedcourseid, 'date' => $reportlog->date, 'modid' => $reportlog->modid, - 'showcourses' => 1, 'showusers' => $reportlog->showusers)); - $a->url = $a->url->out(false); - print_string('logtoomanycourses', 'moodle', $a); - } - } + echo $this->get_course_selector_field($reportlog, $selectedcourseid); // Add group selector. $groups = $reportlog->get_group_list(); @@ -161,10 +139,7 @@ class report_log_renderer extends plugin_renderer_base { ['class' => 'me-2 mb-2']); // Add activity selector. - [$activities, $disabled] = $reportlog->get_activities_list(); - echo html_writer::label(get_string('activities'), 'menumodid', false, array('class' => 'accesshide')); - echo html_writer::select($activities, "modid", $reportlog->modid, get_string("allactivities"), - ['class' => 'me-2 mb-2'], $disabled); + echo $this->get_activity_selector_field($reportlog); // Add actions selector. echo html_writer::label(get_string('actions'), 'menumodaction', false, array('class' => 'accesshide')); @@ -203,5 +178,99 @@ class report_log_renderer extends plugin_renderer_base { echo html_writer::end_div(); echo html_writer::end_tag('form'); } -} + /** + * Generates the course selector field for the log report. + * + * @param report_log_renderable $reportlog The output instance. + * @param int $selectedcourseid + * @return string + */ + private function get_course_selector_field(report_log_renderable $reportlog, int $selectedcourseid): string { + // When the log report is accessed vie an activity, we do not need a course selector. + if ($reportlog->isactivitypage) { + return html_writer::empty_tag( + 'input', + ['type' => 'hidden', 'name' => 'id', 'value' => $selectedcourseid] + ); + } + + $result = ''; + $sitecontext = context_system::instance(); + $courses = $reportlog->get_course_list(); + + if (!empty($courses) && $reportlog->showcourses) { + $result .= html_writer::label(get_string('selectacourse'), 'menuid', false, ['class' => 'accesshide']); + $result .= html_writer::select($courses, "id", $selectedcourseid, null, ['class' => 'me-2 mb-2']); + return $result; + } + + $courses = []; + $courseinfo = ($selectedcourseid == SITEID) ? ' (' . get_string('site') . ') ' : ''; + $courses[$selectedcourseid] = get_course_display_name_for_list($reportlog->course) . $courseinfo; + + $result .= html_writer::label(get_string('selectacourse'), 'menuid', false, ['class' => 'accesshide']); + $result .= html_writer::select($courses, "id", $selectedcourseid, false, ['class' => 'me-2 mb-2']); + + // Check if user is admin and this came because of limitation on number of courses to show in dropdown. + if (has_capability('report/log:view', $sitecontext)) { + $a = new stdClass(); + $a->url = new moodle_url( + '/report/log/index.php', + [ + 'chooselog' => 0, + 'group' => $reportlog->get_selected_group(), + 'user' => $reportlog->userid, + 'id' => $selectedcourseid, + 'date' => $reportlog->date, + 'modid' => $reportlog->modid, + 'showcourses' => 1, 'showusers' => $reportlog->showusers, + ] + ); + $a->url = $a->url->out(false); + $result .= get_string('logtoomanycourses', 'moodle', $a); + } + + return $result; + } + + /** + * Generates the activity selector field for the log report. + * + * @param report_log_renderable $reportlog The output instance. + * @return string + */ + private function get_activity_selector_field(report_log_renderable $reportlog): string { + $result = ''; + // When the log report is accessed vie an activity, we do not need an activity selector. + if ($reportlog->isactivitypage) { + $result .= html_writer::empty_tag( + 'input', + ['type' => 'hidden', 'name' => 'isactivitypage', 'value' => $reportlog->isactivitypage] + ); + $result .= html_writer::empty_tag( + 'input', + ['type' => 'hidden', 'name' => 'modid', 'value' => $reportlog->modid] + ); + return $result; + } + + [$activities, $disabled] = $reportlog->get_activities_list(); + + $result .= html_writer::label( + text: get_string('activities'), + for: 'menumodid', + colonize: false, + attributes: ['class' => 'accesshide'], + ); + $result .= html_writer::select( + options: $activities, + name: "modid", + selected: $reportlog->modid, + nothing: get_string("allactivities"), + attributes: ['class' => 'me-2 mb-2'], + disabled: $disabled, + ); + return $result; + } +} diff --git a/report/log/index.php b/report/log/index.php index 41519990296..73c95b1516a 100644 --- a/report/log/index.php +++ b/report/log/index.php @@ -35,6 +35,7 @@ $group = optional_param('group', 0, PARAM_INT); // Group to display. $user = optional_param('user', 0, PARAM_INT); // User to display. $date = optional_param('date', 0, PARAM_INT); // Date to display. $modid = optional_param('modid', 0, PARAM_ALPHANUMEXT); // Module id or 'site_errors'. +$isactivitypage = optional_param('isactivitypage', false, PARAM_BOOL); // Is this a course module page? $modaction = optional_param('modaction', '', PARAM_ALPHAEXT); // An action as recorded in the logs. $page = optional_param('page', '0', PARAM_INT); // Which page to show. $perpage = optional_param('perpage', '100', PARAM_INT); // How many per page. @@ -99,11 +100,27 @@ $url = new moodle_url("/report/log/index.php", $params); $PAGE->set_url('/report/log/index.php', array('id' => $id)); $PAGE->set_pagelayout('report'); +$cminfo = null; +if (!is_number($modid)) { + $isactivitypage = false; +} +if ($isactivitypage) { + $modinfo = get_fast_modinfo($id); + $cminfo = $modinfo->cms[intval($modid)] ?? null; + if ($cminfo === null) { + throw new moodle_exception('invalidmoduleid', '', '', $modid); + } +} + // Get course details. if ($id != $SITE->id) { $course = $DB->get_record('course', array('id' => $id), '*', MUST_EXIST); require_login($course); $context = context_course::instance($course->id); + if ($cminfo !== null) { + $context = $cminfo->context; + $PAGE->set_cm($cminfo); + } } else { $course = $SITE; require_login(); @@ -141,12 +158,36 @@ if ($course->id == $SITE->id) { $PAGE->set_title($strlogs); $PAGE->set_primary_active_tab('siteadminnode'); } else { - $PAGE->set_title($course->shortname .': '. $strlogs); + $contexttitle = $course->shortname . ': '; + if ($cminfo !== null) { + $contexttitle .= $cminfo->name . ' - '; + } + $PAGE->set_title($contexttitle . $strlogs); $PAGE->set_heading($course->fullname); } -$reportlog = new report_log_renderable($logreader, $course, $user, $modid, $modaction, $group, $edulevel, $showcourses, $showusers, - $chooselog, true, $url, $date, $logformat, $page, $perpage, 'timecreated DESC', $origin); +$reportlog = new report_log_renderable( + logreader: $logreader, + course: $course, + userid: $user, + modid: $modid, + action: $modaction, + groupid: $group, + edulevel: $edulevel, + showcourses: $showcourses, + showusers: $showusers, + showreport: $chooselog, + showselectorform: true, + url: $url, + date: $date, + logformat: $logformat, + page: $page, + perpage: $perpage, + order: 'timecreated DESC', + origin: $origin, + isactivitypage: $isactivitypage, +); + $readers = $reportlog->get_readers(); $output = $PAGE->get_renderer('report_log'); @@ -162,7 +203,9 @@ if (empty($readers)) { echo $output->header(); // Print selector dropdown. $pluginname = get_string('pluginname', 'report_log'); - report_helper::print_report_selector($pluginname); + if (!$isactivitypage) { + report_helper::print_report_selector($pluginname); + } $userinfo = get_string('allparticipants'); $dateinfo = get_string('alldays'); @@ -186,7 +229,9 @@ if (empty($readers)) { echo $output->header(); // Print selector dropdown. $pluginname = get_string('pluginname', 'report_log'); - report_helper::print_report_selector($pluginname); + if (!$isactivitypage) { + report_helper::print_report_selector($pluginname); + } echo $output->heading(get_string('chooselogs') .':', 3); echo $output->render($reportlog); } diff --git a/report/log/lib.php b/report/log/lib.php index 1c6dcf6966b..40743b5533e 100644 --- a/report/log/lib.php +++ b/report/log/lib.php @@ -125,7 +125,12 @@ function report_log_can_access_user_report($user, $course) { */ function report_log_extend_navigation_module($navigation, $cm) { if (has_capability('report/log:view', context_course::instance($cm->course))) { - $url = new moodle_url('/report/log/index.php', array('chooselog'=>'1','id'=>$cm->course,'modid'=>$cm->id)); + $url = new moodle_url('/report/log/index.php', [ + 'chooselog' => '1', + 'id' => $cm->course, + 'modid' => $cm->id, + 'isactivitypage' => '1', + ]); $navigation->add(get_string('logs'), $url, navigation_node::TYPE_SETTING, null, 'logreport', new pix_icon('i/report', '')); } } diff --git a/report/log/tests/behat/activity_report_log.feature b/report/log/tests/behat/activity_report_log.feature new file mode 100644 index 00000000000..9271de8b4e3 --- /dev/null +++ b/report/log/tests/behat/activity_report_log.feature @@ -0,0 +1,56 @@ +@report @report_log +Feature: In a activity page, navigate through the More / Logs menu, test for report log page + In order to navigate through report page + As an admin + Go to the activity page, click on More / Logs menu, and check for the report log page + + Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "activities" exist: + | activity | name | course | section | + | page | Test page 1 | C1 | 1 | + | page | Test page 2 | C1 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | student1 | Student | 1 | student1@example.com | + | student2 | Student | 2 | student2@example.com | + And the following "course enrolments" exist: + | user | course | role | + | admin | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + And I log in as "student1" + And I am on "Course 1" course homepage + And I follow "Test page 1" + And I am on "Course 1" course homepage + And I follow "Test page 2" + And I log out + And I log in as "student2" + And I am on "Course 1" course homepage + And I follow "Test page 1" + And I log out + + Scenario: Report selectors should be targeted toward course module + Given I am on the "Test page 1" Activity page logged in as "admin" + And I navigate to "Logs" in current page administration + And "menuid" "select" should not exist + And "modid" "select" should not exist + And I should see "All participants" in the "user" "select" + And I should see "All days" in the "date" "select" + And I should see "All sources" in the "origin" "select" + And I should see "All events" in the "edulevel" "select" + And I should see "Test page 1" in the "#page-header" "css_element" + And I should see "Student 1" in the "user" "select" + When I set the field "user" to "Student 1" + And I click on "Get these logs" "button" + Then I should see "Test page 1" in the "#page-header" "css_element" + And I should not see "Student 2" in the "table.reportlog" "css_element" + And I should see "Page: Test page 1" in the "table.reportlog" "css_element" + + Scenario: Report submission stays in the same course module page + Given I am on the "Test page 1" Activity page logged in as "admin" + When I navigate to "Logs" in current page administration + And I click on "Get these logs" "button" + Then I should see "Test page 1" in the "#page-header" "css_element"