Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pm 43593 grading #17

Merged
merged 28 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
451f8ef
PM-43593 add grading interface
jz-kialo Sep 16, 2024
ea3e965
PM-43593 grading service implementation WIP
mk-kialo Sep 17, 2024
b384a4f
PM-43593 grading service implementation WIP
mk-kialo Sep 18, 2024
55cbfa7
PM-43593 working proof of concept
mk-kialo Sep 19, 2024
345d90f
PM-43593 started cleanup of code
mk-kialo Sep 19, 2024
9369ee4
PM-43593 cleanup
mk-kialo Sep 19, 2024
ae6f73f
PM-43593 handlefailed grade update
mk-kialo Sep 19, 2024
86e4286
PM-43593 fixed phpdoc issue
mk-kialo Sep 19, 2024
6b764d1
PM-43593 fixed another phpdoc issue
mk-kialo Sep 19, 2024
371ffc6
PM-43593 appeasing linters
mk-kialo Sep 20, 2024
73e9084
PM-43593 remove grades from the gradebook if grade is empty or negative
jz-kialo Sep 20, 2024
e8581a5
PM-43593 fixed existing tests
mk-kialo Sep 20, 2024
723973f
PM-43593 more tests
mk-kialo Sep 30, 2024
33fd9b8
PM-43593 more tests and improvements
mk-kialo Sep 30, 2024
78df90a
PM-43593 review comments
mk-kialo Sep 30, 2024
0ba2d67
PM-43593 fixed linting issues
mk-kialo Sep 30, 2024
1785b50
PM-43593 fixed tests and removed superfluous test code
mk-kialo Sep 30, 2024
310abb1
PM-43593 fixed tests
mk-kialo Sep 30, 2024
34be721
PM-43593 fix: except empty scoreGrades and empty timestamps
jz-kialo Oct 2, 2024
fb59f5e
PM-43593 create grade book item for old acitivties on the fly
jz-kialo Oct 2, 2024
6e8bcf2
PM-43593 added comment about unimplemented lineitems service.
mk-kialo Oct 2, 2024
3d93be4
PM-43593 cleanup code
jz-kialo Oct 2, 2024
de350d5
Merge remote-tracking branch 'refs/remotes/origin/main' into PM-43593…
mk-kialo Oct 14, 2024
70534da
Merge branch 'refs/heads/main' into PM-43593-grading
mk-kialo Oct 15, 2024
899c7b3
[tooling] fixed bundle folder name for real
mk-kialo Oct 15, 2024
7140682
[tooling] leave kialo target url setting empty by default so that the…
mk-kialo Oct 16, 2024
e940501
[tooling] improved kialourl setting description
mk-kialo Oct 16, 2024
a25b636
PM-43593 version updated
jz-kialo Oct 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ development/node_modules/
# Local History for Visual Studio Code
.history/

## vim
.phpactor.json

# macOS
.DS_Store
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
### v1.3.0 (Build - 2024101601)

* Added Grading
* Improved Moodle 4.5 compatibility

### v1.2.1 (Build - 2024091201)

* Namespaced styles
Expand Down
111 changes: 111 additions & 0 deletions classes/grading/grading_service.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.

// phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod
// phpcs:disable moodle.NamingConventions.ValidVariableName.MemberNameUnderscore
// phpcs:disable moodle.Files.RequireLogin.Missing -- doesn't require user to be logged in, as it's an LTI service

namespace mod_kialo\grading;

require_once(__DIR__ . '/../../../../config.php');
require_once(__DIR__ . '/../../lib.php');
require_once(__DIR__ . '/../../constants.php');
require_once(__DIR__ . '/../../vendor/autoload.php');
require_once($CFG->libdir . '/gradelib.php');

use grade_item;
use moodle_url;
use OAT\Library\Lti1p3Core\Exception\LtiException;

/**
* Service offering grading functionalities for LTI requests.
*
* @package mod_kialo
* @copyright 2023 onwards, Kialo GmbH <[email protected]>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grading_service {
/**
* Returns the line_item describing the grading settings for the given course module.
*
* @param int $courseid
* @param int $cmid
* @param string $resourcelinkid
* @return void
* @throws LtiException
* @throws \coding_exception
* @throws \moodle_exception
*/
public static function get_line_item(int $courseid, int $cmid, string $resourcelinkid): line_item {
$module = get_coursemodule_from_id('kialo', $cmid, $courseid, false, MUST_EXIST);

$gradeitem = grade_item::fetch(['iteminstance' => $module->instance, 'itemtype' => 'mod']);
if (!$gradeitem) {
$maxscore = 100;
} else {
$maxscore = $gradeitem->grademax;
}

$lineitem = new line_item();

// Assuming this is called from /mod/kialo/lti_lineitem.php. The ID is the URL of the request.
$lineitem->id = (new moodle_url($_SERVER['REQUEST_URI']))->out(false);
$lineitem->label = $module->name;
$lineitem->scoreMaximum = floatval($maxscore);
$lineitem->resourceLinkId = $resourcelinkid;

return $lineitem;
}

