/mod/lti/service/gradebookservices/classes/local/resources/lineitem.php
PHP | 336 lines | 242 code | 24 blank | 70 comment | 54 complexity | 48e9b814a28cf0d360d15219f6a245da MD5 | raw file
Possible License(s): MIT, AGPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, Apache-2.0, LGPL-2.1, BSD-3-Clause
- <?php
- // 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/>.
- /**
- * This file contains a class definition for the LineItem resource
- *
- * @package ltiservice_gradebookservices
- * @copyright 2017 Cengage Learning http://www.cengage.com
- * @author Dirk Singels, Diego del Blanco, Claude Vervoort
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
- namespace ltiservice_gradebookservices\local\resources;
- use ltiservice_gradebookservices\local\service\gradebookservices;
- use mod_lti\local\ltiservice\resource_base;
- defined('MOODLE_INTERNAL') || die();
- /**
- * A resource implementing LineItem.
- *
- * @package ltiservice_gradebookservices
- * @copyright 2017 Cengage Learning http://www.cengage.com
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
- class lineitem extends resource_base {
- /**
- * Class constructor.
- *
- * @param gradebookservices $service Service instance
- */
- public function __construct($service) {
- parent::__construct($service);
- $this->id = 'LineItem.item';
- $this->template = '/{context_id}/lineitems/{item_id}/lineitem';
- $this->variables[] = 'LineItem.url';
- $this->formats[] = 'application/vnd.ims.lis.v2.lineitem+json';
- $this->methods[] = self::HTTP_GET;
- $this->methods[] = self::HTTP_PUT;
- $this->methods[] = self::HTTP_DELETE;
- }
- /**
- * Execute the request for this resource.
- *
- * @param \mod_lti\local\ltiservice\response $response Response object for this request.
- */
- public function execute($response) {
- global $CFG, $DB;
- $params = $this->parse_template();
- $contextid = $params['context_id'];
- $itemid = $params['item_id'];
- $isget = $response->get_request_method() === self::HTTP_GET;
- // We will receive typeid when working with LTI 1.x, if not then we are in LTI 2.
- $typeid = optional_param('type_id', null, PARAM_INT);
- $scopes = array(gradebookservices::SCOPE_GRADEBOOKSERVICES_LINEITEM);
- if ($response->get_request_method() === self::HTTP_GET) {
- $scopes[] = gradebookservices::SCOPE_GRADEBOOKSERVICES_LINEITEM_READ;
- }
- try {
- if (!$this->check_tool($typeid, $response->get_request_data(), $scopes)) {
- throw new \Exception(null, 401);
- }
- $typeid = $this->get_service()->get_type()->id;
- if (!($course = $DB->get_record('course', array('id' => $contextid), 'id', IGNORE_MISSING))) {
- throw new \Exception("Not Found: Course {$contextid} doesn't exist", 404);
- }
- if (!$this->get_service()->is_allowed_in_context($typeid, $course->id)) {
- throw new \Exception('Not allowed in context', 403);
- }
- if (!$DB->record_exists('grade_items', array('id' => $itemid))) {
- throw new \Exception("Not Found: Grade item {$itemid} doesn't exist", 404);
- }
- $item = $this->get_service()->get_lineitem($contextid, $itemid, $typeid);
- if ($item === false) {
- throw new \Exception('Line item does not exist', 404);
- }
- require_once($CFG->libdir.'/gradelib.php');
- switch ($response->get_request_method()) {
- case self::HTTP_GET:
- $this->get_request($response, $item, $typeid);
- break;
- case self::HTTP_PUT:
- $json = $this->process_put_request($response->get_request_data(), $item, $typeid);
- $response->set_body($json);
- $response->set_code(200);
- break;
- case self::HTTP_DELETE:
- $this->process_delete_request($item);
- $response->set_code(204);
- break;
- }
- } catch (\Exception $e) {
- $response->set_code($e->getCode());
- $response->set_reason($e->getMessage());
- }
- }
- /**
- * Process a GET request.
- *
- * @param \mod_lti\local\ltiservice\response $response Response object for this request.
- * @param object $item Grade item instance.
- * @param string $typeid Tool Type Id
- */
- private function get_request($response, $item, $typeid) {
- $response->set_content_type($this->formats[0]);
- $lineitem = gradebookservices::item_for_json($item, substr(parent::get_endpoint(),
- 0, strrpos(parent::get_endpoint(), "/", -10)), $typeid);
- $response->set_body(json_encode($lineitem));
- }
- /**
- * Process a PUT request.
- *
- * @param string $body PUT body
- * @param \ltiservice_gradebookservices\local\resources\lineitem $olditem Grade item instance
- * @param string $typeid Tool Type Id
- *
- * @return string
- * @throws \Exception
- */
- private function process_put_request($body, $olditem, $typeid) {
- global $DB;
- $json = json_decode($body);
- if (empty($json) ||
- !isset($json->scoreMaximum) ||
- !isset($json->label)) {
- throw new \Exception(null, 400);
- }
- $item = \grade_item::fetch(array('id' => $olditem->id, 'courseid' => $olditem->courseid));
- $gbs = gradebookservices::find_ltiservice_gradebookservice_for_lineitem($olditem->id);
- $updategradeitem = false;
- $rescalegrades = false;
- $oldgrademax = grade_floatval($item->grademax);
- $upgradegradebookservices = false;
- if ($item->itemname !== $json->label) {
- $updategradeitem = true;
- }
- $item->itemname = $json->label;
- if (!is_numeric($json->scoreMaximum)) {
- throw new \Exception(null, 400);
- } else {
- if (grade_floats_different($oldgrademax,
- grade_floatval($json->scoreMaximum))) {
- $updategradeitem = true;
- $rescalegrades = true;
- }
- $item->grademax = grade_floatval($json->scoreMaximum);
- }
- $resourceid = (isset($json->resourceId)) ? $json->resourceId : '';
- if ($item->idnumber !== $resourceid) {
- $updategradeitem = true;
- }
- $item->idnumber = $resourceid;
- if ($gbs) {
- $tag = (isset($json->tag)) ? $json->tag : null;
- if ($gbs->tag !== $tag) {
- $upgradegradebookservices = true;
- }
- $gbs->tag = $tag;
- }
- $ltilinkid = null;
- if (isset($json->resourceLinkId)) {
- if (is_numeric($json->resourceLinkId)) {
- $ltilinkid = $json->resourceLinkId;
- if ($gbs) {
- if (intval($gbs->ltilinkid) !== intval($json->resourceLinkId)) {
- $gbs->ltilinkid = $json->resourceLinkId;
- $upgradegradebookservices = true;
- }
- } else {
- if (intval($item->iteminstance) !== intval($json->resourceLinkId)) {
- $item->iteminstance = intval($json->resourceLinkId);
- $updategradeitem = true;
- }
- }
- } else {
- throw new \Exception(null, 400);
- }
- } else if (isset($json->ltiLinkId)) {
- if (is_numeric($json->ltiLinkId)) {
- $ltilinkid = $json->ltiLinkId;
- if ($gbs) {
- if (intval($gbs->ltilinkid) !== intval($json->ltiLinkId)) {
- $gbs->ltilinkid = $json->ltiLinkId;
- $upgradegradebookservices = true;
- }
- } else {
- if (intval($item->iteminstance) !== intval($json->ltiLinkId)) {
- $item->iteminstance = intval($json->ltiLinkId);
- $updategradeitem = true;
- }
- }
- } else {
- throw new \Exception(null, 400);
- }
- }
- if ($ltilinkid != null) {
- if (is_null($typeid)) {
- if (!gradebookservices::check_lti_id($ltilinkid, $item->courseid,
- $this->get_service()->get_tool_proxy()->id)) {
- throw new \Exception(null, 403);
- }
- } else {
- if (!gradebookservices::check_lti_1x_id($ltilinkid, $item->courseid,
- $typeid)) {
- throw new \Exception(null, 403);
- }
- }
- }
- if ($updategradeitem) {
- if (!$item->update('mod/ltiservice_gradebookservices')) {
- throw new \Exception(null, 500);
- }
- if ($rescalegrades) {
- $item->rescale_grades_keep_percentage(0, $oldgrademax, 0, $item->grademax);
- }
- }
- $lineitem = new lineitem($this->get_service());
- $endpoint = $lineitem->get_endpoint();
- if ($upgradegradebookservices) {
- if (is_null($typeid)) {
- $toolproxyid = $this->get_service()->get_tool_proxy()->id;
- $baseurl = null;
- } else {
- $toolproxyid = null;
- $baseurl = lti_get_type_type_config($typeid)->lti_toolurl;
- }
- $DB->update_record('ltiservice_gradebookservices', (object)array(
- 'id' => $gbs->id,
- 'gradeitemid' => $gbs->gradeitemid,
- 'courseid' => $gbs->courseid,
- 'toolproxyid' => $toolproxyid,
- 'typeid' => $typeid,
- 'baseurl' => $baseurl,
- 'ltilinkid' => $ltilinkid,
- 'tag' => $gbs->tag
- ));
- }
- if (is_null($typeid)) {
- $id = "{$endpoint}";
- $json->id = $id;
- } else {
- $id = "{$endpoint}?type_id={$typeid}";
- $json->id = $id;
- }
- return json_encode($json, JSON_UNESCAPED_SLASHES);
- }
- /**
- * Process a DELETE request.
- *
- * @param \ltiservice_gradebookservices\local\resources\lineitem $item Grade item instance
- * @throws \Exception
- */
- private function process_delete_request($item) {
- global $DB;
- $gradeitem = \grade_item::fetch(array('id' => $item->id));
- if (($gbs = gradebookservices::find_ltiservice_gradebookservice_for_lineitem($item->id)) == false) {
- throw new \Exception(null, 403);
- }
- if (!$gradeitem->delete('mod/ltiservice_gradebookservices')) {
- throw new \Exception(null, 500);
- } else {
- $sqlparams = array();
- $sqlparams['id'] = $gbs->id;
- if (!$DB->delete_records('ltiservice_gradebookservices', $sqlparams)) {
- throw new \Exception(null, 500);
- }
- }
- }
- /**
- * Parse a value for custom parameter substitution variables.
- *
- * @param string $value String to be parsed
- *
- * @return string
- */
- public function parse_value($value) {
- global $COURSE, $CFG;
- if (strpos($value, '$LineItem.url') !== false) {
- $resolved = '';
- require_once($CFG->libdir . '/gradelib.php');
- $this->params['context_id'] = $COURSE->id;
- if ($tool = $this->get_service()->get_type()) {
- $this->params['tool_code'] = $tool->id;
- }
- $id = optional_param('id', 0, PARAM_INT); // Course Module ID.
- if (empty($id)) {
- $id = optional_param('lti_message_hint', 0, PARAM_INT);
- }
- if (!empty($id)) {
- $cm = get_coursemodule_from_id('lti', $id, 0, false, MUST_EXIST);
- $id = $cm->instance;
- $item = grade_get_grades($COURSE->id, 'mod', 'lti', $id);
- if ($item && $item->items) {
- $this->params['item_id'] = $item->items[0]->id;
- $resolved = parent::get_endpoint();
- $resolved .= "?type_id={$tool->id}";
- }
- }
- $value = str_replace('$LineItem.url', $resolved, $value);
- }
- return $value;
- }
- }