ÿØÿà JFIF    ÿÛ „  ( %!1"%)+...383-7(-.+  -%%--------+------------/----------------------------ÿÀ  ¶" ÿÄ     ÿÄ @    !1AQaq‘¡"±ÁÑð2’BRráS‚ñ3b¢CT²Ò #cÿÄ    ÿÄ '   1!AQ2a"‘±#ÿÚ   ? ò(/p‘—–¢·,M|¯G»R£üešT. ôŸEoCFñ‡ 4ÔkåóxR|µÁ¨ÓDà!Ç´µ˜‡p ÍQ‹§!þž^õWsŒy  åÁ§$á«%ºq˜™JyyË0y«^Ϗ -3ÃÏËÈ£Æ\P’ä„s&•‹Üs üô'àWt¹pñCp$bÚF`·7.^)¾!)ÒÙ˜–ÅÏš^h¾ø³·ìe±ŒaeÖ—Í,e=B}Jéߦ$$½—šÙÜCC¯¶è8β–Åkèwx LÉngT±æ¹£Ócœ¿Í/©Éÿ ‰ÚCÒ­mq;Tt¶–}0"zÖPcd1š­¤tˆ„ÐÓâqú[™öUCŠ2޿د­É(¸ßúçšmW,Ò ºf‹Ån™ÄLêÁ8üÁkÁ€L¥ÍuJ1œôrÂSŒÓöt!7EUíïb)AËi¬â-ÙHk8òÁiXYwÅ)O^"ÇØriÛô{»wRUKÙÏÚlÓ¬€‚’שT ] ªb—ÊîKC^×M“xùäñz¬zJ× {4[¹M'IÆeH1LCWÕ]œûº WDæà°OÅ‚¹c²ÞuA–rL`HšpCez‡V’— Ž‚Ë„–ñ­'µR0ÕÖ=À:±G»C\nÆÉ5*¢ †3šhQ4ýÒi$Õ1"Ü]¢p-q3zcQ$ªö¨¥æf›‘»´ÝÚHá„e²JÇ–iÊ:·à¬Øc5Åk»Laª*wi [0Ówk ¦a¦0Õ²ÅÅ‚T¸’³q:Æ<¹ú Ò˜Æ}2VE•Ѐp¡Ô3Úº …h³^LJºçì¥Ánó|˜ÖˆÎˆ+« ¦dø‘Mº–d\ªDðÛ„Ì×LÝ——Ð9Ç|•FèçVm™¨€™3õS–9Äå¢<̉Ìm¢±`·º˜&Z²ž Ë®D«¶»6™‰©­HÈ Àá«h­i³04æ’hxœi3ï¨(ÓL·†‹¶ËpŒ ƒÜÒ? :õdsÀ –3æÓ·Üjâ¬9—]8n¼&]I F£¼…ì–—Œ0v°LǐÅfÛ2TÖ’aµ˜N@ÖBSÏ^à´4-±°b×nÈÈœÆD=KdŒø…ÄÈK,›ÖR§fjü$^ÔÎ!„6^ s:Üun\ôkCÞò÷<—Lúl Í›G¹ÀPá¼Nc¡šÒ…ÙWͳœ±vÊáЄ×9‹P‰cEØ‘™›µŸP<×g1 º©Ø¬wiÁ^l5× I/';Ë+´Z‡ÓÄFÕp[Èð’ HÄ ó 9¬Dl4“é±Ï”V=^Hð;žLädÉa‚°Ë,#/Ž~²BÔÛ QãñQtIeórVB,ÏÂf‹4#Μc‹É3ZIÖ Œ¢¥·üxa‡Ãçè„jŠ[5 Ä!U?,3žÎ×…ðdÓ÷háŠA‰ìÄ4÷ÃÜZÃE{‰®+W\ZÍE[‰»µk»MÝ­`¢©†˜ÃV‹-f¢¡†¢a«eŠ%«Y¨©q%jâd,Ôq`) ¤¦…šˆ ¦E>0Ùb²t–Ÿ  ÷jsςҒKÈcø(é›;k(’#ôŒQ ™C> õ³M9óºÆµ¤çâ;uÀ)5>RÔ¸fÓ~Ȧ—’-$fe«"FâUˆÊwµPÏu w+"åÉó¨6s™Û9(À¨ù©hE°½†n`m~“@©›p!Vkhµ Á1šbEqqÊ@ºèl›2 –Yã%‘‚hÛ{a¶‡ÅÞM²¬çL34®Çl]®‹ŽØŒm'RÜe35æöˆ­Á­ cP9šeÁköo´L³Ì=p8]”‡B¶,šº|ɏdzXˆØk*ÇÚ{#ñ‰pã(€¶‡9ý'šÜ³½¯kƒ†Â’ëSOƒ•Å®H6+a¢µˆ‹Y¨b˜b+XˆÖ!°u!¢"µˆˆn2ˆ Å0Ä`Å Ô®c(ÓÜGº•Ä»Œ âWî%q.áÐÄ÷î%umÍ£+ÜQ,Vn¦-GphU¸¢X­&,Gt ·K¢ÅÅ·¥RÄÊÉbKn N­R2g$VµÕó Qr#–ÓZUÏð0ÎtÙÀœz ëöo“Îk¯n„T°"SÞ+³/…€½"ižãO%Í%&Δâ‘ËØ´IˆÓ°Ë‰ÞM3.™yçÁzit›`4C`k¢¼á!álÄï sÂ[×!¤l¾æo"ƒIÔ'@ªu)3›ô®“@Z à¾] üœ'‡4¸PÞkÁ-qÄH‰ÓÍBd´ÿ —¹°ÄA&ÊUC„öz‚‚RæŠtf¬>˜ÑidšEçÑL÷áý¡V±h§­c¿¥¨ƒ@g¼…Ýö^ÞËc.ž„æ“I[ ª+·zÐÒÚ,½Ð»¶€C›7jk$๖€Ž¾ÅÙpp¶ÍþéΤ ½ØÎŒq ñpæžÅ¥#Øâ49ÃÂK^MYV“,¶Éz_òæ:…;Õ«¦I3âJ£¤û5$7Èxün\â]Êe¯(Ÿ&Ž‹¶2<6Ćf× æ¢ƱqWı[(ÙÂŽç‚T7¨@ÈÉÍß‚ïÙ"&3TYlGށ†)†#5ŠA©^T2ÆÁ†)©†©†¤yGXÁ†©"†)©¼ÅV WS†#©]R–r‹q5ÕbâWþBh¯u+ªÅÄ×ü„nÑ^êkªÁj‰jeœWˆÕÕ`µDµ2Ì+Ä µDµµ5Ô{¤Þ0RF’H÷AÛ<ÊÁ§ ƈæ0Ñ£ê4 öÚµ[¬/1²€â<-¬šö²r×0o×w ´xÐÒË„ g01¬„åEM蛇Ã\6µE›‘fÙO k÷CºnÓ1`iîÒ² áÂ!ÑLÄÿ ³¬\õ*:M=Ç»c‹2[‰ØsÕLò\ŒK L^™üÄN\¶#» Ç\……ßïIœÉ$¸ÎñÍ®ÔHÇ Ûí/´>Li”„†g^$ 7NÍÑÑ2M2ªNg=k½Ð}Ÿl6‡ —JWˆ”ÞéT·+µ¦üÂFè¢Vs6ýÆ4»2+2IÝ9ô9®ÇGÙÇ1+Ä8;*Õ§ž½D*îÑWÚçá3Ma¤·ˆ¥t}š²Ü…Q+Æüµ8HíS”üxGéÁˆ¦Ël„éÈ 5 µÄƒ6äÜ(kIš¯S†fÖ&¸®×v|Äyˆ*禌Éù@7-®Ä[]ÎÖ¿ê`º…=:…žJVnݳvðÖKE¼‚ »mà ÷f®:Ë ™–4rð¡4` ܹçž~‹C=œ…¾Ïj|VDtK.ƒ"9 Ï ­–éXá³6WÒïIL-Ї Ç lang/en/ltiservice_basicoutcomes.php000064400000003034152267124350013700 0ustar00. /** * Strings for component 'ltiservice_basicoutcomes', language 'en' * * @package ltiservice_basicoutcomes * @copyright 2019 Stephen Vickers * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ $string['allow'] = 'Use this service to accept grades from the tool'; $string['ltiservice_basicoutcomes'] = 'Basic Outcomes'; $string['ltiservice_basicoutcomes_help'] = 'Allow the tool to save and retrieve its grades to a gradebook column associated with each link.'; $string['notallow'] = 'Do not use this service'; $string['pluginname'] = 'Basic Outcomes Service'; $string['privacy:metadata:externalpurpose'] = 'This information is sent to an external LTI provider.'; $string['privacy:metadata:grade'] = 'The tool\'s grades of the user using the LTI consumer.'; $string['privacy:metadata:userid'] = 'The ID of the user using the LTI consumer.'; version.php000064400000002056152267124350006754 0ustar00. /** * Version information for the ltiservice_basicoutcomes service. * * @package ltiservice_basicoutcomes * @copyright 2019 Stephen Vickers * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $plugin->version = 2025041400; $plugin->requires = 2025040800; $plugin->component = 'ltiservice_basicoutcomes'; classes/privacy/provider.php000064400000007512152267124350012235 0ustar00. /** * Privacy Subsystem implementation for ltiservice_basicoutcomes. * * @package ltiservice_basicoutcomes * @copyright 2019 Stephen Vickers * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace ltiservice_basicoutcomes\privacy; use \core_privacy\local\metadata\collection; use \core_privacy\local\request\contextlist; use \core_privacy\local\request\approved_contextlist; use \core_privacy\local\request\userlist; use \core_privacy\local\request\approved_userlist; defined('MOODLE_INTERNAL') || die(); /** * Privacy Subsystem for ltiservice_basicoutcomes. * * @copyright 2019 Stephen Vickers * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class provider implements \core_privacy\local\metadata\provider, \core_privacy\local\request\core_userlist_provider, \core_privacy\local\request\plugin\provider { /** * Returns meta data about this system. * * @param collection $collection The initialised collection to add items to. * @return collection A listing of user data stored through this system. */ public static function get_metadata(collection $collection): collection { $collection->link_external_location('External LTI provider.', [ 'userid' => 'privacy:metadata:userid', 'grade' => 'privacy:metadata:grade', ], 'privacy:metadata:externalpurpose'); return $collection; } /** * Get the list of contexts that contain user information for the specified user. * * @param int $userid The user to search. * @return contextlist The contextlist containing the list of contexts used in this plugin. */ public static function get_contexts_for_userid(int $userid): contextlist { return new contextlist(); } /** * Get the list of users who have data within a context. * * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. */ public static function get_users_in_context(userlist $userlist) { } /** * Export all user data for the specified user, in the specified contexts. * * @param approved_contextlist $contextlist The approved contexts to export information for. */ public static function export_user_data(approved_contextlist $contextlist) { } /** * Delete all user data which matches the specified context. * * @param \context $context A user context. */ public static function delete_data_for_all_users_in_context(\context $context) { } /** * Delete multiple users within a single context. * * @param approved_userlist $userlist The approved context and user information to delete information for. */ public static function delete_data_for_users(approved_userlist $userlist) { } /** * Delete all user data for the specified user, in the specified contexts. * * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. */ public static function delete_data_for_user(approved_contextlist $contextlist) { } } classes/local/service/basicoutcomes.php000064400000006437152267124350014325 0ustar00. /** * This file contains a class definition for the Basic Outcomes service * * @package ltiservice_basicoutcomes * @copyright 2019 Stephen Vickers * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace ltiservice_basicoutcomes\local\service; defined('MOODLE_INTERNAL') || die(); /** * A service implementing Basic Outcomes. * * @package ltiservice_basicoutcomes * @since Moodle 3.7 * @copyright 2019 Stephen Vickers * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class basicoutcomes extends \mod_lti\local\ltiservice\service_base { /** Scope for accessing the service */ const SCOPE_BASIC_OUTCOMES = 'https://purl.imsglobal.org/spec/lti-bo/scope/basicoutcome'; /** * Class constructor. */ public function __construct() { parent::__construct(); $this->id = 'basicoutcomes'; $this->name = 'Basic Outcomes'; } /** * Get the resources for this service. * * @return array */ public function get_resources() { if (empty($this->resources)) { $this->resources = array(); $this->resources[] = new \ltiservice_basicoutcomes\local\resources\basicoutcomes($this); } return $this->resources; } /** * Get the scope(s) permitted for the tool relevant to this service. * * @return array */ public function get_permitted_scopes() { $scopes = array(); if (!isset($this->get_typeconfig()['acceptgrades']) || ($this->get_typeconfig()['acceptgrades'] != LTI_SETTING_NEVER)) { $scopes[] = self::SCOPE_BASIC_OUTCOMES; } return $scopes; } /** * Get the scope(s) permitted for the tool relevant to this service. * * @return array */ public function get_scopes() { return [self::SCOPE_BASIC_OUTCOMES]; } /** * Return an array of key/claim mapping allowing LTI 1.1 custom parameters * to be transformed to LTI 1.3 claims. * * @return array Key/value pairs of params to claim mapping. */ public function get_jwt_claim_mappings(): array { return [ 'lis_outcome_service_url' => [ 'suffix' => 'bo', 'group' => 'basicoutcome', 'claim' => 'lis_outcome_service_url', 'isarray' => false ], 'lis_result_sourcedid' => [ 'suffix' => 'bo', 'group' => 'basicoutcome', 'claim' => 'lis_result_sourcedid', 'isarray' => false ] ]; } } classes/local/resources/basicoutcomes.php000064400000004317152267124350014672 0ustar00. /** * This file contains a class definition for the Basic Outcomes resource * * @package ltiservice_basicoutcomes * @copyright 2019 Stephen Vickers * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace ltiservice_basicoutcomes\local\resources; defined('MOODLE_INTERNAL') || die(); /** * A resource implementing the Basic Outcomes service. * * @package ltiservice_basicoutcomes * @since Moodle 3.7 * @copyright 2019 Stephen Vickers * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class basicoutcomes extends \mod_lti\local\ltiservice\resource_base { /** * Class constructor. * * @param \mod_lti\local\ltiservice\service_base $service Service instance */ public function __construct($service) { parent::__construct($service); $this->id = 'Outcomes.LTI1'; $this->template = ''; $this->formats[] = 'application/vnd.ims.lti.v1.outcome+xml'; $this->methods[] = 'POST'; } /** * Get the resource fully qualified endpoint. * * @return string */ public function get_endpoint() { $url = new \moodle_url('/mod/lti/service.php'); return $url->out(false); } /** * Execute the request for this resource. * * @param \mod_lti\local\ltiservice\response $response Response object for this request. */ public function execute($response) { // Should never be called as the endpoint sends requests to the LTI 1 service endpoint. } }