advise.module

  1. 5.x modules/advise/advise.module
  2. 4.x modules/advise/advise.module

Functions & methods

NameDescription
advise_can_access_viewUsed by the menu to determine if the user can see the View tab for the current student.
advise_clear_cacheImplementation of hook_clear_cache Called by other modules, this function will take care of clearing anything this module has cached.
advise_display_popup_change_termThis popup allows the advisor to change the advising term.
advise_display_popup_change_track
advise_display_popup_change_track_non_dynamic_degreeThis is the "change track" popup we will display if the degree cannot be combined with anything else (non-dynamic).
advise_display_popup_course_description
advise_display_popup_group_select
advise_display_popup_substitute_selected
advise_display_viewThis is the page which actually displays the "view" for the user to see their advising session, or for an advisor to advise them.
advise_get_advisees
advise_initImplementation of hook_init
advise_init_advising_variablesTakes various variables from the REQUEST and stores them in our advising_session_variables table for more convenient use later on.
advise_init_screen
advise_menu
advise_perform_clear_advising_cacheFrom menu hook. Clear just the advising cache.
advise_permImplementation of hook_perm
advise_toggle_draft_form
advise_toggle_draft_form_submit
advise_user_can_view_advising_session_access_callbackThis is an access callback. Can the user view the advising session specified in the REQUEST?
advise_what_if_selection_form
advise_what_if_selection_form_submitSubmit handler for the what if selection form. Since at this point we have passed validation, let's just assemble the URL we need to now redirect to.
advise_what_if_selection_form_validateValidate handler for the what_if selection form. This is where we might, for example, make sure that if a non-dynamic degree was selected, that they can't proceed.
hook_advise_build_screen_elementsThis is a hook which developers may use to add custom blocks (or perform other operations) onto the advising View or What If screen.
z__old__advise_display_popup_change_track
z___advise_display_what_if_selectionDisplays the pulldown select list for picking a new What If degree. Returns HTML.

File