/**
* Writes grade information. The expected data format is the one defined in the spec,
* see https://www.imsglobal.org/spec/lti-ags/v2p0#example-posting-a-final-score-update.
*
* @param int $courseid
* @param int $cmid
* @param array $data array with required field userId
* @return bool Returns true if the grade information could be persisted.
* @throws LtiException
* @throws \coding_exception
* @throws \dml_exception
*/
public static function update_grade(int $courseid, int $cmid, array $data): bool {
global $DB;

$module = get_coursemodule_from_id('kialo', $cmid, $courseid, false, MUST_EXIST);
$moduleinstance = $DB->get_record('kialo', ['id' => $module->instance], '*', MUST_EXIST);

if (!isset($data['userId'])) {
throw new LtiException("Missing userId in the request body");
}

// Receive a score for the line item via JSON request body.
$userid = $data['userId'];
$scoregiven = isset($data['scoreGiven']) ? floatval($data['scoreGiven']) : null;
$comment = $data['comment'] ?? '';
$timestamp = isset($data['timestamp']) ? strtotime($data['timestamp']) : time();

$grades = [
'userid' => $userid,
'feedback' => $comment,
'dategraded' => $timestamp,
];
$grades['rawgrade'] = $scoregiven;

$result = kialo_grade_item_update($moduleinstance, (object) $grades);
return ($result === GRADE_UPDATE_OK || $result === GRADE_UPDATE_MULTIPLE);
}
}
94 changes: 94 additions & 0 deletions classes/grading/line_item.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.

// phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod
// phpcs:disable moodle.NamingConventions.ValidVariableName.MemberNameUnderscore

namespace mod_kialo\grading;

/**
* Represents a line item in the LTI 1.3 Assignment and Grading Service.
*
* @package mod_kialo
* @copyright 2023 onwards, Kialo GmbH <[email protected]>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class line_item {
/**
* @var string|null $id
*/
public $id;

/**
* @var float|null $scoreMaximum
*/
public $scoreMaximum;

/**
* @var string|null $label
*/
public $label;

/**
* @var string|null $resourceId
*/
public $resourceId;

/**
* @var string|null $tag
*/
public $resourceLinkId;

/**
* @var string|null $tag
*/
public $tag;

/**
* ISO 8601 timestamp, see https://www.imsglobal.org/spec/lti-ags/v2p0#startdatetime.
*
* @var string|null $startDateTime
*/
public $startDateTime;

/**
* ISO 8601 timestamp, see https://www.imsglobal.org/spec/lti-ags/v2p0#enddatetime.
*
* @var string|null $endDateTime
*/
public $endDateTime;

/**
* @var bool|null $gradesReleased
*/
public $gradesReleased;

/**
* LineItem constructor.
* @param array|null $lineitem
*/
public function __construct(?array $lineitem = null) {
$this->id = $lineitem['id'] ?? null;
$this->scoreMaximum = $lineitem['scoreMaximum'] ?? null;
$this->label = $lineitem['label'] ?? null;
$this->resourceId = $lineitem['resourceId'] ?? null;
$this->resourceLinkId = $lineitem['resourceLinkId'] ?? null;
$this->tag = $lineitem['tag'] ?? null;
$this->startDateTime = $lineitem['startDateTime'] ?? null;
$this->endDateTime = $lineitem['endDateTime'] ?? null;
$this->gradesReleased = $lineitem['gradesReleased'] ?? null;
}
}
22 changes: 18 additions & 4 deletions classes/kialo_config.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use moodle_url;
use OAT\Library\Lti1p3Core\Platform\Platform;
use OAT\Library\Lti1p3Core\Registration\Registration;
use OAT\Library\Lti1p3Core\Registration\RegistrationRepositoryInterface;
use OAT\Library\Lti1p3Core\Security\Key\KeyChainFactory;
use OAT\Library\Lti1p3Core\Security\Key\KeyChainInterface;
use OAT\Library\Lti1p3Core\Security\Key\KeyInterface;
Expand Down Expand Up @@ -133,10 +134,11 @@ public function get_client_id(): string {
*/
public function get_platform(): Platform {
return new Platform(
'kialo-moodle-plugin', // Identifier.
'Kialo Moodle Plugin', // Name.
(new moodle_url('/mod/kialo'))->out(), // Audience.
(new moodle_url('/mod/kialo/lti_auth.php'))->out(), // OIDC authentication url.
'kialo-moodle-plugin', // Identifier.
'Kialo Moodle Plugin', // Name.
(new moodle_url('/mod/kialo'))->out(), // Audience.
(new moodle_url('/mod/kialo/lti_auth.php'))->out(), // OIDC authentication url.
(new moodle_url('/mod/kialo/lti_token.php'))->out(), // OAuth2 access token URL.
);
}

Expand Down Expand Up @@ -180,4 +182,16 @@ public function create_registration(?string $deploymentid = null): Registration
$tooljwksurl, // JWKS URL used to download Kialo's keyset.
);
}

/**
* Returns a registration repository for the Kialo plugin.
*
* @param string|null $deploymentid The deployment id to use, or null, if it's not relevant.
* @return RegistrationRepositoryInterface
* @throws \dml_exception
*/
public function get_registration_repository(?string $deploymentid = null): RegistrationRepositoryInterface {
$registration = $this->create_registration($deploymentid);
return new static_registration_repository($registration);
}
}
Loading
Loading