Course.php

  1. 7.x classes/Course.php
  2. 6.x classes/Course.php
  3. 5.x custom/classes/Course.php

File

classes/Course.php
View source
  1. <?php
  2. /*
  3. Class definition for the Course object.
  4. */
  5. class Course extends stdClass
  6. {
  7. // Some public variables and what they are used for.
  8. const COURSE_UNKNOWN_TERM_ID = 11111;
  9. // Database & misc related:
  10. public $random_id = 0, $db_advised_courses_id = 0;
  11. public $bool_placeholder, $db, $db_substitution_id_array, $db_unassign_transfer_id;
  12. public $db_exclude, $data_entry_comment, $array_index, $data_entry_value, $db_group_attributes;
  13. public $db_group_requirement_id; // the id from the group_requirements table where this was specified.
  14. public $db_degree_requirement_id; // the id from the degree_requirements table where this was specified.
  15. public $extra_attribs = '';
  16. // Course catalog data related:
  17. public $subject_id = '', $course_num = '', $course_id = 0, $requirement_type = '', $catalog_year = '';
  18. public $min_hours = 0, $max_hours = 0, $list_prereqs = '', $repeat_hours = 0;
  19. public $array_valid_names, $school_id = 0;
  20. // Student record related:
  21. public $bool_taken, $term_id = '', $section_number = '', $quality_points = 0, $grade = '', $db_grade = '', $level_code = '';
  22. public $bool_transfer, $institution_id = '', $institution_name = '', $course_transfer;
  23. public $transfer_eqv_text, $transfer_footnote;
  24. public $details_by_degree_array; // meant to hold all details about a substitution, or anything else, keyed by degree id.
  25. // Major/Degree or Group Requirement related:
  26. public $min_grade = '', $specified_repeats = '', $bool_specified_repeat, $required_on_branch_id;
  27. public $assigned_to_semester_num = '', $appears_in_semester_nums, $req_by_degree_id;
  28. public $assigned_to_degree_ids_array, $assigned_to_group_ids_array;
  29. // advising & in-system logic related:
  30. public $advised_hours, $bool_selected, $bool_advised_to_take;
  31. public $course_list_fulfilled_by;
  32. public $bool_added_course, $group_list_unassigned;
  33. public $advised_term_id, $temp_old_course_id;
  34. public $bool_use_draft;
  35. // Display related:
  36. public $display_status = '', $icon_filename = '', $description = '', $title = '';
  37. public $title_text = '', $temp_flag, $disp_for_group_id;
  38. public $bool_unselectable;
  39. public $bool_hide_grade, $bool_ghost_hour, $bool_ghost_min_hour;
  40. public $unique_id = '';
  41. /**
  42. * The constructor for a Course object.
  43. *
  44. * @param int $course_id
  45. * - Numeric course_id of the course to try to load. Leave blank
  46. * if you simply wish to instantiate a course object.
  47. *
  48. * @param bool $is_transfer
  49. * - Is this course a transfer course? Meaning, from another
  50. * school.
  51. *
  52. * @param DatabaseHandler $db
  53. * @param bool $is_blank
  54. * @param int $catalog_year
  55. * - What catalog_year does this Course belong to? This is
  56. * used later when we call load_descriptive_data() to get its
  57. * description, hour count, etc.
  58. *
  59. * @param bool $bool_use_draft
  60. */
  61. function __construct($course_id = 0, $is_transfer = FALSE, DatabaseHandler $db = NULL, $is_blank = FALSE, $catalog_year = 0, $bool_use_draft = FALSE)
  62. {
  63. $this->advised_hours = -1;
  64. if ($is_blank == true)
  65. { // Do nothing if this is a "blank" course.
  66. return;
  67. }
  68. $array_valid_names = array(); // will hold all "valid" names for this course (non excluded names).
  69. $this->course_id = intval($course_id); // Force it to be numeric.
  70. $this->appears_in_semester_nums = array(); // for combo-degrees
  71. $this->temp_old_course_id = 0; // Used in case we delete the course_id, we can get it back (good with substitutions of transfers that are outdated).
  72. $this->catalog_year = $catalog_year;
  73. $this->assigned_to_semester_num = -1;
  74. //$this->assigned_to_group_id = 0; // deprecated
  75. $this->assigned_to_group_ids_array = array();
  76. $this->bool_advised_to_take = false;
  77. $this->bool_added_course = false;
  78. $this->specified_repeats = 0;
  79. $this->bool_specified_repeat = false;
  80. // Give this course instance a "random" numeric id, meaning, it doesn't really mean anything.
  81. // It used to actually be random, but we will use a simple increment instead to ensure it is unique.
  82. if (!isset($GLOBALS['fp_courses_random_ids'])) {
  83. $GLOBALS['fp_courses_random_ids'] = 10;
  84. }
  85. $this->random_id = $GLOBALS['fp_courses_random_ids']++;
  86. $this->display_status = "eligible";
  87. $this->course_list_fulfilled_by = new CourseList();
  88. $this->group_list_unassigned = new GroupList();
  89. $this->bool_use_draft = $bool_use_draft;
  90. $this->disp_for_group_id = "";
  91. $this->req_by_degree_id = 0;
  92. //$this->bool_has_been_displayed_by_degree_array = array();
  93. //$this->bool_substitution_by_degree_array = array();
  94. $this->db_substitution_id_array = array();
  95. //$this->course_substitution_by_degree_array = array();
  96. $this->details_by_degree_array = array();
  97. $this->details_by_degree_array[-1] = array(); // to keep notices from showing up.
  98. $this->assigned_to_degree_ids_array = array();
  99. // Always override if the global variable is set.
  100. if (@$GLOBALS["fp_advising"]["bool_use_draft"] == true) {
  101. $this->bool_use_draft = true;
  102. }
  103. $this->db = $db;
  104. if ($db == NULL)
  105. {
  106. $this->db = get_global_database_handler();;
  107. }
  108. if ($course_id != "")
  109. {
  110. $this->load_course($course_id, $is_transfer);
  111. }
  112. }
  113. function set_bool_substitution_split($degree_id = 0, $val = '') {
  114. // If degree_id is zero, then use the course's currently req_by_degree_id.
  115. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  116. $this->set_details_by_degree($degree_id, "bool_substitution_split", $val);
  117. }
  118. function get_bool_substitution_split($degree_id = 0) {
  119. // If degree_id is zero, then use the course's currently req_by_degree_id.
  120. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  121. if ($degree_id > 0) {
  122. //return $this->bool_substitution_by_degree_array[$degree_id];
  123. return $this->get_details_by_degree($degree_id, "bool_substitution_split");
  124. }
  125. else {
  126. // Any degree?
  127. if ($this->get_count_details_by_degree("bool_substitution_split", TRUE) > 0) {
  128. return TRUE;
  129. }
  130. }
  131. return FALSE;
  132. }
  133. function set_bool_outdated_sub($degree_id = 0, $val = '') {
  134. // If degree_id is zero, then use the course's currently req_by_degree_id.
  135. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  136. $this->set_details_by_degree($degree_id, "bool_outdated_sub", $val);
  137. }
  138. function get_bool_outdated_sub($degree_id = 0) {
  139. // If degree_id is zero, then use the course's currently req_by_degree_id.
  140. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  141. if ($degree_id > 0) {
  142. //return $this->bool_substitution_by_degree_array[$degree_id];
  143. return $this->get_details_by_degree($degree_id, "bool_outdated_sub");
  144. }
  145. else {
  146. // how about for ANY degree?
  147. if ($this->get_count_details_by_degree("bool_outdated_sub", TRUE) > 0) {
  148. return TRUE;
  149. }
  150. }
  151. return FALSE;
  152. }
  153. function set_bool_substitution_new_from_split($degree_id = 0, $val = '') {
  154. // If degree_id is zero, then use the course's currently req_by_degree_id.
  155. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  156. $this->set_details_by_degree($degree_id, "bool_substitution_new_from_split", $val);
  157. }
  158. function get_bool_substitution_new_from_split($degree_id = 0) {
  159. // If degree_id is zero, then use the course's currently req_by_degree_id.
  160. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  161. if ($degree_id > 0) {
  162. //return $this->bool_substitution_by_degree_array[$degree_id];
  163. return $this->get_details_by_degree($degree_id, "bool_substitution_new_from_split");
  164. }
  165. else {
  166. // how about for ANY degree?
  167. if ($this->get_count_details_by_degree("bool_substitution_new_from_split", TRUE) > 0) {
  168. return TRUE;
  169. }
  170. }
  171. return FALSE;
  172. }
  173. function set_substitution_hours($degree_id = 0, $val = '') {
  174. // If degree_id is zero, then use the course's currently req_by_degree_id.
  175. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  176. $this->set_details_by_degree($degree_id, "substitution_hours", $val);
  177. }
  178. /**
  179. * Similar to the functions regarding display-- get the course substitution based on supplied degree_id.
  180. * Set degree_id to -1 to just get the first one, if available.
  181. */
  182. function get_substitution_hours($degree_id = 0) {
  183. // If degree_id is zero, then use the course's currently req_by_degree_id.
  184. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  185. if ($degree_id > 0) {
  186. return $this->get_details_by_degree($degree_id, "substitution_hours");
  187. }
  188. else {
  189. if (isset($this->details_by_degree_array[$degree_id]["substitution_hours"])) {
  190. $x = $this->details_by_degree_array[$degree_id]["substitution_hours"];
  191. if ($x) return $x;
  192. }
  193. }
  194. // Else, return boolean FALSE
  195. return FALSE;
  196. }
  197. function set_hours_awarded($degree_id = 0, $val = 0) {
  198. // If degree_id is zero, then use the course's currently req_by_degree_id.
  199. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  200. $this->set_details_by_degree($degree_id, "hours_awarded", floatval($val)*1); // *1 to force to a number and to trim extra zeroes.
  201. }
  202. function set_course_substitution($degree_id = 0, Course $course = NULL) {
  203. // If degree_id is zero, then use the course's currently req_by_degree_id.
  204. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  205. //$this->course_substitution_by_degree_array[$degree_id] = $course;
  206. $this->set_details_by_degree($degree_id, "course_substitution", $course);
  207. }
  208. /**
  209. * Similar to the functions regarding display-- get the course substitution based on supplied degree_id.
  210. * Set degree_id to -1 to just get the first one, if available.
  211. */
  212. function get_course_substitution($degree_id = 0) {
  213. // If degree_id is zero, then use the course's currently req_by_degree_id.
  214. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  215. if ($degree_id > 0) {
  216. //return $this->course_substitution_by_degree_array[$degree_id];
  217. return $this->get_details_by_degree($degree_id, "course_substitution");
  218. }
  219. else {
  220. //$x = reset($this->course_substitution_by_degree_array);
  221. if (isset($this->details_by_degree_array[$degree_id]["course_substitution"])) {
  222. $x = reset($this->details_by_degree_array[$degree_id]["course_substitution"]);
  223. if ($x) return $x;
  224. }
  225. }
  226. // Else, return boolean FALSE
  227. return FALSE;
  228. }
  229. /**
  230. * If the boolean is set, it means if the supplied degree_id isn't set, then use the first found value.
  231. */
  232. function get_hours_awarded($degree_id = 0, $bool_use_first_found_if_not_found_by_degree = TRUE) {
  233. // If degree_id is zero, then use the course's currently req_by_degree_id.
  234. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  235. $x = NULL;
  236. if ($degree_id > 0) {
  237. //return $this->course_substitution_by_degree_array[$degree_id];
  238. if (isset($this->details_by_degree_array[$degree_id]["hours_awarded"])) {
  239. $x = floatval($this->get_details_by_degree($degree_id, "hours_awarded")) * 1; // *1 forces numeric and trimes extra zeroes.
  240. }
  241. else if ($bool_use_first_found_if_not_found_by_degree) {
  242. // It wasn't set, so get the first value that WAS set.
  243. $x = floatval($this->get_first_value_from_any_degree("hours_awarded"));
  244. }
  245. if ($x) return $x;
  246. }
  247. else {
  248. // We just want the first value of ANY degree returned.
  249. $x = floatval($this->get_first_value_from_any_degree("hours_awarded"));
  250. if ($x) return $x;
  251. }
  252. // Else, return zero
  253. return 0;
  254. }
  255. /**
  256. * Goes through the details_by_degree array and returns the first
  257. * valid value for the supplied key, any degree., or return NULL if not found.
  258. */
  259. function get_first_value_from_any_degree($key) {
  260. foreach ($this->details_by_degree_array as $d => $v) {
  261. if (isset($v[$key])) return $v[$key];
  262. }
  263. // Found nothing, return null
  264. return NULL;
  265. }
  266. /**
  267. * Similar to the functions regarding display, these will say if this course has been used in a substitution
  268. * for a particular degree.
  269. */
  270. function get_bool_substitution($degree_id = 0) {
  271. // If degree_id is zero, then use the course's currently req_by_degree_id.
  272. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  273. if ($degree_id > 0) {
  274. //return $this->bool_substitution_by_degree_array[$degree_id];
  275. return $this->get_details_by_degree($degree_id, "bool_substitution");
  276. }
  277. else {
  278. // has the course been substituted by ANY degree?
  279. if ($this->get_count_details_by_degree("bool_substitution", TRUE) > 0) {
  280. return TRUE;
  281. }
  282. }
  283. return FALSE;
  284. }
  285. /**
  286. * Return back a count from ANY degree for this property name.
  287. */
  288. function get_count_details_by_degree($property_name, $check_for_specific_value = NULL) {
  289. $c = 0;
  290. foreach ($this->details_by_degree_array as $degree_id => $temp) {
  291. if (isset($temp[$property_name])) {
  292. if ($check_for_specific_value !== NULL) {
  293. // We want to SKIP if this property does not have this specific value
  294. if ($temp[$property_name] !== $check_for_specific_value) continue;
  295. }
  296. $c++;
  297. }
  298. }
  299. return $c;
  300. }
  301. function set_bool_substitution($degree_id = 0, $val = TRUE) {
  302. // If degree_id is zero, then use the course's currently req_by_degree_id.
  303. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  304. //$this->bool_substitution_by_degree_array[$degree_id] = $val;
  305. $this->set_details_by_degree($degree_id, "bool_substitution", $val);
  306. }
  307. /**
  308. * Returns TRUE or FALSE if this course has been displayed. Specify a degree_id to be more specific.
  309. * Use -1 to mean "ANY" degree?
  310. */
  311. function get_has_been_displayed($degree_id = 0) {
  312. // If degree_id is zero, then use the course's currently req_by_degree_id.
  313. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  314. if ($degree_id > 0) {
  315. //return $this->bool_has_been_displayed_by_degree_array[$degree_id];
  316. return $this->get_details_by_degree($degree_id, "bool_has_been_displayed");
  317. }
  318. else {
  319. // has the course been displayed by ANY degree?
  320. if ($this->get_count_details_by_degree("bool_has_been_displayed", TRUE) > 0) {
  321. return TRUE;
  322. }
  323. }
  324. return FALSE;
  325. }
  326. /**
  327. * Counterpart to get_has_been_displayed.
  328. * @see get_has_been_displayed()
  329. */
  330. function set_has_been_displayed($degree_id = 0, $val = TRUE) {
  331. // If degree_id is zero, then use the course's currently req_by_degree_id.
  332. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  333. //$this->bool_has_been_displayed_by_degree_array[$degree_id] = $val;
  334. $this->set_details_by_degree($degree_id, "bool_has_been_displayed", $val);
  335. }
  336. function set_bool_exclude_repeat($degree_id = 0, $val = TRUE) {
  337. // If degree_id is zero, then use the course's currently req_by_degree_id.
  338. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  339. //$this->bool_has_been_displayed_by_degree_array[$degree_id] = $val;
  340. $this->set_details_by_degree($degree_id, "bool_exclude_repeat", $val);
  341. }
  342. /**
  343. * Returns TRUE or FALSE if this course has been marked as exclude_repeat. Specify a degree_id to be more specific.
  344. * Use -1 to mean "ANY" degree?
  345. */
  346. function get_bool_exclude_repeat($degree_id = 0) {
  347. // If degree_id is zero, then use the course's currently req_by_degree_id.
  348. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  349. if ($degree_id > 0) {
  350. //return $this->bool_has_been_displayed_by_degree_array[$degree_id];
  351. return $this->get_details_by_degree($degree_id, "bool_exclude_repeat");
  352. }
  353. else {
  354. // has the course been displayed by ANY degree?
  355. if ($this->get_count_details_by_degree("bool_exclude_repeat", TRUE) > 0) {
  356. return TRUE;
  357. }
  358. }
  359. return FALSE;
  360. }
  361. /**
  362. * Convenience function to set a value into our details_by_degree_array.
  363. */
  364. function set_details_by_degree($degree_id, $key, $val) {
  365. $this->details_by_degree_array[$degree_id][$key] = $val;
  366. }
  367. /**
  368. * @see set_details_by_degree()
  369. */
  370. function get_details_by_degree($degree_id, $key) {
  371. return @$this->details_by_degree_array[$degree_id][$key];
  372. }
  373. /**
  374. * This function will create a "data string" of the course.
  375. * Think of it as a poor man's serialize. I can't actually use
  376. * serialize, as I have to call this for every course on the screen,
  377. * and the page load time was too long when using serialize, probably
  378. * because of all the extra fields which I did not need.
  379. *
  380. * The string returned will be used to send information about this
  381. * course to a popup window.
  382. *
  383. * Important details about the course are put into a particular order,
  384. * separated by commas. Booleans are converted to either 1 or 0.
  385. *
  386. * This function is the mirror of load_course_from_data_string().
  387. *
  388. * @return string
  389. */
  390. function to_data_string()
  391. {
  392. $rtn = "";
  393. $rtn .= $this->course_id . "~";
  394. $rtn .= $this->assigned_to_semester_num . "~";
  395. $rtn .= fp_join_assoc($this->assigned_to_group_ids_array) . "~";
  396. $rtn .= intval($this->bool_advised_to_take) . "~";
  397. $rtn .= $this->specified_repeats . "~";
  398. $rtn .= intval($this->bool_specified_repeat) . "~";
  399. $grd = (string) $this->grade;
  400. if (strstr($grd, "+")) {
  401. $grd = str_replace("+", "_pls_", $grd);
  402. }
  403. $rtn .= $grd . "~";
  404. $rtn .= $this->get_hours_awarded() * 1 . "~";
  405. $rtn .= $this->term_id . "~";
  406. $rtn .= $this->advised_hours * 1 . "~";
  407. $rtn .= intval($this->bool_transfer) . "~";
  408. // If this is a transfer, then we will put in various information
  409. // about the original transfer course...
  410. if ($this->bool_transfer == true)
  411. {
  412. $rtn .= $this->course_transfer->course_id . "~";
  413. } else {
  414. // Just enter blank.
  415. $rtn .= "~";
  416. }
  417. $rtn .= intval($this->bool_added_course) . "~";
  418. $rtn .= $this->db_advised_courses_id . "~";
  419. $rtn .= $this->random_id . "~";
  420. $rtn .= fp_join_assoc($this->get_degree_details_data_string("bool_substitution")) . "~";
  421. // If this is a substitution, what is the original requirement?
  422. if ($this->get_bool_substitution(-1))
  423. {
  424. // Create a simple assoc array for our course substitutions, where all we need to keep track of
  425. // is their course_id, not the entire course object.
  426. $temp = $this->get_degree_details_data_string("course_substitution");
  427. $arr = array();
  428. foreach ($temp as $key => $c) {
  429. $arr[$key] = $c->course_id;
  430. }
  431. //$rtn .= $this->course_substitution->course_id . "," . $this->req_by_degree_id . "~";
  432. $rtn .= fp_join_assoc($arr) . "~";
  433. }
  434. else {
  435. // Just enter blank.
  436. $rtn .= "~";
  437. }
  438. ///////////////////
  439. $rtn .= fp_join_assoc($this->db_substitution_id_array) . "~";
  440. $rtn .= floatval($this->min_hours) . "~";
  441. $rtn .= floatval($this->max_hours) . "~";
  442. //$rtn .= intval($this->get_bool_substitution_new_from_split()) . "~";
  443. $rtn .= fp_join_assoc($this->get_degree_details_data_string("bool_substitution_new_from_split")) . "~";
  444. //$rtn .= intval($this->get_bool_substitution_split()) . "~";
  445. $rtn .= fp_join_assoc($this->get_degree_details_data_string("bool_substitution_split")) . "~";
  446. // no longer used
  447. //$rtn .= intval($this->bool_has_been_assigned) . "~";
  448. $rtn .= "0~"; // temporary just to keep place. Should probably just be removed.
  449. $rtn .= $this->display_status . "~";
  450. $rtn .= intval($this->bool_ghost_hour) . "~";
  451. $rtn .= fp_join_assoc($this->assigned_to_degree_ids_array) . "~";
  452. $rtn .= $this->req_by_degree_id . "~";
  453. $rtn .= $this->disp_for_group_id . "~";
  454. $rtn .= $this->school_id . "~";
  455. $rtn .= $this->db_grade . "~";
  456. $rtn .= $this->extra_attribs . "~";
  457. $rtn .= $this->unique_id . "~";
  458. return $rtn;
  459. }
  460. /**
  461. * Returns back an array from our details_by_degree array, for a given property name,
  462. * like: $arr[DEGREE_ID] = $val
  463. * Useful in the to_data_string function
  464. */
  465. function get_degree_details_data_string($property_name) {
  466. $arr = array();
  467. foreach ($this->details_by_degree_array as $degree_id => $temp) {
  468. if (isset($temp[$property_name])) {
  469. $arr[$degree_id] = $temp[$property_name];
  470. }
  471. }
  472. return $arr;
  473. }
  474. /**
  475. * This is the reverse function of:
  476. * @see get_degree_details_data_string
  477. */
  478. function set_degree_details_from_data_array($arr, $property_name) {
  479. foreach ($arr as $degree_id => $val) {
  480. $this->details_by_degree_array[$degree_id][$property_name] = $val;
  481. }
  482. }
  483. /**
  484. * This function uses load_course_from_data_string, but it removes any elements which might interfere with
  485. * the course object then being used as a requirement. This is used specifically by the FlightPath object,
  486. * when creating a clone of a repeatable course.
  487. */
  488. function load_course_from_data_string_for_requirement_clone($str) {
  489. // Begin by loading THIS course from the supplied data string.
  490. $this->load_course_from_data_string($str);
  491. // Now, let's overwrite the values we don't need, since this is to be used as
  492. // a course requirement.
  493. $this->random_id = $GLOBALS['fp_courses_random_ids']++;
  494. $this->set_hours_awarded(0, 0);
  495. $this->grade = "";
  496. $this->advised_hours = 0;
  497. $this->bool_added_course = FALSE;
  498. $this->db_advised_courses_id = 0;
  499. $this->details_by_degree_array = array();
  500. $this->assigned_to_degree_ids_array = array();
  501. $this->db_substitution_id_array = array();
  502. $this->display_status = "eligible"; // match the default constructor so we don't cause issues.
  503. $this->disp_for_group_id = "";
  504. }
  505. /**
  506. * This will take a data string, as created by
  507. * the function to_data_string(), and make $this object
  508. * match the original object. It is a poor man's
  509. * unserialize. See to_data_string()'s description for a fuller
  510. * picture of what is going on.
  511. *
  512. * To use:
  513. * - $newCourse = new Course();
  514. * - $newCourse->load_course_from_data_string($data);
  515. *
  516. *
  517. * @param string $str
  518. */
  519. function load_course_from_data_string($str)
  520. {
  521. $temp = explode("~",$str);
  522. $this->course_id = $temp[0];
  523. $this->load_course($this->course_id);
  524. $this->assigned_to_semester_num = $temp[1];
  525. $this->assigned_to_group_ids_array = fp_explode_assoc($temp[2]);
  526. $this->bool_advised_to_take = (bool) $temp[3];
  527. $this->specified_repeats = $temp[4];
  528. $this->bool_specified_repeat = (bool) $temp[5];
  529. $this->grade = $temp[6];
  530. if (strstr($this->grade, "_pls_")) {
  531. $this->grade = str_replace("_pls_", "+", $this->grade);
  532. }
  533. $this->set_hours_awarded(0,floatval($temp[7]) * 1); // *1 to force numeric, and trim extra zeros.
  534. $this->term_id = $temp[8];
  535. $this->advised_hours = floatval($temp[9]) * 1;
  536. $this->bool_transfer = (bool) $temp[10];
  537. // Was this a transfer course?
  538. if ($this->bool_transfer == true)
  539. {
  540. $t_course = new Course($temp[11], true);
  541. $t_course->term_id = $this->term_id;
  542. $this->course_transfer = $t_course;
  543. }
  544. $this->bool_added_course = (bool) $temp[12];
  545. $this->db_advised_courses_id = $temp[13];
  546. $this->random_id = $temp[14];
  547. //$this->bool_substitution_by_degree_array = fp_explode_assoc($temp[15]);
  548. $this->set_degree_details_from_data_array(fp_explode_assoc($temp[15]), "bool_substitution");
  549. // Was this a substitution course?
  550. if (trim($temp[16]) != "")
  551. {
  552. $arr = fp_explode_assoc($temp[16]);
  553. foreach ($arr as $did => $cid) {
  554. $t_course = new Course($cid); // original course requirement.
  555. $t_course->req_by_degree_id = $did;
  556. $this->set_course_substitution($did, $t_course);
  557. }
  558. /*
  559. $temp2 = explode(",", $temp[16]); // contains course_id,req_by_degree_id. Need to split the values up.
  560. $t_course = new Course($temp2[0]); // original course requirement.
  561. $t_course->req_by_degree_id = $temp2[1];
  562. $this->course_substitution = $t_course;
  563. */
  564. }
  565. $this->db_substitution_id_array = fp_explode_assoc($temp[17]);
  566. $this->min_hours = floatval($temp[18]) * 1;
  567. $this->max_hours = floatval($temp[19]) * 1;
  568. //$this->bool_substitution_new_from_split = (bool) $temp[20];
  569. $this->set_degree_details_from_data_array(fp_explode_assoc($temp[20]), "bool_substitution_new_from_split");
  570. //$this->bool_substitution_split = (bool) $temp[21];
  571. $this->set_degree_details_from_data_array(fp_explode_assoc($temp[21]), "bool_substitution_split");
  572. // No longer used. Using assigned_to_degree_ids instead.
  573. //$this->bool_has_been_assigned = (bool) $temp[22];
  574. $throw_away = $temp[22]; // throw-away value. Can probably just remove entirely.
  575. $this->display_status = $temp[23];
  576. $this->bool_ghost_hour = (bool) $temp[24];
  577. $this->assigned_to_degree_ids_array = fp_explode_assoc($temp[25]);
  578. $this->req_by_degree_id = intval($temp[26]);
  579. $this->disp_for_group_id = trim($temp[27]);
  580. $this->school_id = trim($temp[28]);
  581. $this->db_grade = trim($temp[29]);
  582. $this->extra_attribs = trim($temp[30]);
  583. $this->unique_id = trim($temp[31]);
  584. }
  585. /**
  586. * This function will return a CSV string of all the possible
  587. * names for this course, in alphabetical order.
  588. *
  589. * This function is used by DataEntry primarily.
  590. *
  591. * @param bool $bool_add_white_space
  592. * @param bool $bool_add_exclude
  593. * @return string
  594. */
  595. function get_all_names($bool_add_white_space = false, $bool_add_exclude = true)
  596. {
  597. $rtn = "";
  598. $used_array = array();
  599. $table_name = "courses";
  600. if ($this->bool_use_draft) {$table_name = "draft_$table_name";}
  601. // took out: and `catalog_year`='$this->catalog_year'
  602. // because we don't care what catalog year it comes from...
  603. $res = $this->db->db_query("SELECT * FROM $table_name
  604. WHERE course_id = ?
  605. AND delete_flag = '0'
  606. ORDER BY subject_id, course_num ", $this->course_id);
  607. while($cur = $this->db->db_fetch_array($res))
  608. {
  609. if (in_array($cur["subject_id"] . "~" . $cur["course_num"], $used_array))
  610. { // skip ones we have already seen.
  611. continue;
  612. }
  613. $used_array[] = $cur["subject_id"] . "~" . $cur["course_num"];
  614. $rtn .= $cur["subject_id"] . " " . $cur["course_num"];
  615. if ($cur["exclude"] != '0' && $bool_add_exclude == true)
  616. {
  617. $rtn .= " exclude";
  618. }
  619. $rtn .= ",";
  620. if ($bool_add_white_space == true)
  621. {
  622. $rtn .= " ";
  623. }
  624. }
  625. $rtn = trim($rtn);
  626. // remove last comma.
  627. $rtn = substr($rtn,0,-1);
  628. return $rtn;
  629. }
  630. /**
  631. * The function returns either an integer of the the number of
  632. * hours the course is worth, or, a range in the form of
  633. * min-max (if the course has variable hours)
  634. *
  635. * Examples: 3 or 1-6
  636. *
  637. * @return string|float
  638. */
  639. function get_catalog_hours()
  640. {
  641. if (!$this->has_variable_hours())
  642. {
  643. // Normal course, no var hours.
  644. $h = $this->min_hours * 1;
  645. // check for ghost hours.
  646. if ($this->bool_ghost_min_hour) {
  647. $h = 0;
  648. }
  649. return $h;
  650. } else {
  651. // Meaning this does course have variable hours.
  652. $min_h = $this->min_hours*1;
  653. $max_h = $this->max_hours*1;
  654. // Convert back from ghosthours.
  655. if ($this->bool_ghost_min_hour) {
  656. $min_h = 0;
  657. }
  658. if ($this->bool_ghost_hour) {
  659. $max_h = 0;
  660. }
  661. return "$min_h-$max_h";
  662. }
  663. }
  664. /**
  665. * Returns how many hours this course has been advised for.
  666. * This is used with courses which have variable hours. If
  667. * the course has not been advised for any particular number
  668. * of hours, then it's min_hours are returned.
  669. *
  670. * @return float
  671. */
  672. function get_advised_hours()
  673. {
  674. if ($this->advised_hours > -1)
  675. {
  676. return $this->advised_hours * 1;
  677. } else {
  678. // No, the user has not selected any hours yet. So,
  679. // just display the min_hours.
  680. // Correct for ghost hours, if any.
  681. $min_h = $this->min_hours * 1;
  682. if ($this->bool_ghost_min_hour) {
  683. $min_h = 0;
  684. }
  685. return $min_h;
  686. }
  687. }
  688. /**
  689. * This will assign the $this->display_status string
  690. * based on the grade the student has made on the course.
  691. * The display_status is used by other display functions to decide
  692. * what color the course should show up as.
  693. *
  694. */
  695. function assign_display_status()
  696. {
  697. // Assigns the display status, based on grade.
  698. $grade = $this->grade;
  699. // Get these grade definitions from our system settings
  700. // Configure them in custom/settings.php
  701. $retake_grades = csv_to_array(variable_get_for_school("retake_grades", 'F,W,I', $this->school_id));
  702. $enrolled_grades = csv_to_array(variable_get_for_school("enrolled_grades",'E', $this->school_id));
  703. if (in_array($grade, $retake_grades))
  704. {
  705. $this->display_status = "retake";
  706. }
  707. if (in_array($grade, $enrolled_grades))
  708. {
  709. $this->display_status = "enrolled";
  710. }
  711. }
  712. /**
  713. * Returns TRUE if the student has completed the course
  714. * (and did not make a failing grade on it).
  715. *
  716. *
  717. *
  718. * @return bool
  719. */
  720. function is_completed()
  721. {
  722. // returns true if the course has been completed.
  723. $grade = $this->grade;
  724. // Get these grade definitions from our system settings
  725. // Configure them in custom/settings.php
  726. $retake_grades = csv_to_array(variable_get_for_school("retake_grades", 'F,W,I', $this->school_id));
  727. $enrolled_grades = csv_to_array(variable_get_for_school("enrolled_grades",'E', $this->school_id));
  728. if ($grade == "") {
  729. return false;
  730. }
  731. if (in_array($grade, $enrolled_grades)) {
  732. return false;
  733. }
  734. if (in_array($grade, $retake_grades)) {
  735. return false;
  736. }
  737. return true;
  738. }
  739. /**
  740. * Does $this meed the minimum grade requirement of the
  741. * supplied course requirement? You may specify either
  742. * a Course object, or just enter the min_grade in the mGrade
  743. * variable.
  744. *
  745. * @param Course $course_req
  746. * - The Course object who has the min grade requirement.
  747. * Set to NULL if using $m_grade.
  748. *
  749. * @param string $m_grade
  750. * - The min grade which $this must meet. Do not use if using
  751. * $course_req.
  752. *
  753. * @return bool
  754. */
  755. function meets_min_grade_requirement_of(Course $course_req = NULL, $m_grade = "", $bool_exclude_W_and_F = TRUE)
  756. {
  757. // Does $this course meet the min grade requirement
  758. // of the supplied course requirement?
  759. $m_grade = strtoupper($m_grade);
  760. // Get these grade definitions from our system settings
  761. // Configure them in custom/settings.php
  762. $enrolled_grades = csv_to_array(variable_get_for_school("enrolled_grades", 'E', $this->school_id));
  763. $retake_grades = csv_to_array(variable_get_for_school("retake_grades",'', $this->school_id));
  764. $withdrew_grades = csv_to_array(variable_get_for_school("withdrew_grades", "W", $this->school_id));
  765. $min_grade = '';
  766. if ($course_req != null) {
  767. $min_grade = strtoupper($course_req->min_grade);
  768. } else {
  769. $min_grade = $m_grade;
  770. }
  771. if ($min_grade == "")
  772. { // There is no min grade requirement for this course.
  773. return true;
  774. }
  775. // If the student is currently enrolled, return true.
  776. if (in_array($this->grade, $enrolled_grades))
  777. {
  778. return true;
  779. }
  780. if ($bool_exclude_W_and_F) {
  781. if (in_array($this->grade, $retake_grades) || in_array($this->grade, $withdrew_grades)) {
  782. return FALSE;
  783. }
  784. }
  785. // Okay, let's check those min grade requirements...
  786. $grade_order = csv_to_array(strtoupper(variable_get_for_school("grade_order", "E,AMID,BMID,CMID,DMID,FMID,A,B,C,D,F,W,I", $this->school_id)));
  787. // Make it so the indexes are the grades, their numeric values are values.
  788. $grade_order = array_flip($grade_order);
  789. // Get the "weight" of the min_grade_requirement, and $this->grade
  790. $req_weight = intval(@$grade_order[$min_grade]);
  791. $this_weight = intval(@$grade_order[$this->grade]);
  792. if ($this_weight <= $req_weight) return TRUE; // yay, we have the min grade!
  793. return false;
  794. }
  795. /**
  796. * Simply returns TRUE if $this has variable hours.
  797. *
  798. * @return bool
  799. */
  800. function has_variable_hours()
  801. {
  802. $min_h = $this->min_hours;
  803. $max_h = $this->max_hours;
  804. // Convert back from ghosthours, for the comparison.
  805. if ($this->bool_ghost_min_hour) {
  806. $min_h = 0;
  807. }
  808. if ($this->bool_ghost_hour) {
  809. $max_h = 0;
  810. }
  811. if ($min_h == $max_h)
  812. {
  813. return false;
  814. } else {
  815. return true;
  816. }
  817. }
  818. /**
  819. * Figure out the number of hours this particular
  820. * instance of the course is worth. In the case
  821. * of variable hours, it will return the number
  822. * of hours selected. If that does not exist,
  823. * it will return the MIN HOURS.
  824. *
  825. * @return float
  826. */
  827. function get_hours($degree_id = 0)
  828. {
  829. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  830. // This course might be set to 1 hour, but be a "ghost hour",
  831. // meaning the student actually earned 0 hours, but we recorded 1
  832. // to make FP's math work out. So, let's return back 0 hours.
  833. if ($this->bool_ghost_hour)
  834. {
  835. $h = 0;
  836. return $h;
  837. }
  838. // Was this course used in a substitution? If so, use the substitution hours.
  839. if ($this->get_substitution_hours($degree_id) > 0) {
  840. return floatval($this->get_substitution_hours($degree_id));
  841. }
  842. // Do they have any hours_awarded? (because they completed
  843. // the course)
  844. if ($this->get_hours_awarded($degree_id) > 0)
  845. {
  846. $h = $this->get_hours_awarded($degree_id);
  847. return floatval($h);
  848. }
  849. if ($this->has_variable_hours() && $this->advised_hours > -1) {
  850. return floatval($this->advised_hours);
  851. }
  852. // No selected hours, but it's a variable hour course.
  853. // So, return the min_hours for this course.
  854. return floatval($this->min_hours);
  855. }
  856. /**
  857. * Calculate the quality points for this course's grade and hours.
  858. *
  859. * @return int
  860. */
  861. function get_quality_points($degree_id = 0){
  862. $hours = $this->get_hours($degree_id);
  863. $grade = $this->grade;
  864. $pts = 0;
  865. $qpts_grades = array();
  866. // Let's find out what our quality point grades & values are...
  867. if (isset($GLOBALS["qpts_grades"])) {
  868. // have we already cached this?
  869. $qpts_grades = $GLOBALS["qpts_grades"];
  870. }
  871. else {
  872. $tlines = explode("\n", variable_get_for_school("quality_points_grades", "A ~ 4\nB ~ 3\nC ~ 2\nD ~ 1\nF ~ 0\nI ~ 0", $this->school_id));
  873. foreach ($tlines as $tline) {
  874. $temp = explode("~", trim($tline));
  875. if (trim($temp[0]) != "") {
  876. $qpts_grades[trim($temp[0])] = trim($temp[1]);
  877. }
  878. }
  879. $GLOBALS["qpts_grades"] = $qpts_grades; // save to cache
  880. }
  881. // Okay, find out what the points are by multiplying value * hours...
  882. if (isset($qpts_grades[$grade])) {
  883. $pts = $qpts_grades[$grade] * $hours;
  884. }
  885. return $pts;
  886. }
  887. /**
  888. * This function is used for comparing a course name to the subject_id
  889. * and course_num of $this.
  890. * We expect a space between the subject_id and CourseNum in $str.
  891. *
  892. * For example: MATH 1010
  893. *
  894. * You may also ONLY specify a subject, ex: BIOL. If you do that,
  895. * then only the subject will be compared.
  896. *
  897. * Example of use: if ($c->name_equals("ART 101")) then do this etc.
  898. *
  899. * @param string $str
  900. * @return bool
  901. */
  902. function name_equals($str)
  903. {
  904. // We expect the str to be given to us
  905. // with a space b/t the subject_id and course_num.
  906. // ex: MATH 111
  907. // may also ONLY specify the subject. ex: BIOL
  908. // If our $subject_id is not populated, then call load_descriptive_data()
  909. if ($this->subject_id == "") {
  910. $this->load_descriptive_data();
  911. }
  912. // TODO: We should check ALL names for this course. Use get_all_names to do that.
  913. $temp = explode(" ",$str);
  914. if ($this->subject_id == $temp[0] && ($this->course_num == $temp[1] || trim($temp[1]) == ""))
  915. {
  916. return TRUE;
  917. }
  918. return FALSE;
  919. }
  920. /**
  921. * Convienience function. Simply compare the course_id of
  922. * another course to $this to see if they are equal.
  923. *
  924. * This is also used by CourseList and ObjList to determine
  925. * matches.
  926. *
  927. * Usage: if ($newCourse.equals($otherCourse)) { ... }
  928. *
  929. * @param Course $course_c
  930. * @return bool
  931. */
  932. function equals(Course $course_c = null)
  933. {
  934. if ($course_c != null && $this->course_id == $course_c->course_id)
  935. {
  936. return true;
  937. }
  938. return false;
  939. }
  940. /**
  941. * Loads $this as a new course, based on course_id.
  942. *
  943. * @param int $course_id
  944. * @param bool $is_transfer
  945. */
  946. function load_course($course_id, $is_transfer = false)
  947. {
  948. if ($this->db == NULL)
  949. {
  950. $this->db = get_global_database_handler();
  951. }
  952. $catalog_line = "";
  953. if ($this->catalog_year != 0) {
  954. $catalog_line = " AND catalog_year = '" . intval($this->catalog_year) . "' ";
  955. }
  956. if ($is_transfer == FALSE) {
  957. $this->load_descriptive_data();
  958. }
  959. else {
  960. // This is a transfer course.
  961. $res = $this->db->db_query("SELECT * FROM
  962. transfer_courses a,
  963. transfer_institutions b
  964. WHERE
  965. a.transfer_course_id = ?
  966. AND a.institution_id = b.institution_id ", array($course_id));
  967. $cur = $this->db->db_fetch_array($res);
  968. if ($cur) {
  969. $this->subject_id = $cur["subject_id"];
  970. $this->course_num = $cur["course_num"];
  971. $this->course_id = $course_id;
  972. $this->school_id = $cur['school_id'];
  973. $this->bool_transfer = true;
  974. $this->institution_id = $cur["institution_id"];
  975. $this->institution_name = $cur["name"];
  976. }
  977. }
  978. $this->assign_display_status();
  979. // When we load this course, let's also check for any hooks.
  980. // Since this class might be used outside of FP, only do this if we know
  981. // that the bootstrap.inc file has been executed.
  982. if ($GLOBALS["fp_bootstrap_loaded"] == TRUE) {
  983. invoke_hook("course_load", array(&$this));
  984. }
  985. } // load_course
  986. /**
  987. * This function will correct capitalization problems in course titles.
  988. *
  989. * @param string $str
  990. *
  991. * @return string
  992. *
  993. */
  994. function fix_title($str = "")
  995. {
  996. if ($str == "")
  997. {
  998. $str = $this->title;
  999. }
  1000. // Should we do this at all? We will look at the "autocapitalize_course_titles" setting.
  1001. $auto = variable_get_for_school("autocapitalize_course_titles", 'yes', $this->school_id);
  1002. if ($auto == "no") {
  1003. // Nope! Just return.
  1004. $this->title = $str;
  1005. return $str;
  1006. }
  1007. // Otherwise, we may continue with the capitalization scheme:
  1008. $str = str_replace("/", " / ", $str);
  1009. $str = str_replace("/", " / ", $str);
  1010. $str = str_replace("-", " - ", $str);
  1011. $str = str_replace(":", ": ", $str);
  1012. $str = str_replace("(", "( ", $str);
  1013. // Only pad an ampersand if we are not talking about
  1014. // an HTML character.
  1015. if (!strstr($str,"&#"))
  1016. {
  1017. $str = str_replace("&", " & ", $str);
  1018. }
  1019. // Let's also get rid of extra spaces.
  1020. $str = str_replace(" ", " ", $str);
  1021. $str = str_replace(" ", " ", $str);
  1022. // convert to ucwords and fix some problems introduced by that.
  1023. $str = trim(ucwords(strtolower($str)));
  1024. $str = str_replace("Iii", "III", $str);
  1025. $str = str_replace("Ii", "II", $str);
  1026. $str = str_replace(" Iv"," IV",$str);
  1027. $str = str_replace(" Vi"," VI",$str);
  1028. $str = str_replace(" Of "," of ",$str);
  1029. $str = str_replace(" The "," the ",$str);
  1030. $str = str_replace(" In "," in ",$str);
  1031. $str = str_replace(" And "," and ",$str);
  1032. $str = str_replace(" An "," an ",$str);
  1033. $str = str_replace(" A "," a ",$str);
  1034. $str = str_replace(" To "," to ",$str);
  1035. $str = str_replace(" For "," for ",$str);
  1036. // Strange words and abreviations which should be changed.
  1037. $str = str_replace("Afrotc","AFROTC",$str);
  1038. $str = str_replace("Gis","GIS",$str);
  1039. $str = str_replace("Dna","DNA",$str);
  1040. $str = str_replace(" Cpr","CPR",$str);
  1041. $str = str_replace(" Rn"," RN",$str);
  1042. $str = str_replace(" Micu"," MICU",$str);
  1043. $str = str_replace(" Sicu"," SICU",$str);
  1044. $str = str_replace(" Picu"," PICU",$str);
  1045. $str = str_replace(" Nicu"," NICU",$str);
  1046. $str = str_replace("Uas ","UAS ",$str);
  1047. $str = str_replace(" Uas"," UAS",$str);
  1048. // Cleanup
  1049. $str = str_replace("( ", "(", $str);
  1050. $str = str_replace(" - ", "-", $str);
  1051. // Is this just a course name by itself? If so, it should
  1052. // all be capitalized.
  1053. $temp = explode(" ", $str);
  1054. if (count($temp) == 2
  1055. && strlen($temp[0]) <= 4
  1056. && strlen($temp[1]) <= 4)
  1057. {// We could also test to see if there are numbers starting the
  1058. // second token.
  1059. $str = strtoupper($str);
  1060. }
  1061. // If this contains the word "formerly" then we need to pull out what's
  1062. // there and make it all uppercase, except for the word Formerly.
  1063. if (strstr(strtolower($str), strtolower("formerly ")))
  1064. {
  1065. $formline = preg_replace("/.*\((formerly .*)\).*/i", "$1", $str);
  1066. $str = str_replace($formline, strtoupper($formline), $str);
  1067. $str = str_replace("FORMERLY ", "Formerly ", $str);
  1068. }
  1069. $this->title = $str;
  1070. return $str;
  1071. }
  1072. /**
  1073. * This function will load $this will all sorts of descriptive data
  1074. * from the database. For example, hours, title, description, etc.
  1075. *
  1076. * It must be called before any attempts at sorting (by alphabetical order)
  1077. * are made on lists of courses.
  1078. *
  1079. * It will by default try to load this information from cache. If it cannot
  1080. * find it in the cache, it will query the database, and then add what it finds
  1081. * to the cache.
  1082. *
  1083. *
  1084. * @param bool $bool_load_from_global_cache
  1085. * - If set to TRUE, this will attempt to load the course data
  1086. * from the "global cache", that is, the cache which is held in the
  1087. * GLOBALS array. This should usually be set to TRUE, since this is
  1088. * much faster than querying the database.
  1089. *
  1090. * @param bool $bool_ignore_catalog_year_in_cache
  1091. * - If set to TRUE, we will grab whatever is in the cache for this
  1092. * course's course_id, regardless of if the catalog years match.
  1093. * If set to FALSE, we will try to match the course's catalog year
  1094. * in the cache as well.
  1095. *
  1096. * @param bool $bool_limit_current_catalog_year
  1097. * - If set to TRUE, then we will only *query* for the course's
  1098. * catalog_year in the db, and those before it (if we do not find
  1099. * the exact catalog_year). We will not look for any catalog years
  1100. * after it. If set to FALSE, we will look through any
  1101. * valid catalog year.
  1102. *
  1103. * @param bool $bool_force_catalog_year
  1104. * - If set to TRUE, we will only look for the course's catalog
  1105. * year in the database.
  1106. *
  1107. * @param bool $bool_ignore_exclude
  1108. * - If set to TRUE, we will ignore courses marked as "exclude" in the
  1109. * database.
  1110. *
  1111. */
  1112. function load_descriptive_data($bool_load_from_global_cache = true, $bool_ignore_catalog_year_in_cache = true, $bool_limit_current_catalog_year = true, $bool_force_catalog_year = false, $bool_ignore_exclude = false, $bool_reset_ghost_hours = TRUE)
  1113. {
  1114. if ($this->db == null)
  1115. {
  1116. $this->db = get_global_database_handler();
  1117. }
  1118. $db = $this->db;
  1119. if ($this->catalog_year == "")
  1120. {
  1121. $this->catalog_year = variable_get_for_school("current_catalog_year", 2006, $this->school_id); // current catalog_year.
  1122. }
  1123. $setting_current_catalog_year = variable_get_for_school("current_catalog_year", 2006, $this->school_id) * 1;
  1124. if ($this->bool_use_draft) {
  1125. $setting_current_catalog_year = variable_get_for_school("current_draft_catalog_year", 2006, $this->school_id) * 1;
  1126. }
  1127. $earliest_catalog_year = variable_get_for_school("earliest_catalog_year", 2006, $this->school_id);
  1128. if ($setting_current_catalog_year < $earliest_catalog_year)
  1129. { // If it has not been set, assume the default.
  1130. $setting_current_catalog_year = $earliest_catalog_year;
  1131. }
  1132. if ($bool_limit_current_catalog_year == true && $setting_current_catalog_year > $earliest_catalog_year)
  1133. {
  1134. if ($this->catalog_year*1 > $setting_current_catalog_year)
  1135. {
  1136. $this->catalog_year = $setting_current_catalog_year; // current catalog_year.
  1137. }
  1138. }
  1139. if ($this->catalog_year < $earliest_catalog_year && $this->catalog_year != 1900)
  1140. {
  1141. // Out of range, so set to default
  1142. $this->catalog_year = $earliest_catalog_year;
  1143. }
  1144. $cat_line = "";
  1145. if ($bool_force_catalog_year == true)
  1146. {
  1147. $cat_line = " AND catalog_year = '$this->catalog_year' ";
  1148. }
  1149. $cache_catalog_year = $this->catalog_year;
  1150. if ($bool_ignore_catalog_year_in_cache == true)
  1151. {
  1152. $cache_catalog_year = 0;
  1153. }
  1154. if (!isset($this->array_valid_names))
  1155. {
  1156. $this->array_valid_names = array();
  1157. }
  1158. // First-- is this course in our GLOBALS cache for courses?
  1159. // If it is, then load from that.
  1160. if ($bool_load_from_global_cache == true && $this->course_id != 0 &&
  1161. @$GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["subject_id"] != "")
  1162. {
  1163. $this->subject_id = $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["subject_id"];
  1164. $this->course_num = $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["course_num"];
  1165. $this->title = $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["title"];
  1166. $this->description = $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["description"];
  1167. $this->min_hours = $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["min_hours"];
  1168. $this->school_id = $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["school_id"];
  1169. if ($bool_reset_ghost_hours) {
  1170. // Reset the ghosthours to default.
  1171. $this->bool_ghost_hour = $this->bool_ghost_min_hour = FALSE;
  1172. }
  1173. if ($this->min_hours <= 0) {
  1174. $this->min_hours = 1;
  1175. if ($bool_reset_ghost_hours) {
  1176. $this->bool_ghost_min_hour = TRUE;
  1177. }
  1178. }
  1179. $this->max_hours = $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["max_hours"];
  1180. if ($this->max_hours <= 0) {
  1181. $this->max_hours = 1;
  1182. if ($bool_reset_ghost_hours) {
  1183. $this->bool_ghost_hour = TRUE;
  1184. }
  1185. }
  1186. $this->repeat_hours = $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["repeat_hours"];
  1187. $this->db_exclude = $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["db_exclude"];
  1188. $this->array_valid_names = $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["array_valid_names"];
  1189. return;
  1190. }
  1191. if ($this->course_id != 0)
  1192. {
  1193. $exclude_line = " AND exclude = '0' ";
  1194. if ($bool_ignore_exclude) {
  1195. $exclude_line = "";
  1196. }
  1197. $table_name = "courses";
  1198. if ($this->bool_use_draft) {$table_name = "draft_$table_name";}
  1199. $res = $this->db->db_query("SELECT * FROM $table_name
  1200. WHERE course_id = ?
  1201. AND catalog_year = ?
  1202. AND delete_flag = 0
  1203. $exclude_line ", $this->course_id, $this->catalog_year);
  1204. $cur = $this->db->db_fetch_array($res);
  1205. if ($this->db->db_num_rows($res) < 1)
  1206. {
  1207. // No results found, so instead pick the most recent
  1208. // entry.
  1209. $table_name = "courses";
  1210. if ($this->bool_use_draft) {$table_name = "draft_$table_name";}
  1211. $res2 = $db->db_query("SELECT * FROM $table_name
  1212. WHERE course_id = ?
  1213. AND subject_id != ''
  1214. AND delete_flag = 0
  1215. $exclude_line
  1216. AND catalog_year <= '$setting_current_catalog_year'
  1217. $cat_line
  1218. ORDER BY `catalog_year` DESC LIMIT 1", $this->course_id);
  1219. $cur = $db->db_fetch_array($res2);
  1220. if ($db->db_num_rows($res2) < 1)
  1221. {
  1222. // Meaning, there were no results found that didn't have
  1223. // the exclude flag set.
  1224. // So, try to retrieve any course, even if it has
  1225. // been excluded (but within our catalog year range)
  1226. //$db3 = new DatabaseHandler();
  1227. $table_name = "courses";
  1228. if ($this->bool_use_draft) {$table_name = "draft_$table_name";}
  1229. $res3 = $db->db_query("SELECT * FROM $table_name
  1230. WHERE course_id = ?
  1231. AND subject_id != ''
  1232. AND delete_flag = 0
  1233. AND catalog_year <= '$setting_current_catalog_year'
  1234. $cat_line
  1235. ORDER BY `catalog_year` DESC LIMIT 1", $this->course_id);
  1236. $cur = $db->db_fetch_array($res3);
  1237. }
  1238. }
  1239. if ($cur) {
  1240. // Meaning, we DID find something.
  1241. $this->title = $this->fix_title($cur["title"]);
  1242. $this->description = trim($cur["description"]);
  1243. $this->subject_id = trim(strtoupper($cur["subject_id"]));
  1244. $this->course_num = trim(strtoupper($cur["course_num"]));
  1245. $this->school_id = intval($cur["school_id"]);
  1246. $this->min_hours = $cur["min_hours"] * 1; //*1 will trim extra zeros from end of decimals
  1247. $this->max_hours = $cur["max_hours"] * 1;
  1248. if ($bool_reset_ghost_hours) {
  1249. // Reset the ghosthours to default.
  1250. $this->bool_ghost_hour = $this->bool_ghost_min_hour = FALSE;
  1251. }
  1252. if ($this->min_hours <= 0) {
  1253. $this->min_hours = 1;
  1254. if ($bool_reset_ghost_hours) {
  1255. $this->bool_ghost_min_hour = TRUE;
  1256. }
  1257. }
  1258. if ($this->max_hours <= 0) {
  1259. $this->max_hours = 1;
  1260. if ($bool_reset_ghost_hours) {
  1261. $this->bool_ghost_hour = TRUE;
  1262. }
  1263. }
  1264. $this->repeat_hours = $cur["repeat_hours"] * 1;
  1265. if ($this->repeat_hours <= 0)
  1266. {
  1267. $this->repeat_hours = $this->max_hours;
  1268. }
  1269. $this->db_exclude = $cur["exclude"];
  1270. $this->data_entry_comment = $cur["data_entry_comment"];
  1271. } // if cur
  1272. // Now, lets get a list of all the valid names for this course.
  1273. // In other words, all the non-excluded names. For most
  1274. // courses, this will just be one name. But for cross-listed
  1275. // courses, this will be 2 or more (probably just 2 though).
  1276. // Example: MATH 373 and CSCI 373 are both valid names for that course.
  1277. $table_name = "courses";
  1278. if ($this->bool_use_draft) {$table_name = "draft_$table_name";}
  1279. $res = $this->db->db_query("SELECT * FROM $table_name
  1280. WHERE course_id = ?
  1281. AND exclude = 0 ", $this->course_id);
  1282. while($cur = $this->db->db_fetch_array($res))
  1283. {
  1284. $si = $cur["subject_id"];
  1285. $cn = $cur["course_num"];
  1286. if (in_array("$si~$cn", $this->array_valid_names))
  1287. {
  1288. continue;
  1289. }
  1290. $this->array_valid_names[] = "$si~$cn";
  1291. }
  1292. } else if ($this->bool_transfer == true)
  1293. {
  1294. // This is a transfer credit which did not have a local
  1295. // course eqv. At the moment, the subject_id and
  1296. // course_num are empty. So, let's fill them in with the
  1297. // transfer credit's information.
  1298. if ($this->course_transfer != null)
  1299. {
  1300. $this->subject_id = $this->course_transfer->subject_id;
  1301. $this->course_num = $this->course_transfer->course_num;
  1302. if ($this->course_transfer->get_hours_awarded() > 0)
  1303. {
  1304. $this->set_hours_awarded(0, $this->course_transfer->get_hours_awarded());
  1305. }
  1306. }
  1307. }
  1308. if ($this->description == "")
  1309. {
  1310. $this->description = "There is no course description available at this time.";
  1311. }
  1312. if ($this->title == "")
  1313. {
  1314. $this->title = "$this->subject_id $this->course_num";
  1315. }
  1316. // Now, to reduce the number of database calls in the future, save this
  1317. // to our GLOBALS cache...
  1318. // We do need to go back and correct the ghost hours, setting them
  1319. // back to 0 hrs, or else this will be a problem.
  1320. $min_hours = $this->min_hours;
  1321. $max_hours = $this->max_hours;
  1322. if ($bool_reset_ghost_hours) {
  1323. if ($this->bool_ghost_min_hour) $min_hours = 0;
  1324. if ($this->bool_ghost_hour) $max_hours = 0;
  1325. }
  1326. // Since we may have trouble characters in the description (like smart quotes) let's
  1327. // do our best to try to clean it up a little.
  1328. //$this->description = utf8_encode($this->description);
  1329. // utf8_encode is deprecated in php 8.2 and will be removed in PHP 9. Let's use a more modern approach:
  1330. $this->description = fp_utf8_encode($this->description);
  1331. $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["subject_id"] = $this->subject_id;
  1332. $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["course_num"] = $this->course_num;
  1333. $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["title"] = $this->title;
  1334. $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["description"] = $this->description;
  1335. $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["school_id"] = $this->school_id;
  1336. $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["min_hours"] = $min_hours;
  1337. $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["max_hours"] = $max_hours;
  1338. $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["repeat_hours"] = $this->repeat_hours;
  1339. $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["db_exclude"] = $this->db_exclude;
  1340. $GLOBALS["fp_course_inventory"][$this->course_id][$cache_catalog_year]["array_valid_names"] = $this->array_valid_names;
  1341. $GLOBALS["cache_course_inventory"] = true; // rebuild this cache before it closes.
  1342. }
  1343. /**
  1344. * Similar to load_descriptive_data(), this will load whatever we have
  1345. * for $this transfer course.
  1346. *
  1347. * @param string $student_id
  1348. * - If != '', we will look for the course data which has been
  1349. * assigned for this particular student. If it == '', we will
  1350. * just use the first bit of data we find.
  1351. *
  1352. */
  1353. function load_descriptive_transfer_data($student_id = "", $term_id = NULL)
  1354. {
  1355. // This method should be called to load transfer course data
  1356. // into THIS object. It assumes that $this->course_id is a transfer
  1357. // course's ID, which can be looked up in flightpath.transfer_courses.
  1358. // If a student_id is specified, it will load eqv information.
  1359. if ($this->db == null)
  1360. {
  1361. $this->db = get_global_database_handler();
  1362. }
  1363. $res = $this->db->db_query("SELECT * FROM transfer_courses
  1364. WHERE transfer_course_id = ? ", $this->course_id);
  1365. $cur = $this->db->db_fetch_array($res);
  1366. $this->subject_id = $cur["subject_id"];
  1367. $this->course_num = $cur['course_num'];
  1368. $this->title = $this->fix_title($cur['title']);
  1369. $this->min_hours = $cur["min_hours"] * 1;
  1370. $this->max_hours = $cur["max_hours"] * 1;
  1371. $this->institution_id = $cur["institution_id"];
  1372. $this->school_id = intval($cur['school_id']);
  1373. // Try to figure out the institution name for this course...
  1374. $this->institution_name = $this->db->get_institution_name($this->institution_id);
  1375. if ($student_id != "")
  1376. {
  1377. // Because transfer credit titles may differ from student
  1378. // to student, let's look up the title in the per-student transfer courses table...
  1379. $res = $this->db->db_query("SELECT * FROM student_transfer_courses
  1380. WHERE student_id = ?
  1381. AND transfer_course_id = ?
  1382. ", $student_id, $this->course_id);
  1383. $cur = $this->db->db_fetch_array($res);
  1384. if ($cur) {
  1385. if (fp_trim(@$cur["student_specific_course_title"]) != "") {
  1386. $this->title = trim($cur["student_specific_course_title"]);
  1387. }
  1388. // Also assign hours_awarded and other values while we are here
  1389. $this->set_hours_awarded(0, floatval($cur["hours_awarded"]));
  1390. $this->grade = $cur["grade"];
  1391. $this->term_id = $cur["term_id"];
  1392. ///////////////////
  1393. // If a term_id was specified, then let's try to see if we can get more specific information for this course.
  1394. if ($term_id != NULL) {
  1395. $res = $this->db->db_query("SELECT * FROM student_transfer_courses
  1396. WHERE student_id = ?
  1397. AND transfer_course_id = ?
  1398. AND term_id = ?
  1399. ", $student_id, $this->course_id, $term_id);
  1400. if ($res) {
  1401. $cur = $this->db->db_fetch_array($res);
  1402. if ($cur) {
  1403. if (trim($cur["student_specific_course_title"]) != "") {
  1404. $this->title = trim($cur["student_specific_course_title"]);
  1405. }
  1406. // Also assign hours_awarded and other values while we are here
  1407. if ($cur["grade"] != "" || $cur["hours_awarded"] != "") {
  1408. $this->set_hours_awarded(0, $cur["hours_awarded"] * 1);
  1409. $this->grade = $cur["grade"];
  1410. }
  1411. $this->term_id = $cur["term_id"];
  1412. }
  1413. }
  1414. } // if term_id != NULL
  1415. $already = array(); // to prevent duplicates from showing up, keep up with
  1416. // eqv's we've already recorded.
  1417. $res2 = $this->db->db_query("SELECT * FROM transfer_eqv_per_student
  1418. WHERE student_id = ?
  1419. AND transfer_course_id = ?
  1420. ", $student_id, $this->course_id);
  1421. while($cur2 = $this->db->db_fetch_array($res2))
  1422. {
  1423. if (!in_array($cur2["local_course_id"], $already)) {
  1424. $c = new Course($cur2["local_course_id"]);
  1425. $this->transfer_eqv_text .= "$c->subject_id $c->course_num
  1426. (" . $c->get_catalog_hours() . " " . t("hrs") . ") ";
  1427. $already[] = $cur2["local_course_id"];
  1428. }
  1429. }
  1430. } // if cur
  1431. } // if student_id
  1432. }
  1433. /**
  1434. * Based on $this->term_id, set what catalog year should go with
  1435. * the course.
  1436. *
  1437. */
  1438. function set_catalog_year_from_term_id()
  1439. {
  1440. if ($this->db == null)
  1441. {
  1442. $this->db = get_global_database_handler();
  1443. }
  1444. if (strstr($this->term_id, "1111"))
  1445. {
  1446. $this->catalog_year = variable_get_for_school("earliest_catalog_year", 2006, $this->school_id);
  1447. }
  1448. $this->catalog_year = trim(substr($this->term_id,0,4));
  1449. // If the catalog year is greater than the currentCatalogYear
  1450. // setting, then set it to that.
  1451. if ($this->catalog_year > variable_get_for_school("current_catalog_year","", $this->school_id))
  1452. {
  1453. $this->catalog_year = variable_get_for_school("current_catalog_year","", $this->school_id);
  1454. }
  1455. }
  1456. /**
  1457. * Based on $this->term_id, returns a plain english description
  1458. * of the term. For example, 20061 would return "Spring of 2006".
  1459. *
  1460. * @param bool $bool_abbreviate
  1461. * - If set to TRUE, abbreviations will be used. For example,
  1462. * Spring will be "Spr" and 2006 will be '06.
  1463. *
  1464. *
  1465. * @return string
  1466. */
  1467. function get_term_description($bool_abbreviate = FALSE)
  1468. {
  1469. // Let's use the built-in FP function
  1470. return get_term_description($this->term_id, $bool_abbreviate, $this->school_id);
  1471. }
  1472. /**
  1473. * Basically, this is a comparator function that will return true
  1474. * if $this equals many of the attributes of $course_c. Useful for
  1475. * seeing if $this is an "instance of" a particular course, but not
  1476. * necessairily the course that the student took. Example: if you want
  1477. * to test if MATH 101 is part of a group. You wouldn't use ==, since
  1478. * all the attributes might not be the same.
  1479. *
  1480. * @param Course $course_c
  1481. *
  1482. * @return bool
  1483. */
  1484. function equals_placeholder(Course $course_c)
  1485. {
  1486. // First, see if the courses are identical.
  1487. if ($this->equals($course_c))
  1488. {
  1489. return true;
  1490. }
  1491. // Okay, now we go through and test for particular attributes
  1492. // to be equal.
  1493. if ($this->subject_id == $course_c->subject_id
  1494. && $this->course_num == $course_c->course_num
  1495. && $this->institution == $course_c->institution)
  1496. {
  1497. return true;
  1498. }
  1499. return false;
  1500. }
  1501. /**
  1502. * This is the to_string method for Course. Because we want to pass it
  1503. * values, we are not using the magic method of "__to_string". So, to use,
  1504. * invoke this method directly. Ex:
  1505. *
  1506. * $x = $newCourse->to_string("", true);
  1507. *
  1508. * @param string $pad
  1509. * - How much padding to use. Specified in the form of a string
  1510. * of spaces. Ex: " "
  1511. *
  1512. * @param bool $bool_show_random
  1513. * - Display the randomly assigned number which goes with
  1514. * this course.
  1515. *
  1516. * @return string
  1517. */
  1518. function to_string($pad = " ", $bool_show_random = false)
  1519. {
  1520. $rtn = "";
  1521. if ($this->subject_id == "") {
  1522. $this->load_descriptive_data();
  1523. }
  1524. $x = '';
  1525. if ($bool_show_random) {$x = "rnd:$this->random_id -";}
  1526. $rtn = $pad . "$this->course_id $x- $this->subject_id $this->course_num (" . $this->get_hours_awarded() . ") $this->grade $this->term_id";
  1527. if ($this->course_list_fulfilled_by->is_empty != true) {
  1528. // In other words, if this is a requirement, and it is
  1529. // being fulfilled by one of the student's courses,
  1530. // then let's see it.
  1531. $rtn .= " ->fulfilled by " . $this->course_list_fulfilled_by->get_first()->to_string("");
  1532. }
  1533. if ($this->bool_transfer == true && is_object($this->course_transfer))
  1534. {
  1535. $rtn .= " - XFER eqv to " . $this->course_transfer->to_string("");
  1536. } else if ($this->bool_transfer == true){
  1537. $rtn .= " - XFER no eqv ";
  1538. }
  1539. if ($this->bool_advised_to_take) {
  1540. $rtn .= " - adv in sem " . $this->assigned_to_semester_num . ".";
  1541. }
  1542. if ($this->bool_substitution) {
  1543. $rtn .= " - substitution.";
  1544. }
  1545. if ($this->db_exclude > 0) {
  1546. $rtn .= " - db_exclude = $this->db_exclude";
  1547. }
  1548. if ($this->specified_repeats > 0) {
  1549. $rtn .= " reps: $this->specified_repeats";
  1550. }
  1551. $rtn .= "\n";
  1552. return $rtn;
  1553. }
  1554. /**
  1555. * Return TRUE or FALSE if this this course was ever assigned to the supplied group_id.
  1556. * if $group_id == -1, then return TRUE if it was assigned to ANY group.
  1557. */
  1558. function get_bool_assigned_to_group_id($group_id) {
  1559. // Trim and force NULL or 0 to be ''. This is for PHP 8 compatibility.
  1560. $group_id = fp_trim($group_id);
  1561. if (is_numeric($group_id) && intval($group_id) == 0) {
  1562. $group_id = '';
  1563. }
  1564. $bool_yes_specific_group = FALSE;
  1565. $bool_yes_any_group = FALSE;
  1566. foreach ($this->assigned_to_group_ids_array as $k => $v) {
  1567. if (intval($v) > 0 || strlen($v) > 0) {
  1568. $bool_yes_any_group = TRUE;
  1569. }
  1570. // Convert 0 and NULL to '' for PHP 8 compatibility
  1571. if (is_numeric($v) && intval($v) == 0) $v = '';
  1572. if ($v == NULL) $v = '';
  1573. if ($group_id == $v) {
  1574. $bool_yes_specific_group = TRUE;
  1575. }
  1576. }
  1577. if ($group_id == -1) {
  1578. return $bool_yes_any_group;
  1579. }
  1580. // Else...
  1581. return $bool_yes_specific_group;
  1582. }
  1583. /**
  1584. * Return the first element in our assigned_to_group_ids_array, or FALSE
  1585. */
  1586. function get_first_assigned_to_group_id() {
  1587. if (count($this->assigned_to_group_ids_array) < 1) return FALSE;
  1588. // Otherwise, get it.
  1589. $x = reset($this->assigned_to_group_ids_array); // returns the first element.
  1590. if ($x == 0) { // not a valid group_id number
  1591. return FALSE;
  1592. }
  1593. // Otherwise, return x
  1594. return $x;
  1595. }
  1596. /**
  1597. * Has the course been assigned to ANY degree?
  1598. */
  1599. function get_has_been_assigned_to_any_degree() {
  1600. if (isset($this->assigned_to_degree_ids_array) && count($this->assigned_to_degree_ids_array) > 0) return TRUE;
  1601. return FALSE;
  1602. }
  1603. function get_has_been_assigned_to_degree_id($degree_id = 0) {
  1604. if ($degree_id == 0) $degree_id = $this->req_by_degree_id;
  1605. if (in_array($degree_id, $this->assigned_to_degree_ids_array)) {
  1606. return TRUE;
  1607. }
  1608. return FALSE;
  1609. }
  1610. /**
  1611. * This is the magic method __sleep(). PHP will call this method any time
  1612. * this object is being serialized. It is supposed to return an array of
  1613. * all the variables which need to be serialized.
  1614. *
  1615. * What we are doing in it is skipping
  1616. * any variables which we are not using or which do not need to be
  1617. * serialized. This will greatly reduce the size of the final serialized
  1618. * string.
  1619. *
  1620. * It may not seem worth it at first, but consider that we may be serializing
  1621. * an entire degree plan, with a dozen groups, each with every course in the
  1622. * catalog. That could easily be 10,000+ courses which get serialized!
  1623. *
  1624. * @return array
  1625. */
  1626. function __sleep()
  1627. {
  1628. // This is supposed to return an array with the names
  1629. // of the variables which are supposed to be serialized.
  1630. $arr = array(
  1631. "db_advised_courses_id", "random_id",
  1632. "db_substitution_id_array", "db_unassign_transfer_id",
  1633. "db_exclude", "array_index", "db_group_requirement_id", "db_degree_requirement_id", "array_valid_names",
  1634. "data_entry_value", "db_group_attributes", "appears_in_semester_nums", "extra_attribs",
  1635. "subject_id", "course_num", "course_id", "requirement_type", "catalog_year",
  1636. "min_hours", "max_hours", "repeat_hours", "bool_outdated_sub",
  1637. "bool_taken", "term_id", "section_number", "grade", "db_grade", "quality_points",
  1638. "bool_transfer", "institution_id", "institution_name", "course_transfer", "transfer_footnote",
  1639. "substitution_footnote",
  1640. "min_grade", "specified_repeats", "bool_specified_repeat", "required_on_branch_id",
  1641. "assigned_to_group_id", "assigned_to_semester_num", "level_code", "req_by_degree_id",
  1642. "assigned_to_degree_ids_array", "assigned_to_group_ids_array", "school_id",
  1643. "advised_hours", "bool_selected", "bool_advised_to_take", "bool_use_draft",
  1644. "course_list_fulfilled_by",
  1645. "bool_added_course", "group_list_unassigned",
  1646. "details_by_degree_array",
  1647. "display_status", "disp_for_group_id",
  1648. "bool_hide_grade", "bool_ghost_hour",
  1649. "bool_ghost_min_hour",
  1650. );
  1651. // Okay, remove any variables we are not using
  1652. // from the array.
  1653. $rtn = array();
  1654. foreach($arr as $var)
  1655. {
  1656. if (isset($this->$var)) // This checks to see if we are using
  1657. { // the variable or not.
  1658. $rtn[] = $var;
  1659. }
  1660. }
  1661. return $rtn;
  1662. }
  1663. } // end of Course class.

Classes

Namesort descending Description
Course