Skip to content

Commit abef0d4

Browse files
authored
Merge pull request #2 from catalyst/issue-1
Enable logs retrieval after course deletion by storing metadata
2 parents 63f95c3 + bbd78ae commit abef0d4

File tree

10 files changed

+307
-71
lines changed

10 files changed

+307
-71
lines changed

.github/workflows/ci.yml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# .github/workflows/ci.yml
2+
name: ci
3+
4+
on: [push, pull_request]
5+
6+
jobs:
7+
ci:
8+
uses: catalyst/catalyst-moodle-workflows/.github/workflows/ci.yml@main
9+
with:
10+
extra_plugin_runners: 'moodle-plugin-ci add-plugin catalyst/moodle-tool_lifecycle'

classes/lifecycle/log_table.php

+46-26
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,28 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
1616

17+
/**
18+
* Course backup logs table.
19+
*
20+
* @package tool_lcbackupcourselogstep
21+
* @copyright 2024 Catalyst IT
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
1725
namespace tool_lcbackupcourselogstep\lifecycle;
1826

1927
defined('MOODLE_INTERNAL') || die;
2028

2129
require_once($CFG->libdir . '/tablelib.php');
2230

23-
class log_table extends \table_sql
24-
{
31+
/**
32+
* Backup log table.
33+
*
34+
* @package tool_lcbackupcourselogstep
35+
* @copyright 2024 Catalyst IT
36+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37+
*/
38+
class log_table extends \table_sql {
2539

2640
/**
2741
* @var array "cached" lang strings
@@ -32,44 +46,43 @@ class log_table extends \table_sql
3246
* Constructor for delayed_courses_table.
3347
*
3448
* @throws \coding_exception
49+
* @param array $filterdata Filter data.
3550
*/
36-
public function __construct($filterdata = [])
37-
{
51+
public function __construct($filterdata = []) {
3852
global $DB;
3953

4054
parent::__construct('tool_lcbackupcourselogstep-log');
4155

42-
// Action buttons string
56+
// Action buttons string.
4357
$this->strings = [
44-
'download' => get_string('download')
58+
'download' => get_string('download'),
4559
];
4660

4761
// Build the SQL.
4862
$fields = 'f.id as id,
49-
co.id as courseid, co.shortname as courseshortname, co.fullname as coursefullname,
50-
f.filename as filename, f.timecreated as createdat';
51-
63+
md.oldcourseid as courseid, md.shortname as courseshortname, md.fullname as coursefullname,
64+
f.filename as filename, f.filesize as filesize, f.timecreated as createdat';
5265
$from = '{files} f
5366
JOIN {context} c ON c.id = f.contextid
54-
JOIN {course} co ON co.id = c.instanceid';
67+
LEFT JOIN {tool_lcbackupcourselogstep_metadata} md ON f.id = md.fileid';
5568

5669
$where = ["f.component = :component AND filename <> '.'"];
5770
$params = ['component' => 'tool_lcbackupcourselogstep'];
5871

5972
// Filtering.
6073
if ($filterdata) {
6174
if ($filterdata->shortname) {
62-
$where[] = $DB->sql_like('co.shortname', ':shortname', false, false);
75+
$where[] = $DB->sql_like('md.shortname', ':shortname', false, false);
6376
$params['shortname'] = '%' . $DB->sql_like_escape($filterdata->shortname) . '%';
6477
}
6578

6679
if ($filterdata->fullname) {
67-
$where[] = $DB->sql_like('co.fullname', ':fullname', false, false);
80+
$where[] = $DB->sql_like('md.fullname', ':fullname', false, false);
6881
$params['fullname'] = '%' . $DB->sql_like_escape($filterdata->fullname) . '%';
6982
}
7083

7184
if ($filterdata->courseid) {
72-
$where[] = 'co.id = :courseid';
85+
$where[] = 'md.oldcourseid = :courseid';
7386
$params['courseid'] = $filterdata->courseid;
7487
}
7588
}
@@ -78,13 +91,13 @@ public function __construct($filterdata = [])
7891

7992
$this->set_sql($fields, $from, $where, $params);
8093

81-
8294
// Columns.
8395
$this->define_columns([
8496
'courseid',
8597
'courseshortname',
8698
'coursefullname',
8799
'filename',
100+
'filesize',
88101
'createdat',
89102
'actions',
90103
]);
@@ -94,27 +107,26 @@ public function __construct($filterdata = [])
94107
get_string('course_shortname_header', 'tool_lcbackupcourselogstep'),
95108
get_string('course_fullname_header', 'tool_lcbackupcourselogstep'),
96109
get_string('filename_header', 'tool_lcbackupcourselogstep'),
110+
get_string('filesize_header', 'tool_lcbackupcoursestep'),
97111
get_string('createdat_header', 'tool_lcbackupcourselogstep'),
98112
get_string('actions_header', 'tool_lcbackupcourselogstep'),
99113
]);
100114

101115
// Set default sorting.
102116
$this->sortable(true, 'createdat', SORT_DESC);
117+
$this->sortable(true, 'filesize', SORT_DESC);
103118
$this->collapsible(true);
104119
$this->initialbars(true);
105120
$this->set_attribute('class', 'admintable generaltable');
106121
}
107122

