-
Notifications
You must be signed in to change notification settings - Fork 0
/
locallib.php
695 lines (600 loc) · 22.8 KB
/
locallib.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
<?php
// This file is a part of Kasetsart Moodle Kit - https://github.com/Pongkemon01/moodle-local_kuenrol
//
// Kasetsart Moodle Kit 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.
//
// Kasetsart Moodle Kit 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/>.
/**
* Enrollment refresh is use to synchronize student enrollment with registration office.
*
* @package local_kuenrol
* @author Akrapong Patchararungruang
* @copyright 2015 Kasetsart University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @changelog 17 June 2016 : Move all functions retrieving data from KU Regis
* into a class. Also, support for Sakonnakon is added.
*/
defined('MOODLE_INTERNAL') || die();
require_once("$CFG->libdir/accesslib.php");
require_once("$CFG->libdir/datalib.php");
require_once("$CFG->libdir/enrollib.php");
require_once("$CFG->libdir/grouplib.php");
require_once("$CFG->dirroot/group/lib.php");
require_once("$CFG->dirroot/user/lib.php");
require_once('kuregis.php');
/* Generate log entry */
function ku_log( $string )
{
file_put_contents("Kuenrol.log", date('l j F Y H:i:s') . " : " . $string . "\n", FILE_APPEND );
file_put_contents("/dev/stderr", date('l j F Y H:i:s') . " : " . $string . "\n", FILE_APPEND );
}
function debug_log( $string )
{
file_put_contents("Debug.log", date('l j F Y H:i:s') . " : " . $string . "\n", FILE_APPEND );
}
/*------------------------------------------------------------*/
function csv_to_array( $string )
{
$lines = explode(PHP_EOL, $string);
$array = array();
foreach ($lines as $line)
{
if( strlen( $line ) > 0 )
{
$array[] = str_getcsv($line);
}
}
return( $array );
}
/*------------------------------------------------------------*/
/**
* explode_tag : extract tag setting into an array
* @param string $sTag
* @return array $aTag
**/
function explode_tag( $sTag ) {
$aTag = array();
// Elimitate space in strTag
$sTrimTag = preg_replace('/\s+/', '', $sTag);
// Tag string should have size more than 2 (for key = value )
if( strlen( $sTrimTag ) <= 2 )
return $aTag;
// Explode each key=value pair
$aKeyVal = explode( ';', $sTrimTag );
// Parsing each key=value pair
foreach( $aKeyVal as $sKeyVal ) {
$aKeyValParts = explode( '=', $sKeyVal );
// Whether the tag string has the correct format
if( count( $aKeyValParts ) != 2 ) {
continue;
}
$sKey = $aKeyValParts[0];
$sVal = $aKeyValParts[1];
// Store the result
if( strlen( $sVal ) > 0 ) {
$aTag[$sKey] = explode( ',', $sVal );
} else {
$aTag[$sKey] = array();
}
}
return $aTag;
}
/*------------------------------------------------------------*/
/**
* implode_tag : compact tag array into a string
* @param array $aTag
* @return string $sTag
**/
function implode_tag( $aTag ) {
$sTag = "";
// No tag, return an empty string
if( count( $aTag ) == 0 )
return $sTag;
// Process each tag
foreach( $aTag as $sKey => $aValue ) {
// If the tag string already store some values then add ';'
if( strlen( $sTag ) > 0 ) {
$sTag = $sTag . ';';
}
// Process value list
$sVal = "";
foreach( $aValue as $sItem ) {
// Insert value delimiter if some values exist
if( strlen( $sVal ) > 0 ) {
$sVal = $sVal . ',';
}
$sVal = $sVal . $sItem;
}
$sTag = $sTag . $sKey . '=' . $sVal;
}
return $sTag;
}
/*------------------------------------------------------------*/
/**
* Checking if the provided user name is (likely) a student.
* - Students should not be able to export any grade book.
* @param integer $nUserId
* @return bool. (True if the user is likely a student. False otherwise.)
*/
function is_student( $nUserId ) {
global $COURSE;
$xCourseContext = context_course::instance( $COURSE->id );
return( !has_capability( 'moodle/grade:export', $xCourseContext, $nUserId ) );
}
/*------------------------------------------------------------*/
/**
* Returns a Nontri account of the student with the providing ID
*
* @param string $sStudentID - A valid student ID for KU in the form of
* YYCLMMRRRR where each character should be a digit.
* @return string|bool - A nontri account of the parameter is valid. false otherwise.
**/
function ku_gen_username( $sStudentID ) {
/* The 4th digit from the left of the student ID can be used to identify
student level. Letter '0' - '3' means undergraduate, letter '4' - '6' means
master level, and letter '7' - '9' means doctoral level. */
// Check student ID format
if( strlen( $sStudentID ) != 10 ) {
return false;
}
if( !ctype_digit( $sStudentID ) ) {
return false;
}
$nKeyDigit = intval( $sStudentID[3] ); // Get the key digit
if( $nKeyDigit <= 3 ) {
return( 'b' . $sStudentID );
} else {
return( 'g' . $sStudentID );
}
}
/*------------------------------------------------------------*/
/**
* Returns a Google email of the provided Nontri account
*
* @param string $sNontriAcc - A valid Nontri account.
* @return string|bool - The coresponding Google email if found, Nontri email otherwise.
**/
function ku_get_google( $sNontriAcc ) {
/* The Google mail of a Nontri can be retrieved from
https://hr.ku.ac.th/cpcsnss/itsupport/json_account.php
which accepts a query as JSON format and returns also
in JSON. The query JSON contains only 1 field as
"account" : "Nontri Acc"
the response JSON has relevant field as:
- "google-mail" - @ku.th
- "office365-mail" - @live.ku.th
- "ku_mail" - Nontri account
*/
$sJsonServer = 'https://hr.ku.ac.th/cpcsnss/itsupport/json_account.php';
$sDefaultAnswer = $sNontriAcc . '@ku.ac.th';
$sQueryString = '{"account" : "' . $sNontriAcc . '"}';
/* Get the information through CURL library */
/* Initialize curl */
$ch = curl_init();
/* Set URL */
curl_setopt( $ch, CURLOPT_URL, $sJsonServer );
curl_setopt( $ch, CURLOPT_REFERER, 'https://edufarm.ku.ac.th' );
/* Disable verifying server SSL certificate */
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
/* Get all html result into a variable for parsing cookies */
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
/* Set query */
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $sQueryString );
/* Execute URL request */
$result = curl_exec( $ch );
/* Close curl */
curl_close( $ch );
/* If http request fail, return empty group array */
if( false === $result ) {
return( $sDefaultAnswer );
}
/* Parsing the result. We avoid JSON library as we are not sure
wheter the system has JSON installed.
*/
$sJson = trim( $result, ' \n\r\t\v\0{}' ); // Trim all spaces and brackets.
$sJsonRecords = explode( ',', $sJson ); // Separate each records
/* Search for the "google-mail" field */
$sFinalAnswer = $sDefaultAnswer;
foreach( $sJsonRecords as $sJsonLine ) {
$sJsonFields = explode( ':' , $sJsonLine );
if( trim( $sJsonFields[0] ) == '"google_mail"' ) {
$sFinalAnswer = trim( $sJsonFields[1], ' \n\r\t\v\0"' ); // Trim all spaces and quotes.
}
}
return( $sFinalAnswer );
}
/*------------------------------------------------------------*/
/**
* This function translates CSV data into an array of objects representing
* students who currently enrolled to the class. Its operation is very
* hard coded according to KU Regis format.
* @param string $sCsvStream - The whole CSV file from KU Regis in a string
* @param string $sSecName - Name of the current section in process.
* @return array of Objects index by student ID
**/
function csv_to_student_list( $sCsvStream, $sSecName )
{
$aasStdRawList = csv_to_array( $sCsvStream );
$axStdList = array();
foreach( $aasStdRawList as $asStdRawData ) {
/* KU Regis format
0 => index number
1 => course number
2 => student id
3 => student fullname (in Thai)
4 => student major id
5 => registration type ("C" or "A" for Credit or Audit)
6 => student status ("W" = withdrew, "" = enrolled)
*/
if( strlen( $asStdRawData[6] ) == 0 ) {
$xStudent = new stdClass();
$xStudent->nId = false; // Dummy data for future
$xStudent->sStudentID = $asStdRawData[2]; // Get student id
$xStudent->sUserName = ku_gen_username( $asStdRawData[2] );
$nSpacePos = mb_strpos( $asStdRawData[3], ' ', 0, 'UTF-8');
$xStudent->sFirstName = mb_substr( $asStdRawData[3], 0, $nSpacePos, 'UTF-8' ); // Store first name
$xStudent->sLastName = mb_substr( $asStdRawData[3], $nSpacePos + 1, null, 'UTF-8' ); // Store last name
$xStudent->asGroupList = array();
$xStudent->asGroupList[] = $sSecName;
$axStdList[$xStudent->sStudentID] = $xStudent;
}
}
return( $axStdList );
}
/*------------------------------------------------------------*/
/**
* Create an account for a student with the given information.
* The authentication method is set to LDAP by default
*
* @param Object $xStrudentInfo
* @return false|int id of newly created user. false if error
**/
function create_moodle_user( $xStudentInfo ) {
global $CFG;
// If the username is invalid
if( false === $xStudentInfo->sUserName ) {
return false;
}
ku_log( "Create user : ". $xStudentInfo->sUserName );
$xUser = new stdClass();
// Setting fields from $xStudentInfo
$xUser->username = $xStudentInfo->sUserName;
$xUser->firstname = $xStudentInfo->sFirstName;
$xUser->lastname = $xStudentInfo->sLastName;
$xUser->email = ku_get_google( $xStudentInfo->sUserName );
$xUser->idnumber = $xStudentInfo->sStudentID;
// Setting remaining fields with default values
$xUser->confirmed = 1;
$xUser->mnethostid = $CFG->mnet_localhost_id;;
$xUser->timemodified = time();
$xUser->timecreated = time();
$xUser->suspended = 0;
$xUser->auth = 'oauth2'; // ldap or oauth2
$xUser->lang = '';
$xUser->password = AUTH_PASSWORD_NOT_CACHED;
return( user_create_user( $xUser, false ) );
}
/*------------------------------------------------------------*/
/**
* Returns a subset of users
*
* @global object
* @uses DEBUG_DEVELOPER
* @uses SQL_PARAMS_NAMED
* @param bool $get If false then only a count of the records is returned
* @param string $search A simple string to search for
* @param string $fields A comma separated list of fields to be returned from the chosen table.
* @param string $sort A SQL snippet for the sorting criteria to use
* @return array|int|bool {@link $USER} records unless get is false in which case the integer count of the records found is returned.
* False is returned if an error is encountered.
*/
function ku_get_users($get=true, $search='', $fields='*', $sort='username ASC' ) {
global $DB, $CFG;
$select = " id <> :guestid AND deleted = 0";
$params = array('guestid'=>$CFG->siteguest);
if (!empty($search)){
$search = trim($search);
$select .= " AND (".$DB->sql_like('idnumber', ':search1', false)." OR ".$DB->sql_like('email', ':search2', false)." OR ".$DB->sql_like('username', ':search3', false).")";
$params['search1'] = "%$search%";
$params['search2'] = "%$search%";
$params['search3'] = "%$search";
}
if ($get) {
return $DB->get_records_select('user', $select, $params, $sort, $fields, '', '2');
} else {
return $DB->count_records_select('user', $select, $params);
}
}
/*------------------------------------------------------------*/
/**
* Fill moodle userid field for each student.
* If any username within the list does not exist, that name is skipped or created.
* @param array $axStudents
* @param boolean $bAutoCreate
* @return nothing
*/
function find_students_userid( &$axStudents, $bAutoCreate = false) {
foreach( $axStudents as $sStudentID=>&$xStudentInfo ) {
/* get_users searches the database for:
- idnumber LIKE %$sUserName%
- email LIKE %$sUserName%
- useranme like %$sUserName
Therefore, the pattern covers all possible Nontri accounts with only
student ID as the key. Therefore, $sUserName canbe a full Nontri account
or a student ID. */
$xUserRecords = ku_get_users( true, $sStudentID, 'id, username' );
// If username does not exists then a new user record should be created!!!
if( $xUserRecords === false ) {
if( $bAutoCreate ) {
$xStudentInfo->nId = create_moodle_user( $xStudentInfo );
}
} else {
$xUserRecordData = array_values( $xUserRecords );
if( count( $xUserRecordData ) < 1 ) {
if( $bAutoCreate ) {
$xStudentInfo->nId = create_moodle_user( $xStudentInfo );
}
} else {
$xStudentInfo->nId = $xUserRecordData[0]->id;
$xStudentInfo->sUserName = $xUserRecordData[0]->username;
}
}
}
}
/*------------------------------------------------------------*/
/**
* Retrieve the names of unselected groups in the course. All students belong to
* these groups will be untouched.
* @param array $aGroups in the form of Lect:Lab without 'S' prefix (Becareful)
* @param $bIncludeOld to include students from old course plan.
* @return array of id of the groups that are not in the parameter.
*/
function get_unlist_groups( $aGroups, $sCampus, $bIncludeOld ) {
global $COURSE;
// Generate group name with 'S' prefix
$aListedGroups = array();
foreach( $aGroups as $sGroupName ) {
$aListedGroups[] = 'S' . $sCampus . $sGroupName;
if( $bIncludeOld ) {
$aListedGroups[] = 'S' . $sCampus . '_o' . $sGroupName;
}
}
$xCourseContext = context_course::instance( $COURSE->id );
// Fristly, we get all groups in the course and mark them as unlisted.
// Then, we substract two arrays
// Get all groups in the course
$aGroupObjsInCourse = groups_get_all_groups( $COURSE->id );
// Generate array of group ids
$aUnlistedGroupIDs = array();
foreach( $aGroupObjsInCourse as $xGroupObj ) {
if( ! in_array( $xGroupObj->name, $aListedGroups ) ) {
$aUnlistedGroupIDs[] = $xGroupObj->id;
}
}
// return subtracted arrays
return( $aUnlistedGroupIDs );
}
/*------------------------------------------------------------*/
/**
* Perform enrollment action (enrol new users and suspend/withdraw missing users).
* @param array $axUsers - The array of student information indexed by student id.
* @param array $aUnlistedGroupIDs - The array of group ids which are excluded from processing.
* @param class $xManuallEnrolInstance - The instance of 'manual' enrollment plugin in class-context.
* @param class $xSelflEnrollInstance - The instance of 'self' enrollment plugin in class-context.
* @param integer $nRoleId
* @param string $sMissingAct - action for users missing from the imported data.
* @return none.
*/
function enroll_action( $axUsers, $aUnlistedGroupIDs, $xManualEnrollInstance, $xSelfEnrollInstance, $nRoleId, $sMissingAct ) {
global $COURSE;
ku_log( "Enrollment action");
$xCourseContext = context_course::instance( $COURSE->id );
$xSystemManualEnrol = enrol_get_plugin( 'manual' );
$xSystemSelfEnrol = enrol_get_plugin( 'self' );
// Enroll new users
if ( ( $nRoleId > 0 ) && ( $xManualEnrollInstance != null ) ) {
foreach( $axUsers as $sStudentID=>$xStudentInfo ) {
if( false === $xStudentInfo->nId ) {
continue; // Skip non existing user
}
if( !is_enrolled( $xCourseContext, $xStudentInfo->nId ) ) {
ku_log( "Enrol " . $xStudentInfo->sUserName );
$xSystemManualEnrol->enrol_user( $xManualEnrollInstance, $xStudentInfo->nId, $nRoleId, time() );
}
}
}
// Withdraw/Suspend unlisted users
if( $sMissingAct != 'nothing' ) {
$xEnrolUsers = get_enrolled_users( $xCourseContext, '', 0, 'u.id, u.username' );
// Build userid of the members of unlisted group
$anExcludedUserID = array();
foreach( $aUnlistedGroupIDs as $nUnlistedID ) {
$axGroupMembers = groups_get_members( $nUnlistedID, 'u.id, u.username' );
foreach( $axGroupMembers as $xGroupMember ) {
if( !in_array( $xGroupMember->id, $anExcludedUserID ) ) {
$anExcludedUserID[] = $xGroupMember->id;
}
}
}
foreach( $xEnrolUsers as $xEnrolPerson ) {
// If the interesting student is not a student. Then skip
if( ! is_student( $xEnrolPerson->id ) ) {
continue;
}
// If the interesting student is member of an unselected group. Then skip.
if( in_array( $xEnrolPerson->id, $anExcludedUserID ) ) {
continue;
}
// Process suspension or withdrawing only to students.
// $axUsers is indexed by student id
if( !array_key_exists( substr( $xEnrolPerson->username, 1 ), $axUsers ) ) {
if( $sMissingAct == 'suspend' ) {
ku_log( "Suspend user " . $xEnrolPerson->username );
if( $xManualEnrollInstance != null ) {
$xSystemManualEnrol->update_user_enrol( $xManualEnrollInstance, $xEnrolPerson->id, 1 );
}
if( $xSelfEnrollInstance != null ) {
$xSystemSelfEnrol->update_user_enrol( $xSelfEnrollInstance, $xEnrolPerson->id, 1 );
}
} else {
ku_log( "Withdraw user " . $xEnrolPerson->username );
if( $xManualEnrollInstance != null ) {
$xSystemManualEnrol->unenrol_user( $xManualEnrollInstance, $xEnrolPerson->id );
}
if( $xSelfEnrollInstance != null ) {
$xSystemSelfEnrol->unenrol_user( $xSelfEnrollInstance, $xEnrolPerson->id );
}
}
}
}
}
}
/*------------------------------------------------------------*/
/**
* Perform group-change action.
* @param array $axUsers - The array of student information indexed by student id.
* @param array $aUnlistedGroupIDs - The array of group ids which are excluded from processing.
* @param integer $autogroupcreate - Whether new group should be created if required?
* @param integer $autogroupwithdraw - Whether users should be withdrawn from the group not specified in imported data?
* @return none.
*/
function group_action( $axUsers, $aUnlistedGroupIDs, $bAutoGroupCreate, $bAutoGroupWithdraw ) {
global $COURSE;
ku_log( "Group action" );
$xCourseContext = context_course::instance( $COURSE->id );
foreach( $axUsers as $sStudentID=>$xStudentInfo ) {
if( false === $xStudentInfo->nId ) {
// Skip missing user. All users must already enrolled here.
continue;
}
if( !is_enrolled( $xCourseContext, $xStudentInfo->nId ) ) {
// skip unenrolled users as enrol_action should finish all enrollment
continue;
}
// Add to group
foreach( $xStudentInfo->asGroupList as $sGroupName ) {
// Prepare course group
$nGid = groups_get_group_by_name( $COURSE->id, $sGroupName );
if( false === $nGid ) {
// If group not exists, should we create it?
if ( $bAutoGroupCreate ) {
// Create a group
ku_log( "Create new group with name " . $sGroupName );
$newgroupdata = new stdClass();
$newgroupdata->name = $sGroupName;
$newgroupdata->courseid = $COURSE->id;
$newgroupdata->description = '';
$nGid = groups_create_group($newgroupdata);
if (!$nGid) {
// Fail to create group
continue; // Skip this group entry.
}
} else {
// We don't have the specified group and teacher does not
// want to create it. We cannot do anything now. Just skip
// this group entry.
continue;
}
}
// Add user to group
if ( !groups_is_member( $nGid, $xStudentInfo->nId ) ) {
ku_log( "Invoke user " . $xStudentInfo->sUserName . " into " . $sGroupName );
groups_add_member( $nGid, $xStudentInfo->nId );
}
}
// Withdraw from unlisted groups if required
if( $bAutoGroupWithdraw && is_student( $xStudentInfo->nId ) ) {
// Get current groups that the user already in
$axEnrolledGroups = groups_get_all_groups( $COURSE->id, $xStudentInfo->nId );
// Iterate
foreach( $axEnrolledGroups as $xEnrolledGroup ) {
if( ( !in_array( $xEnrolledGroup->id, $aUnlistedGroupIDs) ) &&
( !in_array( $xEnrolledGroup->name, $xStudentInfo->asGroupList ) ) ) {
$bStatus = groups_remove_member( $xEnrolledGroup->id, $xStudentInfo->nId );
if( $bStatus ) {
ku_log( "Revoke user " . $xStudentInfo->sUserName . " from " . $xEnrolledGroup->name . " (Success)" );
} else {
ku_log( "Revoke user " . $xStudentInfo->sUserName . " from " . $xEnrolledGroup->name . " (FAIL!!)" );
}
}
}
}
}
}
/*------------------------------------------------------------*/
/**
* Perform retrieving all students of a specific course id.
* @param object $xKURegis pointed to active Regis platform
* @param string $courseid
* @param int $year - last 2 digits of B.E.
* @param int $semester - 0 = Summer, 1 = First, 2 = Second, 3 = Third
* @param array $aGroups for each group to include
* @param string $sCampus - Campus suffix (B = Bangkhen, etc...)
* @param array $axStudents to append the data to.
* @return array of the information of all student within the course.
*/
function get_students( $xKURegis, $sCourseID, $sYear, $sSem, $aGroups, $sCampus, $axStudents ) {
// Get section list in the course
$xKURegis->set_active_course( $sCourseID, $sYear, $sSem );
$aRegisSections = $xKURegis->get_sec_list();
//file_put_contents( '/tmp/moodletxt', var_export( $aRegisSections, true ) . "\n" );
ku_log( "=== Start on " . $COURSE->shortname . " ===" );
// Build data for enrollment and group-switch action. Both acctions can accept
// either username (Nontri account) or idnumer as the key.
//$aStdIDList = array();
//$aStdIDGroupList = array();
foreach( $aGroups as $sGroupName ) {
// Split group name into lecture and lab section id.
$aGroupPair = explode( ':', $sGroupName );
if( isset( $aGroupPair[0] ) ) {
$sLectSec = $aGroupPair[0];
} else {
$sLectSec = 0;
}
if( isset( $aGroupPair[1] ) ) {
$sLabSec = $aGroupPair[1];
} else {
$sLabSec = 0;
}
// Retrive data from KU Regis in CSV format
$xCsvStdList = $xKURegis->get_students( $sLectSec, $sLabSec );
// Extract KU Regis output of a sections to a list of student id
// Check whether this sCourseID indicates the course in old course plan
// and set the group suffix according to its value
if( $sCourseID{0} == '9' ) {
$axStudentInSec = csv_to_student_list( $xCsvStdList, 'S' . $sCampus . '_o' . $sGroupName );
} else {
$axStudentInSec = csv_to_student_list( $xCsvStdList, 'S' . $sCampus . $sGroupName );
}
// Merge student within a section into the whole course student list.
foreach( $axStudentInSec as $sStudentID=>$xStudentData ) {
if( array_key_exists( $sStudentID, $axStudents ) ) {
// The student already exist then add his/her section into the list
$axStudents[ $sStudentID ]->asGroupList[] = array_merge(
$axStudents[ $sStudentID ]->asGroupList, $xStudentData->asGroupList );
} else {
// The student does not exist yet so we add the new record
// A new student is always create by "new stdClass()" so we don't
// need to worry about deep copy here
$axStudents[ $sStudentID ] = $xStudentData;
}
}
}
return( $axStudents );
}
/*------------------------------------------------------------*/
//$tag = 'id=01204224;year=57;sem=2;sec=0:11,0:12';
//$expTag = explode_tag( $tag );
//$impTag = implode_tag( $expTag );
//var_dump( $impTag );