AdvisingScreen.php

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

File

classes/AdvisingScreen.php
View source
  1. <?php
  2. class AdvisingScreen extends stdClass
  3. {
  4. public $width_array, $popup_width_array, $script_filename, $is_on_left, $box_array;
  5. public $degree_plan, $student, $bool_popup, $footnote_array, $flightpath;
  6. public $screen_mode, $db, $bool_print, $view, $user_settings;
  7. public $bool_blank, $bool_hiding_grades, $bool_force_pie_charts;
  8. public $admin_message;
  9. // Variables for the template/theme output...
  10. public $theme_location, $page_content, $page_has_search, $page_tabs, $page_on_load;
  11. public $page_hide_report_error, $page_scroll_top, $page_is_popup;
  12. public $page_title, $page_extra_css_files, $page_body_classes, $page_display_currently_advising;
  13. /**
  14. * This is the constructor. Must be named this for inheritence to work
  15. * correctly.
  16. *
  17. * @param string $script_filename
  18. * - This is the script which forms with POST to. Ex: "advise.php"
  19. *
  20. * @param FlightPath $flightpath
  21. * - FlightPath object.
  22. *
  23. * @param string $screen_mode
  24. * - A string describing what "mode" we are in.
  25. * - If left blank, we assume it is full-screen and normal.
  26. * - If set to "popup" then we are in a popup window, and we will
  27. * not draw certain elements.
  28. *
  29. */
  30. function __construct($script_filename = "", FlightPath $flightpath = null, $screen_mode = "")
  31. {
  32. $this->width_array = Array("10%", "8%","8%", "17%", "26%", "10%", "10%", "9%");
  33. $this->popup_width_array = Array("17%", "1%", "1%", "15%", "26%", "15%", "15%", "10%");
  34. $this->script_filename = $script_filename;
  35. $this->is_on_left = true;
  36. $this->box_array = array();
  37. $this->footnote_array = array();
  38. $this->page_extra_css_files = array();
  39. $this->flightpath = $flightpath;
  40. if ($flightpath != null) {
  41. $this->degree_plan = $flightpath->degree_plan;
  42. $this->student = $flightpath->student;
  43. }
  44. $this->db = get_global_database_handler();
  45. if ($screen_mode == "popup")
  46. {
  47. $this->bool_popup = true;
  48. }
  49. $this->bool_blank = false;
  50. $this->screen_mode = $screen_mode;
  51. } // construct
  52. /**
  53. * This function will attempt to determine automatically
  54. * if we are on a mobile device. If so, it will set
  55. * $this->page_is_mobile = TRUE
  56. *
  57. */
  58. function determine_mobile_device(){
  59. depricated_message('determine_mobile_device is depricated');
  60. $user_agent = $_SERVER['HTTP_USER_AGENT'];
  61. $look_for = array(
  62. "ipod",
  63. "iphone",
  64. "android",
  65. "opera mini",
  66. "blackberry",
  67. "(pre\/|palm os|palm|hiptop|avantgo|plucker|xiino|blazer|elaine)",
  68. "(iris|3g_t|windows ce|opera mobi|windows ce; smartphone;|windows ce; iemobile)",
  69. "(smartphone|iemobile)",
  70. );
  71. foreach ($look_for as $test_agent) {
  72. if (preg_match('/' . $test_agent . '/i',$user_agent)) {
  73. $this->page_is_mobile = true;
  74. break;
  75. }
  76. }
  77. $GLOBALS["fp_page_is_mobile"] = $this->page_is_mobile;
  78. } // ends function mobile_device_detect
  79. /**
  80. * This function will return the HTML to contruct a collapsible fieldset,
  81. * complete with javascript and style tags.
  82. *
  83. * @param String $content
  84. * @param String $legend
  85. * @param bool $bool_start_closed
  86. * @return String
  87. */
  88. function draw_c_fieldset($content, $legend = "Click to expand/collapse", $bool_start_closed = false)
  89. {
  90. // Create a random ID for this fieldset, js, and styles.
  91. $id = md5(rand(9,99999) . time());
  92. $start_js_val = 1;
  93. $fsstate = "open";
  94. $content_style = "";
  95. if ($bool_start_closed) {
  96. $start_js_val = 0;
  97. $fsstate = "closed";
  98. $content_style = "display: none;";
  99. }
  100. $js = "<script type='text/javascript'>
  101. var fieldset_state_$id = $start_js_val;
  102. function toggle_fieldset_$id() {
  103. var content = document.getElementById('content_$id');
  104. var fs = document.getElementById('fs_$id');
  105. if (fieldset_state_$id == 1) {
  106. // Already open. Let's close it.
  107. fieldset_state_$id = 0;
  108. content.style.display = 'none';
  109. fs.className = 'c-fieldset-closed-$id';
  110. }
  111. else {
  112. // Was closed. let's open it.
  113. fieldset_state_$id = 1;
  114. content.style.display = '';
  115. fs.className = 'c-fieldset-open-$id';
  116. }
  117. }
  118. </script>";
  119. $rtn = "
  120. <fieldset class='c-fieldset-$fsstate-$id' id='fs_$id'>
  121. <legend><a href='javascript: toggle_fieldset_$id();' class='nounderline'>$legend</a></legend>
  122. <div id='content_$id' style='$content_style'>
  123. $content
  124. </div>
  125. </fieldset>
  126. $js
  127. <style>
  128. fieldset.c-fieldset-open-$id {
  129. border: 1px solid;
  130. }
  131. fieldset.c-fieldset-closed-$id {
  132. border: 1px solid;
  133. border-bottom-width: 0;
  134. border-left-width: 0;
  135. border-right-width: 0;
  136. }
  137. legend a {
  138. text-decoration: none;
  139. }
  140. </style>
  141. ";
  142. return $rtn;
  143. }
  144. /**
  145. * Simply builds a single menu item.
  146. *
  147. * @return string
  148. */
  149. function draw_menu_item($url, $target, $icon_img, $title, $description = "") {
  150. $rtn = "";
  151. if (!$description) $extra_class = "fp-menu-item-tight";
  152. $rtn .= "<div class='fp-menu-item $extra_class'>
  153. <div class='fp-menu-item-link-line'>
  154. <a href='$url' target='$target'>$icon_img $title</a>
  155. </div>
  156. ";
  157. if ($description) {
  158. $rtn .= " <div class='fp-menu-item-description'>$description</div>";
  159. }
  160. $rtn .= "</div>";
  161. return $rtn;
  162. }
  163. /**
  164. * Uses the draw_menu_item method to draw the HTML for
  165. * all the supplied menu items, assuming the user has
  166. * permission to view them.
  167. *
  168. * Returns the HTML or "" if no menus could be drawn.
  169. *
  170. * @param unknown_type $menu_array
  171. */
  172. function draw_menu_items($menu_array) {
  173. $rtn = "";
  174. if (count($menu_array) == 0) return "";
  175. foreach($menu_array as $item) {
  176. $url = $item["url"];
  177. $target = $item["target"];
  178. $icon = $item["icon"];
  179. if ($icon) {
  180. $icon_img = "<img src='$icon' border='0'>";
  181. }
  182. else {
  183. $icon_img = "<span class='fp-menu-item-no-icon'></span>";
  184. }
  185. $title = $item["title"];
  186. $description = $item["description"];
  187. // Make sure they have permission!
  188. if ($item["permission"] != "") {
  189. if (!user_has_permission($item["permission"])) {
  190. // User did NOT have permission to view this link.
  191. continue;
  192. }
  193. }
  194. $rtn .= $this->draw_menu_item($url, $target, $icon_img, $title, $description);
  195. }
  196. return $rtn;
  197. }
  198. /**
  199. * This method outputs the screen to the browser by performing
  200. * an include(path-to-theme-file.php). All necessary information
  201. * must be placed into certain variables before the include happens.
  202. *
  203. */
  204. function output_to_browser()
  205. {
  206. global $user, $current_student_id;
  207. // This method will output the screen to the browser.
  208. // outputs the $page_content variable.
  209. // Figure out our school id.
  210. $school_id = $user->school_id;
  211. if ($current_student_id) {
  212. $school_id = db_get_school_id_for_student_id($current_student_id);
  213. }
  214. else if (isset($this->student) && is_object($this->student)) {
  215. $school_id = $this->student->school_id;
  216. }
  217. else if (isset($this->degree_plan) && is_object($this->degree_plan)) {
  218. $school_id = $this->degree_plan->school_id;
  219. }
  220. $theme_location = fp_theme_location(); // file location of the theme folder
  221. $page_logo_url = variable_get("logo_image_url", "");
  222. if ($page_logo_url == "") {
  223. $page_logo_url = $theme_location . "/images/fp_banner_default.png";
  224. }
  225. $page_content = $this->page_content;
  226. $page_tabs = $this->page_tabs;
  227. $page_has_search = $this->page_has_search;
  228. $page_on_load = $this->page_on_load;
  229. $page_scroll_top = $this->page_scroll_top;
  230. $page_is_popup = $this->page_is_popup;
  231. $page_title = $this->page_title;
  232. $page_body_classes = $this->page_body_classes;
  233. // Are we explicitly setting that this is a popup in the URL?
  234. if (isset($_REQUEST['window_mode']) && $_REQUEST['window_mode'] == 'popup') {
  235. $page_is_popup = TRUE;
  236. }
  237. $page_extra_js_files = "";
  238. $page_extra_js_settings = "";
  239. $page_extra_css_files = "";
  240. $page_breadcrumbs = "";
  241. $system_name = variable_get("system_name", "FlightPath");
  242. if ($page_title == "") {
  243. // By default, page title is this...
  244. $page_title = variable_get_for_school("school_initials", "DEMO", $school_id) . " " . $system_name;
  245. }
  246. $page_title = menu_convert_replacement_pattern($page_title);
  247. $page_display_title = $page_title;
  248. if (isset($GLOBALS["fp_set_show_title"]) && $GLOBALS["fp_set_show_title"] === FALSE) {
  249. $page_display_title = "";
  250. }
  251. $page_title = strip_tags($page_title);
  252. $page_breadcrumbs = fp_render_breadcrumbs();
  253. if ($this->student && $this->page_display_currently_advising == TRUE && !$page_is_popup) {
  254. $page_student_profile_header = fp_render_student_profile_header();
  255. }
  256. $page_hide_report_error = $this->page_hide_report_error;
  257. // We don't have permission, so do not show the report error link regardless.
  258. if (!user_has_permission('access_popup_report_contact')) {
  259. $page_hide_report_error = TRUE;
  260. }
  261. $print_option = "";
  262. if ($this->bool_print == true) {
  263. $page_body_classes .= " bool-print";
  264. }
  265. if ($page_is_popup) {
  266. $page_body_classes .= " page-is-popup";
  267. }
  268. $page_body_classes .= " school-id-" . $school_id;
  269. if (module_enabled('schools')) {
  270. $page_body_classes .= " school-code-" . schools_get_school_code_for_id($school_id);
  271. }
  272. // A dummy query-string is added to filenames, to gain control over
  273. // browser-caching. The string changes on every update or full cache
  274. // flush, forcing browsers to load a new copy of the files, as the
  275. // URL changed.
  276. $page_css_js_query_string = variable_get('css_js_query_string', '0');
  277. // Add extra JS files.
  278. if (is_array($GLOBALS["fp_extra_js"]) && count($GLOBALS["fp_extra_js"]) > 0) {
  279. foreach ($GLOBALS["fp_extra_js"] as $js_file_name) {
  280. $page_extra_js_files .= "<script type='text/javascript' src='$js_file_name?$page_css_js_query_string'></script> \n";
  281. }
  282. }
  283. // Load any extra CSS files which addon modules might have added.
  284. if (isset($GLOBALS["fp_extra_css"]) && is_array($GLOBALS["fp_extra_css"]) && count($GLOBALS["fp_extra_css"]) > 0) {
  285. foreach ($GLOBALS["fp_extra_css"] as $css_file_name) {
  286. $page_extra_css_files .= "<link rel='stylesheet' type='text/css' href='$css_file_name?$page_css_js_query_string' /> \n";
  287. }
  288. }
  289. // Javascript settings... (I know this would be better as a recursive function. For now,
  290. // you can have up to 3 layers deep. Sorry for it looking so ugly.
  291. $page_extra_js_settings .= "var FlightPath = new Object(); \n";
  292. $page_extra_js_settings .= " FlightPath.settings = new Object(); \n";
  293. foreach ($GLOBALS["fp_extra_js_settings"] as $key => $val) {
  294. if (is_array($val)) {
  295. $page_extra_js_settings .= "FlightPath.settings.$key = new Array(); \n";
  296. foreach ($val as $k => $v) {
  297. if (is_array($v)) {
  298. $page_extra_js_settings .= "FlightPath.settings.$key" . "['" . "$k'] = new Array(); \n";
  299. foreach ($v as $kk => $vv) {
  300. $page_extra_js_settings .= "FlightPath.settings.$key" . "['" . "$k']['$kk'] = '$vv'; \n";
  301. }
  302. }
  303. else {
  304. $page_extra_js_settings .= "FlightPath.settings.$key" . "['" . "$k'] = '$v'; \n";
  305. }
  306. }
  307. }
  308. else {
  309. $page_extra_js_settings .= "FlightPath.settings.$key = '$val'; \n";
  310. }
  311. }
  312. // Scrolling somewhere? Add it to the page_on_load...
  313. if (trim($page_scroll_top != "")) {
  314. $page_on_load .= " scrollTo(0, $page_scroll_top);";
  315. }
  316. // Add our dialog HTML if the page isn't a popup.
  317. if (!$page_is_popup) {
  318. $page_content .= "
  319. <!-- iframe dialog, for use by javascript later on -->
  320. <div id='fp-iframe-dialog-small' style='display: none;' title=''>
  321. <iframe id='fp-iframe-dialog-small-iframe' class='dialog-iframe' ></iframe>
  322. </div>
  323. <div id='fp-iframe-dialog-large' style='display: none;' title=''>
  324. <iframe id='fp-iframe-dialog-large-iframe' class='dialog-iframe' ></iframe>
  325. </div>
  326. ";
  327. }
  328. else {
  329. // The page is in a dialog. In order to cope with a strange bug in Chrome (as of 10-29-2020), we need
  330. // to "nudge" the dialog window 1 pixel, or sometimes the internal iframe will not show up.
  331. // We do this after it loads.
  332. $page_on_load .= "\n\n // From: https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser \n\n";
  333. $page_on_load .= ' var browser = (function() {
  334. var test = function(regexp) {return regexp.test(window.navigator.userAgent)}
  335. switch (true) {
  336. case test(/edg/i): return "Microsoft Edge";
  337. case test(/trident/i): return "Microsoft Internet Explorer";
  338. case test(/firefox|fxios/i): return "Mozilla Firefox";
  339. case test(/opr\//i): return "Opera";
  340. case test(/ucbrowser/i): return "UC Browser";
  341. case test(/samsungbrowser/i): return "Samsung Browser";
  342. case test(/chrome|chromium|crios/i): return "Google Chrome";
  343. case test(/safari/i): return "Apple Safari";
  344. default: return "Other";
  345. }
  346. })();';
  347. $page_on_load .= " if (browser == 'Google Chrome') {
  348. parent.fpNudgeDialog();
  349. }";
  350. }
  351. // Grab the appropriate sidebar & top nav content (if any)
  352. $page_sidebar_left_content = $page_top_nav_content = "";
  353. if (!$page_is_popup) {
  354. $page_sidebar_left_content = fp_render_sidebar_left_content();
  355. $page_top_nav_content = fp_render_top_nav_content();
  356. }
  357. if ($page_sidebar_left_content) {
  358. $page_body_classes .= " has-sidebar-left";
  359. }
  360. if ($page_tabs) {
  361. $page_body_classes .= " has-page-tabs";
  362. }
  363. // We are going to try to include the theme. If it can't be found, we will display a CORE theme, and display a message.
  364. $theme = variable_get("theme","themes/fp_clean");
  365. $head_template_filename = $theme . "/head.tpl.php";
  366. $page_template_filename = $theme . "/page.tpl.php";
  367. // If there is a special theme file we should be using based on the URL, set it here.
  368. $q = fp_trim(strtolower((string) $_REQUEST['q']));
  369. if ($q) {
  370. $q = trim(str_replace("/", "-", $q));
  371. if ($q) {
  372. if (file_exists($theme . "/page--" . $q . ".tpl.php")) {
  373. $page_template_filename = $theme . "/page--" . $q . ".tpl.php";
  374. }
  375. }
  376. }
  377. if (!file_exists($page_template_filename)) {
  378. print "<p><b>Theme Error:</b> Tried to load template from: $page_template_filename, but this file could not be found.
  379. <br>This is possibly because either the filename or the directory specified does not exist.
  380. <br>Contact site administrator.</p>";
  381. $page_template_filename = "themes/fp_clean" . "/page.tpl.php";
  382. }
  383. // Are we adding any external CSS files?
  384. $external_css = variable_get("external_css", "");
  385. if ($external_css) {
  386. $temp = explode(",",$external_css);
  387. foreach ($temp as $line) {
  388. if (trim($line) == "") continue;
  389. $page_extra_css_files .= "<link rel='stylesheet' type='text/css' href='" . trim($line) . "?$page_css_js_query_string' /> \n";
  390. }
  391. }
  392. /////////////////////////
  393. // Output to browser:
  394. include($head_template_filename);
  395. include($page_template_filename);
  396. } // output_to_browser
  397. /**
  398. * This function simply adds a reference for additional CSS to be
  399. * link'd in to the theme. It is used by add-on modules.
  400. *
  401. * The filename needs to be from the reference of the base
  402. * FlightPath install.
  403. *
  404. * Ex: $screen->add_css("modules/course_search/css/style.css");
  405. *
  406. * @param String $filename
  407. */
  408. function add_css($filename) {
  409. $this->page_extra_css_files[] = $filename;
  410. }
  411. /**
  412. * Clear the session varibles.
  413. *
  414. */
  415. function clear_variables()
  416. {
  417. // Clear the session variables.
  418. $csid = $_REQUEST["current_student_id"];
  419. $_SESSION["advising_student_id$csid"] = "";
  420. $_SESSION["advising_student_id"] = "";
  421. $_SESSION["advising_major_code$csid"] = "";
  422. $_SESSION["advising_track_code$csid"] = "";
  423. $_SESSION["advising_track_degree_ids$csid"] = "";
  424. $_SESSION["advising_term_id$csid"] = "";
  425. $_SESSION["advising_what_if$csid"] = "";
  426. $_SESSION["what_if_major_code$csid"] = "";
  427. $_SESSION["cache_f_p$csid"] = "";
  428. $_SESSION["cache_what_if$csid"] = "";
  429. }
  430. /**
  431. * Constructs the HTML which will be used to display
  432. * the student's transfer credits
  433. *
  434. */
  435. function build_transfer_credit()
  436. {
  437. $pC = "";
  438. $is_empty = true;
  439. $pC .= $this->draw_semester_box_top("Transfer Credit", FALSE);
  440. // Basically, go through all the courses the student has taken,
  441. // And only show the transfers. This is similar to Excess credit.
  442. $student_id = $this->student->student_id;
  443. $school_id = db_get_school_id_for_student_id($student_id);
  444. // Now, sort alphabetical and display on screen.
  445. $this->student->list_courses_taken->sort_alphabetical_order(false, true);
  446. $this->student->list_courses_taken->reset_counter();
  447. while($this->student->list_courses_taken->has_more())
  448. {
  449. $course = $this->student->list_courses_taken->get_next();
  450. // Skip non transfer credits.
  451. if ($course->bool_transfer != true)
  452. {
  453. continue;
  454. }
  455. $bool_add_footnote = false;
  456. if ($course->get_has_been_displayed($course->req_by_degree_id) == true)
  457. { // Show the footnote if this has already been displayed
  458. // elsewhere on the page.
  459. $bool_add_footnote = true;
  460. }
  461. // Tell the course what group we are coming from. (in this case: none)
  462. $course->disp_for_group_id = "";
  463. $pC .= $this->draw_course_row($course,"","",false,false,$bool_add_footnote,true);
  464. $is_empty = false;
  465. }
  466. if (@$GLOBALS["advising_course_has_asterisk"] == true)
  467. {
  468. $pC .= "<tr>
  469. <td colspan='10'>
  470. <div class=' ' style='margin-top: 10px; padding: 3px;'>
  471. <b>*</b> Courses marked with an asterisk (*) have
  472. equivalencies at " . variable_get_for_school("school_initials", "DEMO", $school_id) . ".
  473. Click on the course for more
  474. details.
  475. </div>
  476. </td>
  477. </tr>
  478. ";
  479. }
  480. $pC .= $this->draw_semester_box_bottom();
  481. if (!$is_empty)
  482. {
  483. $this->add_to_screen($pC, "TRANSFER_CREDIT");
  484. }
  485. } // function build_transfer_credit
  486. /**
  487. * Constructs the HTML which will be used to display
  488. * the student's graduate credits (if any exist)
  489. *
  490. */
  491. function build_graduate_credit()
  492. {
  493. $pC = "";
  494. $is_empty = true;
  495. $pC .= $this->draw_semester_box_top(variable_get_for_school("graduate_credits_block_title", t("Graduate Credits"), $this->student->school_id), FALSE);
  496. // Basically, go through all the courses the student has taken,
  497. // And only show the graduate credits. Similar to build_transfer_credits
  498. $graduate_level_codes_array = csv_to_array(variable_get_for_school("graduate_level_codes", "GR", $this->student->school_id));
  499. $this->student->list_courses_taken->sort_alphabetical_order(false, true);
  500. $this->student->list_courses_taken->reset_counter();
  501. while($this->student->list_courses_taken->has_more())
  502. {
  503. $course = $this->student->list_courses_taken->get_next();
  504. // Skip non graduate credits.
  505. if (!in_array($course->level_code, $graduate_level_codes_array))
  506. {
  507. continue;
  508. }
  509. // Tell the course_row what group we are coming from. (in this case: none)
  510. $course->disp_for_group_id = "";
  511. $pC .= $this->draw_course_row($course,"","",false,false,false,true);
  512. $is_empty = FALSE;
  513. }
  514. $notice = trim(variable_get_for_school("graduate_credits_block_notice", t("These courses may not be used for undergraduate credit."), $this->student->school_id));
  515. // Do we have a notice to display?
  516. if ($notice != "")
  517. {
  518. $pC .= "<tr><td colspan='8'>
  519. <div class='hypo ' style='margin-top: 15px; padding: 5px;'>
  520. <b>" . t("Important Notice:") . "</b> $notice
  521. </div>
  522. </td></tr>";
  523. }
  524. $pC .= $this->draw_semester_box_bottom();
  525. if (!$is_empty)
  526. {
  527. $this->add_to_screen($pC, "GRADUATE_CREDIT");
  528. }
  529. }
  530. /**
  531. * Constructs the HTML to show which courses have been added
  532. * by an advisor.
  533. *
  534. */
  535. function build_added_courses()
  536. {
  537. $pC = "";
  538. $semester = new Semester(DegreePlan::SEMESTER_NUM_FOR_COURSES_ADDED);
  539. if ($new_semester = $this->degree_plan->list_semesters->find_match($semester))
  540. {
  541. $this->add_to_screen($this->display_semester($new_semester), "ADDED_COURSES");
  542. }
  543. }
  544. /**
  545. * Constructs the HTML to show the Excess Credits list.
  546. *
  547. */
  548. function build_excess_credit()
  549. {
  550. $pC = "";
  551. $pC .= $this->draw_semester_box_top(t("Excess Credits"));
  552. $is_empty = true;
  553. // Should we exclude graduate credits from this list?
  554. $bool_grad_credit_block = (variable_get_for_school("display_graduate_credits_block", "yes", $this->student->school_id) == "yes") ? TRUE : FALSE;
  555. $graduate_level_codes_array = csv_to_array(variable_get_for_school("graduate_level_codes", "GR", $this->student->school_id));
  556. // Basically, go through all the courses the student has taken,
  557. // selecting out the ones that are not fulfilling any
  558. // requirements.
  559. $this->student->list_courses_taken->sort_alphabetical_order();
  560. $this->student->list_courses_taken->reset_counter();
  561. while($this->student->list_courses_taken->has_more())
  562. {
  563. $course = $this->student->list_courses_taken->get_next();
  564. if ($course->get_has_been_displayed($course->req_by_degree_id) == TRUE)
  565. { // Skip ones which have been assigned to groups or semesters.
  566. continue;
  567. }
  568. // Skip transfer credits.
  569. if ($course->bool_transfer == true)
  570. {
  571. continue;
  572. }
  573. // Skip substitutions
  574. // Only skip if we have substituted for every degree the student is enrolled in.
  575. if ($course->get_bool_substitution(-1) == TRUE)
  576. {
  577. //fpm($course->get_bool_substitution(-1));
  578. //fpm($course);
  579. continue;
  580. }
  581. // Exclude graduate credits?
  582. if ($bool_grad_credit_block && $course->level_code != "" && in_array($course->level_code, $graduate_level_codes_array)) {
  583. continue;
  584. }
  585. // Tell the course_row what group we are coming from. (in this case: none)
  586. $course->disp_for_group_id = "";
  587. $pC .= $this->draw_course_row($course,"","",false,false);
  588. $is_empty = false;
  589. }
  590. $pC .= $this->draw_semester_box_bottom();
  591. if (!$is_empty)
  592. {
  593. $this->add_to_screen($pC, "EXCESS_CREDIT");
  594. }
  595. }
  596. /**
  597. * Constructs the HTML which will show footnotes for substitutions
  598. * and transfer credits.
  599. *
  600. */
  601. function build_footnotes($bool_include_box_top = TRUE)
  602. {
  603. // Display the footnotes & messages.
  604. $student_id = $this->student->student_id;
  605. $render = array();
  606. $render['#id'] = 'AdvisingScreen_build_footnotes';
  607. $render['#student_id'] = $student_id;
  608. $render['#degree_plan'] = $this->degree_plan;
  609. $render['#degree_id'] = $this->degree_plan->degree_id;
  610. $render['#footnote_array'] = $this->footnote_array;
  611. $school_id = db_get_school_id_for_student_id($student_id);
  612. //$pC = "";
  613. $is_empty = true;
  614. if ($bool_include_box_top) {
  615. //$pC .= $this->draw_semester_box_top(t("Footnotes & Messages"), true);
  616. $render['box_top'] = array(
  617. 'value' => $this->draw_semester_box_top(t("Footnotes & Messages"), true),
  618. 'weight' => 100,
  619. );
  620. }
  621. //$pC .= "<tr><td colspan='8' class=' '>";
  622. $render['tr_td_start'] = array(
  623. 'value' => "<tr><td colspan='8' class=' '>",
  624. 'weight' => 110,
  625. );
  626. $weight = 200;
  627. $fn_type_array = array("substitution","transfer");
  628. $fn_char = array("substitution" => "S", "transfer"=>"T");
  629. $fn_name = array("substitution" => t("Substitutions"),
  630. "transfer" => t("Transfer Equivalency Footnotes"));
  631. $fn_between = array("substitution" => t("for"),
  632. "transfer" => t("for") . " " . variable_get_for_school("school_initials", "DEMO", $school_id) . "'s");
  633. for ($xx = 0; $xx <= 1; $xx++)
  634. {
  635. $fn_type = $fn_type_array[$xx];
  636. if (isset($this->footnote_array[$fn_type]) && @count($this->footnote_array[$fn_type]) < 1)
  637. {
  638. continue;
  639. }
  640. //$pC .= "<div style='padding-bottom: 10px;'><b>{$fn_name[$fn_type]}</b>";
  641. $render['section_' . $fn_name[$fn_type] . '_start'] = array(
  642. 'value' => "<div style='padding-bottom: 10px;'><b>{$fn_name[$fn_type]}</b>",
  643. 'weight' => $weight,
  644. );
  645. $weight = $weight + 10;
  646. $is_empty = false;
  647. $ccount = 0;
  648. if (isset($this->footnote_array) && is_array($this->footnote_array) && isset($this->footnote_array[$fn_type])) {
  649. $ccount = count($this->footnote_array[$fn_type]);
  650. }
  651. for ($t = 1; $t <= $ccount; $t++)
  652. {
  653. $line = @$this->footnote_array[$fn_type][$t];
  654. if ($line == "")
  655. {
  656. continue;
  657. }
  658. $extra = ".";
  659. $temp = explode(" ~~ ", $line);
  660. $o_course = fp_trim(@$temp[0]);
  661. $new_course = fp_trim(@$temp[1]);
  662. $using_hours = fp_trim(@$temp[2]);
  663. if ($using_hours != "")
  664. {
  665. $using_hours = "($using_hours " . t("hrs") . ")";
  666. }
  667. $in_group = fp_trim(@$temp[3]);
  668. $sub_id = fp_trim(@$temp[4]);
  669. $fbetween = $fn_between[$fn_type];
  670. $sub_details = $this->db->get_substitution_details($sub_id);
  671. $remarks = fp_trim(@$sub_details["remarks"]);
  672. $sub_faculty_id = @$sub_details["faculty_id"];
  673. $sub_degree_plan = new DegreePlan();
  674. $sub_degree_plan->degree_id = @$sub_details["required_degree_id"];
  675. $sub_required_group_id = @$sub_details["required_group_id"];
  676. //if ($in_group > 0 && $fn_type=="substitution")
  677. if ($sub_required_group_id != "" && $fn_type=="substitution")
  678. {
  679. $new_group = new Group();
  680. $new_group->group_id = $sub_required_group_id;
  681. $new_group->load_descriptive_data();
  682. $extra = "<div style='padding-left: 45px;'><i>" . t("in") . " $new_group->title.</i></div>";
  683. if ($new_course == $o_course || $o_course == "")
  684. {
  685. $o_course = t("was added");
  686. $fbetween = "";
  687. $extra = str_replace("<i>" . t("in"), "<i>" . t("to"), $extra);
  688. }
  689. }
  690. // Clean this up, as far as the remarks and such. Make it look similar (new function?) as popup text for a substitution.
  691. if ($remarks) $remarks = " ($remarks) ";
  692. // Build a "theme" array, so we can pass it to other modules in a hook.
  693. $theme = array();
  694. $theme["footnote"] = array(
  695. "fn_char" => $fn_char,
  696. "fn_type" => $fn_type,
  697. "fn_num" => $t,
  698. "css_class" => "",
  699. "new_course" => $new_course,
  700. "using_hours" => $using_hours,
  701. "fbetween" => $fbetween,
  702. "o_course" => $o_course,
  703. "extra" => $extra,
  704. "remarks" => $remarks,
  705. "for_degree" => $sub_degree_plan->get_title2(FALSE, TRUE),
  706. "overwrite_with_html" => "",
  707. );
  708. // Invoke a hook on our theme array, so other modules have a chance to change it up.
  709. invoke_hook("theme_advise_footnote", array(&$theme));
  710. $sup = $theme["footnote"]["fn_char"][$theme["footnote"]["fn_type"]] . $theme["footnote"]["fn_num"];
  711. // Actually gather the output for the footnote:
  712. $html = "";
  713. if ($theme["footnote"]["overwrite_with_html"] != "") {
  714. $html = $theme["footnote"]["overwrite_with_html"];
  715. }
  716. else {
  717. $html = "<div class=' advise-footnote {$theme["footnote"]["css_class"]}'>
  718. <sup>$sup</sup>
  719. <span class='advise-footnote-body'>
  720. {$theme["footnote"]["new_course"]}
  721. {$theme["footnote"]["using_hours"]}
  722. {$theme["footnote"]["fbetween"]}
  723. {$theme["footnote"]["o_course"]}{$theme["footnote"]["extra"]}{$theme["footnote"]["remarks"]}
  724. <span class='footnote-for-degree'>(Degree {$theme["footnote"]["for_degree"]})</span>
  725. </span>
  726. </div>";
  727. }
  728. $render['section_' . $fn_name[$fn_type] . '_item_' . $t] = array(
  729. 'value' => $html,
  730. 'weight' => $weight,
  731. );
  732. $weight = $weight + 10;
  733. //$pC .= $html;
  734. }
  735. //$pC .= "</div>";
  736. $render['section_' . $fn_name[$fn_type] . '_end'] = array(
  737. 'value' => "</div>",
  738. 'weight' => $weight,
  739. );
  740. }
  741. //////////////////////////////
  742. /// Unassigned transfer eqv's
  743. $this->student->list_transfer_eqvs_unassigned->load_descriptive_transfer_data();
  744. $this->student->list_transfer_eqvs_unassigned->sort_alphabetical_order();
  745. $this->student->list_transfer_eqvs_unassigned->reset_counter();
  746. $ut_is_empty = TRUE;
  747. $html = "<!--TRANS_UN_COURSES-->";
  748. while ($this->student->list_transfer_eqvs_unassigned->has_more()) {
  749. $c = $this->student->list_transfer_eqvs_unassigned->get_next();
  750. $l_si = $c->subject_id;
  751. $l_cn = $c->course_num;
  752. $l_term = $c->get_term_description(true);
  753. $html .= "<div class=' ' style='padding-left: 10px; padding-bottom: 5px;
  754. margin-left: 1.5em; text-indent: -1.5em;'>
  755. $l_si $l_cn (" . $c->get_hours() . " " . t("hrs") . ") from <em>$c->institution_name</em>.
  756. ";
  757. $html .= "</div>";
  758. $ut_is_empty = false;
  759. $is_empty = false;
  760. }
  761. if ($ut_is_empty == false)
  762. {
  763. $mtitle = "<div style='padding-bottom: 10px;'>
  764. <div style='padding-bottom: 5px;'>
  765. <b>" . t("Transfer Equivalency Removed Courses") . "</b><br>
  766. " . t("These courses have had their default transfer equivalencies removed.
  767. ") . "</div>";
  768. $html = str_replace("<!--TRANS_UN_COURSES-->",$mtitle,$html);
  769. $html .= "</div>";
  770. $render['section_trans_un_courses'] = array(
  771. 'value' => $html,
  772. 'weight' => 400,
  773. );
  774. }
  775. ////////////////////////////////////
  776. //// Moved Courses...
  777. $m_is_empty = TRUE;
  778. $html = "<!--MOVEDCOURSES-->";
  779. $this->student->list_courses_taken->sort_alphabetical_order();
  780. $this->student->list_courses_taken->reset_counter();
  781. while($this->student->list_courses_taken->has_more())
  782. {
  783. $c = $this->student->list_courses_taken->get_next();
  784. // Skip courses which haven't had anything moved.
  785. if ($c->group_list_unassigned->is_empty == true) {
  786. continue;
  787. }
  788. if ($c->course_id > 0)
  789. { $c->load_descriptive_data(); }
  790. $l_s_i = $c->subject_id;
  791. $l_c_n = $c->course_num;
  792. $l_term = $c->get_term_description(true);
  793. $c->group_list_unassigned->reset_counter();
  794. while($c->group_list_unassigned->has_more()) {
  795. $html .= "<div class=' ' style='padding-left: 10px; padding-bottom: 5px;
  796. margin-left: 1.5em; text-indent: -1.5em;'>
  797. $l_s_i $l_c_n (" . $c->get_hours_awarded() . " " . t("hrs") . ") - $c->grade - $l_term
  798. ";
  799. $group = $c->group_list_unassigned->get_next();
  800. $group->load_descriptive_data();
  801. $group_title = "";
  802. $degree_title = "";
  803. if ($group->req_by_degree_id != 0) {
  804. $tdeg = new DegreePlan();
  805. $tdeg->degree_id = $group->req_by_degree_id;
  806. $degree_title = " (" . $tdeg->get_title2(FALSE, TRUE) . ")";
  807. }
  808. if ($group->group_id > 0)
  809. {
  810. $group_title = "<i>$group->title</i>";
  811. } else {
  812. $group_title = t("the degree plan");
  813. }
  814. $html .= t("was removed from") . " $group_title$degree_title.";
  815. $html .= "</div>";
  816. }
  817. $m_is_empty = false;
  818. $is_empty = false;
  819. }
  820. if ($m_is_empty == false)
  821. {
  822. $mtitle = "<div style='padding-bottom: 10px;'>
  823. <div style='padding-bottom: 5px;' class='moved-courses'>
  824. <b>" . t("Moved Courses") . "</b><br>
  825. " . t("These courses have been moved out of their
  826. original positions on your degree plan.") . "</div>";
  827. $html = str_replace("<!--MOVEDCOURSES-->",$mtitle,$html);
  828. $html .= "</div>";
  829. $render['section_moved_courses'] = array(
  830. 'value' => $html,
  831. 'weight' => 410,
  832. );
  833. }
  834. // For admins only....
  835. if (user_has_permission("can_substitute") && $bool_include_box_top) {
  836. if ($this->bool_print != true)
  837. {// Don't display in print view.
  838. $purl = fp_url("advise/popup-toolbox/transfers");
  839. $html = "<div class='admin-toolbox-link-wrapper'>
  840. <a href='javascript: popupSmallIframeDialog(\"" . $purl . "\",\"" . t("Administrator&#39;s Toolbox") . "\",\"\");'><i class='fa fa-gears'></i> " . t("Administrator's Toolbox") . "</a>
  841. </div>";
  842. $is_empty = false;
  843. $render['section_administrator_toolbox_link'] = array(
  844. 'value' => $html,
  845. 'weight' => 700,
  846. );
  847. }
  848. }
  849. //$pC .= "</td></tr>";
  850. $render['tr_td_end'] = array(
  851. 'value' => "</td></tr>",
  852. 'weight' => 800,
  853. );
  854. if ($bool_include_box_top) {
  855. //$pC .= $this->draw_semester_box_bottom();
  856. $render['box_bottom'] = array(
  857. 'value' => $this->draw_semester_box_bottom(),
  858. 'weight' => 810,
  859. );
  860. }
  861. $output = fp_render_content($render, FALSE);
  862. if (!$is_empty)
  863. {
  864. $this->add_to_screen($output, "FOOTNOTES");
  865. }
  866. // Return so other functions can use this output, if needed.
  867. return $output;
  868. }
  869. /**
  870. * Used in the Toolbox popup, this will display content of the tab which
  871. * shows a student's substututions
  872. *
  873. * @return string
  874. */
  875. function display_toolbox_substitutions()
  876. {
  877. $pC = "";
  878. // This will display the substitution management screen.
  879. $pC .= fp_render_section_title(t("Manage Substitutions"));
  880. $pC .= "<div class=' manage-substitutions-wrapper'>
  881. " . t("The following substitutions have been made for this student:") . "
  882. <br><br>
  883. ";
  884. $is_empty = true;
  885. $this->student->list_substitutions->reset_counter();
  886. while ($this->student->list_substitutions->has_more())
  887. {
  888. $substitution = $this->student->list_substitutions->get_next();
  889. $db_substitution_id = $substitution->db_substitution_id;
  890. $course_requirement = $substitution->course_requirement;
  891. $subbed_course = $substitution->course_list_substitutions->get_first();
  892. $assigned_to_degree_id = $substitution->assigned_to_degree_id;
  893. $sub_s_i = $subbed_course->subject_id;
  894. $sub_c_n = $subbed_course->course_num;
  895. $cr_s_i = $course_requirement->subject_id;
  896. $cr_c_n = $course_requirement->course_num;
  897. $cr_hrs = $course_requirement->get_hours();
  898. $in_group = ".";
  899. //if ($subbed_course->assigned_to_group_id > 0)
  900. //if ($subbed_course->get_first_assigned_to_group_id() != "")
  901. if ($substitution->db_required_group_id != "")
  902. {
  903. $new_group = new Group();
  904. //$new_group->group_id = $subbed_course->assigned_to_group_id;
  905. //$new_group->group_id = $subbed_course->get_first_assigned_to_group_id();
  906. $new_group->group_id = $substitution->db_required_group_id;
  907. $new_group->load_descriptive_data();
  908. $in_group = " in $new_group->title.";
  909. }
  910. $sub_action = t("was substituted for");
  911. $sub_trans_notice = "";
  912. if ($substitution->bool_group_addition == true)
  913. {
  914. $sub_action = t("was added to");
  915. $cr_s_i = $cr_c_n = "";
  916. $in_group = str_replace("in","",$in_group);
  917. }
  918. if ($subbed_course->bool_transfer == true && is_object($subbed_course->course_transfer))
  919. {
  920. $sub_s_i = $subbed_course->course_transfer->subject_id;
  921. $sub_c_n = $subbed_course->course_transfer->course_num;
  922. $sub_trans_notice = "[" . t("transfer") . "]";
  923. }
  924. $extra = $by = $remarks = "";
  925. $temp = $this->db->get_substitution_details($db_substitution_id);
  926. $by = $this->db->get_faculty_name($temp["faculty_id"], false);
  927. $remarks = $temp["remarks"];
  928. $ondate = format_date($temp["posted"]);
  929. if ($by != "")
  930. {
  931. $by = " <br>&nbsp; &nbsp; " . t("Substitutor:") . " $by.
  932. <br>&nbsp; &nbsp; <i>$ondate.</i>";
  933. }
  934. if ($remarks != "")
  935. {
  936. $remarks = " <br>&nbsp; &nbsp; " . t("Remarks:") . " <i>$remarks</i>.";
  937. }
  938. // If the sub'd course had ghost hours, make a note of that.
  939. if ($subbed_course->bool_ghost_hour) {
  940. $subbed_course->substitution_hours = "0 (1 ghost) ";
  941. }
  942. if ($substitution->bool_outdated)
  943. {
  944. $extra .= " <span style='color:red'>[OUTDATED: ";
  945. $extra .= $substitution->outdated_note;
  946. $extra .= "]</span>";
  947. }
  948. $substitution_hours = $subbed_course->get_substitution_hours($assigned_to_degree_id);
  949. $pC .= "<div class=' toolbox-remove-sub-wrapper' style='margin-bottom: 20px;'>
  950. $sub_s_i $sub_c_n $sub_trans_notice ($substitution_hours " . t("hrs") . ") $sub_action
  951. $cr_s_i $cr_c_n$in_group $by$remarks $extra
  952. <br>
  953. <a href='javascript: popupRemoveSubstitution(\"$db_substitution_id\");'>" . t("Remove substitution?") . "</a>
  954. </div>";
  955. $is_empty = false;
  956. }
  957. if ($is_empty == true)
  958. {
  959. $pC .= "<div align='center'>" . t("No substitutions have been made for this student.") . "</div>";
  960. }
  961. $pC .= "</div>";
  962. watchdog("toolbox", "substitutions", array(), WATCHDOG_DEBUG);
  963. return $pC;
  964. }
  965. /**
  966. * Used in the Toolbox popup, this will display content of the tab which
  967. * shows a student's transfers
  968. *
  969. * @return string
  970. */
  971. function display_toolbox_transfers()
  972. {
  973. $pC = "";
  974. // This will display the substitution management screen.
  975. $pC .= fp_render_section_title(t("Manage Transfer Equivalencies"));
  976. $pC .= "<div class=' '>
  977. " . t("This student has the following transfer credits and equivalencies.") . "
  978. <br><br>
  979. ";
  980. $is_empty = true;
  981. $student_id = $this->student->student_id;
  982. $school_id = db_get_school_id_for_student_id($student_id);
  983. $retake_grades = csv_to_array(variable_get_for_school("retake_grades", "F,W", $school_id));
  984. $this->student->list_courses_taken->sort_alphabetical_order(false, true);
  985. $this->student->list_courses_taken->reset_counter();
  986. while($this->student->list_courses_taken->has_more())
  987. {
  988. $c = $this->student->list_courses_taken->get_next();
  989. // Skip non transfer credits.
  990. if ($c->bool_transfer != true)
  991. {
  992. continue;
  993. }
  994. if ($c->course_id > 0)
  995. {
  996. $c->load_descriptive_data();
  997. }
  998. $course = $c->course_transfer;
  999. $course->load_descriptive_transfer_data();
  1000. $l_s_i = $c->subject_id;
  1001. $l_c_n = $c->course_num;
  1002. $l_title = $this->fix_course_title($c->title);
  1003. $t_s_i = $course->subject_id;
  1004. $t_c_n = $course->course_num;
  1005. $t_term = $c->get_term_description(true);
  1006. $grade = $c->grade;
  1007. if (in_array($grade, $retake_grades)) {
  1008. $grade = "<span style='color: red;'>$grade</span>";
  1009. }
  1010. $t_inst = $this->fix_institution_name($course->institution_name);
  1011. $pC .= "<div class=' ' style='padding-bottom: 15px;'>
  1012. <b>$t_s_i $t_c_n</b> (" . $c->get_hours_awarded() . " " . t("hrs") . ") - $grade - $t_term - $t_inst
  1013. ";
  1014. if (isset($c->bool_substitution) && $c->bool_substitution_split == true)
  1015. {
  1016. $pC .= "<div class=' '><b> +/- </b> This course's hours were split in a substitution.</div>";
  1017. }
  1018. $initials = variable_get_for_school("school_initials", "DEMO", $school_id);
  1019. // Does this course NOT have an equivalency?
  1020. if ($c->course_id == 0)
  1021. {
  1022. // But, has the eqv been removed? If so, display a link to restore it,
  1023. // if not, show a link to remove it!
  1024. if ($rC = $this->student->list_transfer_eqvs_unassigned->find_match($course))
  1025. {
  1026. // Yes, the eqv WAS removed (or unassigned)
  1027. $pC .= "<div class=' '>" . t("This course's @initials equivalency was removed for this student.", array("@initials" => $initials)) . "<br>
  1028. <a href='javascript: popupRestoreTransferEqv(\"$rC->db_unassign_transfer_id\")'>" . t("Restore?") . "</a></div>";
  1029. } else {
  1030. $pC .= "<div class=' '>" . t("@initials equivalency not yet entered (or is not applicable).", array("@initials" => $initials)) . "</div>";
  1031. }
  1032. } else {
  1033. // This course *DOES* have an equivalency.
  1034. $pC .= "<div class=' '>$initials eqv: $l_s_i $l_c_n - $l_title</div>";
  1035. $pC .= "<div>
  1036. <a href='javascript: popupUnassignTransferEqv(\"" . $course->course_id . "\");'>" . t("Remove this equivalency?") . "</a>
  1037. </div>";
  1038. }
  1039. $pC .= "</div>";
  1040. $is_empty = false;
  1041. }
  1042. if ($is_empty == true) {
  1043. $pC .= "<div align='center'>" . t("There are no transfer equivalencies for this student.") . "</div>";
  1044. }
  1045. $pC .= "</div>";
  1046. watchdog("toolbox", "transfers", array(), WATCHDOG_DEBUG);
  1047. return $pC;
  1048. }
  1049. /**
  1050. * Used in the Toolbox popup, this will display content of the tab which
  1051. * shows a student's courses which they have taken.
  1052. *
  1053. * @return string
  1054. */
  1055. function display_toolbox_courses()
  1056. {
  1057. $pC = "";
  1058. $ns = $os = $fan = $fat = "";
  1059. $pC .= fp_render_section_title(t("All Student Courses"));
  1060. $csid = @$_REQUEST["current_student_id"];
  1061. $school_id = db_get_school_id_for_student_id($csid);
  1062. $order = @$_REQUEST["order"];
  1063. if ($order == "name")
  1064. {
  1065. $ns = "font-weight: bold; text-decoration: none;";
  1066. $fan = " <i class='fa fa-angle-up' style='font-weight:bold;'></i>";
  1067. } else {
  1068. $os = "font-weight: bold; text-decoration: none;";
  1069. $fat = " <i class='fa fa-angle-down' style='font-weight:bold;'></i>";
  1070. }
  1071. /*
  1072. $pC .= "<div class=' '>
  1073. " . t("This window displays all of the student's courses
  1074. which FlightPath is able to load.") . "
  1075. <br><br>
  1076. " . t("Order by:") . " &nbsp; &nbsp;";
  1077. $pC .= l(t("Name"), "advise/popup-toolbox/courses", "order=name&current_student_id=$csid", array("style" => $ns)) . "&nbsp; &nbsp;";
  1078. $pC .= l(t("Term"), "advise/popup-toolbox/courses", "order=date&current_student_id=$csid", array("style" => $os));
  1079. */
  1080. $pC .= "
  1081. <table border='0' cellpadding='2' cellspacing='3'>
  1082. <tr>
  1083. <th colspan='2'>" . l(t("Name") . $fan, "advise/popup-toolbox/courses", "order=name&current_student_id=$csid", array("style" => $ns)) . "</th>
  1084. <th>Hr</th>
  1085. <th>Gr</th>
  1086. <th width=50>" . l(t("Term") . $fat, "advise/popup-toolbox/courses", "order=date&current_student_id=$csid", array("style" => $os)) . "</th>
  1087. <th>Attributes</th>
  1088. </tr>
  1089. ";
  1090. $is_empty = true;
  1091. if ($order == "name")
  1092. {
  1093. $this->student->list_courses_taken->sort_alphabetical_order();
  1094. } else {
  1095. $this->student->list_courses_taken->sort_most_recent_first();
  1096. }
  1097. $this->student->list_courses_taken->reset_counter();
  1098. while($this->student->list_courses_taken->has_more())
  1099. {
  1100. $c = $this->student->list_courses_taken->get_next();
  1101. if ($c->course_id > 0)
  1102. {
  1103. $c->load_descriptive_data();
  1104. }
  1105. $l_s_i = $c->subject_id;
  1106. $l_c_n = $c->course_num;
  1107. $eqv_line = "";
  1108. if (isset($c->course_transfer) && $c->course_transfer->course_id > 0)
  1109. {
  1110. if ($c->course_id > 0)
  1111. {
  1112. $eqv_line = "<tr>
  1113. <td colspan='8' class=' '
  1114. style='padding-left: 20px;'>
  1115. <i>*eqv to " . variable_get_for_school("school_initials", "DEMO", $school_id) . " $l_s_i $l_c_n</i></td>
  1116. </tr>";
  1117. }
  1118. $l_s_i = $c->course_transfer->subject_id;
  1119. $l_c_n = $c->course_transfer->course_num;
  1120. }
  1121. $l_title = $this->fix_course_title($c->title);
  1122. $l_term = $c->get_term_description(true);
  1123. $h = $c->get_hours_awarded();
  1124. if ($c->bool_ghost_hour) {
  1125. $h .= "(" . t("ghost") . "<a href='javascript:alertSubGhost()'>?</a>)";
  1126. }
  1127. $pC .= "<tr>
  1128. <td valign='top' class=' '>$l_s_i</td>
  1129. <td valign='top' class=' '>$l_c_n</td>
  1130. <td valign='top' class=' '>$h</td>
  1131. <td valign='top' class=' '>$c->grade</td>
  1132. <td valign='top' class=' '>$c->term_id</td>
  1133. ";
  1134. $pC .= "<td valign='top' class=' '>";
  1135. if ($c->bool_transfer) {$pC .= "T ";}
  1136. //if ($c->bool_substitution) {$pC .= "S ";}
  1137. if ($c->get_bool_substitution()) {$pC .= "S ";}
  1138. if ($c->get_has_been_assigned_to_any_degree())
  1139. {
  1140. $pC .= "A:";
  1141. //////////////////////////////
  1142. // List all the groups/degrees this course has been assigned to!
  1143. if ($c->get_first_assigned_to_group_id() == "")
  1144. {
  1145. $pC .= "degree plan";
  1146. }
  1147. else {
  1148. $temp_group = new Group();
  1149. //$temp_group->group_id = $c->assigned_to_group_id;
  1150. $temp_group->group_id = $c->get_first_assigned_to_group_id();
  1151. $temp_group->load_descriptive_data();
  1152. $pC .= $temp_group->title;
  1153. }
  1154. }
  1155. $pC .= "</td>";
  1156. $pC .= "</tr>$eqv_line";
  1157. $is_empty = false;
  1158. }
  1159. if ($is_empty == true)
  1160. {
  1161. $pC .= "<div align='center'>" . t("No courses have been moved for this student.") . "</div>";
  1162. }
  1163. $pC .= "</table>";
  1164. $pC .= "</div>";
  1165. $pC .= "<hr><p>" . t("Attrib Legend: T = Transfer credit, A = Assigned to (group or degree plan)") . "</p>";
  1166. watchdog("toolbox", "courses", array(), WATCHDOG_DEBUG);
  1167. return $pC;
  1168. }
  1169. /**
  1170. * Used in the Toolbox popup, this will display content of the tab which
  1171. * shows a student's moved courses. That is, courses which have had
  1172. * their group memberships changed.
  1173. *
  1174. * @return string
  1175. */
  1176. function display_toolbox_moved()
  1177. {
  1178. $pC = "";
  1179. $pC .= fp_render_section_title(t("Manage Moved Courses"));
  1180. $pC .= "<div class=' '>
  1181. " . t("This student has the following course movements.") . "
  1182. <br><br>
  1183. ";
  1184. $is_empty = true;
  1185. $this->student->list_courses_taken->sort_alphabetical_order();
  1186. $this->student->list_courses_taken->reset_counter();
  1187. while($this->student->list_courses_taken->has_more())
  1188. {
  1189. $c = $this->student->list_courses_taken->get_next();
  1190. // Skip courses which haven't had anything moved.
  1191. if ($c->group_list_unassigned->is_empty == true)
  1192. {
  1193. continue;
  1194. }
  1195. if ($c->course_id > 0)
  1196. {
  1197. $c->load_descriptive_data();
  1198. }
  1199. $l_s_i = $c->subject_id;
  1200. $l_c_n = $c->course_num;
  1201. $l_title = $this->fix_course_title($c->title);
  1202. $l_term = $c->get_term_description(true);
  1203. $h = $c->get_hours_awarded();
  1204. if ($c->bool_ghost_hour) {
  1205. $h .= " [" . t("ghost") . "<a href='javascript:alertSubGhost();'>?</a>] ";
  1206. }
  1207. $pC .= "<div class=' ' style='padding-bottom: 15px;'>
  1208. <b>$l_s_i $l_c_n</b> ($h " . t("hrs") . ") - $c->grade - $l_term
  1209. ";
  1210. $c->group_list_unassigned->reset_counter();
  1211. while($c->group_list_unassigned->has_more())
  1212. {
  1213. $group = $c->group_list_unassigned->get_next();
  1214. $group->load_descriptive_data();
  1215. $group_title = "";
  1216. if ($group->group_id > 0)
  1217. {
  1218. $group_title = "<i>$group->title</i>";
  1219. } else {
  1220. $group_title = t("the degree plan");
  1221. }
  1222. $degree_title = "";
  1223. if ($group->req_by_degree_id != 0) {
  1224. $tdeg = new DegreePlan();
  1225. $tdeg->degree_id = $group->req_by_degree_id;
  1226. $degree_title = " (" . $tdeg->get_title2(FALSE, TRUE) . ")";
  1227. }
  1228. $pC .= "<div class=' '>" . t("This course was removed from") . " $group_title$degree_title.<br>
  1229. <a href='javascript: popupRestoreUnassignFromGroup(\"$group->db_unassign_group_id\")'>" . t("Restore?") . "</a>
  1230. </div>
  1231. ";
  1232. }
  1233. $pC .= "</div>";
  1234. $is_empty = false;
  1235. }
  1236. if ($is_empty == true)
  1237. {
  1238. $pC .= "<div align='center'>" . t("No courses have been moved for this student.") . "</div>";
  1239. }
  1240. $pC .= "</div>";
  1241. watchdog("toolbox", "moved", array(), WATCHDOG_DEBUG);
  1242. return $pC;
  1243. }
  1244. /**
  1245. * Constructs the HTML to show the student's test scores.
  1246. *
  1247. */
  1248. function build_test_scores()
  1249. {
  1250. // This function will build our Test Scores box.
  1251. // Only do this if the student actually has any test scores.
  1252. if ($this->student->list_standardized_tests->is_empty)
  1253. {
  1254. return;
  1255. }
  1256. $top_scores = array();
  1257. $pC = "";
  1258. $pC .= $this->draw_semester_box_top(t("Test Scores"), TRUE);
  1259. $pC .= "<tr><td colspan='8' class=' '>
  1260. ";
  1261. $fsC = "";
  1262. // Go through and find all the test scores for the student...
  1263. $this->student->list_standardized_tests->reset_counter();
  1264. while($this->student->list_standardized_tests->has_more()) {
  1265. $st = $this->student->list_standardized_tests->get_next();
  1266. $extra_date_css = "";
  1267. if (!$st->bool_date_unavailable) {
  1268. $dt = strtotime($st->date_taken);
  1269. $ddate = format_date($dt, "just_date");
  1270. }
  1271. else {
  1272. // The date was not available!
  1273. $ddate = t("N/A");
  1274. $extra_date_css = " test-date-unavailable";
  1275. }
  1276. $fsC .= "<div class='test-section'>
  1277. <b class='test-description'>$st->description</b> - <span class='test-date $extra_date_css'>$ddate</span>
  1278. <ul>";
  1279. foreach($st->categories as $position => $cat_array)
  1280. {
  1281. $fsC .= "<li><span class='test-cat-desc'>{$cat_array["description"]}</span> - <span class='test-cat-score'>{$cat_array["score"]}</span></li>";
  1282. }
  1283. $fsC .= "</ul>
  1284. </div>";
  1285. }
  1286. $pC .= fp_render_c_fieldset($fsC, t("Click to view/hide standardized test scores"), TRUE);
  1287. $pC .= "</td></tr>";
  1288. $pC .= $this->draw_semester_box_bottom();
  1289. $this->add_to_screen($pC, "TEST_SCORES");
  1290. }
  1291. /**
  1292. * This function is used by the "build" functions most often. It very
  1293. * simply adds a block of HTML to an array called box_array.
  1294. *
  1295. * @param string $content_box
  1296. */
  1297. function add_to_screen($content_box, $index = "") {
  1298. if ($index == "") {
  1299. $this->box_array[] = $content_box;
  1300. }
  1301. else {
  1302. $this->box_array[$index] = $content_box;
  1303. }
  1304. }
  1305. /**
  1306. * This function calls the other "build" functions to assemble
  1307. * the View or What If tabs in FlightPath.
  1308. *
  1309. */
  1310. function build_screen_elements()
  1311. {
  1312. // This function will build & assemble all of the onscreen
  1313. // elements for the advising screen. It should be
  1314. // called before display_screen();
  1315. $this->build_semester_list();
  1316. $this->build_excess_credit();
  1317. $this->build_test_scores();
  1318. $this->build_transfer_credit();
  1319. // Should we add the graduate credit block?
  1320. if (variable_get("display_graduate_credits_block", "yes") == "yes") {
  1321. $this->build_graduate_credit();
  1322. }
  1323. if (!$this->bool_blank)
  1324. { // Don't show if this is a blank degree plan.
  1325. $this->build_footnotes();
  1326. $this->build_added_courses();
  1327. }
  1328. // invoke a hook, to give custom modules the chance to perform actions
  1329. // (or add blocks) to the advise screen after we have run this function.
  1330. invoke_hook("advise_build_screen_elements", array(&$this));
  1331. }
  1332. /**
  1333. * This function is used to draw an individual pie chart box.
  1334. * It accepts values of top/bottom in order to come up
  1335. * with a percentage.
  1336. *
  1337. * @param string $title
  1338. *
  1339. * @param float $top_value
  1340. * - The top part of a ratio. Ex: for 1/2, $top_value = 1.
  1341. *
  1342. * @param float $bottom_value
  1343. * - The bottom part of a ratio. For 1/2, $bottom_value = 2.
  1344. * - Do not let this equal zero. If it does, the calculation
  1345. * for the pie chart will never be evaluated.
  1346. * @param string $pal
  1347. * - Which palette to use for the pie chart. If set, fore_col will be ignored in the argument list.
  1348. * - Acceptable values:
  1349. * - core
  1350. * - major
  1351. * - cumulative
  1352. * - student
  1353. * @param string $back_col
  1354. * - If $pal is left blank, the value here will be used for the "back" or "unfinished" color.
  1355. * @param string $fore_col
  1356. * - If $pal is left blank, the value here will be used for the "foreground" or "progress" color.
  1357. *
  1358. *
  1359. * @return string
  1360. */
  1361. function draw_pie_chart_box($title, $top_value, $bottom_value, $pal = "", $back_col = "", $fore_col = "", $extra = "")
  1362. {
  1363. $rtn = "";
  1364. $val = 0;
  1365. if ($bottom_value > 0) {
  1366. $val = round(($top_value / $bottom_value)*100);
  1367. }
  1368. if ($val > 100) { $val = 100; }
  1369. $leftval = 100 - $val;
  1370. if ($back_col == "") $back_col = "660000";
  1371. if ($fore_col == "") $fore_col = "FFCC33";
  1372. if ($pal == "major") {
  1373. $fore_col = "93D18B";
  1374. }
  1375. if ($pal == "cumulative") {
  1376. $fore_col = "5B63A5";
  1377. }
  1378. // Remove # from colors, if needed.
  1379. $fore_col = str_replace("#", "", $fore_col);
  1380. $back_col = str_replace("#", "", $back_col);
  1381. $vval = $val;
  1382. if ($vval < 1) $vval = 1;
  1383. // Create a graph using our built-in pchart api:
  1384. // First, establish a token to we know the script is being called from US:
  1385. if (!isset($_SESSION["fp_pie_chart_token"])) {
  1386. $_SESSION["fp_pie_chart_token"] = md5(fp_token());
  1387. }
  1388. //old Google API url: $pie_chart_url = "https://chart.googleapis.com/chart?cht=p&chd=t:$vval,$leftval&chs=75x75&chco=$fore_col|$back_col&chp=91.1";
  1389. $pie_chart_url = base_url() . "/libraries/pchart/fp_pie_chart.php?progress=$vval&unfinished=$leftval&unfinished_col=$back_col&progress_col=$fore_col&token=" . $_SESSION["fp_pie_chart_token"];
  1390. $rtn .= "<table border='0' width='100%' height='100' class='pie-chart-individual-table pie-chart-individual-table-" . fp_get_machine_readable(strtolower($title)) . "' cellpadding='0' cellspacing='0' >
  1391. <tr class='pie-chart-title-tr'>
  1392. <td class='pie-chart-box-title-td' align='center' height='20'>
  1393. " . fp_render_section_title($title, 'pie-chart-box-section') . "
  1394. </td>
  1395. </tr>
  1396. <tr class='pie-chart-inner-table-tr'>
  1397. <td class='pie-chart-inner-table-td'>
  1398. <table border='0' class='pie-chart-chart-table'>
  1399. <td class='pie-visualization'>
  1400. <img src='$pie_chart_url'>
  1401. </td>
  1402. <td class='pie-values'>
  1403. <div class='pie-val-percent'>
  1404. <span class='pie-val-percent-complete'>$val% <span class='pie-v-cap'>" . t("Complete") . "</span></span>
  1405. </div>
  1406. <div class='pie-val-top-bottom'>
  1407. ( <span class='pie-val-top-val'>$top_value</span>
  1408. / <span class='pie-val-bottom-val'>$bottom_value <span class='pie-v-cap'>" . t("hours") . "</span></span> )
  1409. </div>
  1410. $extra";
  1411. $rtn .= "
  1412. </td>
  1413. </table>
  1414. </td>
  1415. </tr>
  1416. </table>
  1417. ";
  1418. return $rtn;
  1419. }
  1420. /**
  1421. * This function calls drawPieChart to construct the student's 3
  1422. * progress pie charts.
  1423. *
  1424. * @return string
  1425. */
  1426. function draw_progress_boxes()
  1427. {
  1428. global $user;
  1429. // Draw the boxes for student progress (where
  1430. // the pie charts go!)
  1431. $rtn = "";
  1432. if (!$this->db) {
  1433. $this->db = get_global_database_handler();
  1434. }
  1435. $bool_charts_are_hidden = FALSE;
  1436. // have we already calculated this degree's data?
  1437. if (@$this->degree_plan->bool_calculated_progess_hours != TRUE)
  1438. {
  1439. // Only bother to get the types calculations needed for the piecharts
  1440. // Get the requested piecharts from our config...
  1441. $types = array();
  1442. $temp = variable_get_for_school("pie_chart_config", "c ~ Core Requirements\nm ~ Major Requirements\ndegree ~ Degree Progress", $this->student->school_id);
  1443. $lines = explode("\n", $temp);
  1444. foreach ($lines as $line) {
  1445. if (trim($line) == "") continue;
  1446. $temp = explode("~", $line);
  1447. $requirement_type = trim($temp[0]);
  1448. $types[$requirement_type] = trim($temp[1]);
  1449. }
  1450. $this->degree_plan->calculate_progress_hours(FALSE, $types);
  1451. $this->degree_plan->calculate_progress_quality_points(FALSE, $types);
  1452. }
  1453. // Create a "theme" array for later use.
  1454. $pie_chart_theme_array = array();
  1455. $pie_chart_theme_array["screen"] = $this;
  1456. $pie_chart_theme_array["student"] = $this->student;
  1457. $pie_chart_theme_array["degree_plan"] = $this->degree_plan;
  1458. // Get the requested piecharts from our config...
  1459. $temp = variable_get_for_school("pie_chart_config", "c ~ Core Requirements\nm ~ Major Requirements\ndegree ~ Degree Progress", $this->student->school_id);
  1460. $config_lines = explode("\n", $temp);
  1461. // Go through each of the degrees we have piecharts for
  1462. foreach ($this->degree_plan->gpa_calculations as $degree_id => $val) {
  1463. $dp = new DegreePlan();
  1464. $dp->degree_id = $degree_id;
  1465. if ($degree_id > 0) {
  1466. $dp->load_descriptive_data();
  1467. $d_title = $dp->get_title2(FALSE, TRUE);
  1468. $d_code = fp_get_machine_readable($dp->major_code);
  1469. }
  1470. else {
  1471. // Degree_id == 0, so this is the "overall" degree.
  1472. $d_title = t("Overall Progress");
  1473. $d_code = "PIE_OVERALL_PROGRESS";
  1474. }
  1475. // Add to our theme array.
  1476. $pie_chart_theme_array["degree_rows"][$degree_id] = array(
  1477. "degree_id" => $degree_id,
  1478. "row_label" => $d_title,
  1479. "row_classes" => "",
  1480. "degree_plan" => $dp,
  1481. "degree_major_code_machine" => $d_code,
  1482. "bool_display" => TRUE,
  1483. );
  1484. foreach ($config_lines as $line) {
  1485. if (trim($line) == "") continue;
  1486. $temp = explode("~", $line);
  1487. $requirement_type = trim($temp[0]);
  1488. $label = trim($temp[1]);
  1489. $unfinished_col = @trim($temp[2]);
  1490. $progress_col = @trim($temp[3]);
  1491. if ($unfinished_col == "") $unfinished_col = "660000";
  1492. if ($progress_col == "") $progress_col = "FFCC33";
  1493. // Okay, let's see if this degreeplan even has any data on this requirement type.
  1494. $total_hours = $this->degree_plan->gpa_calculations[$degree_id][$requirement_type]["total_hours"]*1;
  1495. $fulfilled_hours = $this->degree_plan->gpa_calculations[$degree_id][$requirement_type]["fulfilled_hours"]*1;
  1496. $qpts = $this->degree_plan->gpa_calculations[$degree_id][$requirement_type]["qpts"]*1;
  1497. if (floatval($total_hours) == 0) continue; // no hours for this requirement type!
  1498. // Setting to display GPA
  1499. $gpa = $extra_gpa = "";
  1500. if (variable_get_for_school("pie_chart_gpa", "no", $this->student->school_id) == "yes") {
  1501. if ($this->degree_plan->gpa_calculations[$degree_id][$requirement_type]["qpts_hours"] > 0) {
  1502. $gpa = fp_truncate_decimals($qpts / $this->degree_plan->gpa_calculations[$degree_id][$requirement_type]["qpts_hours"], 3);
  1503. }
  1504. if ($gpa) {
  1505. $extra_gpa = "<div class='view-extra-gpa ' style='text-align: right; color: gray;'>GPA: $gpa</div>";
  1506. }
  1507. }
  1508. // If we are here, then there is indeed enough data to create a piechart!
  1509. // Generate the pie chart and add to our array, for later display.
  1510. $html = $this->draw_pie_chart_box($label,$fulfilled_hours, $total_hours, "", $unfinished_col, $progress_col, $extra_gpa);
  1511. $hide_pie_html = "$label: $fulfilled_hours / $total_hours";
  1512. // Will only display if we've set it above.
  1513. if ($gpa) {
  1514. $hide_pie_html .= " ($gpa)";
  1515. }
  1516. $pie_chart_html_array[] = array(
  1517. "pie" => $html,
  1518. "hide_pie" => $hide_pie_html,
  1519. );
  1520. // Add to our theme array
  1521. $pie_chart_theme_array["degree_rows"][$degree_id]["data"][$requirement_type] = array(
  1522. "full_html" => $html,
  1523. "hide_pie_html" => $hide_pie_html,
  1524. "requirement_type" => $requirement_type,
  1525. "label" => $label,
  1526. "unfinished_col" => $unfinished_col,
  1527. "progress_col" => $progress_col,
  1528. "total_hours" => $total_hours,
  1529. "fulfilled_hours" => $fulfilled_hours,
  1530. "qpts" => $qpts,
  1531. "bool_display" => TRUE,
  1532. "pie_classes" => '',
  1533. );
  1534. } // foreach $line (for piechart by type)
  1535. } //foreach $degree_id
  1536. //////////////////
  1537. // Send the pie_chart_theme_array to a hook for possible extra processing.
  1538. invoke_hook("theme_pie_charts", array(&$pie_chart_theme_array));
  1539. //////////////////
  1540. $prcount = 0;
  1541. $total_rows = count($pie_chart_theme_array["degree_rows"]);
  1542. $degree_classes = fp_get_degree_classifications();
  1543. // Now, cycle through all of the 'rows' of degrees we need to draw.
  1544. foreach ($pie_chart_theme_array["degree_rows"] as $degree_id => $details) {
  1545. if ($details["bool_display"] === FALSE) continue; // hide the entire row
  1546. // We also want to denote if this is part of a "combined" degree or not.
  1547. $extra_pie_trtd_class = "";
  1548. if ($this->degree_plan->is_combined_dynamic_degree_plan) {
  1549. $extra_pie_trtd_class .= "pie-combined-dynamic-degree-plan";
  1550. }
  1551. else {
  1552. $extra_pie_trtd_class .= "pie-single-degree-plan";
  1553. }
  1554. $degree_class = @$details['degree_plan']->degree_class;
  1555. if ($degree_class == "") $degree_class = "NOT_SET";
  1556. $degree_level_num = intval(@$degree_classes['machine_name_to_level_num'][$degree_class]);
  1557. $rtn .= "<tr class='pie-degree-row pie-degree-row-$degree_id pie-degree-row-class-$degree_class pie-total-rows-$total_rows pie-degree-row-degree-level-num-$degree_level_num pie-row-count-$prcount {$details['row_classes']}'><td colspan='2' class='$extra_pie_trtd_class'>
  1558. <div class='pie-row-label'>{$details["row_label"]}</div>";
  1559. $td_width = "";
  1560. if (@count($pie_chart_html_array) > 0) {
  1561. $td_width = round(100 / count($pie_chart_html_array));
  1562. }
  1563. if (!isset($user->settings["hide_charts"])) $user->settings["hide_charts"] = "";
  1564. if ($this->bool_force_pie_charts || ($user->settings["hide_charts"] != "hide" && $this->bool_blank == FALSE ))
  1565. { // Display the pie charts
  1566. $bool_charts_are_hidden = FALSE;
  1567. $rtn .= "
  1568. <div style='margin-bottom: 10px;' class='pies-wrapper'>
  1569. <table class='pie-chart-table' width='100%' cellspacing='0' cellpadding='0' border='0'>
  1570. <tr>
  1571. ";
  1572. $c = 0;
  1573. if (@isset($pie_chart_theme_array['degree_rows'][$degree_id]["data"])) {
  1574. foreach ($pie_chart_theme_array['degree_rows'][$degree_id]["data"] as $requirement_type => $val) {
  1575. $html = $val["full_html"];
  1576. if (@$val["bool_display"] === FALSE) continue; // this particular chart shouldn't be shown.
  1577. $style = @($c == count($pie_chart_html_array) - 1) ? "" : "padding-right:5px;";
  1578. $rtn .= "<td width='$td_width%' style='$style' class='td_full_pie td_full_pie_$requirement_type " . @$val["pie_classes"] . "'>
  1579. " . $html . "
  1580. </td>";
  1581. $c++;
  1582. }
  1583. }
  1584. $rtn .= " </table>";
  1585. $rtn .= "</div>"; // class pies-wrapper
  1586. }
  1587. else {
  1588. // Hide the charts!
  1589. $bool_charts_are_hidden = TRUE;
  1590. $rtn .= "
  1591. <table border='0' width='100%' class='pie-chart-table-hide-charts' cellpadding='0' cellspacing='0' >
  1592. <tr class='pie-hidden-charts-label-row'>
  1593. <td colspan='10' class='' align='center' height='20'>
  1594. " . fp_render_section_title(t("Progress"), 'hidden-pie-charts-section') . "
  1595. </td>
  1596. </tr>
  1597. <tr class='pie-hidden-charts-row'>";
  1598. $c = 0;
  1599. if (isset($pie_chart_theme_array['degree_rows'][$degree_id]["data"])) {
  1600. foreach ($pie_chart_theme_array['degree_rows'][$degree_id]["data"] as $requirement_type => $val) {
  1601. $html = $val["hide_pie_html"];
  1602. if ($val["bool_display"] === FALSE) continue; // this particular chart shouldn't be shown.
  1603. $rtn .= "<td width='$td_width%' align='center' class='td_hidden_pie td_hidden_pie_$requirement_type {$val["pie_classes"]} '>
  1604. " . $html . "
  1605. </td>";
  1606. $c++;
  1607. }
  1608. }
  1609. $rtn .= "
  1610. </tr>
  1611. </table>";
  1612. }
  1613. $rtn .= "</td></tr>";
  1614. $prcount++;
  1615. } // foreach degree_rows
  1616. return $rtn;
  1617. }
  1618. /**
  1619. * Will display the "public note" at the top of a degree. This
  1620. * was entred in Data Entry.
  1621. *
  1622. * @return string
  1623. */
  1624. function draw_public_note()
  1625. {
  1626. // This will display a "public note" to the user about
  1627. // this degree. The public note was entered in Data Entry.
  1628. if (count($this->degree_plan->public_notes_array) == 0)
  1629. {
  1630. return "";
  1631. }
  1632. $pC = "";
  1633. foreach ($this->degree_plan->public_notes_array as $degree_id => $note) {
  1634. if (trim($note) != "") {
  1635. $pC .= "<tr><td colspan='8'>
  1636. <div class=' '
  1637. style='border: 5px double #C1A599;
  1638. padding: 5px;
  1639. margin: 10px;'>
  1640. <b>" . t("Important Message:") . "</b> $note
  1641. </div>
  1642. </td></tr>";
  1643. }
  1644. }
  1645. return $pC;
  1646. }
  1647. /**
  1648. * This function generates the HTML to display the screen. Should
  1649. * be used in conjunction with output_to_browser()
  1650. *
  1651. * @return string
  1652. */
  1653. function display_screen()
  1654. {
  1655. // This will generate the html to display the screen.
  1656. $pC = "";
  1657. $school_id = db_get_school_id_for_student_id($this->student->student_id);
  1658. if (!$this->db) {
  1659. $this->db = get_global_database_handler();
  1660. }
  1661. if ($this->bool_hiding_grades && !$this->bool_print && variable_get_for_school("hiding_grades_message", '', $school_id) != "")
  1662. {
  1663. // Display the message about us hiding grades.
  1664. $pC .= "
  1665. <tr><td colspan='2'>
  1666. <div class=' hypo' style='margin-top: 4px; margin-bottom: 4px;
  1667. padding: 2px; border: 1px solid maroon;'>
  1668. <table border='0' cellspacing='0' cellpadding='0'>
  1669. <td valign='top'>
  1670. <img src='" . fp_theme_location() . "/images/alert_lg.gif' >
  1671. </td>
  1672. <td valign='middle' class=' ' style='padding-left: 8px;'>
  1673. " . variable_get_for_school("hiding_grades_message", "", $school_id) . "
  1674. </td>
  1675. </table>
  1676. </div>
  1677. </td></tr>
  1678. ";
  1679. }
  1680. //$pC .= $this->draw_currently_advising_box();
  1681. $pC .= $this->draw_progress_boxes();
  1682. $pC .= $this->draw_public_note();
  1683. $t = 0;
  1684. foreach ($this->box_array as $index => $box_array_contents) {
  1685. $align = "right";
  1686. if ($this->is_on_left)
  1687. {
  1688. $pC .= "<tr>";
  1689. $align= "left";
  1690. }
  1691. $css_index = fp_get_machine_readable($index);
  1692. $pC .= "<td valign='top' align='$align' class='fp-boxes fp-boxes-$css_index'>";
  1693. $pC .= $box_array_contents;
  1694. $pC .= "</td>";
  1695. if (!$this->is_on_left) // on right of page
  1696. {
  1697. $pC .= "</tr>";
  1698. }
  1699. $this->is_on_left = !$this->is_on_left;
  1700. }
  1701. if (!$this->is_on_left) // on right of the page.
  1702. { // close up any loose ends.
  1703. $pC .= "</tr>";
  1704. }
  1705. if (user_has_permission("can_advise_students"))
  1706. {
  1707. if (!$this->bool_print && !$this->bool_blank)
  1708. {
  1709. $pC .= "<tr>";
  1710. $pC .= "<td class='fp-boxes fp-boxes-blank'>&nbsp;</td>";
  1711. $render = array();
  1712. //$render['html'] = fp_render_button(t("Submit"),"submitSaveActive();");
  1713. $render['submit_button_html'] = array(
  1714. 'value' => "<div class='buttons form-element element-type-submit'>
  1715. <input type='button' id='mainform_submit_btn' value='" . t("Submit") . "' onClick='submitSaveActive();'>
  1716. </div>",
  1717. 'weight' => 100,
  1718. );
  1719. invoke_hook("content_alter", array(&$render, 'advise_submit_button'));
  1720. $pC .= "<td class='fp-boxes fp-boxes-submit-button' align='center'>
  1721. <div class=' advise_submit_button_wrapper' style='margin-top:35px; margin-bottom:10px; padding: 10px;'>
  1722. " . fp_render_content($render) . "
  1723. </div>
  1724. </td></tr>
  1725. ";
  1726. //$this->add_to_screen("<input type='button' value='Submit' onClick='submitSaveActive();'>");
  1727. }
  1728. }
  1729. return $pC;
  1730. }
  1731. /**
  1732. * Returns the HTML to draw a pretty button.
  1733. *
  1734. * @param string $title
  1735. * @param string $on_click
  1736. * @param bool $bool_padd
  1737. * @param string $style
  1738. * @return string
  1739. */
  1740. function draw_button($title, $on_click, $bool_padd = true, $style = "")
  1741. {
  1742. // Style is expected to look like:
  1743. // style='some:thing;'
  1744. // with SINGLE apostrophes! not quotes.
  1745. $on_mouse = "onmouseover='this.className=\"gradbutton gradbutton_hover hand\";'
  1746. onmouseout='this.className=\"gradbutton hand\";'
  1747. onmousedown='this.className=\"gradbutton gradbutton_down hand\";'
  1748. onmouseup='this.className=\"gradbutton gradbutton_hover hand\";'
  1749. ";
  1750. if ($bool_padd)
  1751. {
  1752. $padd = "&nbsp; &nbsp;";
  1753. }
  1754. $rtn = "<span class='gradbutton hand' onClick='$on_click' $on_mouse $style >
  1755. $padd $title $padd
  1756. </span>
  1757. ";
  1758. return $rtn;
  1759. }
  1760. /**
  1761. * Constructs the HTML to display the list of semesters for the student.
  1762. *
  1763. */
  1764. function build_semester_list() {
  1765. $list_semesters = $this->degree_plan->list_semesters;
  1766. // Go through each semester and add it to the screen...
  1767. $list_semesters->reset_counter();
  1768. while($list_semesters->has_more())
  1769. {
  1770. $semester = $list_semesters->get_next();
  1771. $semester->reset_list_counters();
  1772. if ($semester->semester_num == DegreePlan::SEMESTER_NUM_FOR_COURSES_ADDED)
  1773. { // These are the "added by advisor" courses. Skip them.
  1774. continue;
  1775. }
  1776. $semester->req_by_degree_id = $this->degree_plan->degree_id;
  1777. $disp_sem = $this->display_semester($semester, TRUE);
  1778. if ($disp_sem) {
  1779. $this->add_to_screen($disp_sem, "SEMESTER_" . $semester->semester_num);
  1780. }
  1781. }
  1782. }
  1783. /**
  1784. * This function is called when we know we are on a mobile
  1785. * browser. We have to handle tab rendering differently
  1786. * in order to make them all fit.
  1787. *
  1788. * @param unknown_type $tab_array
  1789. */
  1790. function z__draw_mobile_tabs($tab_array) {
  1791. $rtn = "";
  1792. $js_vars = "var mobileTabSelections = new Array(); ";
  1793. if (count($tab_array) <= 1) return "";
  1794. $rtn .= "<table border='0' width='200' cellpadding='0' cellspacing='0' class='fp-mobile-tabs'>
  1795. <td>
  1796. <b>Display: </b>";
  1797. /* if (count($tab_array) == 1) {
  1798. // Just one element, no need to render the select list.
  1799. $rtn .= $tab_array[0]["title"];
  1800. $rtn .= "</td></table>";
  1801. return $rtn;
  1802. }
  1803. */
  1804. $rtn .= "<select onChange='executeSelection()' id='mobileTabsSelect'>";
  1805. for ($t = 0; $t < count($tab_array); $t++)
  1806. {
  1807. $title = $tab_array[$t]["title"];
  1808. $active = $tab_array[$t]["active"];
  1809. $on_click = $tab_array[$t]["on_click"];
  1810. if ($title == "")
  1811. {
  1812. continue;
  1813. }
  1814. $sel = ($active == true) ? $sel = "selected":"";
  1815. $rtn .= "<option $sel value='$t'>$title</option>";
  1816. $js_vars .= "mobile_tab_selections[$t] = '$on_click'; \n";
  1817. }
  1818. $rtn .= "</select>
  1819. </td></table>";
  1820. $rtn .= '
  1821. <script type="text/javascript">
  1822. ' . $js_vars . '
  1823. function executeSelection() {
  1824. var sel = document.getElementById("mobileTabsSelect").value;
  1825. var statement = mobile_tab_selections[sel];
  1826. // Lets execute the statement...
  1827. eval(statement);
  1828. }
  1829. </script>
  1830. ';
  1831. return $rtn;
  1832. }
  1833. /**
  1834. * Displays the contents of the Descripton tab for the course popup.
  1835. *
  1836. * @param int $course_id
  1837. * - The course_id of the course to show. Leave blank if supplying
  1838. * the object instead.
  1839. *
  1840. * @param Course $course
  1841. * - The course object to display. Leave as NULL if supplying
  1842. * the course_id instead.
  1843. *
  1844. * @param Group $group
  1845. * - The Group object that this course has been placed into.
  1846. *
  1847. * @param bool $show_advising_buttons
  1848. * - Should we show the advising buttons in this popup? Would be
  1849. * set to false for student view, or for anyone who is not
  1850. * allowed to advise this course into a group for the student.
  1851. *
  1852. * @return string
  1853. */
  1854. function display_popup_course_description($course_id = "", Course $course = NULL, $group = NULL, $show_advising_buttons = FALSE)
  1855. {
  1856. $pC = "";
  1857. $db = $this->db;
  1858. if ($course_id != "" && $course_id != 0) {
  1859. $course = new Course($course_id);
  1860. }
  1861. // Set up our "render array" for later rendering, using the render API.
  1862. $render = array();
  1863. $render["#id"] = "AdvisingScreen_display_popup_course_description";
  1864. $render["#course"] = array(
  1865. 'type' => 'do_not_render',
  1866. 'value' => $course,
  1867. );
  1868. // Note: $render['#group'] is set lower in this function.
  1869. $db_group_requirement_id = @$_REQUEST["db_group_requirement_id"];
  1870. if ($course == null)
  1871. {
  1872. // No course available!
  1873. $render["no_course_selected"] = array(
  1874. "type" => "markup",
  1875. "value" => t("No course was selected. Please
  1876. click the Select tab at the top of the screen."),
  1877. "attributes" => array("style" => "margin-top: 13px;", "class" => " "),
  1878. );
  1879. $pC .= fp_render_content($render);
  1880. return $pC;
  1881. }
  1882. $school_id = $course->school_id;
  1883. // Not sure I need this line anymore.
  1884. $datastring_max_hours = $course->max_hours;
  1885. $datastring_bool_new_from_split = $course->get_bool_substitution_new_from_split();
  1886. $req_by_degree_id = $course->req_by_degree_id;
  1887. $advising_term_id = @$GLOBALS["fp_advising"]["advising_term_id"];
  1888. $course->load_descriptive_data(TRUE, TRUE, TRUE, FALSE, FALSE, FALSE);
  1889. $course_hours = $course->get_catalog_hours();
  1890. if ($course->bool_transfer)
  1891. {
  1892. // Nothing at the moment.
  1893. }
  1894. // Does this course have more than one valid (non-excluded) name?
  1895. $other_valid_names = "";
  1896. if (count($course->array_valid_names) > 1)
  1897. {
  1898. for ($t = 0; $t < count($course->array_valid_names); $t++)
  1899. {
  1900. $name = $course->array_valid_names[$t];
  1901. if ($name == "$course->subject_id~$course->course_num")
  1902. {
  1903. continue;
  1904. }
  1905. $other_valid_names .= ", " . str_replace("~"," ",$name);
  1906. }
  1907. }
  1908. $course->fix_title();
  1909. $initials = variable_get("school_initials", "DEMO", $school_id);
  1910. $pC .= "<!--EQV1-->";
  1911. $bool_transferEqv = true;
  1912. if ($course->bool_transfer)
  1913. {
  1914. // This is a transfer course. Begin by displaying the transfer credit's
  1915. // information.
  1916. $course->course_transfer->load_descriptive_transfer_data($this->student->student_id, $course->term_id);
  1917. $hrs = $course->course_transfer->get_hours()*1;
  1918. if ($hrs == 0)
  1919. {
  1920. $hrs = $course->get_hours();
  1921. }
  1922. // make transfer course titles all caps.
  1923. $course->course_transfer->title = strtoupper($course->course_transfer->title);
  1924. $html = "";
  1925. $html .= "<div style='margin-top: 13px;' class=' '>
  1926. <b>" . t("Transfer Credit Information:") . "</b><br>
  1927. <div style='margin-left: 20px;' class=' '>
  1928. " . t("Course:") . " " . $course->course_transfer->subject_id . " " . $course->course_transfer->course_num . "
  1929. - " . $course->course_transfer->title . " ($hrs " . t("hrs") . ")<br>
  1930. " . t("Institution:") . " " . $this->fix_institution_name($course->course_transfer->institution_name) . "<br>
  1931. " . t("Term:") . " " . $course->get_term_description() . "<br>
  1932. <!-- Grade: " . $course->grade . "<br> -->
  1933. ";
  1934. $transfer_eqv_text = $course->course_transfer->transfer_eqv_text;
  1935. if ($transfer_eqv_text == "") {
  1936. $transfer_eqv_text = t("Not entered or not applicable.");
  1937. $bool_transferEqv = false;
  1938. }
  1939. $html .= "$initials Eqv: $transfer_eqv_text<br>
  1940. </div>
  1941. </div>";
  1942. $render["transfer_credit_info"] = array(
  1943. "type" => "markup",
  1944. "value" => $html,
  1945. );
  1946. } // if course->bool_transfer
  1947. if ($course->course_id != 0)
  1948. {
  1949. $html = "";
  1950. $use_hours = $course_hours;
  1951. if ($course->bool_transfer)
  1952. {
  1953. $html .= "<b>$initials " . t("Equivalent Course Information:") . "</b><br>
  1954. <b>$course->subject_id $course->course_num</b> - ";
  1955. $new_course = new Course();
  1956. $new_course->course_id = $course->course_id;
  1957. $new_course->load_descriptive_data();
  1958. $use_hours = $new_course->get_catalog_hours();
  1959. }
  1960. // if this is a substitution, use the number of hours for the ORIGNAL course.
  1961. if ($course->get_bool_substitution() == TRUE) {
  1962. $sub_id = $course->db_substitution_id_array[$course->get_course_substitution()->req_by_degree_id];
  1963. $temp = $db->get_substitution_details($sub_id);
  1964. $sub_hours = @$temp['sub_hours'] * 1; // trim excess zeros with *1.
  1965. if ($sub_hours < $use_hours) {
  1966. $use_hours = $sub_hours;
  1967. }
  1968. }
  1969. $html .= "
  1970. <b>$course->subject_id $course->course_num - $course->title ($use_hours " . t("hrs") . ")</b>";
  1971. $render["course_title_line"] = array(
  1972. "type" => "markup",
  1973. "value" => $html,
  1974. "attributes" => array("style" => "margin-top: 13px; margin-bottom: 0;", "class" => " "),
  1975. "weight" => 10,
  1976. );
  1977. // If the course can be repeated for credit, show that information next.
  1978. if ($course->repeat_hours > $course->min_hours)
  1979. {
  1980. $html = t("May be repeated for up to @repeat hours of credit.", array("@repeat" => floatval($course->repeat_hours))); // floatval trims excess zeroes from display.
  1981. // if it is essentially infinite, then we just say it can be repeated for credit, period.
  1982. if ($course->repeat_hours > 20) {
  1983. $html = t("May be repeated for credit.");
  1984. }
  1985. $render["course_repeat_line"] = array(
  1986. "type" => "markup",
  1987. "value" => $html,
  1988. "attributes" => array("class" => " course-search-repeat"),
  1989. "weight" => 15,
  1990. );
  1991. }
  1992. } // if course->course_id != 0
  1993. if ($course->get_bool_substitution_new_from_split($req_by_degree_id) || $course->get_bool_substitution_split($req_by_degree_id))
  1994. {
  1995. $html = "";
  1996. $html .= "<div class=' ' style='margin-bottom:5px;'>
  1997. <i>" . t("This course's hours were split in a substitution.");
  1998. if ($course->get_bool_substitution_new_from_split()) {
  1999. $sub_remaining_hours = @$course->get_hours_awarded($req_by_degree_id);
  2000. $html .= "<br>" . t("Remaining hours after split:") . " $sub_remaining_hours " . t("hrs.") . "";
  2001. }
  2002. $html .= "</i>
  2003. <a href='javascript: alertSplitSub();'>?</a>
  2004. </div>";
  2005. $render["substitution_split"] = array(
  2006. "type" => "markup",
  2007. "value" => $html,
  2008. "weight" => 20,
  2009. );
  2010. }
  2011. if ($course->course_id != 0)
  2012. {
  2013. $render["course_description"] = array(
  2014. "type" => "markup",
  2015. "value" => $course->description,
  2016. "attributes" => array("class" => " "),
  2017. "weight" => 30,
  2018. );
  2019. }
  2020. // The -1 for get_bool_substitution means, is it being used in ANY substitution?
  2021. if ($course->bool_transfer == true && $course->course_id < 1 && $course->get_bool_substitution(-1) == FALSE)
  2022. { // No local eqv!
  2023. $html = "";
  2024. $html .= "<div class=' ' style='margin-top: 10px;'><b>Note:</b> ";
  2025. $pC = str_replace("<!--EQV1-->"," (" . t("Transfer Credit") . ")",$pC); // place the words "transfer credit" in the curved title line at the top.
  2026. if (!$bool_transferEqv)
  2027. {
  2028. $t_msg = t("This course does not have an assigned @initials equivalency, or the equivalency
  2029. has been removed for this student.
  2030. Ask your advisor if this course will count towards your degree.", array("@initials" => $initials)) . "
  2031. </div>";
  2032. }
  2033. else {
  2034. $t_msg = t("FlightPath cannot assign this course to a @initials equivalency on
  2035. the student's degree plan,
  2036. or the equivalency
  2037. has been removed for this student.
  2038. Ask your advisor if this course will count towards your degree.", array("@initials" => $initials)) . "
  2039. </div>";
  2040. }
  2041. $html .= $t_msg;
  2042. $render["course_transfer_no_eqv"] = array(
  2043. "type" => "markup",
  2044. "value" => $html,
  2045. "weight" => 40,
  2046. );
  2047. }
  2048. elseif ($course->bool_transfer == true && $course->course_id > 0 && $course->get_bool_substitution(-1) == FALSE)
  2049. { // Has a local eqv!
  2050. $html = "";
  2051. $t_s_i = $course->course_transfer->subject_id;
  2052. $t_c_n = $course->course_transfer->course_num;
  2053. /* $pC .= "<div class=' ' style='margin-top: 10px;'>
  2054. <b>Note:</b> The course listed above is equivalent
  2055. to <b>$t_s_i $t_c_n</b>,
  2056. which the student completed at <i>";
  2057. // Replace the temporary comment <!--EQV1--> in the header with
  2058. // the new eqv information.
  2059. */
  2060. $pC = str_replace("<!--EQV1-->"," (" . t("Transfer Credit") . " $t_s_i $t_c_n)",$pC);
  2061. // Admin function only.
  2062. if (user_has_permission("can_substitute"))
  2063. {
  2064. $html .= "<div align='left' class=' '>
  2065. <b>" . t("Special administrative function:") . "</b>
  2066. <a href='javascript: popupUnassignTransferEqv(\"" . $course->course_transfer->course_id . "\");'>" . t("Remove this equivalency?") . "</a></div>";
  2067. //$html .= "</div>"; // not sure what this went to. Commenting out.
  2068. }
  2069. //$pC .= "</div>"; // not sure what this went to... commenting out.
  2070. $render["course_transfer_local_eqv"] = array(
  2071. "type" => "markup",
  2072. "value" => $html,
  2073. "weight" => 50,
  2074. );
  2075. }
  2076. ////////////////////////////
  2077. // When was this student enrolled in this course?
  2078. $html = "";
  2079. if ($course->term_id != "" && $course->term_id != Course::COURSE_UNKNOWN_TERM_ID && $course->display_status != "eligible" && $course->display_status != "disabled")
  2080. {
  2081. $html .= "<div class=' ' style='margin-top: 10px;'>
  2082. " . t("The student enrolled in this course in") . " " . $course->get_term_description() . ".
  2083. </div>";
  2084. } else if ($course->term_id == Course::COURSE_UNKNOWN_TERM_ID)
  2085. {
  2086. $html .= "<div class=' ' style='margin-top: 10px;'>
  2087. " . t("The exact date that the student enrolled in this course
  2088. cannot be retrieved at this time. Please check the
  2089. student's official transcript for more details.") . "
  2090. </div>";
  2091. }
  2092. $render["when_enrolled"] = array(
  2093. "type" => "markup",
  2094. "value" => $html,
  2095. "weight" => 50,
  2096. );
  2097. ///////////////////////////////////
  2098. // Did the student earn a grade?
  2099. $html = "";
  2100. if ($course->grade != "") {
  2101. $grd = $course->grade;
  2102. $enrolled_grades = csv_to_array(variable_get_for_school("enrolled_grades",'E', $school_id));
  2103. if (in_array($grd, $enrolled_grades)) {
  2104. $html .= t("The student is currently enrolled in this course.", array("@grade" => $grd));
  2105. $render['enrolled_notice'] = array(
  2106. 'type' => 'markup',
  2107. 'value' => $html,
  2108. 'weight' => 54,
  2109. );
  2110. }
  2111. else {
  2112. if (trim($grd) != trim($course->db_grade)) {
  2113. $grd = "$course->db_grade ($grd)";
  2114. }
  2115. $disp_grade = $grd;
  2116. if (strstr($grd, "MID")) {
  2117. $disp_grade = str_replace("MID", "<span class='superscript'>mid</span>", $grd);
  2118. }
  2119. $html .= t("The student earned a grade of <strong>@grade</strong>.", array("@grade" => $disp_grade));
  2120. $render['earned_grade'] = array(
  2121. 'type' => 'markup',
  2122. 'value' => $html,
  2123. 'weight' => 55,
  2124. );
  2125. }
  2126. }
  2127. ////////////////////////////////
  2128. // Conditions on which this will even appear? Like only if the student has more than one degree selected?
  2129. // What degrees is this course fulfilling?
  2130. if (count($course->assigned_to_degree_ids_array) > 0) {
  2131. $html = "";
  2132. $html .= "<div class=' course-description-assigned-to-degrees'>
  2133. " . t("This course is fulfilling a requirement for: ");
  2134. $c = "";
  2135. $d = "";
  2136. foreach ($course->assigned_to_degree_ids_array as $degree_id) {
  2137. $d .= $degree_id . ",";
  2138. $t_degree_plan = new DegreePlan();
  2139. $t_degree_plan->degree_id = $degree_id;
  2140. $c .= "<span>" . $t_degree_plan->get_title2(FALSE, TRUE) . "</span>, ";
  2141. }
  2142. $c = rtrim($c, ", ");
  2143. $html .= "$c</div>";
  2144. $render["fulfilling_reqs_for_degrees"] = array(
  2145. "type" => "markup",
  2146. "value" => $html,
  2147. "weight" => 60,
  2148. );
  2149. // Also keep track of what degree ids we are fulfilling reqs for, in case we need it later.
  2150. $render["#fulfilling_reqs_for_degree_ids"] = array(
  2151. "type" => "do_not_render",
  2152. "value" => $d,
  2153. );
  2154. }
  2155. ////////////////
  2156. // Is this course assigned to a group?
  2157. if ($course->disp_for_group_id != "" && $course->grade != "" && $course->bool_transfer != true && $course->get_bool_substitution($course->req_by_degree_id) != TRUE)
  2158. {
  2159. $html = "";
  2160. $g = new Group();
  2161. $g->group_id = $course->disp_for_group_id;
  2162. $g->load_descriptive_data();
  2163. $html .= "<div class=' ' style='margin-top: 10px;'>
  2164. <img src='" . fp_theme_location() . "/images/icons/$g->icon_filename' class='advising-course-row-icon advising-course-row-icon-in-group'>
  2165. &nbsp;
  2166. " . t("This course is a member of") . " $g->title.
  2167. ";
  2168. // If user is an admin...
  2169. if (user_has_permission("can_substitute")) {
  2170. $tflag = intval($course->bool_transfer);
  2171. $html .= "<div align='left' class=' '>
  2172. <b>" . t("Special administrative function:") . "</b>
  2173. <a href='javascript: popupUnassignFromGroup(\"$course->course_id\",\"$course->term_id\",\"$tflag\",\"$g->group_id\",\"$req_by_degree_id\");'>" . t("Remove from this group?") . "</a></div>";
  2174. $html .= "</div>";
  2175. }
  2176. $render["course_assigned_to_group"] = array(
  2177. "type" => "markup",
  2178. "value" => $html,
  2179. "weight" => 70,
  2180. );
  2181. $render["#group"] = $g;
  2182. }
  2183. else if ($course->grade != "" && $course->bool_transfer != true && $course->get_bool_substitution($course->req_by_degree_id) != TRUE && $course->get_has_been_assigned_to_degree_id()) {
  2184. // Course is not assigned to a group; it's on the bare degree plan. group_id = 0.
  2185. // If user is an admin...
  2186. $html = "";
  2187. if (user_has_permission("can_substitute"))
  2188. {
  2189. $tflag = intval($course->bool_transfer);
  2190. $html .= "<div align='left' class=' '>
  2191. <b>" . t("Special administrative function:") . "</b>
  2192. <a href='javascript: popupUnassignFromGroup(\"$course->course_id\",\"$course->term_id\",\"$tflag\",\"0\",\"$req_by_degree_id\");'>" . t("Unassign fulfillment?") . "</a></div>";
  2193. $html .= "</div>";
  2194. }
  2195. $render["course_not_assigned_to_group"] = array(
  2196. "type" => "markup",
  2197. "value" => $html,
  2198. "weight" => 80,
  2199. );
  2200. }
  2201. // Substitutors get extra information:
  2202. if (user_has_permission("can_substitute") && $course->get_first_assigned_to_group_id()) {
  2203. $html = "";
  2204. $html .= "
  2205. <span id='viewinfolink'
  2206. onClick='document.getElementById(\"admin_info\").style.display=\"\"; this.style.display=\"none\"; '
  2207. class='hand' style='color: blue;'
  2208. > - " . t("Click to show") . " -</span>
  2209. <div style='padding-left: 20px; display:none;' id='admin_info'>
  2210. Groups this course has been assigned to:
  2211. ";
  2212. // Course is assigned to a group.
  2213. // might be assigned to multiple groups, so show them in a loop
  2214. if ($course->get_first_assigned_to_group_id()) {
  2215. foreach ($course->assigned_to_group_ids_array as $group_id) {
  2216. $group = new Group();
  2217. $group->group_id = $group_id;
  2218. $group->load_descriptive_data();
  2219. $html .= "<div>
  2220. " . t("Course is assigned to group:") . "<br>
  2221. &nbsp; " . t("Group ID:") . " $group->group_id<br>
  2222. &nbsp; " . t("Title:") . " $group->title<br>";
  2223. $html .= "&nbsp; <i>" . t("Internal name:") . " $group->group_name</i><br>";
  2224. $html .= "&nbsp; " . t("Catalog year:") . " $group->catalog_year
  2225. </div>";
  2226. }
  2227. }
  2228. $html .= "
  2229. </div>";
  2230. $render["substitutor_extra"] = array(
  2231. "type" => "markup",
  2232. "label" => ("Special administrative information:"),
  2233. "value" => $html,
  2234. "weight" => 90,
  2235. "attributes" => array("class" => " "),
  2236. );
  2237. }
  2238. // Has the course been substituted into *this* degree plan?
  2239. if ($course->get_bool_substitution() == TRUE)
  2240. {
  2241. $html = "";
  2242. // Find out who did it and if they left any remarks.
  2243. $db = $this->db;
  2244. $sub_id = $course->db_substitution_id_array[$course->get_course_substitution()->req_by_degree_id];
  2245. $temp = $db->get_substitution_details($sub_id);
  2246. $required_degree_id = $temp["required_degree_id"];
  2247. $req_degree_plan = new DegreePlan();
  2248. $req_degree_plan->degree_id = $required_degree_id;
  2249. $by = $db->get_faculty_name($temp["faculty_id"], false);
  2250. $remarks = $temp["remarks"];
  2251. $ondate = format_date($temp["posted"], "", "n/d/Y");
  2252. if ($by != "") {
  2253. $by = " by $by, on $ondate.";
  2254. }
  2255. if ($remarks != "")
  2256. {
  2257. $remarks = " " . t("Substitution remarks:") . " <i>$remarks</i>.";
  2258. }
  2259. $forthecourse = t("for the original course
  2260. requirement of") . " <b>" . $course->get_course_substitution()->subject_id . "
  2261. " . $course->get_course_substitution()->course_num . " (" . $course->get_course_substitution()->get_hours() . " " . t("hrs") . ")</b>";
  2262. if ($temp["required_course_id"]*1 == 0)
  2263. {
  2264. $forthecourse = "";
  2265. }
  2266. $html .= "<div class=' ' style='margin-top: 10px;'>
  2267. <b>" . t("Note:") . "</b> " . t("This course was substituted into the %title
  2268. degree plan", array("%title" => $req_degree_plan->get_title2())) . " $forthecourse
  2269. $by$remarks";
  2270. if (user_has_permission("can_substitute")) {
  2271. $html .= "<div align='left' class=' ' style='padding-left: 10px;'>
  2272. <b>" . t("Special administrative function:") . "</b>
  2273. <a href='javascript: popupRemoveSubstitution(\"$sub_id\");'>" . t("Remove substitution?") . "</a>
  2274. </div>";
  2275. }
  2276. $render["course_sub_this_degree_plan"] = array(
  2277. "type" => "markup",
  2278. "value" => $html,
  2279. "weight" => 100,
  2280. );
  2281. }
  2282. // Variable hours? Only show if the course has not been taken...
  2283. $var_hours_default = "";
  2284. if ($course->has_variable_hours() && $course->grade == "")
  2285. {
  2286. $html = "";
  2287. $html .= "<div class=' '>
  2288. " . t("This course has variable hours. Please select
  2289. how many hours this course will be worth:") . "<br>
  2290. <div style='text-align: center;'>
  2291. <select name='selHours' id='selHours' onChange='popupSetVarHours();'>
  2292. ";
  2293. // Correct for ghost hours, if they are there.
  2294. $min_h = $course->min_hours*1;
  2295. $max_h = $course->max_hours*1;
  2296. if ($course->bool_ghost_min_hour) $min_h = 0;
  2297. if ($course->bool_ghost_hour) $max_h = 0;
  2298. for($t = $min_h; $t <= $max_h; $t++)
  2299. {
  2300. $sel = "";
  2301. if ($t == $course->advised_hours){ $sel = "SELECTED"; }
  2302. $html .= "<option value='$t' $sel>$t</option>";
  2303. }
  2304. $html .= "</select> " . t("hours.") . "<br>
  2305. </div>
  2306. </div>";
  2307. if ($course->advised_hours > -1)
  2308. {
  2309. $var_hours_default = $course->advised_hours *1;
  2310. } else {
  2311. $var_hours_default = $min_h;
  2312. }
  2313. $render["course_var_hour_select"] = array(
  2314. "value" => $html,
  2315. "weight" => 110,
  2316. );
  2317. }
  2318. // Some hidden vars and other details
  2319. $html = "";
  2320. if ($show_advising_buttons == true && !$this->bool_blank) {
  2321. // Insert a hidden radio button so the javascript works okay...
  2322. $html .= "<input type='radio' name='course' value='$course->course_id' checked='checked'
  2323. style='display: none;'>
  2324. <input type='hidden' name='varHours' id='varHours' value='$var_hours_default'>";
  2325. $render['#group_assigned_to_semester_num'] = $group->assigned_to_semester_num;
  2326. $render['#group_id'] = $group->group_id;
  2327. $render['#advising_term_id'] = $advising_term_id;
  2328. $render['#db_group_requirement_id'] = $db_group_requirement_id;
  2329. $render['#req_by_degree_id'] = $req_by_degree_id;
  2330. $group_js_select = "popupAssignSelectedCourseToGroup(\"$group->assigned_to_semester_num\", \"$group->group_id\",\"$advising_term_id\",\"$db_group_requirement_id\",\"$req_by_degree_id\");";
  2331. $render['#group_js_select'] = $group_js_select;
  2332. if (user_has_permission("can_advise_students"))
  2333. {
  2334. $html .= fp_render_button(t("Select Course"), $group_js_select, TRUE, "style='font-size: 10pt;'");
  2335. }
  2336. }
  2337. else if ($show_advising_buttons == false && $course->has_variable_hours() == true && $course->grade == "" && user_has_permission("can_advise_students") && !$this->bool_blank) {
  2338. // Show an "update" button, and use the course's assigned_to_group_id and
  2339. // assigned_to_semester_num.
  2340. $html .= "<input type='hidden' name='varHours' id='varHours' value='$var_hours_default'> \n";
  2341. // Same situation about the group_id. I guess need to find out exactly which group it was assigned to?
  2342. $html .= fp_render_button(t("Update"), "popupUpdateSelectedCourse(\"$course->course_id\",\"" . $course->get_first_assigned_to_group_id() . "\",\"$course->assigned_to_semester_num\",\"$course->random_id\",\"$advising_term_id\",\"$req_by_degree_id\");");
  2343. }
  2344. $render["hidden_vars_and_buttons"] = array(
  2345. "value" => $html,
  2346. "weight" => 1000,
  2347. );
  2348. watchdog("advise", "popup_course_description $course->course_id. <pre>" . print_r($course, TRUE) . "</pre>", array(), WATCHDOG_DEBUG);
  2349. // Okay, render our render array and return.
  2350. $pC .= fp_render_content($render);
  2351. return $pC;
  2352. } // end function
  2353. /**
  2354. * Simple function to make an institution name look more pretty, because
  2355. * all institution names pass through ucwords(), sometimes the capitalization
  2356. * gets messed up. This function tries to correct it.
  2357. *
  2358. * Feel free to override it and add to it, if needed.
  2359. *
  2360. * @param string $str
  2361. * @return string
  2362. */
  2363. function fix_institution_name($str)
  2364. {
  2365. $student_id = $this->student->student_id;
  2366. $school_id = db_get_school_id_for_student_id($student_id);
  2367. // Should we do this at all? We will look at the "autocapitalize_institution_names" setting.
  2368. $auto = variable_get_for_school("autocapitalize_institution_names", 'yes', $school_id);
  2369. if ($auto == "no") {
  2370. // Nope! Just return.
  2371. return $str;
  2372. }
  2373. $str = str_replace("-", " - ", $str);
  2374. $str = ucwords(strtolower($str));
  2375. $str = str_replace(" Of ", " of ", $str);
  2376. $str = str_replace("clep", "CLEP", $str);
  2377. $str = str_replace("_clep", "CLEP", $str);
  2378. $str = str_replace("_act", "ACT", $str);
  2379. $str = str_replace("_sat", "SAT", $str);
  2380. $str = str_replace("Ap ", "AP ", $str);
  2381. $str = str_replace("_dsst", "DSST", $str);
  2382. // Fix school initials.
  2383. // Turns "Ulm" into "ULM"
  2384. $school_initials = variable_get_for_school("school_initials", "DEMO", $school_id);
  2385. $str = str_replace(ucwords(strtolower($school_initials)), $school_initials, $str);
  2386. if ($str == "")
  2387. {
  2388. $str = "<i>unknown institution</i>";
  2389. }
  2390. return $str;
  2391. }
  2392. /**
  2393. * Left in for legacy reasons, this function uses a new Course object's
  2394. * method of $course->fix_title to make a course's title more readable.
  2395. *
  2396. * @param string $str
  2397. * @return stromg
  2398. */
  2399. function fix_course_title($str)
  2400. {
  2401. $new_course = new Course();
  2402. $str = $new_course->fix_title($str);
  2403. return $str;
  2404. }
  2405. /**
  2406. * Given a Semester object, this will generate the HTML to draw it out
  2407. * to the screen. We will take advantage of the render engine, so we
  2408. * can utilize hook_content_alter later on.
  2409. *
  2410. * @param Semester $semester
  2411. * @param bool $bool_display_hour_count
  2412. * - If set to TRUE, it will display a small "hour count" message
  2413. * at the bottom of each semester, showing how many hours are in
  2414. * the semester. Good for debugging purposes.
  2415. *
  2416. * @return string
  2417. */
  2418. function display_semester(Semester $semester, $bool_display_hour_count = false)
  2419. {
  2420. // Display the contents of a semester object
  2421. // on the screen (in HTML)
  2422. $render = array();
  2423. $render['#id'] = 'AdvisingScreen_display_semester';
  2424. $render['#semester'] = $semester;
  2425. $render['#degree_plan'] = $this->degree_plan;
  2426. $render['#bool_display_hour_count'] = $bool_display_hour_count;
  2427. $render_weight = 0;
  2428. $render['semester_box_top'] = array(
  2429. 'value' => $this->draw_semester_box_top($semester->title),
  2430. 'weight' => $render_weight,
  2431. );
  2432. $count_hoursCompleted = 0;
  2433. $html = array();
  2434. // Create a temporary caching system for degree titles, so we don't have to keep looking them back up.
  2435. if (!isset($GLOBALS["fp_temp_degree_titles"])) {
  2436. $GLOBALS["fp_temp_degree_titles"] = array();
  2437. $GLOBALS["fp_temp_degree_types"] = array();
  2438. $GLOBALS["fp_temp_degree_classes"] = array();
  2439. $GLOBALS["fp_temp_degree_levels"] = array();
  2440. }
  2441. $degree_sort_policy = variable_get_for_school("degree_requirement_sort_policy", "alpha", $this->student->school_id);
  2442. // First, display the list of bare courses.
  2443. if ($degree_sort_policy == 'database') {
  2444. $semester->list_courses->sort_degree_requirement_id();
  2445. }
  2446. else {
  2447. // By default, sort alphabetical
  2448. $semester->list_courses->sort_alphabetical_order(); // sort, including the degree title we're sorting for.
  2449. }
  2450. $semester->list_courses->reset_counter();
  2451. while($semester->list_courses->has_more())
  2452. {
  2453. $course = $semester->list_courses->get_next();
  2454. if (!isset($html[$course->req_by_degree_id])) {
  2455. $html[$course->req_by_degree_id] = "";
  2456. }
  2457. // Is this course being fulfilled by anything?
  2458. if (!($course->course_list_fulfilled_by->is_empty))
  2459. { // this requirement is being fulfilled by something the student took...
  2460. $c = $course->course_list_fulfilled_by->get_first();
  2461. $c->req_by_degree_id = $course->req_by_degree_id; // make sure we assign it to the current degree_id.
  2462. // Tell the course what group we are coming from. (in this case: none)
  2463. $c->disp_for_group_id = "";
  2464. $html[$course->req_by_degree_id] .= $this->draw_course_row($c);
  2465. $c->set_has_been_displayed($course->req_by_degree_id);
  2466. if ($c->display_status == "completed")
  2467. { // We only want to count completed hours, no midterm or enrolled courses.
  2468. $h = $c->get_hours_awarded();
  2469. if ($c->bool_ghost_hour == TRUE) {
  2470. $h = 0;
  2471. }
  2472. $count_hoursCompleted += $h;
  2473. }
  2474. } else {
  2475. // This requirement is not being fulfilled...
  2476. // Tell the course what group we are coming from. (in this case: none)
  2477. $course->disp_for_group_id = "";
  2478. $x = $this->draw_course_row($course);
  2479. //fpm(htmlentities($x));
  2480. $html[$course->req_by_degree_id] .= $x;
  2481. }
  2482. }
  2483. /////////////////////////////////////
  2484. // Now, draw all the groups.
  2485. $semester->list_groups->sort_alphabetical_order();
  2486. $semester->list_groups->reset_counter();
  2487. while($semester->list_groups->has_more())
  2488. {
  2489. $group = $semester->list_groups->get_next();
  2490. if (!isset($html[$group->req_by_degree_id])) {
  2491. $html[$group->req_by_degree_id] = "";
  2492. }
  2493. //$html[$group->req_by_degree_id] .= "<tr class='semester-display-group-tr'><td colspan='8'>";
  2494. $x = $this->display_group($group);
  2495. //fpm(htmlentities($x, TRUE));
  2496. $html[$group->req_by_degree_id] .= $x;
  2497. $count_hoursCompleted += $group->hours_fulfilled_for_credit;
  2498. //$html[$group->req_by_degree_id] .= "</td></tr>";
  2499. } //while groups.
  2500. // Sort by degree's advising weight
  2501. $new_html = array();
  2502. foreach($html as $req_by_degree_id => $content) {
  2503. $dtitle = @$GLOBALS["fp_temp_degree_titles"][$req_by_degree_id];
  2504. $dweight = intval(@$GLOBALS["fp_temp_degree_advising_weights"][$req_by_degree_id]);
  2505. if ($dtitle == "") {
  2506. $t_degree_plan = new DegreePlan();
  2507. $t_degree_plan->degree_id = $req_by_degree_id;
  2508. //$t_degree_plan->load_descriptive_data();
  2509. $dtitle = $t_degree_plan->get_title2(TRUE, TRUE);
  2510. $dweight = $t_degree_plan->db_advising_weight;
  2511. $dtype = $t_degree_plan->degree_type;
  2512. $dclass = $t_degree_plan->degree_class;
  2513. $dlevel = $t_degree_plan->degree_level;
  2514. $GLOBALS["fp_temp_degree_titles"][$req_by_degree_id] = $dtitle . " "; //save for next time.
  2515. $GLOBALS["fp_temp_degree_types"][$req_by_degree_id] = $dtype; //save for next time.
  2516. $GLOBALS["fp_temp_degree_classes"][$req_by_degree_id] = $dclass; //save for next time.
  2517. $GLOBALS["fp_temp_degree_levels"][$req_by_degree_id] = $dlevel; //save for next time.
  2518. $GLOBALS["fp_temp_degree_advising_weights"][$req_by_degree_id] = $dweight . " "; //save for next time.
  2519. }
  2520. $degree_title = fp_get_machine_readable($dtitle); // make it machine readable. No funny characters.
  2521. $degree_advising_weight = str_pad($dweight, 4, "0", STR_PAD_LEFT);
  2522. $new_html[$degree_advising_weight . "__" . $degree_title][$req_by_degree_id] = $content;
  2523. }
  2524. // Sort by the first index, the advising weight.
  2525. ksort($new_html);
  2526. $pC = "";
  2527. //////////////////////////
  2528. // Okay, now let's go through our HTML array and add to the screen....
  2529. foreach ($new_html as $w => $html) {
  2530. foreach($html as $req_by_degree_id => $content) {
  2531. // Get the degree title...
  2532. $dtitle = @$GLOBALS["fp_temp_degree_titles"][$req_by_degree_id];
  2533. $dtype = @$GLOBALS["fp_temp_degree_types"][$req_by_degree_id];
  2534. $dclass = @$GLOBALS["fp_temp_degree_classes"][$req_by_degree_id];
  2535. $dlevel = @$GLOBALS["fp_temp_degree_levels"][$req_by_degree_id];
  2536. if ($dtitle == "") {
  2537. $t_degree_plan = new DegreePlan();
  2538. $t_degree_plan->degree_id = $req_by_degree_id;
  2539. //$t_degree_plan->load_descriptive_data();
  2540. $dtitle = $t_degree_plan->get_title2(TRUE, TRUE);
  2541. $dtype = $t_degree_plan->degree_type;
  2542. $dclass = $t_degree_plan->degree_class;
  2543. $dlevel = $t_degree_plan->degree_level;
  2544. $GLOBALS["fp_temp_degree_titles"][$req_by_degree_id] = $dtitle; //save for next time.
  2545. $GLOBALS["fp_temp_degree_types"][$req_by_degree_id] = $dtype; //save for next time.
  2546. $GLOBALS["fp_temp_degree_classes"][$req_by_degree_id] = $dclass; //save for next time.
  2547. $GLOBALS["fp_temp_degree_levels"][$req_by_degree_id] = $dlevel; //save for next time.
  2548. }
  2549. $css_dtitle = fp_get_machine_readable($dtitle);
  2550. $theme = array(
  2551. 'classes' => array(' ', 'required-by-degree',
  2552. "required-by-degree-$css_dtitle",
  2553. "required-by-degree-type-" . fp_get_machine_readable($dtype),
  2554. "required-by-degree-class-" . fp_get_machine_readable($dclass),
  2555. "required-by-degree-level-" . fp_get_machine_readable($dlevel)),
  2556. 'css_dtitle' => $css_dtitle,
  2557. 'degree_id' => $req_by_degree_id,
  2558. 'required_by_html' => "<span class='req-by-label'>" . t("Required by") . "</span> <span class='req-by-degree-title'>$dtitle</span>",
  2559. 'view_by' => 'year',
  2560. );
  2561. // Don't display if we are in the Courses Added semester, or if we are NOT a "combined" degree.
  2562. if ($semester->semester_num == DegreePlan::SEMESTER_NUM_FOR_COURSES_ADDED || (is_object($this->degree_plan)) && !$this->degree_plan->is_combined_dynamic_degree_plan) {
  2563. $theme['required_by_html'] = '';
  2564. }
  2565. invoke_hook("theme_advise_degree_header_row", array(&$theme));
  2566. if ($theme['required_by_html']) {
  2567. $pC .= "<tr><td colspan='8' class='required-by-td'>
  2568. <div class='" . implode(' ',$theme['classes']) ."'>{$theme['required_by_html']}</div>
  2569. </td></tr>";
  2570. }
  2571. $pC .= $content;
  2572. }
  2573. }
  2574. $render_weight = $render_weight + 10;
  2575. $render['semester_content'] = array(
  2576. 'value' => $pC,
  2577. 'weight' => $render_weight,
  2578. );
  2579. // Add hour count to the bottom...
  2580. if ($bool_display_hour_count == true && $count_hoursCompleted > 0)
  2581. {
  2582. $p = "<tr><td colspan='8'>
  2583. <div class='advise-completed-hours' style='text-align:right; margin-top: 10px;'>
  2584. <span class='completed-hours-label'>" . t("Completed hours:") . "</span> <span class='count-hours-completed'>$count_hoursCompleted</span>
  2585. </div>
  2586. </td></tr>";
  2587. $render_weight = $render_weight + 10;
  2588. $render['semester_disp_hour_count'] = array(
  2589. 'value' => $p,
  2590. 'weight' => $render_weight,
  2591. );
  2592. }
  2593. // Does the semester have a notice?
  2594. if ($semester->notice != "")
  2595. {
  2596. $p = "<tr><td colspan='8'>
  2597. <div class='hypo advise-semester-notice' style='margin-top: 15px; padding: 5px;'>
  2598. <b>" . t("Important Notice:") . "</b> $semester->notice
  2599. </div>
  2600. </td></tr>";
  2601. $render_weight = $render_weight + 10;
  2602. $render['semester_notice'] = array(
  2603. 'value' => $p,
  2604. 'weight' => $render_weight,
  2605. );
  2606. }
  2607. //$pC .= $this->draw_semester_box_bottom();
  2608. $render_weight = $render_weight + 10;
  2609. $render['semester_box_bottom'] = array(
  2610. 'value' => $this->draw_semester_box_bottom(),
  2611. 'weight' => $render_weight,
  2612. );
  2613. // If the semester has NO content, then just return FALSE.
  2614. if (trim($render['semester_content']['value']) == "" && !isset($render['semester_notice']) && !isset($render['semester_disp_hour_count'])) {
  2615. return FALSE;
  2616. }
  2617. // Otherwise, render out and return the HTML
  2618. return fp_render_content($render);
  2619. }
  2620. /**
  2621. * This function displays a Group object on the degree plan. This is not
  2622. * the selection popup display. It will either show the group as multi
  2623. * rows, filled in with courses, or as a "blank row" for the user to click
  2624. * on.
  2625. *
  2626. * @param Group $place_group
  2627. * @return string
  2628. */
  2629. function display_group(Group $place_group)
  2630. {
  2631. // Display a group, either filled in with courses,
  2632. // and/or with a "blank row" for the user to
  2633. // click on.
  2634. $rtn = "";
  2635. // Now, if you will recall, all of the groups and their courses, etc,
  2636. // are in the degree_plan's list_groups. The $place_group object here
  2637. // is just a placeholder. So, get the real group...
  2638. if (!$group = $this->degree_plan->find_group($place_group->group_id))
  2639. {
  2640. fpm("Group not found.");
  2641. return;
  2642. }
  2643. $title = $group->title;
  2644. $display_course_list = new CourseList();
  2645. // Okay, first look for courses in the first level
  2646. // of the group.
  2647. $display_semesterNum = $place_group->assigned_to_semester_num;
  2648. $req_by_degree_id = $group->req_by_degree_id;
  2649. // Make sure all courses and subgroups have the same req_by_degree_id set.
  2650. $group->set_req_by_degree_id($group->req_by_degree_id);
  2651. // What we are trying to do is end up with a list of courses we want to display on the screen (for example,
  2652. // that the student took or were substituted in)
  2653. $group->list_courses->remove_unfulfilled_and_unadvised_courses();
  2654. $group->list_courses->reset_counter();
  2655. while($group->list_courses->has_more())
  2656. {
  2657. $course = $group->list_courses->get_next();
  2658. // Do we have enough hours to keep going?
  2659. $fulfilled_hours = $display_course_list->count_hours("", FALSE, TRUE, FALSE, FALSE, $req_by_degree_id);
  2660. $remaining = $place_group->hours_required - $fulfilled_hours;
  2661. // If the course in question is part of a substitution that is not
  2662. // for this group, then we should skip it.
  2663. if (!($course->course_list_fulfilled_by->is_empty))
  2664. {
  2665. $try_c = $course->course_list_fulfilled_by->get_first();
  2666. if ($try_c->get_bool_substitution($req_by_degree_id) == TRUE && $try_c->get_bool_assigned_to_group_id($group->group_id) != TRUE)
  2667. {
  2668. continue;
  2669. }
  2670. }
  2671. if (!($course->course_list_fulfilled_by->is_empty) && $course->course_list_fulfilled_by->get_first()->get_has_been_displayed($req_by_degree_id) != TRUE && $course->get_has_been_displayed($req_by_degree_id) != TRUE)
  2672. {
  2673. $c = $course->course_list_fulfilled_by->get_first();
  2674. $ch = $c->get_hours($req_by_degree_id);
  2675. // Because PHP has dumb floating point arithmatic, we are going to round our values to 8 places,
  2676. // otherwise I was getting weird results like 0.34 < 0.34 == true. I chose 8 places to make sure it wouldn't
  2677. // actually cause the values to round and mess up the math.
  2678. $remaining = round($remaining, 8);
  2679. $ch = round($ch, 8);
  2680. // Is whats remaining actually LESS than the course hours? If so, we need to skip it.
  2681. if ($remaining < $ch)
  2682. {
  2683. continue;
  2684. }
  2685. $c->temp_flag = false;
  2686. $c->icon_filename = $group->icon_filename;
  2687. $c->title_text = "This course is a member of $group->title." . " ($place_group->requirement_type)";
  2688. $c->requirement_type = $place_group->requirement_type;
  2689. $c->req_by_degree_id = $req_by_degree_id;
  2690. $display_course_list->add($c);
  2691. }
  2692. if ($course->bool_advised_to_take && $course->get_has_been_displayed($req_by_degree_id) != true && $course->assigned_to_semester_num == $display_semesterNum)
  2693. {
  2694. $c = $course;
  2695. if ($remaining < $c->get_hours($req_by_degree_id))
  2696. {
  2697. continue;
  2698. }
  2699. $c->temp_flag = true;
  2700. $c->icon_filename = $group->icon_filename;
  2701. $c->req_by_degree_id = $req_by_degree_id;
  2702. $c->title_text = t("The student has been advised to take this course to fulfill a @gt requirement.", array("@gt" => $group->title));
  2703. $display_course_list->add($c);
  2704. }
  2705. }
  2706. $group->list_groups->reset_counter();
  2707. while($group->list_groups->has_more())
  2708. {
  2709. $branch = $group->list_groups->get_next();
  2710. // look for courses at this level...
  2711. if (!$branch->list_courses->is_empty)
  2712. {
  2713. $branch->list_courses->sort_alphabetical_order();
  2714. $branch->list_courses->reset_counter();
  2715. while($branch->list_courses->has_more())
  2716. {
  2717. $course = $branch->list_courses->get_next();
  2718. // Do we have enough hours to keep going?
  2719. $fulfilled_hours = $display_course_list->count_hours("", FALSE, TRUE, FALSE, FALSE, $req_by_degree_id);
  2720. $remaining = $place_group->hours_required - $fulfilled_hours;
  2721. if (!($course->course_list_fulfilled_by->is_empty) && $course->course_list_fulfilled_by->get_first()->get_has_been_displayed($req_by_degree_id) != true && $course->get_has_been_displayed($req_by_degree_id) != true)
  2722. {
  2723. $c = $course->course_list_fulfilled_by->get_first();
  2724. if ($remaining < $c->get_hours() || $remaining == 0)
  2725. {
  2726. continue;
  2727. }
  2728. $c->temp_flag = false;
  2729. $c->icon_filename = $group->icon_filename;
  2730. $c->title_text = "This course is a member of $group->title." . "($place_group->requirement_type)";
  2731. $c->requirement_type = $place_group->requirement_type;
  2732. $c->req_by_degree_id = $req_by_degree_id;
  2733. // TODO: This right here is how we show specified-repeats in groups with branches.
  2734. // TODO: Originally we were making sure there wasn't a "match" already in the display_course_list, which was
  2735. // of course excluding any of our specified repeats.
  2736. //if (!$display_course_list->find_match($c))
  2737. $found_match = $display_course_list->find_match($c);
  2738. if (!$found_match || ($found_match && $c->bool_specified_repeat == TRUE)) {
  2739. $display_course_list->add($c);
  2740. }
  2741. else if (is_object($c->course_transfer)) {
  2742. if (!$display_course_list->find_match($c->course_transfer))
  2743. { // Make sure it isn't already in the display list.
  2744. $display_course_list->add($c);
  2745. }
  2746. }
  2747. }
  2748. if ($course->bool_advised_to_take && $course->get_has_been_displayed($req_by_degree_id) != true && $course->assigned_to_semester_num == $display_semesterNum)
  2749. {
  2750. $c = $course;
  2751. if ($remaining < $c->get_hours($req_by_degree_id) || $remaining == 0)
  2752. {
  2753. continue;
  2754. }
  2755. $c->temp_flag = true;
  2756. $c->icon_filename = $group->icon_filename;
  2757. $c->req_by_degree_id = $req_by_degree_id;
  2758. $c->title_text = "The student has been advised to take this course to fulfill a $group->title requirement.";
  2759. if (!$display_course_list->find_match($c))
  2760. {
  2761. $display_course_list->add($c);
  2762. }
  2763. }
  2764. }
  2765. }
  2766. }
  2767. $display_course_list->sort_advised_last_alphabetical();
  2768. // Make sure we're all on the same page, for what degree_id we're being displayed under.
  2769. $display_course_list->set_req_by_degree_id($req_by_degree_id);
  2770. $rtn .= $this->display_group_course_list($display_course_list, $group, $display_semesterNum);
  2771. // original: $fulfilled_hours = $display_course_list->count_hours("", false, false, TRUE, false, $req_by_degree_id);
  2772. // Changing to new line, to match other argument list for previous occurances of 'fulfilled_hours'. This makes it so that
  2773. // a zero-hour course does not "use up" a 1 hour spot in the course hour counts.
  2774. // TODO: This might cause a group of *only* zero hour courses to never count as being filled.
  2775. // TODO: Maybe this difference between the original and this line should be a setting? Or per-group?
  2776. $fulfilled_hours = $display_course_list->count_hours("", FALSE, TRUE, FALSE, FALSE, $req_by_degree_id);
  2777. $fulfilled_credit_hours = $display_course_list->count_credit_hours("",false,true);
  2778. $test_hours = $fulfilled_hours;
  2779. // if the fulfilledCreditHours is > than the fulfilledHours,
  2780. // then assign the fulfilledCreditHours to the testHours.
  2781. if ($fulfilled_credit_hours > $fulfilled_hours)
  2782. { // done to fix a bug involving splitting hours in a substitution.
  2783. $test_hours = $fulfilled_credit_hours;
  2784. }
  2785. // If there are any remaining hours in this group,
  2786. // draw a "blank" selection row.
  2787. $remaining = $place_group->hours_required - $test_hours;
  2788. $place_group->hours_remaining = $remaining;
  2789. $place_group->hours_fulfilled = $fulfilled_hours;
  2790. $place_group->hours_fulfilled_for_credit = $fulfilled_credit_hours;
  2791. if ($remaining > 0)
  2792. {
  2793. $rowclass = "";
  2794. // If we have met the min hours (if the group even HAS min hours) then add a class to $rowclass,
  2795. // so we can hide it or whatever with CSS.
  2796. if ($group->has_min_hours_allowed()) {
  2797. if ($test_hours >= $group->min_hours_allowed) {
  2798. $rowclass .= "group-select-min-hours-fulfilled";
  2799. }
  2800. }
  2801. $rtn .= $this->draw_group_select_row($place_group, $remaining, $rowclass);
  2802. }
  2803. return $rtn;
  2804. }
  2805. /**
  2806. * Find all instaces of a Course in a Group and mark as displayed.
  2807. *
  2808. * @param Group $group
  2809. * @param Course $course
  2810. */
  2811. function mark_course_as_displayed(Group $group, Course $course)
  2812. {
  2813. // Find all instances of $course in $group,
  2814. // and mark as displayed.
  2815. if ($obj_list = $group->list_courses->find_all_matches($course))
  2816. {
  2817. $course_list = CourseList::cast($obj_list);
  2818. $course_list->mark_as_displayed();
  2819. }
  2820. // Now, go through all the course lists within each branch...
  2821. $group->list_groups->reset_counter();
  2822. while($group->list_groups->has_more())
  2823. {
  2824. $g = $group->list_groups->get_next();
  2825. if ($obj_list = $g->list_courses->find_all_matches($course))
  2826. {
  2827. $course_list = CourseList::cast($obj_list);
  2828. $course_list->mark_as_displayed($semester_num);
  2829. }
  2830. }
  2831. }
  2832. /**
  2833. * Displays all the courses in a CourseList object, using
  2834. * the draw_course_row function.
  2835. *
  2836. * It looks like the group and semester_num are not being used
  2837. * anymore.
  2838. *
  2839. * @todo Check on unused variables.
  2840. *
  2841. * @param CourseList $course_list
  2842. * @param unknown_type $group
  2843. * @param unknown_type $semester_num
  2844. * @return unknown
  2845. */
  2846. function display_group_course_list($course_list, $group, $semester_num)
  2847. {
  2848. $pC = "";
  2849. $course_list->reset_counter();
  2850. while($course_list->has_more())
  2851. {
  2852. $course = $course_list->get_next();
  2853. // Tell the course what group we are coming from, so it displays correctly
  2854. $course->disp_for_group_id = $group->group_id;
  2855. $pC .= $this->draw_course_row($course, $course->icon_filename, $course->title_text, $course->temp_flag, TRUE, TRUE, FALSE, $group);
  2856. // Doesn't matter if its a specified repeat or not. Just
  2857. // mark it as having been displayed.
  2858. $course->set_has_been_displayed($group->req_by_degree_id);
  2859. }
  2860. return $pC;
  2861. }
  2862. /**
  2863. * This draws the "blank row" for a group on the degree plan, which instructs
  2864. * the user to click on it to select a course from the popup.
  2865. *
  2866. * @param Group $group
  2867. * @param int $remaining_hours
  2868. * @return string
  2869. */
  2870. function draw_group_select_row(Group $group, $remaining_hours, $rowclass = "")
  2871. {
  2872. $img_path = fp_theme_location() . "/images";
  2873. $on_mouse_over = "
  2874. onmouseover='$(this).addClass(\"selection_highlight\");'
  2875. onmouseout='$(this).removeClass(\"selection_highlight\");' ";
  2876. $render = array();
  2877. $render['#id'] = 'AdvisingScreen_draw_group_select_row';
  2878. $render['#group'] = $group;
  2879. $render['#group_name'] = $group->group_name;
  2880. $render['#remaining_hours'] = $remaining_hours;
  2881. $render['#semester_num'] = $group->assigned_to_semester_num;
  2882. $school_id = $group->school_id;
  2883. $s = "s";
  2884. if ($remaining_hours < 2)
  2885. {
  2886. $s = "";
  2887. }
  2888. $title_text = $extra_classes = "";
  2889. // Add the name of the group to the extra-classes
  2890. $extra_classes .= " gr-" . fp_get_machine_readable($group->group_name);
  2891. $select_icon = "<img src='$img_path/select.gif' class='advising-course-row-select-icon'>";
  2892. $icon_link = "<img src='$img_path/icons/$group->icon_filename' class='advising-course-row-icon advising-group-select-icon' alt='$title_text' title='$title_text'>";
  2893. $blank_degree_id = "";
  2894. if ($this->bool_blank)
  2895. {
  2896. $blank_degree_id = $this->degree_plan->degree_id;
  2897. }
  2898. $req_by_degree_id = $group->req_by_degree_id;
  2899. $render['#degree_id'] = $req_by_degree_id;
  2900. $disp_remaining_hours = $remaining_hours;
  2901. // If the group has min_hours, then the disp_remaining_hours gets that too.
  2902. if ($group->has_min_hours_allowed()) {
  2903. $disp_remaining_hours = ($group->min_hours_allowed - $group->hours_fulfilled) . "-" . $remaining_hours;
  2904. }
  2905. $dialog_title = t("Select @disp_hrs hour$s from %group_title", array('@disp_hrs' => $disp_remaining_hours, '%group_title' => $group->title));
  2906. if ($remaining_hours > 200) {
  2907. // Don't bother showing the remaining hours number.
  2908. $dialog_title = t("Select additional hour$s from %group_title", array('%group_title' => $group->title));
  2909. if ($group->group_id == DegreePlan::GROUP_ID_FOR_COURSES_ADDED) {
  2910. $dialog_title = t("Select additional courses");
  2911. }
  2912. }
  2913. $js_code = "selectCourseFromGroup(\"$group->group_id\", \"$group->assigned_to_semester_num\", \"$remaining_hours\", \"$blank_degree_id\",\"$req_by_degree_id\",\"$dialog_title\");";
  2914. $row_msg = t("Click") . " <span style='color:red;' class='group-select-arrows'>&gt;&gt;</span> " . t("to select @drh hour$s.", array("@drh" => $disp_remaining_hours));
  2915. if ($remaining_hours > 200) {
  2916. // Don't bother showing the remaining hours number.
  2917. $row_msg = t("Click") . " <span style='color:red;' class='group-select-arrows'>&gt;&gt;</span> " . t("to select additional courses.");
  2918. }
  2919. $hand_class = "hand";
  2920. if (variable_get_for_school("show_group_titles_on_view", "no", $school_id) == "yes")
  2921. {
  2922. $row_msg = t("Select") . " $disp_remaining_hours " . t("hour$s from") . " $group->title.";
  2923. if ($remaining_hours > 200) {
  2924. // Don't bother showing the remaining hours number.
  2925. $row_msg = t("Select additional courses from") . " $group->title.";
  2926. }
  2927. if ($this->bool_print) {
  2928. // In print view, disable all popups and mouseovers.
  2929. $on_mouse_over = "";
  2930. $js_code = "";
  2931. $hand_class = "";
  2932. }
  2933. }
  2934. if ($group->group_id == DegreePlan::GROUP_ID_FOR_COURSES_ADDED)
  2935. { // This is the Add a Course group.
  2936. $row_msg = t("Click to add an additional course.");
  2937. $select_icon = "<span style='color:#0080ff;'><i class='fa fa-plus'></i></span>";
  2938. $icon_link = "";
  2939. }
  2940. // Let's find out if this group contains courses which can be used in more than one degree.
  2941. $res = intval($this->degree_plan->get_max_course_appears_in_degrees_count($group->group_id));
  2942. if ($res > 1) {
  2943. $extra_classes .= " contains-course-which-appears-in-mult-degrees contains-course-which-appears-in-$res-degrees";
  2944. }
  2945. // Just like the other times we check to theme a course row, let's give the option to theme this as well.
  2946. $theme = array();
  2947. $theme["screen"] = $this;
  2948. $theme["degree_plan"] = $this->degree_plan;
  2949. $theme["student"] = $this->student;
  2950. $theme["group"]["group"] = $group;
  2951. $theme["group"]["extra_classes"] = $extra_classes;
  2952. $theme["group"]["icon_link"] = $icon_link;
  2953. $theme["group"]["select_icon"] = $select_icon;
  2954. $theme["group"]["js_code"] = $js_code;
  2955. $theme["group"]["row_msg"] = $row_msg;
  2956. $theme["group"]["title"] = $group->title;
  2957. $theme["group"]["remaining_hours"] = $remaining_hours;
  2958. // Invoke a hook on our theme array, so other modules have a chance to change it up.
  2959. invoke_hook("theme_advise_group_select_row", array(&$theme));
  2960. $render['#js_code'] = $js_code;
  2961. $render['start_group_select_row'] = array(
  2962. 'value' => "<tr class='from-render-api $rowclass'><td colspan='8' class='group-select-row-tr'>",
  2963. 'weight' => 0,
  2964. );
  2965. $render['group_select_table_top'] = array(
  2966. 'value' => "<table border='0' cellpadding='0' class='table-group-select-row' cellspacing='0' >",
  2967. 'weight' => 100,
  2968. );
  2969. $render['group_select_table_tr'] = array(
  2970. 'value' => "<tr class='$hand_class {$theme["group"]["extra_classes"]} group-select-row'
  2971. $on_mouse_over title='{$theme["group"]["title"]}'>",
  2972. 'weight' => 200,
  2973. );
  2974. $render['group_select_table_w1_1'] = array(
  2975. 'value' => "<td class='group-w1_1 w1_1' ></td>",
  2976. 'weight' => 300,
  2977. );
  2978. $render['group_select_table_icon_link'] = array(
  2979. 'value' => "<td class='group-w1_2 w1_2' onClick='{$theme["group"]["js_code"]}'>{$theme["group"]["icon_link"]}</td>",
  2980. 'weight' => 400,
  2981. );
  2982. $render['group_select_table_select_icon'] = array(
  2983. 'value' => "<td class='group-w1_3 w1_3' onClick='{$theme["group"]["js_code"]}'>{$theme["group"]["select_icon"]}</td>",
  2984. 'weight' => 500,
  2985. );
  2986. $render['group_select_table_row_msg'] = array(
  2987. 'value' => "<td class='underline group-row-msg' onClick='{$theme["group"]["js_code"]}'>
  2988. {$theme["group"]["row_msg"]}
  2989. </td>",
  2990. 'weight' => 600,
  2991. );
  2992. $render['group_select_table_bottom'] = array(
  2993. 'value' => "</tr>
  2994. </table>",
  2995. 'weight' => 5000,
  2996. );
  2997. $render['end_group_select_row'] = array(
  2998. 'value' => "</td></tr>",
  2999. 'weight' => 9999,
  3000. );
  3001. return fp_render_content($render, FALSE);
  3002. }
  3003. /**
  3004. * Uses the draw_box_top function, specifically for semesters.
  3005. *
  3006. * @param string $title
  3007. * @param bool $hideheaders
  3008. * @return string
  3009. */
  3010. function draw_semester_box_top($title, $hideheaders = false)
  3011. {
  3012. $extra_classes = " fp-semester-box-top fp-semester-box-top-" . fp_get_machine_readable(strtolower($title));
  3013. return $this->draw_box_top($title, $hideheaders, $extra_classes);
  3014. }
  3015. /**
  3016. * Uses the draw_box_bottom function, specifically for semesters.
  3017. * Actually, this function is a straight alias for $this->draw_box_bottom().
  3018. *
  3019. * @return string
  3020. */
  3021. function draw_semester_box_bottom()
  3022. {
  3023. return $this->draw_box_bottom();
  3024. }
  3025. /**
  3026. * Very, very simple. Just returns "</table>";
  3027. *
  3028. * @return string
  3029. */
  3030. function draw_box_bottom()
  3031. {
  3032. return "</table>";
  3033. }
  3034. /**
  3035. * Used to draw the beginning of semester boxes and other boxes, for example
  3036. * the footnotes.
  3037. *
  3038. * @param string $title
  3039. * @param bool $hideheaders
  3040. * - If TRUE, then the course/hrs/grd headers will not be displayed.
  3041. *
  3042. * @param int $table_width
  3043. * - The HTML table width, in pixels. If not set, it will default
  3044. * to 300 pixels wide.
  3045. *
  3046. * @return string
  3047. */
  3048. function draw_box_top($title, $hideheaders=false, $extra_classes = ""){
  3049. // returns the beginnings of the semester block tables...
  3050. $headers = array();
  3051. if ($hideheaders != true)
  3052. {
  3053. $headers[0] = t("Course");
  3054. $headers[1] = t("Hrs");
  3055. $headers[2] = t("Grd");
  3056. $headers[3] = t("Pts");
  3057. }
  3058. $extra_classes .= " fp-box-top-" . fp_get_machine_readable(strtolower($title));
  3059. $render = array();
  3060. $render['#id'] = 'AdvisingScreen_draw_box_top';
  3061. $render['#title'] = $title;
  3062. $render['#hideheaders'] = $hideheaders;
  3063. $render['#extra_classes'] = $extra_classes;
  3064. $render['table_top'] = array(
  3065. 'value' => "<table border='0' cellpadding='0' cellspacing='0' class='fp-box-top $extra_classes'>",
  3066. );
  3067. $render['semester_title_box_top'] = array(
  3068. 'value' => "<tr>
  3069. <td colspan='8' class='semester-box-top'>
  3070. ",
  3071. );
  3072. $render['section_title'] = array(
  3073. 'value' => fp_render_section_title($title),
  3074. );
  3075. $render['semester_title_box_bottom'] = array(
  3076. 'value' => "</td>
  3077. </tr>",
  3078. );
  3079. if (!$hideheaders)
  3080. {
  3081. $render['headers'] = array(
  3082. 'value' => "<tr class='box-headers-row'>
  3083. <td colspan='8'>
  3084. <table class='header-table' cellpadding='0' cellspacing='0'>
  3085. <th class='w1_1'></th>
  3086. <th class='w1_2'></th>
  3087. <th class='w1_3'></th>
  3088. <th class='w2'>
  3089. $headers[0]
  3090. </th>
  3091. <th class='w3'></th>
  3092. <th class='w4'>
  3093. $headers[1]
  3094. </th>
  3095. <th class='w5'>
  3096. $headers[2]
  3097. </th>
  3098. <th class='w6'>
  3099. $headers[3]
  3100. </th>
  3101. <!--after_last_th-->
  3102. </tr>
  3103. </table>
  3104. </td>
  3105. </tr>
  3106. ",
  3107. );
  3108. }
  3109. return fp_render_content($render, FALSE);
  3110. } // draw_year_box_top
  3111. /**
  3112. * This is used by lots of other functions to display a course on the screen.
  3113. * It will show the course, the hours, the grade, and quality points, as well
  3114. * as any necessary icons next to it.
  3115. *
  3116. * @param Course $course
  3117. * @param string $icon_filename
  3118. * @param string $title_text
  3119. * @param bool $js_toggle_and_save
  3120. * - If set to TRUE, when the checkbox next to this course is clicked,
  3121. * the page will be submitted and a draft will be saved.
  3122. *
  3123. * @param bool $bool_display_check
  3124. * - If set to FALSE, no checkbox will be displayed for this course row.
  3125. *
  3126. * @param bool $bool_add_footnote
  3127. * @param bool $bool_add_asterisk_to_transfers
  3128. *
  3129. * @return string
  3130. */
  3131. function draw_course_row(Course $course, $icon_filename = "", $title_text = "", $js_toggle_and_save = false, $bool_display_check = true, $bool_add_footnote = true, $bool_add_asterisk_to_transfers = false, $group = NULL)
  3132. {
  3133. $render = array();
  3134. $render['#id'] = 'AdvisingScreen_draw_course_row';
  3135. $render['#course'] = $course;
  3136. $render['#group'] = $group;
  3137. // Display a course itself
  3138. $theme = array();
  3139. $theme["screen"] = $this;
  3140. $theme["student"] = $this->student;
  3141. $theme["degree_plan"] = $this->degree_plan;
  3142. $img_path = fp_theme_location() . "/images";
  3143. // The current term we are advising for.
  3144. $advising_term_id = @$GLOBALS["fp_advising"]["advising_term_id"];
  3145. $pts = "";
  3146. if (!$advising_term_id) {
  3147. $advising_term_id = 0;
  3148. }
  3149. $extra_classes = "";
  3150. $course->assign_display_status();
  3151. // If the course has already been advised in a different semester,
  3152. // we should set the advising_term_id to that and disable unchecking.
  3153. if ($course->advised_term_id*1 > 0 && $course->bool_advised_to_take == true && $course->advised_term_id != $advising_term_id)
  3154. {
  3155. $course->display_status = "disabled";
  3156. $advising_term_id = $course->advised_term_id;
  3157. }
  3158. // Add the name of the course to the extra-classes
  3159. $extra_classes .= " cr-" . fp_get_machine_readable($course->subject_id . " " . $course->course_num);
  3160. // Has the course been assigned to more than one degree?
  3161. if (count($course->assigned_to_degree_ids_array) > 1) {
  3162. $extra_classes .= " course-assigned-more-than-one-degree course-assigned-" . count($course->assigned_to_degree_ids_array) . "-degrees";
  3163. }
  3164. // If this is a course fragment, created as a remainder of a split substitution, add extra class.
  3165. if (@$course->details_by_degree_array[$course->req_by_degree_id]["bool_substitution_new_from_split"]) {
  3166. $extra_classes .= " course-sub-new-from-split";
  3167. }
  3168. if (@$course->details_by_degree_array[$course->req_by_degree_id]["bool_substitution_split"]) {
  3169. $extra_classes .= " course-sub-split";
  3170. }
  3171. // If the course has NOT been assigned, but is appearing in more than one degree, give it an extra CSS class
  3172. // Check to see if the course is in our required_courses_id_array for more than one degree.
  3173. if ($course->display_status == "eligible") {
  3174. if (isset($this->degree_plan->required_course_id_array[$course->course_id])) {
  3175. if (count($this->degree_plan->required_course_id_array[$course->course_id]) > 1) {
  3176. // Add a new classname for this course...
  3177. $extra_classes .= " course-appears-in-mult-degrees course-appears-in-" . count($this->degree_plan->required_course_id_array[$course->course_id]) . "-degrees";
  3178. }
  3179. }
  3180. }
  3181. if ($course->subject_id == "")
  3182. {
  3183. $course->load_descriptive_data();
  3184. }
  3185. $bool_transfer = FALSE;
  3186. $subject_id = $course->subject_id;
  3187. $course_num = $course->course_num;
  3188. $o_subject_id = $subject_id;
  3189. $o_course_num = $course_num;
  3190. $degree_id = $course->req_by_degree_id;
  3191. $footnote = "";
  3192. $ast = "";
  3193. // Is this actually a transfer course? If so, display its
  3194. // original subject_id and course_num.
  3195. if ($course->bool_transfer == true)
  3196. {
  3197. $bool_transfer = TRUE;
  3198. if ($course->course_transfer->subject_id == '') {
  3199. $course->course_transfer->load_descriptive_transfer_data($this->student->student_id);
  3200. }
  3201. $subject_id = $course->course_transfer->subject_id;
  3202. $course_num = $course->course_transfer->course_num;
  3203. $institution_name = $course->course_transfer->institution_name;
  3204. if ($bool_add_asterisk_to_transfers == true)
  3205. {
  3206. $course->course_transfer->load_descriptive_transfer_data($this->student->student_id);
  3207. if ($course->course_transfer->transfer_eqv_text != "")
  3208. {
  3209. $ast = "<i class='advising-course-transfer-ast fa fa-asterisk'></i>";
  3210. $GLOBALS["advising_course_has_asterisk"] = true;
  3211. }
  3212. }
  3213. // Apply a footnote if it has a local eqv.
  3214. if ($bool_add_footnote == true && $course->course_id > 0)
  3215. {
  3216. $footnote = "";
  3217. $footnote .= "<span class='superscript'>T";
  3218. $fcount = 0;
  3219. if (isset($this->footnote_array) && is_array($this->footnote_array) && isset($this->footnote_array["transfer"])) {
  3220. $fcount = @count($this->footnote_array["transfer"]) + 1;
  3221. }
  3222. if ($course->get_has_been_displayed() == true)
  3223. { // If we've already displayed this course once, and are
  3224. // now showing it again (like in the Transfer Credit list)
  3225. // we do not want to increment the footnote counter.
  3226. $fcount = $course->transfer_footnote;
  3227. }
  3228. $course->transfer_footnote = $fcount;
  3229. $footnote .= "$fcount</span>";
  3230. $this->footnote_array["transfer"][$fcount] = "$o_subject_id $o_course_num ~~ $subject_id $course_num ~~ ~~ $institution_name";
  3231. }
  3232. } // bool_transfer == true
  3233. $hours = $course->get_hours_awarded();
  3234. if ($course->get_bool_substitution() == TRUE )
  3235. {
  3236. $hours = $course->get_substitution_hours();
  3237. $temp_sub_course = $course->get_course_substitution();
  3238. if (is_object($temp_sub_course))
  3239. {
  3240. if ($temp_sub_course->subject_id == "")
  3241. { // Reload subject_id, course_num, etc, for the substitution course,
  3242. // which is actually the original requirement.
  3243. $temp_sub_course->load_descriptive_data();
  3244. }
  3245. $o_subject_id = $temp_sub_course->subject_id;
  3246. $o_course_num = $temp_sub_course->course_num;
  3247. }
  3248. if ($bool_add_footnote == true)
  3249. {
  3250. if (!isset($this->footnote_array["substitution"])) $this->footnote_array["substitution"] = array();
  3251. $footnote = "";
  3252. $footnote .= "<span class='superscript'>S";
  3253. $fcount = count($this->footnote_array["substitution"]) + 1;
  3254. if ($course->get_has_been_displayed($course->req_by_degree_id) == true)
  3255. { // If we've already displayed this course once, and are
  3256. // now showing it again (like in the Transfer Credit list)
  3257. // we do not want to increment the footnote counter.
  3258. $fcount = $course->substitution_footnote;
  3259. }
  3260. $course->substitution_footnote = $fcount;
  3261. $footnote .= "$fcount</span>";
  3262. $r = $course->req_by_degree_id;
  3263. @$sub_id = $course->db_substitution_id_array[$r];
  3264. $this->footnote_array["substitution"][$fcount] = "$o_subject_id $o_course_num ~~ $subject_id $course_num ~~ " . $course->get_substitution_hours() . " ~~ " . $course->get_first_assigned_to_group_id() . " ~~ $sub_id";
  3265. }
  3266. } // if course->get_bool_substitution() == true
  3267. if (is_numeric($hours) && $hours <= 0) {
  3268. // Some kind of error-- default to catalog hours
  3269. $hours = $course->get_catalog_hours();
  3270. }
  3271. if (is_numeric($hours)) {
  3272. $hours = $hours * 1; // force numeric, trim extra zeros.
  3273. }
  3274. $var_hour_icon = "&nbsp;";
  3275. // Show the var_hour icon if this has variable hours and is NOT from a split substitution.
  3276. if ($course->has_variable_hours() == TRUE && !$course->bool_taken && !$course->get_bool_substitution_split() && !$course->get_bool_substitution_new_from_split())
  3277. {
  3278. // The bool_taken part of this IF statement is because if the course
  3279. // has been completed, we should only use the hours_awarded.
  3280. $var_hour_icon = "<img src='" . fp_theme_location() . "/images/var_hour.gif'
  3281. title='" . t("This course has variable hours.") . "'
  3282. alt='" . t("This course has variable hours.") . "'>";
  3283. $hours = $course->get_advised_hours();
  3284. }
  3285. if ($course->bool_ghost_hour == TRUE) {
  3286. // This course was given a "ghost hour", meaning it is actually
  3287. // worth 0 hours, not 1, even though it's hours_awarded is currently
  3288. // set to 1. So, let's just make the display be 0.
  3289. $hours = "0";
  3290. }
  3291. $grade = (string) $course->grade;
  3292. $dispgrade = $grade;
  3293. // If there is a MID, then this is a midterm grade.
  3294. $dispgrade = str_replace("MID","<span class='superscript'>" . t("mid") . "</span>", $dispgrade);
  3295. if (strtoupper($grade) == "E")
  3296. { // Currently enrolled. Show no grade.
  3297. $dispgrade = "";
  3298. }
  3299. if ($course->bool_hide_grade)
  3300. {
  3301. $dispgrade = "--";
  3302. $this->bool_hiding_grades = true;
  3303. }
  3304. $display_status = $course->display_status;
  3305. if ($display_status == "completed")
  3306. {
  3307. $pts = $this->get_quality_points($grade, $hours);
  3308. }
  3309. $course_id = $course->course_id;
  3310. $semester_num = $course->assigned_to_semester_num;
  3311. if ($group != NULL && $course->bool_advised_to_take != TRUE) {
  3312. $semester_num = $group->assigned_to_semester_num;
  3313. }
  3314. $render['#semester_num'] = $semester_num;
  3315. $render['#course_id'] = $course_id;
  3316. //$group_id = $course->assigned_to_group_id;
  3317. $group_id = $course->get_first_assigned_to_group_id();
  3318. $hid_group_id = str_replace("_", "U", $group_id); // replace _ with placeholder U so it doesn't mess up submission.
  3319. $random_id = $course->random_id;
  3320. $advised_hours = $course->advised_hours*1;
  3321. $row_random_num = mt_rand(1,99999);
  3322. $render['#row_random_num'] = $row_random_num;
  3323. $unique_id = $course_id . "_" . $semester_num . "_" . $row_random_num;
  3324. $hid_name = "advcr_$course_id" . "_$semester_num" . "_$hid_group_id" . "_$advised_hours" . "_$random_id" . "_$advising_term_id" . "_$degree_id" . "_r" . $row_random_num;
  3325. $render['#row_unique_id'] = $unique_id;
  3326. $render['#row_hid_name'] = $hid_name;
  3327. $render['#row_hid_id'] = "advcr_$unique_id";
  3328. // Add unique_id to the course object for later use.
  3329. $course->unique_id = $unique_id;
  3330. // Due to an interesting bug, the hid_name cannot contain periods. So, if a course
  3331. // has decimal hours, we need to replace the decimal with a placeholder.
  3332. if (strstr($hid_name, ".")) {
  3333. $hid_name = str_replace(".", "DoT", $hid_name);
  3334. }
  3335. $hid_value = "";
  3336. $opchecked = "";
  3337. if ($course->bool_advised_to_take == true)
  3338. {
  3339. $hid_value = "true";
  3340. $opchecked = "-check";
  3341. }
  3342. $op_on_click_function = "toggleSelection";
  3343. if ($js_toggle_and_save == true)
  3344. {
  3345. $op_on_click_function = "toggleSelectionAndSave";
  3346. }
  3347. $extra_js_vars = "";
  3348. if ($course->display_status == "disabled")
  3349. { // Checkbox needs to be disabled because this was advised in another
  3350. // term.
  3351. $op_on_click_function = "toggleDisabledChangeTerm";
  3352. $course->term_id = $course->advised_term_id;
  3353. $extra_js_vars = $course->get_term_description();
  3354. }
  3355. if ($course->display_status == "completed" || $course->display_status == "enrolled")
  3356. {
  3357. $op_on_click_function = "toggleDisabledCompleted";
  3358. $opchecked = "";
  3359. $extra_js_vars = $course->display_status;
  3360. }
  3361. if ($course->display_status == "retake")
  3362. {
  3363. // this course was probably subbed in while the student
  3364. // was still enrolled, and they have since made an F or W.
  3365. // So, disable it.
  3366. $op_on_click_function = "dummyToggleSelection";
  3367. $opchecked = "";
  3368. }
  3369. if ($this->bool_print || $this->bool_blank)
  3370. {
  3371. // If this is print view, disable clicking.
  3372. $op_on_click_function = "dummyToggleSelection";
  3373. }
  3374. if (!user_has_permission("can_advise_students"))
  3375. {
  3376. // This user does not have the abilty to advise,
  3377. // so take away the ability to toggle anything (like
  3378. // we are in print view).
  3379. $op_on_click_function = "dummyToggleSelection";
  3380. }
  3381. $extra_css = "";
  3382. if ($opchecked == "-check") {
  3383. $extra_css .= " advise-checkbox-$display_status-checked";
  3384. }
  3385. $theme["op"] = array(
  3386. "display_status" => $display_status,
  3387. "extra_css" => $extra_css,
  3388. "unique_id" => $unique_id,
  3389. "onclick" => array(
  3390. "function" => $op_on_click_function,
  3391. "arguments" => array($unique_id, $display_status, $extra_js_vars),
  3392. ),
  3393. "hidden_field" => "<input type='hidden' name='$hid_name' id='advcr_$unique_id' value='$hid_value'>",
  3394. );
  3395. // Okay, we can't actually serialize a course, as it takes too much space.
  3396. // It was slowing down the page load significantly! So, I am going
  3397. // to use a function I wrote called to_data_string().
  3398. $data_string = $course->to_data_string();
  3399. $blank_degree_id = "";
  3400. if ($this->bool_blank == true)
  3401. {
  3402. $blank_degree_id = $this->degree_plan->degree_id;
  3403. }
  3404. $js_code = "describeCourse(\"$data_string\",\"$blank_degree_id\",\"$subject_id $course_num\");";
  3405. $theme["course"]["js_code"] = $js_code;
  3406. // Assemble theme array elements for the course itself.
  3407. $theme["course"] = array(
  3408. "course" => $course,
  3409. "js_code" => $js_code,
  3410. "subject_id" => $subject_id,
  3411. "course_num" => $course_num,
  3412. "display_status" => $display_status,
  3413. "extra_classes" => $extra_classes,
  3414. "footnote" => $footnote,
  3415. "hours" => $hours,
  3416. "var_hour_icon" => $var_hour_icon,
  3417. "dispgrade" => $dispgrade,
  3418. "grade" => $grade,
  3419. "pts" => $pts,
  3420. "title" => $title_text,
  3421. "group_id" => $group_id,
  3422. );
  3423. $theme['course']['row_unique_id'] = $unique_id;
  3424. $theme['course']['row_hid_name'] = $hid_name;
  3425. $theme['course']['row_hid_id'] = "advcr_$unique_id";
  3426. // If the course has a 'u' in it, it is a 'University Capstone' course.
  3427. if (strstr($course->requirement_type, "u")) {
  3428. $icon_filename = "ucap.gif";
  3429. $title_text = t("This course is a University Capstone.");
  3430. }
  3431. if ($icon_filename != "") {
  3432. //$icon_link = "<img src='" . fp_theme_location() . "/images/icons/$icon_filename' width='19' height='19' border='0' alt='$title_text' title='$title_text'>";
  3433. $theme["icon"] = array();
  3434. $theme["icon"]["filename"] = $icon_filename;
  3435. $theme["icon"]["location"] = fp_theme_location() . "/images/icons";
  3436. $theme["icon"]["title"] = $title_text;
  3437. }
  3438. $on_mouse_over = "
  3439. onmouseover='$(this).addClass(\"selection_highlight\");'
  3440. onmouseout='$(this).removeClass(\"selection_highlight\");'
  3441. ";
  3442. $hand_class = "hand";
  3443. if ($bool_display_check == false) {
  3444. unset($theme["op"]);
  3445. }
  3446. if ($this->bool_print) {
  3447. // In print view, disable all popups and mouseovers.
  3448. $on_mouse_over = "";
  3449. $theme["course"]["js_code"] = "";
  3450. $hand_class = "";
  3451. }
  3452. // Invoke a hook on our theme array, so other modules have a chance to change it up.
  3453. invoke_hook("theme_advise_course_row", array(&$theme));
  3454. $render['#degree_id'] = $degree_id;
  3455. /////////////////////////////////
  3456. // Actually draw out our $theme array now....
  3457. // The checkbox & hidden element....
  3458. $op = $hid = "";
  3459. if (isset($theme["op"]) && count($theme["op"]) > 0) {
  3460. $onclick = "";
  3461. $onclick = $theme["op"]["onclick"]["function"] . "(\"" . join("\",\"", $theme["op"]["onclick"]["arguments"]) . "\")";
  3462. $op = "<span class='advise-checkbox advise-checkbox-{$theme["op"]["display_status"]} {$theme["op"]["extra_css"]}'
  3463. id='cb_span_{$theme["op"]["unique_id"]}'
  3464. onClick='$onclick;'></span>";
  3465. $hid = $theme["op"]["hidden_field"];
  3466. }
  3467. // The icon....
  3468. $icon_html = "";
  3469. if (isset($theme["icon"]) && count($theme["icon"]) > 0) {
  3470. $icon_html = "<img class='advising-course-row-icon'
  3471. src='{$theme["icon"]["location"]}/{$theme["icon"]["filename"]}' alt='{$theme["icon"]["title"]}' title='{$theme["icon"]["title"]}'>";
  3472. }
  3473. ////////////////////////////////////
  3474. // Draw the actual course row...
  3475. $render['start_course_row'] = array(
  3476. 'value' => "<tr class='from-render-api'><td colspan='8'>",
  3477. 'weight' => 0,
  3478. );
  3479. if ($course->get_bool_substitution_new_from_split() != TRUE || ($course->get_bool_substitution_new_from_split() == TRUE && $course->display_status != "eligible")){
  3480. if ($course_num == ""){
  3481. $course_num = "&nbsp;";
  3482. }
  3483. $js_code = $theme["course"]["js_code"];
  3484. $render['#js_code'] = $js_code;
  3485. $render['course_row_start_table'] = array(
  3486. 'value' => "<table border='0' cellpadding='0' cellspacing='0' class='draw-course-row'>",
  3487. 'weight' => 100,
  3488. );
  3489. $render['course_row_start_tr'] = array(
  3490. 'value' => "<tr class='$hand_class {$theme["course"]["display_status"]} {$theme["course"]["extra_classes"]}'
  3491. $on_mouse_over title='{$theme["course"]["title"]}' >",
  3492. 'weight' => 200,
  3493. );
  3494. $render['course_row_td_op_and_hidden'] = array(
  3495. 'value' => "<td class='w1_1'>$op$hid</td>",
  3496. 'weight' => 300,
  3497. );
  3498. $render['course_row_td_icon_html'] = array(
  3499. 'value' => "<td class='w1_2' onClick='$js_code'>$icon_html</td>",
  3500. 'weight' => 400,
  3501. );
  3502. $render['course_row_td_ast'] = array(
  3503. 'value' => "<td class='w1_3' onClick='$js_code'>&nbsp;$ast</td>",
  3504. 'weight' => 500,
  3505. );
  3506. $render['course_row_td_subject_id'] = array(
  3507. 'value' => "<td class='underline w2 ' onClick='$js_code'>
  3508. {$theme["course"]["subject_id"]}</td>",
  3509. 'weight' => 600,
  3510. );
  3511. $render['course_row_td_course_num'] = array(
  3512. 'value' => "<td class='underline w3' align='left'
  3513. onClick='$js_code'>
  3514. {$theme["course"]["course_num"]}{$theme["course"]["footnote"]}</td>",
  3515. 'weight' => 700,
  3516. );
  3517. $render['course_row_td_hrs'] = array(
  3518. 'value' => "<td class='underline w4' onClick='$js_code'>{$theme["course"]["hours"]}{$theme["course"]["var_hour_icon"]}</td>",
  3519. 'weight' => 800,
  3520. );
  3521. $render['course_row_td_grd'] = array(
  3522. 'value' => "<td class='underline w5' onClick='$js_code'>{$theme["course"]["dispgrade"]}&nbsp;</td>",
  3523. 'weight' => 900,
  3524. );
  3525. $render['course_row_td_pts'] = array(
  3526. 'value' => "<td class='underline w6' onClick='$js_code'>{$theme["course"]["pts"]}&nbsp;</td>",
  3527. 'weight' => 1000,
  3528. );
  3529. /*
  3530. $pC .= "
  3531. <table border='0' cellpadding='0' width='100%' cellspacing='0' align='left' class='draw-course-row'>
  3532. <tr height='20' class='$hand_class {$theme["course"]["display_status"]} {$theme["course"]["extra_classes"]}'
  3533. $on_mouse_over title='{$theme["course"]["title"]}' >
  3534. <td style='width:$w1_1; white-space:nowrap;' class='w1_1' align='left'>$op$hid</td>
  3535. <td style='width:$w1_2; white-space:nowrap;' align='left' class='w1_2' onClick='$js_code'>$icon_html</td>
  3536. <td style='width:$w1_3; white-space:nowrap;' align='left' class='w1_3' onClick='$js_code'>&nbsp;$ast</td>
  3537. <td align='left' style='width:$w2; white-space:nowrap;' class='underline w2 ' onClick='$js_code'>
  3538. {$theme["course"]["subject_id"]}</td>
  3539. <td class='underline w3' style='width:$w3; white-space:nowrap;' align='left'
  3540. onClick='$js_code'>
  3541. {$theme["course"]["course_num"]}{$theme["course"]["footnote"]}</td>
  3542. <td class='underline w4' style='width:$w4; max-width:36px; white-space:nowrap;' onClick='$js_code'>{$theme["course"]["hours"]}{$theme["course"]["var_hour_icon"]}</td>
  3543. <td class='underline w5' style='width:$w5; max-width:35px; white-space:nowrap;' onClick='$js_code'>{$theme["course"]["dispgrade"]}&nbsp;</td>
  3544. <td class='underline w6' style='width:$w6; max-width:31px; white-space:nowrap;' onClick='$js_code'>{$theme["course"]["pts"]}&nbsp;</td>
  3545. </tr>
  3546. </table>";
  3547. */
  3548. $render['course_row_end_row_and_table'] = array(
  3549. 'value' => "</tr></table>",
  3550. 'weight' => 5000,
  3551. );
  3552. }
  3553. else {
  3554. // These are the leftover hours from a partial substitution.
  3555. $render['#leftover_hours_from_partial_sub'] = TRUE;
  3556. $render['#js_code'] = $js_code;
  3557. $render['course_row_start_table'] = array(
  3558. 'value' => "<table border='0' cellpadding='0' width='100%' cellspacing='0' align='left' class='draw-course-row-leftover-hours'>",
  3559. 'weight' => 100,
  3560. );
  3561. $render['course_row_start_tr'] = array(
  3562. 'value' => "<tr class='hand {$theme["course"]["display_status"]}'
  3563. $on_mouse_over title='{$theme["course"]["title"]}'>",
  3564. 'weight' => 200,
  3565. );
  3566. $render['course_row_td_op_and_hidden'] = array(
  3567. 'value' => "<td class='w1_1'>$op$hid</td>",
  3568. 'weight' => 300,
  3569. );
  3570. $render['course_row_td_icon_html'] = array(
  3571. 'value' => "<td class='w1_2' onClick='$js_code'>$icon_html</td>",
  3572. 'weight' => 400,
  3573. );
  3574. $render['course_row_td_ast'] = array(
  3575. 'value' => "<td class='w1_3' onClick='$js_code'>&nbsp;</td>",
  3576. 'weight' => 500,
  3577. );
  3578. $render['course_row_td_leftover_course_details'] = array(
  3579. 'value' => "<td class='underline course-part-sub-hrs-left' onClick='$js_code'
  3580. colspan='4'>
  3581. &nbsp; &nbsp; {$theme["course"]["subject_id"]} &nbsp;
  3582. {$theme["course"]["course_num"]}{$theme["course"]["footnote"]}
  3583. &nbsp; ({$theme["course"]["hours"]} " . t("hrs left") . ")
  3584. </td>",
  3585. 'weight' => 600,
  3586. );
  3587. $render['course_row_end_row_and_table'] = array(
  3588. 'value' => "</tr></table>",
  3589. 'weight' => 5000,
  3590. );
  3591. }
  3592. $render['end_course_row'] = array(
  3593. 'value' => "</td></tr>",
  3594. 'weight' => 9999,
  3595. );
  3596. return fp_render_content($render, FALSE);
  3597. //return $pC;
  3598. }
  3599. /**
  3600. * Calculate the quality points for a grade and hours.
  3601. *
  3602. * This function is very similar to the one in the Course class.
  3603. * It is only slightly different here. Possibly, the two functions should be
  3604. * merged.
  3605. *
  3606. * @param string $grade
  3607. * @param int $hours
  3608. * @return int
  3609. */
  3610. function get_quality_points($grade, $hours){
  3611. $pts = 0;
  3612. $qpts_grades = array();
  3613. // Let's find out what our quality point grades & values are...
  3614. if (isset($GLOBALS["qpts_grades"])) {
  3615. // have we already cached this?
  3616. $qpts_grades = $GLOBALS["qpts_grades"];
  3617. }
  3618. else {
  3619. $tlines = explode("\n", variable_get_for_school("quality_points_grades", "A ~ 4\nB ~ 3\nC ~ 2\nD ~ 1\nF ~ 0\nI ~ 0", $this->student->school_id));
  3620. foreach ($tlines as $tline) {
  3621. $temp = explode("~", trim($tline));
  3622. if (trim($temp[0]) != "") {
  3623. $qpts_grades[trim($temp[0])] = trim($temp[1]);
  3624. }
  3625. }
  3626. $GLOBALS["qpts_grades"] = $qpts_grades; // save to cache
  3627. }
  3628. // Okay, find out what the points are by multiplying value * hours...
  3629. if (isset($qpts_grades[$grade])) {
  3630. $pts = $qpts_grades[$grade] * $hours;
  3631. }
  3632. return $pts;
  3633. }
  3634. /**
  3635. * Used in the group selection popup, this will display a course with
  3636. * a radio button next to it, so the user can select it.
  3637. *
  3638. * @param Course $course
  3639. * @param int $group_hours_remaining
  3640. *
  3641. * @return string
  3642. */
  3643. function draw_popup_group_select_course_row(Course $course, $group_hours_remaining = 0)
  3644. {
  3645. // Display a course itself...
  3646. $pC = "";
  3647. $w1_1 = $this->popup_width_array[0];
  3648. $w1_2 = $this->popup_width_array[1];
  3649. $w1_3 = $this->popup_width_array[2];
  3650. $w2 = $this->popup_width_array[3];
  3651. $w3 = $this->popup_width_array[4];
  3652. $w4 = $this->popup_width_array[5];
  3653. $w5 = $this->popup_width_array[6];
  3654. $w6 = $this->popup_width_array[7];
  3655. $title_text = "";
  3656. $icon_html = "";
  3657. $pts = "";
  3658. $theme["icon"] = array();
  3659. $theme = array();
  3660. $theme["screen"] = $this;
  3661. $theme["student"] = $this->student;
  3662. $theme["degree_plan"] = $this->degree_plan;
  3663. $theme["from_group_select"] = TRUE;
  3664. if ($course->subject_id == "")
  3665. {
  3666. // Lacking course's display data, so reload it from the DB.
  3667. $course->load_course($course->course_id);
  3668. }
  3669. $subject_id = $course->subject_id;
  3670. $course_num = $course->course_num;
  3671. $hours = $course->get_catalog_hours();
  3672. $display_status = $course->display_status;
  3673. $db_group_requirement_id = $course->db_group_requirement_id;
  3674. $grade = $course->grade;
  3675. $repeats = $course->specified_repeats;
  3676. if ($repeats > 0 && $show_repeat_information)
  3677. {
  3678. $w3 = "15%";
  3679. }
  3680. $attributes = $course->db_group_attributes;
  3681. $attributes_class = "";
  3682. if ($attributes == "*") {
  3683. $attributes_class .= "group-attr-recommended";
  3684. }
  3685. if ($attributes == "-") {
  3686. $attributes_class .= "group-attr-hidden";
  3687. }
  3688. //Setting in Configure School Settings:
  3689. $show_repeat_information = (variable_get_for_school("group_list_course_show_repeat_information", "yes", $course->school_id) == "yes");
  3690. $course_id = $course->course_id;
  3691. //$group_id = $course->assigned_to_group_id;
  3692. $group_id = $course->get_first_assigned_to_group_id();
  3693. $semester_num = $course->assigned_to_semester_num;
  3694. $req_by_degree_id = $course->req_by_degree_id;
  3695. $min_var_hours = "";
  3696. $var_hour_icon = "&nbsp;";
  3697. if ($course->has_variable_hours() == true)
  3698. {
  3699. $var_hour_icon = "<img src='" . fp_theme_location() . "/images/var_hour.gif'
  3700. title='" . t("This course has variable hours.") . "'
  3701. alt='" . t("This course has variable hours.") . "'>";
  3702. $min_var_hours = $course->min_hours;
  3703. // Does the var hours actually start at zero?
  3704. if ($course->bool_ghost_min_hour) {
  3705. $min_var_hours = 0;
  3706. }
  3707. }
  3708. $checked = "";
  3709. if ($course->bool_selected == true)
  3710. {
  3711. $checked = " checked='checked' ";
  3712. }
  3713. $blank_degree_id = "";
  3714. if ($this->bool_blank)
  3715. {
  3716. $blank_degree_id = $this->degree_plan->degree_id;
  3717. }
  3718. //$serializedCourse = urlencode(serialize($course));
  3719. $js_code = "popupDescribeSelected(\"$group_id\",\"$semester_num\",\"$course_id\",\"$subject_id\",\"req_by_degree_id=$req_by_degree_id&group_hours_remaining=$group_hours_remaining&db_group_requirement_id=$db_group_requirement_id&blank_degree_id=$blank_degree_id\");";
  3720. /*
  3721. $on_mouse_over = " onmouseover=\"style.backgroundColor='#FFFF99'\"
  3722. onmouseout=\"style.backgroundColor='white'\" ";
  3723. */
  3724. $on_mouse_over = "
  3725. onmouseover='$(this).addClass(\"selection_highlight\");'
  3726. onmouseout='$(this).removeClass(\"selection_highlight\");'
  3727. ";
  3728. $hand_class = "hand";
  3729. $extra_style = $extra_classes = $extra_css = $extra_html = "";
  3730. // Add the name of the course to the extra-classes
  3731. $extra_classes .= " cr-" . fp_get_machine_readable($course->subject_id . " " . $course->course_num);
  3732. // Check to see if the course is in our required_courses_id_array for more than one degree.
  3733. if (isset($this->degree_plan->required_course_id_array[$course->course_id])) {
  3734. if (count($this->degree_plan->required_course_id_array[$course->course_id]) > 1) {
  3735. // Add a new classname for this course...
  3736. $extra_classes .= " course-appears-in-mult-degrees course-appears-in-" . count($this->degree_plan->required_course_id_array[$course->course_id]) . "-degrees";
  3737. }
  3738. }
  3739. // Assemble theme array elements for the course itself.
  3740. $theme["course"] = array(
  3741. "course" => $course,
  3742. "course_id" => $course->course_id,
  3743. "js_code" => $js_code,
  3744. "subject_id" => $subject_id,
  3745. "course_num" => $course_num,
  3746. "display_status" => $display_status,
  3747. "extra_classes" => $extra_classes,
  3748. "hours" => $hours,
  3749. "var_hour_icon" => $var_hour_icon,
  3750. "grade" => $grade,
  3751. "pts" => $pts,
  3752. "title" => $title_text,
  3753. "extra_html" => $extra_html,
  3754. );
  3755. $op_on_click_function = "adviseSelectCourseFromGroupPopup";
  3756. $theme["op"] = array(
  3757. "display_status" => $display_status,
  3758. "extra_css" => $extra_css,
  3759. "onclick" => array(
  3760. "function" => $op_on_click_function,
  3761. "arguments" => array(""),
  3762. ),
  3763. "checked" => $checked,
  3764. "hidden_field" => "<input type='hidden' name='$course_id" . "_subject'
  3765. id='$course_id" . "_subject' value='$subject_id'>
  3766. <input type='hidden' name='$course_id" . "_db_group_requirement_id'
  3767. id='$course_id" . "_db_group_requirement_id' value='$db_group_requirement_id'>
  3768. <input type='hidden' name='$course_id" . "_req_by_degree_id' id='$course_id" . "_req_by_degree_id' value='$req_by_degree_id'>
  3769. <input type='hidden' name='$course_id" . "_min_var_hours' id='$course_id" . "_min_var_hours' value='$min_var_hours'>
  3770. ",
  3771. );
  3772. $theme["course"]["js_code"] = $js_code;
  3773. // Invoke a hook on our theme array, so other modules have a chance to change it up.
  3774. invoke_hook("theme_advise_course_row", array(&$theme));
  3775. /////////////////////////////////
  3776. // Actually draw out our $theme array now....
  3777. // The checkbox & hidden element....
  3778. $op = $hid = "";
  3779. if (isset($theme["op"]) && count($theme["op"]) > 0) {
  3780. $onclick = "";
  3781. $onclick = $theme["op"]["onclick"]["function"] . "(\"" . join("\",\"", $theme["op"]["onclick"]["arguments"]) . "\")";
  3782. $checked = $theme["op"]["checked"];
  3783. $hid = $theme["op"]["hidden_field"];
  3784. $op = "<input type='radio' name='course' class='cb-course' id='cb-course-$course_id' value='$course_id' $checked onClick='return $onclick;' $extra_css>";
  3785. }
  3786. // The icon....
  3787. $icon_html = "";
  3788. if (isset($theme["icon"]) && count($theme["icon"]) > 0) {
  3789. $icon_html = "<img class='advising-popup-group-select-course-icon'
  3790. src='{$theme["icon"]["location"]}/{$theme["icon"]["filename"]}' width='14' height='14' border='0' alt='{$theme["icon"]["title"]}' title='{$theme["icon"]["title"]}'>";
  3791. }
  3792. if ($course->bool_unselectable == true)
  3793. {
  3794. // Cannot be selected, so remove that ability!
  3795. $hand_class = "";
  3796. $on_mouse_over = "";
  3797. $js_code = "";
  3798. $op = $op_on_click_function = "";
  3799. $extra_style = "style='font-style: italic; color:gray;'";
  3800. }
  3801. //////////////////////////////////////
  3802. //////////////////////////////////////
  3803. // Actually draw the row's HTML
  3804. //////////////////////////////////////
  3805. $js_code = $theme["course"]["js_code"];
  3806. $pC .= "
  3807. <table border='0' cellpadding='0' width='100%' cellspacing='0' align='left' class='group-course-row $attributes_class'>
  3808. <tr class='$hand_class {$theme["course"]["display_status"]} {$theme["course"]["extra_classes"]}'
  3809. $on_mouse_over title='{$theme["course"]["title"]}'>
  3810. <td width='$w1_1' class='group-w1_1' align='left'>$op$hid<span onClick='$js_code'>$icon_html</span></td>
  3811. <td width='$w1_2' class='group-w1_2' align='left' onClick='$js_code'> </td>
  3812. <td width='$w1_3' class='group-w1_3' align='left' onClick='$js_code'>&nbsp;</td>
  3813. <td align='left' width='$w2' class=' underline group-w2'
  3814. onClick='$js_code' $extra_style>
  3815. {$theme["course"]["subject_id"]}</td>
  3816. <td class=' underline group-w3' $extra_style width='$w3' align='left'
  3817. onClick='$js_code'>
  3818. {$theme["course"]["course_num"]}</td>
  3819. ";
  3820. if ($repeats > 0 && $repeats < 20 && $show_repeat_information)
  3821. {
  3822. $pC .= "
  3823. <td class=' underline group-may-repeat' style='color: gray;'
  3824. onClick='$js_code' colspan='3'>
  3825. <i>" . t("May take up to") . " <span style='color: blue;'>" . ($repeats + 1) . "</span> " . t("times.") . "</i>
  3826. </td>
  3827. ";
  3828. }
  3829. else if ($repeats > 0 && $repeats >= 20 && $show_repeat_information) {
  3830. $pC .= "
  3831. <td class=' underline group-may-repeat' style='color: gray;'
  3832. onClick='$js_code' colspan='3'>
  3833. <i>" . t("May be repeated for credit.") . "</i>
  3834. </td>
  3835. ";
  3836. }
  3837. else if ($theme["course"]["extra_html"] != "") {
  3838. $pC .= "
  3839. <td class=' underline' class='group-w4' width='$w4' onClick='$js_code' $extra_style>{$theme["course"]["hours"]} {$theme["course"]["var_hour_icon"]}</td>
  3840. <td class=' underline group-course-extra-html'
  3841. onClick='$js_code' colspan='10'>
  3842. {$theme["course"]["extra_html"]}
  3843. </td>
  3844. ";
  3845. }
  3846. else {
  3847. $pC .= "
  3848. <td class=' underline' class='group-w4' width='$w4' onClick='$js_code' $extra_style>{$theme["course"]["hours"]} {$theme["course"]["var_hour_icon"]}</td>
  3849. <td class=' underline' class='group-w5' width='$w5' onClick='$js_code'>{$theme["course"]["grade"]}&nbsp;</td>
  3850. <td class=' underline' class='group-w6' width='$w6' onClick='$js_code'>{$theme["course"]["pts"]}&nbsp;</td>
  3851. ";
  3852. }
  3853. $pC .= "
  3854. </tr>
  3855. </table>";
  3856. return $pC;
  3857. }
  3858. /**
  3859. * This is used to display the substitution popup to a user, to let them
  3860. * actually make a substitution.
  3861. *
  3862. * @param int $course_id
  3863. * @param int $group_id
  3864. * @param int $semester_num
  3865. * @param int $hours_avail
  3866. *
  3867. * @return string
  3868. */
  3869. function display_popup_substitute($course_id = 0, $group_id, $semester_num, $hours_avail = "", $req_by_degree_id = 0)
  3870. {
  3871. global $current_student_id;
  3872. // This lets the user make a substitution for a course.
  3873. $pC = "";
  3874. $school_id = db_get_school_id_for_student_id($current_student_id);
  3875. // Bring in advise's css...
  3876. fp_add_css(fp_get_module_path("advise") . "/css/advise.css");
  3877. $course = new Course($course_id);
  3878. $bool_sub_add = false;
  3879. $req_degree_plan = new DegreePlan();
  3880. $req_degree_plan->degree_id = $req_by_degree_id;
  3881. if ($req_by_degree_id > 0) {
  3882. $course->req_by_degree_id = $req_by_degree_id;
  3883. $req_degree_plan->load_descriptive_data();
  3884. }
  3885. $c_title = t("Substitute for") . " $course->subject_id $course->course_num";
  3886. if ($course_id == 0)
  3887. {
  3888. $c_title = t("Substitute an additional course");
  3889. $bool_sub_add = true;
  3890. }
  3891. $pC .= fp_render_section_title($c_title);
  3892. if ($req_by_degree_id > 0) {
  3893. $pC .= "<div class=' sub-req-by-degree-title-line'>" . t("This substitution will only affect the <b>%title</b> degree requirements.", array("%title" => $req_degree_plan->get_title2())) . "
  3894. </div>";
  3895. }
  3896. $extra = ".<input type='checkbox' id='cbAddition' value='true' style='display:none;'>";
  3897. if ($group_id > 0)
  3898. {
  3899. $new_group = new Group($group_id);
  3900. $checked = "";
  3901. if ($bool_sub_add == true){$checked = "checked disabled";}
  3902. $extra = " " . t("in the group %newg.", array("%newg" => $new_group->title)) . "
  3903. " . t("Addition only:") . " <input type='checkbox' id='cbAddition' value='true' $checked>
  3904. <a href='javascript: alertSubAddition();'>?</a>";
  3905. }
  3906. $c_hours = $course->max_hours*1;
  3907. $c_ghost_hour = "";
  3908. if ($course->bool_ghost_hour == TRUE) {
  3909. $c_ghost_hour = t("ghost") . "<a href='javascript: alertSubGhost();'>?</a>";
  3910. }
  3911. if (($hours_avail*1 > 0 && $hours_avail < $c_hours) || ($c_hours <= 0))
  3912. {
  3913. // Use the remaining hours if we have fewer hours left in
  3914. // the group than the course we are subbing for.
  3915. $c_hours = $hours_avail;
  3916. }
  3917. if ($hours_avail == "" || $hours_avail*1 <= 0)
  3918. {
  3919. $hours_avail = $c_hours;
  3920. }
  3921. $pC .= "<div class=' '>
  3922. " . t("Please select a course to substitute
  3923. for %course", array("%course" => "$course->subject_id $course->course_num ($c_hours $c_ghost_hour " . t("hrs") . ")")) . "$extra
  3924. </div>
  3925. ";
  3926. // If this course has ghost hours, and if we've set that you can only sub ghost hours
  3927. // for other ghost hours, then display a message here explaining that.
  3928. $bool_ghost_for_ghost = (variable_get("restrict_ghost_subs_to_ghost_hours", "yes") == "yes" && $course->bool_ghost_hour);
  3929. if ($bool_ghost_for_ghost) {
  3930. $pC .= "<div class=' '>" . t("<b>Note:</b> As per a setting in FlightPath, the only courses which
  3931. may be substituted must be worth zero hours (1 ghost hour).") . "</div>";
  3932. }
  3933. $pC .= "
  3934. <div class=' '
  3935. style='height: 175px; overflow: auto; border:1px inset black; padding: 5px;'>
  3936. <table border='0' cellpadding='0' cellspacing='0' width='100%'>
  3937. ";
  3938. $this->student->list_courses_taken->sort_alphabetical_order(false, true, FALSE, $req_by_degree_id);
  3939. $school_id = db_get_school_id_for_student_id($this->student->student_id);
  3940. for ($t = 0; $t <= 1; $t++)
  3941. {
  3942. if ($t == 0) {$the_title = variable_get_for_school("school_initials", "DEMO", $school_id) . " " . t("Credits"); $bool_transferTest = true;}
  3943. if ($t == 1) {$the_title = t("Transfer Credits"); $bool_transferTest = false;}
  3944. $pC .= "<tr><td colspan='3' valign='top' class=' ' style='padding-bottom: 10px;'>
  3945. $the_title
  3946. </td>
  3947. <td class=' ' valign='top' >" . t("Hrs") . "</td>
  3948. <td class=' ' valign='top' >" . t("Grd") . "</td>
  3949. <td class=' ' valign='top' >" . t("Term") . "</td>
  3950. </tr>";
  3951. $already_seen = array(); // keep track of the courses we've already seen.
  3952. $used_hours_subs = array(); // extra help keeping up with how many hours we've used for particular courses in split up subs.
  3953. $is_empty = true;
  3954. $this->student->list_courses_taken->reset_counter();
  3955. while($this->student->list_courses_taken->has_more())
  3956. {
  3957. $c = $this->student->list_courses_taken->get_next();
  3958. if ($c->bool_transfer == $bool_transferTest)
  3959. {
  3960. continue;
  3961. }
  3962. if (!$c->meets_min_grade_requirement_of(null, variable_get_for_school("minimum_substitutable_grade", "D", $school_id)))
  3963. {// Make sure the grade is OK.
  3964. continue;
  3965. }
  3966. $bool_disable_selection = $disabled_msg = FALSE;
  3967. // Should we skip this course, because of a ghost_for_ghost requirement?
  3968. if ($bool_ghost_for_ghost && !$c->bool_ghost_hour) {
  3969. continue;
  3970. }
  3971. // If we are supposed to restrict ghost for ghost, but the course does NOT
  3972. // have a ghost hour, and this $c course does, then disable it
  3973. if (variable_get_for_school("restrict_ghost_subs_to_ghost_hours", "yes", $school_id) == "yes"
  3974. && $course->bool_ghost_hour != TRUE
  3975. && $c->bool_ghost_hour == TRUE) {
  3976. $bool_disable_selection = TRUE;
  3977. $disabled_msg = t("Substitution of this course has been disabled.
  3978. As per a setting in FlightPath, courses worth zero hours (1 ghost hour)
  3979. may only be substituted for course requirements also worth zero hours.");
  3980. }
  3981. $t_flag = 0;
  3982. if ($c->bool_transfer == true)
  3983. {
  3984. $t_flag = 1;
  3985. }
  3986. $is_empty = false;
  3987. $subject_id = $c->subject_id;
  3988. $course_num = $c->course_num;
  3989. $tcourse_id = $c->course_id;
  3990. if ($bool_transferTest == false)
  3991. {
  3992. // Meaning, we are looking at transfers now.
  3993. // Does the transfer course have an eqv set up? If so,
  3994. // we want *that* course to appear.
  3995. if (is_object($c->course_transfer))
  3996. {
  3997. $subject_id = $c->course_transfer->subject_id;
  3998. $course_num = $c->course_transfer->course_num;
  3999. $tcourse_id = $c->course_transfer->course_id;
  4000. $t_flag = 1;
  4001. }
  4002. }
  4003. $m_hours = $c->get_hours_awarded($req_by_degree_id);
  4004. /*
  4005. *
  4006. * We don't want to do this. What it's saying is if the max_hours (from the course database)
  4007. * is LESS than the awarded hours, use the lower hours. Instead, we want to always use
  4008. * what the student was AWARDED.
  4009. *
  4010. if ($c->max_hours*1 < $m_hours)
  4011. {
  4012. $m_hours = $c->max_hours*1;
  4013. }
  4014. */
  4015. if (($hours_avail*1 > 0 && $hours_avail < $m_hours) || ($m_hours == 0))
  4016. {
  4017. $m_hours = $hours_avail;
  4018. }
  4019. // is max_hours more than the original course's hours?
  4020. if ($m_hours > $c_hours)
  4021. {
  4022. $m_hours = $c_hours;
  4023. }
  4024. if ($m_hours > $c->get_hours_awarded($req_by_degree_id))
  4025. {
  4026. $m_hours = $c->get_hours_awarded($req_by_degree_id);
  4027. }
  4028. // If we have already displayed this EXACT course, then we shouldn't display it again. This is to
  4029. // fix a multi-degree bug, where we see the same course however many times it was split for a DIFFERENT degree.
  4030. // If it's never been split for THIS degree, it should just show up as 1 course.
  4031. $ukey = md5($c->course_id . $c->catalog_year . $c->term_id . $m_hours . $tcourse_id . intval(@$c->db_substitution_id_array[$req_by_degree_id]));
  4032. if (isset($already_seen[$ukey])) {
  4033. continue;
  4034. }
  4035. // Else, add it.
  4036. $already_seen[$ukey] = TRUE;
  4037. // We should also keep up with how many hours have been used by this sub...
  4038. // Is this course NOT a substitution for this degree, and NOT an outdated sub?
  4039. // In other words, are we safe to just display this course as an option for selection?
  4040. if ($c->get_bool_substitution($req_by_degree_id) != TRUE && $c->get_bool_outdated_sub($req_by_degree_id) != TRUE)
  4041. {
  4042. $h = $c->get_hours_awarded($req_by_degree_id);
  4043. if ($c->bool_ghost_hour == TRUE) {
  4044. $h .= "(ghost<a href='javascript: alertSubGhost();'>?</a>)";
  4045. }
  4046. // If this course was split up, we need to use our
  4047. // helper array to see what the OTHER, already-used pieces add up to.
  4048. if ($c->get_bool_substitution_split($req_by_degree_id)) {
  4049. $ukey = md5($c->course_id . $c->catalog_year . $c->term_id . $tcourse_id);
  4050. if (isset($used_hours_subs[$ukey])) {
  4051. $used_hours = $used_hours_subs[$ukey];
  4052. // Get the remaining hours by subtracting the ORIGINAL hours for this course against
  4053. // the used hours.
  4054. // Okay, I believe this is a bug. Somewhere, I have set the hours_awarded to the remaining hours, so
  4055. // this math is no longer needed.
  4056. /*
  4057. $remaining_hours = $c->get_hours_awarded(0) - $used_hours; // (0) gets the original hours awarded.
  4058. if ($remaining_hours > 0) {
  4059. $h = $remaining_hours;
  4060. }*/
  4061. }
  4062. }
  4063. $pC .= "<tr>
  4064. <td valign='top' class=' ' width='15%'>
  4065. <input type='radio' name='subCourse' id='subCourse' value='$tcourse_id'
  4066. onClick='popupUpdateSubData(\"$m_hours\",\"$c->term_id\",\"$t_flag\",\"$hours_avail\",\"" . $c->get_hours_awarded($req_by_degree_id) . "\");'
  4067. ";
  4068. if ($bool_disable_selection) $pC .= "disabled=disabled";
  4069. $pC .= " >";
  4070. if ($disabled_msg) {
  4071. $pC .= fp_get_js_alert_link(fp_reduce_whitespace(str_replace("\n", " ", $disabled_msg)), "?");
  4072. }
  4073. $pC .= "
  4074. </td>
  4075. <td valign='top' class=' underline' width='13%'>
  4076. $subject_id
  4077. </td>
  4078. <td valign='top' class=' underline' width='15%'>
  4079. $course_num
  4080. </td>
  4081. <td valign='top' class=' underline' width='10%'>
  4082. $h
  4083. </td>
  4084. <td valign='top' class=' underline' width='10%'>
  4085. $c->grade
  4086. </td>
  4087. <td valign='top' class=' underline'>
  4088. " . $c->get_term_description(true) . "
  4089. </td>
  4090. </tr>
  4091. ";
  4092. }
  4093. else {
  4094. // Does this course have a substitution for THIS degree?
  4095. if (!is_object($c->get_course_substitution($req_by_degree_id))) {
  4096. continue;
  4097. }
  4098. if (is_object($c->get_course_substitution($req_by_degree_id)) && $c->get_course_substitution($req_by_degree_id)->subject_id == "")
  4099. { // Load subject_id and course_num of the original
  4100. // requirement.
  4101. $c->get_course_substitution($req_by_degree_id)->load_descriptive_data();
  4102. }
  4103. $extra = "";
  4104. //if ($c->assigned_to_group_id > 0)
  4105. if ($c->get_bool_assigned_to_group_id(-1))
  4106. {
  4107. // TODO: based on degree (hint: probably so...?
  4108. $new_group = new Group($c->get_first_assigned_to_group_id());
  4109. $extra = " in $new_group->title";
  4110. }
  4111. if ($c->get_bool_outdated_sub($req_by_degree_id))
  4112. {
  4113. $help_link = fp_get_js_alert_link(t("This substitution is outdated. It was made for a course or group which does not currently appear on the student's degree plan. You may remove this sub using the Administrator's Toolbox, at the bottom of the View tab."), "?");
  4114. $extra .= " <span style='color:red;'>[" . t("Outdated") . "$help_link]</span>";
  4115. }
  4116. // It has already been substituted!
  4117. $pC .= "<tr style='background-color: beige;'>
  4118. <td valign='top' class=' ' width='15%'>
  4119. " . t("Sub:") . "
  4120. </td>
  4121. <td valign='top' class=' ' colspan='5'>
  4122. $subject_id
  4123. $course_num (" . $c->get_substitution_hours($req_by_degree_id) . ")
  4124. -> " . $c->get_course_substitution($req_by_degree_id)->subject_id . "
  4125. " . $c->get_course_substitution($req_by_degree_id)->course_num . "$extra
  4126. </td>
  4127. </tr>
  4128. ";
  4129. // Keep track of how many hours THIS course has been subbed, if it was split.
  4130. $ukey = md5($c->course_id . $c->catalog_year . $c->term_id . $tcourse_id);
  4131. if (!isset($used_hours_subs[$ukey])) $used_hours_subs[$ukey] = 0;
  4132. $used_hours_subs[$ukey] += $c->get_substitution_hours($req_by_degree_id);
  4133. }
  4134. // If this was a transfer course, have an extra line under the course, stating it's title.
  4135. if ($bool_transferTest == FALSE) { // Means this IS INDEED a transfer courses.
  4136. $c->course_transfer->load_descriptive_transfer_data($this->student->student_id, $c->term_id);
  4137. $pC .= "<tr class='advise-substitute-popup-transfer-course-title'>
  4138. <td colspan='8'>
  4139. {$c->course_transfer->title} ({$c->course_transfer->institution_name})
  4140. </td>
  4141. </tr>";
  4142. }
  4143. } // while list_courses_taken
  4144. if ($is_empty == true)
  4145. {
  4146. // Meaning, there were no credits (may be the case with
  4147. // transfer credits)
  4148. $pC .= "<tr><td colspan='8' class=' '>
  4149. - " . t("No substitutable credits available.") . "
  4150. </td></tr>";
  4151. }
  4152. $pC .= "<tr><td colspan='4'>&nbsp;</td></tr>";
  4153. }
  4154. $pC .= "</table></div>
  4155. <div class=' ' style='margin-top: 5px;'>
  4156. " . t("Select number of hrs to use:") . "
  4157. <select name='subHours' id='subHours' onChange='popupOnChangeSubHours()'>
  4158. <option value=''>" . t("None Selected") . "</option>
  4159. </select>
  4160. ";
  4161. // If we have entered manual hours (like for decimals), they go here:
  4162. // The subManual span will *display* them, the hidden field keeps them so they can be transmitted.
  4163. $pC .= "
  4164. <span id='subManual' style='font-style:italic; display:none;'></span>
  4165. <input type='hidden' id='subManualHours' value=''>
  4166. </div>
  4167. <input type='hidden' name='subTransferFlag' id='subTransferFlag' value=''>
  4168. <input type='hidden' name='subTermID' id='subTermID' value=''>
  4169. <input type='button' value='Save Substitution' onClick='popupSaveSubstitution(\"$course_id\",\"$group_id\",\"$semester_num\",\"$req_by_degree_id\");'>
  4170. <div class=' ' style='padding-top: 5px;'><b>" . t("Optional") . "</b> - " . t("Enter remarks:") . "
  4171. <input type='text' name='subRemarks' id='subRemarks' value='' size='30' maxlength='254'>
  4172. </div>
  4173. ";
  4174. return $pC;
  4175. }
  4176. /**
  4177. * This function displays the popup which lets a user select a course to be
  4178. * advised into a group.
  4179. *
  4180. * @param Group $place_group
  4181. * @param int $group_hours_remaining
  4182. * @return string
  4183. */
  4184. function display_popup_group_select(Group $place_group, $group_hours_remaining = 0, $req_by_degree_id = 0)
  4185. {
  4186. $pC = "";
  4187. $advising_term_id = $GLOBALS["fp_advising"]["advising_term_id"];
  4188. if ($req_by_degree_id == 0) {
  4189. $req_by_degree_id = $place_group->req_by_degree_id;
  4190. }
  4191. $bool_no_courses = FALSE;
  4192. if ($place_group->group_id != DegreePlan::GROUP_ID_FOR_COURSES_ADDED)
  4193. {
  4194. // This is NOT the Add a Course group.
  4195. if (!$group = $this->degree_plan->find_group($place_group->group_id))
  4196. {
  4197. fpm("Group not found.");
  4198. return;
  4199. }
  4200. else {
  4201. // Found the group... we don't need to do anything.
  4202. }
  4203. }
  4204. else {
  4205. // This is the Add a Course group.
  4206. $group = $place_group;
  4207. }
  4208. $group_id = $group->group_id;
  4209. // So now we have a group object, $group, which is most likely
  4210. // missing courses. This is because when we loaded & cached it
  4211. // earlier, we did not load any course which wasn't a "significant course,"
  4212. // meaning, the student didn't have credit for it or the like.
  4213. // So what we need to do now is reload the group, being careful
  4214. // to preserve the existing courses / sub groups in the group.
  4215. $group->reload_missing_courses();
  4216. if ($group_hours_remaining == 0)
  4217. {
  4218. // Attempt to figure out the remaining hours (NOT WORKING IN ALL CASES!)
  4219. // This specifically messes up when trying to get fulfilled hours in groups
  4220. // with branches.
  4221. $group_fulfilled_hours = $group->get_fulfilled_hours(true, true, false, $place_group->assigned_to_semester_num);
  4222. $group_hours_remaining = $place_group->hours_required - $group_fulfilled_hours;
  4223. }
  4224. $display_semesterNum = $place_group->assigned_to_semester_num;
  4225. $pC .= "<!--MSG--><!--MSG2--><!--BOXTOP-->";
  4226. $bool_display_submit = true;
  4227. $bool_display_back_to_subject_select = false;
  4228. $bool_subject_select = false;
  4229. $bool_unselectableCourses = false;
  4230. $final_course_list = new CourseList();
  4231. $public_note = fp_trim($group->public_note);
  4232. if ($public_note) {
  4233. $pC .= "<tr><td colspan='8'><div class='group-public-note'>" . $public_note . "</div></td></tr>";
  4234. }
  4235. $group_sort_policy = variable_get_for_school("group_requirement_sort_policy", "alpha", $this->student->school_id);
  4236. $group->list_courses->reset_counter();
  4237. if (!($group->list_courses->is_empty))
  4238. {
  4239. $group->list_courses->assign_semester_num($display_semesterNum);
  4240. $new_course_list = $group->list_courses;
  4241. // Is this list so long that we first need to ask the user to
  4242. // select a subject?
  4243. if ($new_course_list->get_size() > 30)
  4244. {
  4245. // First, we are only going to do this if there are more
  4246. // than 30 courses, AND more than 2 subjects in the list.
  4247. $new_course_list->sort_alphabetical_order();
  4248. $subject_array = $new_course_list->get_course_subjects();
  4249. //print_pre($new_course_list->to_string());
  4250. //var_dump($subject_array);
  4251. if (count($subject_array) > 2)
  4252. {
  4253. // First, check to see if the user has already
  4254. // selected a subject.
  4255. $selected_subject = addslashes(fp_trim(@$_GET["selected_subject"]));
  4256. if ($selected_subject == "")
  4257. {
  4258. // Prompt them to select a subject first.
  4259. $pC .= $this->draw_popup_group_subject_select($subject_array, $group->group_id, $display_semesterNum, $group_hours_remaining, $req_by_degree_id);
  4260. $new_course_list = new CourseList(); // empty it
  4261. $bool_display_submit = false;
  4262. $bool_subject_select = true;
  4263. } else {
  4264. // Reduce the newCourseList to only contain the
  4265. // subjects selected.
  4266. $new_course_list->exclude_all_subjects_except($selected_subject);
  4267. $bool_display_back_to_subject_select = true;
  4268. }
  4269. }
  4270. }
  4271. if ($group_sort_policy == 'database') {
  4272. $new_course_list->sort_group_requirement_id();
  4273. }
  4274. else {
  4275. // By default, sort alphabetical
  4276. $new_course_list->sort_alphabetical_order();
  4277. }
  4278. $new_course_list->reset_counter();
  4279. $final_course_list->add_list($new_course_list);
  4280. }
  4281. if (!($group->list_groups->is_empty))
  4282. {
  4283. // Basically, this means that this group
  4284. // has multiple subgroups. We need to find out
  4285. // which branches the student may select from
  4286. // (based on what they have already taken, or been
  4287. // advised to take), and display it (excluding duplicates).
  4288. //print_pre($group->to_string());
  4289. // The first thing we need to do, is find the subgroup
  4290. // or subgroups with the most # of matches.
  4291. $new_course_list = new CourseList();
  4292. $all_zero= true;
  4293. // Okay, this is a little squirely. What I need to do
  4294. // first is get a course list of all the courses which
  4295. // are currently either fulfilling or advised for all branches
  4296. // of this group.
  4297. $fa_course_list = new CourseList();
  4298. $group->list_groups->reset_counter();
  4299. while($group->list_groups->has_more())
  4300. {
  4301. $branch = $group->list_groups->get_next();
  4302. $fa_course_list->add_list($branch->list_courses->get_fulfilled_or_advised(true));
  4303. }
  4304. $fa_course_list->remove_duplicates();
  4305. //print_pre($fa_course_list->to_string());
  4306. // Alright, now we create a fake student and set their
  4307. // list_courses_taken, so that we can use this student
  4308. // to recalculate the count_of_matches in just a moment.
  4309. $new_student = new Student();
  4310. $new_student->load_student();
  4311. $new_student->list_courses_taken = $fa_course_list;
  4312. $new_student->load_significant_courses_from_list_courses_taken();
  4313. // Okay, now we need to go through and re-calculate our
  4314. // count_of_matches for each branch. This is because we
  4315. // have cached this value, and after some advisings, it may
  4316. // not be true any longer.
  4317. $highest_match_count = 0;
  4318. $group->list_groups->reset_counter();
  4319. while($group->list_groups->has_more())
  4320. {
  4321. $branch = $group->list_groups->get_next();
  4322. // recalculate count_of_matches here.
  4323. $clone_branch = new Group();
  4324. $clone_branch->list_courses = $branch->list_courses->get_clone(true);
  4325. $matches_count = $this->flightpath->get_count_of_matches($clone_branch, $new_student, $group);
  4326. $branch->count_of_matches = $matches_count;
  4327. if ($matches_count >= $highest_match_count)
  4328. { // Has more than one match on this branch.
  4329. $highest_match_count = $matches_count;
  4330. }
  4331. }
  4332. // If highestMatchCount > 0, then get all the branches
  4333. // which have that same match count.
  4334. if ($highest_match_count > 0)
  4335. {
  4336. $group->list_groups->reset_counter();
  4337. while($group->list_groups->has_more())
  4338. {
  4339. $branch = $group->list_groups->get_next();
  4340. if ($branch->count_of_matches == $highest_match_count)
  4341. { // This branch has the right number of matches. Add it.
  4342. $new_course_list->add_list($branch->list_courses);
  4343. $all_zero = false;
  4344. }
  4345. }
  4346. }
  4347. if ($all_zero == true)
  4348. {
  4349. // Meaning, all of the branches had 0 matches,
  4350. // so we should add all the branches to the
  4351. // newCourseList.
  4352. $group->list_groups->reset_counter();
  4353. while($group->list_groups->has_more())
  4354. {
  4355. $branch = $group->list_groups->get_next();
  4356. $new_course_list->add_list($branch->list_courses);
  4357. }
  4358. } else {
  4359. // Meaning that at at least one branch is favored.
  4360. // This also means that a user's course
  4361. // selections have been restricted as a result.
  4362. // Replace the MSG at the top saying so.
  4363. $msg = "<div class=' '>" . t("Your selection of courses has been
  4364. restricted based on previous course selections.") . "</div>";
  4365. $pC = str_replace("<!--MSG-->", $msg, $pC);
  4366. }
  4367. // Okay, in the newCourseList object, we should
  4368. // now have a list of all the courses the student is
  4369. // allowed to take, but there are probably duplicates.
  4370. //print_pre($new_course_list->to_string());
  4371. $new_course_list->remove_duplicates();
  4372. $new_course_list->assign_group_id($group->group_id);
  4373. $new_course_list->assign_semester_num($display_semesterNum);
  4374. $final_course_list->add_list($new_course_list);
  4375. }
  4376. // Remove courses which have been marked as "exclude" in the database.
  4377. $final_course_list->remove_excluded();
  4378. $final_course_list->assign_group_id($group->group_id); // make sure everyone is in THIS group.
  4379. //print_pre($final_course_list->to_string());
  4380. // Here's a fun one: We need to remove courses for which the student
  4381. // already has credit that *don't* have repeating hours.
  4382. // For example, if a student took MATH 113, and it fills in to
  4383. // Core Math, then we should not see it as a choice for advising
  4384. // in Free Electives (or any other group except Add a Course).
  4385. // We also should not see it in other instances of Core Math.
  4386. if ($group->group_id != DegreePlan::SEMESTER_NUM_FOR_COURSES_ADDED && $this->bool_blank != TRUE)
  4387. {
  4388. // Only do this if NOT in Add a Course group...
  4389. // also, don't do it if we're looking at a "blank" degree.
  4390. $final_course_list->remove_previously_fulfilled($this->student->list_courses_taken, $group->group_id, true, $this->student->list_substitutions, $req_by_degree_id);
  4391. }
  4392. if ($group_sort_policy == 'database') {
  4393. $final_course_list->sort_group_requirement_id();
  4394. }
  4395. else {
  4396. // By default, sort alphabetical
  4397. $final_course_list->sort_alphabetical_order();
  4398. }
  4399. // flag any courses with more hours than are available for this group.
  4400. if ($final_course_list->assign_unselectable_courses_with_hours_greater_than($group_hours_remaining))
  4401. {
  4402. $bool_unselectableCourses = true;
  4403. }
  4404. // Make sure all the courses in our final list have the same req_by_degree_id.
  4405. $final_course_list->set_req_by_degree_id($req_by_degree_id);
  4406. $pC .= $this->display_popup_group_select_course_list($final_course_list, $group_hours_remaining);
  4407. // If there were no courses in the finalCourseList, display a message.
  4408. if (count($final_course_list->array_list) < 1 && !$bool_subject_select)
  4409. {
  4410. $pC .= "<tr>
  4411. <td colspan='8'>
  4412. <div class=' '>
  4413. <b>Please Note:</b>
  4414. " . t("FlightPath could not find any eligible
  4415. courses to display for this list. Ask your advisor
  4416. if you have completed courses, or may enroll in
  4417. courses, which can be
  4418. displayed here.");
  4419. if (user_has_permission("can_advise_students")){
  4420. // This is an advisor, so put in a little more
  4421. // information.
  4422. $pC .= "
  4423. <div class=' ' style='padding-top: 5px;'><b>" . t("Special note to advisors:") . "</b> " . t("You may still
  4424. advise a student to take a course, even if it is unselectable
  4425. in this list. Use the \"add an additional course\" link at
  4426. the bottom of the page.") . "</div>";
  4427. }
  4428. $pC .= " </div>
  4429. </td>
  4430. </tr>";
  4431. $bool_no_courses = true;
  4432. }
  4433. $pC .= $this->draw_semester_box_bottom();
  4434. $s = "s";
  4435. //print_pre($place_group->to_string());
  4436. $unselectable_notice = "";
  4437. if ($group_hours_remaining == 1){$s = "";}
  4438. if ($bool_unselectableCourses == true) {
  4439. $unselectable_notice = " <div class=' '><i>(" . t("Courses worth more than %hrs hour$s
  4440. may not be selected.", array("%hrs" => $group_hours_remaining)) . ")</i></div>";
  4441. if (user_has_permission("can_advise_students")) {
  4442. // This is an advisor, so put in a little more
  4443. // information.
  4444. $unselectable_notice .= "
  4445. <div class=' ' style='padding-top: 5px;'><b>" . t("Special note to advisors:") . "</b> " . t("You may still
  4446. advise a student to take a course, even if it is unselectable
  4447. in this list. Use the \"add an additional course\" link at
  4448. the bottom of the page.") . "</div>";
  4449. }
  4450. }
  4451. if ($group_hours_remaining < 200 && $bool_no_courses != true) {
  4452. $disp_group_hours_remaining = $group_hours_remaining;
  4453. // If we have min_hours, display that information.
  4454. if ($place_group->has_min_hours_allowed()) {
  4455. // Make sure the "real" group has the same min hours set.
  4456. $group->min_hours_allowed = $place_group->min_hours_allowed;
  4457. }
  4458. if ($group->has_min_hours_allowed()) {
  4459. $g_fulfilled_hours = $group->hours_required - $group_hours_remaining; // How many have we actually used?
  4460. $d_min_hours = $group->min_hours_allowed - $g_fulfilled_hours; // min hours must be reduced by the number already assigned
  4461. $disp_group_hours_remaining = $d_min_hours . "-" . $group_hours_remaining;
  4462. }
  4463. // Don't show for huge groups (like add-a-course)
  4464. $pC .= "<div class=' ' style='margin-top:5px;'>
  4465. " . t("You may select <b>@hrs</b>
  4466. hour$s from this list.", array("@hrs" => $disp_group_hours_remaining)) . "$unselectable_notice</div>";
  4467. }
  4468. ////////////////////////////////
  4469. // TODO: Conditions on which this will even appear? Like only if the student has more than one degree selected?
  4470. // What degrees is this group req by?
  4471. $t_degree_plan = new DegreePlan();
  4472. $t_degree_plan->degree_id = $req_by_degree_id;
  4473. $t = $t_degree_plan->get_title2(FALSE, TRUE);
  4474. if (trim($t) != "") {
  4475. $pC .= "<div class=' group-select-req-by-degree'>
  4476. " . t("This group is required by ");
  4477. $html = "";
  4478. $html .= "<span class='group-req-by-degree-title'>" . $t . "</span>";
  4479. $pC .= "$html</div>";
  4480. }
  4481. /////////////////////////////
  4482. if ($bool_display_submit == true && !$this->bool_blank && $bool_no_courses != true)
  4483. {
  4484. if (user_has_permission("can_advise_students")) {
  4485. $pC .= "<input type='hidden' name='varHours' id='varHours' value=''>
  4486. <div style='margin-top: 20px;'>
  4487. " . fp_render_button(t("Select Course"), "popupAssignSelectedCourseToGroup(\"$place_group->assigned_to_semester_num\", \"$group->group_id\",\"$advising_term_id\",\"-1\");", true, "style='font-size: 10pt;'") . "
  4488. </div>
  4489. ";
  4490. }
  4491. }
  4492. // Substitutors get extra information:
  4493. if (user_has_permission("can_substitute") && $group->group_id != DegreePlan::GROUP_ID_FOR_COURSES_ADDED)
  4494. {
  4495. $pC .= "<div class=' ' style='margin-top: 20px;'>
  4496. <b>" . t("Special administrative information:") . "</b>
  4497. <span id='viewinfolink'
  4498. onClick='document.getElementById(\"admin_info\").style.display=\"\"; this.style.display=\"none\"; '
  4499. class='hand' style='color: blue;'
  4500. > - " . t("Click to show") . " -</span>
  4501. <div style='padding-left: 20px; display:none;' id='admin_info'>
  4502. " . t("Information about this group:") . "<br>
  4503. &nbsp; " . t("Group ID:") . " $group->group_id<br>
  4504. &nbsp; " . t("Title:") . " $group->title<br>";
  4505. $pC .= "&nbsp; <i>" . t("Internal name:") . " $group->group_name</i><br>";
  4506. $pC .= "&nbsp; " . t("Catalog year:") . " $group->catalog_year
  4507. </div>
  4508. </div>";
  4509. }
  4510. if ($bool_display_back_to_subject_select == true) {
  4511. $csid = $GLOBALS["current_student_id"];
  4512. $blank_degree_id = "";
  4513. if ($this->bool_blank)
  4514. {
  4515. $blank_degree_id = $this->degree_plan->degree_id;
  4516. }
  4517. $back_link = "<span class=' '>
  4518. <a href='" . fp_url("advise/popup-group-select", "window_mode=popup&group_id=$group->group_id&semester_num=$display_semesterNum&group_hours_remaining=$group_hours_remaining&current_student_id=$csid&blank_degree_id=$blank_degree_id") . "'
  4519. class='nounderline'>&laquo; " . t("return to subject selection") . "</a></span>";
  4520. $pC = str_replace("<!--MSG2-->",$back_link,$pC);
  4521. }
  4522. $box_top = $this->draw_semester_box_top("$group->title", !$bool_display_submit);
  4523. $pC = str_replace("<!--BOXTOP-->",$box_top,$pC);
  4524. watchdog("advise", "popup_group_select id:$group->group_id, name:$group->group_name, semester_num:$display_semesterNum", array(), WATCHDOG_DEBUG);
  4525. return $pC;
  4526. }
  4527. /**
  4528. * When the groupSelect has too many courses, they are broken down into
  4529. * subjects, and the user first selects a subject. This function will
  4530. * draw out that select list.
  4531. *
  4532. * @param array $subject_array
  4533. * @param int $group_id
  4534. * @param int $semester_num
  4535. * @param int $group_hours_remaining
  4536. * @return string
  4537. */
  4538. function draw_popup_group_subject_select($subject_array, $group_id, $semester_num, $group_hours_remaining = 0, $req_by_degree_id = 0)
  4539. {
  4540. $csid = $GLOBALS["current_student_id"];
  4541. $blank_degree_id = "";
  4542. if ($this->bool_blank)
  4543. {
  4544. $blank_degree_id = $this->degree_plan->degree_id;
  4545. }
  4546. $db = get_global_database_handler();
  4547. $school_id = db_get_school_id_for_student_id($this->student->student_id);
  4548. $pC = "";
  4549. $clean_urls = variable_get("clean_urls", FALSE);
  4550. $pC .= "<tr><td colspan='8' class=' '>";
  4551. $pC .= "<form action='" . fp_url("advise/popup-group-select") . "' method='GET' style='margin:0px; padding:0px;' id='theform'>
  4552. <input type='hidden' name='window_mode' value='popup'>
  4553. <input type='hidden' name='group_id' value='$group_id'>";
  4554. if (!$clean_urls) {
  4555. // Hack so that non-clean URLs sites still work
  4556. $pC .= "<input type='hidden' name='q' value='advise/popup-group-select'>";
  4557. }
  4558. $pC .= "
  4559. <input type='hidden' name='semester_num' value='$semester_num'>
  4560. <input type='hidden' name='group_hours_remaining' value='$group_hours_remaining'>
  4561. <input type='hidden' name='current_student_id' value='$csid'>
  4562. <input type='hidden' name='blank_degree_id' value='$blank_degree_id'>
  4563. <input type='hidden' name='req_by_degree_id' value='$req_by_degree_id'>
  4564. " . t("Please begin by selecting a subject from the list below.") . "
  4565. <br><br>
  4566. <select name='selected_subject'>
  4567. <option value=''>" . t("Please select a subject...") . "</option>
  4568. <option value=''>----------------------------------------</option>
  4569. ";
  4570. $new_array = array();
  4571. foreach($subject_array as $key => $subject_id)
  4572. {
  4573. if ($title = $this->flightpath->get_subject_title($subject_id, $school_id)) {
  4574. $new_array[] = "$title ~~ $subject_id";
  4575. } else {
  4576. $new_array[] = "$subject_id ~~ $subject_id";
  4577. }
  4578. }
  4579. sort($new_array);
  4580. foreach ($new_array as $key => $value)
  4581. {
  4582. $temp = explode(" ~~ ",$value);
  4583. $title = trim($temp[0]);
  4584. $subject_id = trim($temp[1]);
  4585. $pC .= "<option value='$subject_id'>$title ($subject_id)</option>";
  4586. }
  4587. $pC .= "</select>
  4588. <div style='margin: 20px;' align='left'>
  4589. " . fp_render_button(t("Next") . " ->","document.getElementById(\"theform\").submit();") . "
  4590. </div>
  4591. <!-- <input type='submit' value='submit'> -->
  4592. </form>
  4593. ";
  4594. $pC .= "</td></tr>";
  4595. return $pC;
  4596. }
  4597. /**
  4598. * Accepts a CourseList object and draws it out to the screen. Meant to
  4599. * be called by display_popup_group_select();
  4600. *
  4601. * @param CourseList $course_list
  4602. * @param int $group_hours_remaining
  4603. * @return string
  4604. */
  4605. function display_popup_group_select_course_list(CourseList $course_list = null, $group_hours_remaining = 0)
  4606. {
  4607. // Accepts a CourseList object and draws it out to the screen. Meant to
  4608. // be called by display_popup_group_select().
  4609. $rtn = "";
  4610. if ($course_list == null)
  4611. {
  4612. return;
  4613. }
  4614. $old_course = null;
  4615. $bool_has_recommended = FALSE;
  4616. $course_list->reset_counter();
  4617. while($course_list->has_more())
  4618. {
  4619. $course = $course_list->get_next();
  4620. if ($course->equals($old_course))
  4621. { // don't display the same course twice in a row.
  4622. continue;
  4623. }
  4624. if ($course->db_group_attributes == "*") {
  4625. $bool_has_recommended = TRUE;
  4626. }
  4627. $rtn .= "<tr><td colspan='8'>";
  4628. // Only display this course for advising IF it hasn't been fulfilled, or if it has infinite repeats, and only if it isn't already
  4629. // advised to be taken.
  4630. if (($course->course_list_fulfilled_by->is_empty || $course->specified_repeats == Group::GROUP_COURSE_INFINITE_REPEATS) && !$course->bool_advised_to_take ){
  4631. // So, only display if it has not been fulfilled by anything.
  4632. $rtn .= $this->draw_popup_group_select_course_row($course, $group_hours_remaining);
  4633. $old_course = $course;
  4634. }
  4635. $rtn .= "</td></tr>";
  4636. }
  4637. if ($bool_has_recommended) {
  4638. $rtn .= "<tr><td colspan='8'><span class='group-recommended-message'>" . t("<b>Note:</b> Courses in <strong>bold</strong> are recommended.") . "</span></td></tr>";
  4639. }
  4640. return $rtn;
  4641. }
  4642. /**
  4643. * Returns a list of "hidden" HTML input tags which are used to keep
  4644. * track of advising variables between page loads.
  4645. *
  4646. * @param string $perform_action
  4647. * - Used for when we submit the form, so that FlightPath will
  4648. * know what action we are trying to take.
  4649. *
  4650. * @return string
  4651. */
  4652. function get_hidden_advising_variables($perform_action = "")
  4653. {
  4654. $school_id = db_get_school_id_for_student_id($GLOBALS["fp_advising"]["current_student_id"]);
  4655. $rtn = "";
  4656. if (!isset($GLOBALS["print_view"])) $GLOBALS["print_view"] = "";
  4657. $rtn .= "<span id='hidden_elements'>
  4658. <input type='hidden' name='perform_action' id='perform_action' value='$perform_action'>
  4659. <input type='hidden' name='perform_action2' id='perform_action2' value=''>
  4660. <input type='hidden' name='scroll_top' id='scroll_top' value=''>
  4661. <input type='hidden' name='load_from_cache' id='load_from_cache' value='yes'>
  4662. <input type='hidden' name='print_view' id='print_view' value='{$GLOBALS["print_view"]}'>
  4663. <input type='hidden' name='hide_charts' id='hide_charts' value=''>
  4664. <input type='hidden' name='advising_load_active' id='advising_load_active' value='{$GLOBALS["fp_advising"]["advising_load_active"]}'>
  4665. <input type='hidden' name='advising_student_id' id='advising_student_id' value='{$GLOBALS["fp_advising"]["advising_student_id"]}'>
  4666. <input type='hidden' name='advising_term_id' id='advising_term_id' value='{$GLOBALS["fp_advising"]["advising_term_id"]}'>
  4667. <input type='hidden' name='advising_major_code' id='advising_major_code' value='{$GLOBALS["fp_advising"]["advising_major_code"]}'>
  4668. <input type='hidden' name='advising_track_degree_ids' id='advising_track_degree_ids' value='{$GLOBALS["fp_advising"]["advising_track_degree_ids"]}'>
  4669. <input type='hidden' name='advising_update_student_settings_flag' id='advising_update_student_settings_flag' value=''>
  4670. <input type='hidden' name='advising_what_if' id='advising_what_if' value='{$GLOBALS["fp_advising"]["advising_what_if"]}'>
  4671. <input type='hidden' name='what_if_major_code' id='what_if_major_code' value='{$GLOBALS["fp_advising"]["what_if_major_code"]}'>
  4672. <input type='hidden' name='what_if_catalog_year' id='what_if_catalog_year' value='{$GLOBALS["fp_advising"]["what_if_catalog_year"]}'>
  4673. <input type='hidden' name='what_if_track_degree_ids' id='what_if_track_degree_ids' value='{$GLOBALS["fp_advising"]["what_if_track_degree_ids"]}'>
  4674. <input type='hidden' name='advising_view' id='advising_view' value='{$GLOBALS["fp_advising"]["advising_view"]}'>
  4675. <input type='hidden' name='current_student_id' id='current_student_id' value='{$GLOBALS["fp_advising"]["current_student_id"]}'>
  4676. <input type='hidden' name='log_addition' id='log_addition' value=''>
  4677. <input type='hidden' name='fp_update_user_settings_flag' id='fp_update_user_settings_flag' value=''>
  4678. <input type='hidden' name='advising_update_student_degrees_flag' id='advising_update_student_degrees_flag' value=''>
  4679. <input type='hidden' name='reinit_fp_after_draft_save' id='reinit_fp_after_draft_save' value='no'>
  4680. </span>
  4681. ";
  4682. return $rtn;
  4683. }
  4684. }

Classes

Namesort descending Description
AdvisingScreen