_CourseList.php

  1. 4.x classes/_CourseList.php
  2. 5.x classes/_CourseList.php

File

classes/_CourseList.php
View source
  1. <?php
  2. require_once("ObjList.php");
  3. class _CourseList extends ObjList
  4. {
  5. // This inherits most of its classes from ObjList,
  6. // but, it has to be able to do special functions
  7. // specific to Courses. Use parent:: to access
  8. // a parent function within ObjList.
  9. // Example: parent::indexOf();
  10. //public $arrayCourseIDList = array();
  11. /**
  12. * Used to cast a regular ObjList object into a CourseList.
  13. *
  14. * @param ObjList $obj
  15. *
  16. * @return CourseList
  17. */
  18. static public function cast(ObjList $obj)
  19. { // This can be used to cast a regular ObjList
  20. // into a CourseList object.
  21. // Use the syntax: CourseList::cast($x);
  22. $new_c_l = new CourseList();
  23. $new_c_l->array_list = $obj->array_list;
  24. $new_c_l->is_empty = $obj->is_empty;
  25. $new_c_l->reset_counter();
  26. return $new_c_l;
  27. }
  28. /**
  29. * Give every course in the list a minimum grade.
  30. *
  31. * @param string $min_grade
  32. */
  33. function assign_min_grade($min_grade)
  34. {
  35. // Go through the list and give every course the specified
  36. // min grade.
  37. for ($t = 0; $t < $this->count; $t++)
  38. {
  39. $course = $this->array_list[$t];
  40. $course->min_grade = $min_grade;
  41. }
  42. }
  43. /**
  44. * Go through the list and find any course whose hours are greater
  45. * than $hours. Make that course "unselectable." Used in the groups.
  46. *
  47. * For example, if a student may only select 3 hours from a group, we don't
  48. * want to give them the option of selecting a 5 hour course. But we also
  49. * don't want to remove that course either. We want to display it so they
  50. * know it was an option (and possibly need to substitute or move things
  51. * around if they need it).
  52. *
  53. * Returns TRUE if anything got assigned, FALSE if nothing got assigned.
  54. *
  55. * @param int $hours
  56. *
  57. * @return bool
  58. */
  59. function assign_unselectable_courses_with_hours_greater_than($hours)
  60. {
  61. // Go through the list and assign bool_unselectable courses whose minHour
  62. // is greater than $hours.
  63. // Returns TRUE if it did assign something,
  64. // false if it didn't.
  65. $bool_assigned = false;
  66. for ($t = 0; $t < $this->count; $t++)
  67. {
  68. $course = $this->array_list[$t];
  69. if ($course->subject_id == "")
  70. {
  71. $course->load_descriptive_data();
  72. }
  73. if ($course->min_hours > $hours)
  74. {
  75. $course->bool_unselectable = true;
  76. $bool_assigned = true;
  77. }
  78. }
  79. return $bool_assigned;
  80. }
  81. /**
  82. * Find and return a specific course from the list.
  83. *
  84. * @param int $course_id
  85. * - The course_id to look for. Do not set if using
  86. * $use_course.
  87. *
  88. * @param int $term_id
  89. * - The term_id for the course to look for. Do not set if using
  90. * $use_course.
  91. *
  92. * @param bool $bool_transfer
  93. * - Is the course we are looking for a transfer course? Do not
  94. * use if using $use_course.
  95. *
  96. * @param bool $bool_exclude_substitutions
  97. * - If TRUE, we will not consider courses which have been used
  98. * in a substitution.
  99. *
  100. * @param Course $use_course
  101. * - Optional. If you already have a course object which can be used
  102. * as a template to search for, specify it here. Otherwise, set to
  103. * NULL. If using this, then $course_id, $term_id, and $bool_transfer
  104. * will be ignored.
  105. *
  106. * @param Int $sub_req_by_degree_id
  107. * - Optional. If set, we will only exclude substituted courses if they were substitutions made for this degree_id. Leave 0 if not sure
  108. * what to use.
  109. *
  110. *
  111. * @return Course
  112. */
  113. function find_specific_course($course_id = 0, $term_id = 0, $bool_transfer = false, $bool_exclude_substitutions = true, Course $use_course = null, $sub_req_by_degree_id = 0)
  114. {
  115. if ($use_course != null && is_object($use_course))
  116. {
  117. $course_id = $use_course->course_id;
  118. $term_id = $use_course->term_id;
  119. $bool_transfer = $use_course->bool_transfer;
  120. }
  121. // Look through the array for a course with this id, termId, and
  122. // transfer credit status.
  123. for ($t = 0; $t < $this->count; $t++)
  124. {
  125. $course = $this->array_list[$t];
  126. $check_course_id = $course->course_id;
  127. if ($bool_transfer == true && is_object($course->course_transfer))
  128. {
  129. $check_course_id = $course->course_transfer->course_id;
  130. }
  131. if ($check_course_id == $course_id && $course->term_id == $term_id && $course->bool_transfer == $bool_transfer)
  132. {
  133. if ($bool_exclude_substitutions == true)
  134. {
  135. if ($course->get_bool_substitution($sub_req_by_degree_id) == TRUE)
  136. {
  137. continue;
  138. }
  139. }
  140. return $course;
  141. }
  142. }
  143. return false;
  144. }
  145. /**
  146. * Call the $course->load_course_descriptive_data() on
  147. * every course in the list.
  148. *
  149. */
  150. function load_course_descriptive_data()
  151. {
  152. // Call the load_descriptive_data() method
  153. // for every course in the list.
  154. for ($t = 0; $t < $this->count; $t++)
  155. {
  156. $course = $this->array_list[$t];
  157. $course->load_descriptive_data();
  158. }
  159. }
  160. /**
  161. * Call the $course->load_descriptive_transfer_data() on
  162. * every course in the list. Meant for transfer courses.
  163. *
  164. */
  165. function load_descriptive_transfer_data($student_id = 0)
  166. {
  167. for ($t = 0; $t < $this->count; $t++)
  168. {
  169. $course = $this->array_list[$t];
  170. $course->load_descriptive_transfer_data($student_id);
  171. }
  172. }
  173. /**
  174. * Using the parent's function of find_all_matches, this
  175. * will return a CourseList of all courses which match
  176. * the Course object.
  177. *
  178. * @param Course $course_c
  179. * @return CourseList
  180. */
  181. function find_all_matches(stdClass $course_c)
  182. {
  183. if (!$list_matches = parent::find_all_matches($course_c))
  184. {
  185. return false;
  186. }
  187. $list_matches = CourseList::cast($list_matches);
  188. return $list_matches;
  189. }
  190. /**
  191. * Returns a match to the Course courseC which does
  192. * not have any courses fulfilling it. Usefull for finding
  193. * course requirement matches in a list which have not
  194. * yet been assigned.
  195. *
  196. * @param Course $course_c
  197. * @return Course
  198. */
  199. function find_first_unfulfilled_match(Course $course_c)
  200. {
  201. // Returns match to courseC which does not have
  202. // any courses fulfilling it. Useful for finding
  203. // course requirement matches in a list which have not
  204. // yet been assigned.
  205. for ($t = 0; $t < $this->count; $t++)
  206. {
  207. if ($this->array_list[$t]->equals($course_c) && $this->array_list[$t]->course_list_fulfilled_by->is_empty == true)
  208. {
  209. return $this->array_list[$t];
  210. }
  211. }
  212. return false;
  213. }
  214. /**
  215. * Go through the list and set the $bool_exclude_repeat flag to TRUE
  216. * for all matches of $course in this list.
  217. *
  218. * Returns FALSE if no matches could be found.
  219. *
  220. * @param Course $course
  221. * @return bool
  222. */
  223. function mark_repeats_exclude(Course $course, $degree_id = 0, Course $except_for_course = NULL)
  224. {
  225. // Set the bool_exclude_repeat flag to TRUE for all
  226. // occurances of $course in THIS list.
  227. if (!$list_matches = parent::find_all_matches($course))
  228. {
  229. return false;
  230. }
  231. $list_matches = CourseList::cast($list_matches);
  232. $list_matches->reset_counter();
  233. while($list_matches->has_more())
  234. {
  235. $c = $list_matches->get_next();
  236. if ($except_for_course != NULL) {
  237. if ($c == $except_for_course) {
  238. // Skip it.
  239. continue;
  240. }
  241. }
  242. $c->set_bool_exclude_repeat($degree_id, TRUE);
  243. }
  244. return true;
  245. }
  246. /**
  247. * Find a list of matches to Course courseC, which fulfill
  248. * the min_grade requirement, ordered by most recently taken.
  249. *
  250. * Returns FALSE if no matches were found, else it will
  251. * return the matched Course object.
  252. *
  253. * @return Course
  254. */
  255. function find_most_recent_match(Course $course_c, $min_grade = "", $bool_mark_repeats_exclude = false, $degree_id = 0, $bool_skip_already_assigned_to_degree = TRUE, $bool_skip_subs = FALSE, $group_id = 0)
  256. {
  257. // Get a list of all matches to courseC, and
  258. // then order them by the most recently taken course
  259. // first.
  260. // We should, too, check for minimum grades here
  261. // as well.
  262. if (!$list_matches = parent::find_all_matches($course_c))
  263. {
  264. return false;
  265. }
  266. $list_matches = CourseList::cast($list_matches);
  267. if ($list_matches->is_empty)
  268. {
  269. return false;
  270. }
  271. // If we are here, then we have at least one match.
  272. // Meaning, we have at least one class which might fit
  273. // into this course requirement.
  274. // Sort the courses into most recently taken first.
  275. $list_matches->sort_most_recent_first();
  276. $withdrew_grades = csv_to_array(variable_get("withdrew_grades", "W"));
  277. // So, now that it's sorted, we should look through the list,
  278. // checking the min grade requirements (if any). When we find
  279. // a good one, we will select it.
  280. $list_matches->reset_counter();
  281. while($list_matches->has_more())
  282. {
  283. $c = $list_matches->get_next();
  284. if ($c->get_bool_exclude_repeat($degree_id, TRUE))
  285. {
  286. continue;
  287. }
  288. if ($bool_skip_subs && $c->get_bool_substitution($degree_id) == TRUE) {
  289. // It is already being used in a substitution for this degree id, so we skip it.
  290. continue;
  291. }
  292. //////////////////////////////////////////
  293. /// Check for min grade, etc, here.
  294. if (!$c->meets_min_grade_requirement_of(null, $min_grade))
  295. {
  296. //if ($min_grade == "B-") fpm("[did not meet min grade requirement of $min_grade :: $c->subject_id $c->course_num $c->grade");
  297. if ($bool_mark_repeats_exclude == true)
  298. {
  299. // Since this course does not meet the min_grade,
  300. // check to see if it may be repeated. If it can't,
  301. // then we must mark ALL previous attempts at this
  302. // course as being excluded from further consideration.
  303. //
  304. // We don't do this consideration if they simply
  305. // withdrew from a course...
  306. if (in_array($c->grade, $withdrew_grades)) { continue; }
  307. if ($c->min_hours < 1 || $c->min_hours == "") {
  308. $c->load_descriptive_data(); // make sure we get hour data for this course.
  309. }
  310. if ($c->repeat_hours <= $c->min_hours)
  311. {
  312. // No repeats.
  313. $this->mark_repeats_exclude($c, $degree_id);
  314. return false;
  315. } else {
  316. // Repeats allowed, so just continue.
  317. continue;
  318. }
  319. } // if bool_mark_repeats_exclude == true
  320. else {
  321. // We did NOT meet the min_grade requirement!
  322. //if ($min_grade == "B-") fpm("[did not meet min grade requirement of $min_grade :: $c->subject_id $c->course_num $c->grade");
  323. $c = FALSE;
  324. continue;
  325. }
  326. } // course did NOT meet the min_grade requirement
  327. else {
  328. // The course DID meet the min grade requirement.
  329. // Are we supposed to exclude repeats?
  330. if ($bool_mark_repeats_exclude) {
  331. // Make sure the course isn't allowed to be repeated...
  332. if ($c->repeat_hours <= $c->min_hours) {
  333. // No repeats allowed.
  334. $this->mark_repeats_exclude($c, $degree_id, $c);
  335. }
  336. }
  337. }
  338. // Has the course already been assigned [to this degree]?
  339. if ($bool_skip_already_assigned_to_degree && $c->get_has_been_assigned_to_degree_id($degree_id)) {
  340. // Yes, it's been assigned, so we can just skip it.
  341. continue;
  342. }
  343. // At this point, we are going to invoke a hook, to give add-on modules
  344. // one last chance to "skip" the course or not.
  345. $bool_can_proceed = TRUE;
  346. $result = invoke_hook("courselist_find_match_allow_course", array($c, $course_c, $list_matches, $degree_id, $group_id));
  347. foreach ($result as $m => $val) {
  348. // If *any* module said FALSE, then we must skip this course and not assign it to this degree.
  349. if ($val === FALSE) $bool_can_proceed = $val;
  350. }
  351. if (!$bool_can_proceed) {
  352. continue;
  353. }
  354. return $c;
  355. }
  356. return FALSE;
  357. }
  358. /**
  359. * Find a list of matches to Course courseC, which fulfill
  360. * the min_grade requirement, ordered by most best grade first.
  361. *
  362. * Returns FALSE if no matches were found, else it will
  363. * return the matched Course object.
  364. *
  365. *
  366. * @return Course
  367. */
  368. function find_best_grade_match(Course $course_c, $min_grade = "", $bool_mark_repeats_exclude = false, $degree_id = 0, $bool_skip_already_assigned_to_degree = TRUE, $bool_skip_subs = FALSE, $group_id = 0)
  369. {
  370. $list_matches = parent::find_all_matches($course_c);
  371. if (!$list_matches) {
  372. return false;
  373. }
  374. $list_matches = CourseList::cast($list_matches);
  375. //sort the courses into largest hours first, so equal grades will be sorted by hours
  376. $list_matches->sort_largest_hours_first();
  377. // Sort the courses into best grade first.
  378. $list_matches->sort_best_grade_first();
  379. if (!$list_matches || $list_matches->is_empty)
  380. {
  381. return false;
  382. }
  383. // If we are here, then we have more than one match.
  384. // Meaning, we have more than one class which might fit
  385. // into this course requirement.
  386. $withdrew_grades = csv_to_array(variable_get("withdrew_grades", "W"));
  387. // So, now that it's sorted, we should look through the list,
  388. // checking the min grade requirements (if any). When we find
  389. // a good one, we will select it.
  390. $list_matches->reset_counter();
  391. while($list_matches->has_more())
  392. {
  393. $c = $list_matches->get_next();
  394. if ($c->get_bool_exclude_repeat($degree_id) == TRUE)
  395. {
  396. continue;
  397. }
  398. // Has the course already been assigned [to this degree]?
  399. if ($bool_skip_already_assigned_to_degree && $c->get_has_been_assigned_to_degree_id($degree_id)) {
  400. // Yes, it's been assigned, so we can just skip it.
  401. continue;
  402. }
  403. if ($bool_skip_subs && $c->get_bool_substitution($degree_id) == TRUE) {
  404. // It is already being used in a substitution for this degree id, so we skip it.
  405. continue;
  406. }
  407. //////////////////////////////////////////
  408. /// Check for min grade, etc, here.
  409. if (!$c->meets_min_grade_requirement_of(null, $min_grade))
  410. {
  411. if ($bool_mark_repeats_exclude == true)
  412. {
  413. // Since this course does not meet the min_grade,
  414. // check to see if it may be repeated. If it can't,
  415. // then we must mark ALL previous attempts at this
  416. // course as being excluded from further consideration.
  417. // (ULM policy on repeats).
  418. // We don't do this consideration if they simply
  419. // withdrew from a course...
  420. if (in_array($c->grade, $withdrew_grades)) { continue; }
  421. if ($c->min_hours < 1 || $c->min_hours == "") {
  422. $c->load_descriptive_data(); // make sure we get hour data for this course.
  423. }
  424. if ($c->repeat_hours <= $c->min_hours)
  425. {
  426. // No repeats.
  427. $this->mark_repeats_exclude($c, $degree_id);
  428. return false;
  429. } else {
  430. // Repeats allowed, so just continue.
  431. continue;
  432. }
  433. } // if bool_mark_repeats_exclude == true
  434. else {
  435. // We did NOT meet the min_grade requirement!
  436. $c = FALSE;
  437. continue;
  438. }
  439. } // course did NOT meet the min_grade requirement
  440. else {
  441. // The course DID meet the min grade requirement.
  442. // Are we supposed to exclude repeats?
  443. if ($bool_mark_repeats_exclude) {
  444. // Make sure the course isn't allowed to be repeated...
  445. if ($c->repeat_hours <= $c->min_hours) {
  446. // No repeats allowed.
  447. $this->mark_repeats_exclude($c, $degree_id, $c);
  448. }
  449. }
  450. }
  451. // At this point, we are going to invoke a hook, to give add-on modules
  452. // one last chance to "skip" the course or not.
  453. $bool_can_proceed = TRUE;
  454. $result = invoke_hook("courselist_find_match_allow_course", array($c, $course_c, $list_matches, $degree_id, $group_id));
  455. foreach ($result as $m => $val) {
  456. // If *any* module said FALSE, then we must skip this course and not assign it to this degree.
  457. if ($val === FALSE) $bool_can_proceed = $val;
  458. }
  459. if (!$bool_can_proceed) {
  460. continue;
  461. }
  462. return $c;
  463. } // while
  464. return FALSE;
  465. } // find_best_grade_match
  466. /**
  467. * Sorts best-grade-first, as defined by the setting "grade_order", which is a CSV of
  468. * grades, best-first. Ex: A, B, C, D, F
  469. *
  470. * If the student object is set to a student, we will use that's student's best grade for a course, rather
  471. * than the actual course's grade. Generally, this can be left as set to null. This is only for when we are
  472. * trying to organize a list of courses into the grade order, based on what a student has taken. For example, if we want
  473. * to order a Group's list of courses based on what the student has taken and the grades they made.
  474. *
  475. */
  476. function sort_best_grade_first(Student $student = NULL) {
  477. $temp = csv_to_array(variable_get("grade_order", "AMID,BMID,CMID,DMID,FMID,A,B,C,D,F,W,I"));
  478. // We will use array_flip to get back an assoc array where the grades are the keys and the indexes are the values.
  479. $temp = array_flip($temp);
  480. // Go through the grades and convert the integers to strings, padd with zeros so that everything is at least 3 digits.
  481. $grades = array();
  482. foreach ($temp as $grade => $val) {
  483. $grades[$grade] = str_pad((string)$val, 3, "0", STR_PAD_LEFT);
  484. }
  485. // We now have our grades array just how we want it. Best grade has lowest value. Worst grade has highest value.
  486. $unknown_grade_value = 999; // sort to the very end, in other words.
  487. $student_grade_score = 0;
  488. // We are going to go through our courses and, based on the grade, assign them a value.
  489. $tarray = array();
  490. for ($t = 0; $t < $this->count; $t++) {
  491. // $t is the index for the array_list, keep in mind.
  492. $c = $this->array_list[$t];
  493. $use_grade = $c->grade;
  494. if ($student != null) {
  495. $use_grade = $student->get_best_grade_for_course($c);
  496. if (!$use_grade) $use_grade = "";
  497. }
  498. @$grade_value = $grades[$use_grade];
  499. if ($grade_value == "") {
  500. // Couldn't find this grade in our array, so give it the unknown value.
  501. $grade_value = $unknown_grade_value;
  502. }
  503. $student_grade_score += intval($grade_value);
  504. // Add to a string in array so we can sort easily using a normal sort operation.
  505. $tarray[$grade_value][] = $c;
  506. }
  507. // Sort best-grade-first:
  508. ksort($tarray,SORT_NUMERIC);
  509. // Okay, now go back through tarray and re-construct a new CourseList
  510. $new_list = new CourseList();
  511. foreach ($tarray as $per_grade_courses) {
  512. foreach ($per_grade_courses as $course) {
  513. $new_list->add($course);
  514. }
  515. }
  516. // Okay, now $new_list should contain the correct values.
  517. // We will transfer over the reference.
  518. $this->array_list = $new_list->array_list;
  519. // And we are done!
  520. if ($student != NULL) {
  521. // Return the "student grade score" for this list of courses.
  522. return $student_grade_score;
  523. }
  524. }
  525. /**
  526. * This is the original sort_best_grade_first method, replaced by the new one (modified by Logan Buth) on 3-29-2018)
  527. */
  528. function z____sort_best_grade_first(Student $student = NULL) {
  529. $temp = csv_to_array(variable_get("grade_order", "AMID,BMID,CMID,DMID,FMID,A,B,C,D,F,W,I"));
  530. // We will use array_flip to get back an assoc array where the grades are the keys and the indexes are the values.
  531. $temp = array_flip($temp);
  532. // Go through the grades and convert the integers to strings, padd with zeros so that everything is at least 3 digits.
  533. $grades = array();
  534. foreach ($temp as $grade => $val) {
  535. $grades[$grade] = str_pad((string)$val, 3, "0", STR_PAD_LEFT);
  536. }
  537. // We now have our grades array just how we want it. Best grade has lowest value. Worst grade has highest value.
  538. $unknown_grade_value = "999"; // sort to the very end, in other words.
  539. $student_grade_score = 0;
  540. // We are going to go through our courses and, based on the grade, assign them a value.
  541. $tarray = array();
  542. for ($t = 0; $t < $this->count; $t++) {
  543. // $t is the index for the array_list, keep in mind.
  544. $c = $this->array_list[$t];
  545. $use_grade = $c->grade;
  546. if ($student != null) {
  547. $use_grade = $student->get_best_grade_for_course($c);
  548. if (!$use_grade) $use_grade = "";
  549. }
  550. @$grade_value = $grades[$use_grade];
  551. if ($grade_value == "") {
  552. // Couldn't find this grade in our array, so give it the unknown value.
  553. $grade_value = $unknown_grade_value;
  554. }
  555. $student_grade_score += intval($grade_value);
  556. // Add to a string in array so we can sort easily using a normal sort operation.
  557. $tarray[] = "$grade_value ~~ $t";
  558. }
  559. // Sort best-grade-first:
  560. sort($tarray);
  561. // Okay, now go back through tarray and re-construct a new CourseList
  562. $new_list = new CourseList();
  563. for($t = 0; $t < count($tarray); $t++)
  564. {
  565. $temp = explode(" ~~ ",$tarray[$t]);
  566. $i = $temp[1];
  567. $new_list->add($this->array_list[$i]);
  568. }
  569. // Okay, now $new_list should contain the correct values.
  570. // We will transfer over the reference.
  571. $this->array_list = $new_list->array_list;
  572. // And we are done!
  573. if ($student != NULL) {
  574. // Return the "student grade score" for this list of courses.
  575. return $student_grade_score;
  576. }
  577. }
  578. /**
  579. * Remove courses from THIS list which appear in listCourses under
  580. * these conditions:
  581. * - the listCourses->"assigned_to_group_id" != $group_id
  582. * This function is being used primarily with $list_courses being the
  583. * list of courses that students have taken.
  584. * Also checking substitutions for courses substituted into groups.
  585. * @param CourseList $list_courses
  586. * @param int $group_id
  587. * @param bool $bool_keep_repeatable_courses
  588. * @param SubstitutionList $list_substitutions
  589. * @param $degree_id The degree id to look for. If it's -1, then ignore it. If it's 0, use the course's req_by_degree_id.
  590. */
  591. function remove_previously_fulfilled(CourseList $list_courses, $group_id, $bool_keep_repeatable_courses = true, $list_substitutions, $degree_id = 0)
  592. {
  593. $rtn_list = new CourseList();
  594. for ($t = 0; $t < $this->count; $t++)
  595. {
  596. $course = $this->array_list[$t];
  597. if ($bool_keep_repeatable_courses == true)
  598. { // We can always keep repeatable courses in the list.
  599. if ($course->repeat_hours > $course->min_hours)
  600. {
  601. $rtn_list->add($course);
  602. continue;
  603. }
  604. }
  605. // Has the course been substituted?
  606. if ($test_sub = $list_substitutions->find_requirement($course, false, -1))
  607. {
  608. // it WAS substituted, so we should NOT add it to our
  609. // rtnList.
  610. // We should only skip it if the test_sub's degree_id matches the one supplied...
  611. if ($degree_id >= 0) {
  612. if ($test_sub->assigned_to_degree_id == $degree_id) {
  613. continue;
  614. }
  615. }
  616. else if ($degree_id < 0) {
  617. // degree_id is -1, so we don't care what degree it was assigned to.
  618. continue;
  619. }
  620. }
  621. // Okay, now check if $course is anywhere in $list_courses
  622. //if ($test_course = $list_courses->find_match($course))
  623. // Instead of using simply find_match(), which does not allow for any hook interventions, switch to using find_best_match.
  624. // Thanks for Logan Buth for this.
  625. if ($test_course = $list_courses->find_best_match($course, '', FALSE, $degree_id, TRUE, FALSE, $group_id))
  626. {
  627. // Yes, it found a match.
  628. // I am taking out this part where I say if it is in
  629. // this group then we can keep it. I think that shouldn't
  630. // be in.
  631. // This course is in another group, so do nothing
  632. // and skip it.
  633. // perhaps the course is on the degreePlan in excess with a W
  634. // or F?
  635. if (!$test_course->meets_min_grade_requirement_of(null, "D"))
  636. {
  637. // Meaning, this was a failed attempt, so we can add
  638. // our original course back in.
  639. $rtn_list->add($course);
  640. continue;
  641. }
  642. // perhaps this course was purposefully excluded from
  643. // this list because it did not meet the min grade
  644. // requirements? If this is the case, $course should
  645. // still appear in THIS list.
  646. if (!$test_course->meets_min_grade_requirement_of($course))
  647. {
  648. // Meaning, this was attempt did not meet the
  649. // min grade of the original requirement, so we can add
  650. // our original requirement back in.
  651. $rtn_list->add($course);
  652. continue;
  653. }
  654. } else {
  655. // The course was NOT found in the courseList,
  656. // so its safe to add it back in.
  657. $rtn_list->add($course);
  658. }
  659. }
  660. $this->array_list = $rtn_list->array_list;
  661. $this->reset_counter();
  662. }
  663. /**
  664. * Return an array of all the course_id's in this course_list.
  665. */
  666. function get_course_id_array() {
  667. $rtn = array();
  668. for ($t = 0; $t < $this->count; $t++)
  669. {
  670. $course = $this->array_list[$t];
  671. $rtn[$course->course_id] = TRUE;
  672. }
  673. return $rtn;
  674. }
  675. /**
  676. * Returns an array containing the unique subject_id's of
  677. * the courses in this list. Its assumed to be ordered
  678. * already!
  679. *
  680. * @param bool $bool_ignore_excluded
  681. * @return array
  682. */
  683. function get_course_subjects($bool_ignore_excluded = true)
  684. {
  685. // returns an array containing the unique subject_id's
  686. // of the courses in this list.
  687. // IMPORTANT: The list is assumed to be ordered already! Either
  688. // alphabetically or reverse alphabetically.
  689. $old_subject_id = "";
  690. $rtn_array = array();
  691. for ($t = 0; $t < $this->count; $t++)
  692. {
  693. $course = $this->array_list[$t];
  694. if ($course->subject_id == "")
  695. {
  696. $course->load_descriptive_data();
  697. }
  698. // Go through all valid names for this course.
  699. for ($x = 0; $x < count($course->array_valid_names); $x++)
  700. {
  701. $temp = explode("~",$course->array_valid_names[$x]);
  702. $subj = strtoupper($temp[0]);
  703. if (in_array($subj, $rtn_array))
  704. { // skip ones with subjects we have already looked at.
  705. continue;
  706. }
  707. if ($course->db_exclude == 1)
  708. {
  709. continue;
  710. }
  711. // We have a new subject. Add it to the array.
  712. $rtn_array[] = $subj;
  713. }
  714. }
  715. return $rtn_array;
  716. }
  717. /**
  718. * Go through the courseList and take out any course
  719. * which does not have the $subject as its subject_id.
  720. *
  721. * @param string $subject
  722. * @param bool $bool_reassign_valid_name
  723. * - If set to TRUE, we will look at other possible valid names
  724. * for this course. If we find one, we will reassign the course's
  725. * subject_id and course_num to the new valid name.
  726. *
  727. */
  728. function exclude_all_subjects_except($subject, $bool_reassign_valid_name = true)
  729. {
  730. $new_course_list = new CourseList();
  731. for ($t = 0; $t < $this->count; $t++)
  732. {
  733. $course = $this->array_list[$t];
  734. if ($course->subject_id == $subject)
  735. {
  736. $new_course_list->add($course);
  737. continue;
  738. }
  739. // Not the right subject-- but perhaps the course has another
  740. // valid name with this subject? Ex: CSCI 373 and MATH 373.
  741. if ($bool_reassign_valid_name == true && count($course->array_valid_names) > 1)
  742. {
  743. for ($x = 0; $x < count($course->array_valid_names); $x++)
  744. {
  745. if (strstr($course->array_valid_names[$x], $subject))
  746. {
  747. $temp = explode("~",$course->array_valid_names[$x]);
  748. $course->subject_id = $temp[0];
  749. $course->course_num = $temp[1];
  750. $new_course_list->add($course);
  751. continue;
  752. }
  753. }
  754. }
  755. }
  756. // Now, transfer ownership of the arraylist.
  757. $this->array_list = $new_course_list->array_list;
  758. }
  759. /**
  760. * This re-sorts the CourseList so that fulfilled courses
  761. * are first, in alphabetical order, followed by
  762. * unfulfilled courses, in alphabetical order.
  763. * This is most useful for making the groups
  764. * show up correctly.
  765. *
  766. */
  767. function sort_fulfilled_first_alphabetical()
  768. {
  769. $tarray = array();
  770. for ($t = 0; $t < $this->count; $t++)
  771. {
  772. //if (!is_object($this->array_list[$t]->courseFulfilledBy))
  773. if ($this->array_list[$t]->course_list_fulfilled_by->is_empty == true)
  774. { // Skip if not fulfilled.
  775. continue;
  776. }
  777. $c = $this->array_list[$t];
  778. $str = "$c->subject_id ~~ $c->course_num ~~ $t";
  779. array_push($tarray,$str);
  780. }
  781. sort($tarray);
  782. $new_list = new CourseList();
  783. for($t = 0; $t < count($tarray); $t++)
  784. {
  785. $temp = explode(" ~~ ",$tarray[$t]);
  786. $i = $temp[2];
  787. $new_list->add($this->array_list[$i]);
  788. }
  789. // Alright, now we do it again, but with unfulfilled courses.
  790. $tarray = array();
  791. for ($t = 0; $t < $this->count; $t++)
  792. {
  793. //if (is_object($this->array_list[$t]->courseFulfilledBy))
  794. if ($this->array_list[$t]->course_list_fulfilled_by->is_empty != true)
  795. { // Skip if fulfilled.
  796. continue;
  797. }
  798. $c = $this->array_list[$t];
  799. $str = "$c->subject_id ~~ $c->course_num ~~ $t";
  800. array_push($tarray,$str);
  801. }
  802. sort($tarray);
  803. $new_list2 = new CourseList();
  804. for($t = 0; $t < count($tarray); $t++)
  805. {
  806. $temp = explode(" ~~ ",$tarray[$t]);
  807. $i = $temp[2];
  808. $new_list2->add($this->array_list[$i]);
  809. }
  810. // Now, combine the two lists.
  811. $new_list->add_list($new_list2);
  812. // And, transfer the newList into this list.
  813. $this->array_list = $new_list->array_list;
  814. }
  815. /**
  816. * This re-sorts the CourseList so that advised courses
  817. * are last, in alphabetical order, preceeded by
  818. * unfulfilled courses, in alphabetical order.
  819. *
  820. *
  821. */
  822. function sort_advised_last_alphabetical()
  823. {
  824. $tarray = array();
  825. for ($t = 0; $t < $this->count; $t++)
  826. {
  827. if ($this->array_list[$t]->bool_advised_to_take == true)
  828. { // Skip if not fulfilled.
  829. continue;
  830. }
  831. $c = $this->array_list[$t];
  832. $str = "$c->subject_id ~~ $c->course_num ~~ $t";
  833. array_push($tarray,$str);
  834. }
  835. sort($tarray);
  836. // Alright, now we do it again, but with advised courses.
  837. $t2array = array();
  838. for ($t = 0; $t < $this->count; $t++)
  839. {
  840. if ($this->array_list[$t]->bool_advised_to_take == false)
  841. { // Skip if not advised
  842. continue;
  843. }
  844. $c = $this->array_list[$t];
  845. $str = "$c->subject_id ~~ $c->course_num ~~ $t";
  846. array_push($t2array,$str);
  847. }
  848. sort($t2array);
  849. $t3array = array_merge($tarray, $t2array);
  850. $new_list = new CourseList();
  851. for($t = 0; $t < count($t3array); $t++)
  852. {
  853. $temp = explode(" ~~ ",$t3array[$t]);
  854. $i = $temp[2];
  855. $new_list->add($this->array_list[$i]);
  856. }
  857. // And, transfer the newList into this list.
  858. $this->array_list = $new_list->array_list;
  859. }
  860. /**
  861. * This function will resort this courselist for which a substitution
  862. * has been made in listSubstitutions.
  863. *
  864. * @param SubstitutionList $list_substitutions
  865. * @param int $group_id
  866. */
  867. function sort_substitutions_first($list_substitutions, $group_id = 0)
  868. {
  869. // This will sort courses in a list for which
  870. // a substitution has been made in listSubstitutions.
  871. // It will place those courses at the top of the list.
  872. $top_array = array();
  873. // Since I need the indexes, I will have to go through the array
  874. // myself...
  875. // array to keep track of all the substitutions that have been used for this list (Logan's change ticket 2291)
  876. $used_substitution_ids = array();
  877. for ($t = 0; $t < $this->count; $t++) {
  878. $c = $this->array_list[$t];
  879. // So-- does this course have a substitution somewhere in
  880. // the list (for the supplied groupID) ?
  881. // supply the list of used ids, so they are not reused in this list. (Logan's change ticket 2291)
  882. if ($substitution = $list_substitutions->find_requirement($c, true, $group_id,0,$used_substitution_ids))
  883. {
  884. // yes, there is a sub for this group (or bare degree plan)
  885. //mark the substitution so it doesn't get used again (Logan's change ticket 2291)
  886. $used_substitution_ids[] = $substitution->db_substitution_id;
  887. $top_array[] = $t;
  888. }
  889. }
  890. // Okay, we now have, in the topArray, a list of indexes which should
  891. // appear at the top.
  892. $new_list = new CourseList();
  893. for ($j = 0; $j < count($top_array); $j++)
  894. {
  895. $new_list->add($this->array_list[$top_array[$j]]);
  896. }
  897. // Now, add everything else in the array (except indecies
  898. // appearing in topArray)
  899. for ($t = 0; $t < $this->count; $t++)
  900. {
  901. if (in_array($t, $top_array))
  902. {
  903. continue;
  904. }
  905. $new_list->add($this->array_list[$t]);
  906. }
  907. $this->array_list = $new_list->array_list;
  908. $new_list->reset_counter();
  909. }
  910. /**
  911. * This will sort so that courses with the smallest hours
  912. * (first trying hours_awarded, then min_hours)
  913. * are at the top of the list. If the list contains more
  914. * than one course with a set of hours (like there are 30
  915. * courses all worth 3 hours) then it orders those as
  916. * most-recently-taken first.
  917. *
  918. */
  919. function sort_smallest_hours_first()
  920. {
  921. $tarray = array();
  922. // Since I need the indexes, I will have to go through the array
  923. // myself...
  924. for ($t = 0; $t < $this->count; $t++)
  925. {
  926. $c = $this->array_list[$t];
  927. $hours = $c->get_hours_awarded();
  928. if ($hours < 1)
  929. {
  930. $hours = $c->min_hours*1;
  931. }
  932. $str = "$hours ~~ $t";
  933. array_push($tarray,$str);
  934. }
  935. // Now, sort the array...
  936. //print_pre(print_r($tarray));
  937. sort($tarray);
  938. //print_pre(print_r($tarray));
  939. // Now, convert the array back into a list of courses.
  940. $new_list = new CourseList();
  941. for($t = 0; $t < count($tarray); $t++)
  942. {
  943. $temp = explode(" ~~ ",$tarray[$t]);
  944. $i = $temp[1];
  945. $new_list->add($this->array_list[$i]);
  946. }
  947. // Okay, now $new_list should contain the correct values.
  948. // We will transfer over the reference.
  949. $this->array_list = $new_list->array_list;
  950. } // sort_smallest_hours_first
  951. /*
  952. * Sort the courses of this list by number of hours descending.
  953. * Order of courses with the same number of hours is preserved.
  954. */
  955. function sort_largest_hours_first() {
  956. $sort_list = array();
  957. // go through the courses, creating an array keyed by hours.
  958. for ($t = 0; $t < count($this->array_list); $t++) {
  959. $hrs = $this->array_list[$t]->get_hours();
  960. if ($this->array_list[$t]->bool_ghost_hour) $hrs = 0;
  961. $sort_list[$hrs][] = $this->array_list[$t];
  962. }
  963. //sort the array in order of hours descending
  964. krsort($sort_list,SORT_NUMERIC);
  965. //clear the internal array, then refill it with the now sorted courses.
  966. $this->array_list = array();
  967. foreach ($sort_list as $courses) {
  968. foreach ($courses as $course) {
  969. $this->array_list[] = $course;
  970. }
  971. }
  972. $this->reset_counter();
  973. }
  974. /**
  975. * This method will sort by the most recently taken
  976. * courses (determined by the term_id).
  977. * The easiest way I can think to do this is to temporarily
  978. * put their term_id's and index#'s into an array, and then
  979. * have PHP sort the array itself. PHP's sorting algorithm
  980. * is faster than anything I can program right now, anyway.
  981. *
  982. * @param bool $bool_maintain_alpha_order
  983. */
  984. function sort_most_recent_first($bool_maintain_alpha_order = true)
  985. {
  986. $tarray = array();
  987. // Since I need the indexes, I will have to go through the array
  988. // myself...
  989. for ($t = 0; $t < $this->count; $t++)
  990. {
  991. $c = $this->array_list[$t];
  992. $cn = "";
  993. if ($bool_maintain_alpha_order == true)
  994. {
  995. // We say 1000- the course number in order to give
  996. // us the complement of the number. That is so it will
  997. // reverse-sort in the correct order. Strange, but it fixes
  998. // a small display issue where PHYS 207 and PHYS 209, taken at
  999. // the same time, causes PHYS 209 to be displayed first.
  1000. // We also reverse the subject_id, again, so that
  1001. // MATH will be sorted above ZOOL, when taken at the same time.
  1002. // This might not work at all, though...
  1003. // TODO: The 1000 - course_num bit doesn't work (throws a warning) if the course_num
  1004. // is non-numeric. Ex: 301A. Let's instead use the same strrev() function on course_num, but we put it in quotes
  1005. // to guarantee it gets evaluated as a string.
  1006. //$cn = strrev($c->subject_id) . "," . (1000 - $c->course_num);
  1007. $cn = strrev($c->subject_id) . "," . strrev("$c->course_num");
  1008. }
  1009. $str = "$c->term_id ~~ $cn ~~ $t";
  1010. array_push($tarray,$str);
  1011. }
  1012. // Now, sort the array...
  1013. rsort($tarray);
  1014. // Now, convert the array back into a list of courses.
  1015. $new_list = new CourseList();
  1016. for($t = 0; $t < count($tarray); $t++)
  1017. {
  1018. $temp = explode(" ~~ ",$tarray[$t]);
  1019. $i = $temp[2];
  1020. $new_list->add($this->array_list[$i]);
  1021. }
  1022. // Okay, now $new_list should contain the correct values.
  1023. // We will transfer over the reference.
  1024. $this->array_list = $new_list->array_list;
  1025. }
  1026. /**
  1027. * Convienence function. It simply calls sort_alphabetical_order(), but
  1028. * passes the boolean value to make it be reversed.
  1029. *
  1030. */
  1031. function sort_reverse_alphabetical_order()
  1032. {
  1033. $this->sort_alphabetical_order(true);
  1034. }
  1035. /**
  1036. * Sorts the course list into alphabetical order. If load_descriptive_data()
  1037. * has not already been called for each course, it will call it.
  1038. *
  1039. * @param bool $bool_reverse_order
  1040. * - If set to TRUE, the list will be in reverse order.
  1041. *
  1042. * @param unknown_type $bool_only_transfers
  1043. * - Only sort the transfer courses.
  1044. *
  1045. * @param unknown_type $bool_set_array_index
  1046. * - If set to true, it will set the $course->array_index value
  1047. * to the index value in $this's array_list array.
  1048. * @param new_split_subs_higher_priority_in_degree_id
  1049. * - If the course is a split substitution for the supplied degree_id, then give it a higher "priority" so it will
  1050. * sort above courses with identical names.
  1051. *
  1052. */
  1053. function sort_alphabetical_order($bool_reverse_order = false, $bool_only_transfers = false, $bool_set_array_index = false, $subs_higher_prority_in_degree_id = 0, $bool_include_degree_sort = FALSE)
  1054. {
  1055. // Sort the list into alphabetical order, based
  1056. // on the subject_id and course_num.
  1057. $tarray = array();
  1058. // Since I need the indexes, I will have to go through the array
  1059. // myself...
  1060. for ($t = 0; $t < $this->count; $t++)
  1061. {
  1062. $c = $this->array_list[$t];
  1063. if ($c->subject_id == "")
  1064. {
  1065. $c->load_descriptive_data();
  1066. }
  1067. $priority = 5; // default sort priority for courses with identical names.
  1068. if ($subs_higher_prority_in_degree_id > 0) {
  1069. if (@$c->details_by_degree_array[$subs_higher_prority_in_degree_id]["bool_substitution_new_from_split"] == TRUE
  1070. || @$c->details_by_degree_array[$subs_higher_prority_in_degree_id]["bool_substitution_split"] == TRUE
  1071. || @$c->details_by_degree_array[$subs_higher_prority_in_degree_id]["bool_substitution"] == TRUE) {
  1072. //fpm("here for $c->subject_id $c->course_num");
  1073. $priority = 3; // lower priority so it sorts higher in the list.
  1074. }
  1075. }
  1076. // Make $t at least 5 characters long, padded with zeroes on the left, so sorting works correctly. We are using it to
  1077. // find out our index later, but it is throwing off the sorting when courses have the same name. For example,
  1078. // if a course is from a split sub.
  1079. $tpad = str_pad("$t",5,"0",STR_PAD_LEFT);
  1080. $degree_title = "n"; // Default.
  1081. $degree_advising_weight = "0000";
  1082. if ($bool_include_degree_sort) {
  1083. // Find the actual degree title for this course.
  1084. if (intval($c->req_by_degree_id) > 0) {
  1085. // Get the degree title...
  1086. $dtitle = @$GLOBALS["fp_temp_degree_titles"][$c->req_by_degree_id];
  1087. $dweight = intval(@$GLOBALS["fp_temp_degree_advising_weights"][$c->req_by_degree_id]);
  1088. if ($dtitle == "" || $dweight == "" || $dweight == 0) {
  1089. $t_degree_plan = new DegreePlan($c->req_by_degree_id);
  1090. $t_degree_plan->load_descriptive_data();
  1091. $dtitle = $t_degree_plan->get_title2(TRUE, TRUE);
  1092. $dweight = $t_degree_plan->db_advising_weight;
  1093. $GLOBALS["fp_temp_degree_titles"][$c->req_by_degree_id] = $dtitle . " "; //save for next time.
  1094. $GLOBALS["fp_temp_degree_advising_weights"][$c->req_by_degree_id] = $dweight . " "; //save for next time.
  1095. }
  1096. $degree_title = fp_get_machine_readable($dtitle); // make it machine readable. No funny characters.
  1097. $degree_advising_weight = str_pad($dweight, 4, "0", STR_PAD_LEFT);
  1098. }
  1099. }
  1100. if ($bool_only_transfers == true)
  1101. {
  1102. // Rarer. We only want to sort the transfer credits. If the course doesn not
  1103. // have transfers, don't skip, just put in the original. Otherwise, we will be using
  1104. // the transfer credit's SI and CN.
  1105. if (is_object($c->course_transfer))
  1106. {
  1107. $str = $degree_advising_weight . " ~~ " . $degree_title . " ~~ " . $c->course_transfer->subject_id . " ~~ " . $c->course_transfer->course_num ." ~~ $priority ~~ $tpad";
  1108. } else {
  1109. // There was no transfer!
  1110. $str = "$degree_advising_weight ~~ $degree_title ~~ $c->subject_id ~~ $c->course_num ~~ $priority ~~ $tpad";
  1111. }
  1112. } else {
  1113. // This is the one which will be run most often. Just sort the list
  1114. // in alphabetical order.
  1115. $str = "$degree_advising_weight ~~ $degree_title ~~ $c->subject_id ~~ $c->course_num ~~ $priority ~~ $tpad";
  1116. }
  1117. array_push($tarray,$str);
  1118. }
  1119. // Now, sort the array...
  1120. //print_pre(print_r($tarray));
  1121. if ($bool_reverse_order == true)
  1122. {
  1123. rsort($tarray);
  1124. } else {
  1125. sort($tarray);
  1126. }
  1127. //print_pre(print_r($tarray));
  1128. // Now, convert the array back into a list of courses.
  1129. $new_list = new CourseList();
  1130. for($t = 0; $t < count($tarray); $t++)
  1131. {
  1132. $temp = explode(" ~~ ",$tarray[$t]);
  1133. $i = intval($temp[5]);
  1134. if ($bool_set_array_index == true)
  1135. {
  1136. $this->array_list[$i]->array_index = $i;
  1137. }
  1138. $new_list->add($this->array_list[$i]);
  1139. }
  1140. // Okay, now $new_list should contain the correct values.
  1141. // We will transfer over the reference.
  1142. $this->array_list = $new_list->array_list;
  1143. }
  1144. /**
  1145. * Returns an array of db_group_requirement_id's from the courses
  1146. * in this list.
  1147. *
  1148. * @return array
  1149. */
  1150. function get_group_requirement_id_array()
  1151. {
  1152. // Return an array of db_group_requirement_id's
  1153. // from the courses in this list, indexed by the
  1154. // id's.
  1155. $rtn_array = array();
  1156. for ($t = 0; $t < $this->count; $t++)
  1157. {
  1158. $course = $this->array_list[$t];
  1159. $rtn_array[$course->db_group_requirement_id] = true;
  1160. }
  1161. return $rtn_array;
  1162. }
  1163. /**
  1164. * Returns TRUE if this list has a course which contains
  1165. * $id for it's db_group_requirement_id property.
  1166. *
  1167. * @param int $id
  1168. * - This is the id to test for.
  1169. *
  1170. * @return bool
  1171. */
  1172. function contains_group_requirement_id($id)
  1173. {
  1174. // Returns true if the list has a course
  1175. // which contains $id for it's db_group_requirement_id.
  1176. // False if it cannot be found.
  1177. for ($t = 0; $t < $this->count; $t++)
  1178. {
  1179. $course = $this->array_list[$t];
  1180. if ($course->db_group_requirement_id == $id)
  1181. {
  1182. return true;
  1183. }
  1184. }
  1185. return false;
  1186. }
  1187. /**
  1188. * Returns the first course in the list
  1189. * which the user may select for advising. This
  1190. * method is used by the popup window to determine
  1191. * what exactly is the first element of the course list.
  1192. * (so it can make that radio button checked).
  1193. *
  1194. * Returns FALSE if it cannot find a selectable course.
  1195. *
  1196. * @return Course
  1197. */
  1198. function find_first_selectable()
  1199. {
  1200. /*
  1201. */
  1202. $temp_i = $this->i; // preserve the counter.
  1203. $this->reset_counter();
  1204. while($this->has_more())
  1205. {
  1206. $c = $this->get_next();
  1207. if ($c->bool_advised_to_take == true)
  1208. {
  1209. continue;
  1210. }
  1211. if (!$c->course_list_fulfilled_by->is_empty)
  1212. {
  1213. continue;
  1214. }
  1215. if ($c->bool_unselectable == true)
  1216. {
  1217. continue;
  1218. }
  1219. // $c is our valid course...
  1220. $this->i = $temp_i;
  1221. //print_pre($c->to_string());
  1222. return $c;
  1223. }
  1224. $this->i = $temp_i;
  1225. return false;
  1226. }
  1227. /**
  1228. * Returns TRUE if there is at least one course in this list which
  1229. * is selected (for advising).
  1230. *
  1231. * @return bool
  1232. */
  1233. function has_any_course_selected()
  1234. {
  1235. /*
  1236. Returns TRUE if there is at least one course
  1237. in this list which is "selected." FALSE, otherwise.
  1238. */
  1239. $temp_i = $this->i; // preserve the counter.
  1240. $this->reset_counter();
  1241. $rtn = false;
  1242. while($this->has_more())
  1243. {
  1244. $c = $this->get_next();
  1245. if ($c->bool_selected == true)
  1246. {
  1247. $rtn = true;
  1248. break;
  1249. }
  1250. }
  1251. $this->i = $temp_i;
  1252. return $rtn;
  1253. }
  1254. /**
  1255. * Mark every course in this list as bool_has_been_displayed = true.
  1256. * Used for making sure we don't display the same course twice on
  1257. * screen.
  1258. *
  1259. * Returns FALSE if we did not mark any courses.
  1260. *
  1261. * @param int $semester_num
  1262. * - If > -1, we will first make sure the course
  1263. * falls into this semesterNum. This way we can only
  1264. * perform this operation on a particular semester.
  1265. *
  1266. * @return bool
  1267. */
  1268. function mark_as_displayed($semester_num = -1)
  1269. {
  1270. $temp_i = $this->i; // preserve the counter.
  1271. $this->reset_counter();
  1272. $rtn = false;
  1273. while($this->has_more())
  1274. {
  1275. $c = $this->get_next();
  1276. if ($semester_num != -1)
  1277. { // A semesterNum was specified.
  1278. // Make sure the course is in the correct semester.
  1279. if ($c->assigned_to_semester_num != $semester_num)
  1280. {
  1281. continue;
  1282. }
  1283. }
  1284. $c->bool_has_been_displayed = true;
  1285. $rtn = true;
  1286. }
  1287. $this->i = $temp_i;
  1288. return $rtn;
  1289. }
  1290. /**
  1291. * Returns a CourseList of all the courses matching course_id
  1292. * that has bool_has_been_assigned == TRUE for the requested degree
  1293. *
  1294. * @param int $course_id
  1295. * @return CourseList
  1296. */
  1297. function get_previous_assignments($course_id, $degree_id = 0)
  1298. {
  1299. // Return a courseList of all the times a course matching
  1300. // course_id has the bool_has_been_assigned set to TRUE.
  1301. $rtn_list = new CourseList();
  1302. for ($t = 0; $t < $this->count; $t++)
  1303. {
  1304. $course = $this->array_list[$t];
  1305. if ($course->course_id == $course_id && $course->get_has_been_assigned_to_degree_id($degree_id) == true)
  1306. {
  1307. $rtn_list->add($course);
  1308. }
  1309. }
  1310. return $rtn_list;
  1311. }
  1312. /**
  1313. * Find the "best" match for this course, based on what
  1314. * the university considers a best match.
  1315. * This largely has to do with repeats.
  1316. * If the student has more than one credit, what is
  1317. * the "best" match?
  1318. *
  1319. * For example, at ULM we consider the best match to be the
  1320. * most recent that meets the minimum requirements.
  1321. * Other schools might simply take the best grade.
  1322. *
  1323. *
  1324. * @return Course
  1325. */
  1326. function find_best_match(Course $course_c, $min_grade = "", $bool_mark_repeats_exclude = false, $degree_id = 0, $bool_skip_already_assigned_to_degree = TRUE, $bool_skip_subs = FALSE, $group_id = 0)
  1327. {
  1328. $rtn = FALSE;
  1329. // We will look at the course_repeat_policy to determine which type of search to do on this list.
  1330. $course_repeat_policy = variable_get("course_repeat_policy", "most_recent_exclude_previous");
  1331. if ($course_repeat_policy == "best_grade_exclude_others") {
  1332. // Search for best grade, exclude other attempts.
  1333. $rtn = $this->find_best_grade_match($course_c, $min_grade, TRUE, $degree_id, $bool_skip_already_assigned_to_degree, $bool_skip_subs, $group_id);
  1334. }
  1335. else {
  1336. // Search for most recent first, possibly mark previous as excluded.
  1337. $rtn = $this->find_most_recent_match($course_c, $min_grade, $bool_mark_repeats_exclude, $degree_id, $bool_skip_already_assigned_to_degree, $bool_skip_subs, $group_id);
  1338. }
  1339. return $rtn;
  1340. }
  1341. /**
  1342. * Adds the supplied CourseList to the bottom of $this's list.
  1343. *
  1344. * @param CourseList $course_l
  1345. */
  1346. function add_list(CourseList $course_l) {
  1347. $c = count($course_l->array_list);
  1348. for ($t = 0; $t < $c; $t++)
  1349. {
  1350. $this->add($course_l->array_list[$t]);
  1351. }
  1352. }
  1353. /**
  1354. * Returns hour many hours are in $this CourseList.
  1355. *
  1356. * @param string $requirement_type
  1357. * - If specified, we will only count courses which match this
  1358. * requirement_type.
  1359. *
  1360. * @param bool $bool_use_ignore_list
  1361. * @return int
  1362. */
  1363. function count_hours($requirement_type = "", $bool_use_ignore_list = false, $bool_correct_ghost_hour = true, $bool_force_zero_hours_to_one_hour = false, $bool_exclude_all_transfer_credits = FALSE, $degree_id = 0)
  1364. {
  1365. // Returns how many hours are being represented in this courseList.
  1366. // A requirement type of "uc" is the same as "c"
  1367. // (university capstone is a core requirement)
  1368. $count = 0;
  1369. for ($t = 0; $t < $this->count; $t++)
  1370. {
  1371. $course = $this->array_list[$t];
  1372. // Does this course belong to the same degree we are interested in? If not, skip it.
  1373. if ($degree_id > 0) {
  1374. if ($course->req_by_degree_id != $degree_id && $course->get_has_been_assigned_to_degree_id($degree_id) != TRUE) continue;
  1375. }
  1376. if ($bool_use_ignore_list == true)
  1377. {
  1378. // Do ignore some courses...
  1379. $temp_course_name = $course->subject_id . " " . $course->course_num;
  1380. // Check in our settings to see if we should ignore this course
  1381. // (configured in /custom/settings.php)
  1382. if (in_array($temp_course_name, csv_to_array(@$GLOBALS["fp_system_settings"]["ignore_courses_from_hour_counts"]))) {
  1383. continue;
  1384. }
  1385. // Also, if the course's requirement_type is "x" it means we should ignore it.
  1386. if ($course->requirement_type == 'x') continue;
  1387. }
  1388. if ($course->get_bool_substitution_new_from_split($degree_id) == TRUE)
  1389. {
  1390. // Do not count the possible fragments that are created
  1391. // from a new substitution split. This is causing problems
  1392. // in getting accurate numbers on the pie charts.
  1393. // BUT-- only skip if this new fragment isn't also being
  1394. // substituted somewhere else!
  1395. if ($course->get_bool_substitution($degree_id) == FALSE)
  1396. { // not being used in another sub, so skip it.
  1397. continue;
  1398. }
  1399. }
  1400. $h_get_hours = $course->get_hours($degree_id);
  1401. if ($bool_correct_ghost_hour) {
  1402. // If this course has a ghosthour, then use the
  1403. // hours_awarded (probably 1). However, if it was substituted,
  1404. // then we actually want the 0 hour. Confusing, isn't it?
  1405. if ($course->bool_ghost_hour) {
  1406. $h_get_hours = $course->get_hours_awarded($degree_id);
  1407. }
  1408. }
  1409. if ($bool_force_zero_hours_to_one_hour) {
  1410. // We want to force anything with a 0 hour to be 1 hour.
  1411. // Helps when selecting 0 hour courses from groups.
  1412. if ($h_get_hours == 0) {
  1413. $h_get_hours = 1;
  1414. }
  1415. }
  1416. // Make sure we aren't trying to exclude any transfer credits.
  1417. if ($bool_exclude_all_transfer_credits) {
  1418. if ($course->bool_transfer) {
  1419. continue;
  1420. }
  1421. // Is this a requirement which has been fulfilled by a course? And if so, is THAT course a transfer?
  1422. if ($course->course_list_fulfilled_by->is_empty == false) {
  1423. $cc = $course->course_list_fulfilled_by->get_first();
  1424. if ($cc->bool_transfer) {
  1425. continue;
  1426. }
  1427. }
  1428. }
  1429. if ($requirement_type == "")
  1430. {
  1431. $count = $count + $h_get_hours;
  1432. }
  1433. else {
  1434. // Requirement Type not blank, so only count these hours
  1435. // if it has the set requirement type.
  1436. if ($course->requirement_type == $requirement_type)
  1437. {
  1438. $count = $count + $h_get_hours;
  1439. continue;
  1440. }
  1441. // For specifically "university capstone" courses (which have a 'u' in front)...
  1442. if ($course->requirement_type == "u" . $requirement_type)
  1443. {
  1444. $count = $count + $h_get_hours;
  1445. }
  1446. }
  1447. }
  1448. return $count;
  1449. }
  1450. /**
  1451. * Removes courses which have neither been fulfilled or advised.
  1452. *
  1453. */
  1454. function remove_unfulfilled_and_unadvised_courses()
  1455. {
  1456. // remove courses from THIS list
  1457. // which have not been fulfilled AND
  1458. // are not currently advised.
  1459. $rtn_list = new CourseList();
  1460. for ($t = 0; $t < $this->count; $t++)
  1461. {
  1462. $course = $this->array_list[$t];
  1463. if ($course->course_list_fulfilled_by->is_empty == false)
  1464. {
  1465. // something IS fulfilling it!
  1466. $rtn_list->add($course);
  1467. } else if ($course->bool_advised_to_take == true)
  1468. {
  1469. // Was not being fulfilled, but, it was advised
  1470. // to take.
  1471. $rtn_list->add($course);
  1472. }
  1473. }
  1474. $this->array_list = $rtn_list->array_list;
  1475. $this->reset_counter();
  1476. }
  1477. /**
  1478. * Removes courses from this list which have not been fulfilled
  1479. * (ther course_list_fulfilled_by is empty).
  1480. *
  1481. */
  1482. function remove_unfulfilled_courses()
  1483. {
  1484. // remove courses in THIS list
  1485. // which have nothing in their course_list_fulfilled_by
  1486. // object.
  1487. $rtn_list = new CourseList();
  1488. for ($t = 0; $t < $this->count; $t++)
  1489. {
  1490. $course = $this->array_list[$t];
  1491. if ($course->course_list_fulfilled_by->is_empty == false)
  1492. {
  1493. $rtn_list->add($course);
  1494. }
  1495. }
  1496. $this->array_list = $rtn_list->array_list;
  1497. $this->reset_counter();
  1498. }
  1499. /**
  1500. * Returns a clone CourseList of $this.
  1501. *
  1502. * @param bool $bool_return_new_courses
  1503. * - If set to TRUE, it will create new Course objects
  1504. * based on the course_id's of the ones in $this's list.
  1505. * If set to FALSE, this will add the exact same Course
  1506. * objects by reference to the new list.
  1507. *
  1508. * @return CourseList
  1509. */
  1510. function get_clone($bool_return_new_courses = FALSE)
  1511. {
  1512. // This will return a clone of this list.
  1513. // If boolReturnNewCourses is true, then it will
  1514. // return a new list of new instances of courses
  1515. // from this list.
  1516. $rtn_list = new CourseList();
  1517. for ($t = 0; $t < $this->count; $t++)
  1518. {
  1519. $course = $this->array_list[$t];
  1520. if ($bool_return_new_courses)
  1521. {
  1522. $new_course = new Course();
  1523. $new_course->course_id = $course->course_id;
  1524. $rtn_list->add($new_course);
  1525. } else {
  1526. $rtn_list->add($course);
  1527. }
  1528. }
  1529. return $rtn_list;
  1530. }
  1531. /**
  1532. * Returns a CourseList of all the fulfilled or advised courses
  1533. * in $this's list.
  1534. *
  1535. * @param bool $bool_return_new_courses
  1536. * - Works the same as get_clone()'s boolReturnNewCourses
  1537. * variable.
  1538. *
  1539. * @return Course
  1540. */
  1541. function get_fulfilled_or_advised($bool_return_new_courses = false)
  1542. {
  1543. $rtn_list = new CourseList();
  1544. for ($t = 0; $t < $this->count; $t++)
  1545. {
  1546. $course = $this->array_list[$t];
  1547. $add_course = $course;
  1548. if ($bool_return_new_courses == true)
  1549. {
  1550. $add_course = new Course();
  1551. $add_course->course_id = $course->course_id;
  1552. }
  1553. if ($course->bool_advised_to_take == true)
  1554. {
  1555. $rtn_list->add($add_course);
  1556. }
  1557. // Several ways to tell if a course is here by credit...
  1558. if (!$course->course_list_fulfilled_by->is_empty) {
  1559. $rtn_list->add($add_course);
  1560. }
  1561. else if ($course->grade != "") {
  1562. $rtn_list->add($add_course);
  1563. }
  1564. else if ($course->get_bool_substitution() == true) {
  1565. $rtn_list->add($add_course);
  1566. }
  1567. }
  1568. return $rtn_list;
  1569. }
  1570. /**
  1571. * Returns the number of courses in this list which have either
  1572. * been fulfilled or advised to take. It does not count hours,
  1573. * just the courses themselves.
  1574. *
  1575. * @return int
  1576. */
  1577. function count_fulfilled_or_advised()
  1578. {
  1579. // This function returns the number of courses in this
  1580. // courseList which is either fulfilled or has been advised
  1581. // to take. It does care about hours, just the number of
  1582. // courses themselves.
  1583. $count = 0;
  1584. for ($t = 0; $t < $this->count; $t++)
  1585. {
  1586. $course = $this->array_list[$t];
  1587. if ($course->bool_advised_to_take == true)
  1588. {
  1589. $count++;
  1590. }
  1591. // Several ways to tell if a course is here by credit...
  1592. if (!$course->course_list_fulfilled_by->is_empty)
  1593. {
  1594. $count++;
  1595. } else if ($course->grade != "") {
  1596. $count++;
  1597. } else if ($course->bool_substitution == true)
  1598. {
  1599. $count++;
  1600. }
  1601. }
  1602. return $count;
  1603. }
  1604. /**
  1605. * Returns a CourseList of courses which have bool_advised_to_take == true.
  1606. *
  1607. * @return CourseList
  1608. */
  1609. function get_advised_courses_list()
  1610. {
  1611. // Return a courseList object of courses in THIS
  1612. // list which have bool_advised_to_take == true.
  1613. $rtn_list = new CourseList();
  1614. for ($t = 0; $t < $this->count; $t++)
  1615. {
  1616. $course = $this->array_list[$t];
  1617. if ($course->bool_advised_to_take == true)
  1618. {
  1619. $rtn_list->add($course);
  1620. }
  1621. }
  1622. return $rtn_list;
  1623. }
  1624. /**
  1625. * Similar to count_hours, but this will only count courses
  1626. * which have been taken and have a grade.
  1627. *
  1628. * @param string $requirement_type
  1629. * - If set, we will only look for courses matching this requirement_type.
  1630. *
  1631. * @param bool $bool_use_ignore_list
  1632. * @param bool $bool_ignore_enrolled
  1633. * @return int
  1634. */
  1635. function count_credit_hours($requirement_type = "", $bool_use_ignore_list = false, $bool_ignore_enrolled = false, $bool_qpts_grades_only = FALSE, $bool_exclude_all_transfer_credits = FALSE, $degree_id = 0)
  1636. {
  1637. // Similar to count_hours, but this will only
  1638. // count courses which have been taken (have a grade).
  1639. $count = 0;
  1640. // Let's find out what our quality point grades & values are...
  1641. $qpts_grades = array();
  1642. $tlines = explode("\n", variable_get("quality_points_grades", "A ~ 4\nB ~ 3\nC ~ 2\nD ~ 1\nF ~ 0\nI ~ 0"));
  1643. foreach ($tlines as $tline) {
  1644. $temp = explode("~", trim($tline));
  1645. if (trim($temp[0]) != "") {
  1646. $qpts_grades[trim($temp[0])] = trim($temp[1]);
  1647. }
  1648. }
  1649. $enrolled_grades = csv_to_array($GLOBALS["fp_system_settings"]["enrolled_grades"]);
  1650. $retake_grades = csv_to_array($GLOBALS["fp_system_settings"]["retake_grades"]);
  1651. for ($t = 0; $t < $this->count; $t++)
  1652. {
  1653. $course = $this->array_list[$t];
  1654. // Does this course belong to the same degree we are interested in? If not, skip it.
  1655. if ($degree_id > 0) {
  1656. if ($course->req_by_degree_id != $degree_id && $course->get_has_been_assigned_to_degree_id($degree_id) != TRUE) continue;
  1657. }
  1658. if ($bool_use_ignore_list == true)
  1659. {
  1660. // Do ignore some courses...
  1661. $temp_course_name = $course->subject_id . " " . $course->course_num;
  1662. // Check in our settings to see if we should ignore this course
  1663. // (configured in /custom/settings.php)
  1664. if (in_array($temp_course_name, csv_to_array(@$GLOBALS["fp_system_settings"]["ignore_courses_from_hour_counts"]))) {
  1665. continue;
  1666. }
  1667. // Also, if the course's requirement_type is "x" it means we should ignore it.
  1668. if ($course->requirement_type == 'x') continue;
  1669. }
  1670. if ($bool_ignore_enrolled == true)
  1671. {
  1672. if (in_array($course->grade, $enrolled_grades)) {
  1673. continue;
  1674. }
  1675. /*
  1676. if ($course->is_completed() == false)
  1677. {
  1678. if ($course->course_list_fulfilled_by->is_empty)
  1679. {
  1680. continue;
  1681. } else {
  1682. if ($course->course_list_fulfilled_by->get_first()->is_completed() == false)
  1683. {
  1684. continue;
  1685. }
  1686. }
  1687. }
  1688. */
  1689. }
  1690. // Only allowing grades which we have quality points for?
  1691. if ($bool_qpts_grades_only) {
  1692. if ($course->grade != "" && !isset($qpts_grades[$course->grade])) {
  1693. continue;
  1694. }
  1695. }
  1696. else {
  1697. // Is this grade a "retake" grade? If so, skip it.
  1698. if (in_array($course->grade, $retake_grades)) continue;
  1699. }
  1700. // Correct the course's requirement type, if needed (remove the "u")
  1701. $cr_type = $course->requirement_type;
  1702. $cr_type = str_replace("u", "", $cr_type);
  1703. if ($course->grade != "")// || !($course->course_list_fulfilled_by->is_empty))
  1704. {
  1705. // Make sure we aren't trying to exclude any transfer credits.
  1706. if ($bool_exclude_all_transfer_credits) {
  1707. if ($course->bool_transfer) {
  1708. continue;
  1709. }
  1710. // Is this a requirement which has been fulfilled by a course? And if so, is THAT course a transfer?
  1711. if ($course->course_list_fulfilled_by->is_empty == false) {
  1712. $cc = $course->course_list_fulfilled_by->get_first();
  1713. if ($cc->bool_transfer) {
  1714. continue;
  1715. }
  1716. }
  1717. }
  1718. // If we require the grade to be a qpts_grade, then check that now.
  1719. if ($bool_qpts_grades_only && !isset($qpts_grades[$course->grade])) {
  1720. continue;
  1721. }
  1722. // Do our requirement types match?
  1723. if ($requirement_type == "" || ($requirement_type != "" && $requirement_type == $cr_type))
  1724. {
  1725. $h = $course->get_hours();
  1726. $count = $count + $h;
  1727. }
  1728. }
  1729. else {
  1730. // maybe it's a substitution?
  1731. if ($requirement_type == "" || ($requirement_type != "" && $requirement_type == $cr_type))
  1732. {
  1733. if ($course->course_list_fulfilled_by->is_empty == false)
  1734. {
  1735. $cc = $course->course_list_fulfilled_by->get_first();
  1736. if ($cc->get_bool_substitution())
  1737. {
  1738. // If we require the grade to be a qpts_grade, then check that now.
  1739. if ($bool_qpts_grades_only && !isset($qpts_grades[$cc->grade])) {
  1740. continue;
  1741. }
  1742. // Make sure we aren't trying to exclude any transfer credits.
  1743. if ($bool_exclude_all_transfer_credits && $cc->bool_transfer) {
  1744. //fpm($requirement_type);
  1745. //fpm($cc);
  1746. continue;
  1747. }
  1748. $h = $cc->get_substitution_hours();
  1749. if ($cc->bool_ghost_hour) {
  1750. $h = 0;
  1751. }
  1752. $count = $count + $h;
  1753. }
  1754. }
  1755. }
  1756. }
  1757. }
  1758. return $count;
  1759. }
  1760. /**
  1761. * Similar to count_credit_hours, but this will only count courses
  1762. * which have been taken and have a grade. We will return back
  1763. * a sum of their quality points.
  1764. *
  1765. * @param string $requirement_type
  1766. * - If set, we will only look for courses matching this requirement_type.
  1767. *
  1768. * @param bool $bool_use_ignore_list
  1769. * @param bool $bool_ignore_enrolled
  1770. * @return int
  1771. */
  1772. function count_credit_quality_points($requirement_type = "", $bool_use_ignore_list = false, $bool_ignore_enrolled = false, $bool_exclude_all_transfer_credits = FALSE, $degree_id = 0)
  1773. {
  1774. $points = 0;
  1775. for ($t = 0; $t < $this->count; $t++)
  1776. {
  1777. $course = $this->array_list[$t];
  1778. // Does this course belong to the same degree we are interested in? If not, skip it.
  1779. if ($degree_id > 0) {
  1780. if ($course->req_by_degree_id != $degree_id && $course->get_has_been_assigned_to_degree_id($degree_id) != TRUE) continue;
  1781. }
  1782. // Correct the course's requirement type, if needed (remove the "u")
  1783. $cr_type = $course->requirement_type;
  1784. $cr_type = str_replace("u", "", $cr_type);
  1785. if ($bool_use_ignore_list == true)
  1786. {
  1787. // Do ignore some courses...
  1788. $temp_course_name = $course->subject_id . " " . $course->course_num;
  1789. // Check in our settings to see if we should ignore this course
  1790. // (configured in /custom/settings.php)
  1791. if (in_array($temp_course_name, csv_to_array(@$GLOBALS["fp_system_settings"]["ignore_courses_from_hour_counts"]))) {
  1792. continue;
  1793. }
  1794. // Also, if the course's requirement_type is "x" it means we should ignore it.
  1795. if ($course->requirement_type == 'x') continue;
  1796. }
  1797. if ($bool_ignore_enrolled == true)
  1798. {
  1799. if ($course->is_completed() == false)
  1800. {
  1801. if ($course->course_list_fulfilled_by->is_empty)
  1802. {
  1803. continue;
  1804. } else {
  1805. if ($course->course_list_fulfilled_by->get_first()->is_completed() == false)
  1806. {
  1807. continue;
  1808. }
  1809. }
  1810. }
  1811. }
  1812. if ($course->grade != "")
  1813. {
  1814. // Make sure we aren't trying to exclude any transfer credits.
  1815. if ($bool_exclude_all_transfer_credits) {
  1816. if ($course->bool_transfer) {
  1817. continue;
  1818. }
  1819. // Is this a requirement which has been fulfilled by a course? And if so, is THAT course a transfer?
  1820. if ($course->course_list_fulfilled_by->is_empty == false) {
  1821. $cc = $course->course_list_fulfilled_by->get_first();
  1822. if ($cc->bool_transfer) {
  1823. continue;
  1824. }
  1825. }
  1826. }
  1827. if ($requirement_type == "")
  1828. {
  1829. $p = $course->get_quality_points($degree_id);
  1830. $points = $points + $p;
  1831. } else {
  1832. if ($cr_type == $requirement_type)
  1833. {
  1834. $p = $course->get_quality_points($degree_id);
  1835. $points = $points + $p;
  1836. continue;
  1837. }
  1838. }
  1839. }
  1840. else {
  1841. // maybe it's a substitution?
  1842. if (($requirement_type == "") || ($requirement_type != "" && $requirement_type == $cr_type))
  1843. {
  1844. if ($course->course_list_fulfilled_by->is_empty == false)
  1845. {
  1846. $cc = $course->course_list_fulfilled_by->get_first();
  1847. if ($cc->get_bool_substitution($degree_id))
  1848. {
  1849. // Make sure we aren't trying to exclude any transfer credits.
  1850. if ($bool_exclude_all_transfer_credits) {
  1851. if ($cc->bool_transfer) {
  1852. //fpm($course);
  1853. continue;
  1854. }
  1855. }
  1856. //$h = $cc->substitution_hours;
  1857. //if ($cc->bool_ghost_hour) {
  1858. // $h = 0;
  1859. //}
  1860. // What are the quality points for this course?
  1861. $p = $cc->get_quality_points($degree_id);
  1862. $points = $points + $p;
  1863. }
  1864. }
  1865. }
  1866. }
  1867. }
  1868. return $points;
  1869. }
  1870. /**
  1871. * Assign a groupID to every course in the list.
  1872. *
  1873. * @param int $group_id
  1874. */
  1875. function assign_group_id($group_id)
  1876. {
  1877. for ($t = 0; $t < $this->count; $t++)
  1878. {
  1879. $course = $this->array_list[$t];
  1880. //$course->assigned_to_group_id = $group_id;
  1881. $course->assigned_to_group_ids_array[$group_id] = $group_id;
  1882. }
  1883. }
  1884. /**
  1885. * Assign a semesterNum to every course in the list.
  1886. *
  1887. * @param int $semester_num
  1888. */
  1889. function assign_semester_num($semester_num)
  1890. {
  1891. for ($t = 0; $t < $this->count; $t++)
  1892. {
  1893. $course = $this->array_list[$t];
  1894. $course->assigned_to_semester_num = $semester_num;
  1895. }
  1896. }
  1897. /**
  1898. * Sets the bool_has_been_assigned property of every course in
  1899. * the list.
  1900. *
  1901. * @param bool $bool_has_been_assigned
  1902. * - What to set each course's->boolhasBeenAssigned property
  1903. * to.
  1904. *
  1905. */
  1906. function set_has_been_assigned($bool_has_been_assigned = true)
  1907. {
  1908. // Set the bool_has_been_assigned for all items
  1909. // in this list.
  1910. for ($t = 0; $t < $this->count; $t++)
  1911. {
  1912. $course = $this->array_list[$t];
  1913. $course->bool_has_been_assigned = $bool_has_been_assigned;
  1914. }
  1915. }
  1916. /**
  1917. * Set's each course's bool_substitution value.
  1918. *
  1919. * @param bool $bool_s
  1920. * - What to set each course's bool_substitution value to.
  1921. */
  1922. function set_bool_substitution($degree_id = 0, $bool_s = true)
  1923. {
  1924. // Set the bool_substitution for all items
  1925. // in this list.
  1926. for ($t = 0; $t < $this->count; $t++)
  1927. {
  1928. $course = $this->array_list[$t];
  1929. $course->set_bool_substitution($degree_id, $bool_s);
  1930. }
  1931. }
  1932. /**
  1933. * Set all the courses in this list to have the same "req_by_degree_id" value.
  1934. */
  1935. function set_req_by_degree_id($degree_id = 0)
  1936. {
  1937. // Set the bool_substitution for all items
  1938. // in this list.
  1939. for ($t = 0; $t < $this->count; $t++)
  1940. {
  1941. $course = $this->array_list[$t];
  1942. $course->req_by_degree_id = $degree_id;
  1943. }
  1944. }
  1945. /**
  1946. * Set all the courses in this list to have the same "requirement_type" value.
  1947. */
  1948. function set_requirement_type($requirement_type = "")
  1949. {
  1950. // Set the bool_substitution for all items
  1951. // in this list.
  1952. for ($t = 0; $t < $this->count; $t++)
  1953. {
  1954. $course = $this->array_list[$t];
  1955. $course->requirement_type = $requirement_type;
  1956. }
  1957. }
  1958. /**
  1959. * Sets each course's $course_substitution value to the supplied
  1960. * Course object.
  1961. *
  1962. * @param Course $course_s
  1963. * @param string $sub_remarks
  1964. */
  1965. function set_course_substitution(Course $course_s, $sub_remarks = "", $degree_id = 0)
  1966. {
  1967. for ($t = 0; $t < $this->count; $t++)
  1968. {
  1969. $course = $this->array_list[$t];
  1970. $course->set_course_substitution($degree_id, $course_s);
  1971. $course->req_by_degree_id = $course_s->req_by_degree_id; // match it up to the degree its being subbed for
  1972. $course->sub_remarks = $sub_remarks;
  1973. }
  1974. }
  1975. /**
  1976. * Go through the list and decrement the specified_repeats
  1977. * value for all instances of Course $course.
  1978. *
  1979. * @param Course $course
  1980. */
  1981. function dec_specified_repeats(Course $course, $bool_ignore_infinite_repeats = TRUE) {
  1982. // Go through the list, and decrement the specified_repeats
  1983. // value for all instances of $course.
  1984. for ($t = 0; $t < $this->count; $t++)
  1985. {
  1986. $course2 = $this->array_list[$t];
  1987. if ($course2->course_id == $course->course_id)
  1988. {
  1989. if ($bool_ignore_infinite_repeats && $course2->specified_repeats == Group::GROUP_COURSE_INFINITE_REPEATS) continue;
  1990. $course2->specified_repeats--;
  1991. }
  1992. }
  1993. }
  1994. /**
  1995. * Go through the list and set the specified_repeats value to $num
  1996. * for all instances of $course.
  1997. *
  1998. * @param Course $course
  1999. * @param int $num
  2000. */
  2001. function set_specified_repeats(Course $course, $num)
  2002. {
  2003. for ($t = 0; $t < $this->count; $t++)
  2004. {
  2005. $course2 = $this->array_list[$t];
  2006. if ($course2->course_id == $course->course_id)
  2007. {
  2008. $course2->specified_repeats = $num;
  2009. $course2->bool_specified_repeats = true;
  2010. }
  2011. }
  2012. }
  2013. /**
  2014. * Removes excluded courses from the list (courses that
  2015. * have db_exclude == 1)
  2016. *
  2017. */
  2018. function remove_excluded()
  2019. {
  2020. // Removes courses from the list that have a db_exclude == 1.
  2021. $new_list = new CourseList();
  2022. // Do this by adding elements to an array.
  2023. // course_id => index in list.
  2024. for ($t = 0; $t < $this->count; $t++)
  2025. {
  2026. $course = $this->array_list[$t];
  2027. if ($course->subject_id == "")
  2028. { // load descriptive data (include exclude info)
  2029. $course->load_descriptive_data();
  2030. }
  2031. if ($course->db_exclude == 1)
  2032. {
  2033. continue;
  2034. }
  2035. $new_list->add($course);
  2036. }
  2037. $this->array_list = $new_list->array_list;
  2038. $this->reset_counter();
  2039. }
  2040. /**
  2041. * Remove occurances of the course in the course list.
  2042. *
  2043. * If a limit is higher than zero, we will STOP after that limit has been reached.
  2044. */
  2045. function remove_course_with_course_id($course_id, $limit = 0) {
  2046. // If the limit is 0, set it to an int's max, which is around 2 billion (32bit) or 9 quintillion (64 bit).
  2047. // Either way, it's effectively infinite for FlightPath in this purpose.
  2048. if ($limit == 0) $limit = PHP_INT_MAX;
  2049. $new_list = new CourseList();
  2050. $c = 0;
  2051. for ($t = 0; $t < $this->count; $t++)
  2052. {
  2053. $course = $this->array_list[$t];
  2054. if ($course == null)
  2055. {
  2056. continue;
  2057. }
  2058. if ($c < $limit && $course->course_id == $course_id) {
  2059. // We found the course. Since we do not want it to be part of the list,
  2060. // we will skip adding it to the new_list.
  2061. $c++;
  2062. continue;
  2063. }
  2064. // Otherwise, let's add it to the new_list.
  2065. $new_list->add($course);
  2066. }
  2067. // Switch over the reference.
  2068. $this->array_list = $new_list->array_list;
  2069. $this->reset_counter();
  2070. }
  2071. /**
  2072. * Removes all courses which are not assigned to this degree_id.
  2073. */
  2074. function remove_courses_not_in_degree($degree_id) {
  2075. $new_list = new CourseList();
  2076. for ($t = 0; $t < $this->count; $t++)
  2077. {
  2078. $course = $this->array_list[$t];
  2079. if ($course == null)
  2080. {
  2081. continue;
  2082. }
  2083. if ($course->req_by_degree_id != $degree_id) {
  2084. continue;
  2085. }
  2086. // Otherwise, let's add it to the new_list.
  2087. $new_list->add($course);
  2088. }
  2089. // Switch over the reference.
  2090. $this->array_list = $new_list->array_list;
  2091. $this->reset_counter();
  2092. }
  2093. /**
  2094. * Removes null's and duplicate courses from the list.
  2095. *
  2096. */
  2097. function remove_duplicates()
  2098. {
  2099. // Go through and remove duplicates from the list.
  2100. // Also remove null's
  2101. $tarray = array();
  2102. $new_list = new CourseList();
  2103. // Do this by adding elements to an array.
  2104. // course_id => index in list.
  2105. for ($t = 0; $t < $this->count; $t++)
  2106. {
  2107. $course = $this->array_list[$t];
  2108. if ($course == null)
  2109. {
  2110. continue;
  2111. }
  2112. $tarray[$course->course_id] = -1;
  2113. }
  2114. for ($t = 0; $t < $this->count; $t++)
  2115. {
  2116. $course = $this->array_list[$t];
  2117. if ($course == null)
  2118. {
  2119. continue;
  2120. }
  2121. //if (is_object($course->courseFulfilledBy))
  2122. if (!($course->course_list_fulfilled_by->is_empty))
  2123. {
  2124. $tarray[$course->course_id] = $t;
  2125. continue;
  2126. }
  2127. if ($tarray[$course->course_id]*1 < 0)
  2128. {
  2129. $tarray[$course->course_id] = $t;
  2130. }
  2131. }
  2132. // Now, go through tarray and rebuild the newList.
  2133. foreach($tarray as $course_id => $i)
  2134. {
  2135. $new_list->add($this->array_list[$i]);
  2136. }
  2137. // Switch over the reference.
  2138. $this->array_list = $new_list->array_list;
  2139. $this->reset_counter();
  2140. }
  2141. } // end class CourseList

Classes

Namesort descending Description
_CourseList