"dta/classes/view_submission_utils.php" did not exist on "8e9e343e09a87509af9f70b490d093f3e1bfbb1a"
db_utils.php 11.6 KB
Newer Older
1
<?php
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16

17
namespace assignsubmission_dta;
18
19

use assignsubmission_dta\dta_backend_utils;
20
use assignsubmission_dta\dta_view_submission_utils;
21
22
23
use assignsubmission_dta\models\dta_result;
use assignsubmission_dta\models\dta_result_summary;
use assignsubmission_dta\models\dta_recommendation;
24
25
26
27
28
29
30
31
32
33
34

/**
 * Class dta_db_utils
 *
 * Persistence layer utility class for storing and retrieving
 * DTA plugin data (results, summaries, recommendations).
 *
 * @package    assignsubmission_dta
 * @copyright  2023 Gero Lueckemeyer
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
35
class dta_db_utils {
36

Lückemeyer's avatar
Lückemeyer committed
37
38
39
    /**
     * Summary database table name.
     */
40
41
    private const ASSIGNSUBMISSION_DTA_TABLE_SUMMARY = 'assignsubmission_dta_summary';

Lückemeyer's avatar
Lückemeyer committed
42
43
44
    /**
     * Result database table name.
     */
45
    private const ASSIGNSUBMISSION_DTA_TABLE_RESULT = 'assignsubmission_dta_result';
46

47
48
49
50
    /**
     * Recommendations database table name.
     */
    private const ASSIGNSUBMISSION_DTA_TABLE_RECOMMENDATIONS = 'assignsubmission_dta_recommendations';
Kurzenberger's avatar
Kurzenberger committed
51

52
53
54
55
56
57
58
59
60
61
62
63
    /**
     * Returns an array of recommendations from the database.
     *
     * @param int $assignmentid The assignment ID.
     * @param int $submissionid The submission ID.
     * @return array An array of recommendation records.
     */
    public static function assignsubmission_dta_get_recommendations_from_database(
        int $assignmentid,
        int $submissionid
    ): array {
        global $DB, $USER;
64
        $userid = $USER->id;
65
66
67
68
69
70
71
72
73
74
75

        // Step 1: Retrieve all recommendations.
        $records = $DB->get_records(
            self::ASSIGNSUBMISSION_DTA_TABLE_RECOMMENDATIONS,
            [
                'assignment_id' => $assignmentid,
                'submission_id' => $submissionid,
            ]
        );

        // Step 2: Retrieve module ID for 'assign'.
76
77
        $module = $DB->get_record('modules', ['name' => 'assign'], 'id');
        if (!$module) {
78
            // Handle error case if the module is not found.
79
80
81
            return $records;
        }
        $moduleid = $module->id;
82
83

        // Step 3: Check each record.
84
        foreach ($records as $key => $record) {
85
            // Get the name of the exercise from the record.
86
            $exercisename = $record->exercise_name;
87
88

            // Find the assignment with this name.
89
90
            $assign = $DB->get_record('assign', ['name' => $exercisename], 'id');
            if ($assign) {
91
92
93
94
95
96
97
98
99
100
                // Get the course module ID for this assignment.
                $cm = $DB->get_record(
                    'course_modules',
                    [
                        'module'   => $moduleid,
                        'instance' => $assign->id,
                    ],
                    'id'
                );

101
                if ($cm) {
102
103
104
105
106
107
108
109
110
                    // Check the completion status for this course module and user.
                    $completion = $DB->get_record(
                        'course_modules_completion',
                        [
                            'coursemoduleid' => $cm->id,
                            'userid' => $userid,
                        ],
                        'completionstate'
                    );
Kurzenberger's avatar
Kurzenberger committed
111

112
113
114
                    // If the completion state is 1, remove the record from $records.
                    if ($completion && (int)$completion->completionstate === 1) {
                        unset($records[$key]);
115
116
117
118
                    }
                }
            }
        }
119
120

        // Return the filtered records.
Kurzenberger's avatar
Kurzenberger committed
121
122
123
        return $records;
    }

