fbbec969d0e84876b8bcc143ee523b7899e1e3fd
[moodle.git] / mod / lti / service / memberships / classes / local / service / memberships.php
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/>.
17 /**
18  * This file contains a class definition for the Memberships service
19  *
20  * @package    ltiservice_memberships
21  * @copyright  2015 Vital Source Technologies http://vitalsource.com
22  * @author     Stephen Vickers
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
27 namespace ltiservice_memberships\local\service;
29 defined('MOODLE_INTERNAL') || die();
31 /**
32  * A service implementing Memberships.
33  *
34  * @package    ltiservice_memberships
35  * @since      Moodle 3.0
36  * @copyright  2015 Vital Source Technologies http://vitalsource.com
37  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38  */
39 class memberships extends \mod_lti\local\ltiservice\service_base {
41     /** Default prefix for context-level roles */
42     const CONTEXT_ROLE_PREFIX = 'http://purl.imsglobal.org/vocab/lis/v2/membership#';
43     /** Context-level role for Instructor */
44     const CONTEXT_ROLE_INSTRUCTOR = 'http://purl.imsglobal.org/vocab/lis/v2/membership#Instructor';
45     /** Context-level role for Learner */
46     const CONTEXT_ROLE_LEARNER = 'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner';
47     /** Capability used to identify Instructors */
48     const INSTRUCTOR_CAPABILITY = 'moodle/course:manageactivities';
50     /**
51      * Class constructor.
52      */
53     public function __construct() {
55         parent::__construct();
56         $this->id = 'memberships';
57         $this->name = get_string('servicename', 'ltiservice_memberships');
59     }
61     /**
62      * Get the resources for this service.
63      *
64      * @return array
65      */
66     public function get_resources() {
68         if (empty($this->resources)) {
69             $this->resources = array();
70             $this->resources[] = new \ltiservice_memberships\local\resource\contextmemberships($this);
71             $this->resources[] = new \ltiservice_memberships\local\resource\linkmemberships($this);
72         }
74         return $this->resources;
76     }
78     /**
79      * Get the JSON for members.
80      *
81      * @param \mod_lti\local\ltiservice\resource_base $resource       Resource handling the request
82      * @param \context_course   $context    Course context
83      * @param string            $id         Course ID
84      * @param object            $tool       Tool instance object
85      * @param string            $role       User role requested (empty if none)
86      * @param int               $limitfrom  Position of first record to be returned
87      * @param int               $limitnum   Maximum number of records to be returned
88      * @param object            $lti        LTI instance record
89      * @param info_module       $info       Conditional availability information for LTI instance (null if context-level request)
90      *
91      * @return array
92      */
93     public static function get_users_json($resource, $context, $id, $tool, $role, $limitfrom, $limitnum, $lti, $info) {
95         $withcapability = '';
96         $exclude = array();
97         if (!empty($role)) {
98             if ((strpos($role, 'http://') !== 0) && (strpos($role, 'https://') !== 0)) {
99                 $role = self::CONTEXT_ROLE_PREFIX . $role;
100             }
101             if ($role === self::CONTEXT_ROLE_INSTRUCTOR) {
102                 $withcapability = self::INSTRUCTOR_CAPABILITY;
103             } else if ($role === self::CONTEXT_ROLE_LEARNER) {
104                 $exclude = array_keys(get_enrolled_users($context, self::INSTRUCTOR_CAPABILITY, 0, 'u.id',
105                                                          null, null, null, true));
106             }
107         }
108         $users = get_enrolled_users($context, $withcapability, 0, 'u.*', null, $limitfrom, $limitnum, true);
109         if (count($users) < $limitnum) {
110             $limitfrom = 0;
111             $limitnum = 0;
112         }
113         $json = self::users_to_json($resource, $users, $id, $tool, $exclude, $limitfrom, $limitnum, $lti, $info);
115         return $json;
117     }
119     /**
120      * Get the JSON representation of the users.
121      *
122      * Note that when a limit is set and the exclude array is not empty, then the number of memberships
123      * returned may be less than the limit.
124      *
125      * @param \mod_lti\local\ltiservice\resource_base $resource       Resource handling the request
126      * @param array  $users               Array of user records
127      * @param string $id                  Course ID
128      * @param object $tool                Tool instance object
129      * @param array  $exclude             Array of user records to be excluded from the response
130      * @param int    $limitfrom           Position of first record to be returned
131      * @param int    $limitnum            Maximum number of records to be returned
132      * @param object $lti                 LTI instance record
133      * @param \core_availability\info_module  $info     Conditional availability information for LTI instance
134      *
135      * @return string
136      */
137     private static function users_to_json($resource, $users, $id, $tool, $exclude, $limitfrom, $limitnum,
138                                          $lti, $info) {
140         $nextpage = 'null';
141         if ($limitnum > 0) {
142             $limitfrom += $limitnum;
143             $nextpage = "\"{$resource->get_endpoint()}?limit={$limitnum}&amp;from={$limitfrom}\"";
144         }
145         $json = <<< EOD
147   "@context" : "http://purl.imsglobal.org/ctx/lis/v2/MembershipContainer",
148   "@type" : "Page",
149   "@id" : "{$resource->get_endpoint()}",
150   "nextPage" : {$nextpage},
151   "pageOf" : {
152     "@type" : "LISMembershipContainer",
153     "membershipSubject" : {
154       "@type" : "Context",
155       "contextId" : "{$id}",
156       "membership" : [
158 EOD;
159         $enabledcapabilities = lti_get_enabled_capabilities($tool);
160         $sep = '        ';
161         foreach ($users as $user) {
162             $include = !in_array($user->id, $exclude);
163             if ($include && !empty($info)) {
164                 $include = $info->is_user_visible($info->get_course_module(), $user->id);
165             }
166             if ($include) {
167                 $member = new \stdClass();
168                 if (in_array('User.id', $enabledcapabilities)) {
169                     $member->userId = $user->id;
170                 }
171                 if (in_array('Person.sourcedId', $enabledcapabilities)) {
172                     $member->sourcedId = format_string($user->idnumber);
173                 }
174                 if (in_array('Person.name.full', $enabledcapabilities)) {
175                     $member->name = format_string("{$user->firstname} {$user->lastname}");
176                 }
177                 if (in_array('Person.name.given', $enabledcapabilities)) {
178                     $member->givenName = format_string($user->firstname);
179                 }
180                 if (in_array('Person.name.family', $enabledcapabilities)) {
181                     $member->familyName = format_string($user->lastname);
182                 }
183                 if (in_array('Person.email.primary', $enabledcapabilities)) {
184                     $member->email = format_string($user->email);
185                 }
186                 if (in_array('Result.sourcedId', $enabledcapabilities) && !empty($lti) && !empty($lti->servicesalt)) {
187                     $member->resultSourcedId = json_encode(lti_build_sourcedid($lti->id, $user->id, $lti->servicesalt,
188                                                            $lti->typeid));
189                 }
190                 $roles = explode(',', lti_get_ims_role($user->id, null, $id, true));
192                 $membership = new \stdClass();
193                 $membership->status = 'Active';
194                 $membership->member = $member;
195                 $membership->role = $roles;
197                 $json .= $sep . json_encode($membership);
198                 $sep = ",\n        ";
199             }
201         }
203         $json .= <<< EOD
205       ]
206     }
207   }
209 EOD;
211         return $json;
213     }