_AdvisingScreen.php

Classes

NameDescription
_AdvisingScreen

File

classes/_AdvisingScreen.php
View source
  1. <?php
  2. class _AdvisingScreen
  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, $settings, $user_settings;
  7. public $bool_blank, $bool_hiding_grades;
  8. public $admin_message, $earliest_catalog_year;
  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, $page_is_mobile;
  12. public $page_title, $page_extra_css_files, $page_body_classes;
  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. $this->degree_plan = $flightpath->degree_plan;
  41. $this->student = $flightpath->student;
  42. $this->db = get_global_database_handler();
  43. if ($screen_mode == "popup")
  44. {
  45. $this->bool_popup = true;
  46. }
  47. $this->bool_blank = false;
  48. $this->screen_mode = $screen_mode;
  49. //$this->settings = $this->db->get_flightpath_settings();
  50. $this->earliest_catalog_year = $GLOBALS["fp_system_settings"]["earliest_catalog_year"];
  51. $this->determine_mobile_device();
  52. }
  53. /**
  54. * This function will attempt to determine automatically
  55. * if we are on a mobile device. If so, it will set
  56. * $this->page_is_mobile = TRUE
  57. *
  58. */
  59. function determine_mobile_device(){
  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. // This method will output the screen to the browser.
  207. // outputs the $page_content variable.
  208. $page_content = $this->page_content;
  209. $page_tabs = $this->page_tabs;
  210. $page_has_search = $this->page_has_search;
  211. $page_on_load = $this->page_on_load;
  212. $page_scroll_top = $this->page_scroll_top;
  213. $page_is_popup = $this->page_is_popup;
  214. $page_title = $this->page_title;
  215. $page_body_classes = $this->page_body_classes;
  216. if ($page_title == "") {
  217. // By default, page title is this...
  218. $page_title = $GLOBALS["fp_system_settings"]["school_initials"] . " FlightPath";
  219. }
  220. $page_hide_report_error = $this->page_hide_report_error;
  221. $print_option = "";
  222. if ($this->bool_print == true) {
  223. $print_option = "print_";
  224. }
  225. if ($this->page_is_mobile == true) {
  226. $print_option = "mobile_";
  227. }
  228. // Add extra JS files.
  229. if (is_array($GLOBALS["fp_extra_js"]) && count($GLOBALS["fp_extra_js"]) > 0) {
  230. foreach ($GLOBALS["fp_extra_js"] as $js_file_name) {
  231. $page_extra_js_files .= "<script type='text/javascript' src='$js_file_name'></script> \n";
  232. }
  233. }
  234. // Load any extra CSS files which addon modules might have added.
  235. if (is_array($GLOBALS["fp_extra_css"]) && count($GLOBALS["fp_extra_css"]) > 0) {
  236. foreach ($GLOBALS["fp_extra_css"] as $css_file_name) {
  237. $page_extra_css_files .= "<link rel='stylesheet' type='text/css' href='$css_file_name'>";
  238. }
  239. }
  240. // Javascript settings...
  241. $page_extra_js_settings .= "var FlightPath = new Object(); \n";
  242. $page_extra_js_settings .= " FlightPath.settings = new Object(); \n";
  243. foreach ($GLOBALS["fp_extra_js_settings"] as $key => $val) {
  244. $page_extra_js_settings .= "FlightPath.settings.$key = '$val'; \n";
  245. }
  246. // Scrolling somewhere? Add it to the page_on_load...
  247. if (trim($page_scroll_top != "")) {
  248. $page_on_load .= " scrollTo(0, $page_scroll_top);";
  249. }
  250. // Add in our hidden divs which we will sometimes display...
  251. $page_content .= "<div id='updateMsg' class='updateMsg' style='display: none;'>" . t("Updating...") . "</div>
  252. <div id='loadMsg' class='updateMsg' style='display: none;'>" . t("Loading...") . "</div>";
  253. include($GLOBALS["fp_system_settings"]["theme"] . "/fp_" . $print_option . "template.php");
  254. }
  255. /**
  256. * This function simply adds a reference for additional CSS to be
  257. * link'd in to the theme. It is used by add-on modules.
  258. *
  259. * The filename needs to be from the reference of the base
  260. * FlightPath install.
  261. *
  262. * Ex: $screen->add_css("modules/course_search/css/style.css");
  263. *
  264. * @param String $filename
  265. */
  266. function add_css($filename) {
  267. $this->page_extra_css_files[] = $filename;
  268. }
  269. /**
  270. * Converts a string containing BBCode to the equivalent HTML.
  271. *
  272. * @param string $str
  273. * @return string
  274. */
  275. function z__convert_bbcode_to_html($str)
  276. {
  277. // This will accept a string with BBcode tags in it,
  278. // and convert them to HTML tags.
  279. $str = str_replace("[b]","<b>",$str);
  280. $str = str_replace("[/b]","</b>",$str);
  281. $str = str_replace("[i]","<i>",$str);
  282. $str = str_replace("[/i]","</i>",$str);
  283. $str = str_replace("[u]","<u>",$str);
  284. $str = str_replace("[/u]","</u>",$str);
  285. $str = str_replace("[center]","<center>",$str);
  286. $str = str_replace("[/center]","</center>",$str);
  287. $str = str_replace("[ul]","<ul>",$str);
  288. $str = str_replace("[/ul]","</ul>",$str);
  289. $str = str_replace("[li]","<li>",$str);
  290. $str = str_replace("[/li]","</li>",$str);
  291. $str = str_replace("[br]","<br>",$str);
  292. // convert more than 1 space into 2 hard spaces...
  293. $str = str_replace(" ","&nbsp;&nbsp;",$str);
  294. // Check for colored text
  295. $str = preg_replace("(\[color=(.+?)\](.+?)\[\/color\])is","<span style='color:$1;'>$2</span>",$str);
  296. // valid URL characters...
  297. $url_search_string = " a-zA-Z0-9\:\/\-\?\&\.\=\_\~\#\'";
  298. // Check for a link...
  299. $str = preg_replace("(\[url\=([$url_search_string]*)\](.+?)\[/url\])", "<a href='$1' target='_blank' class='nounderline'>$2</a>", $str);
  300. // check for a link that does NOT load in a new window (URL2)
  301. $str = preg_replace("(\[url2\=([$url_search_string]*)\](.+?)\[/url2\])", "<a href='$1'>$2</a>", $str);
  302. // check for a link to a popup....
  303. $str = preg_replace("(\[popup\=([$url_search_string]*)\](.+?)\[/popup\])", "<a href='javascript: popupHelpWindow(\"$1\");' class='nounderline'>$2</a>", $str);
  304. // Images... (looks like: [img]http://www.image.jpg[/img]
  305. //$str = preg_replace("(\[img\]([$url_search_string]*)\](.+?)\[/img\])", "<img src='$1' border='0'>", $str);
  306. // Images
  307. // [img]pathtoimage[/img]
  308. $str = preg_replace("/\[img\](.+?)\[\/img\]/", "<img src='$1' border='0'>", $str);
  309. // [img=widthxheight]image source[/img]
  310. $str = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.+?)\[\/img\]/", "<img src='$3' width='$1' height='$2' border='0'>", $str);
  311. return $str;
  312. }
  313. /**
  314. * Clear the session varibles.
  315. *
  316. */
  317. function clear_variables()
  318. {
  319. // Clear the session variables.
  320. $csid = $_REQUEST["current_student_id"];
  321. $_SESSION["advising_student_id$csid"] = "";
  322. $_SESSION["advising_student_id"] = "";
  323. $_SESSION["advising_major_code$csid"] = "";
  324. $_SESSION["advising_track_code$csid"] = "";
  325. $_SESSION["advising_term_id$csid"] = "";
  326. $_SESSION["advising_what_if$csid"] = "";
  327. $_SESSION["what_if_major_code$csid"] = "";
  328. $_SESSION["cache_f_p$csid"] = "";
  329. $_SESSION["cache_what_if$csid"] = "";
  330. }
  331. /**
  332. * Constructs the HTML which will be used to display
  333. * the student's transfer credits
  334. *
  335. */
  336. function build_transfer_credit()
  337. {
  338. $pC = "";
  339. $is_empty = true;
  340. $pC .= $this->draw_semester_box_top("Transfer Credit", true);
  341. // Basically, go through all the courses the student has taken,
  342. // And only show the transfers. This is similar to Excess credit.
  343. $this->student->list_courses_taken->sort_alphabetical_order(false, true);
  344. $this->student->list_courses_taken->reset_counter();
  345. while($this->student->list_courses_taken->has_more())
  346. {
  347. $course = $this->student->list_courses_taken->get_next();
  348. // Skip non transfer credits.
  349. if ($course->bool_transfer != true)
  350. {
  351. continue;
  352. }
  353. $bool_add_footnote = false;
  354. if ($course->bool_has_been_displayed == true)
  355. { // Show the footnote if this has already been displayed
  356. // elsewhere on the page.
  357. $bool_add_footnote = true;
  358. }
  359. $pC .= $this->draw_course_row($course,"","",false,false,$bool_add_footnote,true);
  360. $is_empty = false;
  361. }
  362. if ($GLOBALS["advising_course_has_asterisk"] == true)
  363. {
  364. $pC .= "<tr>
  365. <td colspan='10'>
  366. <div class='tenpt' style='margin-top: 10px; padding: 3px;'>
  367. <b>*</b> Courses marked with an asterisk (*) have
  368. equivalencies at {$GLOBALS["fp_system_settings"]["school_initials"]}.
  369. Click on the course for more
  370. details.
  371. </div>
  372. </td>
  373. </tr>
  374. ";
  375. }
  376. $pC .= $this->draw_semester_box_bottom();
  377. if (!$is_empty)
  378. {
  379. $this->add_to_screen($pC);
  380. }
  381. }
  382. /**
  383. * Constructs the HTML to show which courses have been added
  384. * by an advisor.
  385. *
  386. */
  387. function build_added_courses()
  388. {
  389. $pC = "";
  390. $semester = new Semester(-88);
  391. if ($new_semester = $this->degree_plan->list_semesters->find_match($semester))
  392. {
  393. $this->add_to_screen($this->display_semester($new_semester));
  394. }
  395. }
  396. /**
  397. * Constructs the HTML to show the Excess Credits list.
  398. *
  399. */
  400. function build_excess_credit()
  401. {
  402. $pC = "";
  403. $pC .= $this->draw_semester_box_top(t("Excess Credits"));
  404. $is_empty = true;
  405. // Basically, go through all the courses the student has taken,
  406. // selecting out the ones that are not fulfilling any
  407. // requirements.
  408. $this->student->list_courses_taken->sort_alphabetical_order();
  409. $this->student->list_courses_taken->reset_counter();
  410. while($this->student->list_courses_taken->has_more())
  411. {
  412. $course = $this->student->list_courses_taken->get_next();
  413. if ($course->bool_has_been_displayed == true)
  414. { // Skip ones which have been assigned to groups or semesters.
  415. continue;
  416. }
  417. // Skip transfer credits.
  418. if ($course->bool_transfer == true)
  419. {
  420. continue;
  421. }
  422. // Skip substitutions
  423. if ($course->bool_substitution == true)
  424. {
  425. continue;
  426. }
  427. $pC .= $this->draw_course_row($course,"","",false,false);
  428. $is_empty = false;
  429. }
  430. $pC .= $this->draw_semester_box_bottom();
  431. if (!$is_empty)
  432. {
  433. $this->add_to_screen($pC);
  434. }
  435. }
  436. /**
  437. * Constructs the HTML which will show footnotes for substitutions
  438. * and transfer credits.
  439. *
  440. */
  441. function build_footnotes($bool_include_box_top = TRUE)
  442. {
  443. // Display the footnotes & messages.
  444. $pC = "";
  445. $is_empty = true;
  446. if ($bool_include_box_top) {
  447. $pC .= $this->draw_semester_box_top(t("Footnotes & Messages"), true);
  448. }
  449. $pC .= "<tr><td colspan='8' class='tenpt'>
  450. ";
  451. $fn_type_array = array("substitution","transfer");
  452. $fn_char = array("substitution" => "S", "transfer"=>"T");
  453. $fn_name = array("substitution" => t("Substitutions"),
  454. "transfer" => t("Transfer Equivalency Footnotes"));
  455. $fn_between = array("substitution" => t("for"),
  456. "transfer" => t("for") . " {$GLOBALS["fp_system_settings"]["school_initials"]}'s");
  457. for ($xx = 0; $xx <= 1; $xx++)
  458. {
  459. $fn_type = $fn_type_array[$xx];
  460. if (count($this->footnote_array[$fn_type]) < 1)
  461. {
  462. continue;
  463. }
  464. $pC .= "<div style='padding-bottom: 10px;'>
  465. <b>{$fn_name[$fn_type]}</b>";
  466. $is_empty = false;
  467. for ($t = 1; $t <= count($this->footnote_array[$fn_type]); $t++)
  468. {
  469. $line = $this->footnote_array[$fn_type][$t];
  470. if ($line == "")
  471. {
  472. continue;
  473. }
  474. $extra = ".";
  475. $temp = explode(" ~~ ", $line);
  476. $o_course = trim($temp[0]);
  477. $new_course = trim($temp[1]);
  478. $using_hours = trim($temp[2]);
  479. if ($using_hours != "")
  480. {
  481. $using_hours = "($using_hours hrs)";
  482. }
  483. $in_group = trim($temp[3]);
  484. $fbetween = $fn_between[$fn_type];
  485. if ($in_group > 0 && $fn_type=="substitution")
  486. {
  487. $new_group = new Group();
  488. $new_group->group_id = $in_group;
  489. $new_group->load_descriptive_data();
  490. $extra = "<div style='padding-left:45px;'><i>" . t("in") . " $new_group->title.</i></div>";
  491. if ($new_course == $o_course || $o_course == "")
  492. {
  493. $o_course = t("was added");
  494. $fbetween = "";
  495. $extra = str_replace("<i>" . t("in"), "<i>" . t("to"), $extra);
  496. }
  497. }
  498. $pC .= "<div class='tenpt'>&nbsp; &nbsp;
  499. <sup>{$fn_char[$fn_type]}$t</sup>
  500. $new_course $using_hours $fbetween $o_course$extra</div>";
  501. }
  502. $pC .= "</div>";
  503. }
  504. ////////////////////////////////////
  505. //// Moved Courses...
  506. $m_is_empty = true;
  507. $pC .= "<!--MOVEDCOURSES-->";
  508. $this->student->list_courses_taken->sort_alphabetical_order();
  509. $this->student->list_courses_taken->reset_counter();
  510. while($this->student->list_courses_taken->has_more())
  511. {
  512. $c = $this->student->list_courses_taken->get_next();
  513. // Skip courses which haven't had anything moved.
  514. if ($c->group_list_unassigned->is_empty == true)
  515. { continue; }
  516. if ($c->course_id > 0)
  517. { $c->load_descriptive_data(); }
  518. $l_s_i = $c->subject_id;
  519. $l_c_n = $c->course_num;
  520. $l_term = $c->get_term_description(true);
  521. $pC .= "<div class='tenpt' style='padding-left: 10px; padding-bottom: 5px;'>
  522. $l_s_i $l_c_n ($c->hours_awarded " . t("hrs") . ") - $c->grade - $l_term
  523. ";
  524. $c->group_list_unassigned->reset_counter();
  525. while($c->group_list_unassigned->has_more())
  526. {
  527. $group = $c->group_list_unassigned->get_next();
  528. $group->load_descriptive_data();
  529. $group_title = "";
  530. if ($group->group_id > 0)
  531. {
  532. $group_title = "<i>$group->title</i>";
  533. } else {
  534. $group_title = t("the degree plan");
  535. }
  536. $pC .= t("was removed from") . " $group_title.";
  537. }
  538. $pC .= "</div>";
  539. $m_is_empty = false;
  540. $is_empty = false;
  541. }
  542. if ($m_is_empty == false)
  543. {
  544. $mtitle = "<div style='padding-bottom: 10px;'>
  545. <div style='padding-bottom: 5px;'>
  546. <b>" . t("Moved Courses") . "</b><br>
  547. " . t("Some courses have been moved out of their
  548. original positions on your degree plan.") . "</div>";
  549. $pC = str_replace("<!--MOVEDCOURSES-->",$mtitle,$pC);
  550. $pC .= "</div>";
  551. }
  552. // For admins only....
  553. if (user_has_permission("can_substitute") && $bool_include_box_top) {
  554. if ($this->bool_print != true)
  555. {// Don't display in print view.
  556. $pC .= "<div style='tenpt'>
  557. <a href='javascript: popupWindow2(\"" . base_path() . "/advise/popup-toolbox/transfers\",\"\");'><img src='" . fp_theme_location() . "/images/toolbox.gif' border='0'>" . t("Administrator's Toolbox") . "</a>
  558. </div>";
  559. $is_empty = false;
  560. }
  561. }
  562. $pC .= "</td></tr>";
  563. if ($bool_include_box_top) {
  564. $pC .= $this->draw_semester_box_bottom();
  565. }
  566. if (!$is_empty)
  567. {
  568. $this->add_to_screen($pC);
  569. }
  570. // Return so other functions can use this output, if needed.
  571. return $pC;
  572. }
  573. /**
  574. * Used in the Toolbox popup, this will display content of the tab which
  575. * shows a student's substututions
  576. *
  577. * @return string
  578. */
  579. function display_toolbox_substitutions()
  580. {
  581. $pC = "";
  582. // This will display the substitution management screen.
  583. $pC .= fp_render_curved_line(t("Manage Substitutions"));
  584. $pC .= "<div class='tenpt'>
  585. " . t("The following substitutions have been made for this student:") . "
  586. <br><br>
  587. ";
  588. $is_empty = true;
  589. $this->student->list_substitutions->reset_counter();
  590. while ($this->student->list_substitutions->has_more())
  591. {
  592. $substitution = $this->student->list_substitutions->get_next();
  593. $course_requirement = $substitution->course_requirement;
  594. $subbed_course = $substitution->course_list_substitutions->get_first();
  595. $sub_s_i = $subbed_course->subject_id;
  596. $sub_c_n = $subbed_course->course_num;
  597. $cr_s_i = $course_requirement->subject_id;
  598. $cr_c_n = $course_requirement->course_num;
  599. $cr_hrs = $course_requirement->get_hours();
  600. $in_group = ".";
  601. if ($subbed_course->assigned_to_group_id > 0)
  602. {
  603. $new_group = new Group();
  604. $new_group->group_id = $subbed_course->assigned_to_group_id;
  605. $new_group->load_descriptive_data();
  606. $in_group = " in $new_group->title.";
  607. }
  608. $sub_action = t("was substituted for");
  609. $sub_trans_notice = "";
  610. if ($substitution->bool_group_addition == true)
  611. {
  612. $sub_action = t("was added to");
  613. $cr_s_i = $cr_c_n = "";
  614. $in_group = str_replace("in","",$in_group);
  615. }
  616. if ($subbed_course->bool_transfer == true && is_object($subbed_course->course_transfer))
  617. {
  618. $sub_s_i = $subbed_course->course_transfer->subject_id;
  619. $sub_c_n = $subbed_course->course_transfer->course_num;
  620. $sub_trans_notice = "[" . t("transfer") . "]";
  621. }
  622. $by = $remarks = "";
  623. $temp = $this->db->get_substitution_details($subbed_course->db_substitution_id);
  624. $by = $this->db->get_faculty_name($temp["faculty_id"], false);
  625. $remarks = $temp["remarks"];
  626. $ondate = format_date($temp["posted"]);
  627. if ($by != "")
  628. {
  629. $by = " <br>&nbsp; &nbsp; " . t("Substitutor:") . " $by.
  630. <br>&nbsp; &nbsp; <i>$ondate.</i>";
  631. }
  632. if ($remarks != "")
  633. {
  634. $remarks = " <br>&nbsp; &nbsp; " . t("Remarks:") . " <i>$remarks</i>.";
  635. }
  636. $extra = "";
  637. if ($substitution->bool_outdated)
  638. {
  639. $extra = " <span style='color:red'>[OUTDATED: ";
  640. $extra .= $substitution->outdated_note;
  641. $extra .= "]</span>";
  642. }
  643. $pC .= "<div class='tenpt' style='margin-bottom: 20px;'>
  644. $sub_s_i $sub_c_n $sub_trans_notice ($subbed_course->substitution_hours hrs) $sub_action
  645. $cr_s_i $cr_c_n$in_group $by$remarks $extra
  646. <br>
  647. <a href='javascript: popupRemoveSubstitution(\"$subbed_course->db_substitution_id\");'>" . t("Remove substitution?") . "</a>
  648. </div>";
  649. $is_empty = false;
  650. }
  651. if ($is_empty == true)
  652. {
  653. $pC .= "<div align='center'>" . t("No substitutions have been made for this student.") . "</div>";
  654. }
  655. $pC .= "</div>";
  656. watchdog("toolbox", "substitutions", array(), WATCHDOG_DEBUG);
  657. return $pC;
  658. }
  659. /**
  660. * Used in the Toolbox popup, this will display content of the tab which
  661. * shows a student's transfers
  662. *
  663. * @return string
  664. */
  665. function display_toolbox_transfers()
  666. {
  667. $pC = "";
  668. // This will display the substitution management screen.
  669. $pC .= fp_render_curved_line(t("Manage Transfer Equivalencies"));
  670. $pC .= "<div class='tenpt'>
  671. " . t("This student has the following transfer credits and equivalencies.") . "
  672. <br><br>
  673. ";
  674. $is_empty = true;
  675. $this->student->list_courses_taken->sort_alphabetical_order(false, true);
  676. $this->student->list_courses_taken->reset_counter();
  677. while($this->student->list_courses_taken->has_more())
  678. {
  679. $c = $this->student->list_courses_taken->get_next();
  680. // Skip non transfer credits.
  681. if ($c->bool_transfer != true)
  682. {
  683. continue;
  684. }
  685. if ($c->course_id > 0)
  686. {
  687. $c->load_descriptive_data();
  688. }
  689. $course = $c->course_transfer;
  690. $course->load_descriptive_transfer_data();
  691. $l_s_i = $c->subject_id;
  692. $l_c_n = $c->course_num;
  693. $l_title = $this->fix_course_title($c->title);
  694. $t_s_i = $course->subject_id;
  695. $t_c_n = $course->course_num;
  696. $t_term = $c->get_term_description(true);
  697. $grade = $c->grade;
  698. if ($grade == "W" || $grade == "F" || $grade == "NC" || $grade == "I")
  699. {
  700. $grade = "<span style='color: red;'>$grade</span>";
  701. }
  702. $t_inst = $this->fix_institution_name($course->institution_name);
  703. $pC .= "<div class='tenpt' style='padding-bottom: 15px;'>
  704. <b>$t_s_i $t_c_n</b> ($c->hours_awarded hrs) - $grade - $t_term - $t_inst
  705. ";
  706. if ($c->bool_substitution_split == true)
  707. {
  708. $pC .= "<div class='tenpt'><b> +/- </b> This course's hours were split in a substitution.</div>";
  709. }
  710. $initials = $GLOBALS["fp_system_settings"]["school_initials"];
  711. // Does this course NOT have an equivalency?
  712. if ($c->course_id == 0)
  713. {
  714. // But, has the eqv been removed? If so, display a link to restore it,
  715. // if not, show a link to remove it!
  716. if ($rC = $this->student->list_transfer_eqvs_unassigned->find_match($course))
  717. {
  718. // Yes, the eqv WAS removed (or unassigned)
  719. $pC .= "<div class='tenpt'>" . t("This course's @initials equivalency was removed for this student.", array("@initials" => $initials)) . "<br>
  720. <a href='javascript: popupRestoreTransferEqv(\"$rC->db_unassign_transfer_id\")'>" . t("Restore?") . "</a></div>";
  721. } else {
  722. $pC .= "<div class='tenpt'>" . t("@initials equivalency not yet entered (or is not applicable).", array("@initials" => $initials)) . "</div>";
  723. }
  724. } else {
  725. // This course *DOES* have an equivalency.
  726. $pC .= "<div class='tenpt'>$initials eqv: $l_s_i $l_c_n - $l_title</div>";
  727. $pC .= "<div class='tenpt' align='right'>
  728. <a href='javascript: popupUnassignTransferEqv(\"" . $course->course_id . "\");'>" . t("Remove this equivalency?") . "</a>
  729. </div>";
  730. }
  731. $pC .= "</div>";
  732. $is_empty = false;
  733. }
  734. if ($is_empty == true) {
  735. $pC .= "<div align='center'>" . t("There are no transfer equivalencies for this student.") . "</div>";
  736. }
  737. $pC .= "</div>";
  738. watchdog("toolbox", "transfers", array(), WATCHDOG_DEBUG);
  739. return $pC;
  740. }
  741. /**
  742. * Used in the Toolbox popup, this will display content of the tab which
  743. * shows a student's courses which they have taken.
  744. *
  745. * @return string
  746. */
  747. function display_toolbox_courses()
  748. {
  749. $pC = "";
  750. $pC .= fp_render_curved_line(t("All Student Courses"));
  751. $csid = $_REQUEST["current_student_id"];
  752. $order = $_REQUEST["order"];
  753. if ($order == "name")
  754. {
  755. $ns = "font-weight: bold; color: black; text-decoration: none;";
  756. } else {
  757. $os = "font-weight: bold; color: black; text-decoration: none;";
  758. }
  759. $pC .= "<div class='tenpt'>
  760. " . t("This window displays all of the student's courses
  761. which FlightPath is able to load.") . "
  762. <br><br>
  763. " . t("Order by:") . " &nbsp; &nbsp;";
  764. $pC .= l(t("Name"), "advise/popup-toolbox/courses", "order=name&current_student_id=$csid", array("style" => $ns)) . "&nbsp; &nbsp;";
  765. $pC .= l(t("Date Taken"), "advise/popup-toolbox/courses", "order=date&current_student_id=$csid", array("style" => $os));
  766. $pC .= "<hr>
  767. <table border='0' cellpadding='2'>
  768. ";
  769. $is_empty = true;
  770. if ($order == "name")
  771. {
  772. $this->student->list_courses_taken->sort_alphabetical_order();
  773. } else {
  774. $this->student->list_courses_taken->sort_most_recent_first();
  775. }
  776. $this->student->list_courses_taken->reset_counter();
  777. while($this->student->list_courses_taken->has_more())
  778. {
  779. $c = $this->student->list_courses_taken->get_next();
  780. if ($c->course_id > 0)
  781. {
  782. $c->load_descriptive_data();
  783. }
  784. $l_s_i = $c->subject_id;
  785. $l_c_n = $c->course_num;
  786. $eqv_line = "";
  787. if ($c->course_transfer->course_id > 0)
  788. {
  789. if ($c->course_id > 0)
  790. {
  791. $eqv_line = "<tr>
  792. <td colspan='8' class='tenpt'
  793. style='padding-left: 20px;'>
  794. <i>*eqv to {$GLOBALS["fp_system_settings"]["school_initials"]} $l_s_i $l_c_n</i></td>
  795. </tr>";
  796. }
  797. $l_s_i = $c->course_transfer->subject_id;
  798. $l_c_n = $c->course_transfer->course_num;
  799. }
  800. $l_title = $this->fix_course_title($c->title);
  801. $l_term = $c->get_term_description(true);
  802. $h = $c->hours_awarded;
  803. if ($c->bool_ghost_hour) {
  804. $h .= "(" . t("ghost") . "<a href='javascript:alertSubGhost()'>?</a>)";
  805. }
  806. $pC .= "<tr>
  807. <td valign='top' class='tenpt'>$l_s_i</td>
  808. <td valign='top' class='tenpt'>$l_c_n</td>
  809. <td valign='top' class='tenpt'>$h</td>
  810. <td valign='top' class='tenpt'>$c->grade</td>
  811. <td valign='top' class='tenpt'>$c->term_id</td>
  812. ";
  813. $pC .= "<td valign='top' class='tenpt'>";
  814. if ($c->bool_transfer) {$pC .= "T ";}
  815. if ($c->bool_substitution) {$pC .= "S ";}
  816. if ($c->bool_has_been_assigned)
  817. {
  818. $pC .= "A:";
  819. if ($c->assigned_to_group_id == 0)
  820. {
  821. $pC .= "degree plan";
  822. } else {
  823. $temp_group = new Group();
  824. $temp_group->group_id = $c->assigned_to_group_id;
  825. $temp_group->load_descriptive_data();
  826. $pC .= $temp_group->title;
  827. }
  828. }
  829. $pC .= "</td>";
  830. $pC .= "</tr>$eqv_line";
  831. $is_empty = false;
  832. }
  833. if ($is_empty == true)
  834. {
  835. $pC .= "<div align='center'>" . t("No courses have been moved for this student.") . "</div>";
  836. }
  837. $pC .= "</table>";
  838. $pC .= "</div>";
  839. watchdog("toolbox", "courses", array(), WATCHDOG_DEBUG);
  840. return $pC;
  841. }
  842. /**
  843. * Used in the Toolbox popup, this will display content of the tab which
  844. * shows a student's moved courses. That is, courses which have had
  845. * their group memberships changed.
  846. *
  847. * @return string
  848. */
  849. function display_toolbox_moved()
  850. {
  851. $pC = "";
  852. $pC .= fp_render_curved_line(t("Manage Moved Courses"));
  853. $pC .= "<div class='tenpt'>
  854. " . t("This student has the following course movements.") . "
  855. <br><br>
  856. ";
  857. $is_empty = true;
  858. $this->student->list_courses_taken->sort_alphabetical_order();
  859. $this->student->list_courses_taken->reset_counter();
  860. while($this->student->list_courses_taken->has_more())
  861. {
  862. $c = $this->student->list_courses_taken->get_next();
  863. // Skip courses which haven't had anything moved.
  864. if ($c->group_list_unassigned->is_empty == true)
  865. {
  866. continue;
  867. }
  868. if ($c->course_id > 0)
  869. {
  870. $c->load_descriptive_data();
  871. }
  872. $l_s_i = $c->subject_id;
  873. $l_c_n = $c->course_num;
  874. $l_title = $this->fix_course_title($c->title);
  875. $l_term = $c->get_term_description(true);
  876. $h = $c->hours_awarded;
  877. if ($c->bool_ghost_hour) {
  878. $h .= " [" . t("ghost") . "<a href='javascript:alertSubGhost();'>?</a>] ";
  879. }
  880. $pC .= "<div class='tenpt' style='padding-bottom: 15px;'>
  881. <b>$l_s_i $l_c_n</b> ($h " . t("hrs") . ") - $c->grade - $l_term
  882. ";
  883. $c->group_list_unassigned->reset_counter();
  884. while($c->group_list_unassigned->has_more())
  885. {
  886. $group = $c->group_list_unassigned->get_next();
  887. $group->load_descriptive_data();
  888. $group_title = "";
  889. if ($group->group_id > 0)
  890. {
  891. $group_title = "<i>$group->title</i>";
  892. } else {
  893. $group_title = t("the degree plan");
  894. }
  895. $pC .= "<div class='tenpt'>" . t("This course was removed from") . " $group_title.<br>
  896. <a href='javascript: popupRestoreUnassignFromGroup(\"$group->db_unassign_group_id\")'>" . t("Restore?") . "</a>
  897. </div>
  898. ";
  899. }
  900. $pC .= "</div>";
  901. $is_empty = false;
  902. }
  903. if ($is_empty == true)
  904. {
  905. $pC .= "<div align='center'>" . t("No courses have been moved for this student.") . "</div>";
  906. }
  907. $pC .= "</div>";
  908. watchdog("toolbox", "moved", array(), WATCHDOG_DEBUG);
  909. return $pC;
  910. }
  911. /**
  912. * Constructs the HTML to show the student's test scores.
  913. *
  914. */
  915. function build_test_scores()
  916. {
  917. // This function will build our Test Scores box.
  918. // Only do this if the student actually has any test scores.
  919. if ($this->student->list_standardized_tests->is_empty)
  920. {
  921. return;
  922. }
  923. $top_scores = array();
  924. $pC = "";
  925. $pC .= $this->draw_semester_box_top(t("Test Scores"), TRUE);
  926. $pC .= "<tr><td colspan='8' class='tenpt'>
  927. ";
  928. $fsC = "";
  929. // Go through and find all the test scores for the student...
  930. $this->student->list_standardized_tests->reset_counter();
  931. while($this->student->list_standardized_tests->has_more()) {
  932. $st = $this->student->list_standardized_tests->get_next();
  933. $dt = strtotime($st->date_taken);
  934. $ddate = format_date($dt, "just_date");
  935. $fsC .= "<div>
  936. <b>$st->description</b> - $ddate
  937. <ul>";
  938. foreach($st->categories as $position => $cat_array)
  939. {
  940. $fsC .= "<li>{$cat_array["description"]} - {$cat_array["score"]}</li>";
  941. }
  942. $fsC .= "</ul>
  943. </div>";
  944. }
  945. $pC .= fp_render_c_fieldset($fsC, t("Click to view/hide standardized test scores"), TRUE);
  946. $pC .= "</td></tr>";
  947. $pC .= $this->draw_semester_box_bottom();
  948. $this->add_to_screen($pC);
  949. }
  950. /**
  951. * This function is used by the "build" functions most often. It very
  952. * simply adds a block of HTML to an array called box_array.
  953. *
  954. * @param string $content_box
  955. */
  956. function add_to_screen($content_box)
  957. {
  958. $this->box_array[] = $content_box;
  959. }
  960. /**
  961. * This function calls the other "build" functions to assemble
  962. * the View or What If tabs in FlightPath.
  963. *
  964. */
  965. function build_screen_elements()
  966. {
  967. // This function will build & assemble all of the onscreen
  968. // elements for the advising screen. It should be
  969. // called before display_screen();
  970. $this->build_semester_list();
  971. $this->build_excess_credit();
  972. $this->build_test_scores();
  973. $this->build_transfer_credit();
  974. if (!$this->bool_blank)
  975. { // Don't show if this is a blank degree plan.
  976. $this->build_footnotes();
  977. $this->build_added_courses();
  978. }
  979. // invoke a hook, to give custom modules the chance to perform actions
  980. // (or add blocks) to the advise screen after we have run this function.
  981. invoke_hook("advise_build_screen_elements", array(&$this));
  982. }
  983. /**
  984. * This function is used to draw an individual pie chart box.
  985. * It accepts values of top/bottom in order to come up
  986. * with a percentage.
  987. *
  988. * @param string $title
  989. *
  990. * @param float $top_value
  991. * - The top part of a ratio. Ex: for 1/2, $top_value = 1.
  992. *
  993. * @param float $bottom_value
  994. * - The bottom part of a ratio. For 1/2, $bottom_value = 2.
  995. * - Do not let this equal zero. If it does, the calculation
  996. * for the pie chart will never be evaluated.
  997. * @param string $pal
  998. * - Which palette to use for the pie chart.
  999. * - Acceptable values:
  1000. * - core
  1001. * - major
  1002. * - cumulative
  1003. * - student
  1004. *
  1005. *
  1006. * @return string
  1007. */
  1008. function draw_pie_chart_box($title, $top_value, $bottom_value, $pal)
  1009. {
  1010. $pC = "";
  1011. if ($bottom_value > 0)
  1012. {
  1013. $val = round(($top_value / $bottom_value)*100);
  1014. }
  1015. if ($val > 100) { $val = 99; }
  1016. $leftval = 100 - $val;
  1017. $back_col = "660000";
  1018. $fore_col = "FFCC33";
  1019. if ($pal == "major")
  1020. {
  1021. $fore_col = "93D18B";
  1022. }
  1023. if ($pal == "cumulative")
  1024. {
  1025. $fore_col = "5B63A5";
  1026. }
  1027. $vval = $val;
  1028. if ($vval < 1) $vval = 1;
  1029. // Create a graph using google's chart API
  1030. $google_chart_url = "https://chart.googleapis.com/chart?cht=p&chd=t:$vval,$leftval&chs=75x75&chco=$fore_col|$back_col&chp=91.1";
  1031. $pC .= "<table border='0' width='100%' height='100' class='elevenpt blueBorder' cellpadding='0' cellspacing='0' >
  1032. <tr>
  1033. <td class='blueTitle' align='center' height='20'>
  1034. " . fp_render_square_line($title) . "
  1035. </td>
  1036. </tr>
  1037. <tr>
  1038. <td>
  1039. <table border='0'>
  1040. <td>
  1041. <!-- <img src='jgraph/display_graph.php?pal=$pal&value=$val'> -->
  1042. <img src='$google_chart_url'>
  1043. </td>
  1044. <td class='elevenpt'>
  1045. <span style='color: blue;'>$val% " . t("Complete") . "</span><br>
  1046. ( <span style='color: blue;'>$top_value</span>
  1047. / <span style='color: gray;'>$bottom_value " . t("hours") . "</span> )
  1048. ";
  1049. $pC .= "
  1050. </td>
  1051. </table>
  1052. </td>
  1053. </tr>
  1054. </table>
  1055. ";
  1056. return $pC;
  1057. }
  1058. /**
  1059. * This function calls drawPieChart to construct the student's 3
  1060. * progress pie charts.
  1061. *
  1062. * @return string
  1063. */
  1064. function draw_progress_boxes()
  1065. {
  1066. global $user;
  1067. // Draw the boxes for student progress (where
  1068. // the pie charts go!)
  1069. $pC = "";
  1070. if ($this->degree_plan->total_degree_hours < 1)
  1071. {
  1072. $this->degree_plan->calculate_progress_hours();
  1073. $this->degree_plan->calculate_progress_quality_points();
  1074. }
  1075. $total_major_hours = $this->degree_plan->total_major_hours;
  1076. $total_core_hours = $this->degree_plan->total_core_hours;
  1077. $total_degree_hours = $this->degree_plan->total_degree_hours;
  1078. $fulfilled_major_hours = $this->degree_plan->fulfilled_major_hours;
  1079. $fulfilled_core_hours = $this->degree_plan->fulfilled_core_hours;
  1080. $fulfilled_degree_hours = $this->degree_plan->fulfilled_degree_hours;
  1081. $major_qpts = $this->degree_plan->major_qpts;
  1082. $degree_qpts = $this->degree_plan->degree_qpts;
  1083. $core_qpts = $this->degree_plan->core_qpts;
  1084. $pC .= "<tr><td colspan='2'>
  1085. ";
  1086. $user->settings = $this->db->get_user_settings($user->id);
  1087. if ($user->settings["hide_charts"] != "hide" && $this->bool_print == false && $this->bool_blank == false && $this->page_is_mobile == false)
  1088. { // Display the pie charts unless the student's settings say to hide them.
  1089. $pC .= "
  1090. <div style='margin-bottom: 10px;'>
  1091. <table width='100%' cellspacing='0' cellpadding='0' border='0'>
  1092. <td width='33%' style='padding-right:5px;'>
  1093. " . $this->draw_pie_chart_box(t("Progress - Core Courses"),$fulfilled_core_hours, $total_core_hours, "core") . "
  1094. </td>
  1095. <td width='33%' style='padding-right: 5px;'>
  1096. " . $this->draw_pie_chart_box(t("Progress - Major Courses"),$fulfilled_major_hours, $total_major_hours, "major") . "
  1097. </td>
  1098. <td width='33%'>
  1099. " . $this->draw_pie_chart_box(t("Progress - Degree"),$fulfilled_degree_hours, $total_degree_hours, "cumulative") . "
  1100. </td>
  1101. </table>
  1102. ";
  1103. $pC .= "
  1104. <div style='font-size: 8pt; text-align:right;'>
  1105. <a href='javascript:hideShowCharts(\"hide\");'>" . t("hide charts") . "</a>
  1106. </div>";
  1107. $pC .= "
  1108. </div>";
  1109. } else {
  1110. // Hide the charts! Show a "show" link....
  1111. $pC .= "
  1112. <table border='0' width='100%' class='elevenpt blueBorder' cellpadding='0' cellspacing='0' >
  1113. <tr>
  1114. <td colspan='4' class='blueTitle' align='center' height='20'>
  1115. " . fp_render_square_line(t("Progress")) . "
  1116. </td>
  1117. </tr>
  1118. <tr>
  1119. <td class='tenpt' width='33%' align='center'>
  1120. " . t("Core:") . " $fulfilled_core_hours / $total_core_hours
  1121. </td>
  1122. <td class='tenpt' width='33%' align='center'>
  1123. " . t("Major:") . " $fulfilled_major_hours / $total_major_hours
  1124. </td>
  1125. <td class='tenpt' width='33%' align='center'>
  1126. " . t("Degree:") . " $fulfilled_degree_hours / $total_degree_hours
  1127. </td>
  1128. </tr>
  1129. </table>
  1130. ";
  1131. if ($this->bool_print != true && $this->bool_blank != true && $this->page_is_mobile != true)
  1132. {
  1133. $pC .= "<div style='font-size: 8pt; text-align:right;'>
  1134. <a href='javascript:hideShowCharts(\"show\");'>" . t("show charts") . "</a>
  1135. </div>
  1136. ";
  1137. } else {
  1138. $pC .= "<div> &nbsp; </div>";
  1139. }
  1140. }
  1141. $pC .= "
  1142. </td></tr>";
  1143. return $pC;
  1144. }
  1145. /**
  1146. * Will display the "public note" at the top of a degree. This
  1147. * was entred in Data Entry.
  1148. *
  1149. * @return string
  1150. */
  1151. function draw_public_note()
  1152. {
  1153. // This will display a "public note" to the user about
  1154. // this degree. The public note was entered in Data Entry.
  1155. if ($this->degree_plan->public_note == "")
  1156. {
  1157. return "";
  1158. }
  1159. $public_note = filter_markup($this->degree_plan->public_note);
  1160. $pC = "";
  1161. $pC .= "<tr><td colspan='8'>
  1162. <div class='tenpt'
  1163. style='border: 5px double #C1A599;
  1164. padding: 5px;
  1165. margin: 10px;'>
  1166. <b>" . t("Important Message:") . "</b> $public_note
  1167. </div>
  1168. </td></tr>";
  1169. return $pC;
  1170. }
  1171. /**
  1172. * This function generates the HTML to display the screen. Should
  1173. * be used in conjunction with output_to_browser()
  1174. *
  1175. * @return string
  1176. */
  1177. function display_screen()
  1178. {
  1179. // This will generate the html to display the screen.
  1180. $pC = "";
  1181. if ($this->bool_hiding_grades && !$this->bool_print && $GLOBALS["fp_system_settings"]["hiding_grades_message"] != "")
  1182. {
  1183. // Display the message about us hiding grades.
  1184. $pC .= "
  1185. <tr><td colspan='2'>
  1186. <div class='tenpt hypo' style='margin-top: 4px; margin-bottom: 4px;
  1187. padding: 2px; border: 1px solid maroon;'>
  1188. <table border='0' cellspacing='0' cellpadding='0'>
  1189. <td valign='top'>
  1190. <img src='" . fp_theme_location() . "/images/alert_lg.gif' >
  1191. </td>
  1192. <td valign='middle' class='tenpt' style='padding-left: 8px;'>
  1193. {$GLOBALS["fp_system_settings"]["hiding_grades_message"]}
  1194. </td>
  1195. </table>
  1196. </div>
  1197. </td></tr>
  1198. ";
  1199. }
  1200. //$pC .= $this->draw_currently_advising_box();
  1201. $pC .= $this->draw_progress_boxes();
  1202. $pC .= $this->draw_public_note();
  1203. for ($t = 0; $t < count($this->box_array); $t++)
  1204. {
  1205. $align = "right";
  1206. if ($this->is_on_left)
  1207. {
  1208. $pC .= "<tr>";
  1209. $align= "left";
  1210. }
  1211. $pC .= "<td valign='top' align='$align' class='fp-boxes'>";
  1212. $pC .= $this->box_array[$t];
  1213. $pC .= "</td>";
  1214. if (fp_screen_is_mobile()) {
  1215. // If we are on a mobile device, force it to use
  1216. // only one column.
  1217. $this->is_on_left = false;
  1218. }
  1219. if (!$this->is_on_left) // on right of page
  1220. {
  1221. $pC .= "</tr>";
  1222. }
  1223. $this->is_on_left = !$this->is_on_left;
  1224. }
  1225. if (!$this->is_on_left) // on right of the page.
  1226. { // close up any loose ends.
  1227. $pC .= "</tr>";
  1228. }
  1229. if (user_has_permission("can_advise_students"))
  1230. {
  1231. if (!$this->bool_print && !$this->bool_blank)
  1232. {
  1233. $pC .= "<tr>";
  1234. if (!fp_screen_is_mobile()) {
  1235. $pC .= "<td>&nbsp;</td>";
  1236. }
  1237. $pC .= "<td align='center'>
  1238. <div class='tenpt' style='margin-top:35px; margin-bottom:10px; padding: 10px; width: 200px;'>
  1239. " . fp_render_button(t("Submit"),"submitSaveActive();") . "
  1240. </div>
  1241. </td></tr>
  1242. ";
  1243. //$this->add_to_screen("<input type='button' value='Submit' onClick='submitSaveActive();'>");
  1244. }
  1245. }
  1246. return $pC;
  1247. }
  1248. /**
  1249. * Returns the HTML to draw a pretty button.
  1250. *
  1251. * @param string $title
  1252. * @param string $on_click
  1253. * @param bool $bool_padd
  1254. * @param string $style
  1255. * @return string
  1256. */
  1257. function draw_button($title, $on_click, $bool_padd = true, $style = "")
  1258. {
  1259. // Style is expected to look like:
  1260. // style='some:thing;'
  1261. // with SINGLE apostrophes! not quotes.
  1262. $on_mouse = "onmouseover='this.className=\"gradbutton gradbutton_hover hand\";'
  1263. onmouseout='this.className=\"gradbutton hand\";'
  1264. onmousedown='this.className=\"gradbutton gradbutton_down hand\";'
  1265. onmouseup='this.className=\"gradbutton gradbutton_hover hand\";'
  1266. ";
  1267. if ($this->page_is_mobile) $on_mouse = ""; // Causes problems for some mobile devices.
  1268. if ($bool_padd)
  1269. {
  1270. $padd = "&nbsp; &nbsp;";
  1271. }
  1272. $rtn = "<span class='gradbutton hand' onClick='$on_click' $on_mouse $style >
  1273. $padd $title $padd
  1274. </span>
  1275. ";
  1276. return $rtn;
  1277. }
  1278. /**
  1279. * Constructs the HTML to display the list of semesters for the student.
  1280. *
  1281. */
  1282. function build_semester_list() {
  1283. $list_semesters = $this->degree_plan->list_semesters;
  1284. // Go through each semester and add it to the screen...
  1285. $list_semesters->reset_counter();
  1286. while($list_semesters->has_more())
  1287. {
  1288. $semester = $list_semesters->get_next();
  1289. $semester->reset_list_counters();
  1290. if ($semester->semester_num == -88)
  1291. { // These are the "added by advisor" courses. Skip them.
  1292. continue;
  1293. }
  1294. $this->add_to_screen($this->display_semester($semester, true));
  1295. }
  1296. }
  1297. /**
  1298. * This function is called when we know we are on a mobile
  1299. * browser. We have to handle tab rendering differently
  1300. * in order to make them all fit.
  1301. *
  1302. * @param unknown_type $tab_array
  1303. */
  1304. function z__draw_mobile_tabs($tab_array) {
  1305. $rtn = "";
  1306. $js_vars = "var mobileTabSelections = new Array(); ";
  1307. if (count($tab_array) <= 1) return "";
  1308. $rtn .= "<table border='0' width='200' cellpadding='0' cellspacing='0' class='fp-mobile-tabs'>
  1309. <td>
  1310. <b>Display: </b>";
  1311. /* if (count($tab_array) == 1) {
  1312. // Just one element, no need to render the select list.
  1313. $rtn .= $tab_array[0]["title"];
  1314. $rtn .= "</td></table>";
  1315. return $rtn;
  1316. }
  1317. */
  1318. $rtn .= "<select onChange='executeSelection()' id='mobileTabsSelect'>";
  1319. for ($t = 0; $t < count($tab_array); $t++)
  1320. {
  1321. $title = $tab_array[$t]["title"];
  1322. $active = $tab_array[$t]["active"];
  1323. $on_click = $tab_array[$t]["on_click"];
  1324. if ($title == "")
  1325. {
  1326. continue;
  1327. }
  1328. $sel = ($active == true) ? $sel = "selected":"";
  1329. $rtn .= "<option $sel value='$t'>$title</option>";
  1330. $js_vars .= "mobile_tab_selections[$t] = '$on_click'; \n";
  1331. }
  1332. $rtn .= "</select>
  1333. </td></table>";
  1334. $rtn .= '
  1335. <script type="text/javascript">
  1336. ' . $js_vars . '
  1337. function executeSelection() {
  1338. var sel = document.getElementById("mobileTabsSelect").value;
  1339. var statement = mobile_tab_selections[sel];
  1340. // Lets execute the statement...
  1341. eval(statement);
  1342. }
  1343. </script>
  1344. ';
  1345. return $rtn;
  1346. }
  1347. /**
  1348. * Displays the contents of the Descripton tab for the course popup.
  1349. *
  1350. * @param int $course_id
  1351. * - The course_id of the course to show. Leave blank if supplying
  1352. * the object instead.
  1353. *
  1354. * @param Course $course
  1355. * - The course object to display. Leave as NULL if supplying
  1356. * the course_id instead.
  1357. *
  1358. * @param Group $group
  1359. * - The Group object that this course has been placed into.
  1360. *
  1361. * @param bool $show_advising_buttons
  1362. * - Should we show the advising buttons in this popup? Would be
  1363. * set to false for student view, or for anyone who is not
  1364. * allowed to advise this course into a group for the student.
  1365. *
  1366. * @return string
  1367. */
  1368. function display_popup_course_description($course_id = "", Course $course = null, $group = null, $show_advising_buttons = false)
  1369. {
  1370. $pC = "";
  1371. if ($course_id != "" && $course_id != 0) {
  1372. $course = new Course($course_id);
  1373. }
  1374. $db_group_requirement_id = $_REQUEST["db_group_requirement_id"];
  1375. if ($course == null)
  1376. {
  1377. // No course available!
  1378. $pC .= fp_render_curved_line(t("Description"));
  1379. $pC .= "<div class='tenpt'>" . t("No course was selected. Please
  1380. click the Select tab at the top of the screen.") . "
  1381. </div>";
  1382. return $pC;
  1383. }
  1384. $advising_term_id = $GLOBALS["fp_advising"]["advising_term_id"];
  1385. $course->load_descriptive_data();
  1386. $course_hours = $course->get_hours();
  1387. if ($course->bool_transfer)
  1388. {
  1389. }
  1390. // Does this course have more than one valid (non-excluded) name?
  1391. $other_valid_names = "";
  1392. if (count($course->array_valid_names) > 1)
  1393. {
  1394. for ($t = 0; $t < count($course->array_valid_names); $t++)
  1395. {
  1396. $name = $course->array_valid_names[$t];
  1397. if ($name == "$course->subject_id~$course->course_num")
  1398. {
  1399. continue;
  1400. }
  1401. $other_valid_names .= ", " . str_replace("~"," ",$name);
  1402. }
  1403. }
  1404. $course->fix_title();
  1405. $initials = $GLOBALS["fp_system_settings"]["school_initials"];
  1406. $pC .= fp_render_curved_line("$course->subject_id $course->course_num$other_valid_names <!--EQV1-->");
  1407. $bool_transferEqv = true;
  1408. if ($course->bool_transfer)
  1409. {
  1410. // This is a transfer course. Begin by displaying the transfer credit's
  1411. // information.
  1412. $course->course_transfer->load_descriptive_transfer_data($this->student->student_id);
  1413. $hrs = $course->course_transfer->get_hours()*1;
  1414. if ($hrs == 0)
  1415. {
  1416. $hrs = $course->get_hours();
  1417. }
  1418. // make transfer course titles all caps.
  1419. $course->course_transfer->title = strtoupper($course->course_transfer->title);
  1420. $pC .= "<div style='margin-top: 13px;' class='tenpt'>
  1421. <b>" . t("Transfer Credit Information:") . "</b><br>
  1422. <div style='margin-left: 20px;' class='tenpt'>
  1423. " . t("Course:") . " " . $course->course_transfer->subject_id . " " . $course->course_transfer->course_num . "
  1424. - " . $course->course_transfer->title . " ($hrs hrs)<br>
  1425. " . t("Institution:") . " " . $this->fix_institution_name($course->course_transfer->institution_name) . "<br>
  1426. " . t("Term:") . " " . $course->get_term_description() . "<br>
  1427. <!-- Grade: " . $course->grade . "<br> -->
  1428. ";
  1429. $transfer_eqv_text = $course->course_transfer->transfer_eqv_text;
  1430. if ($transfer_eqv_text == "") {
  1431. $transfer_eqv_text = t("Not entered or not applicable.");
  1432. $bool_transferEqv = false;
  1433. }
  1434. $pC .= "$initials Eqv: $transfer_eqv_text<br>
  1435. </div>
  1436. </div>";
  1437. }
  1438. $pC .= "
  1439. <div style='margin-top: 13px;'>
  1440. <div class='tenpt'>";
  1441. if ($course->course_id != 0)
  1442. {
  1443. $use_hours = $course_hours;
  1444. if ($course->bool_transfer)
  1445. {
  1446. $pC .= "<b>$initials " . t("Equivalent Course Information:") . "</b><br>
  1447. <b>$course->subject_id $course->course_num</b> - ";
  1448. $new_course = new Course();
  1449. $new_course->course_id = $course->course_id;
  1450. $new_course->load_descriptive_data();
  1451. $use_hours = $new_course->get_catalog_hours();
  1452. }
  1453. $pC .= "
  1454. <b>$course->title ($use_hours " . t("hrs") . ")</b>";
  1455. }
  1456. if ($course->bool_substitution_new_from_split || $course->bool_substitution_split)
  1457. {
  1458. $pC .= "<div class='tenpt' style='margin-bottom:5px;'>
  1459. <i>" . t("This course's hours were split in a substitution.") . "</i>
  1460. <a href='javascript: alertSplitSub();'>?</a>
  1461. </div>";
  1462. }
  1463. $pC .= "</div>";
  1464. if ($course->course_id != 0)
  1465. {
  1466. $pC .= "
  1467. <div class='tenpt'>
  1468. $course->description
  1469. </div>
  1470. </div>
  1471. ";
  1472. }
  1473. if ($course->bool_transfer == true && $course->course_id < 1 && $course->bool_substitution == false)
  1474. { // No local eqv!
  1475. $pC .= "<div class='tenpt' style='margin-top: 10px;'><b>Note:</b> ";
  1476. /*
  1477. $pC .= "
  1478. <b>Note:</b> This course is a transfer credit which
  1479. the student completed at <i>";
  1480. $pC .= $this->fix_institution_name($course->course_transfer->institution_name) . "</i>.";
  1481. */
  1482. $pC = str_replace("<!--EQV1-->"," (" . t("Transfer Credit") . ")",$pC);
  1483. if (!$bool_transferEqv)
  1484. {
  1485. $t_msg = t("This course does not have an assigned @initials equivalency, or the equivalency
  1486. has been removed for this student.
  1487. Ask your advisor if this course will count towards your degree.", array("@initials" => $initials)) . "
  1488. </div>";
  1489. } else {
  1490. $t_msg = t("FlightPath cannot assign this course to a @initials equivalency on
  1491. the student's degree plan,
  1492. or the equivalency
  1493. has been removed for this student.
  1494. Ask your advisor if this course will count towards your degree.", array("@initials" => $initials)) . "
  1495. </div>";
  1496. }
  1497. $pC .= $t_msg;
  1498. } elseif ($course->bool_transfer == true && $course->course_id > 0 && $course->bool_substitution == false)
  1499. { // Has a local eqv!
  1500. $t_s_i = $course->course_transfer->subject_id;
  1501. $t_c_n = $course->course_transfer->course_num;
  1502. /* $pC .= "<div class='tenpt' style='margin-top: 10px;'>
  1503. <b>Note:</b> The course listed above is equivalent
  1504. to <b>$t_s_i $t_c_n</b>,
  1505. which the student completed at <i>";
  1506. // Replace the temporary comment <!--EQV1--> in the header with
  1507. // the new eqv information.
  1508. */
  1509. $pC = str_replace("<!--EQV1-->"," (" . t("Transfer Credit") . " $t_s_i $t_c_n)",$pC);
  1510. /* $pC .= $this->fix_institution_name($course->course_transfer->institution_name);
  1511. $pC .= "</i>.";
  1512. */
  1513. // Admin function only.
  1514. if (user_has_permission("can_substitute"))
  1515. {
  1516. $pC .= "<div align='left' class='tenpt'>
  1517. <b>" . t("Special administrative function:") . "</b>
  1518. <a href='javascript: popupUnassignTransferEqv(\"" . $course->course_transfer->course_id . "\");'>" . t("Remove this equivalency?") . "</a></div>";
  1519. $pC .= "</div>";
  1520. }
  1521. $pC .= "</div>";
  1522. }
  1523. if ($course->term_id != "" && $course->term_id != "11111" && $course->display_status != "eligible" && $course->display_status != "disabled")
  1524. {
  1525. $pC .= "<div class='tenpt' style='margin-top: 10px;'>
  1526. " . t("The student enrolled in this course in") . " " . $course->get_term_description() . ".
  1527. </div>";
  1528. } else if ($course->term_id == "11111")
  1529. {
  1530. $pC .= "<div class='tenpt' style='margin-top: 10px;'>
  1531. " . t("The exact date that the student enrolled in this course
  1532. cannot be retrieved at this time. Please check the
  1533. student's official transcript for more details.") . "
  1534. </div>";
  1535. }
  1536. if ($course->assigned_to_group_id*1 > 0 && $course->grade != "" && $course->bool_transfer != true && $course->bool_substitution != true)
  1537. {
  1538. //$g = new Group($course->assigned_to_group_id);
  1539. $g = new Group();
  1540. $g->group_id = $course->assigned_to_group_id;
  1541. $g->load_descriptive_data();
  1542. $pC .= "<div class='tenpt' style='margin-top: 10px;'>
  1543. <img src='" . fp_theme_location() . "/images/icons/$g->icon_filename' width='19' height='19'>
  1544. &nbsp;
  1545. " . t("This course is a member of") . " $g->title.
  1546. ";
  1547. // If user is an admin...
  1548. if (user_has_permission("can_substitute")) {
  1549. $tflag = intval($course->bool_transfer);
  1550. $pC .= "<div align='left' class='tenpt'>
  1551. <b>" . t("Special administrative function:") . "</b>
  1552. <a href='javascript: popupUnassignFromGroup(\"$course->course_id\",\"$course->term_id\",\"$tflag\",\"$g->group_id\");'>" . t("Remove from this group?") . "</a></div>";
  1553. $pC .= "</div>";
  1554. }
  1555. } else if ($course->grade != "" && $course->bool_transfer != true && $course->bool_substitution != true && $course->bool_has_been_assigned == true) {
  1556. // Course is not assigned to a group; it's on the bare degree plan. group_id = 0.
  1557. // If user is an admin...
  1558. if (user_has_permission("can_substitute"))
  1559. {
  1560. $tflag = intval($course->bool_transfer);
  1561. $pC .= "<div align='left' class='tenpt'>
  1562. <b>" . t("Special administrative function:") . "</b>
  1563. <a href='javascript: popupUnassignFromGroup(\"$course->course_id\",\"$course->term_id\",\"$tflag\",\"0\");'>" . t("Remove from the degree plan?") . "</a></div>";
  1564. $pC .= "</div>";
  1565. }
  1566. }
  1567. // Substitutors get extra information:
  1568. if (user_has_permission("can_substitute") && $course->assigned_to_group_id > 0) {
  1569. $pC .= "<div class='tenpt' style='margin-top: 20px;'>
  1570. <b>" . t("Special administrative information:") . "</b>
  1571. <span id='viewinfolink'
  1572. onClick='document.getElementById(\"admin_info\").style.display=\"\"; this.style.display=\"none\"; '
  1573. class='hand' style='color: blue;'
  1574. > - " . t("Click to show") . " -</span>
  1575. <div style='padding-left: 20px; display:none;' id='admin_info'>
  1576. ";
  1577. // Course is assigned to a group.
  1578. if ($course->assigned_to_group_id > 0) {
  1579. $group = new Group();
  1580. $group->group_id = $course->assigned_to_group_id;
  1581. $group->load_descriptive_data();
  1582. $pC .= "
  1583. " . t("Course is assigned to group:") . "<br>
  1584. &nbsp; " . t("Group ID:") . " $group->group_id<br>
  1585. &nbsp; " . t("Title:") . " $group->title<br>";
  1586. $pC .= "&nbsp; <i>" . t("Internal name:") . " $group->group_name</i><br>";
  1587. $pC .= "&nbsp; " . t("Catalog year:") . " $group->catalog_year
  1588. ";
  1589. }
  1590. $pC .= "
  1591. </div>
  1592. </div>";
  1593. }
  1594. if ($course->bool_substitution == true)
  1595. {
  1596. // Find out who did it and if they left any remarks.
  1597. $db = $this->db;
  1598. $temp = $db->get_substitution_details($course->db_substitution_id);
  1599. $by = $db->get_faculty_name($temp["faculty_id"], false);
  1600. $remarks = $temp["remarks"];
  1601. $ondate = format_date($temp["posted"], "", "n/d/Y");
  1602. if ($by != "")
  1603. {
  1604. $by = " by $by, on $ondate.";
  1605. }
  1606. if ($remarks != "")
  1607. {
  1608. $remarks = " " . t("Substitution remarks:") . " <i>$remarks</i>.";
  1609. }
  1610. $forthecourse = t("for the original course
  1611. requirement of") . " <b>" . $course->course_substitution->subject_id . "
  1612. " . $course->course_substitution->course_num . "</b>";
  1613. if ($temp["required_course_id"]*1 == 0)
  1614. {
  1615. $forthecourse = "";
  1616. }
  1617. $pC .= "<div class='tenpt' style='margin-top: 10px;'>
  1618. <b>" . t("Note:") . "</b> " . t("This course was substituted into the
  1619. degree plan") . " $forthecourse
  1620. $by$remarks";
  1621. if (user_has_permission("can_substitute")) {
  1622. $pC .= "<div align='left' class='tenpt' style='padding-left: 10px;'>
  1623. <b>" . t("Special administrative function:") . "</b>
  1624. <a href='javascript: popupRemoveSubstitution(\"$course->db_substitution_id\");'>" . t("Remove substitution?") . "</a>
  1625. </div>";
  1626. }
  1627. }
  1628. // Only show if the course has not been taken...
  1629. if ($course->has_variable_hours() && $course->grade == "")
  1630. {
  1631. $pC .= "<div class='tenpt' style='margin-top: 10px;'>
  1632. " . t("This course has variable hours. Please select
  1633. how many hours this course will be worth:") . "<br>
  1634. <center>
  1635. <select name='selHours' id='selHours' onChange='popupSetVarHours();'>
  1636. ";
  1637. // Correct for ghost hours, if they are there.
  1638. $min_h = $course->min_hours;
  1639. $max_h = $course->max_hours;
  1640. if ($course->bool_ghost_min_hour) $min_h = 0;
  1641. if ($course->bool_ghost_hour) $max_h = 0;
  1642. for($t = $min_h; $t <= $max_h; $t++)
  1643. {
  1644. $sel = "";
  1645. if ($t == $course->advised_hours){ $sel = "SELECTED"; }
  1646. $pC .= "<option value='$t' $sel>$t</option>";
  1647. }
  1648. $pC .= "</select> " . t("hours.") . "<br>
  1649. </center>
  1650. </div>";
  1651. if ($course->advised_hours > -1)
  1652. {
  1653. $var_hours_default = $course->advised_hours;
  1654. } else {
  1655. $var_hours_default = $min_h;
  1656. }
  1657. }
  1658. if ($show_advising_buttons == true && !$this->bool_blank) {
  1659. // Insert a hidden radio button so the javascript works okay...
  1660. $pC .= "<input type='radio' name='course' value='$course->course_id' checked='checked'
  1661. style='display: none;'>
  1662. <input type='hidden' name='varHours' id='varHours' value='$var_hours_default'>";
  1663. if (user_has_permission("can_advise_students"))
  1664. {
  1665. $pC .= "<div style='margin-top: 20px;'>
  1666. " . fp_render_button(t("Select Course"), "popupAssignSelectedCourseToGroup(\"$group->assigned_to_semester_num\", \"$group->group_id\",\"$advising_term_id\",\"$db_group_requirement_id\");", true, "style='font-size: 10pt;'") . "
  1667. </div>
  1668. ";
  1669. }
  1670. }
  1671. else if ($show_advising_buttons == false && $course->has_variable_hours() == true && $course->grade == "" && user_has_permission("can_advise_students") && !$this->bool_blank) {
  1672. // Show an "update" button, and use the course's assigned_to_group_id and
  1673. // assigned_to_semester_num.
  1674. $pC .= "
  1675. <input type='hidden' name='varHours' id='varHours' value='$var_hours_default'>";
  1676. $pC .= fp_render_button(t("Update"), "popupUpdateSelectedCourse(\"$course->course_id\",\"$course->assigned_to_group_id\",\"$course->assigned_to_semester_num\",\"$course->random_id\",\"$advising_term_id\");");
  1677. }
  1678. return $pC;
  1679. }
  1680. /**
  1681. * Simple function to make an institution name look more pretty, because
  1682. * all institution names pass through ucwords(), sometimes the capitalization
  1683. * gets messed up. This function tries to correct it.
  1684. *
  1685. * Feel free to override it and add to it, if needed.
  1686. *
  1687. * @param string $str
  1688. * @return string
  1689. */
  1690. function fix_institution_name($str)
  1691. {
  1692. $str = str_replace("-", " - ", $str);
  1693. $str = ucwords(strtolower($str));
  1694. $str = str_replace(" Of ", " of ", $str);
  1695. $str = str_replace("clep", "CLEP", $str);
  1696. $str = str_replace("_clep", "CLEP", $str);
  1697. $str = str_replace("_act", "ACT", $str);
  1698. $str = str_replace("_sat", "SAT", $str);
  1699. $str = str_replace("Ap ", "AP ", $str);
  1700. $str = str_replace("_dsst", "DSST", $str);
  1701. // Fix school initials.
  1702. // Turns "Ulm" into "ULM"
  1703. $school_initials = $GLOBALS["fp_system_settings"]["school_initials"];
  1704. $str = str_replace(ucwords(strtolower($school_initials)), $school_initials, $str);
  1705. if ($str == "")
  1706. {
  1707. $str = "<i>unknown institution</i>";
  1708. }
  1709. return $str;
  1710. }
  1711. /**
  1712. * Left in for legacy reasons, this function uses a new Course object's
  1713. * method of $course->fix_title to make a course's title more readable.
  1714. *
  1715. * @param string $str
  1716. * @return stromg
  1717. */
  1718. function fix_course_title($str)
  1719. {
  1720. $new_course = new Course();
  1721. $str = $new_course->fix_title($str);
  1722. return $str;
  1723. }
  1724. /**
  1725. * Given a Semester object, this will generate the HTML to draw it out
  1726. * to the screen.
  1727. *
  1728. * @param Semester $semester
  1729. * @param bool $bool_display_hour_count
  1730. * - If set to TRUE, it will display a small "hour count" message
  1731. * at the bottom of each semester, showing how many hours are in
  1732. * the semester. Good for debugging purposes.
  1733. *
  1734. * @return string
  1735. */
  1736. function display_semester(Semester $semester, $bool_display_hour_count = false)
  1737. {
  1738. // Display the contents of a semester object
  1739. // on the screen (in HTML)
  1740. $pC = "";
  1741. $pC .= $this->draw_semester_box_top($semester->title);
  1742. $count_hoursCompleted = 0;
  1743. // First, display the list of bare courses.
  1744. $semester->list_courses->sort_alphabetical_order();
  1745. $semester->list_courses->reset_counter();
  1746. while($semester->list_courses->has_more())
  1747. {
  1748. $course = $semester->list_courses->get_next();
  1749. // Is this course being fulfilled by anything?
  1750. if (!($course->course_list_fulfilled_by->is_empty))
  1751. { // this requirement is being fulfilled by something the student took...
  1752. $pC .= $this->draw_course_row($course->course_list_fulfilled_by->get_first());
  1753. $course->course_list_fulfilled_by->get_first()->bool_has_been_displayed = true;
  1754. if ($course->course_list_fulfilled_by->get_first()->display_status == "completed")
  1755. { // We only want to count completed hours, no midterm or enrolled courses.
  1756. $h = $course->course_list_fulfilled_by->get_first()->hours_awarded;
  1757. if ($course->course_list_fulfilled_by->get_first()->bool_ghost_hour == TRUE) {
  1758. $h = 0;
  1759. }
  1760. $count_hoursCompleted += $h;
  1761. }
  1762. } else {
  1763. // This requirement is not being fulfilled...
  1764. $pC .= $this->draw_course_row($course);
  1765. }
  1766. //$pC .= "</td></tr>";
  1767. }
  1768. // Now, draw all the groups.
  1769. $semester->list_groups->sort_alphabetical_order();
  1770. $semester->list_groups->reset_counter();
  1771. while($semester->list_groups->has_more())
  1772. {
  1773. $group = $semester->list_groups->get_next();
  1774. $pC .= "<tr><td colspan='8'>";
  1775. $pC .= $this->display_group($group);
  1776. $count_hoursCompleted += $group->hours_fulfilled_for_credit;
  1777. $pC .= "</td></tr>";
  1778. }
  1779. // Add hour count to the bottom...
  1780. if ($bool_display_hour_count == true && $count_hoursCompleted > 0)
  1781. {
  1782. $pC .= "<tr><td colspan='8'>
  1783. <div class='tenpt' style='text-align:right; margin-top: 10px;'>
  1784. Completed hours: $count_hoursCompleted
  1785. </div>
  1786. ";
  1787. $pC .= "</td></tr>";
  1788. }
  1789. // Does the semester have a notice?
  1790. if ($semester->notice != "")
  1791. {
  1792. $pC .= "<tr><td colspan='8'>
  1793. <div class='hypo tenpt' style='margin-top: 15px; padding: 5px;'>
  1794. <b>Important Notice:</b> $semester->notice
  1795. </div>
  1796. </td></tr>";
  1797. }
  1798. $pC .= $this->draw_semester_box_bottom();
  1799. return $pC;
  1800. }
  1801. /**
  1802. * This function displays a Group object on the degree plan. This is not
  1803. * the selection popup display. It will either show the group as multi
  1804. * rows, filled in with courses, or as a "blank row" for the user to click
  1805. * on.
  1806. *
  1807. * @param Group $place_group
  1808. * @return string
  1809. */
  1810. function display_group(Group $place_group)
  1811. {
  1812. // Display a group, either filled in with courses,
  1813. // and/or with a "blank row" for the user to
  1814. // click on.
  1815. $pC = "";
  1816. // Now, if you will recall, all of the groups and their courses, etc,
  1817. // are in the degree_plan's list_groups. The $place_group object here
  1818. // is just a placeholder. So, get the real group...
  1819. if (!$group = $this->degree_plan->find_group($place_group->group_id))
  1820. {
  1821. fpm("Group not found.");
  1822. return;
  1823. }
  1824. $title = $group->title;
  1825. $display_course_list = new CourseList();
  1826. // Okay, first look for courses in the first level
  1827. // of the group.
  1828. $display_semesterNum = $place_group->assigned_to_semester_num;
  1829. $group->list_courses->remove_unfulfilled_and_unadvised_courses();
  1830. $group->list_courses->reset_counter();
  1831. while($group->list_courses->has_more())
  1832. {
  1833. $course = $group->list_courses->get_next();
  1834. // Do we have enough hours to keep going?
  1835. $fulfilled_hours = $display_course_list->count_hours();
  1836. $remaining = $place_group->hours_required - $fulfilled_hours;
  1837. // If the course in question is part of a substitution that is not
  1838. // for this group, then we should skip it.
  1839. if (!($course->course_list_fulfilled_by->is_empty))
  1840. {
  1841. $try_c = $course->course_list_fulfilled_by->get_first();
  1842. if ($try_c->bool_substitution == true && $try_c->assigned_to_group_id != $group->group_id)
  1843. {
  1844. continue;
  1845. }
  1846. }
  1847. if (!($course->course_list_fulfilled_by->is_empty) && $course->course_list_fulfilled_by->get_first()->bool_has_been_displayed != true && $course->bool_has_been_displayed != true)
  1848. {
  1849. $c = $course->course_list_fulfilled_by->get_first();
  1850. if ($remaining < $c->get_hours())
  1851. {
  1852. continue;
  1853. }
  1854. $c->temp_flag = false;
  1855. $c->icon_filename = $group->icon_filename;
  1856. $c->title_text = "This course is a member of $group->title.";
  1857. $display_course_list->add($c);
  1858. }
  1859. if ($course->bool_advised_to_take && $course->bool_has_been_displayed != true && $course->assigned_to_semester_num == $display_semesterNum)
  1860. {
  1861. $c = $course;
  1862. if ($remaining < $c->get_hours())
  1863. {
  1864. continue;
  1865. }
  1866. $c->temp_flag = true;
  1867. $c->icon_filename = $group->icon_filename;
  1868. $c->title_text = "The student has been advised to take this course to fulfill a $group->title requirement.";
  1869. $display_course_list->add($c);
  1870. }
  1871. }
  1872. $group->list_groups->reset_counter();
  1873. while($group->list_groups->has_more())
  1874. {
  1875. $branch = $group->list_groups->get_next();
  1876. // look for courses at this level...
  1877. if (!$branch->list_courses->is_empty)
  1878. {
  1879. $branch->list_courses->sort_alphabetical_order();
  1880. $branch->list_courses->reset_counter();
  1881. while($branch->list_courses->has_more())
  1882. {
  1883. $course = $branch->list_courses->get_next();
  1884. // Do we have enough hours to keep going?
  1885. $fulfilled_hours = $display_course_list->count_hours();
  1886. $remaining = $place_group->hours_required - $fulfilled_hours;
  1887. if (!($course->course_list_fulfilled_by->is_empty) && $course->course_list_fulfilled_by->get_first()->bool_has_been_displayed != true && $course->bool_has_been_displayed != true)
  1888. {
  1889. $c = $course->course_list_fulfilled_by->get_first();
  1890. if ($remaining < $c->get_hours() || $remaining < 1)
  1891. {
  1892. continue;
  1893. }
  1894. $c->temp_flag = false;
  1895. $c->icon_filename = $group->icon_filename;
  1896. $c->title_text = "This course is a member of $group->title.";
  1897. if (!$display_course_list->find_match($c))
  1898. { // Make sure it isn't already in the display list.
  1899. $display_course_list->add($c);
  1900. } else if (is_object($c->course_transfer))
  1901. {
  1902. if (!$display_course_list->find_match($c->course_transfer))
  1903. { // Make sure it isn't already in the display list.
  1904. $display_course_list->add($c);
  1905. }
  1906. }
  1907. }
  1908. if ($course->bool_advised_to_take && $course->bool_has_been_displayed != true && $course->assigned_to_semester_num == $display_semesterNum)
  1909. {
  1910. $c = $course;
  1911. if ($remaining < $c->get_hours() || $remaining < 1)
  1912. {
  1913. continue;
  1914. }
  1915. $c->temp_flag = true;
  1916. $c->icon_filename = $group->icon_filename;
  1917. $c->title_text = "The student has been advised to take this course to fulfill a $group->title requirement.";
  1918. if (!$display_course_list->find_match($c))
  1919. {
  1920. $display_course_list->add($c);
  1921. }
  1922. }
  1923. }
  1924. }
  1925. }
  1926. $display_course_list->sort_advised_last_alphabetical();
  1927. $pC .= $this->display_group_course_list($display_course_list, $group, $display_semesterNum);
  1928. $fulfilled_hours = $display_course_list->count_hours("", false, false, true);
  1929. $fulfilled_credit_hours = $display_course_list->count_credit_hours("",false,true);
  1930. $test_hours = $fulfilled_hours;
  1931. // if the fulfilledCreditHours is > than the fulfilledHours,
  1932. // then assign the fulfilledCreditHours to the testHours.
  1933. if ($fulfilled_credit_hours > $fulfilled_hours)
  1934. { // done to fix a bug involving splitting hours in a substitution.
  1935. $test_hours = $fulfilled_credit_hours;
  1936. }
  1937. // If there are any remaining hours in this group,
  1938. // draw a "blank" selection row.
  1939. $remaining = $place_group->hours_required - $test_hours;
  1940. $place_group->hours_remaining = $remaining;
  1941. $place_group->hours_fulfilled = $fulfilled_hours;
  1942. $place_group->hours_fulfilled_for_credit = $fulfilled_credit_hours;
  1943. if ($remaining > 0)
  1944. {
  1945. $pC .= "<tr><td colspan='8' class='tenpt'>";
  1946. $pC .= $this->draw_group_select_row($place_group, $remaining);
  1947. $pC .= "</td></tr>";
  1948. }
  1949. return $pC;
  1950. }
  1951. /**
  1952. * Find all instaces of a Course in a Group and mark as displayed.
  1953. *
  1954. * @param Group $group
  1955. * @param Course $course
  1956. */
  1957. function mark_course_as_displayed(Group $group, Course $course)
  1958. {
  1959. // Find all instances of $course in $group,
  1960. // and mark as displayed.
  1961. if ($obj_list = $group->list_courses->find_all_matches($course))
  1962. {
  1963. $course_list = CourseList::cast($obj_list);
  1964. $course_list->mark_as_displayed();
  1965. }
  1966. // Now, go through all the course lists within each branch...
  1967. $group->list_groups->reset_counter();
  1968. while($group->list_groups->has_more())
  1969. {
  1970. $g = $group->list_groups->get_next();
  1971. if ($obj_list = $g->list_courses->find_all_matches($course))
  1972. {
  1973. $course_list = CourseList::cast($obj_list);
  1974. $course_list->mark_as_displayed($semester_num);
  1975. }
  1976. }
  1977. }
  1978. /**
  1979. * Displays all the courses in a CourseList object, using
  1980. * the draw_course_row function.
  1981. *
  1982. * It looks like the group and semester_num are not being used
  1983. * anymore.
  1984. *
  1985. * @todo Check on unused variables.
  1986. *
  1987. * @param CourseList $course_list
  1988. * @param unknown_type $group
  1989. * @param unknown_type $semester_num
  1990. * @return unknown
  1991. */
  1992. function display_group_course_list($course_list, $group, $semester_num)
  1993. {
  1994. $course_list->reset_counter();
  1995. while($course_list->has_more())
  1996. {
  1997. $course = $course_list->get_next();
  1998. $pC .= $this->draw_course_row($course, $course->icon_filename, $course->title_text, $course->temp_flag);
  1999. // Doesn't matter if its a specified repeat or not. Just
  2000. // mark it as having been displayed.
  2001. $course->bool_has_been_displayed = true;
  2002. }
  2003. return $pC;
  2004. }
  2005. /**
  2006. * This draws the "blank row" for a group on the degree plan, which instructs
  2007. * the user to click on it to select a course from the popup.
  2008. *
  2009. * @param Group $group
  2010. * @param int $remaining_hours
  2011. * @return string
  2012. */
  2013. function draw_group_select_row(Group $group, $remaining_hours)
  2014. {
  2015. $pC = "";
  2016. $img_path = fp_theme_location() . "/images";
  2017. $on_mouse_over = " onmouseover=\"style.backgroundColor='#FFFF99'\"
  2018. onmouseout=\"style.backgroundColor='white'\" ";
  2019. if ($this->page_is_mobile) $on_mouse_over = ""; // Causes problems for some mobile devices.
  2020. $w1_1 = $this->width_array[0];
  2021. $w1_2 = $this->width_array[1];
  2022. $w1_3 = $this->width_array[2];
  2023. $w2 = $this->width_array[3];
  2024. $w3 = $this->width_array[4];
  2025. $w4 = $this->width_array[5];
  2026. $w5 = $this->width_array[6];
  2027. $w6 = $this->width_array[7];
  2028. $s = "s";
  2029. if ($remaining_hours < 2)
  2030. {
  2031. $s = "";
  2032. }
  2033. $select_icon = "<img src='$img_path/select.gif' border='0'>";
  2034. $icon_link = "<img src='$img_path/icons/$group->icon_filename' width='19' height='19' border='0' alt='$title_text' title='$title_text'>";
  2035. $blank_degree_id = "";
  2036. if ($this->bool_blank)
  2037. {
  2038. $blank_degree_id = $this->degree_plan->degree_id;
  2039. }
  2040. $js_code = "selectCourseFromGroup(\"$group->group_id\", \"$group->assigned_to_semester_num\", \"$remaining_hours\", \"$blank_degree_id\");";
  2041. $row_msg = "<i>Click <font color='red'>&gt;&gt;</font> to select $remaining_hours hour$s.</i>";
  2042. $hand_class = "hand";
  2043. if ($this->bool_print)
  2044. {
  2045. // In print view, disable all popups and mouseovers.
  2046. $on_mouse_over = "";
  2047. $js_code = "";
  2048. $hand_class = "";
  2049. $row_msg = "<i>Select $remaining_hours hour$s from $group->title.</i>";
  2050. }
  2051. if ($group->group_id == -88)
  2052. { // This is the Add a Course group.
  2053. $row_msg = "<i>Click to add an additional course.</i>";
  2054. $select_icon = "<span style='font-size: 16pt; color:blue;'>+</span>";
  2055. $icon_link = "";
  2056. }
  2057. $pC .= "
  2058. <table border='0' cellpadding='0' width='100%' cellspacing='0' align='left'>
  2059. <tr height='20' class='$hand_class'
  2060. $on_mouse_over title='$group->title'>
  2061. <td width='$w1_1' align='left'>&nbsp;</td>
  2062. <td width='$w1_2' align='left' onClick='$js_code'>$icon_link</td>
  2063. <td width='$w1_3' align='left' onClick='$js_code'>$select_icon</td>
  2064. <td align='left' colspan='5' class='tenpt underline' onClick='$js_code'>
  2065. $row_msg
  2066. </tr>
  2067. </table>";
  2068. return $pC;
  2069. }
  2070. /**
  2071. * Uses the draw_box_top function, specifically for semesters.
  2072. *
  2073. * @param string $title
  2074. * @param bool $hideheaders
  2075. * @return string
  2076. */
  2077. function draw_semester_box_top($title, $hideheaders = false)
  2078. {
  2079. $w = 340;
  2080. if ($this->page_is_mobile) $w = "100%";
  2081. return $this->draw_box_top($title, $hideheaders, $w);
  2082. }
  2083. /**
  2084. * Uses the draw_box_bottom function, specifically for semesters.
  2085. * Actually, this function is a straight alias for $this->draw_box_bottom().
  2086. *
  2087. * @return string
  2088. */
  2089. function draw_semester_box_bottom()
  2090. {
  2091. return $this->draw_box_bottom();
  2092. }
  2093. /**
  2094. * Very, very simple. Just returns "</table>";
  2095. *
  2096. * @return string
  2097. */
  2098. function draw_box_bottom()
  2099. {
  2100. return "</table>";
  2101. }
  2102. /**
  2103. * Used to draw the beginning of semester boxes and other boxes, for example
  2104. * the footnotes.
  2105. *
  2106. * @param string $title
  2107. * @param bool $hideheaders
  2108. * - If TRUE, then the course/hrs/grd headers will not be displayed.
  2109. *
  2110. * @param int $table_width
  2111. * - The HTML table width, in pixels. If not set, it will default
  2112. * to 300 pixels wide.
  2113. *
  2114. * @return string
  2115. */
  2116. function draw_box_top($title, $hideheaders=false, $table_width = 300){
  2117. // returns the beginnings of the year tables...
  2118. // Get width values from width_array (supplied by calling function,
  2119. // for example, draw_year_box_top
  2120. $w1_1 = $this->width_array[0];
  2121. $w1_2 = $this->width_array[1];
  2122. $w1_3 = $this->width_array[2];
  2123. $w2 = $this->width_array[3];
  2124. $w3 = $this->width_array[4];
  2125. $w4 = $this->width_array[5];
  2126. $w5 = $this->width_array[6];
  2127. $w6 = $this->width_array[7];
  2128. if ($this->bool_popup == true)
  2129. {
  2130. $w1_1 = $this->popup_width_array[0];
  2131. $w1_2 = $this->popup_width_array[1];
  2132. $w1_3 = $this->popup_width_array[2];
  2133. $w2 = $this->popup_width_array[3];
  2134. $w3 = $this->popup_width_array[4];
  2135. $w4 = $this->popup_width_array[5];
  2136. $w5 = $this->popup_width_array[6];
  2137. $w6 = $this->popup_width_array[7];
  2138. }
  2139. $headers = array();
  2140. if ($hideheaders != true)
  2141. {
  2142. $headers[0] = t("Course");
  2143. $headers[1] = t("Hrs");
  2144. $headers[2] = t("Grd");
  2145. $headers[3] = t("Pts");
  2146. }
  2147. $rtn = "
  2148. <table border='0' width='$table_width' cellpadding='0' cellspacing='0' class='fp-box-top'>
  2149. <tr>
  2150. <td colspan='8' class='blueTitle' align='center' valign='top'>
  2151. ";
  2152. $rtn .= fp_render_curved_line($title);
  2153. $rtn .= "
  2154. </td>
  2155. </tr>
  2156. ";
  2157. if (!$hide_headers)
  2158. {
  2159. $rtn .= "
  2160. <tr height='20'>
  2161. <td width='$w1_1' align='left'>
  2162. &nbsp;
  2163. </td>
  2164. <td width='$w1_2' align='left'>
  2165. &nbsp;
  2166. </td>
  2167. <td width='$w1_3' align='left'>
  2168. &nbsp;
  2169. </td>
  2170. <td align='left' width='$w2'>
  2171. <font size='2'><b>$headers[0]</b></font>
  2172. </td>
  2173. <td width='$w3' align='left'>&nbsp;</td>
  2174. <td width='$w4'>
  2175. <font size='2'><b>$headers[1]</b></font>
  2176. </td>
  2177. <td width='$w5'>
  2178. <font size='2'><b>$headers[2]</b></font>
  2179. </td>
  2180. <td width='$w6'>
  2181. <font size='2'><b>$headers[3]</b></font>
  2182. </td>
  2183. </tr>
  2184. ";
  2185. }
  2186. return $rtn;
  2187. } // draw_year_box_top
  2188. /**
  2189. * This is used by lots of other functions to display a course on the screen.
  2190. * It will show the course, the hours, the grade, and quality points, as well
  2191. * as any necessary icons next to it.
  2192. *
  2193. * @param Course $course
  2194. * @param string $icon_filename
  2195. * @param string $title_text
  2196. * @param bool $js_toggle_and_save
  2197. * - If set to TRUE, when the checkbox next to this course is clicked,
  2198. * the page will be submitted and a draft will be saved.
  2199. *
  2200. * @param bool $bool_display_check
  2201. * - If set to FALSE, no checkbox will be displayed for this course row.
  2202. *
  2203. * @param bool $bool_add_footnote
  2204. * @param bool $bool_add_asterisk_to_transfers
  2205. *
  2206. * @return string
  2207. */
  2208. 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)
  2209. {
  2210. // Display a course itself...
  2211. $pC = "";
  2212. $w1_1 = $this->width_array[0];
  2213. $w1_2 = $this->width_array[1];
  2214. $w1_3 = $this->width_array[2];
  2215. $w2 = $this->width_array[3];
  2216. $w3 = $this->width_array[4];
  2217. $w4 = $this->width_array[5];
  2218. $w5 = $this->width_array[6];
  2219. $w6 = $this->width_array[7];
  2220. $img_path = fp_theme_location() . "/images";
  2221. // The current term we are advising for.
  2222. $advising_term_id = $GLOBALS["fp_advising"]["advising_term_id"];
  2223. if (!$advising_term_id) {
  2224. $advising_term_id = 0;
  2225. }
  2226. $course->assign_display_status();
  2227. // If the course has already been advised in a different semester,
  2228. // we should set the advising_term_id to that and disable unchecking.
  2229. if ($course->advised_term_id*1 > 0 && $course->bool_advised_to_take == true && $course->advised_term_id != $advising_term_id)
  2230. {
  2231. $course->display_status = "disabled";
  2232. $advising_term_id = $course->advised_term_id;
  2233. }
  2234. if ($course->subject_id == "")
  2235. {
  2236. $course->load_descriptive_data();
  2237. }
  2238. $subject_id = $course->subject_id;
  2239. $course_num = $course->course_num;
  2240. $o_subject_id = $subject_id;
  2241. $o_course_num = $course_num;
  2242. $footnote = "";
  2243. $ast = "";
  2244. // Is this actually a transfer course? If so, display its
  2245. // original subject_id and course_num.
  2246. if ($course->bool_transfer == true)
  2247. {
  2248. $subject_id = $course->course_transfer->subject_id;
  2249. $course_num = $course->course_transfer->course_num;
  2250. $institution_name = $course->course_transfer->institution_name;
  2251. if ($bool_add_asterisk_to_transfers == true)
  2252. {
  2253. $course->course_transfer->load_descriptive_transfer_data($this->student->student_id);
  2254. if ($course->course_transfer->transfer_eqv_text != "")
  2255. {
  2256. $ast = "*";
  2257. $GLOBALS["advising_course_has_asterisk"] = true;
  2258. }
  2259. }
  2260. // Apply a footnote if it has a local eqv.
  2261. if ($bool_add_footnote == true && $course->course_id > 0)
  2262. {
  2263. $footnote = "";
  2264. $footnote .= "<span class='superscript'>T";
  2265. $fcount = count($this->footnote_array["transfer"]) + 1;
  2266. if ($course->bool_has_been_displayed == true)
  2267. { // If we've already displayed this course once, and are
  2268. // now showing it again (like in the Transfer Credit list)
  2269. // we do not want to increment the footnote counter.
  2270. $fcount = $course->transfer_footnote;
  2271. }
  2272. $course->transfer_footnote = $fcount;
  2273. $footnote .= "$fcount</span>";
  2274. $this->footnote_array["transfer"][$fcount] = "$o_subject_id $o_course_num ~~ $subject_id $course_num ~~ ~~ $institution_name";
  2275. }
  2276. }
  2277. if ($course->bool_substitution == true )
  2278. {
  2279. if ($course->course_substitution->subject_id == "")
  2280. { // Reload subject_id, course_num, etc, for the substitution course,
  2281. // which is actually the original requirement.
  2282. if (is_object($course->course_substitution))
  2283. {
  2284. $course->course_substitution->load_descriptive_data();
  2285. }
  2286. }
  2287. $o_subject_id = $course->course_substitution->subject_id;
  2288. $o_course_num = $course->course_substitution->course_num;
  2289. if ($bool_add_footnote == true)
  2290. {
  2291. $footnote = "";
  2292. $footnote .= "<span class='superscript'>S";
  2293. $fcount = count($this->footnote_array["substitution"]) + 1;
  2294. if ($course->bool_has_been_displayed == true)
  2295. { // If we've already displayed this course once, and are
  2296. // now showing it again (like in the Transfer Credit list)
  2297. // we do not want to increment the footnote counter.
  2298. $fcount = $course->substitution_footnote;
  2299. }
  2300. $course->substitution_footnote = $fcount;
  2301. $footnote .= "$fcount</span>";
  2302. $this->footnote_array["substitution"][$fcount] = "$o_subject_id $o_course_num ~~ $subject_id $course_num ~~ $course->substitution_hours ~~ $course->assigned_to_group_id";
  2303. }
  2304. }
  2305. $hours = $course->hours_awarded * 1;
  2306. if ($hours <= 0) {
  2307. // Some kind of error-- default to catalog hours
  2308. $hours = $course->get_catalog_hours();
  2309. }
  2310. $hours = $hours * 1; // force numeric, trim extra zeros.
  2311. $var_hour_icon = "&nbsp;";
  2312. if ($course->has_variable_hours() == true && !$course->bool_taken)
  2313. {
  2314. // The bool_taken part of this IF statement is because if the course
  2315. // has been completed, we should only use the hours_awarded.
  2316. $var_hour_icon = "<img src='" . fp_theme_location() . "/images/var_hour.gif'
  2317. title='" . t("This course has variable hours.") . "'
  2318. alt='" . t("This course has variable hours.") . "'>";
  2319. $hours = $course->get_advised_hours();
  2320. }
  2321. if ($course->bool_ghost_hour == TRUE) {
  2322. // This course was given a "ghost hour", meaning it is actually
  2323. // worth 0 hours, not 1, even though it's hours_awarded is currently
  2324. // set to 1. So, let's just make the display be 0.
  2325. $hours = "0";
  2326. }
  2327. $grade = $course->grade;
  2328. $dispgrade = $grade;
  2329. // If there is a MID, then this is a midterm grade.
  2330. $dispgrade = str_replace("MID","<span class='superscript'>" . t("mid") . "</span>",$dispgrade);
  2331. if (strtoupper($grade) == "E")
  2332. { // Currently enrolled. Show no grade.
  2333. $dispgrade = "";
  2334. }
  2335. if ($course->bool_hide_grade)
  2336. {
  2337. $dispgrade = "--";
  2338. $this->bool_hiding_grades = true;
  2339. }
  2340. $display_status = $course->display_status;
  2341. if ($display_status == "completed")
  2342. {
  2343. $pts = $this->get_quality_points($grade, $hours);
  2344. }
  2345. $course_id = $course->course_id;
  2346. $semester_num = $course->assigned_to_semester_num;
  2347. $group_id = $course->assigned_to_group_id;
  2348. $random_id = $course->random_id;
  2349. $advised_hours = $course->advised_hours;
  2350. $unique_id = $course_id . "_" . $semester_num . "_" . rand(1,9999);
  2351. $hid_name = "advisecourse_$course_id" . "_$semester_num" . "_$group_id" . "_$advised_hours" . "_$random_id" . "_$advising_term_id" . "_random" . rand(1,9999);
  2352. $hid_value = "";
  2353. $opchecked = "";
  2354. if ($course->bool_advised_to_take == true)
  2355. {
  2356. $hid_value = "true";
  2357. $opchecked = "-check";
  2358. }
  2359. $op_on_click_function = "toggleSelection";
  2360. if ($js_toggle_and_save == true)
  2361. {
  2362. $op_on_click_function = "toggleSelectionAndSave";
  2363. }
  2364. $extra_js_vars = "";
  2365. if ($course->display_status == "disabled")
  2366. { // Checkbox needs to be disabled because this was advised in another
  2367. // term.
  2368. $op_on_click_function = "toggleDisabledChangeTerm";
  2369. $course->term_id = $course->advised_term_id;
  2370. $extra_js_vars = $course->get_term_description();
  2371. }
  2372. if ($course->display_status == "completed" || $course->display_status == "enrolled")
  2373. {
  2374. $op_on_click_function = "toggleDisabledCompleted";
  2375. $opchecked = "";
  2376. $extra_js_vars = $course->display_status;
  2377. }
  2378. if ($course->display_status == "retake")
  2379. {
  2380. // this course was probably subbed in while the student
  2381. // was still enrolled, and they have since made an F or W.
  2382. // So, disable it.
  2383. $op_on_click_function = "dummyToggleSelection";
  2384. $opchecked = "";
  2385. }
  2386. if ($this->bool_print || $this->bool_blank)
  2387. {
  2388. // If this is print view, disable clicking.
  2389. $op_on_click_function = "dummyToggleSelection";
  2390. }
  2391. if (!user_has_permission("can_advise_students"))
  2392. {
  2393. // This user does not have the abilty to advise,
  2394. // so take away the ability to toggle anything (like
  2395. // we are in print view).
  2396. $op_on_click_function = "dummyToggleSelection";
  2397. }
  2398. $op = "<img src='$img_path/cb_" . $display_status . "$opchecked.gif'
  2399. border='0'
  2400. id='cb_$unique_id'
  2401. onclick='{$op_on_click_function}(\"$unique_id\",\"$display_status\",\"$extra_js_vars\");'
  2402. >";
  2403. $hid = "<input type='hidden' name='$hid_name'
  2404. id='advisecourse_$unique_id' value='$hid_value'>";
  2405. // Okay, we can't actually serialize a course, as it takes too much space.
  2406. // It was slowing down the page load significantly! So, I am going
  2407. // to use a function I wrote called to_data_string().
  2408. $data_string = $course->to_data_string();
  2409. $blank_degree_id = "";
  2410. if ($this->bool_blank == true)
  2411. {
  2412. $blank_degree_id = $this->degree_plan->degree_id;
  2413. }
  2414. $js_code = "describeCourse(\"$data_string\",\"$blank_degree_id\");";
  2415. $icon_link = "";
  2416. if ($course->requirement_type == "um" || $course->requirement_type == "uc")
  2417. {
  2418. $icon_filename = "ucap.gif";
  2419. $title_text = t("This course is a University Capstone.");
  2420. }
  2421. if ($icon_filename != "") {
  2422. $icon_link = "<img src='" . fp_theme_location() . "/images/icons/$icon_filename' width='19' height='19' border='0' alt='$title_text' title='$title_text'>";
  2423. }
  2424. $on_mouse_over = " onmouseover=\"style.backgroundColor='#FFFF99'\"
  2425. onmouseout=\"style.backgroundColor='white'\" ";
  2426. if (fp_screen_is_mobile()) $on_mouse_over = ""; // Causes problems for some mobile devices.
  2427. $hand_class = "hand";
  2428. if ($bool_display_check == false) {
  2429. $op = $hid = "";
  2430. }
  2431. if ($this->bool_print) {
  2432. // In print view, disable all popups and mouseovers.
  2433. $on_mouse_over = "";
  2434. $js_code = "";
  2435. $hand_class = "";
  2436. }
  2437. $pC .= "<tr><td colspan='8'>";
  2438. if ($course->bool_substitution_new_from_split != true || ($course->bool_substitution_new_from_split == true && $course->display_status != "eligible")){
  2439. if ($course_num == ""){
  2440. $course_num = "&nbsp;";
  2441. }
  2442. $pC .= "
  2443. <table border='0' cellpadding='0' width='100%' cellspacing='0' align='left'>
  2444. <tr height='20' class='$hand_class $display_status'
  2445. $on_mouse_over title='$title_text'>
  2446. <td width='$w1_1' align='left'>$op$hid</td>
  2447. <td width='$w1_2' align='left' onClick='$js_code'>$icon_link</td>
  2448. <td width='$w1_3' align='left' onClick='$js_code'>&nbsp;$ast</td>
  2449. <td align='left' width='$w2' class='tenpt underline' onClick='$js_code'>
  2450. $subject_id</td>
  2451. <td class='tenpt underline' width='$w3' align='left'
  2452. onClick='$js_code'>
  2453. $course_num$footnote</td>
  2454. <td class='tenpt underline' width='$w4' onClick='$js_code'>$hours$var_hour_icon</td>
  2455. <td class='tenpt underline' width='$w5' onClick='$js_code'>$dispgrade&nbsp;</td>
  2456. <td class='tenpt underline' width='$w6' onClick='$js_code'>$pts&nbsp;</td>
  2457. </tr>
  2458. </table>";
  2459. } else {
  2460. // These are the leftover hours from a partial substitution.
  2461. $pC .= "
  2462. <table border='0' cellpadding='0' width='100%' cellspacing='0' align='left'>
  2463. <tr height='20' class='hand $display_status'
  2464. $on_mouse_over title='$title_text'>
  2465. <td width='$w1_1' align='left'>$op$hid</td>
  2466. <td width='$w1_2' align='left' onClick='$js_code'>$icon_link</td>
  2467. <td width='$w1_3' align='left' onClick='$js_code'>&nbsp;</td>
  2468. <td align='left' class='tenpt underline' onClick='$js_code'
  2469. colspan='4'>
  2470. &nbsp; &nbsp; $subject_id &nbsp;
  2471. $course_num$footnote
  2472. &nbsp; ($hours " . t("hrs left") . ")
  2473. </td>
  2474. </tr>
  2475. </table>";
  2476. }
  2477. $pC .= "</td></tr>";
  2478. return $pC;
  2479. }
  2480. /**
  2481. * Calculate the quality points for a grade and hours.
  2482. *
  2483. * This function is very similar to the one in the Course class.
  2484. * It is only slightly different here. Possibly, the two functions should be
  2485. * merged.
  2486. *
  2487. * @param string $grade
  2488. * @param int $hours
  2489. * @return int
  2490. */
  2491. function get_quality_points($grade, $hours){
  2492. $pts = 0;
  2493. $qpts_grades = array();
  2494. // Let's find out what our quality point grades & values are...
  2495. if (isset($GLOBALS["qpts_grades"])) {
  2496. // have we already cached this?
  2497. $qpts_grades = $GLOBALS["qpts_grades"];
  2498. }
  2499. else {
  2500. $tlines = explode("\n", variable_get("quality_points_grades", "A ~ 4\nB ~ 3\nC ~ 2\nD ~ 1\nF ~ 0\nI ~ 0"));
  2501. foreach ($tlines as $tline) {
  2502. $temp = explode("~", trim($tline));
  2503. if (trim($temp[0]) != "") {
  2504. $qpts_grades[trim($temp[0])] = trim($temp[1]);
  2505. }
  2506. }
  2507. $GLOBALS["qpts_grades"] = $qpts_grades; // save to cache
  2508. }
  2509. // Okay, find out what the points are by multiplying value * hours...
  2510. if (isset($qpts_grades[$grade])) {
  2511. $pts = $qpts_grades[$grade] * $hours;
  2512. }
  2513. return $pts;
  2514. }
  2515. /**
  2516. * Used in the group selection popup, this will display a course with
  2517. * a radio button next to it, so the user can select it.
  2518. *
  2519. * @param Course $course
  2520. * @param int $group_hours_remaining
  2521. *
  2522. * @return string
  2523. */
  2524. function draw_popup_group_select_course_row(Course $course, $group_hours_remaining = 0)
  2525. {
  2526. // Display a course itself...
  2527. $pC = "";
  2528. $w1_1 = $this->popup_width_array[0];
  2529. $w1_2 = $this->popup_width_array[1];
  2530. $w1_3 = $this->popup_width_array[2];
  2531. $w2 = $this->popup_width_array[3];
  2532. $w3 = $this->popup_width_array[4];
  2533. $w4 = $this->popup_width_array[5];
  2534. $w5 = $this->popup_width_array[6];
  2535. $w6 = $this->popup_width_array[7];
  2536. if ($course->subject_id == "")
  2537. {
  2538. // Lacking course's display data, so reload it from the DB.
  2539. $course->load_course($course->course_id);
  2540. }
  2541. $subject_id = $course->subject_id;
  2542. $course_num = $course->course_num;
  2543. $hours = $course->get_catalog_hours();
  2544. $display_status = $course->display_status;
  2545. $db_group_requirement_id = $course->db_group_requirement_id;
  2546. $grade = $course->grade;
  2547. $repeats = $course->specified_repeats;
  2548. if ($repeats > 0)
  2549. {
  2550. $w3 = "15%";
  2551. }
  2552. $course_id = $course->course_id;
  2553. $group_id = $course->assigned_to_group_id;
  2554. $semester_num = $course->assigned_to_semester_num;
  2555. $var_hour_icon = "&nbsp;";
  2556. if ($course->has_variable_hours() == true)
  2557. {
  2558. $var_hour_icon = "<img src='" . fp_theme_location() . "/images/var_hour.gif'
  2559. title='" . t("This course has variable hours.") . "'
  2560. alt='" . t("This course has variable hours.") . "'>";
  2561. }
  2562. $checked = "";
  2563. if ($course->bool_selected == true)
  2564. {
  2565. $checked = " checked='checked' ";
  2566. }
  2567. $op = "<input type='radio' name='course' value='$course_id' $checked>";
  2568. $hid = "<input type='hidden' name='$course_id" . "_subject'
  2569. id='$course_id" . "_subject' value='$subject_id'>
  2570. <input type='hidden' name='$course_id" . "_db_group_requirement_id'
  2571. id='$course_id" . "_db_group_requirement_id' value='$db_group_requirement_id'>";
  2572. $blank_degree_id = "";
  2573. if ($this->bool_blank)
  2574. {
  2575. $blank_degree_id = $this->degree_plan->degree_id;
  2576. }
  2577. //$serializedCourse = urlencode(serialize($course));
  2578. $js_code = "popupDescribeSelected(\"$group_id\",\"$semester_num\",\"$course_id\",\"$subject_id\",\"group_hours_remaining=$group_hours_remaining&db_group_requirement_id=$db_group_requirement_id&blank_degree_id=$blank_degree_id\");";
  2579. $on_mouse_over = " onmouseover=\"style.backgroundColor='#FFFF99'\"
  2580. onmouseout=\"style.backgroundColor='white'\" ";
  2581. if ($this->page_is_mobile) $on_mouse_over = ""; // Causes problems for some mobile devices.
  2582. $hand_class = "hand";
  2583. $extra_style = "";
  2584. if ($course->bool_unselectable == true)
  2585. {
  2586. // Cannot be selected, so remove that ability!
  2587. $hand_class = "";
  2588. $on_mouse_over = "";
  2589. $js_code = "";
  2590. $op = "";
  2591. $extra_style = "style='font-style: italic; color:gray;'";
  2592. }
  2593. $pC .= "
  2594. <table border='0' cellpadding='0' width='100%' cellspacing='0' align='left'>
  2595. <tr height='20' class='$hand_class $display_status'
  2596. $on_mouse_over title='$title_text'>
  2597. <td width='$w1_1' align='left'>$op$hid</td>
  2598. <td width='$w1_2' align='left' onClick='$js_code'>$icon_link</td>
  2599. <td width='$w1_3' align='left' onClick='$js_code'>&nbsp;</td>
  2600. <td align='left' width='$w2' class='tenpt underline'
  2601. onClick='$js_code' $extra_style>
  2602. $subject_id</td>
  2603. <td class='tenpt underline' $extra_style width='$w3' align='left'
  2604. onClick='$js_code'>
  2605. $course_num</td>
  2606. ";
  2607. if ($repeats > 0)
  2608. {
  2609. $pC .= "
  2610. <td class='tenpt underline' style='color: gray;'
  2611. onClick='$js_code' colspan='3'>
  2612. <i>" . t("May take up to") . " <span style='color: blue;'>" . ($repeats + 1) . "</span> " . t("times.") . "</i>
  2613. </td>
  2614. ";
  2615. } else {
  2616. $pC .= "
  2617. <td class='tenpt underline' width='$w4' onClick='$js_code' $extra_style>$hours&nbsp;$var_hour_icon</td>
  2618. <td class='tenpt underline' width='$w5' onClick='$js_code'>$grade&nbsp;</td>
  2619. <td class='tenpt underline' width='$w6' onClick='$js_code'>$pts&nbsp;</td>
  2620. ";
  2621. }
  2622. $pC .= "
  2623. </tr>
  2624. </table>";
  2625. return $pC;
  2626. }
  2627. /**
  2628. * This is used to display the substitution popup to a user, to let them
  2629. * actually make a substitution.
  2630. *
  2631. * @param int $course_id
  2632. * @param int $group_id
  2633. * @param int $semester_num
  2634. * @param int $hours_avail
  2635. *
  2636. * @return string
  2637. */
  2638. function display_popup_substitute($course_id = 0, $group_id, $semester_num, $hours_avail = "")
  2639. {
  2640. // This lets the user make a substitution for a course.
  2641. $pC = "";
  2642. $course = new Course($course_id);
  2643. $bool_sub_add = false;
  2644. $c_title = t("Substitute for") . " $course->subject_id $course->course_num";
  2645. if ($course_id == 0)
  2646. {
  2647. $c_title = t("Substitute an additional course");
  2648. $bool_sub_add = true;
  2649. }
  2650. $pC .= fp_render_curved_line($c_title);
  2651. $extra = ".<input type='checkbox' id='cbAddition' value='true' style='display:none;'>";
  2652. if ($group_id > 0)
  2653. {
  2654. $new_group = new Group($group_id);
  2655. $checked = "";
  2656. if ($bool_sub_add == true){$checked = "checked disabled";}
  2657. $extra = " " . t("in the group %newg.", array("%newg" => $new_group->title)) . "
  2658. " . t("Addition only:") . " <input type='checkbox' id='cbAddition' value='true' $checked>
  2659. <a href='javascript: alertSubAddition();'>?</a>";
  2660. }
  2661. $c_hours = $course->max_hours*1;
  2662. $c_ghost_hour = "";
  2663. if ($course->bool_ghost_hour == TRUE) {
  2664. $c_ghost_hour = t("ghost") . "<a href='javascript: alertSubGhost();'>?</a>";
  2665. }
  2666. if (($hours_avail*1 > 0 && $hours_avail < $c_hours) || ($c_hours < 1))
  2667. {
  2668. // Use the remaining hours if we have fewer hours left in
  2669. // the group than the course we are subbing for.
  2670. $c_hours = $hours_avail;
  2671. }
  2672. if ($hours_avail == "" || $hours_avail*1 < 1)
  2673. {
  2674. $hours_avail = $c_hours;
  2675. }
  2676. $pC .= "<div class='tenpt'>
  2677. " . t("Please select a course to substitute
  2678. for %course", array("%course" => "$course->subject_id $course->course_num ($c_hours $c_ghost_hour " . t("hrs") . ")")) . "$extra
  2679. </div>
  2680. <div class='tenpt'
  2681. style='height: 175px; overflow: auto; border:1px inset black; padding: 5px;'>
  2682. <table border='0' cellpadding='0' cellspacing='0' width='100%'>
  2683. ";
  2684. $this->student->list_courses_taken->sort_alphabetical_order(false, true);
  2685. for ($t = 0; $t <= 1; $t++)
  2686. {
  2687. if ($t == 0) {$the_title = "{$GLOBALS["fp_system_settings"]["school_initials"]} " . t("Credits"); $bool_transferTest = true;}
  2688. if ($t == 1) {$the_title = t("Transfer Credits"); $bool_transferTest = false;}
  2689. $pC .= "<tr><td colspan='3' valign='top' class='tenpt' style='padding-bottom: 10px;'>
  2690. $the_title
  2691. </td>
  2692. <td class='tenpt' valign='top' >" . t("Hrs") . "</td>
  2693. <td class='tenpt' valign='top' >" . t("Grd") . "</td>
  2694. <td class='tenpt' valign='top' >" . t("Term") . "</td>
  2695. </tr>";
  2696. $is_empty = true;
  2697. $this->student->list_courses_taken->reset_counter();
  2698. while($this->student->list_courses_taken->has_more())
  2699. {
  2700. $c = $this->student->list_courses_taken->get_next();
  2701. if ($c->bool_transfer == $bool_transferTest)
  2702. {
  2703. continue;
  2704. }
  2705. if (!$c->meets_min_grade_requirement_of(null, "D"))
  2706. {// Make sure the grade is OK.
  2707. continue;
  2708. }
  2709. $t_flag = 0;
  2710. if ($c->bool_transfer == true)
  2711. {
  2712. $t_flag = 1;
  2713. }
  2714. $is_empty = false;
  2715. $subject_id = $c->subject_id;
  2716. $course_num = $c->course_num;
  2717. $tcourse_id = $c->course_id;
  2718. if ($bool_transferTest == false)
  2719. {
  2720. // Meaning, we are looking at transfers now.
  2721. // Does the transfer course have an eqv set up? If so,
  2722. // we want *that* course to appear.
  2723. if (is_object($c->course_transfer))
  2724. {
  2725. $subject_id = $c->course_transfer->subject_id;
  2726. $course_num = $c->course_transfer->course_num;
  2727. $tcourse_id = $c->course_transfer->course_id;
  2728. $t_flag = 1;
  2729. }
  2730. }
  2731. $m_hours = $c->hours_awarded*1;
  2732. if ($c->max_hours*1 < $m_hours)
  2733. {
  2734. $m_hours = $c->max_hours*1;
  2735. }
  2736. if (($hours_avail*1 > 0 && $hours_avail < $m_hours) || ($m_hours < 1))
  2737. {
  2738. $m_hours = $hours_avail;
  2739. }
  2740. // is max_hours more than the original course's hours?
  2741. if ($m_hours > $c_hours)
  2742. {
  2743. $m_hours = $c_hours;
  2744. }
  2745. if ($m_hours > $c->hours_awarded)
  2746. {
  2747. $m_hours = $c->hours_awarded;
  2748. }
  2749. if ($c->bool_substitution != true && $c->bool_outdated_sub != true)
  2750. {
  2751. $h = $c->hours_awarded;
  2752. if ($c->bool_ghost_hour == TRUE) {
  2753. $h .= "(ghost<a href='javascript: alertSubGhost();'>?</a>)";
  2754. }
  2755. $pC .= "<tr>
  2756. <td valign='top' class='tenpt' width='15%'>
  2757. <input type='radio' name='subCourse' id='subCourse' value='$tcourse_id'
  2758. onClick='popupUpdateSubData(\"$m_hours\",\"$c->term_id\",\"$t_flag\",\"$hours_avail\",\"$c->hours_awarded\");'>
  2759. </td>
  2760. <td valign='top' class='tenpt underline' width='13%'>
  2761. $subject_id
  2762. </td>
  2763. <td valign='top' class='tenpt underline' width='15%'>
  2764. $course_num
  2765. </td>
  2766. <td valign='top' class='tenpt underline' width='10%'>
  2767. $h
  2768. </td>
  2769. <td valign='top' class='tenpt underline' width='10%'>
  2770. $c->grade
  2771. </td>
  2772. <td valign='top' class='tenpt underline'>
  2773. " . $c->get_term_description(true) . "
  2774. </td>
  2775. </tr>
  2776. ";
  2777. } else {
  2778. if (is_object($c->course_substitution) && $c->course_substitution->subject_id == "")
  2779. { // Load subject_id and course_num of the original
  2780. // requirement.
  2781. $c->course_substitution->load_descriptive_data();
  2782. }
  2783. $extra = "";
  2784. if ($c->assigned_to_group_id > 0)
  2785. {
  2786. $new_group = new Group($c->assigned_to_group_id);
  2787. $extra = " in $new_group->title";
  2788. }
  2789. if ($c->bool_outdated_sub == true)
  2790. {
  2791. $help_link = "<a href='javascript: popupHelpWindow(\"help.php?i=9\");' class='nounderline'>(?)</a>";
  2792. $extra .= " <span style='color:red;'>[" . t("Outdated") . "$help_link]</span>";
  2793. }
  2794. // It has already been substituted!
  2795. $pC .= "<tr style='background-color: beige;'>
  2796. <td valign='top' class='tenpt' width='15%'>
  2797. " . t("Sub:") . "
  2798. </td>
  2799. <td valign='top' class='tenpt' colspan='5'>
  2800. $subject_id
  2801. $course_num ($c->substitution_hours)
  2802. -> " . $c->course_substitution->subject_id . "
  2803. " . $c->course_substitution->course_num . "$extra
  2804. </td>
  2805. </tr>
  2806. ";
  2807. }
  2808. }
  2809. if ($is_empty == true)
  2810. {
  2811. // Meaning, there were no credits (may be the case with
  2812. // transfer credits)
  2813. $pC .= "<tr><td colspan='8' class='tenpt'>
  2814. - " . t("No substitutable credits available.") . "
  2815. </td></tr>";
  2816. }
  2817. $pC .= "<tr><td colspan='4'>&nbsp;</td></tr>";
  2818. }
  2819. $pC .= "</table></div>
  2820. <div class='tenpt' style='margin-top: 5px;'>
  2821. " . t("Select number of hrs to use:") . "
  2822. <select name='subHours' id='subHours' onChange='popupOnChangeSubHours()'>
  2823. <option value=''>" . t("None Selected") . "</option>
  2824. </select>
  2825. ";
  2826. // If we have entered manual hours (like for decimals), they go here:
  2827. // The subManual span will *display* them, the hidden field keeps them so they can be transmitted.
  2828. $pC .= "
  2829. <span id='subManual' style='font-style:italic; display:none;'></span>
  2830. <input type='hidden' id='subManualHours' value=''>
  2831. </div>
  2832. <input type='hidden' name='subTransferFlag' id='subTransferFlag' value=''>
  2833. <input type='hidden' name='subTermID' id='subTermID' value=''>
  2834. <input type='button' value='Save Substitution' onClick='popupSaveSubstitution(\"$course_id\",\"$group_id\",\"$semester_num\");'>
  2835. <div class='tenpt' style='padding-top: 5px;'><b>" . t("Optional") . "</b> - " . t("Enter remarks:") . "
  2836. <input type='text' name='subRemarks' id='subRemarks' value='' size='30' maxlength='254'>
  2837. </div>
  2838. ";
  2839. return $pC;
  2840. }
  2841. /**
  2842. * This function displays the popup which lets a user select a course to be
  2843. * advised into a group.
  2844. *
  2845. * @param Group $place_group
  2846. * @param int $group_hours_remaining
  2847. * @return string
  2848. */
  2849. function display_popup_group_select(Group $place_group, $group_hours_remaining = 0)
  2850. {
  2851. $pC = "";
  2852. $advising_term_id = $GLOBALS["fp_advising"]["advising_term_id"];
  2853. if ($place_group->group_id != -88)
  2854. {
  2855. // This is NOT the Add a Course group.
  2856. if (!$group = $this->degree_plan->find_group($place_group->group_id))
  2857. {
  2858. fpm("Group not found.");
  2859. return;
  2860. }
  2861. } else {
  2862. // This is the Add a Course group.
  2863. $group = $place_group;
  2864. }
  2865. $group_id = $group->group_id;
  2866. // So now we have a group object, $group, which is most likely
  2867. // missing courses. This is because when we loaded & cached it
  2868. // earlier, we did not load any course which wasn't a "significant course,"
  2869. // meaning, the student didn't have credit for it or the like.
  2870. // So what we need to do now is reload the group, being careful
  2871. // to preserve the existing courses / sub groups in the group.
  2872. $group->reload_missing_courses();
  2873. if ($group_hours_remaining == 0)
  2874. {
  2875. // Attempt to figure out the remaining hours (NOT WORKING IN ALL CASES!)
  2876. // This specifically messes up when trying to get fulfilled hours in groups
  2877. // with branches.
  2878. $group_fulfilled_hours = $group->get_fulfilled_hours(true, true, false, $place_group->assigned_to_semester_num);
  2879. $group_hours_remaining = $place_group->hours_required - $group_fulfilled_hours;
  2880. }
  2881. $display_semesterNum = $place_group->assigned_to_semester_num;
  2882. $pC .= "<!--MSG--><!--MSG2--><!--BOXTOP-->";
  2883. $bool_display_submit = true;
  2884. $bool_display_back_to_subject_select = false;
  2885. $bool_subject_select = false;
  2886. $bool_unselectableCourses = false;
  2887. $final_course_list = new CourseList();
  2888. $group->list_courses->reset_counter();
  2889. if (!($group->list_courses->is_empty))
  2890. {
  2891. $group->list_courses->assign_semester_num($display_semesterNum);
  2892. $new_course_list = $group->list_courses;
  2893. // Is this list so long that we first need to ask the user to
  2894. // select a subject?
  2895. if ($new_course_list->get_size() > 30)
  2896. {
  2897. // First, we are only going to do this if there are more
  2898. // than 30 courses, AND more than 2 subjects in the list.
  2899. $new_course_list->sort_alphabetical_order();
  2900. $subject_array = $new_course_list->get_course_subjects();
  2901. //print_pre($new_course_list->to_string());
  2902. //var_dump($subject_array);
  2903. if (count($subject_array) > 2)
  2904. {
  2905. // First, check to see if the user has already
  2906. // selected a subject.
  2907. $selected_subject = trim(addslashes($_GET["selected_subject"]));
  2908. if ($selected_subject == "")
  2909. {
  2910. // Prompt them to select a subject first.
  2911. $pC .= $this->draw_popup_group_subject_select($subject_array, $group->group_id, $display_semesterNum, $group_hours_remaining);
  2912. $new_course_list = new CourseList(); // empty it
  2913. $bool_display_submit = false;
  2914. $bool_subject_select = true;
  2915. } else {
  2916. // Reduce the newCourseList to only contain the
  2917. // subjects selected.
  2918. $new_course_list->exclude_all_subjects_except($selected_subject);
  2919. $bool_display_back_to_subject_select = true;
  2920. }
  2921. }
  2922. }
  2923. $new_course_list->reset_counter();
  2924. $new_course_list->sort_alphabetical_order();
  2925. $final_course_list->add_list($new_course_list);
  2926. }
  2927. if (!($group->list_groups->is_empty))
  2928. {
  2929. // Basically, this means that this group
  2930. // has multiple subgroups. We need to find out
  2931. // which branches the student may select from
  2932. // (based on what they have already taken, or been
  2933. // advised to take), and display it (excluding duplicates).
  2934. //print_pre($group->to_string());
  2935. // The first thing we need to do, is find the subgroup
  2936. // or subgroups with the most # of matches.
  2937. $new_course_list = new CourseList();
  2938. $all_zero= true;
  2939. // Okay, this is a little squirely. What I need to do
  2940. // first is get a course list of all the courses which
  2941. // are currently either fulfilling or advised for all branches
  2942. // of this group.
  2943. $fa_course_list = new CourseList();
  2944. $group->list_groups->reset_counter();
  2945. while($group->list_groups->has_more())
  2946. {
  2947. $branch = $group->list_groups->get_next();
  2948. $fa_course_list->add_list($branch->list_courses->get_fulfilled_or_advised(true));
  2949. }
  2950. $fa_course_list->remove_duplicates();
  2951. //print_pre($fa_course_list->to_string());
  2952. // Alright, now we create a fake student and set their
  2953. // list_courses_taken, so that we can use this student
  2954. // to recalculate the count_of_matches in just a moment.
  2955. $new_student = new Student();
  2956. $new_student->load_student();
  2957. $new_student->list_courses_taken = $fa_course_list;
  2958. $new_student->load_significant_courses_from_list_courses_taken();
  2959. // Okay, now we need to go through and re-calculate our
  2960. // count_of_matches for each branch. This is because we
  2961. // have cached this value, and after some advisings, it may
  2962. // not be true any longer.
  2963. $highest_match_count = 0;
  2964. $group->list_groups->reset_counter();
  2965. while($group->list_groups->has_more())
  2966. {
  2967. $branch = $group->list_groups->get_next();
  2968. // recalculate count_of_matches here.
  2969. $clone_branch = new Group();
  2970. $clone_branch->list_courses = $branch->list_courses->get_clone(true);
  2971. $matches_count = $this->flightpath->get_count_of_matches($clone_branch, $new_student, null);
  2972. $branch->count_of_matches = $matches_count;
  2973. if ($matches_count >= $highest_match_count)
  2974. { // Has more than one match on this branch.
  2975. $highest_match_count = $matches_count;
  2976. }
  2977. }
  2978. // If highestMatchCount > 0, then get all the branches
  2979. // which have that same match count.
  2980. if ($highest_match_count > 0)
  2981. {
  2982. $group->list_groups->reset_counter();
  2983. while($group->list_groups->has_more())
  2984. {
  2985. $branch = $group->list_groups->get_next();
  2986. if ($branch->count_of_matches == $highest_match_count)
  2987. { // This branch has the right number of matches. Add it.
  2988. $new_course_list->add_list($branch->list_courses);
  2989. $all_zero = false;
  2990. }
  2991. }
  2992. }
  2993. if ($all_zero == true)
  2994. {
  2995. // Meaning, all of the branches had 0 matches,
  2996. // so we should add all the branches to the
  2997. // newCourseList.
  2998. $group->list_groups->reset_counter();
  2999. while($group->list_groups->has_more())
  3000. {
  3001. $branch = $group->list_groups->get_next();
  3002. $new_course_list->add_list($branch->list_courses);
  3003. }
  3004. } else {
  3005. // Meaning that at at least one branch is favored.
  3006. // This also means that a user's course
  3007. // selections have been restricted as a result.
  3008. // Replace the MSG at the top saying so.
  3009. $msg = "<div class='tenpt'>" . t("Your selection of courses has been
  3010. restricted based on previous course selections.") . "</div>";
  3011. $pC = str_replace("<!--MSG-->", $msg, $pC);
  3012. }
  3013. // Okay, in the newCourseList object, we should
  3014. // now have a list of all the courses the student is
  3015. // allowed to take, but there are probably duplicates.
  3016. //print_pre($new_course_list->to_string());
  3017. $new_course_list->remove_duplicates();
  3018. $new_course_list->assign_group_id($group->group_id);
  3019. $new_course_list->assign_semester_num($display_semesterNum);
  3020. $final_course_list->add_list($new_course_list);
  3021. }
  3022. //print_pre($final_course_list->to_string());
  3023. // Remove courses which have been marked as "exclude" in the database.
  3024. $final_course_list->remove_excluded();
  3025. //print_pre($final_course_list->to_string());
  3026. // Here's a fun one: We need to remove courses for which the student
  3027. // already has credit that *don't* have repeating hours.
  3028. // For example, if a student took MATH 113, and it fills in to
  3029. // Core Math, then we should not see it as a choice for advising
  3030. // in Free Electives (or any other group except Add a Course).
  3031. // We also should not see it in other instances of Core Math.
  3032. if ($group->group_id != -88 && $this->bool_blank != TRUE)
  3033. {
  3034. // Only do this if NOT in Add a Course group...
  3035. // also, don't do it if we're looking at a "blank" degree.
  3036. $final_course_list->remove_previously_fulfilled($this->student->list_courses_taken, $group->group_id, true, $this->student->list_substitutions);
  3037. }
  3038. $final_course_list->sort_alphabetical_order();
  3039. if (!$final_course_list->has_any_course_selected()) {
  3040. if ($c = $final_course_list->find_first_selectable()) {
  3041. $c->bool_selected = true;
  3042. }
  3043. }
  3044. // flag any courses with more hours than are available for this group.
  3045. if ($final_course_list->assign_unselectable_courses_with_hours_greater_than($group_hours_remaining))
  3046. {
  3047. $bool_unselectableCourses = true;
  3048. }
  3049. $pC .= $this->display_popup_group_select_course_list($final_course_list, $group_hours_remaining);
  3050. // If there were no courses in the finalCourseList, display a message.
  3051. if (count($final_course_list->array_list) < 1 && !$bool_subject_select)
  3052. {
  3053. $pC .= "<tr>
  3054. <td colspan='8'>
  3055. <div class='tenpt'>
  3056. <b>Please Note:</b>
  3057. " . t("FlightPath could not find any eligible
  3058. courses to display for this list. Ask your advisor
  3059. if you have completed courses, or may enroll in
  3060. courses, which can be
  3061. displayed here.");
  3062. if (user_has_permission("can_advise_students")){
  3063. // This is an advisor, so put in a little more
  3064. // information.
  3065. $pC .= "
  3066. <div class='tenpt' style='padding-top: 5px;'><b>" . t("Special note to advisors:") . "</b> " . t("You may still
  3067. advise a student to take a course, even if it is unselectable
  3068. in this list. Use the \"add an additional course\" link at
  3069. the bottom of the page.") . "</div>";
  3070. }
  3071. $pC .= " </div>
  3072. </td>
  3073. </tr>";
  3074. $bool_no_courses = true;
  3075. }
  3076. $pC .= $this->draw_semester_box_bottom();
  3077. $s = "s";
  3078. //print_pre($place_group->to_string());
  3079. if ($group_hours_remaining == 1){$s = "";}
  3080. if ($bool_unselectableCourses == true) {
  3081. $unselectable_notice = " <div class='tenpt'><i>(" . t("Courses worth more than %hrs hour$s
  3082. may not be selected.", array("%hrs" => $group_hours_remaining)) . ")</i></div>";
  3083. if (user_has_permission("can_advise_students")) {
  3084. // This is an advisor, so put in a little more
  3085. // information.
  3086. $unselectable_notice .= "
  3087. <div class='tenpt' style='padding-top: 5px;'><b>" . t("Special note to advisors:") . "</b> " . t("You may still
  3088. advise a student to take a course, even if it is unselectable
  3089. in this list. Use the \"add an additional course\" link at
  3090. the bottom of the page.") . "</div>";
  3091. }
  3092. }
  3093. if ($group_hours_remaining < 100 && $bool_no_courses != true) {
  3094. // Don't show for huge groups (like add-a-course)
  3095. $pC .= "<div class='elevenpt' style='margin-top:5px;'>
  3096. " . t("You may select <b>@hrs</b>
  3097. hour$s from this list.", array("@hrs" => $group_hours_remaining)) . "$unselectable_notice</div>";
  3098. }
  3099. if ($bool_display_submit == true && !$this->bool_blank && $bool_no_courses != true)
  3100. {
  3101. if (user_has_permission("can_advise_students")) {
  3102. $pC .= "<input type='hidden' name='varHours' id='varHours' value=''>
  3103. <div style='margin-top: 20px;'>
  3104. " . 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;'") . "
  3105. </div>
  3106. ";
  3107. }
  3108. }
  3109. // Substitutors get extra information:
  3110. if (user_has_permission("can_substitute") && $group->group_id != -88)
  3111. {
  3112. $pC .= "<div class='tenpt' style='margin-top: 20px;'>
  3113. <b>" . t("Special administrative information:") . "</b>
  3114. <span id='viewinfolink'
  3115. onClick='document.getElementById(\"admin_info\").style.display=\"\"; this.style.display=\"none\"; '
  3116. class='hand' style='color: blue;'
  3117. > - " . t("Click to show") . " -</span>
  3118. <div style='padding-left: 20px; display:none;' id='admin_info'>
  3119. " . t("Information about this group:") . "<br>
  3120. &nbsp; " . t("Group ID:") . " $group->group_id<br>
  3121. &nbsp; " . t("Title:") . " $group->title<br>";
  3122. $pC .= "&nbsp; <i>" . t("Internal name:") . " $group->group_name</i><br>";
  3123. $pC .= "&nbsp; " . t("Catalog year:") . " $group->catalog_year
  3124. </div>
  3125. </div>";
  3126. }
  3127. if ($bool_display_back_to_subject_select == true) {
  3128. $csid = $GLOBALS["current_student_id"];
  3129. $blank_degree_id = "";
  3130. if ($this->bool_blank)
  3131. {
  3132. $blank_degree_id = $this->degree_plan->degree_id;
  3133. }
  3134. $back_link = "<span class='tenpt'>
  3135. <a href='" . base_path() . "/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'
  3136. class='nounderline'>" . t("Click here to return to subject selection.") . "</a></span>";
  3137. $pC = str_replace("<!--MSG2-->",$back_link,$pC);
  3138. }
  3139. $box_top = $this->draw_semester_box_top("$group->title", !$bool_display_submit);
  3140. $pC = str_replace("<!--BOXTOP-->",$box_top,$pC);
  3141. return $pC;
  3142. }
  3143. /**
  3144. * When the groupSelect has too many courses, they are broken down into
  3145. * subjects, and the user first selects a subject. This function will
  3146. * draw out that select list.
  3147. *
  3148. * @param array $subject_array
  3149. * @param int $group_id
  3150. * @param int $semester_num
  3151. * @param int $group_hours_remaining
  3152. * @return string
  3153. */
  3154. function draw_popup_group_subject_select($subject_array, $group_id, $semester_num, $group_hours_remaining = 0)
  3155. {
  3156. $csid = $GLOBALS["current_student_id"];
  3157. $blank_degree_id = "";
  3158. if ($this->bool_blank)
  3159. {
  3160. $blank_degree_id = $this->degree_plan->degree_id;
  3161. }
  3162. $pC .= "<tr><td colspan='8' class='tenpt'>";
  3163. $pC .= "<form action='" . base_path() . "/advise/popup-group-select' method='GET' style='margin:0px; padding:0px;' id='theform'>
  3164. <input type='hidden' name='window_mode' value='popup'>
  3165. <input type='hidden' name='group_id' value='$group_id'>
  3166. <input type='hidden' name='semester_num' value='$semester_num'>
  3167. <input type='hidden' name='group_hours_remaining' value='$group_hours_remaining'>
  3168. <input type='hidden' name='current_student_id' value='$csid'>
  3169. <input type='hidden' name='blank_degree_id' value='$blank_degree_id'>
  3170. " . t("Please begin by selecting a subject from the list below.") . "
  3171. <br><br>
  3172. <select name='selected_subject'>
  3173. <option value=''>" . t("Please select a subject...") . "</option>
  3174. <option value=''>----------------------------------------</option>
  3175. ";
  3176. $new_array = array();
  3177. foreach($subject_array as $key => $subject_id)
  3178. {
  3179. if ($title = $this->flightpath->get_subject_title($subject_id)) {
  3180. $new_array[] = "$title ~~ $subject_id";
  3181. } else {
  3182. $new_array[] = "$subject_id ~~ $subject_id";
  3183. }
  3184. }
  3185. sort($new_array);
  3186. foreach ($new_array as $key => $value)
  3187. {
  3188. $temp = explode(" ~~ ",$value);
  3189. $title = trim($temp[0]);
  3190. $subject_id = trim($temp[1]);
  3191. $pC .= "<option value='$subject_id'>$title ($subject_id)</option>";
  3192. }
  3193. $pC .= "</select>
  3194. <div style='margin: 20px;' align='left'>
  3195. " . fp_render_button(t("Next") . " ->","document.getElementById(\"theform\").submit();") . "
  3196. </div>
  3197. <!-- <input type='submit' value='submit'> -->
  3198. </form>
  3199. ";
  3200. $pC .= "</td></tr>";
  3201. return $pC;
  3202. }
  3203. /**
  3204. * Accepts a CourseList object and draws it out to the screen. Meant to
  3205. * be called by display_popup_group_select();
  3206. *
  3207. * @param CourseList $course_list
  3208. * @param int $group_hours_remaining
  3209. * @return string
  3210. */
  3211. function display_popup_group_select_course_list(CourseList $course_list = null, $group_hours_remaining = 0)
  3212. {
  3213. // Accepts a CourseList object and draws it out to the screen. Meant to
  3214. // be called by display_popup_group_select().
  3215. $pC = "";
  3216. if ($course_list == null)
  3217. {
  3218. return;
  3219. }
  3220. $old_course = null;
  3221. $course_list->reset_counter();
  3222. while($course_list->has_more())
  3223. {
  3224. $course = $course_list->get_next();
  3225. if ($course->equals($old_course))
  3226. { // don't display the same course twice in a row.
  3227. continue;
  3228. }
  3229. $pC .= "<tr><td colspan='8'>";
  3230. if ($course->course_list_fulfilled_by->is_empty && !$course->bool_advised_to_take)
  3231. { // So, only display if it has not been fulfilled by anything.
  3232. $pC .= $this->draw_popup_group_select_course_row($course, $group_hours_remaining);
  3233. $old_course = $course;
  3234. }
  3235. $pC .= "</td></tr>";
  3236. }
  3237. return $pC;
  3238. }
  3239. /**
  3240. * Returns a list of "hidden" HTML input tags which are used to keep
  3241. * track of advising variables between page loads.
  3242. *
  3243. * @param string $perform_action
  3244. * - Used for when we submit the form, so that FlightPath will
  3245. * know what action we are trying to take.
  3246. *
  3247. * @return string
  3248. */
  3249. function get_hidden_advising_variables($perform_action = "")
  3250. {
  3251. $rtn = "";
  3252. $rtn .= "<span id='hidden_elements'>
  3253. <input type='hidden' name='perform_action' id='perform_action' value='$perform_action'>
  3254. <input type='hidden' name='perform_action2' id='perform_action2' value=''>
  3255. <input type='hidden' name='scroll_top' id='scroll_top' value=''>
  3256. <input type='hidden' name='load_from_cache' id='load_from_cache' value='yes'>
  3257. <input type='hidden' name='print_view' id='print_view' value='{$GLOBALS["print_view"]}'>
  3258. <input type='hidden' name='hide_charts' id='hide_charts' value=''>
  3259. <input type='hidden' name='advising_load_active' id='advising_load_active' value='{$GLOBALS["fp_advising"]["advising_load_active"]}'>
  3260. <input type='hidden' name='advising_student_id' id='advising_student_id' value='{$GLOBALS["fp_advising"]["advising_student_id"]}'>
  3261. <input type='hidden' name='advising_term_id' id='advising_term_id' value='{$GLOBALS["fp_advising"]["advising_term_id"]}'>
  3262. <input type='hidden' name='advising_major_code' id='advising_major_code' value='{$GLOBALS["fp_advising"]["advising_major_code"]}'>
  3263. <input type='hidden' name='advising_track_code' id='advising_track_code' value='{$GLOBALS["fp_advising"]["advising_track_code"]}'>
  3264. <input type='hidden' name='advising_update_student_settings_flag' id='advising_update_student_settings_flag' value=''>
  3265. <input type='hidden' name='advising_what_if' id='advising_what_if' value='{$GLOBALS["fp_advising"]["advising_what_if"]}'>
  3266. <input type='hidden' name='what_if_major_code' id='what_if_major_code' value='{$GLOBALS["fp_advising"]["what_if_major_code"]}'>
  3267. <input type='hidden' name='what_if_track_code' id='what_if_track_code' value='{$GLOBALS["fp_advising"]["what_if_track_code"]}'>
  3268. <input type='hidden' name='advising_view' id='advising_view' value='{$GLOBALS["fp_advising"]["advising_view"]}'>
  3269. <input type='hidden' name='current_student_id' id='current_student_id' value='{$GLOBALS["fp_advising"]["current_student_id"]}'>
  3270. <input type='hidden' name='log_addition' id='log_addition' value=''>
  3271. <input type='hidden' name='fp_update_user_settings_flag' id='fp_update_user_settings_flag' value=''>
  3272. </span>
  3273. ";
  3274. return $rtn;
  3275. }
  3276. }