124
    /**
125
     * Gets a summary with all corresponding result entries.
126
     *
127
128
129
     * @param int $assignmentid Assignment ID to search for.
     * @param int $submissionid Submission ID to search for.
     * @return dta_result_summary Summary representing the submission.
130
     */
131
    public static function assignsubmission_dta_get_result_summary_from_database(
132
133
        int $assignmentid,
        int $submissionid
134
    ): dta_result_summary {
135
136
        global $DB;

137
        // Fetch data from database.
138
139
140
141
142
143
144
        $summaryrecord = $DB->get_record(
            self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY,
            [
                'assignment_id' => $assignmentid,
                'submission_id' => $submissionid,
            ]
        );
145

146
147
148
149
150
151
152
        $resultsarray = $DB->get_records(
            self::ASSIGNSUBMISSION_DTA_TABLE_RESULT,
            [
                'assignment_id' => $assignmentid,
                'submission_id' => $submissionid,
            ]
        );
153

154
        // Create a summary instance.
155
        $summary = new dta_result_summary();
156
        $summary->timestamp = $summaryrecord->timestamp;
157
158
159
        $summary->globalstacktrace = $summaryrecord->global_stacktrace;
        $summary->successfultestcompetencies = $summaryrecord->successful_competencies;
        $summary->overalltestcompetencies = $summaryrecord->tested_competencies;
160
        $summary->results = [];
161

162
163
        // Create result instances and add to array of summary instance.
        foreach ($resultsarray as $rr) {
164
            $result = new dta_result();
165
166
            $result->packagename = $rr->package_name;
            $result->classname = $rr->class_name;
167
168
            $result->name = $rr->name;
            $result->state = $rr->state;
169
170
            $result->failuretype = $rr->failure_type;
            $result->failurereason = $rr->failure_reason;
171
            $result->stacktrace = $rr->stacktrace;
172
173
            $result->columnnumber = $rr->column_number;
            $result->linenumber = $rr->line_number;
174
175
176
177
178
179
180
            $result->position = $rr->position;

            $summary->results[] = $result;
        }

        return $summary;
    }
181
182
183
184
185
186
187
188

    /**
     * Stores an array of recommendations in the database.
     *
     * @param int $assignmentid The assignment ID.
     * @param int $submissionid The submission ID.
     * @param array $recommendations An array of dta_recommendation objects.
     */
189
    public static function assignsubmission_dta_store_recommendations_to_database(
Kurzenberger's avatar
Kurzenberger committed
190
191
192
193
194
        int $assignmentid,
        int $submissionid,
        array $recommendations
    ): void {
        global $DB;
195
196
197
198

        // Debug output (you can remove or adapt this if unneeded).
        debugging('Recommendations array: ' . json_encode($recommendations));

Kurzenberger's avatar
Kurzenberger committed
199
        // If recommendations already exist, delete old values beforehand.
200
201
202
        $existingrecords = $DB->get_records(
            'assignsubmission_dta_recommendations',
            [
Kurzenberger's avatar
Kurzenberger committed
203
204
                'assignment_id' => $assignmentid,
                'submission_id' => $submissionid,
205
206
207
208
209
210
211
212
213
214
215
            ]
        );

        if ($existingrecords) {
            $DB->delete_records(
                'assignsubmission_dta_recommendations',
                [
                    'assignment_id' => $assignmentid,
                    'submission_id' => $submissionid,
                ]
            );
Kurzenberger's avatar
Kurzenberger committed
216
        }
217

Kurzenberger's avatar
Kurzenberger committed
218
        // Create new recommendation entries.
219
        foreach ($recommendations as $recommendation) {
220
            // Check if $recommendation is an instance of dta_recommendation.
221
            if ($recommendation instanceof dta_recommendation) {
222
                // Add assignment and submission IDs to the recommendation object.
223
224
                $recommendation->assignment_id = $assignmentid;
                $recommendation->submission_id = $submissionid;
225
226
227
228

                debugging('Inserting new recommendation record: ' . json_encode($recommendation));

                // Insert the recommendation into the database.
229
230
                $DB->insert_record('assignsubmission_dta_recommendations', $recommendation);
            } else {
231
232
                // Handle the case where $recommendation is not a dta_recommendation instance.
                debugging('Invalid recommendation object encountered.');
233
            }
Kurzenberger's avatar
Kurzenberger committed
234
235
        }
    }
