_Group.php

Classes

NameDescription
_Group

File

classes/_Group.php
View source
  1. <?php
  2. class _Group
  3. {
  4. public $title, $icon_filename, $group_id, $requirement_type, $min_grade, $group_name;
  5. public $hours_required, $hours_remaining, $hours_fulfilled, $hours_fulfilled_for_credit;
  6. public $hours_required_by_type;
  7. public $assigned_to_semester_num, $bool_placeholder, $data_entry_comment;
  8. public $list_courses, $list_groups, $db, $count_of_matches, $bool_winning_branch;
  9. public $catalog_year;
  10. public $priority;
  11. //////////////////
  12. /// From the database...
  13. public $db_unassign_group_id, $db_delete_flag;
  14. ///////////////
  15. /// Used with in-system logic....
  16. public $hours_assigned;
  17. public $bool_use_draft;
  18. /**
  19. * $title "Free Electives","Core Fine Arts", etc.
  20. * $icon_filename monalisa.gif, tower1.gif, etc.
  21. * $group_id ID of the group in the db table.
  22. *
  23. * $type Major, Supporting, Core, etc.
  24. * $min_grade This is if the group itself has a min grade requirement.
  25. * Ex: B,C etc.
  26. * $list_courses This is a CourseList of courses. These are
  27. * the courses which are actually required by the group.
  28. * If individual courses have their own min grade requirements,
  29. * or what have you, that only refer to this group, then they
  30. * would be put in here.
  31. * $list_groups This is a list of groups that belong within this group.
  32. * Used when you have branching. Potentially can be quite
  33. * complicated, since each group in the list can also have
  34. * subgroups.
  35. **/
  36. function __construct($group_id = "", DatabaseHandler $db = NULL, $semester_num = -1, $array_significant_courses = false, $bool_use_draft = false)
  37. {
  38. $this->group_id = $group_id;
  39. $this->assigned_to_semester_num = $semester_num;
  40. $this->count_of_matches = 0;
  41. $this->hours_assigned = 0;
  42. $this->list_courses = new CourseList();
  43. $this->list_groups = new GroupList();
  44. $this->bool_use_draft = $bool_use_draft;
  45. $this->hours_required_by_type = array();
  46. // Always override if the global variable is set.
  47. if ($GLOBALS["fp_advising"]["bool_use_draft"] == true) {
  48. $this->bool_use_draft = true;
  49. }
  50. $this->db = $db;
  51. if ($db == NULL)
  52. {
  53. $this->db = get_global_database_handler();
  54. }
  55. if ($group_id != "")
  56. {
  57. $this->bool_placeholder = false;
  58. $this->load_group(true, $array_significant_courses);
  59. }
  60. }
  61. function assign_to_semester($semester_num)
  62. {
  63. $this->assigned_to_semester_num = $semester_num;
  64. $temp_i = $this->list_courses->i;
  65. $this->list_courses->reset_counter();
  66. while($this->list_courses->has_more())
  67. {
  68. $c = $this->list_courses->get_next();
  69. $c->assigned_to_semester_num = $semester_num;
  70. }
  71. $this->list_courses->i = $temp_i;
  72. }
  73. function reset_list_counters()
  74. {
  75. // Resets the counters on all groups and course lists
  76. // in this group.
  77. $this->list_courses->reset_counter();
  78. $this->list_groups->reset_counter();
  79. }
  80. function assign_min_grade($min_grade)
  81. {
  82. // Assign every course in the group to have this particular min grade.
  83. $this->min_grade = $min_grade;
  84. $this->list_courses->assign_min_grade($min_grade);
  85. $this->list_groups->assign_min_grade($min_grade);
  86. }
  87. function get_hours_remaining($semester_num = -1)
  88. {
  89. // returns hor many hours are left for this group.
  90. return ($this->hours_required - $this->get_fulfilled_hours(true, true, false, $semester_num));
  91. }
  92. function load_group($bool_load_significant_only = true, $array_significant_courses = false, $bool_reload_missing_only = false)
  93. {
  94. $group_id = $this->group_id;
  95. $this->load_descriptive_data();
  96. if ($this->db_delete_flag == 1)
  97. {
  98. return;
  99. }
  100. $bool_significant_courses_empty = true;
  101. if (is_array($array_significant_courses))
  102. {
  103. $bool_significant_courses_empty = false;
  104. }
  105. if ($bool_reload_missing_only == true)
  106. {
  107. // We are only going to load the *missing* courses from
  108. // this group. So, begin by getting an array of what is
  109. // not missing.
  110. $array_group_requirement_ids = $this->list_courses->get_group_requirement_id_array();
  111. //var_dump($array_group_requirement_ids);
  112. }
  113. $table_name = "group_requirements";
  114. if ($this->bool_use_draft) {$table_name = "draft_$table_name";}
  115. $res = $this->db->db_query("SELECT * FROM $table_name
  116. WHERE group_id = '?' ", $this->group_id);
  117. while ($cur = $this->db->db_fetch_array($res))
  118. {
  119. $id = $cur["id"];
  120. $course_id = $cur["course_id"]*1;
  121. if ($cur["course_id"]*1 > 0)
  122. {
  123. if ($bool_load_significant_only == true && $bool_significant_courses_empty == false)
  124. {
  125. // If this course_id is NOT in the array of significant courses
  126. // (that the student took or has transfer credit or subs for)
  127. // then skip it. Never add it to the group.
  128. if ($array_significant_courses[$cur["course_id"]] != true)
  129. {// course was not in there, so skip!
  130. continue;
  131. }
  132. }
  133. // A course is the next requirement.
  134. for ($t = 0; $t <= $cur["course_repeats"]; $t++)
  135. { // Add in the specified repeats for this group...
  136. // This will usually only go through the loop once.
  137. $use_id = $id . "_rep_$t";
  138. if ($bool_reload_missing_only == true)
  139. {
  140. // Only load this course if it is missing from the group.
  141. // Read the reload_missing_courses() method for an explanation
  142. // of why we should want to do this.
  143. // Basically, check all the courses in the current
  144. // list_courses object for a db_group_requirement_id of $id.
  145. // Only proceed if $id was NOT found.
  146. if ($array_group_requirement_ids[$use_id] == true)
  147. {
  148. continue;
  149. }
  150. }
  151. $course_c = new Course();
  152. $course_c->bool_use_draft = $this->bool_use_draft;
  153. $course_c->course_id = $cur["course_id"];
  154. $course_c->db_group_requirement_id = $use_id;
  155. $course_c->db = $this->db;
  156. $course_c->catalog_year = $this->catalog_year;
  157. $course_c->assigned_to_group_id = $group_id;
  158. $course_c->assigned_to_semester_num = $this->assigned_to_semester_num;
  159. $course_c->specified_repeats = $cur["course_repeats"];
  160. if ($cur["course_repeats"] > 0)
  161. {
  162. $course_c->bool_specified_repeat = true;
  163. }
  164. $course_c->min_grade = trim(strtoupper($cur["course_min_grade"]));
  165. if ($course_c->min_grade == "")
  166. { // By default, all courses have a
  167. // min grade requirement of D.
  168. $course_c->min_grade = "D";
  169. }
  170. $this->list_courses->add($course_c);
  171. }
  172. }
  173. if ($cur["child_group_id"]*1 > 0)
  174. {
  175. // Another group is the next requirement (its a branch)
  176. if ($bool_reload_missing_only == true)
  177. { // Since we are reloading courses, this subgroup is already
  178. // part of this group, so do not re-create it, just find it
  179. // and reload it's missing courses.
  180. $temp_g = new Group();
  181. $temp_g->bool_use_draft = $this->bool_use_draft;
  182. $temp_g->group_id = $cur["child_group_id"];
  183. if ($group_g = $this->list_groups->find_match($temp_g))
  184. {
  185. $group_g->reload_missing_courses();
  186. } else {
  187. fpm("could not find sub group to reload!");
  188. }
  189. } else {
  190. // This is a brand-new sub group, so create it
  191. // and add it to this group.
  192. $group_g = new Group($cur["child_group_id"],null,$this->assigned_to_semester_num, $array_significant_courses, $this->bool_use_draft);
  193. $this->list_groups->add($group_g);
  194. }
  195. }
  196. }
  197. }
  198. function reload_missing_courses()
  199. {
  200. // This function will go through the group and reload
  201. // any courses which are missing from the group object,
  202. // but are spelled out in the database table.
  203. // This is used after we have loaded a group from
  204. // cache (because the cached group only contains
  205. // courses which the student has taken).
  206. $this->load_group(false, "", true);
  207. }
  208. function replace_missing_course($course_id, $db_group_requirement_id="")
  209. {
  210. // replace course_id in this group, if it is missing.
  211. $this->db = new DatabaseHandler();
  212. $table_name = "group_requirements";
  213. if ($this->bool_use_draft) {$table_name = "draft_$table_name";}
  214. // Look for all instances of this course in the group's base list...
  215. $res = $this->db->db_query("SELECT * FROM $table_name
  216. WHERE `group_id`='?'
  217. AND `course_id`='?' ", $this->group_id, $course_id);
  218. while ($cur = $this->db->db_fetch_array($res))
  219. {
  220. $id = $cur["id"];
  221. for ($t = 0; $t <= $cur["course_repeats"]; $t++)
  222. {
  223. $course = new Course($course_id,false,$db, false, "", $this->bool_use_draft);
  224. $use_id = $id . "_rep_$t";
  225. // Make sure the group does not already have this requirementID...
  226. if ($this->list_courses->contains_group_requirement_id($use_id))
  227. {
  228. continue;
  229. }
  230. $course->assigned_to_group_id = $this->group_id;
  231. $course->db_group_requirement_id = $use_id;
  232. $course->specified_repeats = $cur["course_repeats"];
  233. if ($cur["course_repeats"] > 0)
  234. {
  235. $course->bool_specified_repeat = true;
  236. }
  237. $this->list_courses->add($course);
  238. }
  239. }
  240. // Now, go through all of the group's branches and
  241. // do the same thing.
  242. $this->list_groups->reset_counter();
  243. while($this->list_groups->has_more())
  244. {
  245. $g = $this->list_groups->get_next();
  246. $g->replace_missing_course($course_id);
  247. }
  248. }
  249. function load_descriptive_data()
  250. {
  251. if ($db == NULL)
  252. {
  253. $this->db = get_global_database_handler();
  254. }
  255. $table_name = "groups";
  256. if ($this->bool_use_draft) {$table_name = "draft_$table_name";}
  257. // Load information about the group's title, icon, etc.
  258. $res = $this->db->db_query("SELECT * FROM $table_name
  259. WHERE group_id = '?' ", $this->group_id);
  260. $cur = $this->db->db_fetch_array($res);
  261. $this->title = trim($cur["title"]);
  262. $this->icon_filename = trim($cur["icon_filename"]);
  263. $this->group_name = trim($cur["group_name"]);
  264. $this->data_entry_comment = trim($cur["data_entry_comment"]);
  265. $this->priority = trim($cur["priority"]);
  266. $this->definition = trim($cur["definition"]);
  267. $this->db_delete_flag = trim($cur["delete_flag"]);
  268. $this->catalog_year = trim($cur["catalog_year"]);
  269. if ($this->group_id == -88)
  270. {
  271. $this->title = "Add an Additional Course";
  272. }
  273. }
  274. function get_fulfilled_hours($bool_check_subgroups = true, $bool_count_advised = true, $bool_require_has_been_displayed = false, $only_count_semester_num = -1, $bool_ignore_enrolled = false, $bool_qpts_grades_only = FALSE)
  275. {
  276. // Returns how many hours have been used by the
  277. // course fulfillments for this group...
  278. $count = 0;
  279. // if onlyCountSemesterNum != -1, then we will only count courses
  280. // who have their "assigned_to_semester_num" = $only_count_semester_num.
  281. // TODO: Replace with setting instead
  282. $qpts_grades = array(
  283. "A" => 4,
  284. "B" => 3,
  285. "C" => 2,
  286. "D" => 1,
  287. );
  288. //print_pre($this->to_string());
  289. $this->list_courses->reset_counter();
  290. while($this->list_courses->has_more())
  291. {
  292. $c = $this->list_courses->get_next();
  293. if ($only_count_semester_num != -1 && $c->assigned_to_semester_num != $only_count_semester_num)
  294. {
  295. // Only accept courses assigned to a particular semester.
  296. continue;
  297. }
  298. if (is_object($c->course_list_fulfilled_by) && !($c->course_list_fulfilled_by->is_empty))
  299. {
  300. if ($bool_ignore_enrolled == true)
  301. {
  302. // Only allow it if it has been completed.
  303. if ($c->course_list_fulfilled_by->get_first()->is_completed() == false)
  304. {
  305. continue;
  306. }
  307. }
  308. if (!$bool_require_has_been_displayed)
  309. { // The course does not have to have been displayed on the page yet.
  310. //$count = $count + $c->course_list_fulfilled_by->count_hours("", false, false);
  311. $count = $count + $c->course_list_fulfilled_by->count_credit_hours("", false, false, $bool_qpts_grades_only);
  312. } else {
  313. if ($c->course_list_fulfilled_by->get_first()->bool_has_been_displayed == true)
  314. {
  315. //$count = $count + $c->course_list_fulfilled_by->count_hours("", false, false);
  316. $count = $count + $c->course_list_fulfilled_by->count_credit_hours("", false, false, $bool_qpts_grades_only);
  317. }
  318. }
  319. } else if ($c->bool_advised_to_take && $bool_count_advised == true)
  320. {
  321. $h = $c->get_hours();
  322. $count = $count + $h;
  323. }
  324. }
  325. if ($bool_check_subgroups == true)
  326. {
  327. // If there are any subgroups for this group, then run
  328. // this function for each group as well.
  329. $this->list_groups->reset_counter();
  330. while($this->list_groups->has_more())
  331. {
  332. $g = $this->list_groups->get_next();
  333. $gc = $g->get_fulfilled_hours(true, $bool_count_advised, $bool_require_has_been_displayed, $only_count_semester_num, $bool_ignore_enrolled, $bool_qpts_grades_only);
  334. $count = $count + $gc;
  335. }
  336. }
  337. return $count;
  338. }
  339. /**
  340. * Returns the quality points earned for all of the courses in this group
  341. *
  342. */
  343. function get_fulfilled_quality_points($bool_check_subgroups = true, $only_count_semester_num = -1, $bool_ignore_enrolled = false, $bool_require_has_been_displayed = false)
  344. {
  345. $points = 0;
  346. // if onlyCountSemesterNum != -1, then we will only count courses
  347. // who have their "assigned_to_semester_num" = $only_count_semester_num.
  348. $this->list_courses->reset_counter();
  349. while($this->list_courses->has_more())
  350. {
  351. $c = $this->list_courses->get_next();
  352. if ($only_count_semester_num != -1 && $c->assigned_to_semester_num != $only_count_semester_num)
  353. {
  354. // Only accept courses assigned to a particular semester.
  355. continue;
  356. }
  357. if (is_object($c->course_list_fulfilled_by) && !($c->course_list_fulfilled_by->is_empty))
  358. {
  359. if ($bool_ignore_enrolled == true)
  360. {
  361. // Only allow it if it has been completed.
  362. if ($c->course_list_fulfilled_by->get_first()->is_completed() == false)
  363. {
  364. continue;
  365. }
  366. }
  367. $p = 0;
  368. // Are we requiring that the course has been displayed?
  369. if (!$bool_require_has_been_displayed || ($bool_require_has_been_displayed && $c->course_list_fulfilled_by->get_first()->bool_has_been_displayed == TRUE))
  370. {
  371. $p = $c->course_list_fulfilled_by->count_credit_quality_points("", TRUE, TRUE);
  372. }
  373. $points = $points + $p;
  374. }
  375. }
  376. if ($bool_check_subgroups == TRUE)
  377. {
  378. // If there are any subgroups for this group, then run
  379. // this function for each group as well.
  380. $this->list_groups->reset_counter();
  381. while($this->list_groups->has_more())
  382. {
  383. $g = $this->list_groups->get_next();
  384. $gp = $g->get_fulfilled_quality_points(TRUE, $only_count_semester_num, $bool_ignore_enrolled);
  385. $points = $points + $gp;
  386. }
  387. }
  388. return $points;
  389. }
  390. function equals(Group $group)
  391. {
  392. if ($this->group_id == $group->group_id)
  393. {
  394. return true;
  395. }
  396. return false;
  397. }
  398. function to_string()
  399. {
  400. $rtn = "";
  401. $rtn .= " Group: $this->group_id | $this->title $this->catalog_year ($this->hours_required hrs req.)\n {\n";
  402. if (!$this->list_courses->is_empty)
  403. {
  404. $rtn .= $this->list_courses->to_string();
  405. }
  406. if (!$this->list_groups->is_empty)
  407. {
  408. $rtn .= $this->list_groups->to_string();
  409. }
  410. $rtn .= " } \n";
  411. return $rtn;
  412. }
  413. function find_courses(Course $course)
  414. {
  415. // Return a CourseList of all the Course objects
  416. // which are in this group that match
  417. $rtn_course_list = new CourseList();
  418. if ($obj_list = $this->list_courses->find_all_matches($course))
  419. {
  420. $obj_list->reset_counter();
  421. while($obj_list->has_more())
  422. {
  423. $c = $obj_list->get_next();
  424. $c->required_on_branch_id = $this->group_id;
  425. }
  426. $rtn_course_list->add_list($obj_list);
  427. return $rtn_course_list;
  428. }
  429. return false;
  430. }
  431. } // end class Group