modules/advise/advise.module
View source
  1. <?php
  2. function advise_menu() {
  3. $items = array();
  4. $items["admin-tools/toggle-draft"] = array(
  5. "title" => "Toggle Draft Mode",
  6. "page_callback" => "fp_render_form",
  7. "page_arguments" => array("advise_toggle_draft_form"),
  8. "access_arguments" => array("toggle_draft"),
  9. "page_settings" => array(
  10. "menu_links" => array(
  11. 0 => array(
  12. "text" => "Back to Main",
  13. "path" => "main",
  14. ),
  15. ),
  16. ),
  17. "type" => MENU_TYPE_TAB,
  18. "tab_parent" => "main",
  19. );
  20. $items["admin-tools/clear-advising-cache"] = array(
  21. "title" => "Clear advising cache",
  22. "page_callback" => "advise_perform_clear_advising_cache",
  23. "access_arguments" => array("toggle_draft"),
  24. "type" => MENU_TYPE_NORMAL_ITEM,
  25. );
  26. $items["view"] = array(
  27. "title" => "View",
  28. "page_callback" => "advise_display_view",
  29. "page_arguments" => array("view"),
  30. "access_callback" => "advise_can_access_view",
  31. "tab_family" => "system",
  32. "page_settings" => array (
  33. "display_currently_advising" => TRUE,
  34. "display_greeting" => TRUE,
  35. "page_has_search" => TRUE,
  36. ),
  37. "weight" => 30,
  38. "type" => MENU_TYPE_TAB,
  39. );
  40. $items["view/print"] = array(
  41. "title" => "View",
  42. "page_callback" => "advise_display_view",
  43. "page_arguments" => array("view"),
  44. "access_callback" => TRUE,
  45. "page_settings" => array (
  46. "display_currently_advising" => TRUE,
  47. "bool_print" => TRUE,
  48. "screen_mode" => "not_advising",
  49. ),
  50. "type" => MENU_TYPE_CALLBACK,
  51. );
  52. $items["what-if"] = array(
  53. "title" => "What If?",
  54. "page_callback" => "advise_display_view",
  55. "page_arguments" => array("what-if"),
  56. "access_callback" => "advise_can_access_view",
  57. "tab_family" => "system",
  58. "page_settings" => array (
  59. "display_currently_advising" => TRUE,
  60. "display_greeting" => TRUE,
  61. "page_has_search" => TRUE,
  62. ),
  63. "weight" => 60,
  64. "type" => MENU_TYPE_TAB,
  65. );
  66. $items["what-if/print"] = array(
  67. "title" => "What If?",
  68. "page_callback" => "advise_display_view",
  69. "page_arguments" => array("what-if"),
  70. "access_callback" => TRUE,
  71. "page_settings" => array (
  72. "display_currently_advising" => TRUE,
  73. "bool_print" => TRUE,
  74. "screen_mode" => "not_advising",
  75. ),
  76. "type" => MENU_TYPE_CALLBACK,
  77. );
  78. $items["history"] = array(
  79. "title" => "History",
  80. "page_callback" => "advise_display_history",
  81. "access_callback" => "advise_can_access_view",
  82. "tab_family" => "system",
  83. "page_settings" => array (
  84. "display_currently_advising" => TRUE,
  85. "display_greeting" => TRUE,
  86. "page_has_search" => TRUE,
  87. ),
  88. "weight" => 40,
  89. "type" => MENU_TYPE_TAB,
  90. "file" => menu_get_module_path("advise") . "/advise.history.inc",
  91. );
  92. // My popups....
  93. $items["advise/popup-display-summary"] = array(
  94. "title" => "Advising Summary",
  95. "page_callback" => "advise_popup_display_summary",
  96. "access_callback" => "advise_user_can_view_advising_session_access_callback",
  97. "page_settings" => array(
  98. "page_is_popup" => TRUE,
  99. "page_hide_report_error" => TRUE,
  100. "bool_print" => TRUE,
  101. ),
  102. "type" => MENU_TYPE_CALLBACK,
  103. "file" => menu_get_module_path("advise") . "/advise.history.inc",
  104. );
  105. $items["advise/popup-change-term"] = array(
  106. "title" => "Change advising term",
  107. "page_callback" => "advise_display_popup_change_term",
  108. "access_arguments" => array("can_advise_students"),
  109. "page_settings" => array(
  110. "page_is_popup" => TRUE,
  111. "page_hide_report_error" => TRUE,
  112. ),
  113. "type" => MENU_TYPE_CALLBACK,
  114. );
  115. $items["advise/popup-change-track"] = array(
  116. "title" => "Change advising track",
  117. "page_callback" => "advise_display_popup_change_track",
  118. "access_arguments" => array("access_logged_in_content"),
  119. "page_settings" => array(
  120. "page_is_popup" => TRUE,
  121. "page_hide_report_error" => TRUE,
  122. ),
  123. "type" => MENU_TYPE_CALLBACK,
  124. );
  125. $items["advise/popup-course-description"] = array(
  126. "title" => "Description",
  127. "page_callback" => "advise_display_popup_course_description",
  128. "access_callback" => TRUE,
  129. "page_settings" => array(
  130. "page_is_popup" => TRUE,
  131. "page_hide_report_error" => TRUE,
  132. ),
  133. "weight" => 10,
  134. );
  135. $items["advise/popup-substitute-selected"] = array(
  136. "title" => "Substitute",
  137. "page_callback" => "advise_display_popup_substitute_selected",
  138. "access_arguments" => array("can_substitute"),
  139. "page_settings" => array(
  140. "page_is_popup" => TRUE,
  141. "page_hide_report_error" => TRUE,
  142. ),
  143. "weight" => 10,
  144. );
  145. $items["advise/popup-group-select"] = array(
  146. "title" => "Select",
  147. "page_callback" => "advise_display_popup_group_select",
  148. "access_callback" => TRUE,
  149. "page_settings" => array(
  150. "page_is_popup" => TRUE,
  151. "page_hide_report_error" => TRUE,
  152. ),
  153. "weight" => 10,
  154. );
  155. // Toolbox...
  156. $items["advise/popup-toolbox/transfers"] = array(
  157. "title" => "Transfers",
  158. "page_callback" => "advise_display_popup_toolbox_transfers",
  159. "access_arguments" => array("can_substitute"),
  160. "page_settings" => array(
  161. "page_is_popup" => TRUE,
  162. "page_hide_report_error" => TRUE,
  163. ),
  164. "weight" => 10,
  165. "type" => MENU_TYPE_TAB,
  166. "tab_family" => "advise-toolbox",
  167. "file" => menu_get_module_path("advise") . "/advise.toolbox.inc",
  168. );
  169. $items["advise/popup-toolbox/substitutions"] = array(
  170. "title" => "Substitutions",
  171. "page_callback" => "advise_display_popup_toolbox_substitutions",
  172. "access_arguments" => array("can_substitute"),
  173. "page_settings" => array(
  174. "page_is_popup" => TRUE,
  175. "page_hide_report_error" => TRUE,
  176. ),
  177. "weight" => 20,
  178. "type" => MENU_TYPE_TAB,
  179. "tab_family" => "advise-toolbox",
  180. "file" => menu_get_module_path("advise") . "/advise.toolbox.inc",
  181. );
  182. $items["advise/popup-toolbox/moved"] = array(
  183. "title" => "Moved",
  184. "page_callback" => "advise_display_popup_toolbox_moved",
  185. "access_arguments" => array("can_substitute"),
  186. "page_settings" => array(
  187. "page_is_popup" => TRUE,
  188. "page_hide_report_error" => TRUE,
  189. ),
  190. "weight" => 30,
  191. "type" => MENU_TYPE_TAB,
  192. "tab_family" => "advise-toolbox",
  193. "file" => menu_get_module_path("advise") . "/advise.toolbox.inc",
  194. );
  195. $items["advise/popup-toolbox/courses"] = array(
  196. "title" => "Courses",
  197. "page_callback" => "advise_display_popup_toolbox_courses",
  198. "access_arguments" => array("can_substitute"),
  199. "page_settings" => array(
  200. "page_is_popup" => TRUE,
  201. "page_hide_report_error" => TRUE,
  202. ),
  203. "weight" => 40,
  204. "type" => MENU_TYPE_TAB,
  205. "tab_family" => "advise-toolbox",
  206. "file" => menu_get_module_path("advise") . "/advise.toolbox.inc",
  207. );
  208. return $items;
  209. }
  210. /**
  211. * Used by the menu to determine if the user can see the View tab for the current student.
  212. */
  213. function advise_can_access_view($student_id = "") {
  214. global $current_student_id, $user;
  215. if ($student_id == "") $student_id = $current_student_id;
  216. // must be logged in first...
  217. if (!user_has_permission("access_logged_in_content")) return FALSE;
  218. if ($student_id == "" || $student_id === 0) return FALSE;
  219. if ($user->id == 1) return TRUE; // the admin user.
  220. // Can the user view ANY advising session?
  221. if (user_has_permission("view_any_advising_session")) return TRUE;
  222. // can the user only see their own advisees, and is this student one of their advisees?
  223. if (user_has_permission("view_advisee_advising_session")) {
  224. // Is the student_id in their list of advisees?
  225. $advisees = advise_get_advisees();
  226. if (in_array($student_id, $advisees)) return TRUE;
  227. }
  228. // Is this user viewing THEIR OWN advising session?
  229. if (user_has_permission("view_own_advising_session")) {
  230. if ($student_id == $user->cwid && ($student_id != "" && $student_id !== 0)) return TRUE;
  231. }
  232. // All else fails, return FALSE
  233. return FALSE;
  234. }
  235. function advise_get_advisees($faculty_id = "") {
  236. global $user;
  237. if ($faculty_id == "") $faculty_id = $user->cwid;
  238. $rtn = array();
  239. $res = db_query("SELECT * FROM advisor_student WHERE faculty_id = ?", $faculty_id);
  240. foreach ($res as $cur) {
  241. $rtn[] = $cur["student_id"];
  242. }
  243. return $rtn;
  244. }
  245. function advise_toggle_draft_form() {
  246. $form = array();
  247. $form["mark" . $m++] = array(
  248. "value" => "<p>" . t("By turning Draft Mode on, you will be able
  249. to view degree plans which are still in 'Draft' mode
  250. in both the regular View tab, as well as the Blank Degrees module,
  251. if enabled.") . "</p>",
  252. );
  253. $form["draft"] = array(
  254. "type" => "radios",
  255. "label" => t("Enable Draft Mode?"),
  256. "options" => array("yes" => t("Yes"), "no" => t("No")),
  257. "value" => $_SESSION["fp_draft_mode"],
  258. );
  259. $form["submit"] = array(
  260. "type" => "submit",
  261. "value" => t("Submit"),
  262. "prefix" => "<hr>",
  263. );
  264. $form["#redirect"] = array(
  265. "path" => "main",
  266. "query" => "",
  267. );
  268. return $form;
  269. }
  270. function advise_toggle_draft_form_submit($form, $form_state) {
  271. fp_add_message(t("Draft mode successfully updated."));
  272. $_SESSION["fp_draft_mode"] = $form_state["values"]["draft"];
  273. }
  274. /**
  275. * Lets the user change the track for this degree.
  276. */
  277. function z__old__advise_display_popup_change_track() {
  278. global $degree_plan, $student;
  279. $rtn = "";
  280. advise_init_screen();
  281. fp_add_js(fp_get_module_path("advise") . "/js/advise.js");
  282. $degree_plan->load_descriptive_data();
  283. $rtn .= fp_render_curved_line(t("Select a Degree Option"));
  284. $rtn .= "<div class='tenpt'>
  285. " . t("The student's degree has one or more degree options, which affects which courses are required.
  286. Please select a degree option (or track) from the list below.") . "
  287. <br><br>
  288. " . t("If you are unsure of what to do, simply close this window.");
  289. $rtn .= "<br><br><b>" . $degree_plan->title . "</b> " . t("degree options:") . "</div><!--DEFAULT-->
  290. <ul>";
  291. // Get the list of available tracks for this student.
  292. if (!$tracks = $degree_plan->get_available_tracks())
  293. {
  294. $rtn .= "<li>" . t("This major has no degree options.") . "</li>";
  295. }
  296. // Is there a "default" message for all tracks, which will override
  297. // any other track descriptions?
  298. // We need to look through all the tracks for the
  299. // characters: "DEFAULT:"
  300. // If we find this, then this is the default description
  301. // which applies to all the tracks, and it should be displayed
  302. // at the top.
  303. $bool_default_description = false;
  304. for ($t = 0; $t < count($tracks); $t++)
  305. {
  306. $temp = explode(" ~~ ", $tracks[$t]);
  307. $track_code = trim($temp[0]);
  308. $track_title = trim($temp[1]);
  309. $track_description = trim($temp[2]);
  310. if (strstr($track_description, "DEFAULT:")) {
  311. // Yes! We found a default message.
  312. $bool_default_description = true;
  313. $track_description = filter_markup(trim(str_replace("DEFAULT:", "", $track_description)));
  314. $track_description = "<div style='padding-top: 10px;' class='tenpt'>$track_description</div>";
  315. $rtn = str_replace("<!--DEFAULT-->",$track_description, $rtn);
  316. break;
  317. }
  318. }
  319. for ($t = 0; $t < count($tracks); $t++)
  320. {
  321. $temp = explode(" ~~ ", $tracks[$t]);
  322. $track_code = trim($temp[0]);
  323. $track_title = trim($temp[1]);
  324. $track_description = "";
  325. // If this is the current track_code, mark it as such.
  326. if ($student->array_settings["track_code"] == $track_code
  327. && $student->array_settings["major_code"] == $degree_plan->major_code)
  328. {
  329. $track_title .= " <b>(" . t("current") . ")</b>";
  330. }
  331. if ($bool_default_description == false)
  332. {
  333. $track_description = filter_markup(trim($temp[2]));
  334. if ($track_description != "")
  335. {
  336. $track_description = " - $track_description";
  337. }
  338. }
  339. $temp_tc = $track_code;
  340. if ($temp_tc == "")
  341. {
  342. $temp_tc = "none";
  343. }
  344. $link = fp_get_js_confirm_link(t("Are you sure you wish to change degree options?"), "opener.changeTrack(\"$temp_tc\"); window.close(); ", $track_title);
  345. if ($GLOBALS["fp_advising"]["advising_what_if"] == "yes") {
  346. $link = "<a href='javascript: popupChangeWhatIfTrack(\"$temp_tc\", \"" . t("Are you sure you wish to change degree options?") . "\");'>$track_title</a>";
  347. }
  348. $rtn .= "<li class='tenpt' style='padding:3px;'>
  349. $link $track_description</li>";
  350. }
  351. $rtn .= "</ul>";
  352. return $rtn;
  353. }
  354. /**
  355. * This is the "change track" popup we will display if the degree cannot be combined with anything else (non-dynamic).
  356. *
  357. * We will basically treat it similarly to how FlightPath 4x did things.
  358. */
  359. function advise_display_popup_change_track_non_dynamic_degree() {
  360. global $degree_plan, $student;
  361. $rtn = "";
  362. $db = get_global_database_handler();
  363. // Find out what track the user is already on.
  364. // From What If mode...
  365. if (@$GLOBALS["fp_advising"]["advising_what_if"] == "yes") {
  366. $student_majors_array = @csv_to_array($_SESSION["what_if_major_code" . $student->student_id]);
  367. }
  368. else {
  369. // Not in what if mode-- get the data from the normal student_majors table.
  370. $student_majors_array = fp_get_student_majors($student->student_id, FALSE, FALSE);
  371. } //else
  372. $degree_plan->load_descriptive_data();
  373. $major_code = $degree_plan->major_code;
  374. $catalog_year = $degree_plan->catalog_year;
  375. $bare_degree_plan = $degree_plan;
  376. // Are we already on a track? If so, find out what the original degree was.
  377. if (strstr($major_code, "_")) {
  378. $temp = explode("_", $major_code);
  379. $m = trim($temp[0]);
  380. // Remove trailing | if its there.
  381. $m = rtrim($m, "|");
  382. $bare_degree_plan = $db->get_degree_plan($m, $catalog_year); // the original degree plan (bare, no tracks)
  383. $major_code = $m;
  384. }
  385. $just_major_code = $major_code;
  386. $temp = explode("_" , $just_major_code);
  387. $just_major_code = $temp[0];
  388. $just_major_code = rtrim($just_major_code, "|");
  389. $rtn .= fp_render_curved_line(t("Select a Degree Option"));
  390. $rtn .= "<div class='tenpt'>
  391. " . t("The student's degree has one or more degree options, which affects which courses are required.
  392. Please select a degree option (or track) from the list below.") . "
  393. <br><br>
  394. " . t("If you are unsure of what to do, simply close this window.") . "
  395. </div>
  396. ";
  397. $rtn .= "<br><br><b>" . $bare_degree_plan->title . "</b> " . t("degree options:") . "<!--DEFAULT-->
  398. <ul>";
  399. // Get the list of available tracks for this degree.
  400. if (!$tracks = $bare_degree_plan->get_available_tracks())
  401. {
  402. $rtn .= "<li>" . t("This major has no degree options.") . "</li>";
  403. }
  404. // Is there a "default" message for all tracks, which will override
  405. // any other track descriptions?
  406. // We need to look through all the tracks for the
  407. // characters: "DEFAULT:"
  408. // If we find this, then this is the default description
  409. // which applies to all the tracks, and it should be displayed
  410. // at the top.
  411. $bool_default_description = false;
  412. for ($t = 0; $t < count($tracks); $t++)
  413. {
  414. $temp = explode(" ~~ ", $tracks[$t]);
  415. $track_code = trim($temp[0]);
  416. $track_title = trim($temp[1]);
  417. $track_description = trim($temp[2]);
  418. if (strstr($track_description, "DEFAULT:")) {
  419. // Yes! We found a default message.
  420. $bool_default_description = true;
  421. $track_description = filter_markup(trim(str_replace("DEFAULT:", "", $track_description)));
  422. $track_description = "<div style='padding-top: 10px;' class='tenpt'>$track_description</div>";
  423. $rtn = str_replace("<!--DEFAULT-->",$track_description, $rtn);
  424. break;
  425. }
  426. }
  427. for ($t = 0; $t < count($tracks); $t++)
  428. {
  429. $temp = explode(" ~~ ", $tracks[$t]);
  430. $track_code = trim($temp[0]);
  431. $track_title = trim($temp[1]);
  432. $track_description = "";
  433. $temp_tc = $track_code;
  434. if ($temp_tc == "")
  435. {
  436. $temp_tc = "none";
  437. }
  438. $major_and_track_code = $just_major_code;
  439. if ($temp_tc != "none") {
  440. if (!strstr($major_and_track_code, "|")) {
  441. $major_and_track_code .= "|";
  442. }
  443. $major_and_track_code .= "_" . $temp_tc;
  444. }
  445. // If this is the current track_code, mark it as such.
  446. if (in_array($major_and_track_code, $student_majors_array)) {
  447. $track_title .= " <b>(" . t("current") . ")</b>";
  448. }
  449. if ($bool_default_description == false)
  450. {
  451. $track_description = filter_markup(trim($temp[2]));
  452. if ($track_description != "")
  453. {
  454. $track_description = " - $track_description";
  455. }
  456. }
  457. // We need the track's degree id.
  458. $trid = $db->get_degree_id($major_and_track_code, $catalog_year);
  459. if ($trid == $bare_degree_plan->degree_id) $trid = ""; // don't use anything for the "none" option (the "orignal" degree plan)
  460. $link = fp_get_js_confirm_link(t("Are you sure you wish to change degree options?"), "opener.changeTrackNonDynamicDegree(\"$trid\"); window.close(); ", $track_title);
  461. if ($GLOBALS["fp_advising"]["advising_what_if"] == "yes") {
  462. $link = "<a href='javascript: popupChangeWhatIfTrackNonDynamicDegree(\"$major_and_track_code\", \"" . t("Are you sure you wish to change degree options?") . "\");'>$track_title</a>";
  463. }
  464. $rtn .= "<li class='tenpt' style='padding:3px;'>
  465. $link $track_description</li>";
  466. }
  467. $rtn .= "</ul>";
  468. return $rtn;
  469. } // popup_change_track_non_dynamic_degree
  470. function advise_display_popup_change_track() {
  471. global $degree_plan, $student;
  472. $rtn = "";
  473. advise_init_screen();
  474. fp_add_js(fp_get_module_path("advise") . "/js/advise.js");
  475. fp_add_css(fp_get_module_path("advise") . "/css/advise.css");
  476. if ($degree_plan->db_allow_dynamic == 0) {
  477. // Since this is NOT a degree plan which can be combined with others, we
  478. // want to display this popup like in FlightPath 4.x.
  479. return advise_display_popup_change_track_non_dynamic_degree();
  480. }
  481. $top_level_majors_csv = "";
  482. $degree_plan_array = array();
  483. if ($degree_plan->is_combined_dynamic_degree_plan == FALSE) {
  484. // NOT a combined degree plan. Just use the 1 degree plan we gots.
  485. $degree_plan_array[$degree_plan->degree_id] = $degree_plan;
  486. }
  487. else {
  488. // It IS a combined degree plan, so we need to get all the plans out of there.
  489. foreach ($degree_plan->combined_degree_ids_array as $t_degree_id) {
  490. $t_degree_plan = fp_load_degree($t_degree_id);
  491. $t_degree_plan->load_descriptive_data();
  492. if ($t_degree_plan->get_available_tracks()) {
  493. }
  494. $degree_plan_array[$t_degree_plan->degree_id] = $t_degree_plan;
  495. }
  496. }
  497. $locked_array = array(); // keep track of any degree classes which are "locked".
  498. // From What If mode...
  499. if (@$GLOBALS["fp_advising"]["advising_what_if"] == "yes") {
  500. $student_majors_array = @csv_to_array($_SESSION["what_if_major_code" . $student->student_id]);
  501. }
  502. else {
  503. // Not in what if mode-- get the data from the normal student_majors table.
  504. $student_majors_array = fp_get_student_majors($student->student_id, FALSE, TRUE);
  505. // Also see if any degree classes should be "locked" for this student.
  506. $db = get_global_database_handler();
  507. $temp = $db->get_student_majors_from_db($student->student_id, FALSE, FALSE, FALSE);
  508. foreach ($temp as $line) {
  509. $t = explode("~", $line);
  510. if (trim(strtoupper($t[0])) == "LOCKED") {
  511. $locked_array[] = trim($t[1]);
  512. }
  513. }
  514. } //else
  515. $rtn .= fp_render_curved_line(t("Select a Degree Option"));
  516. $rtn .= "<div class='tenpt'>
  517. " . t("The student's degree has one or more degree options, which affects which courses are required.
  518. Please select a degree option (or track) from the list below.") . "
  519. <br><br>
  520. " . t("If you are unsure of what to do, simply close this window.") . "
  521. </div>
  522. ";
  523. // Loop through available degrees here
  524. foreach ($degree_plan_array as $t_degree_plan) {
  525. $t_degree_plan->load_descriptive_data();
  526. // Skip any degree plan that isn't level 1 or level 2. In other words,
  527. // if this is already a track, then skip it.
  528. $details = fp_get_degree_classification_details($t_degree_plan->degree_class);
  529. if ($details["level_num"] == 3) continue;
  530. // Go through each type of classification in this degree's track_selection_config_array.
  531. //foreach ($t_degree_plan->track_selection_config_array as $machine_name => $tdetails) {
  532. $degree_classes = fp_get_degree_classifications();
  533. foreach ($degree_classes["levels"][3] as $machine_name => $class_title) {
  534. $extra_css_class = "";
  535. $class_is_empty = TRUE;
  536. $is_locked = FALSE;
  537. if (in_array($machine_name, $locked_array)) {
  538. $is_locked = TRUE;
  539. $extra_css_class = "degree-class-is-locked";
  540. }
  541. $html = "";
  542. $min_max_options = "";
  543. // Check to see what we have in this degree's track_selection_config_array
  544. $min_tracks = @intval($t_degree_plan->track_selection_config_array[$machine_name]["min_tracks"]);
  545. $max_tracks = @intval($t_degree_plan->track_selection_config_array[$machine_name]["max_tracks"]);
  546. $default_tracks = @trim($t_degree_plan->track_selection_config_array[$machine_name]["default_tracks"]);
  547. $default_tracks_array = csv_to_array($default_tracks);
  548. $degree_id = $t_degree_plan->degree_id;
  549. // Add this information to our javascript settings...
  550. $js = array(
  551. "degree_min_max_tracks_" . $degree_id . "_split_" . $machine_name => $min_tracks . "~" . $max_tracks,
  552. "degree_name_" . $degree_id => $t_degree_plan->get_title2(FALSE, FALSE, FALSE),
  553. "class_title_" . $machine_name => $class_title,
  554. );
  555. fp_add_js($js, "setting");
  556. $min_max_options = "<div class='advise-select-track-min-max advise-select-track-between'>Please select between $min_tracks and $max_tracks $class_title options.</div>";
  557. if ($min_tracks == $max_tracks && $max_tracks == 1) {
  558. $min_max_options = "<div class='advise-select-track-min-max advise-select-track-exactly-one'>Please select 1 $class_title option.</div>";
  559. }
  560. if ($min_tracks > 0 && $max_tracks == 0) {
  561. // Meaning, there is no maximum. It's infinite.
  562. $min_max_options = "<div class='advise-select-track-min-max advise-select-track-at-least-one'>Please select at least $min_tracks $class_title option(s) for this degree.</div>";
  563. }
  564. if ($min_tracks == $max_tracks && $max_tracks == 0) {
  565. $min_max_options = "<div class='advise-select-track-min-max advise-select-track-optional'>Optional: You are not required to select any additional $class_title options.</div>";
  566. }
  567. // Let's look to see what "tracks" this degree has.
  568. $html .= "<br>
  569. <div class='advise-track-selection-tracks $extra_css_class'>
  570. <div class='tenpt'><span class='advise-select-degree-title'>" . $t_degree_plan->title . "</span> <span class='advise-select-class-title'>$class_title</span> options:</div>
  571. <div class='advise-track-min-max-options advise-track-min-$min_tracks advise-track-max-$max_tracks'>$min_max_options</div>
  572. <!--DEFAULT_$machine_name-->
  573. <div class='advise-track-options-region'>
  574. ";
  575. $major_code = $t_degree_plan->major_code;
  576. $top_level_majors_csv .= $major_code . ",";
  577. // Get the list of available tracks for this student.
  578. if (!$tracks = $t_degree_plan->get_available_tracks())
  579. {
  580. $html .= "<div class='advise-select-track-none'>&nbsp; &nbsp; &bull; " . t("This degree has no degree options.") . "</div>";
  581. }
  582. // Is there a "default" message for all tracks, which will override
  583. // any other track descriptions?
  584. // We need to look through all the tracks for the
  585. // characters: "DEFAULT:"
  586. // If we find this, then this is the default description
  587. // which applies to all the tracks, and it should be displayed
  588. // at the top.
  589. $bool_default_description = false;
  590. for ($t = 0; $t < count($tracks); $t++)
  591. {
  592. $temp = explode(" ~~ ", $tracks[$t]);
  593. $track_code = trim(@$temp[0]);
  594. $track_title = trim(@$temp[1]);
  595. $track_description = trim(@$temp[2]);
  596. // if this track is NOT of the same classification as the current machine_code, we skip it.
  597. $track_machine_name = trim(@$temp[4]);
  598. if ($track_machine_name != $machine_name) continue; // not the right degree_class
  599. if (strstr($track_description, "DEFAULT:")) {
  600. // Yes! We found a default message.
  601. $bool_default_description = true;
  602. $track_description = filter_markup(trim(str_replace("DEFAULT:", "", $track_description)));
  603. $track_description = "<div style='padding-top: 10px;' class='tenpt advise-select-track-description'>$track_description</div>";
  604. $html = str_replace("<!--DEFAULT_$machine_name-->",$track_description, $rtn);
  605. break;
  606. }
  607. }
  608. ///////////////////
  609. // Okay, go through the tracks,
  610. for ($t = 0; $t < count($tracks); $t++)
  611. {
  612. $temp = explode(" ~~ ", $tracks[$t]);
  613. $track_code = trim(@$temp[0]);
  614. $track_title = trim(@$temp[1]);
  615. $track_degree_id = intval(trim(@$temp[3]));
  616. $track_description = "";
  617. // if this track is NOT of the same classification as the current machine_code, we skip it.
  618. $track_machine_name = trim(@$temp[4]);
  619. if ($track_machine_name != $machine_name) continue; // not the right degree_class
  620. $selected = $disabled = "";
  621. // If this track has been selected already, mark it as such
  622. if (isset($degree_plan_array[$track_degree_id])) {
  623. // Meaning yes, this was already selected for this student.
  624. $selected = "checked=checked";
  625. }
  626. // Is this track marked as NOT is_editable?
  627. $is_editable = 1;
  628. if (isset($student_majors_array[$t_degree_plan->major_code . "|_" . $track_code])) {
  629. $is_editable = intval(@$student_majors_array[$t_degree_plan->major_code . "|_" . $track_code]["is_editable"]);
  630. }
  631. if ($is_editable != 1 || $is_locked == TRUE) {
  632. $disabled = "disabled=disabled";
  633. }
  634. if ($bool_default_description == false) {
  635. $track_description = filter_markup(trim(@$temp[2]));
  636. }
  637. $temp_tc = $track_code;
  638. if ($temp_tc == "") {
  639. $temp_tc = "none";
  640. }
  641. $link = fp_get_js_confirm_link(t("Are you sure you wish to change degree options?"), "opener.changeTrack(\"$temp_tc\"); window.close(); ", $track_title);
  642. // We actually don't need to do anything special for what_if, I think. When
  643. // we save, it should automatically detect it and set the appropriate values.
  644. $is_whatif = 0;
  645. if ($GLOBALS["fp_advising"]["advising_what_if"] == "yes") {
  646. $is_whatif = 1;
  647. }
  648. $track_degree_plan = fp_load_degree($track_degree_id, NULL, TRUE); // load minimally
  649. $input_type = "checkbox";
  650. $input_name = "track_degree_id_$track_degree_id";
  651. // We are extected to select EXACTLY 1 track...
  652. if ($min_tracks == $max_tracks && $max_tracks == 1) {
  653. $input_type = "radio";
  654. $input_name = "track_degree_id_" . $degree_id; // needs to be the same for all options.
  655. }
  656. if ($track_degree_plan->db_allow_dynamic == 1) {
  657. $extra_class = "";
  658. $is_default = FALSE;
  659. if (in_array($t_degree_plan->major_code . "|_" . $track_code, $default_tracks_array)) {
  660. $extra_class = "advise-select-track-default-track";
  661. $is_default = TRUE;
  662. }
  663. $html .= "<div class='track-option $extra_class'>";
  664. $html .= "
  665. <label>
  666. <input type='$input_type' name='$input_name' degree_id_class='{$degree_id}_class_{$machine_name}'
  667. is_editable='$is_editable'
  668. value='$track_degree_id' $selected $disabled>
  669. <span class='track-title'>" . $track_degree_plan->get_title2(TRUE, TRUE) . "
  670. ";
  671. if ($is_default) {
  672. $html .= "<span class='track-default-track'>" . t("(Default)") . "</span>";
  673. }
  674. $html .= "
  675. </span>
  676. </label>";
  677. if (!$is_editable) {
  678. $html .= "<div class='track-not-editable'>" . t("You are not allowed to modify this option.") . "</div>";
  679. }
  680. $html .= "
  681. <div class='track-description'>
  682. $track_description
  683. </div>
  684. </div>";
  685. $class_is_empty = FALSE;
  686. }
  687. } // for (count(tracks))
  688. if ($is_locked) {
  689. $html .= "<div class='track-class-is-locked-msg'>" . t("Selections from this degree classification are locked. You may use What If mode to explore
  690. other options, or ask your advisor about changing these options officially.") . "</div>";
  691. }
  692. $html .= "</div>";
  693. $html .= "</div>"; // advise-track-selection-tracks
  694. if (!$class_is_empty) {
  695. $rtn .= $html;
  696. }
  697. }
  698. } // foreach degree_plan_array
  699. $rtn .= "<input type='button' value='" . t("Apply Selections") . "'
  700. onClick='if(confirm(\"Are you sure you wish to apply these selections to the degree plan?\")) { popupChangeTrackSelections($is_whatif); }'>";
  701. // Keep track of what our top-level majors were.
  702. $top_level_majors_csv = rtrim($top_level_majors_csv, ","); // remove trailing comma if exists
  703. $rtn .= "<input type='hidden' name='top_level_majors_csv' id='top_level_majors_csv' value='$top_level_majors_csv'>";
  704. return $rtn;
  705. } // display_popup_change_track
  706. /**
  707. * This popup allows the advisor to change the advising term.
  708. */
  709. function advise_display_popup_change_term() {
  710. $rtn = "";
  711. fp_add_js(fp_get_module_path("advise") . "/js/advise.js");
  712. $current_term_id = $_REQUEST["advising_term_id"];
  713. $current_term = get_term_description($current_term_id);
  714. $rtn .= fp_render_curved_line(t("Select an Advising Term"));
  715. $rtn .= "<div>
  716. " . t("You may advise this student for future semesters. Please select which
  717. advising term you would like to advise for from the list below. If you
  718. are unsure, simply close this window and continue to advise for the current
  719. term of %current_term.", array("%current_term" => $current_term)) . "
  720. </div>";
  721. $rtn .= "<ul>";
  722. $temp = explode(",", variable_get("available_advising_term_ids", "0"));
  723. for ($t = 0; $t < count($temp); $t++) {
  724. $term_id = trim($temp[$t]);
  725. $term_desc = get_term_description($term_id);
  726. if ($term_id == $current_term_id) {
  727. $term_desc = "<b>$term_desc</b> - " . t("current");
  728. }
  729. $link = fp_get_js_confirm_link(t("Are you sure you wish to change advising terms?"), "opener.changeTerm(\"$term_id\"); window.close(); ", $term_desc);
  730. $rtn .= "<li class='tenpt' style='padding:3px;'>$link</li>";
  731. }
  732. $rtn .= "</ul>";
  733. return $rtn;
  734. }
  735. /**
  736. * This is an access callback. Can the user view the advising session specified
  737. * in the REQUEST?
  738. */
  739. function advise_user_can_view_advising_session_access_callback() {
  740. global $user;
  741. if (user_has_permission("view_any_advising_session")) {
  742. return TRUE;
  743. }
  744. if (user_has_permission("view_own_advising_session") || user_has_permission("view_advisee_advising_session")) {
  745. $advising_session_id = $_REQUEST["advising_session_id"];
  746. // First, what was the student's CWID associated with that advising_session_id?
  747. $res = db_query("SELECT student_id FROM advising_sessions
  748. WHERE advising_session_id = '?' ", $advising_session_id);
  749. $cur = db_fetch_array($res);
  750. if (user_has_permission("view_own_advising_session") && $user->cwid == $cur["student_id"]) {
  751. return TRUE;
  752. }
  753. if (user_has_permission("view_advisee_advising_session")) {
  754. $faculty_advisees = advise_get_advisees();
  755. if (in_array($cur["student_id"], $faculty_advisees)) {
  756. return TRUE;
  757. }
  758. }
  759. }
  760. return FALSE;
  761. }
  762. function advise_display_popup_group_select() {
  763. global $current_student_id, $fp, $screen, $degree_plan;
  764. $rtn = "";
  765. advise_init_screen();
  766. fp_add_js(fp_get_module_path("advise") . "/js/advise.js");
  767. fp_add_css(fp_get_module_path("advise") . "/css/advise.css");
  768. $settings = fp_get_system_settings();
  769. $blank_degree_id = trim(@$_GET["blank_degree_id"]);
  770. $course_id = trim(@$_GET["course_id"]);
  771. $group_id = trim(addslashes(@$_GET["group_id"]));
  772. $group_hours_remaining = trim(addslashes(@$_GET["group_hours_remaining"]));
  773. $semester_num = trim(addslashes(@$_GET["semester_num"]));
  774. $req_by_degree_id = trim(addslashes(@$_REQUEST["req_by_degree_id"]));
  775. $perform_action2 = @$_REQUEST["perform_action2"];
  776. // If this is a "blank" degree, make sure we set the degree_id correctly.
  777. if($blank_degree_id != "") {
  778. // If req_by_degree_id isn't blank or zero, then use it instead.
  779. if ($req_by_degree_id != '' && intval($req_by_degree_id) != 0) {
  780. $degree_plan = fp_load_degree($req_by_degree_id);
  781. }
  782. else {
  783. // Default behavior
  784. $degree_plan = fp_load_degree($blank_degree_id);
  785. }
  786. $fp->degree_plan = $degree_plan;
  787. $screen->degree_plan = $degree_plan;
  788. $screen->bool_blank = TRUE;
  789. }
  790. if (!$group = $degree_plan->find_placeholder_group($group_id, $semester_num)) {
  791. fpm("Could not find group (id: $group_id) in semester (num: $semester_num).");
  792. fpm($degree_plan);
  793. return;
  794. }
  795. if ($group_id == -88) {
  796. // This is the Add a Course group. We must initialize it, as it
  797. // does not exist yet.
  798. // We need to populate this group now.
  799. $group->list_courses = $fp->get_all_courses_in_catalog_year($settings["current_catalog_year"]);
  800. $group->title = "Add an Additional Course";
  801. $group->list_courses->assign_group_id($group_id);
  802. $group->list_courses->load_course_descriptive_data();
  803. }
  804. if ($course_id != "") {
  805. // Meaning, a course_id was specified, so make sure
  806. // it is "selected" inside the group and branches.
  807. $course = new Course();
  808. $course->course_id = $course_id;
  809. $course->req_by_degree_id = $req_by_degree_id;
  810. // TODO: Right here, do we need to limit by degree id? Probably...
  811. $temp_course_list = $group->find_courses($course);
  812. if (!$temp_course_list) {
  813. $temp_course_list = $degree_plan->find_courses($course_id, $group_id, $semester_num);
  814. }
  815. if ($temp_course_list) {
  816. $temp_course_list->reset_counter();
  817. while($temp_course_list->has_more()) {
  818. $temp_course = $temp_course_list->get_next();
  819. $temp_course->bool_selected = true;
  820. //$temp_course->assigned_to_semester_num = $semester_num;
  821. }
  822. }
  823. }
  824. if ($perform_action2 == "" || $perform_action2 == "select") {
  825. if ($group) {
  826. $rtn .= $screen->display_popup_group_select($group, $group_hours_remaining, $req_by_degree_id);
  827. }
  828. // Create the tabs for the page...
  829. $tab_array = array();
  830. $tab_array[0]["title"] = "Description";
  831. $tab_array[0]["on_click"] = "popupDescribeSelected(\"$group_id\",\"$semester_num\",\"0\",\"\",\"req_by_degree_id=$req_by_degree_id&group_hours_remaining=$group_hours_remaining&blank_degree_id=$blank_degree_id\");";
  832. $tab_array[1]["title"] = "Select";
  833. $tab_array[1]["active"] = true;
  834. // If we are allowed to substitute....
  835. if (user_has_permission("can_substitute") && $group_id != -88 && !$screen->bool_blank) {
  836. $tab_array[2]["title"] = "Substitute";
  837. $tab_array[2]["on_click"] = "popupSubstituteSelected(\"0\",\"$group_id\",\"$semester_num\",\"$req_by_degree_id\",\"group_hours_remaining=$group_hours_remaining\");";
  838. }
  839. }
  840. if ($perform_action2 == "describe_course") {
  841. $rtn .= $screen->display_popup_course_description($course_id,null,$group, true);
  842. // Create the tabs for the page...
  843. $tab_array = array();
  844. $tab_array[0]["title"] = "Description";
  845. $tab_array[0]["active"] = true;
  846. $tab_array[1]["title"] = "Select";
  847. $subject = trim($_GET["selected_subject"]);
  848. $tab_array[1]["on_click"] = "popupBackToGroupSelect(\"$course_id\",\"$group_id\",\"$semester_num\",\"req_by_degree_id=$req_by_degree_id&selected_subject=$subject&group_hours_remaining=$group_hours_remaining&blank_degree_id=$blank_degree_id\");";
  849. // If we are allowed to substitute....
  850. if (user_has_permission("can_substitute") && $group_id != -88 && !$screen->bool_blank) {
  851. $tab_array[2]["title"] = "Substitute";
  852. $tab_array[2]["on_click"] = "popupSubstituteSelected(\"$course_id\",\"$group_id\",\"$semester_num\",\"$req_by_degree_id\",\"group_hours_remaining=$group_hours_remaining\");";
  853. }
  854. }
  855. if ($tab_array) {
  856. fp_set_page_tabs($tab_array);
  857. }
  858. return $rtn;
  859. }
  860. function advise_display_popup_substitute_selected() {
  861. global $current_student_id, $fp, $screen;
  862. $rtn = "";
  863. advise_init_screen();
  864. fp_add_js(fp_get_module_path("advise") . "/js/advise.js");
  865. $sub_decimals_allowed = variable_get("sub_hours_decimals_allowed", 2);
  866. // Add our allowed substitution decimals as a js setting for later use.
  867. fp_add_js(array("subDecimalsAllowed" => $sub_decimals_allowed), "setting");
  868. $course_id = trim(@$_GET["course_id"]);
  869. $group_id = trim(addslashes(@$_GET["group_id"]));
  870. $semester_num = trim(addslashes(@$_GET["semester_num"]));
  871. $req_by_degree_id = trim(addslashes(@$_GET["req_by_degree_id"]));
  872. $hours_avail = trim(addslashes(@$_GET["group_hours_remaining"]));
  873. if (@$_GET["hours_avail"] * 1 > 0) {
  874. $hours_avail = $_GET["hours_avail"] * 1;
  875. }
  876. $rtn .= "<div class='tenpt'><a href='javascript:history.go(-1);' class='nounderline'>&laquo; " . t("return to course selection") . "</a></div>";
  877. $rtn .= $screen->display_popup_substitute($course_id, $group_id, $semester_num, $hours_avail, $req_by_degree_id);
  878. return $rtn;
  879. }
  880. function advise_display_popup_course_description() {
  881. global $current_student_id, $screen;
  882. $rtn = "";
  883. advise_init_screen();
  884. fp_add_js(fp_get_module_path("advise") . "/js/advise.js");
  885. fp_add_css(fp_get_module_path("advise") . "/css/advise.css");
  886. $data_string = trim($_GET["data_string"]);
  887. $course = new Course();
  888. if ($data_string != "")
  889. {
  890. $course->load_course_from_data_string($data_string);
  891. }
  892. $req_by_degree_id = $course->req_by_degree_id;
  893. // Save the max hours from the data string here. This is to fix a bug where we didn't keep track
  894. // of a course's remainder from a split substitution. Due to pass-by-reference, it gets reset
  895. // in the display_popup_course_description function.
  896. $datastring_max_hours = $course->max_hours;
  897. $rtn .= $screen->display_popup_course_description("", $course);
  898. // Create the tabs for the page...
  899. $tab_array = array();
  900. $tab_array[0]["title"] = "Description";
  901. $tab_array[0]["active"] = true;
  902. if (user_has_permission("can_substitute") && !$screen->bool_blank) {
  903. if ($course->get_bool_substitution() != TRUE && $course->grade == "") {
  904. // By checking grade, we are making sure this course has NOT already
  905. // been taken by the student. In other words, verify that this course
  906. // is an unfulfilled requirement on the degree plan ONLY.
  907. $extra_vars = "hours_avail=$datastring_max_hours";
  908. $tab_array[1]["title"] = "Substitute";
  909. $tab_array[1]["on_click"] = "popupSubstituteSelected(\"$course->course_id\",\"" . $course->get_first_assigned_to_group_id() . "\",\"$course->assigned_to_semester_num\",\"$req_by_degree_id\",\"$extra_vars\");";
  910. }
  911. }
  912. fp_set_page_tabs($tab_array);
  913. //$screen->page_tabs = $screen->draw_tabs($tab_array);
  914. return $rtn;
  915. }
  916. /**
  917. * Implementation of hook_perm
  918. */
  919. function advise_perm() {
  920. $perms = array();
  921. $perms["view_any_advising_session"] = array(
  922. "title" => t("View any advising session"),
  923. "description" => t("The user is allowed to view any advising sessions for any user.
  924. For example, the user is an advisor."),
  925. );
  926. $perms["view_advisee_advising_session"] = array(
  927. "title" => t("View advisee advising sessions"),
  928. "description" => t("The user is allowed to view their assigned advisee's advising sessions.
  929. For example, the user is a limited advisor with advisees assigned."),
  930. );
  931. $perms["view_own_advising_session"] = array(
  932. "title" => t("View own advising session"),
  933. "description" => t("The user is allowed to view their own advising sessions.
  934. For example, the user is a student."),
  935. );
  936. $perms["can_advise_students"] = array(
  937. "title" => t("Can advise students"),
  938. "description" => t("The user is allowed to advise other students,
  939. by clicking a checkbox next to a course, or by selecting
  940. a course from an elective group."),
  941. );
  942. $perms["can_substitute"] = array(
  943. "title" => t("Can substitute"),
  944. "description" => t("The user is allowed to substitute courses on a student's
  945. degree plan."),
  946. );
  947. $perms["toggle_draft"] = array(
  948. "title" => t("Toggle draft mode"),
  949. "description" => t("The user toggle 'draft' mode, so they can view draft degree plans
  950. in FlightPath."),
  951. );
  952. return $perms;
  953. }
  954. /**
  955. * This is the page which actually displays the "view" for the user
  956. * to see their advising session, or for an advisor to advise them.
  957. *
  958. */
  959. function advise_display_view($view = "view") {
  960. global $user, $fp, $degree_plan, $screen;
  961. $rtn = "";
  962. if ($view == "what-if") {
  963. $GLOBALS["fp_advising"]["advising_what_if"] = "yes";
  964. $_REQUEST["advising_what_if"] = "yes";
  965. }
  966. else {
  967. $GLOBALS["fp_advising"]["advising_what_if"] = "no";
  968. $_REQUEST["advising_what_if"] = "no";
  969. }
  970. // Initialize everything we need to initialize for this advising session.
  971. advise_init_screen();
  972. // Add some body classes to the page for this student.
  973. $student = $screen->student;
  974. if (is_object($student)) {
  975. fp_add_body_class("student-rank-$student->db_rank student-catalog-year-$student->catalog_year");
  976. }
  977. fp_add_js(fp_get_module_path("advise") . "/js/advise.js");
  978. // Add advise.css to the screen
  979. fp_add_css(fp_get_module_path("advise") . "/css/advise.css");
  980. // If we are on a print screen, we need to go out of our
  981. // way to set the screen mode, so we don't display certain things
  982. // when we go to draw the screen.
  983. if (strstr($_REQUEST["q"], "/print")) {
  984. $screen->bool_print = TRUE;
  985. $screen->screen_mode = "not_advising";
  986. }
  987. if ($GLOBALS["fp_advising"]["advising_what_if"] == "yes" && $GLOBALS["fp_advising"]["what_if_major_code"] == "") {
  988. // We are in WhatIf, but we have not selected a major, so give
  989. // the user a selection screen.
  990. $screen->screen_mode = "not_advising";
  991. //$rtn .= advise_display_what_if_selection();
  992. // TODO: If graduate degree selection is allowed for graduate students, then change bool_undergrad_only to FALSE.
  993. // (if the student is a grad student!)
  994. $bool_undergrad_only = TRUE;
  995. if ($student->db_rank == 'GR') { // TODO: make it a settings list of graduate ranks
  996. // TODO: check setting to see if we should allow graduate students to see what if (?) Maybe?
  997. $bool_undergrad_only = FALSE;
  998. }
  999. $rtn .= fp_render_form("advise_what_if_selection_form", "", $bool_undergrad_only);
  1000. }
  1001. else {
  1002. // This is a normal advising screen. Either View or WhatIf.
  1003. //$page_content .= $screen->display_view_options();
  1004. $screen->build_screen_elements();
  1005. $form_token = md5("advise_display_view" . fp_token());
  1006. $vurl = fp_url($view);
  1007. $rtn .= "<form id='mainform' method='POST' action='$vurl'>
  1008. <input type='hidden' name='form_token' value='$form_token'>
  1009. <table class='fp-semester-table'>";
  1010. $rtn .= $screen->display_screen();
  1011. $rtn .= "</table>";
  1012. // Add in the required "advising variables"
  1013. $rtn .= $screen->get_hidden_advising_variables("save_draft");
  1014. $rtn .= "</form>";
  1015. // Figure out what the page's sub-tabs should be, and set them.
  1016. $tab_array = array();
  1017. $tab_array[0]["title"] = "Display by Year";
  1018. $tab_array[0]["active"] = ($screen->view != "type");
  1019. $tab_array[0]["on_click"] = "changeView(\"year\");";
  1020. $tab_array[1]["title"] = "Display by Type";
  1021. $tab_array[1]["active"] = ($screen->view == "type");
  1022. $tab_array[1]["on_click"] = "changeView(\"type\");";
  1023. if (!fp_screen_is_mobile()) {
  1024. $tab_array[2]["title"] = "Print";
  1025. $tab_array[2]["type"] = "link";
  1026. $tab_array[2]["active"] = FALSE;
  1027. $tab_array[2]["on_click"] = "popupPrintWindow(\"" . fp_url("$view/print", "advising_view=$screen->view") . "\");";
  1028. }
  1029. fp_set_page_sub_tabs($tab_array);
  1030. watchdog("view_by_$screen->view", "", array(), WATCHDOG_DEBUG);
  1031. }
  1032. /* We aren't doing anything with these variables, so I am commenting-out
  1033. *
  1034. // If we are in WhatIf mode, let's write something special to
  1035. // the log.
  1036. if ($GLOBALS["fp_advising"]["advising_what_if"] == "yes" && $GLOBALS["fp_advising"]["what_if_major_code"] != "")
  1037. {
  1038. $log_action .= "_whatif";
  1039. $log_extra = $GLOBALS["fp_advising"]["what_if_major_code"] . " " . $GLOBALS["fp_advising"]["what_if_track_code"];
  1040. }
  1041. */
  1042. // print_pre($student->list_courses_taken->toString());
  1043. // Should we re-cache the course inventory? If there have been any changes
  1044. // to it, then we will see that in a GLOBALS variable...
  1045. if (@$GLOBALS["cache_course_inventory"] == true)
  1046. {
  1047. $_SESSION["fp_cache_course_inventory"] = serialize(@$GLOBALS["fp_course_inventory"]);
  1048. }
  1049. return $rtn;
  1050. }
  1051. function advise_what_if_selection_form($bool_undergrad_only = TRUE) {
  1052. global $screen, $current_student_id;
  1053. if ($screen->bool_print) {
  1054. return array();
  1055. }
  1056. fp_add_js(fp_get_module_path("advise") . "/js/advise.what-if-selection.js");
  1057. fp_add_css(fp_get_module_path("advise") . "/css/advise.css");
  1058. $form = array();
  1059. $m = 0;
  1060. fp_set_title(""); // Remove the default form's title
  1061. $db = get_global_database_handler();
  1062. $major_codes = array();
  1063. $form["mark" . $m++] = array(
  1064. "value" => fp_render_curved_line("What if I change my degree to...") . "<br>",
  1065. );
  1066. //$settings = fp_get_system_settings();
  1067. $catalog_year = variable_get("current_catalog_year", 0);
  1068. $current_catalog_year = $catalog_year; // keep track of what the current catalog year is.
  1069. $earliest_catalog_year = variable_get("earliest_catalog_year", 2006);
  1070. // Use the student's catalog year, based on a setting instead?
  1071. if (variable_get("what_if_catalog_year", "current") == "student") {
  1072. $db = get_global_database_handler();
  1073. $catalog_year = $db->get_student_catalog_year($current_student_id);
  1074. }
  1075. $form["mark_cat_year"] = array(
  1076. "value" => "<div class='mark-select-from-cat-year'>" . t("Please select from the %cat catalog year:", array("%cat" => $catalog_year . "-" . ($catalog_year+1))) . "</div>",
  1077. );
  1078. // We cannot go beyond the current catalog year, so if the catalog_year is now > than current, we must stop
  1079. // the user.
  1080. if ($catalog_year > $current_catalog_year || $catalog_year < $earliest_catalog_year) {
  1081. $form["mark_cat_year_past_current"] = array(
  1082. "value" => "<p class='cat-year-past-current'>" . t("Sorry, but the catalog year %cat is not available yet within
  1083. FlightPath. Please speak with your adviser about how to proceed
  1084. with advising.", array("%cat" => $catalog_year . "-" . ($catalog_year+1))) . "</p>",
  1085. );
  1086. return $form;
  1087. }
  1088. $form["catalog_year"] = array(
  1089. "type" => "hidden",
  1090. "value" => $catalog_year,
  1091. );
  1092. $bool_use_draft = FALSE; // leave as false for now. Because you can't select
  1093. // degree options, and if you click submit it really does
  1094. // save it. Better to just use blank degrees.
  1095. $c = 100;
  1096. /////////////////////
  1097. // Select a major....
  1098. $options = array();
  1099. if ($degree_array = $db->get_degrees_in_catalog_year($catalog_year, FALSE, $bool_use_draft, $bool_undergrad_only, array(1))) {
  1100. foreach($degree_array as $major_code => $value) {
  1101. if (trim($value["title"]) == ""){continue;}
  1102. $options[$major_code] = $value["title"];
  1103. $major_codes[$major_code] = $major_code;
  1104. }
  1105. }
  1106. // Place in a fieldset...
  1107. $e1["select_level_1_degrees"] = array(
  1108. "type" => "checkboxes",
  1109. "label" => "",
  1110. "options" => $options,
  1111. );
  1112. $form["cfieldset_level_1"] = array(
  1113. "type" => "cfieldset",
  1114. "label" => "Select Major &raquo;",
  1115. "elements" => array($e1),
  1116. "start_closed" => FALSE,
  1117. );
  1118. /////////////////////////
  1119. // Select a minor....
  1120. $options = array();
  1121. if ($degree_array = $db->get_degrees_in_catalog_year($catalog_year, FALSE, $bool_use_draft, $bool_undergrad_only, array(2))) {
  1122. foreach($degree_array as $major_code => $value) {
  1123. if (trim($value["title"]) == ""){continue;}
  1124. $options[$major_code] = $value["title"];
  1125. $major_codes[$major_code] = $major_code;
  1126. }
  1127. }
  1128. if (count($options) > 0) {
  1129. $e2["select_level_2_degrees"] = array(
  1130. "type" => "checkboxes",
  1131. "label" => "",
  1132. "options" => $options,
  1133. );
  1134. $form["cfieldset_level_2"] = array(
  1135. "type" => "cfieldset",
  1136. "label" => "Select Minor &raquo;",
  1137. "elements" => array($e2),
  1138. );
  1139. }
  1140. /////////////////////
  1141. // All the tracks...
  1142. if (variable_get("show_level_3_on_what_if_selection", "yes") == 'yes') {
  1143. foreach ($major_codes as $major_code => $temp) {
  1144. // Let's see if this major has any tracks...
  1145. if ($tracks = $db->get_degree_tracks($major_code, $catalog_year)) {
  1146. // Let's load the original degree plan.
  1147. $degree_plan = $db->get_degree_plan($major_code, $catalog_year, TRUE);
  1148. $degree_plan->load_degree_plan_ancillary();
  1149. // Yes, there are indeed tracks for THIS major. Let's load them up...
  1150. // First, organize them by degree_class...
  1151. $tracks_by_class = array();
  1152. foreach ($tracks as $track) {
  1153. $t_degree_plan = $db->get_degree_plan($major_code . "|_" . $track, $catalog_year, TRUE);
  1154. $t_degree_plan->load_degree_plan_ancillary();
  1155. $degree_class = trim($t_degree_plan->degree_class);
  1156. if ($degree_class) {
  1157. $tracks_by_class[$degree_class][] = $t_degree_plan;
  1158. }
  1159. }
  1160. // Now, create the form element...
  1161. foreach ($tracks_by_class as $degree_class => $c) {
  1162. $options = array();
  1163. $temp = fp_get_degree_classification_details($degree_class);
  1164. $class_title = $temp["title"];
  1165. // Are there any special requirements or defaults for this degree_class selection?
  1166. $tsca = $degree_plan->track_selection_config_array;
  1167. $default_tracks_array = @csv_to_array($tsca[$degree_class]["default_tracks"]);
  1168. $min_tracks = @intval($tsca[$degree_class]["min_tracks"]);
  1169. $max_tracks = @intval($tsca[$degree_class]["max_tracks"]);
  1170. $element_type = "checkboxes";
  1171. $element_value = array();
  1172. // If we require exactly 1 selection, then make this a radio button, and pre-select either the first element
  1173. // or the first default track.
  1174. if ($min_tracks == 1 && $max_tracks == 1) {
  1175. $element_type = "radios";
  1176. $element_value = array($default_tracks_array[0] => $default_tracks_array[0]);
  1177. }
  1178. // Actually build up the options...
  1179. foreach ($tracks_by_class[$degree_class] as $t_degree_plan) {
  1180. //$degree_id = $t_degree_plan->degree_id;
  1181. $tmajor_code = "" . trim($t_degree_plan->major_code);
  1182. $options[$tmajor_code] = $t_degree_plan->get_title2(FALSE, TRUE);
  1183. if (trim($t_degree_plan->track_description) != "") {
  1184. $options[$tmajor_code] .= "<div class='what-if-selection-track-desc what-if-selection-track-desc-for-" . fp_get_machine_readable($tmajor_code) . "'
  1185. >" . $t_degree_plan->track_description . "</div>";
  1186. }
  1187. // Is this a "default" major code?
  1188. if (in_array(trim($tmajor_code), $default_tracks_array)) {
  1189. $element_value[$tmajor_code] = $tmajor_code; // make it be selected
  1190. }
  1191. }
  1192. $min_max_options = "<div class='what-if-select-track-min-max what-if-select-track-between'>Please select between $min_tracks and $max_tracks $class_title options.</div>";
  1193. if ($min_tracks == $max_tracks && $max_tracks == 1) {
  1194. $min_max_options = "<div class='what-if-select-track-min-max what-if-select-track-exactly-one'>Please select 1 $class_title option.</div>";
  1195. }
  1196. if ($min_tracks > 0 && $max_tracks == 0) {
  1197. // Meaning, there is no maximum. It's infinite.
  1198. $min_max_options = "<div class='what-if-select-track-min-max what-if-select-track-at-least-one'>Please select at least $min_tracks $class_title option(s) for this degree.</div>";
  1199. }
  1200. if ($min_tracks == $max_tracks && $max_tracks == 0) {
  1201. $min_max_options = "<div class='what-if-select-track-min-max what-if-select-track-optional'>Optional: You are not required to select any additional $class_title options.</div>";
  1202. }
  1203. $form["L3__sel__{$degree_class}__for__{$major_code}__xx"] = array( //ends with xx so we can be sure when the major code ends.
  1204. "type" => $element_type,
  1205. "label" => "Select $class_title for " . $degree_plan->get_title2(),
  1206. "options" => $options,
  1207. "description" => "$min_max_options",
  1208. "value" => $element_value,
  1209. );
  1210. // Save min and max options for quick look-up later.
  1211. $form["L3__ops__{$degree_class}__for__{$major_code}__xx"] = array(
  1212. "type" => "hidden",
  1213. "value" => "$min_tracks~$max_tracks",
  1214. );
  1215. }
  1216. } // if tracks
  1217. } // foreach major codes
  1218. } // if level-3 selection...
  1219. $form["submit_btn"] = array(
  1220. "value" => "<div align='right'>
  1221. " . fp_render_button("Try It Out!", "showUpdate(true);$(\"#fp-form-advise_what_if_selection_form\").submit(); ") . "
  1222. </div>",
  1223. );
  1224. /*
  1225. $rtn .= "<br><br>
  1226. <div align='right'>
  1227. " . fp_render_button("Try It Out!", "showUpdate(true);submitForm();") . "
  1228. </div>
  1229. <br><br>
  1230. <div class='hypo tenpt'>
  1231. <b>Important Notice:</b> What If displays degree plans
  1232. from the most recent catalog year ($current_catalog_year-" . ($current_catalog_year + 1) . "),
  1233. as any major change would place the student into the
  1234. most recent catalog.
  1235. </div>";
  1236. // Include only certain variables, so we don't overwrite our selection of what_if_major_code.
  1237. $rtn .= "
  1238. <input type='hidden' name='load_from_cache' value='no'>
  1239. <input type='hidden' name='window_mode' value='screen'>
  1240. <input type='hidden' id='scroll_top'>
  1241. <input type='hidden' id='perform_action' name='perform_action'>
  1242. <input type='hidden' id='advising_what_if' name='advising_what_if' value='yes'>
  1243. <input type='hidden' id='current_student_id' name='current_student_id' value='$current_student_id'>
  1244. <input type='hidden' id='from_what_if_selection_form' name='from_what_if_selection_form' value='yes'>
  1245. ";
  1246. $rtn .= "</form>
  1247. ";
  1248. */
  1249. $form["current_student_id"] = array(
  1250. "type" => "hidden",
  1251. "value" => $current_student_id,
  1252. );
  1253. return $form;
  1254. }
  1255. /**
  1256. * Validate handler for the what_if selection form. This is where we might, for example, make sure
  1257. * that if a non-dynamic degree was selected, that they can't proceed.
  1258. */
  1259. function advise_what_if_selection_form_validate($form, &$form_state) {
  1260. $catalog_year = $form_state['values']['catalog_year'];
  1261. // Make sure they selected at least 1 level 1 degree.
  1262. $selected_degrees = array();
  1263. $temp = FALSE;
  1264. foreach (array(1,2) as $num) {
  1265. if (is_array($form_state["values"]["select_level_{$num}_degrees"])) {
  1266. foreach ($form_state["values"]["select_level_{$num}_degrees"] as $k => $v) {
  1267. if ((string)$k === (string)$v && $k != "") {
  1268. $temp = TRUE;
  1269. $selected_degrees[$k] = $v;
  1270. }
  1271. }
  1272. }
  1273. }
  1274. if (!$temp) {
  1275. form_error("select_level_1_degrees", t("Sorry, you must select at least one top-level degree to proceed. Please try again."));
  1276. return;
  1277. }
  1278. $db = get_global_database_handler();
  1279. // If a non-dynamic degree was selected, along with anything else, the user may not proceed.
  1280. if (count($selected_degrees) > 1) {
  1281. foreach ($selected_degrees as $major_code) {
  1282. $temp = $db->get_degree_plan($major_code, $catalog_year, TRUE);
  1283. if (is_object($temp) && intval($temp->db_allow_dynamic) != 1) {
  1284. $temp->load_descriptive_data();
  1285. // meaning, we have selected more than one degree, and at least THIS degree does NOT allow for dynamic recombination. So, reject it!
  1286. form_error("select_level_1_degrees", t("Sorry, but the degree you selected, %deg, does not allow you to combine it with any other degree.
  1287. It must be selected by itself. Please alter your selection and try again.", array("%deg"=> $temp->get_title2())));
  1288. return;
  1289. }
  1290. }
  1291. }
  1292. /////////////////////////
  1293. // Make sure they selected appropriate number of required tracks, if any.
  1294. // Begin by going through each track which was selected, and keep track of how many we selected.
  1295. $selected_for = array();
  1296. foreach ($form_state["values"] as $key => $val) {
  1297. if (strstr($key, "L3__sel__")) {
  1298. // L3_sel_{$degree_class}_for_{$major_code}_xx
  1299. $temp = explode("__", $key);
  1300. $degree_class = $temp[2];
  1301. $major_code = $temp[4];
  1302. if (!isset($selected_for[$major_code . "__" . $degree_class])) {
  1303. $selected_for[$major_code . "__" . $degree_class] = 0;
  1304. }
  1305. if (is_array($val)) { // In other words, this was a group of checkboxes.
  1306. foreach ($val as $k => $v) {
  1307. // Did the user select an item? Val's key and value will be identical if so.
  1308. if ($k == $v && $k != "") {
  1309. // YES. It was selected!
  1310. $selected_for[$major_code . "__" . $degree_class]++;
  1311. }
  1312. }
  1313. } // if is_array (val)
  1314. else if (is_string($val) && trim($val) != ""){
  1315. // Not an array-- was a radio list? So, this was a selection.
  1316. $selected_for[$major_code . "__" . $degree_class]++;
  1317. }
  1318. }
  1319. }
  1320. // Okay, now that we know how many were selected, let's make sure that the number falls within
  1321. // our min/max range for those tracks.
  1322. //foreach ($selected_for as $key => $count) {
  1323. foreach ($form_state["values"] as $key => $val) {
  1324. if (!strstr($key, "L3__sel__")) { continue; }
  1325. $temp = explode("__", $key);
  1326. $degree_class = $temp[2];
  1327. $major_code = $temp[4];
  1328. $count = @intval($selected_for[$major_code . "__" . $degree_class]);
  1329. //First, make sure it's top-level degree was even selected. If it wasn't, skip it, it doesn't matter.
  1330. $temp = explode("|_", $major_code);
  1331. $top_level_code = trim($temp[0]);
  1332. if (@$form_state["values"]["select_level_1_degrees"][$top_level_code] != $top_level_code) {
  1333. if (@$form_state["values"]["select_level_2_degrees"][$top_level_code] != $top_level_code) {
  1334. continue;
  1335. }
  1336. }
  1337. // Okay, check to see if the count falls within the range for this degree & class.
  1338. $temp = explode("~", $form_state["values"]["L3__ops__{$degree_class}__for__{$major_code}__xx"]);
  1339. $min_tracks = @intval($temp[0]);
  1340. $max_tracks = @intval($temp[1]);
  1341. if ($count > $max_tracks && $max_tracks != 0) {
  1342. // We picked too many!
  1343. form_error("L3__sel__{$degree_class}__for__{$major_code}__xx", t("Sorry, you did not select the correct number of options for this degree."));
  1344. return;
  1345. }
  1346. if ($count < $min_tracks && $min_tracks > 0) {
  1347. // We picked too few!
  1348. form_error("L3__sel__{$degree_class}__for__{$major_code}__xx", t("Sorry, you did not select the correct number of options for this degree."));
  1349. return;
  1350. }
  1351. }
  1352. } //what_if_selection_form_validate
  1353. /**
  1354. * Submit handler for the what if selection form.
  1355. * Since at this point we have passed validation, let's just assemble the URL we need to now
  1356. * redirect to.
  1357. */
  1358. function advise_what_if_selection_form_submit($form, $form_state) {
  1359. $current_student_id = $form_state["values"]["current_student_id"];
  1360. $catalog_year = $form_state["values"]["catalog_year"];
  1361. // Get the major codes CSV
  1362. $what_if_major_code = "";
  1363. foreach (array(1, 2) as $num) {
  1364. if (is_array($form_state["values"]["select_level_{$num}_degrees"])) {
  1365. foreach ($form_state["values"]["select_level_{$num}_degrees"] as $k => $v) {
  1366. if ((string)$k === (string)$v && $k != "") {
  1367. $what_if_major_code .= $k . ",";
  1368. }
  1369. }
  1370. }
  1371. }
  1372. // Add in the tracks, too, if selected.
  1373. foreach ($form_state["values"] as $key => $val) {
  1374. if (strstr($key, "L3__sel__")) {
  1375. if (is_array($val) && count($val) > 0) {
  1376. // Did the user select this item? Val's key and value will be identical if so.
  1377. foreach ($val as $k => $v) {
  1378. if ($k == $v && $k != "") {
  1379. // YES. It was selected!
  1380. //First, make sure it's top-level degree was even selected. If it wasn't, skip it, it doesn't matter.
  1381. $temp = explode("|_", $k);
  1382. $top_level_code = trim($temp[0]);
  1383. if (@$form_state["values"]["select_level_1_degrees"][$top_level_code] != $top_level_code) {
  1384. if (@$form_state["values"]["select_level_2_degrees"][$top_level_code] != $top_level_code) {
  1385. continue;
  1386. }
  1387. }
  1388. $what_if_major_code .= $k . ",";
  1389. }
  1390. }
  1391. } // if is_array val (cause it was a checkbox)
  1392. else if (is_string($val) && trim($val) != "") {
  1393. // This was from radio buttons.
  1394. //First, make sure it's top-level degree was even selected. If it wasn't, skip it, it doesn't matter.
  1395. $temp = explode("|_", $val);
  1396. $top_level_code = trim($temp[0]);
  1397. if (@$form_state["values"]["select_level_1_degrees"][$top_level_code] != $top_level_code) {
  1398. if (@$form_state["values"]["select_level_2_degrees"][$top_level_code] != $top_level_code) {
  1399. continue;
  1400. }
  1401. }
  1402. $what_if_major_code .= $val . ",";
  1403. }
  1404. }
  1405. }
  1406. // Remove training comma
  1407. $what_if_major_code = rtrim($what_if_major_code, ",");
  1408. // Okay, let's redirect the user to their proper destination
  1409. $query = "advising_what_if=yes&load_from_cache=no&window_mode=screen&current_student_id=$current_student_id&what_if_major_code=$what_if_major_code&what_if_catalog_year=$catalog_year";
  1410. fp_goto("what-if", $query);
  1411. }
  1412. /**
  1413. * Displays the pulldown select list for picking a new What If degree.
  1414. * Returns HTML.
  1415. *
  1416. * This function is no longer used...
  1417. *
  1418. * @return string
  1419. */
  1420. function z___advise_display_what_if_selection($bool_undergrad_only = TRUE) {
  1421. global $screen, $current_student_id;
  1422. $rtn = "";
  1423. if ($screen->bool_print) {
  1424. return "";
  1425. }
  1426. $db = get_global_database_handler();
  1427. $url = fp_url("what-if");
  1428. $rtn .= "<form action='" . $url . "' id='mainform' method='POST'>";
  1429. $rtn .= fp_render_curved_line("What if I change my major to...");
  1430. $rtn .= "<br>
  1431. Major: <select name='what_if_major_code' class='what-if-selector'>
  1432. <option value=''>Please select a major</option>
  1433. <option value=''>------------------------------</option>\n
  1434. ";
  1435. //$settings = fp_get_system_settings();
  1436. $current_catalog_year = variable_get("current_catalog_year", 0); // get the current catalog year, 0 if not set (which is an error condition)
  1437. //$bool_use_draft = $GLOBALS["fp_advising"]["bool_use_draft"];
  1438. $bool_use_draft = FALSE; // leave as false for now. Because you can't select
  1439. // degree options, and if you click submit it really does
  1440. // save it. Better to just use blank degrees.
  1441. if ($degree_array = $db->get_degrees_in_catalog_year($current_catalog_year, false, $bool_use_draft, $bool_undergrad_only, array(1))) {
  1442. foreach($degree_array as $major_code => $value) {
  1443. if (trim($value["title"]) == ""){continue;}
  1444. $rtn .= "<option value='$major_code'>{$value["title"]}</option> \n";
  1445. }
  1446. }
  1447. $rtn .= "</select>
  1448. <br><br>";
  1449. $c = 100;
  1450. /////////////////////
  1451. // Select a major....
  1452. $content = "";
  1453. if ($degree_array = $db->get_degrees_in_catalog_year($current_catalog_year, false, $bool_use_draft, $bool_undergrad_only, array(1))) {
  1454. foreach($degree_array as $major_code => $value) {
  1455. if (trim($value["title"]) == ""){continue;}
  1456. $content .= "<label style='display:block;'><input type='checkbox' name='cb_$c' value='$major_code'>{$value["title"]} </label> \n";
  1457. $c++;
  1458. }
  1459. }
  1460. $rtn .= fp_render_c_fieldset($content, "Select a Major &raquo;", FALSE);
  1461. /////////////////////////
  1462. // Select a minor....
  1463. $content = "";
  1464. if ($degree_array = $db->get_degrees_in_catalog_year($current_catalog_year, false, $bool_use_draft, $bool_undergrad_only, array(2))) {
  1465. foreach($degree_array as $major_code => $value) {
  1466. if (trim($value["title"]) == ""){continue;}
  1467. $content .= "<label style='display:block;'><input type='checkbox' name='cb_$c' value='$major_code'>{$value["title"]} </label> \n";
  1468. $c++;
  1469. }
  1470. }
  1471. $rtn .= "<br><br>" .fp_render_c_fieldset($content, "Select a Minor &raquo;", FALSE);
  1472. $rtn .= "<br><br>
  1473. <div align='right'>
  1474. " . fp_render_button("Try It Out!", "showUpdate(true);submitForm();") . "
  1475. </div>
  1476. <br><br>
  1477. <div class='hypo tenpt'>
  1478. <b>Important Notice:</b> What If displays degree plans
  1479. from the most recent catalog year ($current_catalog_year-" . ($current_catalog_year + 1) . "),
  1480. as any major change would place the student into the
  1481. most recent catalog.
  1482. </div>";
  1483. // Include only certain variables, so we don't overwrite our selection of what_if_major_code.
  1484. $rtn .= "
  1485. <input type='hidden' name='load_from_cache' value='no'>
  1486. <input type='hidden' name='window_mode' value='screen'>
  1487. <input type='hidden' id='scroll_top'>
  1488. <input type='hidden' id='perform_action' name='perform_action'>
  1489. <input type='hidden' id='advising_what_if' name='advising_what_if' value='yes'>
  1490. <input type='hidden' id='current_student_id' name='current_student_id' value='$current_student_id'>
  1491. <input type='hidden' id='from_what_if_selection_form' name='from_what_if_selection_form' value='yes'>
  1492. ";
  1493. $rtn .= "</form>
  1494. ";
  1495. return $rtn;
  1496. }
  1497. /**
  1498. * Takes various variables from the REQUEST and stores them in our advising_session_variables table for more convenient use later on.
  1499. */
  1500. function advise_init_advising_variables($bool_ignore_what_if_variables = FALSE) {
  1501. global $user;
  1502. $vars = array();
  1503. $student = null;
  1504. // The current student ID is what we append to all session variables
  1505. // dealing with the current student. We do this so that we will
  1506. // keep session variables unique, so that we can have more than one
  1507. // window open at a time, with multiple students.
  1508. // Therefor, this should never go into the session.
  1509. // Annoyingly, we must pass carry this around on each page in the system.
  1510. $vars["current_student_id"] = @$_REQUEST["current_student_id"];
  1511. if ($vars["current_student_id"] == "")
  1512. {
  1513. $vars["current_student_id"] = @$_REQUEST["advising_student_id"];
  1514. }
  1515. $csid = $vars["current_student_id"];
  1516. // Get the student ID.
  1517. $vars["advising_student_id"] = @$_REQUEST["advising_student_id"];
  1518. if ($vars["advising_student_id"] == "")
  1519. {
  1520. $vars["advising_student_id"] = @$_SESSION["advising_student_id$csid"];
  1521. if ($vars["advising_student_id"] == "")
  1522. { // Default value...
  1523. $vars["advising_student_id"] = $csid;
  1524. }
  1525. }
  1526. // Should we load from the Draft advising session? or the active?
  1527. $vars["advising_load_active"] = @$_REQUEST["advising_load_active"];
  1528. if ($vars["advising_load_active"] == "")
  1529. { // values will either be "yes" or "" (any other value than "yes" is
  1530. // considered to be negative.
  1531. // Default value...
  1532. $vars["advising_load_active"] = "";
  1533. }
  1534. // Are we currently in WhatIf mode?
  1535. @$vars["advising_what_if"] = $_REQUEST["advising_what_if"]; // Get it from the GET or POST.
  1536. if ($vars["advising_what_if"] == "")
  1537. {
  1538. // Will equal "yes" if we ARE in whatIf mode.
  1539. @$vars["advising_what_if"] = $_SESSION["advising_what_if$csid"];
  1540. if ($vars["advising_what_if"] == "")
  1541. {
  1542. // Default value:
  1543. $vars["advising_what_if"] = "no";
  1544. }
  1545. }
  1546. // Go ahead and set our GLOBALS variable for advising_what_if. It's needed when we load
  1547. // the $student variable.
  1548. $GLOBALS["fp_advising"]["advising_what_if"] = $vars["advising_what_if"];
  1549. // Get the major_code(s).
  1550. $vars["advising_major_code"] = @$_REQUEST["advising_major_code"];
  1551. if ($vars["advising_major_code"] == "")
  1552. {
  1553. $vars["advising_major_code"] = @$_SESSION["advising_major_code$csid"];
  1554. if ($vars["advising_major_code"] == "")
  1555. { // Default value...
  1556. if (!$student) $student = new Student($csid);
  1557. $vars["advising_major_code"] = $student->major_code_csv;
  1558. $_REQUEST["advising_major_code"] = $student->major_code_csv;
  1559. }
  1560. }
  1561. // Get the track_code.
  1562. /*
  1563. $vars["advising_track_code"] = @$_REQUEST["advising_track_code"];
  1564. if ($vars["advising_track_code"] == "")
  1565. {
  1566. $vars["advising_track_code"] = @$_SESSION["advising_track_code$csid"];
  1567. if ($vars["advising_track_code"] == "")
  1568. { // Default value...
  1569. if (!$student) $student = new Student($csid);
  1570. //$vars["advising_track_code"] = $student->track_code;
  1571. // NOTE: Student doesn't have a track_code property... This code would have never worked.
  1572. }
  1573. }
  1574. */
  1575. $vars["advising_track_degree_ids"] = @$_REQUEST["advising_track_degree_ids"];
  1576. if ($vars["advising_track_degree_ids"] == "")
  1577. {
  1578. $vars["advising_track_degree_ids"] = @$_SESSION["advising_track_degree_ids$csid"];
  1579. if ($vars["advising_track_degree_ids"] == "")
  1580. { // Default value...
  1581. if (!$student) $student = new Student($csid);
  1582. // Re-load the major codes, as the tracks might have changed.
  1583. $student->load_student_data();
  1584. $vars["advising_major_code"] = $student->major_code_csv;
  1585. }
  1586. }
  1587. // Update the student's settings?
  1588. $vars["advising_update_student_settings_flag"] = @$_REQUEST["advising_update_student_settings_flag"];
  1589. // Make it only come from the POST, for safety.
  1590. if ($vars["advising_update_student_settings_flag"] == "")
  1591. {
  1592. $vars["advising_update_student_settings_flag"] = @$_SESSION["advising_update_student_settings_flag$csid"];
  1593. if ($vars["advising_update_student_settings_flag"] == "")
  1594. { // Default value...
  1595. }
  1596. }
  1597. // Update the logged-in user's settings?
  1598. $vars["fp_update_user_settings_flag"] = @$_REQUEST["fp_update_user_settings_flag"];
  1599. // Make it only come from the POST, for safety.
  1600. if ($vars["fp_update_user_settings_flag"] == "")
  1601. {
  1602. $vars["fp_update_user_settings_flag"] = @$_SESSION["fp_update_user_settings_flag$csid"];
  1603. if ($vars["fp_update_user_settings_flag"] == "")
  1604. { // Default value...
  1605. }
  1606. }
  1607. $settings = fp_get_system_settings();
  1608. @$vars["advising_term_id"] = $_REQUEST["advising_term_id"]; // Get it from the GET or POST.
  1609. if ($vars["advising_term_id"] == "")
  1610. {
  1611. // Set to the default advising term.
  1612. @$vars["advising_term_id"] = $_SESSION["advising_term_id$csid"];
  1613. if ($vars["advising_term_id"] == "")
  1614. {
  1615. // default value:
  1616. $vars["advising_term_id"] = $settings["advising_term_id"];
  1617. if ($vars["advising_term_id"] == "") {
  1618. // It's STILL blank?! Just use 0 then.
  1619. $vars["advising_term_id"] = "0";
  1620. }
  1621. }
  1622. }
  1623. @$vars["what_if_major_code"] = $_REQUEST["what_if_major_code"]; // Get it from the GET or POST.
  1624. if ($vars["what_if_major_code"] == "")
  1625. {
  1626. // Will equal "yes" if we ARE in whatIf mode.
  1627. @$vars["what_if_major_code"] = $_SESSION["what_if_major_code$csid"];
  1628. if ($vars["what_if_major_code"] == "")
  1629. {
  1630. // Default value:
  1631. $vars["what_if_major_code"] = "";
  1632. }
  1633. }
  1634. @$vars["what_if_catalog_year"] = $_REQUEST["what_if_catalog_year"]; // Get it from the GET or POST.
  1635. if ($vars["what_if_catalog_year"] == "")
  1636. {
  1637. @$vars["what_if_catalog_year"] = $_SESSION["what_if_catalog_year$csid"];
  1638. if ($vars["what_if_catalog_year"] == "")
  1639. {
  1640. // Default value:
  1641. $vars["what_if_catalog_year"] = "";
  1642. }
  1643. }
  1644. /*
  1645. @$vars["what_if_track_code"] = $_REQUEST["what_if_track_code"]; // Get it from the GET or POST.
  1646. if ($vars["what_if_track_code"] == "")
  1647. {
  1648. // Will equal "yes" if we ARE in whatIf mode.
  1649. @$vars["what_if_track_code"] = $_SESSION["what_if_track_code$csid"];
  1650. if ($vars["what_if_track_code"] == "")
  1651. {
  1652. // Default value:
  1653. $vars["what_if_track_code"] = "";
  1654. }
  1655. }
  1656. */
  1657. @$vars["what_if_track_degree_ids"] = $_REQUEST["what_if_track_degree_ids"]; // Get it from the GET or POST.
  1658. if ($vars["what_if_track_degree_ids"] == "")
  1659. {
  1660. // Will equal "yes" if we ARE in whatIf mode.
  1661. @$vars["what_if_track_degree_ids"] = $_SESSION["what_if_track_degree_ids$csid"];
  1662. if ($vars["what_if_track_degree_ids"] == "")
  1663. {
  1664. // Default value:
  1665. $vars["what_if_track_degree_ids"] = "";
  1666. }
  1667. }
  1668. if ($vars["what_if_major_code"] == "none")
  1669. {
  1670. $vars["what_if_major_code"] = "";
  1671. }
  1672. if ($vars["what_if_track_degree_ids"] == "none")
  1673. {
  1674. $vars["what_if_track_degree_ids"] = "";
  1675. }
  1676. // if ($vars["advising_track_code"] == "none")
  1677. // {
  1678. // $vars["advising_track_code"] = "";
  1679. // }
  1680. if ($vars["advising_track_degree_ids"] == "none")
  1681. {
  1682. $vars["advising_track_degree_ids"] = "";
  1683. }
  1684. // Settings... (from the database)
  1685. $vars["setting_available_advising_term_ids"] = $settings["available_advising_term_ids"];
  1686. $vars["setting_advising_term_id"] = $settings["advising_term_id"];
  1687. $vars["setting_current_catalog_year"] = $settings["current_catalog_year"];
  1688. $vars["setting_current_draft_catalog_year"] = $settings["current_draft_catalog_year"];
  1689. // Are we in Print View?
  1690. @$vars["print_view"] = $_REQUEST["print_view"];
  1691. // Should we try to load from the cache?
  1692. @$vars["load_from_cache"] = $_REQUEST["load_from_cache"];
  1693. if ($vars["load_from_cache"] == "")
  1694. {
  1695. // By default, attempt to load from cache.
  1696. $vars["load_from_cache"] = "yes";
  1697. }
  1698. // What "view" are we in? View by Year or by Type?
  1699. // Not the same as printView. printView should work regardless
  1700. // of our advising_view.
  1701. @$vars["advising_view"] = $_REQUEST["advising_view"];
  1702. if ($vars["advising_view"] == "")
  1703. {
  1704. @$vars["advising_view"] = $_SESSION["advising_view$csid"];
  1705. }
  1706. // Place values into session.
  1707. $_SESSION["advising_student_id$csid"] = $vars["advising_student_id"];
  1708. $_SESSION["advising_student_id"] = $vars["advising_student_id"]; // used ONLY in the error report popup!
  1709. $_SESSION["advising_major_code$csid"] = $vars["advising_major_code"];
  1710. //$_SESSION["advising_track_code$csid"] = $vars["advising_track_code"];
  1711. $_SESSION["advising_track_degree_ids$csid"] = $vars["advising_track_degree_ids"];
  1712. $_SESSION["advising_term_id$csid"] = $vars["advising_term_id"];
  1713. $_SESSION["advising_what_if$csid"] = $vars["advising_what_if"];
  1714. $_SESSION["what_if_major_code$csid"] = $vars["what_if_major_code"];
  1715. $_SESSION["what_if_catalog_year$csid"] = $vars["what_if_catalog_year"];
  1716. $_SESSION["what_if_track_degree_ids$csid"] = $vars["what_if_track_degree_ids"];
  1717. $_SESSION["advising_view$csid"] = $vars["advising_view"];
  1718. if ($bool_ignore_what_if_variables == true)
  1719. {
  1720. $vars["advising_what_if"] = "";
  1721. $vars["what_if_major_code"] = "";
  1722. $vars["what_if_catalog_year"] = "";
  1723. $vars["what_if_track_degree_ids"] = "";
  1724. }
  1725. // Are we in draft mode?
  1726. if ($_SESSION["fp_draft_mode"] == "yes")
  1727. {
  1728. $vars["bool_use_draft"] = true;
  1729. } else {
  1730. $vars["bool_use_draft"] = false;
  1731. }
  1732. $GLOBALS["fp_advising"] = $vars;
  1733. }
  1734. /**
  1735. * Implementation of hook_init
  1736. */
  1737. function advise_init() {
  1738. global $current_student_id, $user, $screen, $student, $degree_plan;
  1739. $current_student_id = @$_REQUEST["current_student_id"];
  1740. // Since this user doesn't have permission to view this student's sessions,
  1741. // he can only view his own. This is to stop hackers from experimenting with the URL
  1742. // to see other users' data.
  1743. if (!advise_can_access_view($current_student_id)) {
  1744. // Reset our global vars....
  1745. $current_student_id = "";
  1746. if (isset($user->cwid) && $user->is_student) {
  1747. $current_student_id = $user->cwid;
  1748. }
  1749. $_REQUEST["current_student_id"] = $current_student_id;
  1750. $_POST["current_student_id"] = $current_student_id;
  1751. $_GET["current_student_id"] = $current_student_id;
  1752. $_SESSION["current_student_id"] = $current_student_id;
  1753. $_REQUEST["advising_student_id"] = $current_student_id;
  1754. $_POST["advising_student_id"] = $current_student_id;
  1755. $_GET["advising_student_id"] = $current_student_id;
  1756. $_SESSION["advising_student_id"] = $current_student_id;
  1757. $GLOBALS["fp_advising"]["advising_student_id"] = $current_student_id;
  1758. $_REQUEST["advising_load_active"] = "yes";
  1759. }
  1760. if (!isset($_SESSION["fp_draft_mode"])) $_SESSION["fp_draft_mode"] = "";
  1761. // Is draft mode enabled?
  1762. if ($_SESSION["fp_draft_mode"] == "yes") {
  1763. fp_add_message("<b>" . t("Draft mode") . "</b> " . t("is currently enabled, however, substitutions and advisings will
  1764. still be saved normally."), "status", TRUE);
  1765. }
  1766. }
  1767. /**
  1768. * Implementation of hook_clear_cache
  1769. * Called by other modules, this function will take care of clearing
  1770. * anything this module has cached.
  1771. */
  1772. function advise_clear_cache() {
  1773. foreach ($_SESSION as $key => $value) {
  1774. if (strstr($key, "cache_")) {
  1775. $_SESSION[$key] = FALSE;
  1776. unset($_SESSION[$key]); // do this just to make sure our server-side session file gets overwritten
  1777. }
  1778. if (strstr($key, "advising_") || strstr($key, "what_if_")) {
  1779. $_SESSION[$key] = FALSE;
  1780. unset($_SESSION[$key]);
  1781. }
  1782. }
  1783. fp_add_message(t("Advising cache has been cleared."));
  1784. }
  1785. /**
  1786. * From menu hook. Clear just the advising cache.
  1787. *
  1788. */
  1789. function advise_perform_clear_advising_cache() {
  1790. advise_clear_cache();
  1791. fp_goto("<front>");
  1792. }
  1793. function advise_init_screen() {
  1794. global $degree_plan, $student, $fp, $window_mode, $user, $current_student_id, $screen;
  1795. $db = get_global_database_handler();
  1796. $faculty_id = $user->cwid;
  1797. // Insert our advising vars into the GLOBALS array for easy use later.
  1798. advise_init_advising_variables();
  1799. $perform_action = trim(addslashes(@$_REQUEST["perform_action"]));
  1800. if (@$_REQUEST["clear_session"] == "yes") {
  1801. //advise_save_advising_variables_to_db();
  1802. // reload our advising vars into the GLOBALS array for easy use later.
  1803. //$GLOBALS["fp_advising"] = advise_load_advising_variables_from_db($current_student_id, $user->id);
  1804. }
  1805. // Insert our advising vars into the GLOBALS array for easy use later.
  1806. //$GLOBALS["fp_advising"] = advise_load_advising_variables_from_db($current_student_id, $user->id);
  1807. $bool_what_if = false;
  1808. $csid = $current_student_id;
  1809. $cache = @$_SESSION["cache_fp$csid"];
  1810. if (@$GLOBALS["fp_advising"]["advising_what_if"] == "yes") {
  1811. $major_code = @$GLOBALS["fp_advising"]["what_if_major_code"];
  1812. $track_code = @$GLOBALS["fp_advising"]["what_if_track_code"];
  1813. $bool_what_if = true;
  1814. $cache = @$_SESSION["cache_what_if$csid"];
  1815. }
  1816. $bool_draft = true;
  1817. if (@$GLOBALS["fp_advising"]["advising_load_active"] == "yes") {
  1818. // If we are loading from Active, then rebuild the cache as well.
  1819. $bool_draft = false;
  1820. @$GLOBALS["fp_advising"]["load_from_cache"] = "no";
  1821. }
  1822. ///////////////////////
  1823. /// Disable student data Caching....
  1824. //$GLOBALS["load_from_cache"] = "no";
  1825. // Attempt to load the course inventory cache...
  1826. if ($course_inventory = unserialize(@$_SESSION["fp_cache_course_inventory"])) {
  1827. $GLOBALS["fp_course_inventory"] = $course_inventory;
  1828. }
  1829. $bool_loaded = FALSE;
  1830. if ($GLOBALS["fp_advising"]["load_from_cache"] == "yes" && $cache != "" && $fp = unserialize($cache)) {
  1831. $bool_loaded = TRUE;
  1832. $fp->db = get_global_database_handler();
  1833. $student = $fp->student;
  1834. if ($student->student_id == "") $bool_loaded = FALSE;
  1835. $degree_plan = $fp->degree_plan;
  1836. $student->db = get_global_database_handler();
  1837. $degree_plan->db = get_global_database_handler();
  1838. }
  1839. if (!$bool_loaded) {
  1840. $fp = new FlightPath();
  1841. $fp->init();
  1842. $student = $fp->student;
  1843. $degree_plan = $fp->degree_plan;
  1844. $GLOBALS["fp_advising"]["load_from_cache"] = "no";
  1845. $bool_loaded = TRUE;
  1846. }
  1847. // Should we update the USER settings for anything?
  1848. if ($GLOBALS["fp_advising"]["fp_update_user_settings_flag"] != "") {
  1849. if (!$db->update_user_settings_from_post($user->id)) {
  1850. fp_add_message(t("Unable to update user settings. Please try again later."));
  1851. }
  1852. }
  1853. // If the form has been saved, this token is expected. This protects
  1854. // against XSS attacks.
  1855. $form_token = md5("advise_display_view" . fp_token());
  1856. if ($perform_action == "save_draft") {
  1857. if ($_REQUEST["form_token"] != $form_token) {
  1858. die(t("Sorry, but you have encountered an error. A form submission was flagged
  1859. as possibly being an invalid or forged submission. This may constitute a bug
  1860. in the system. Please report this error to your Systems Administrator."));
  1861. }
  1862. // Save, then reload the student.
  1863. $adv_id_array = $fp->save_advising_session_from_post(0,true);
  1864. // Look for hook_save_advising_session()...
  1865. invoke_hook("save_advising_session", $adv_id_array);
  1866. $bool_draft = TRUE; // load draft, since we just saved it (and changed something)
  1867. }
  1868. else if ($perform_action == "save_active") {
  1869. if ($_REQUEST["form_token"] != $form_token) {
  1870. die(t("Sorry, but you have encountered an error. A form submission was flagged
  1871. as possibly being an invalid or forged submission. This may constitute a bug
  1872. in the system. Please report this error to your Systems Administrator."));
  1873. }
  1874. // Save, then go to the history screen.
  1875. $adv_id_array = $fp->save_advising_session_from_post(0,false);
  1876. // Look for hook_save_advising_session()...
  1877. invoke_hook("save_advising_session", $adv_id_array);
  1878. // Use an fp_goto command here to go to the History screen
  1879. // Serialize the adv_id_array so we can send it along in our fp_goto command...
  1880. $adv_id_serialized = serialize($adv_id_array);
  1881. fp_goto("history", "adv_id_array_serialized=" . urlencode($adv_id_serialized));
  1882. return;
  1883. }
  1884. // Is the user trying to view "by type" or by year?
  1885. if ($GLOBALS["fp_advising"]["advising_view"] == "type") {
  1886. $screen = new AdvisingScreenTypeView("", $fp);
  1887. $screen->view = "type";
  1888. }
  1889. else {
  1890. // Default advising view. "View by Year"
  1891. $screen = new AdvisingScreen("", $fp);
  1892. $screen->view = "year";
  1893. }
  1894. if (@$_REQUEST["bool_blank"] == "true" || @$_REQUEST["blank_degree_id"] != "") {
  1895. $screen->bool_blank = TRUE;
  1896. }
  1897. if ($bool_what_if == true && @$GLOBALS["fp_advising"]["what_if_major_code"] == "") {
  1898. // In other words, we are on the WhatIf tab, but we have not
  1899. // selected a major. So, just exit out. We will give the user
  1900. // a display_screen later.
  1901. return;
  1902. }
  1903. if (@$GLOBALS["fp_advising"]["load_from_cache"] != "yes") {
  1904. // do not load from cache.... load the student fresh....
  1905. /*
  1906. $fp = new FlightPath();
  1907. $fp->init();
  1908. $student = $fp->student;
  1909. $degree_plan = $fp->degree_plan;
  1910. $GLOBALS["fp_advising"]["load_from_cache"] = "no";
  1911. */
  1912. $student->load_student();
  1913. $student->load_student_substitutions();
  1914. $student->load_unassignments();
  1915. // Make sure we assign the freshly-loaded student, and re-establish all of our connections.
  1916. $fp->student = $student;
  1917. $screen->flightpath = $fp;
  1918. $screen->student = $fp->student;
  1919. $fp->flag_outdated_substitutions();
  1920. $fp->assign_courses_to_semesters(); // bare degree plan. not groups.
  1921. $fp->assign_courses_to_groups();
  1922. ////////////
  1923. /*
  1924. // Good place to output a serialization, in case we need it for testing.
  1925. $student->name = "Test Student2";
  1926. $student->student_id = "123457";
  1927. $temp = serialize($screen);
  1928. file_put_contents(fp_get_files_path() . "/test.txt", $temp);
  1929. /////////////*/
  1930. }
  1931. else {
  1932. }
  1933. if (@$GLOBALS["fp_advising"]["save_to_cache"] != "no" && $window_mode != "popup") {
  1934. if ($bool_what_if == false) {
  1935. // NOT in whatIf mode. Normal.
  1936. $_SESSION["cache_fp$csid"] = serialize($fp);
  1937. }
  1938. else {
  1939. // We are in WhatIf mode.
  1940. $_SESSION["cache_what_if$csid"] = serialize($fp);
  1941. }
  1942. }
  1943. // If we are loading from draft, then load the faculty_id which saved draft last. If we are
  1944. // loading fresh, not from draft, then load *any* faculty that saved last.
  1945. $use_faculty_id = $faculty_id;
  1946. if (!$bool_draft) $use_faculty_id = 0;
  1947. // We shouldn't supply the advising_term_id, so that it will load all terms available.
  1948. $fp->load_advising_session_from_database($use_faculty_id,"",$bool_what_if,$bool_draft,0,$faculty_id);
  1949. // Once we have loaded the advising session, we should always try to load
  1950. // from draft from then on out.
  1951. $GLOBALS["fp_advising"]["advising_load_active"] = "";
  1952. }
  1953. /**
  1954. * This is a hook which developers may use to add custom blocks (or perform other operations)
  1955. * onto the advising View or What If screen.
  1956. *
  1957. * This is called AFTER the AdvisingScreen class has called it's build_screen_elements()
  1958. * function, which draws the various semester blocks, footnotes, etc, onto the screen.
  1959. *
  1960. * This gives other modules a chance to alter the screen, or to add a custom block to the
  1961. * bottom of the screen. Note that the $screen element is sent by reference. Any changes
  1962. * you make to it will be instant; there is no need to return anything.
  1963. *
  1964. * To see how these blocks are best set up, look at AdvisingScreen->build_excess_credit(), or
  1965. * AdvisingScreen->displaySemester() for inspiration.
  1966. *
  1967. * @param AdvisingScreen &$screen
  1968. */
  1969. function hook_advise_build_screen_elements(&$screen) {
  1970. $html = "";
  1971. $html .= $screen->draw_semester_box_top("Sample", TRUE); // pass TRUE to hide the "headers"
  1972. $html .= "<tr><td colspan='8'>"; // required after the top!
  1973. ////////////////
  1974. // The content...
  1975. $html .= "<b>Hello World!</b>";
  1976. ///////////////////
  1977. // All done, time to tidy up...
  1978. $html .= "</td></tr>"; // required before the bottom!
  1979. $html .= $screen->draw_semester_box_bottom();
  1980. // Add to the screen as a "semester block".
  1981. $screen->add_to_screen($html);
  1982. }