236
237

    /**
238
239
     * Saves the given result summary and single results to the database
     * under the specified assignment and submission ID.
240
     *
241
242
243
     * @param int $assignmentid Assignment this submission is linked to.
     * @param int $submissionid Submission ID for these results.
     * @param dta_result_summary $summary Summary instance to persist.
244
     */
245
    public static function assignsubmission_dta_store_result_summary_to_database(
246
247
        int $assignmentid,
        int $submissionid,
248
        dta_result_summary $summary
249
250
251
    ): void {
        global $DB;

252
        // Prepare new database entries.
253
        $summaryrecord = new dta_result_summary();
254
255
256
        $summaryrecord->assignment_id = $assignmentid;
        $summaryrecord->submission_id = $submissionid;
        $summaryrecord->timestamp = $summary->timestamp;
257
258
259
        $summaryrecord->global_stacktrace = $summary->globalstacktrace;
        $summaryrecord->successful_competencies = $summary->successfultestcompetencies;
        $summaryrecord->tested_competencies = $summary->overalltestcompetencies;
260
261

        // Prepare results to persist.
262
        $resultrecords = [];
263
        foreach ($summary->results as $r) {
264
            $record = new dta_result();
265
266
            $record->assignment_id = $assignmentid;
            $record->submission_id = $submissionid;
267
268
            $record->package_name = $r->packagename;
            $record->class_name = $r->classname;
269
270
            $record->name = $r->name;
            $record->state = $r->state;
271
272
            $record->failure_type = $r->failuretype;
            $record->failure_reason = $r->failurereason;
273
            $record->stacktrace = $r->stacktrace;
274
275
            $record->column_number = $r->columnnumber;
            $record->line_number = $r->linenumber;
276
            $record->position = $r->position;
277
            $resultrecords[] = $record;
278
279
        }

280
        // If results already exist, delete old values beforehand.
281
282
283
        $submission = $DB->get_record(
            self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY,
            [
284
                'assignment_id' => $assignmentid,
285
                'submission_id' => $submissionid,
286
287
            ]
        );
288

289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
        if ($submission) {
            $DB->delete_records(
                self::ASSIGNSUBMISSION_DTA_TABLE_RESULT,
                [
                    'assignment_id' => $assignmentid,
                    'submission_id' => $submissionid,
                ]
            );

            $DB->delete_records(
                self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY,
                [
                    'assignment_id' => $assignmentid,
                    'submission_id' => $submissionid,
                ]
            );
305
306
        }

307
        // Create summary and single result entries.
308
        $DB->insert_record(self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY, $summaryrecord);
309
        foreach ($resultrecords as $rr) {
310
            $DB->insert_record(self::ASSIGNSUBMISSION_DTA_TABLE_RESULT, $rr);
311
312
313
314
        }
    }

    /**
315
     * Cleans up database if plugin is uninstalled.
316
     */
317
    public static function assignsubmission_dta_uninstall_plugin_cleaup(): void {
318
319
        global $DB;

320
321
322
        $DB->delete_records(self::ASSIGNSUBMISSION_DTA_TABLE_RESULT, null);
        $DB->delete_records(self::ASSIGNSUBMISSION_DTA_TABLE_SUMMARY, null);
        $DB->delete_records(self::ASSIGNSUBMISSION_DTA_TABLE_RECOMMENDATIONS, null);
323
324
    }
}