PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/sisdb/sisdb.php

https://github.com/scyrma/moodle-cegep
PHP | 698 lines | 522 code | 115 blank | 61 comment | 167 complexity | 4dfcfffca27ef575d723238ce7f1cefd MD5 | raw file
  1. <?php
  2. // as seen in /auth/ldap/auth_ldap_sync_users.php
  3. require_once(dirname(dirname(dirname(dirname(__FILE__)))).'/config.php');
  4. require_once($CFG->dirroot .'/blocks/cegep/lib.php');
  5. global $CFG, $USER;
  6. // Get parameters
  7. $op = optional_param('op', null, PARAM_ACTION);
  8. $start_term = optional_param('start_term', null, PARAM_INT);
  9. $keep_terms = optional_param('keep_terms', null, PARAM_INT);
  10. set_time_limit(600);
  11. // Check access permissions
  12. if (!empty($CFG->block_cegep_cron_password) && $password == $CFG->block_cegep_cron_password) {
  13. $start_term = cegep_local_current_term();
  14. $in_cron = true;
  15. } else {
  16. require_login();
  17. if (!is_siteadmin($USER->id)) {
  18. print_error("Désolé, cette page n'est accessible qu'aux administrateurs du système.");
  19. }
  20. $strtitle = 'SIS DB maintenance';
  21. print_header($strtitle,$strtitle,build_navigation(array(array('name'=>get_string('admincegep','block_cegep'),'link'=>'','type'=>'misc'),array('name'=>get_string('sisdb_maintenance','block_cegep'),'link'=>'','type'=>'misc'))));
  22. }
  23. // Verify if external database enrolment is enabled
  24. if (!in_array('database',explode(',',$CFG->enrol_plugins_enabled))) {
  25. print_error('errorenroldbnotavailable','block_cegep');
  26. }
  27. // Prepare external enrolment database connection
  28. if ($enroldb = enroldb_connect()) {
  29. $enroldb->Execute("SET NAMES 'utf8'");
  30. }
  31. else {
  32. error_log('[ENROL_DB] Could not make a connection');
  33. print_error('dbconnectionfailed','error');
  34. }
  35. // Prepare external SIS database connection
  36. if ($sisdb = sisdb_connect()) {
  37. $sisdb->Execute("SET NAMES 'utf8'");
  38. }
  39. else {
  40. error_log('[SIS_DB] Could not make a connection');
  41. print_error('dbconnectionfailed','error');
  42. }
  43. // Prepare external SIS source database connection
  44. if ($sisdbsource = sisdbsource_connect()) {
  45. //$sisdbsource->Execute("SET NAMES 'utf8'");
  46. }
  47. else {
  48. error_log('[SIS_DB_SOURCE] Could not make a connection');
  49. print_error('dbconnectionfailed','error');
  50. }
  51. // Main switch
  52. switch ($op) {
  53. case 'prune' :
  54. (empty($keep_terms)) ? (cegep_sisdb_prune_form()) : (cegep_sisdb_prune($keep_terms));
  55. break;
  56. case 'sync' :
  57. (empty($start_term)) ? (cegep_sisdb_sync_form()) : (cegep_sisdb_sync($start_term));
  58. break;
  59. default :
  60. cegep_sisdb_sync_form();
  61. break;
  62. }
  63. function cegep_sisdb_sync_form() {
  64. $currenttab = 'sync';
  65. require('sisdb_tabs.php');
  66. print_box('Please input the term at which you would like to start the synchronization.');
  67. $form = '<center><form enctype="multipart/form-data" action="sisdb.php" method="post">';
  68. $form .= 'Term (eg. '. cegep_local_current_term() .'): <input name="start_term" type="text" size="5" maxlength="5" />';
  69. $form .= '<input type="hidden" name="op" value="sync" />';
  70. $form .= '<br /><br /><input type="submit" value="Start" /></form></center>';
  71. print_box($form);
  72. print_footer();
  73. }
  74. function cegep_sisdb_sync($start_term) {
  75. global $CFG, $enroldb, $sisdb, $sisdbsource;
  76. // Keep track of time
  77. $start_time = (float) array_sum(explode(' ',microtime()));
  78. $timestamp = time();
  79. $mysqltimestamp = date('Y-m-d H:i:s', $timestamp);
  80. // Set up SQL variables for triggers
  81. if ($CFG->sisdb_logging) {
  82. $sisdb->Execute('SET @LOGGING = 1');
  83. $sisdb->Execute("SET @TIMESTAMP = '$mysqltimestamp'");
  84. } else {
  85. $sisdb->Execute('SET @LOGGING = 0');
  86. }
  87. // Get data from external SIS database (ie, Clara)
  88. $select = cegep_local_sisdbsource_select_students($start_term);
  89. $sisdbsource_rs = $sisdbsource->Execute($select);
  90. // Don't proceed any further if no data is returned
  91. if (!$sisdbsource_rs || $sisdbsource_rs->EOF || $sisdbsource_rs->RowCount() == 0) {
  92. die("Database query returned no results!");
  93. }
  94. // Initialize variables
  95. // Keep track of processed objects
  96. $terms = array();
  97. $students = array();
  98. $programs = array();
  99. $courses = array();
  100. $coursegroups = array();
  101. // These arrays are used for comparison (determine additions and removals)
  102. $student_enrol_localdb = array(); // Student enrolments in moodle-sis
  103. $student_enrol_remotedb = array(); // Student enrolments in sisdbsource (ex. Clara)
  104. $teacher_enrol_localdb = array(); // Teacher enrolments in moodle-sis
  105. $teacher_enrol_remotedb = array(); // Teacher enrolments in sisdbsource (ex. Clara)
  106. // Counters for report
  107. $count = array();
  108. $count['records_skipped'] = 0;
  109. $count['students_added'] = 0;
  110. $count['students_updated'] = 0;
  111. $count['courses_added'] = 0;
  112. $count['courses_updated'] = 0;
  113. $count['programs_added'] = 0;
  114. $count['programs_updated'] = 0;
  115. $count['coursegroups_added'] = 0;
  116. $count['student_enrolments_added'] = 0;
  117. $count['student_enrolments_removed'] = 0;
  118. $count['student_program_enrolments_added'] = 0;
  119. $count['student_program_enrolments_removed'] = 0;
  120. $count['teacher_enrolments_added'] = 0;
  121. $count['teacher_enrolments_removed'] = 0;
  122. $student_role = get_record('role','shortname',$CFG->block_cegep_studentrole);
  123. while ($sisdbsource_rs && !$sisdbsource_rs->EOF) {
  124. $term = array();
  125. $term = implode(cegep_local_sisdbsource_decode('courseterm',$sisdbsource_rs->fields['CourseTerm']));
  126. if (!in_array($term,$terms)) {
  127. $terms[] = $term;
  128. }
  129. $student = cegep_local_sisdbsource_decode('studentnumber',$sisdbsource_rs->fields['StudentNumber']);
  130. $course = cegep_local_sisdbsource_decode('coursenumber',$sisdbsource_rs->fields['CourseNumber']);
  131. $course_title = cegep_local_sisdbsource_decode('coursetitle',$sisdbsource_rs->fields['CourseTitle']);
  132. $course_unit = cegep_local_sisdbsource_decode('courseunit',$sisdbsource_rs->fields['CourseUnit']);
  133. $coursegroup = cegep_local_sisdbsource_decode('coursegroup',$sisdbsource_rs->fields['CourseGroup']);
  134. $student_firstname = cegep_local_sisdbsource_decode('studentfirstname',$sisdbsource_rs->fields['StudentFirstName']);
  135. $student_lastname = cegep_local_sisdbsource_decode('studentlastname',$sisdbsource_rs->fields['StudentLastName']);
  136. $program = cegep_local_sisdbsource_decode('studentprogram',$sisdbsource_rs->fields['StudentProgram']);
  137. $programyear = cegep_local_sisdbsource_decode('studentprogramyear',$sisdbsource_rs->fields['StudentProgramYear']);
  138. $programtitle = cegep_local_sisdbsource_decode('studentprogramname',$sisdbsource_rs->fields['StudentProgramName']);
  139. $coursegroup_id = '';
  140. // We ignore enrolments that don't have a coursegroup (section) number
  141. if (empty($sisdbsource_rs->fields['CourseGroup'])) {
  142. $count['records_skipped']++;
  143. $sisdbsource_rs->moveNext();
  144. continue;
  145. }
  146. // Update student data
  147. if (!in_array($student, $students)) {
  148. $select = "SELECT * FROM `$CFG->sisdb_name`.`student` WHERE `username` = '$student'";
  149. $result = $sisdb->Execute($select);
  150. if ($result && $result->RecordCount() == 0) {
  151. $insert = "INSERT INTO `$CFG->sisdb_name`.`student` (`username` , `lastname`, `firstname`, `program_id`, `program_year`) VALUES ('$student', \"$student_lastname\", \"$student_firstname\", \"$program\", '$programyear'); ";
  152. $result = $sisdb->Execute($insert);
  153. if (!$result) {
  154. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $insert);
  155. if (!$in_cron) echo "Sync error : student process";
  156. break;
  157. } else { $count['students_added']++; }
  158. }
  159. elseif ($result && ($result->fields['lastname'] != $student_lastname || $result->fields['firstname'] != $student_firstname || $result->fields['program_id'] != $program || $result->fields['program_year'] != $programyear)) {
  160. $update = "UPDATE `$CFG->sisdb_name`.`student` SET `lastname` = \"$student_lastname\", `firstname` = \"$student_firstname\", `program_id` = \"$program\", `program_year` = \"$programyear\" WHERE `username` = '$student'; ";
  161. $result = $sisdb->Execute($update);
  162. if (!$result) {
  163. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $update);
  164. if (!$in_cron) echo "Sync error : student process";
  165. break;
  166. } else { $count['students_updated']++; }
  167. }
  168. array_push($students, $student);
  169. // Update program enrolments for student
  170. $program_idyear = $program . '_' . $programyear;
  171. // Removals
  172. $delete = "DELETE FROM `$CFG->enrol_dbname`.`$CFG->enrol_dbtable` WHERE `$CFG->enrol_remoteuserfield` = '$student' AND `$CFG->enrol_db_remoterolefield` = '$student_role->shortname' AND `coursegroup_id` IS NULL AND program_idyear IS NOT NULL AND program_idyear != '$program_idyear'";
  173. if (!$result = $enroldb->Execute($delete)) {
  174. trigger_error($enroldb->ErrorMsg() .' STATEMENT: '. $delete);
  175. if (!$in_cron) echo "Erreur : inscription process";
  176. break;
  177. } else {
  178. $count['student_program_enrolments_removed'] += $enroldb->Affected_Rows();
  179. }
  180. // Additions
  181. $select = "SELECT $CFG->enrol_remotecoursefield, (SELECT count(*) FROM `$CFG->enrol_dbname`.`$CFG->enrol_dbtable` WHERE $CFG->enrol_remoteuserfield = '$student' AND e1.$CFG->enrol_remotecoursefield = $CFG->enrol_remotecoursefield AND program_idyear IS NOT NULL AND `$CFG->enrol_db_remoterolefield` = '$student_role->shortname') AS c FROM `$CFG->enrol_dbname`.`$CFG->enrol_dbtable` e1 WHERE program_idyear = '$program_idyear' AND `$CFG->enrol_db_remoterolefield` = '$student_role->shortname' GROUP BY $CFG->enrol_remotecoursefield;";
  182. $progadd_rs = $enroldb->Execute($select);
  183. while ($progadd_rs && !$progadd_rs->EOF && $progadd_rs->fields['c'] == 0) {
  184. $course = $progadd_rs->fields[$CFG->enrol_remotecoursefield];
  185. $insert = "INSERT INTO `$CFG->enrol_dbname`.`$CFG->enrol_dbtable` (`$CFG->enrol_remotecoursefield` , `$CFG->enrol_remoteuserfield`, `$CFG->enrol_db_remoterolefield`, `program_idyear`) VALUES ('$course', '$student', '$student_role->shortname', '$program_idyear');";
  186. if (!$result = $enroldb->Execute($insert)) {
  187. trigger_error($enroldb->ErrorMsg() .' STATEMENT: '. $insert);
  188. if (!$in_cron) echo "Erreur : inscription process";
  189. break;
  190. } else {
  191. $count['student_program_enrolments_added']++;
  192. }
  193. $progadd_rs->MoveNext();
  194. }
  195. }
  196. // Update programs data
  197. if (!in_array($program, $programs)) {
  198. $select = "SELECT * FROM `$CFG->sisdb_name`.`program` WHERE `id` = '$program'";
  199. $result = $sisdb->Execute($select);
  200. if ($result && $result->RecordCount() == 0) {
  201. $insert = "INSERT INTO `$CFG->sisdb_name`.`program` (`id` , `title`) VALUES ('$program', \"$programtitle\"); ";
  202. $result = $sisdb->Execute($insert);
  203. if (!$result) {
  204. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $insert);
  205. if (!$in_cron) echo "Sync error : program process";
  206. break;
  207. } else { $count['programs_added']++; }
  208. }
  209. elseif ($result && ($result->fields['title'] != $programtitle) ) {
  210. $update = "UPDATE `$CFG->sisdb_name`.`program` SET `title` = \"$programtitle\" WHERE `id` = '$program'; ";
  211. $result = $sisdb->Execute($update);
  212. if (!$result) {
  213. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $update);
  214. if (!$in_cron) echo "Sync error : program process";
  215. break;
  216. } else { $count['programs_updated']++; }
  217. }
  218. array_push($programs, $program);
  219. }
  220. // Update courses data
  221. if (!in_array($course, $courses)) {
  222. $select = "SELECT * FROM `$CFG->sisdb_name`.`course` WHERE `coursecode` = '$course'";
  223. $result = $sisdb->Execute($select);
  224. if ($result && $result->RecordCount() == 0) {
  225. $insert = "INSERT INTO `$CFG->sisdb_name`.`course` (`coursecode` , `title`, `unit`) VALUES ('$course', \"$course_title\", '$course_unit'); ";
  226. $result = $sisdb->Execute($insert);
  227. if (!$result) {
  228. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $insert);
  229. if (!$in_cron) echo "Sync error : course process";
  230. break;
  231. } else { $count['courses_added']++; }
  232. }
  233. elseif ($result && ($result->fields['title'] != $course_title || $result->fields['unit'] != $course_unit)) {
  234. $update = "UPDATE `$CFG->sisdb_name`.`course` SET `title` = \"$course_title\", `unit` = \"$course_unit\" WHERE `coursecode` = '$course'; ";
  235. $result = $sisdb->Execute($update);
  236. if (!$result) {
  237. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $update);
  238. if (!$in_cron) echo "Sync error : student process";
  239. break;
  240. } else { $count['courses_updated']++; }
  241. }
  242. array_push($courses, $course);
  243. }
  244. // Update coursegroups data
  245. foreach ($coursegroups as $cg) {
  246. if ($cg['coursecode'] == $course && $cg['group'] == $coursegroup && $cg['term'] == $term) {
  247. $coursegroup_id = $cg['id'];
  248. break;
  249. }
  250. }
  251. if (empty($coursegroup_id)) {
  252. $select = "SELECT * FROM `$CFG->sisdb_name`.`coursegroup` WHERE `coursecode` = '$course' AND `group` = '$coursegroup' AND `term` = $term";
  253. $result = $sisdb->Execute($select);
  254. if ($result && $result->RecordCount() == 0) {
  255. $insert = "INSERT INTO `coursegroup` (`coursecode`, `group`, `term`) VALUES ('$course', '$coursegroup', $term); ";
  256. $result = $sisdb->Execute($insert);
  257. if (!$result) {
  258. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $insert);
  259. print($sisdb->ErrorMsg() .' STATEMENT: '. $insert);
  260. break;
  261. } else { $coursegroup_id = $sisdb->Insert_ID(); $count['coursegroups_added']++; }
  262. } else { $coursegroup_id = $result->fields['id']; }
  263. array_push($coursegroups, array('coursecode' => $course, 'group' => $coursegroup, 'term' => $term, 'id' => $coursegroup_id));
  264. }
  265. array_push($student_enrol_remotedb, serialize(array($coursegroup_id, $student)));
  266. $sisdbsource_rs->moveNext();
  267. }
  268. // Update student enrolments
  269. // Get enrolments from local database
  270. $student_enrol_localdb = array();
  271. $select = "SELECT * FROM `$CFG->sisdb_name`.`student_enrolment` WHERE `coursegroup_id` IN (SELECT id FROM `$CFG->sisdb_name`.`coursegroup` WHERE `term` >= $start_term)";
  272. $result = $sisdb->Execute($select);
  273. while ($result && !$result->EOF) {
  274. array_push($student_enrol_localdb, serialize(array($result->fields['coursegroup_id'], $result->fields['username'])));
  275. $result->MoveNext();
  276. }
  277. // Compute differences between local and remote datasets
  278. $student_enrolments_add = array_diff($student_enrol_remotedb, $student_enrol_localdb);
  279. $student_enrolments_del = array_diff($student_enrol_localdb, $student_enrol_remotedb);
  280. // Add and remove enrolments as required
  281. foreach ($student_enrolments_add as $enrolment) {
  282. $enrolment = unserialize($enrolment);
  283. $insert = "INSERT INTO `$CFG->sisdb_name`.`student_enrolment` (`coursegroup_id` , `username`) VALUES ('$enrolment[0]', '$enrolment[1]'); ";
  284. if (!$result = $sisdb->Execute($insert)) {
  285. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $insert);
  286. if (!$in_cron) echo "Erreur : inscription process";
  287. break;
  288. }
  289. // Add student to courses to which this coursegroup is assigned
  290. $coursegroup_enrolments_rs = get_recordset_sql("SELECT DISTINCT `$CFG->enrol_remotecoursefield` AS courseidnumber FROM `$CFG->enrol_dbname`.`$CFG->enrol_dbtable` WHERE `coursegroup_id` = '$enrolment[0]'");
  291. while ($coursegroup_enrolment = rs_fetch_next_record($coursegroup_enrolments_rs)) {
  292. // Do external enrolments DB
  293. $insert = "INSERT INTO `$CFG->enrol_dbname`.`$CFG->enrol_dbtable` (`$CFG->enrol_remotecoursefield` , `$CFG->enrol_remoteuserfield`, `$CFG->enrol_db_remoterolefield`, `coursegroup_id`) VALUES ('$coursegroup_enrolment->courseidnumber', '$enrolment[1]', '$student_role->shortname', '$enrolment[0]'); ";
  294. if (!$result = $enroldb->Execute($insert)) {
  295. trigger_error($enroldb->ErrorMsg() .' STATEMENT: '. $insert);
  296. if (!$in_cron) echo "Erreur : inscription process";
  297. break;
  298. }
  299. // Do internal enrolments DB
  300. $course = get_record('course', 'idnumber', $coursegroup_enrolment->courseidnumber);
  301. $context = get_context_instance(CONTEXT_COURSE, $course->id);
  302. if ($student_user = get_record('user', 'username', $enrolment[1])) {
  303. role_assign($student_role->id, $student_user->id, 0, $context->id);
  304. }
  305. $count['student_enrolments_added']++;
  306. }
  307. }
  308. foreach ($student_enrolments_del as $enrolment) {
  309. $enrolment = unserialize($enrolment);
  310. $delete = "DELETE FROM `$CFG->sisdb_name`.`student_enrolment` WHERE (`coursegroup_id` = '$enrolment[0]' AND `username` = '$enrolment[1]'); ";
  311. if (!$result = $sisdb->Execute($delete)) {
  312. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $delete);
  313. if (!$in_cron) echo "Erreur : inscription process";
  314. break;
  315. }
  316. // Remove student from courses to which this coursegroup is assigned
  317. $coursegroup_enrolments_rs = get_recordset_sql("SELECT DISTINCT `$CFG->enrol_remotecoursefield` AS courseidnumber FROM `$CFG->enrol_dbname`.`$CFG->enrol_dbtable` WHERE `coursegroup_id` = '$enrolment[0]'");
  318. while ($coursegroup_enrolment = rs_fetch_next_record($coursegroup_enrolments_rs)) {
  319. // Do external enrolments DB
  320. $delete = "DELETE FROM `$CFG->enrol_dbname`.`$CFG->enrol_dbtable` WHERE `$CFG->enrol_remotecoursefield` = '$coursegroup_enrolment->courseidnumber' AND `$CFG->enrol_remoteuserfield` = '$enrolment[1]' AND `$CFG->enrol_db_remoterolefield` = '$student_role->shortname'";
  321. if (!$result = $enroldb->Execute($delete)) {
  322. trigger_error($enroldb->ErrorMsg() .' STATEMENT: '. $delete);
  323. if (!$in_cron) echo "Erreur : inscription process";
  324. break;
  325. }
  326. // Do internal enrolments DB
  327. $course = get_record('course', 'idnumber', $coursegroup_enrolment->courseidnumber);
  328. $context = get_context_instance(CONTEXT_COURSE, $course->id);
  329. if ($student_user = get_record('user', 'username', $enrolment[1])) {
  330. role_unassign($student_role->id, $student_user->id, 0, $context->id);
  331. }
  332. }
  333. $count['student_enrolments_removed']++;
  334. }
  335. // Update teacher enrolments
  336. // Get enrolments from remote database (ie, Clara)
  337. $select = cegep_local_sisdbsource_select_teachers($start_term);
  338. $sisdbsource_rs = $sisdbsource->Execute($select);
  339. while ($sisdbsource_rs && !$sisdbsource_rs->EOF) {
  340. if (!in_array($term,$terms)) {
  341. $terms[] = $term;
  342. }
  343. $term = implode(cegep_local_sisdbsource_decode('courseterm',$sisdbsource_rs->fields['CourseTerm']));
  344. $teacher = cegep_local_sisdbsource_decode('teachernumber',$sisdbsource_rs->fields['TeacherNumber']);
  345. $course = cegep_local_sisdbsource_decode('coursenumber',$sisdbsource_rs->fields['CourseNumber']);
  346. $coursegroup = cegep_local_sisdbsource_decode('coursegroup',$sisdbsource_rs->fields['CourseGroup']);
  347. $course_title = cegep_local_sisdbsource_decode('coursetitle',$sisdbsource_rs->fields['CourseTitle']);
  348. $coursegroup_id = '';
  349. $course_unit = 0;
  350. foreach ($coursegroups as $cg) {
  351. if ($cg['coursecode'] == $course && $cg['group'] == $coursegroup && $cg['term'] == $term) {
  352. $coursegroup_id = $cg['id'];
  353. break;
  354. }
  355. }
  356. // Add coursegroup if not found (no students enrolled yet)
  357. if (empty($coursegroup_id)) {
  358. $select = "SELECT * FROM `$CFG->sisdb_name`.`coursegroup` WHERE `coursecode` = '$course' AND `group` = '$coursegroup' AND `term` = $term";
  359. $result = $sisdb->Execute($select);
  360. if ($result && $result->RecordCount() == 0) {
  361. $insert = "INSERT INTO `coursegroup` (`coursecode`, `group`, `term`) VALUES ('$course', '$coursegroup', $term); ";
  362. $result = $sisdb->Execute($insert);
  363. if (!$result) {
  364. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $insert);
  365. print($sisdb->ErrorMsg() .' STATEMENT: '. $insert);
  366. break;
  367. } else { $coursegroup_id = $sisdb->Insert_ID(); $count['coursegroups_added']++; }
  368. } else { $coursegroup_id = $result->fields['id']; }
  369. array_push($coursegroups, array('coursecode' => $course, 'group' => $coursegroup, 'term' => $term, 'id' => $coursegroup_id));
  370. }
  371. // Update courses data
  372. if (!in_array($course, $courses)) {
  373. $select = "SELECT * FROM `$CFG->sisdb_name`.`course` WHERE `coursecode` = '$course'";
  374. $result = $sisdb->Execute($select);
  375. if ($result && $result->RecordCount() == 0) {
  376. $insert = "INSERT INTO `$CFG->sisdb_name`.`course` (`coursecode` , `title`, `unit`) VALUES ('$course', \"$course_title\", '$course_unit'); ";
  377. $result = $sisdb->Execute($insert);
  378. if (!$result) {
  379. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $insert);
  380. if (!$in_cron) echo "Sync error : course process";
  381. break;
  382. } else { $count['courses_added']++; }
  383. }
  384. elseif ($result && $result->fields['title'] != $course_title) {
  385. $update = "UPDATE `$CFG->sisdb_name`.`course` SET `title` = \"$course_title\" WHERE `coursecode` = '$course'; ";
  386. $result = $sisdb->Execute($update);
  387. if (!$result) {
  388. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $update);
  389. if (!$in_cron) echo "Sync error : student process";
  390. break;
  391. } else { $count['courses_updated']++; }
  392. }
  393. array_push($courses, $course);
  394. }
  395. array_push($teacher_enrol_remotedb, serialize(array($coursegroup_id, $teacher)));
  396. $sisdbsource_rs->MoveNext();
  397. }
  398. // Get enrolments from local database
  399. $select = "SELECT * FROM `$CFG->sisdb_name`.`teacher_enrolment` WHERE `coursegroup_id` IN (SELECT id FROM `$CFG->sisdb_name`.`coursegroup` WHERE `term` >= '$start_term')";
  400. $result = $sisdb->Execute($select);
  401. while ($result && !$result->EOF) {
  402. array_push($teacher_enrol_localdb, serialize(array($result->fields['coursegroup_id'], $result->fields['idnumber'])));
  403. $result->MoveNext();
  404. }
  405. // Compute differences between local and remote datasets
  406. $teacher_enrolments_add = array_diff($teacher_enrol_remotedb, $teacher_enrol_localdb);
  407. $teacher_enrolments_del = array_diff($teacher_enrol_localdb, $teacher_enrol_remotedb);
  408. // Add and remove enrolments as required
  409. foreach ($teacher_enrolments_add as $enrolment) {
  410. $enrolment = unserialize($enrolment);
  411. $insert = "INSERT INTO `$CFG->sisdb_name`.`teacher_enrolment` (`coursegroup_id` , `idnumber`) VALUES ('$enrolment[0]', '$enrolment[1]'); ";
  412. if (!$result = $sisdb->Execute($insert)) {
  413. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $insert);
  414. if (!$in_cron) echo "Erreur : inscription process";
  415. break;
  416. }
  417. $count['teacher_enrolments_added']++;
  418. }
  419. foreach ($teacher_enrolments_del as $enrolment) {
  420. $enrolment = unserialize($enrolment);
  421. $delete = "DELETE FROM `$CFG->sisdb_name`.`teacher_enrolment` WHERE `coursegroup_id` = '$enrolment[0]' AND `idnumber` = '$enrolment[1]';";
  422. if (!$result = $sisdb->Execute($delete)) {
  423. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $delete);
  424. if (!$in_cron) echo "Erreur : inscription process";
  425. break;
  426. }
  427. $count['teacher_enrolments_removed']++;
  428. }
  429. // Stop counting time
  430. $end_time = (float) array_sum(explode(' ',microtime()));
  431. // Display report
  432. $msg = '';
  433. $msg .= "<strong><u>Synchronization completed</u></strong><br /><br />";
  434. $msg .= sprintf("<strong>Terms</strong> : %s<br /><br />", implode(', ', $terms));
  435. $msg .= sprintf("<strong>Students</strong> : %d added; %d updated; %d processed<br /><br />", $count['students_added'], $count['students_updated'], count($students));
  436. $msg .= sprintf("<strong>Programs</strong> : %d added; %d updated; %d processed<br /><br />", $count['programs_added'], $count['programs_updated'], count($programs));
  437. $msg .= sprintf("<strong>Courses</strong> : %d added; %d updated; %d processed<br /><br />", $count['courses_added'], $count['courses_updated'], count($courses));
  438. $msg .= sprintf("<strong>Coursegroups</strong> : %d added; %d processed<br /><br />", $count['coursegroups_added'], count($coursegroups));
  439. $msg .= sprintf("<strong>Student course enrolments</strong> : %d added; %d removed; %d skipped; %d processed<br /><br />", $count['student_enrolments_added'], $count['student_enrolments_removed'], $count['records_skipped'], count($student_enrol_remotedb));
  440. $msg .= sprintf("<strong>Student program enrolments</strong> : %d added; %d removed<br /><br />", $count['student_program_enrolments_added'], $count['student_program_enrolments_removed']);
  441. $msg .= sprintf("<strong>Teacher course enrolments</strong> : %d added; %d removed; %d processed<br /><br />", $count['teacher_enrolments_added'], $count['teacher_enrolments_removed'], count($teacher_enrol_remotedb));
  442. $msg .= "Started at : $mysqltimestamp<br />";
  443. $msg .= "Execution time : ". sprintf("%.4f", ($end_time-$start_time))." seconds";
  444. $currenttab = 'sync';
  445. require('sisdb_tabs.php');
  446. notice($msg,$CFG->wwwroot);
  447. print_footer();
  448. }
  449. function cegep_sisdb_prune_form() {
  450. $currenttab = 'prune';
  451. require('sisdb_tabs.php');
  452. print_box('Please indicate the number of back terms (other than the most current term) to keep in the database.<br /><br />For example, if the latest term in the database is 20102 and you indicate 3, then all terms older that 20102, 20101, 20093 and 20092 will be pruned from the database.<br /><br />Older coursegroups that have active enrolments in Moodle courses will not be affected.');
  453. $form = '<center><form enctype="multipart/form-data" action="sisdb.php" method="post">';
  454. $form .= 'Number of terms to keep : <input name="keep_terms" type="text" size="5" maxlength="1" value="3" />';
  455. $form .= '<input type="hidden" name="op" value="prune" />';
  456. $form .= '<br /><br /><input type="submit" value="Start" /></form></center>';
  457. print_box($form);
  458. print_footer();
  459. }
  460. function cegep_sisdb_prune($keep_terms) {
  461. global $CFG, $enroldb, $sisdb;
  462. // Keep track of time
  463. $start_time = (float) array_sum(explode(' ',microtime()));
  464. $timestamp = time();
  465. $mysqltimestamp = date('Y-m-d H:i:s', $timestamp);
  466. // Set up SQL variables for triggers
  467. if ($CFG->sisdb_logging) {
  468. $sisdb->Execute('SET @LOGGING = 1');
  469. $sisdb->Execute("SET @TIMESTAMP = '$mysqltimestamp'");
  470. } else {
  471. $sisdb->Execute('SET @LOGGING = 0');
  472. }
  473. // Set up counters
  474. $pruned_terms = array();
  475. $count['courses_pruned'] = 0;
  476. $count['students_pruned'] = 0;
  477. $count['programs_pruned'] = 0;
  478. $count['coursegroups_pruned'] = 0;
  479. $count['student_enrolments_pruned'] = 0;
  480. $count['teacher_enrolments_pruned'] = 0;
  481. // Get most recent term
  482. $select = "SELECT MAX(term) as latest_term FROM `$CFG->sisdb_name`.`coursegroup`;";
  483. $result = $sisdb->Execute($select);
  484. $latest_term = $result->fields['latest_term'];
  485. if (!empty($latest_term)) {
  486. // Get old coursegroups
  487. $select = "SELECT * FROM `$CFG->sisdb_name`.`coursegroup` WHERE `term` < " . cegep_local_decrement_term($latest_term, $keep_terms) . ";";
  488. $coursegroups_rs = $sisdb->Execute($select);
  489. while ($coursegroups_rs && !$coursegroups_rs->EOF) {
  490. $coursegroup_id = $coursegroups_rs->fields['id'];
  491. // Check if coursegroup has any active enrolments
  492. $select = "SELECT COUNT(*) as count FROM `$CFG->enrol_dbname`.`$CFG->enrol_dbtable` WHERE coursegroup_id = $coursegroup_id";
  493. $result = $sisdb->Execute($select);
  494. if ($result && $result->fields['count'] > 0) {
  495. // Don't remove it, skip to next coursegroup
  496. $coursegroups_rs->MoveNext();
  497. continue;
  498. }
  499. // Keep track of pruned terms
  500. if (!in_array($coursegroups_rs->fields['term'], $pruned_terms)) {
  501. array_push($pruned_terms, $coursegroups_rs->fields['term']);
  502. }
  503. // Prune old and inactive student and enrolment records
  504. $delete = "DELETE FROM `$CFG->sisdb_name`.`student_enrolment` WHERE `coursegroup_id` = $coursegroup_id;";
  505. if (!$result = $sisdb->Execute($delete)) {
  506. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $delete);
  507. if (!$in_cron) echo "Error pruning old student enrolment records.";
  508. } else {
  509. $count['student_enrolments_pruned'] += $sisdb->Affected_Rows();
  510. }
  511. // Prune old and inactive teacher enrolment records
  512. $delete = "DELETE FROM `$CFG->sisdb_name`.`teacher_enrolment` WHERE `coursegroup_id` = $coursegroup_id;";
  513. if (!$result = $sisdb->Execute($delete)) {
  514. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $delete);
  515. if (!$in_cron) echo "Error pruning old teacher enrolment records.";
  516. } else {
  517. $count['teacher_enrolments_pruned'] += $sisdb->Affected_Rows();
  518. }
  519. // Prune coursegroup record
  520. $delete = "DELETE FROM `$CFG->sisdb_name`.`coursegroup` WHERE `id` = $coursegroup_id;";
  521. if (!$result = $sisdb->Execute($delete)) {
  522. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $delete);
  523. if (!$in_cron) echo "Error pruning old coursegroup records.";
  524. } else {
  525. $count['coursegroups_pruned'] += $sisdb->Affected_Rows();
  526. }
  527. $coursegroups_rs->MoveNext();
  528. }
  529. // Prune courses with no coursegroups
  530. $delete = "DELETE FROM `$CFG->sisdb_name`.`course` WHERE `coursecode` NOT IN (SELECT DISTINCT `coursecode` FROM `$CFG->sisdb_name`.`coursegroup`);";
  531. if (!$result = $sisdb->Execute($delete)) {
  532. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $delete);
  533. if (!$in_cron) echo "Error pruning old course records.";
  534. } else {
  535. $count['courses_pruned'] += $sisdb->Affected_Rows();
  536. }
  537. // Prune students with no enrolments
  538. $delete = "DELETE FROM `$CFG->sisdb_name`.`student` WHERE `username` NOT IN (SELECT DISTINCT `username` FROM `$CFG->sisdb_name`.`student_enrolment`);";
  539. if (!$result = $sisdb->Execute($delete)) {
  540. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $delete);
  541. if (!$in_cron) echo "Error pruning old student records.";$coursegroup_id = $coursegroups->fields['coursegroup_id'];
  542. } else {
  543. $count['students_pruned'] += $sisdb->Affected_Rows();
  544. }
  545. // Prune programs with no students
  546. $delete = "DELETE FROM `$CFG->sisdb_name`.`program` WHERE `id` NOT IN (SELECT DISTINCT `program_id` FROM `$CFG->sisdb_name`.`student`);";
  547. if (!$result = $sisdb->Execute($delete)) {
  548. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $delete);
  549. if (!$in_cron) echo "Error pruning old program records.";
  550. } else {
  551. $count['programs_pruned'] += $sisdb->Affected_Rows();
  552. }
  553. // Optimize tables
  554. $optimize = 'OPTIMIZE TABLE `course` , `coursegroup` , `program` , `student` , `student_enrolment` , `teacher_enrolment`;';
  555. if (!$result = $sisdb->Execute($optimize)) {
  556. trigger_error($sisdb->ErrorMsg() .' STATEMENT: '. $optimize);
  557. if (!$in_cron) echo "Error optimizing tables.";
  558. }
  559. }
  560. // Stop counting time
  561. $end_time = (float) array_sum(explode(' ',microtime()));
  562. // Display report
  563. $msg = '';
  564. $msg .= "<strong><u>Pruning completed</u></strong><br /><br />";
  565. $msg .= sprintf("<strong>Terms</strong> : %s<br /><br />", implode(', ', $pruned_terms));
  566. $msg .= sprintf("<strong>Students</strong> : %d removed<br /><br />", $count['students_pruned']);
  567. $msg .= sprintf("<strong>Programs</strong> : %d removed<br /><br />", $count['programs_pruned']);
  568. $msg .= sprintf("<strong>Courses</strong> : %d removed<br /><br />", $count['courses_pruned']);
  569. $msg .= sprintf("<strong>Coursegroups</strong> : %d removed<br /><br />", $count['coursegroups_pruned']);
  570. $msg .= sprintf("<strong>Student enrolments</strong> : %d removed<br /><br />", $count['student_enrolments_pruned']);
  571. $msg .= sprintf("<strong>Teacher course enrolments</strong> : %d removed<br /><br />", $count['teacher_enrolments_pruned']);
  572. $msg .= "Started at : $mysqltimestamp<br />";
  573. $msg .= "Execution time : ". sprintf("%.4f", ($end_time-$start_time))." seconds";
  574. $currenttab = 'prune';
  575. require('sisdb_tabs.php');
  576. notice($msg,$CFG->wwwroot);
  577. print_footer();
  578. }
  579. $enroldb->Close();
  580. $sisdb->Close();
  581. $sisdbsource->Close();
  582. exit(0);
  583. ?>