edulegit_submission_manager::init()   C
last analyzed

Complexity

Conditions 13
Paths 5

Size

Total Lines 76
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 54
c 2
b 0
f 0
dl 0
loc 76
rs 6.6166
cc 13
nc 5
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
/**
18
 * The assignsubmission_edulegit submission manager class.
19
 *
20
 * @package   assignsubmission_edulegit
21
 * @author    Alex Crosby <[email protected]>
22
 * @copyright @2024 EduLegit.com
23
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
26
namespace assignsubmission_edulegit;
27
28
/**
29
 * Class edulegit_submission_manager
30
 *
31
 * This class manages the interaction between Moodle submissions and the EduLegit system.
32
 */
33
class edulegit_submission_manager {
34
35
    /**
36
     * @var edulegit_config Configuration object for the EduLegit plugin.
37
     */
38
    protected edulegit_config $config;
39
40
    /**
41
     * @var edulegit_client Client for communicating with the EduLegit API.
42
     */
43
    protected edulegit_client $client;
44
45
    /**
46
     * @var edulegit_submission_repository Repository for handling submission data.
47
     */
48
    protected edulegit_submission_repository $repository;
49
50
    /**
51
     * Constructor for the submission manager.
52
     *
53
     * @param edulegit_config $config Configuration object for the EduLegit plugin.
54
     * @param edulegit_client $client Client for communicating with the EduLegit API.
55
     * @param edulegit_submission_repository $repository Repository for handling submission data.
56
     */
57
    public function __construct(edulegit_config $config, edulegit_client $client,
58
            edulegit_submission_repository $repository) {
59
        $this->config = $config;
60
        $this->client = $client;
61
        $this->repository = $repository;
62
    }
63
64
    /**
65
     * Initializes a submission with EduLegit.
66
     *
67
     * @param object $submission The Moodle submission object.
68
     * @param array $options Additional options, such as user information.
69
     * @return edulegit_submission_entity|null The EduLegit submission entity or null if initialization fails.
70
     */
71
    public function init($submission, $options = []): ?edulegit_submission_entity {
72
        if (empty($submission) || empty($submission->assignment) || empty($submission->userid)) {
73
            return null;
74
        }
75
        $edulegitsubmission = $this->get_or_create_edulegit_submission($submission);
76
        if (!$edulegitsubmission) {
77
            return null;
78
        }
79
80
        $assignment = $this->repository->get_assignment_info($submission->assignment);
81
82
        $callbackurl = new \moodle_url('/mod/assign/submission/edulegit/callback.php');
0 ignored issues
show
Bug introduced by
The type moodle_url was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
83
84
        $autoplagiarismcheck = (bool) $this->config->get_plugin_or_global_config('enable_plagiarism');
85
        $autoaicheck = (bool) $this->config->get_plugin_or_global_config('enable_ai');
86
        $mustrecordevents = (bool) $this->config->get_plugin_or_global_config('enable_plagiarism');
87
        $mustrecordscreen = (bool) $this->config->get_plugin_or_global_config('enable_screen');
88
        $mustrecordcamera = (bool) $this->config->get_plugin_or_global_config('enable_camera');
89
        $mustrecognizeattentionmap = (bool) $this->config->get_plugin_or_global_config('enable_attention');
90
91
        $data = [
92
                'meta' => [
93
                        'callbackUrl' => $callbackurl,
94
                        'moodle' => $this->config->get_release(),
95
                        'plugin' => $this->config->get_plugin_release(),
96
                ],
97
                'user' => [
98
                        'externalId' => (int) $submission->userid,
99
                        'email' => $options['user']?->email ?? null,
100
                        'firstName' => $options['user']?->firstname ?? null,
101
                        'lastName' => $options['user']?->lastname ?? null,
102
                ],
103
                'taskUser' => [
104
                        'externalId' => (int) $edulegitsubmission->id,
105
                ],
106
                'task' => [
107
                        'externalId' => (int) $assignment->id,
108
                        'title' => $assignment->name ?: $assignment->id,
109
                        'text' => $assignment->activity ?: ($assignment->intro ?? ''),
110
                        'description' => ($assignment->intro ?? ''),
111
                        'startedAt' => $assignment->allowsubmissionsfromdate ?? null,
112
                        'finishedAt' => $assignment->duedate ?? ($assignment->gradingduedate ?? null),
113
                ],
114
                'course' => [
115
                        'externalId' => (int) $assignment->course,
116
                        'title' => $assignment->course_fullname ?: $assignment->course_shortname,
117
                        'text' => $assignment->course_summary ?? '',
118
                        'startedAt' => $assignment->course_startdate ?? null,
119
                        'finishedAt' => $assignment->course_enddate ?? null,
120
                        'setting' => [
121
                                'autoPlagiarismCheck' => $autoplagiarismcheck,
122
                                'autoAiCheck' => $autoaicheck,
123
                                'mustRecordEvents' => $mustrecordevents,
124
                                'mustRecordScreen' => $mustrecordscreen,
125
                                'mustRecordCamera' => $mustrecordcamera,
126
                                'mustRecognizeAttentionMap' => $mustrecognizeattentionmap,
127
                        ],
128
                ],
129
        ];
130
131
        $response = $this->client->init_assignment($data);
132
133
        $payload = $response->get_payload();
134
        $responseobject = $payload->data ?? null;
135
136
        // Handle API service errors.
137
        if (!$response->get_success() || empty($payload->success) || !$responseobject) {
138
            $error = $payload->error ?? ($response->get_error() ?: 'EduLegit service error.');
139
140
            $edulegitsubmission->status = 0;
141
            $edulegitsubmission->error = $error;
142
143
            return $this->repository->update_submission($edulegitsubmission) ? $edulegitsubmission : null;
144
        }
145
146
        return $this->sync_submission_edulegit_response($submission, $responseobject);
147
    }
148
149
    /**
150
     * Synchronizes a submission with EduLegit by its id.
151
     *
152
     * @param int $submissionid The ID of the submission to synchronize.
153
     * @return edulegit_submission_entity|null The EduLegit submission entity or null if synchronization fails.
154
     */
155
    public function sync(int $submissionid): ?edulegit_submission_entity {
156
        $edulegitsubmission = $this->repository->get_submission($submissionid);
157
158
        return $edulegitsubmission;
159
    }
160
161
    /**
162
     * Retrieves or creates an EduLegit submission entity.
163
     *
164
     * @param object $submission The Moodle submission object.
165
     * @return edulegit_submission_entity|null The EduLegit submission entity or null if creation fails.
166
     */
167
    private function get_or_create_edulegit_submission($submission): ?edulegit_submission_entity {
168
        $edulegitsubmission = $this->repository->get_submission($submission->id);
169
        if ($edulegitsubmission) {
170
            return $edulegitsubmission;
171
        }
172
173
        $edulegitsubmission = new edulegit_submission_entity();
174
        $edulegitsubmission->submission = $submission->id;
175
        $edulegitsubmission->assignment = $submission->assignment;
176
177
        $edulegitsubmission->id = $this->repository->insert_submission($edulegitsubmission);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->repository->inser...on($edulegitsubmission) can also be of type false. However, the property $id is declared as type integer|null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
178
179
        if (!$edulegitsubmission->id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $edulegitsubmission->id of type integer|null is loosely compared to false; this is ambiguous if the integer can be 0. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
180
            return null;
181
        }
182
183
        return $edulegitsubmission;
184
    }
185
186
    /**
187
     * Synchronizes the EduLegit submission entity with the data from response.
188
     *
189
     * @param object $submission The Moodle submission object.
190
     * @param object $data The data received from the EduLegit response.
191
     * @return edulegit_submission_entity|null The updated EduLegit submission entity or null if update fails.
192
     */
193
    private function sync_submission_edulegit_response($submission, $data): ?edulegit_submission_entity {
194
        $edulegitsubmission = $this->get_or_create_edulegit_submission($submission);
195
        if (!$edulegitsubmission) {
196
            return null;
197
        }
198
199
        $edulegitsubmission->title = $data->taskDocument->title ?? null;
200
        $edulegitsubmission->content = $data->taskDocument->content ?? null;
201
        $edulegitsubmission->documentid = $data->taskDocument->id ?? 0;
202
        $edulegitsubmission->taskid = $data->task->id ?? ($data->taskUser->taskId ?? 0);
203
        $edulegitsubmission->taskuserid = $data->taskUser->id ?? ($data->taskUser->taskUserId);
204
        $edulegitsubmission->url = $data->sharedDocument->viewUrl ?? ($data->sharedDocument->pdfUrl ?? null);
205
        $edulegitsubmission->authkey = $data->sharedDocument->authKey ?? null;
206
        $edulegitsubmission->score = $data->taskDocument->score ?? null;
207
        $edulegitsubmission->plagiarism = $data->taskDocument->plagiarism ?? null;
208
        $edulegitsubmission->airate = $data->taskDocument->aiAverageProbability ?? null;
209
        $edulegitsubmission->aiprobability = $data->taskDocument->aiProbability ?? null;
210
        $edulegitsubmission->baseurl = $data->baseUrl ?? null;
211
        $edulegitsubmission->userid = $data->user->id ?? null;
212
        $edulegitsubmission->userkey = $data->user->loginTimeToken ?? null;
213
214
        $edulegitsubmission->error = null;
215
        $edulegitsubmission->status = 1;
216
217
        return $this->repository->update_submission($edulegitsubmission) ? $edulegitsubmission : null;
218
    }
219
}
220