LTI Integration Library 4.10.3
PHP class library for building LTI integrations
 
Loading...
Searching...
No Matches
MoodleApi.php
1<?php
2
3namespace ceLTIc\LTI\ApiHook\moodle;
4
8
18{
19
23 private static $DEFAULT_PER_PAGE = 50;
24
28 private $url = null;
29
33 private $token = null;
34
38 private $courseId = null;
39
43 private $sourceObject = null;
44
50 public function isConfigured()
51 {
52 $platform = $this->sourceObject->getPlatform();
53
54 return !empty($platform->getSetting('moodle.url')) && !empty($platform->getSetting('moodle.token'));
55 }
56
64 private function get($withGroups)
65 {
66 $platform = $this->sourceObject->getPlatform();
67 $this->url = $platform->getSetting('moodle.url');
68 $this->token = $platform->getSetting('moodle.token');
69 $perPage = $platform->getSetting('moodle.per_page', '');
70 if (!is_numeric($perPage)) {
71 $perPage = self::$DEFAULT_PER_PAGE;
72 } else {
73 $perPage = intval($perPage);
74 }
75 $prefix = $platform->getSetting('moodle.grouping_prefix');
76 if ($this->url && $this->token && $this->courseId) {
77 if ($withGroups) {
78 $this->setGroupings($prefix);
79 }
80 $users = $this->getUsers($perPage, $withGroups);
81 if ($users && $withGroups) {
82 $this->setGroups($users);
83 }
84 } else {
85 $users = false;
86 }
87
88 return $users;
89 }
90
98 private function setGroupings($prefix)
99 {
100 $ok = false;
101 $this->sourceObject->groupSets = array();
102 $this->sourceObject->groups = array();
103 $params = array(
104 'courseid' => $this->courseId
105 );
106 $courseGroupings = $this->callMoodleApi('core_group_get_course_groupings', $params);
107 if (is_array($courseGroupings)) {
108 $groupingIds = array_map(function($grouping) {
109 return $grouping->id;
110 }, $courseGroupings);
111 if (empty($groupingIds)) {
112 $ok = true;
113 } else {
114 $params = array(
115 'groupingids' => $groupingIds,
116 'returngroups' => 1
117 );
118 $groupings = $this->callMoodleApi('core_group_get_groupings', $params);
119 if (is_array($groupings)) {
120 $ok = true;
121 foreach ($groupings as $grouping) {
122 if (!empty($grouping->groups) && (empty($prefix) || (strpos($grouping->name, $prefix) === 0))) {
123 $groupingId = strval($grouping->id);
124 $this->sourceObject->groupSets[$groupingId] = array('title' => $grouping->name, 'groups' => array(),
125 'num_members' => 0, 'num_staff' => 0, 'num_learners' => 0);
126 foreach ($grouping->groups as $group) {
127 $groupId = strval($group->id);
128 $this->sourceObject->groupSets[$groupingId]['groups'][] = $groupId;
129 if (!isset($this->sourceObject->groups[$groupId])) {
130 $this->sourceObject->groups[$groupId] = array('title' => $group->name, 'set' => $groupingId);
131 } elseif (!is_array($this->sourceObject->groups[$groupId]['set'])) {
132 $this->sourceObject->groups[$groupId]['set'] = array($this->sourceObject->groups[$groupId]['set'], $groupingId);
133 } else {
134 $this->sourceObject->groups[$groupId]['set'][] = $groupingId;
135 }
136 }
137 }
138 }
139 }
140 }
141 }
142
143 return $ok;
144 }
145
154 private function getUsers($perPage, $withGroups)
155 {
156 $users = array();
157
158 $params = array(
159 'courseid' => $this->courseId,
160 'options' => array(
161 array(
162 'name' => 'onlyactive',
163 'value' => 1
164 ),
165 array(
166 'name' => 'userfields',
167 'value' => 'id'
168 ),
169 array(
170 'name' => 'withcapability',
171 'value' => 'mod/lti:manage'
172 )
173 )
174 );
175 $teachers = array();
176 $enrolments = $this->callMoodleApi('core_enrol_get_enrolled_users', $params);
177 if (is_array($enrolments)) {
178 foreach ($enrolments as $enrolment) {
179 $teachers[] = $enrolment->id;
180 }
181 }
182 $userFields = 'id, username, idnumber, firstname, lastname, fullname, email, roles';
183 if ($withGroups) {
184 $userFields .= ', groups';
185 }
186 $params = array(
187 'courseid' => $this->courseId,
188 'options' => array(
189 array(
190 'name' => 'onlyactive',
191 'value' => 1
192 ),
193 array(
194 'name' => 'userfields',
195 'value' => $userFields
196 )
197 )
198 );
199 if ($perPage > 0) {
200 array_push($params['options'],
201 array(
202 'name' => 'limitnumber',
203 'value' => $perPage
204 )
205 );
206 }
207 $n = 0;
208 do {
209 if ($perPage > 0) {
210 array_push($params['options'],
211 array(
212 'name' => 'limitfrom',
213 'value' => $n
214 )
215 );
216 }
217 $enrolments = $this->callMoodleApi('core_enrol_get_enrolled_users', $params);
218 if (is_array($enrolments)) {
219 foreach ($enrolments as $enrolment) {
220 $userId = strval($enrolment->id);
221 if (is_a($this->sourceObject, 'ceLTIc\LTI\ResourceLink')) {
222 $user = UserResult::fromResourceLink($this->sourceObject, $userId);
223 } else {
224 $user = new UserResult();
225 $user->ltiUserId = $userId;
226 }
227 $user->setEmail($enrolment->email, $this->sourceObject->getPlatform()->defaultEmail);
228 $user->setNames($enrolment->firstname, $enrolment->lastname, $enrolment->fullname);
229 $user->username = $enrolment->username;
230 if (!empty($enrolment->idnumber)) {
231 $user->sourcedId = $enrolment->idnumber;
232 } else {
233 $user->sourcedId = null;
234 }
235 if (!empty($enrolment->groups)) {
236 foreach ($enrolment->groups as $group) {
237 $groupId = strval($group->id);
238 if (array_key_exists($groupId, $this->sourceObject->groups)) {
239 $user->groups[] = $groupId;
240 }
241 }
242 }
243 // Add Instructor or Learner role - NB no check is made for the Administrator role
244 if (in_array($enrolment->id, $teachers)) {
245 $user->roles[] = 'urn:lti:role:ims/lis/Instructor';
246 } else {
247 $user->roles[] = 'urn:lti:role:ims/lis/Learner';
248 }
249 $users[$userId] = $user;
250 }
251 if ($perPage > 0) {
252 $n += count($enrolments);
253 array_pop($params['options']);
254 }
255 } else {
256 $users = false;
257 break;
258 }
259 } while (is_array($enrolments) && !empty($enrolments));
260
261 return $users;
262 }
263
269 private function setGroups($users)
270 {
271 foreach ($users as $user) {
272 $sets = array();
273 foreach ($user->groups as $group) {
274 if (array_key_exists($group, $this->sourceObject->groups) && !empty($this->sourceObject->groups[$group]['set'])) {
275 $setIds = $this->sourceObject->groups[$group]['set'];
276 if (!is_array($setIds)) {
277 $setIds = array($setIds);
278 }
279 foreach ($setIds as $setId) {
280 // Check that user is not a member of another group in the same grouping
281 if (in_array($setId, $sets)) {
282 // Remove groups but leave grouping as empty to acknowledge its existence in the platform
283 foreach ($this->sourceObject->groupSets[$setId]['groups'] as $groupId) {
284 if (!is_array($this->sourceObject->groups[$groupId]['set']) && ($this->sourceObject->groups[$groupId]['set'] === $setId)) {
285 unset($this->sourceObject->groups[$groupId]['set']);
286 } else if (is_array($this->sourceObject->groups[$groupId]['set']) && in_array($setId,
287 $this->sourceObject->groups[$groupId]['set'])) {
288 $pos = array_search($setId, $this->sourceObject->groups[$groupId]['set']);
289 unset($this->sourceObject->groups[$groupId]['set'][$pos]);
290 if (empty($this->sourceObject->groups[$groupId]['set'])) {
291 unset($this->sourceObject->groups[$groupId]['set']);
292 }
293 }
294 }
295 } elseif (array_key_exists($group, $this->sourceObject->groups)) {
296 $this->sourceObject->groupSets[$setId]['num_members']++;
297 if ($user->isStaff()) {
298 $this->sourceObject->groupSets[$setId]['num_staff']++;
299 }
300 if ($user->isLearner()) {
301 $this->sourceObject->groupSets[$setId]['num_learners']++;
302 }
303 $sets[] = $setId;
304 }
305 }
306 }
307 }
308 }
309 }
310
319 private function callMoodleApi($method, $params)
320 {
321 $json = null;
322 $serviceUrl = $this->url . '/webservice/rest/server.php';
323 $params = array_merge(array(
324 'wstoken' => $this->token,
325 'wsfunction' => $method,
326 'moodlewsrestformat' => 'json'
327 ), $params);
328 $http = new HttpMessage($serviceUrl, 'POST', $params);
329 $http->send();
330 if ($http->ok) {
331 $json = Util::jsonDecode($http->response);
332 $http->ok = !is_null($json) && is_array($json);
333 if (!$http->ok) {
334 Util::logError("Moodle web service returned an error: {$http->response}");
335 }
336 }
337
338 return $json;
339 }
340
341}
Class to handle Moodle web service requests.
Definition MoodleApi.php:18
isConfigured()
Check if the API hook has been configured.
Definition MoodleApi.php:50
Class to represent an HTTP message request.
Class to represent a platform user association with a resource link.
static fromResourceLink($resourceLink, $ltiUserId)
Class constructor from resource link.
Class to implement utility methods.
Definition Util.php:15
static logError($message, $showSource=true)
Log an error message.
Definition Util.php:248
static jsonDecode($str, $associative=false)
Decode a JSON string.
Definition Util.php:560