108123
/**
109-
* Define download action.
124+
* Download action column.
110125
*
111-
* @param $row
112-
* @return bool|string
113-
* @throws \coding_exception
114-
* @throws \moodle_exception
126+
* @param object $row
127+
* @return string
115128
*/
116-
public function col_actions($row)
117-
{
129+
public function col_actions($row) {
118130
global $OUTPUT;
119131

120132
$actionmenu = new \action_menu();
@@ -130,15 +142,23 @@ public function col_actions($row)
130142
}
131143

132144
/**
133-
* Time when the file is created, displayed in user-friendly format.
145+
* Display time when the file was created.
134146
*
135-
* @param $row
147+
* @param object $row
136148
* @return string
137-
* @throws \coding_exception
138149
*/
139-
public function col_createdat($row)
140-
{
150+
public function col_createdat($row) {
141151
return userdate($row->createdat);
142152
}
143153

154+
/**
155+
* Display size in user friendly format.
156+
*
157+
* @param object $row
158+
* @return string
159+
*/
160+
public function col_filesize($row) {
161+
return display_size($row->filesize);
162+
}
163+
144164
}

classes/lifecycle/step.php

+71-20
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,18 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
1616

17+
/**
18+
* Step for backing up a course logs in the lifecycle process.
19+
*
20+
* @package tool_lcbackupcourselogstep
21+
* @copyright 2024 Catalyst
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
1725
namespace tool_lcbackupcourselogstep\lifecycle;
1826

27+
defined('MOODLE_INTERNAL') || die();
28+
1929
global $CFG;
2030
require_once($CFG->dirroot . '/admin/tool/lifecycle/step/lib.php');
2131

@@ -28,32 +38,52 @@
2838
use tool_lifecycle\step\instance_setting;
2939
use tool_lifecycle\step\libbase;
3040

31-
defined('MOODLE_INTERNAL') || die();
32-
41+
/**
42+
* Step class for the Backup Course Log Step plugin.
43+
*
44+
* @package tool_lcbackupcourselogstep
45+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
46+
*/
3347
class step extends libbase {
34-
public function get_subpluginname()
35-
{
48+
/**
49+
* Returns the subplugin name.
50+
*
51+
* @return string
52+
*/
53+
public function get_subpluginname() {
3654
return 'tool_lcbackupcourselogstep';
3755
}
3856

57+
/**
58+
* Get the plugin description.
59+
*
60+
* @return string
61+
*/
3962
public function get_plugin_description() {
4063
return "Backup course log step plugin";
4164
}
4265

43-
public function process_course($processid, $instanceid, $course)
44-
{
66+
/**
67+
* Processes the course.
68+
*
69+
* @param int $processid the process id.
70+
* @param int $instanceid step instance id.
71+
* @param object $course the course object.
72+
* @return step_response
73+
*/
74+
public function process_course($processid, $instanceid, $course) {
4575
global $DB;
4676

4777
// Get all logs for the course with related courses and user details.
4878
$sql = "SELECT log.*, c.shortname as courseshortname, c.fullname as coursefullname,
49-
u1.firstname as userfirstname, u1.lastname as userlastname,
79+
u1.firstname as userfirstname, u1.lastname as userlastname,
5080
u2.firstname as realuserfirstname, u2.lastname as realuserlastname,
51-
u3.firstname as relateduserfirstname, u3.lastname as relateduserlastname
52-
FROM {logstore_standard_log} as log
53-
LEFT JOIN {course} as c ON log.courseid = c.id
54-
LEFT JOIN {user} as u1 ON log.userid = u1.id
55-
LEFT JOIN {user} as u2 ON log.realuserid = u2.id
56-
LEFT JOIN {user} as u3 ON log.relateduserid = u3.id
81+
u3.firstname as relateduserfirstname, u3.lastname as relateduserlastname
82+
FROM {logstore_standard_log} log
83+
LEFT JOIN {course} c ON log.courseid = c.id
84+
LEFT JOIN {user} u1 ON log.userid = u1.id
85+
LEFT JOIN {user} u2 ON log.realuserid = u2.id
86+
LEFT JOIN {user} u3 ON log.relateduserid = u3.id
5787
WHERE courseid = :courseid";
5888

5989
// Get all logs for the course.
@@ -82,7 +112,7 @@ public function process_course($processid, $instanceid, $course)
82112

83113
// Prepare file record.
84114
$filerecord = [
85-
'contextid' => \context_course::instance($course->id)->id,
115+
'contextid' => \context_system::instance()->id,
86116
'component' => 'tool_lcbackupcourselogstep',
87117
'filearea' => 'course_log',
88118
'itemid' => $instanceid,
@@ -99,18 +129,37 @@ public function process_course($processid, $instanceid, $course)
99129
}
100130

101131
// Write data to file.
102-
dataformat::write_data_to_filearea($filerecord, $fileformat, $columns, $logs);
132+
$newfile = dataformat::write_data_to_filearea($filerecord, $fileformat, $columns, $logs);
133+
134+
$DB->insert_record('tool_lcbackupcourselogstep_metadata', [
135+
'shortname' => $course->shortname,
136+
'fullname' => $course->fullname,
137+
'oldcourseid' => $course->id,
138+
'fileid' => $newfile->get_id(),
139+
'timecreated' => time(),
140+
]);
103141

104142
// Proceed.
105143
return step_response::proceed();
106144
}
107145

146+
/**
147+
* Returns instance settings for the plugin.
148+
*
149+
* @return array The instance settings for this step.
150+
*/
108151
public function instance_settings() {
109152
return [
110153
new instance_setting('fileformat', PARAM_TEXT, true),
111154
];
112155
}
113156

157+
/**
158+
* Extend the instance form to add file format options.
159+
*
160+
* @param \MoodleQuickForm $mform The form object.
161+
* @return void
162+
*/
114163
public function extend_add_instance_form_definition($mform) {
115164
$fileformatoptions = [
116165
'csv' => 'CSV',
@@ -119,7 +168,7 @@ public function extend_add_instance_form_definition($mform) {
119168

120169
// Check if XMLWriter is available.
121170
// Available data formats are installed under 'dataformat' folder.
122-
// We need to install https://moodle.org/plugins/dataformat_xml
171+
// We need to install https://moodle.org/plugins/dataformat_xml.
123172
$classname = 'dataformat_xml\writer';
124173
if (class_exists($classname)) {
125174
$fileformatoptions['xml'] = 'XML';
@@ -131,17 +180,19 @@ public function extend_add_instance_form_definition($mform) {
131180
);
132181
$mform->setType('fileformat', PARAM_TEXT);
133182
$mform->setDefault('fileformat', 'csv');
134-
135183
}
136184

137-
public function get_plugin_settings()
138-
{
185+
/**
186+
* Returns the instance settings.
187+
*
188+
* @return void
189+
*/
190+
public function get_plugin_settings() {
139191
global $ADMIN;
140192
// Page to show the logs.
141193
$ADMIN->add('lifecycle_category', new admin_externalpage('tool_lcbackupcourselogstep_logs',
142194
get_string('courselogs', 'tool_lcbackupcourselogstep'),
143195
new moodle_url('/admin/tool/lcbackupcourselogstep/logs.php')));
144-
145196
}
146197

147198
}

classes/privacy/provider.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919
use core_privacy\local\metadata\null_provider;
2020

2121
/**
22-
* Privacy subsystem implementation for tool_samplestep.
22+
* Privacy subsystem implementation for tool_lcbackupcourselogstep.
2323
*
24-
* @package tool_samplestep
24+
* @package tool_lcbackupcourselogstep
25+
* @copyright 2024 Catalyst IT
2526
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2627
*/
2728
class provider implements null_provider {
@@ -32,7 +33,7 @@ class provider implements null_provider {
3233
*
3334
* @return string the reason
3435
*/
35-
public static function get_reason() : string {
36+
public static function get_reason(): string {
3637
return 'privacy:metadata';
3738
}
3839
}

db/install.xml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<XMLDB PATH="admin/tool/lcbackupcourselogstep/db" VERSION="2024102000" COMMENT="XMLDB file for Moodle tool/lcbackupcourselogstep"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
5+
>
6+
<TABLES>
7+
<TABLE NAME="tool_lcbackupcourselogstep_metadata" COMMENT="Metadata for course logs.">
8+
<FIELDS>
9+
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
10+
<FIELD NAME="shortname" TYPE="char" LENGTH="255" NOTNULL="true"/>
11+
<FIELD NAME="fullname" TYPE="char" LENGTH="255" NOTNULL="true"/>
12+
<FIELD NAME="oldcourseid" TYPE="int" LENGTH="10" NOTNULL="true"/>
13+
<FIELD NAME="fileid" TYPE="int" LENGTH="10" NOTNULL="true"/>
14+
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" COMMENT="Timestamp when the log file was created"/>
15+
</FIELDS>
16+
<KEYS>
17+
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
18+
<KEY NAME="fileid_fk" TYPE="foreign" FIELDS="fileid" REFTABLE="files" REFFIELDS="id"/>
19+
</KEYS>
20+
</TABLE>
21+
</TABLES>
22+
</XMLDB>

0 commit comments

Comments
 (0)