Skip to content

Commit e7bb900

Browse files
moniNaydenovmwreichel
authored andcommitted
#8617 - implement overview page
1 parent be9d783 commit e7bb900

File tree

2 files changed

+327
-1
lines changed

2 files changed

+327
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CHANGELOG
22
=========
33

44

5-
5.0.1 (2025-09-29)
5+
5.1.0 (2026-01-14)
66
-------------------
77
* Moodle 5.1.0 compatible version
88
* [BUG] #8440 - fix resetting of filters after applying changes on All files table
@@ -12,6 +12,7 @@ CHANGELOG
1212
* [BUG] #8567 - fix incorrect participants count and title in group mode
1313
* [FEATURE] #8094 - implement new completion criteria for imported files from assignment activities
1414
* [FEAUTRE] #8581 - show which group the user belongs to, and also groups members
15+
* [FEATURE] #8617 - Implement Overview class
1516

1617
5.0.1 (2025-09-29)
1718
-------------------

classes/courseformat/overview.php

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
<?php
2+
// This file is part of Moodle - http://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
namespace mod_publication\courseformat;
18+
19+
use cm_info;
20+
use core\url;
21+
use core_calendar\output\humandate;
22+
use core\output\local\properties\text_align;
23+
use core_courseformat\activityoverviewbase;
24+
use core_courseformat\local\overview\overviewitem;
25+
use core_courseformat\output\local\overview\overviewaction;
26+
27+
/**
28+
* Activity overview integration for mod_publication.
29+
*
30+
* @package mod_publication
31+
* @copyright 2026 Simeon Naydenov <moniNaydenov@gmail.com>
32+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33+
*/
34+
class overview extends activityoverviewbase {
35+
/** @var \publication The publication instance. */
36+
private \publication $publication;
37+
38+
/** @var ?overviewitem Cached completion overview item (moved to end of extra items). */
39+
private ?overviewitem $completionitem = null;
40+
41+
/**
42+
* Constructor.
43+
*
44+
* @param cm_info $cm The course module instance.
45+
*/
46+
public function __construct(cm_info $cm) {
47+
global $CFG;
48+
require_once($CFG->dirroot . '/mod/publication/locallib.php');
49+
50+
parent::__construct($cm);
51+
$this->publication = new \publication($this->cm, $this->course, $this->context);
52+
}
53+
54+
#[\Override]
55+
public function get_due_date_overview(): ?overviewitem {
56+
$instance = $this->publication->get_instance();
57+
$duedate = $instance->duedate;
58+
59+
// Check for user/group override.
60+
$override = $this->publication->override_get_currentuserorgroup();
61+
if ($override && $override->submissionoverride && $override->duedate > 0) {
62+
$duedate = $override->duedate;
63+
}
64+
65+
if (empty($duedate)) {
66+
return new overviewitem(
67+
name: get_string('duedate', 'publication'),
68+
value: null,
69+
content: '-',
70+
);
71+
}
72+
73+
return new overviewitem(
74+
name: get_string('duedate', 'publication'),
75+
value: $duedate,
76+
content: humandate::create_from_timestamp($duedate),
77+
);
78+
}
79+
80+
#[\Override]
81+
public function get_actions_overview(): ?overviewitem {
82+
if (!has_capability('mod/publication:approve', $this->context)) {
83+
return null;
84+
}
85+
86+
$instance = $this->publication->get_instance();
87+
$pendingcount = 0;
88+
$actiontext = get_string('view');
89+
$alertlabel = get_string('approval_required', 'publication');
90+
91+
if ($instance->obtainteacherapproval == 1) {
92+
$pendingcount = $this->publication->get_allfilestable(PUBLICATION_FILTER_APPROVALREQUIRED, true)->get_count();
93+
if ($pendingcount > 0) {
94+
$actiontext = get_string('giveapproval', 'publication');
95+
}
96+
}
97+
98+
$content = new overviewaction(
99+
url: new url('/mod/publication/view.php', [
100+
'id' => $this->cm->id,
101+
'filter' => PUBLICATION_FILTER_APPROVALREQUIRED,
102+
'allfilespage' => 1,
103+
]),
104+
text: $actiontext,
105+
badgevalue: $pendingcount > 0 ? (string)$pendingcount : null,
106+
badgetitle: $pendingcount > 0 ? $alertlabel : null,
107+
);
108+
109+
return new overviewitem(
110+
name: get_string('actions'),
111+
value: $actiontext,
112+
content: $content,
113+
textalign: text_align::CENTER,
114+
alertcount: $pendingcount,
115+
alertlabel: $alertlabel,
116+
);
117+
}
118+
119+
#[\Override]
120+
public function get_extra_overview_items(): array {
121+
$items = [];
122+
123+
// Approvaltodate first (right after duedate) - for students only.
124+
$approvaltodateitem = $this->get_extra_approval_to_date_overview();
125+
if ($approvaltodateitem !== null) {
126+
$items['approvaltodate'] = $approvaltodateitem;
127+
}
128+
129+
// Release status - for students only.
130+
$statusitem = $this->get_extra_release_status_overview();
131+
if ($statusitem !== null) {
132+
$items['releasestatus'] = $statusitem;
133+
}
134+
135+
// Submissions count - for teachers only.
136+
$submissionsitem = $this->get_extra_submissions_overview();
137+
if ($submissionsitem !== null) {
138+
$items['submissions'] = $submissionsitem;
139+
}
140+
141+
return $items;
142+
}
143+
144+
/**
145+
* Get the submissions overview for teachers.
146+
*
147+
* @return overviewitem|null The overview item or null if user lacks capability.
148+
*/
149+
private function get_extra_submissions_overview(): ?overviewitem {
150+
if (!has_capability('mod/publication:approve', $this->context)) {
151+
return null;
152+
}
153+
154+
$submissions = $this->publication->get_allfilestable(PUBLICATION_FILTER_ALLFILES, true)->get_count();
155+
156+
$mode = $this->publication->get_mode();
157+
if ($mode == PUBLICATION_MODE_ASSIGN_TEAMSUBMISSION) {
158+
$total = count($this->publication->get_groups($this->publication->get_groupingid()));
159+
} else {
160+
$total = count($this->publication->get_users([], true));
161+
}
162+
163+
return new overviewitem(
164+
name: get_string('allfiles', 'publication'),
165+
value: $submissions,
166+
content: get_string('count_of_total', 'core', ['count' => $submissions, 'total' => $total]),
167+
textalign: text_align::END,
168+
);
169+
}
170+
171+
/**
172+
* Get the release status overview for students.
173+
*
174+
* @return overviewitem|null The overview item or null if user lacks capability.
175+
*/
176+
private function get_extra_release_status_overview(): ?overviewitem {
177+
global $USER;
178+
179+
if (
180+
!has_capability('mod/publication:upload', $this->context, $USER, false)
181+
|| has_capability('moodle/site:config', $this->context)
182+
) {
183+
return null;
184+
}
185+
186+
$filestable = $this->publication->get_filestable();
187+
$filestable->init();
188+
189+
if (empty($filestable->data)) {
190+
return new overviewitem(
191+
name: get_string('publicationstatus', 'publication'),
192+
value: null,
193+
content: '-',
194+
);
195+
}
196+
197+
$status = $this->get_combined_approval_status();
198+
199+
return new overviewitem(
200+
name: get_string('publicationstatus', 'publication'),
201+
value: $status,
202+
content: $status,
203+
);
204+
}
205+
206+
/**
207+
* Get the approval deadline overview for students.
208+
*
209+
* @return overviewitem|null The overview item or null if not applicable.
210+
*/
211+
private function get_extra_approval_to_date_overview(): ?overviewitem {
212+
global $USER;
213+
214+
// Only show for students (not admins/teachers).
215+
if (
216+
!has_capability('mod/publication:upload', $this->context, $USER, false)
217+
|| has_capability('moodle/site:config', $this->context)
218+
) {
219+
return null;
220+
}
221+
222+
$instance = $this->publication->get_instance();
223+
224+
// Only show when student approval is required.
225+
if (!$instance->obtainstudentapproval) {
226+
return null;
227+
}
228+
229+
$approvaltodate = $instance->approvaltodate;
230+
231+
// Check for user/group override.
232+
$override = $this->publication->override_get_currentuserorgroup();
233+
if ($override && $override->approvaloverride && $override->approvaltodate > 0) {
234+
$approvaltodate = $override->approvaltodate;
235+
}
236+
237+
if (empty($approvaltodate)) {
238+
return null;
239+
}
240+
241+
return new overviewitem(
242+
name: get_string('approvaltodate', 'publication'),
243+
value: $approvaltodate,
244+
content: humandate::create_from_timestamp($approvaltodate),
245+
);
246+
}
247+
248+
/**
249+
* Calculate the combined approval status for the current user's files.
250+
*
251+
* @return string The status string.
252+
*/
253+
private function get_combined_approval_status(): string {
254+
global $USER;
255+
256+
$instance = $this->publication->get_instance();
257+
$contextid = $this->context->id;
258+
259+
$fs = get_file_storage();
260+
$files = $fs->get_area_files($contextid, 'mod_publication', 'attachment', $USER->id, 'timemodified', false);
261+
262+
if (empty($files)) {
263+
return '-';
264+
}
265+
266+
$hasapproved = false;
267+
$hasrejected = false;
268+
$haspending = false;
269+
270+
foreach ($files as $file) {
271+
if ($file->get_filepath() == '/resources/') {
272+
continue;
273+
}
274+
275+
$studentapproved = true;
276+
$studentrejected = false;
277+
$teacherapproved = true;
278+
$teacherrejected = false;
279+
280+
if ($instance->obtainstudentapproval == 1) {
281+
$studentapproval = $this->publication->student_approval($file);
282+
if ($studentapproval == 1) {
283+
$studentapproved = true;
284+
} else if ($studentapproval == 2) {
285+
$studentrejected = true;
286+
$studentapproved = false;
287+
} else {
288+
$studentapproved = false;
289+
}
290+
}
291+
292+
if ($instance->obtainteacherapproval == 1) {
293+
$teacherapproval = $this->publication->teacher_approval($file);
294+
if ($teacherapproval == 1) {
295+
$teacherapproved = true;
296+
} else if ($teacherapproval == 2) {
297+
$teacherrejected = true;
298+
$teacherapproved = false;
299+
} else {
300+
$teacherapproved = false;
301+
}
302+
}
303+
304+
if ($studentapproved && $teacherapproved) {
305+
$hasapproved = true;
306+
} else if ($studentrejected || $teacherrejected) {
307+
$hasrejected = true;
308+
} else {
309+
$haspending = true;
310+
}
311+
}
312+
313+
if ($hasrejected) {
314+
return get_string('rejected', 'publication');
315+
}
316+
if ($haspending) {
317+
return get_string('approval_required', 'publication');
318+
}
319+
if ($hasapproved) {
320+
return get_string('approved', 'publication');
321+
}
322+
323+
return '-';
324+
}
325+
}

0 commit comments

Comments
 (0)