admin.degrees.inc

  1. 7.x modules/admin/admin.degrees.inc
  2. 6.x modules/admin/admin.degrees.inc
  3. 4.x modules/admin/admin.degrees.inc
  4. 5.x modules/admin/admin.degrees.inc

File

modules/admin/admin.degrees.inc
View source
  1. <?php
  2. function admin_display_degrees_popup_add_group() {
  3. $semester_num = trim($_GET["semester_num"]);
  4. $de_catalog_year = admin_get_de_catalog_year();
  5. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  6. $rtn = "";
  7. $rtn .= "<b>" . t("Add an elective group to semester: @semester_num in @de_catalog_year", array("@semester_num" => $semester_num, "@de_catalog_year" => $de_catalog_year)) . "</b><br>
  8. <span class='tenpt'>" . t("Use keyboard shortcut CTRL-F to find groups quickly.") . "</span>
  9. <br><br>
  10. First, select a group (from $de_catalog_year):
  11. <div class='tenpt'
  12. style='height:200px; overflow-y: scroll; border: 1px solid black;
  13. margin:5px;'>
  14. <table border='0' cellspacing='5'>";
  15. $res = db_query("SELECT * FROM draft_groups
  16. WHERE catalog_year = '?'
  17. AND delete_flag = '0'
  18. ORDER BY title ", $de_catalog_year);
  19. while($cur = db_fetch_array($res)) {
  20. extract($cur, 3, "db");
  21. $rtn .= "<tr><td valign='middle'>
  22. <input type='radio' name='rgroups' value='$db_group_id'></td>
  23. <td valign='top' class='tenpt'>
  24. $db_title<br><i>$db_group_name</i>
  25. </td>
  26. </tr>
  27. ";
  28. }
  29. $min_grades = csv_to_array(variable_get("group_min_grades", "A,B,C,D"));
  30. $rtn .= "</table></div>
  31. " . t("Next, select properties for this group:") . "
  32. <a href='javascript: adminPopupAlertHelp(\"group_properties\");'>?</a>
  33. <div class='tenpt' style='padding-top: 5px;'>
  34. Hrs: <input type='text' name='hours' id='hours' size='2'>
  35. Min Grade: <select name='min_grade' id='min_grade'>
  36. <option value=''>--</option>
  37. ";
  38. foreach ($min_grades as $g) {
  39. $rtn .= "<option value='$g'>$g</option>";
  40. }
  41. $rtn .= "
  42. </select>
  43. Type: <select name='type' id='type'>";
  44. // Get our list of requirement types from our settings.
  45. $types = fp_get_requirement_types();
  46. foreach ($types as $code => $desc) {
  47. $rtn .= "<option value='$code'>$code - $desc</option>";
  48. }
  49. $rtn .= "
  50. </select>
  51. &nbsp; &nbsp;
  52. " . fp_render_button("Add group &raquo;", "adminPopupAddGroup(\"$semester_num\");") . "
  53. </div>";
  54. return $rtn;
  55. }
  56. function admin_display_degrees_popup_add_group2() {
  57. $semester_num = trim($_GET["semester_num"]);
  58. $de_catalog_year = admin_get_de_catalog_year();
  59. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  60. $rtn = "";
  61. $rtn .= "<b>" . t("VERSION 2 - Add an elective group to semester: @semester_num in @de_catalog_year", array("@semester_num" => $semester_num, "@de_catalog_year" => $de_catalog_year)) . "</b><br>
  62. <span class='tenpt'>" . t("Use keyboard shortcut CTRL-F to find groups quickly.") . "</span>
  63. <br><br>
  64. First, select a group (from $de_catalog_year):
  65. <div class='tenpt'
  66. style='height:200px; overflow-y: scroll; border: 1px solid black;
  67. margin:5px;'>
  68. <table border='0' cellspacing='5'>";
  69. $res = db_query("SELECT * FROM draft_groups
  70. WHERE catalog_year = '?'
  71. AND delete_flag = '0'
  72. ORDER BY title ", $de_catalog_year);
  73. while($cur = db_fetch_array($res)) {
  74. extract($cur, 3, "db");
  75. $rtn .= "<tr><td valign='middle'>
  76. <input type='radio' name='rgroups' value='$db_group_id'></td>
  77. <td valign='top' class='tenpt'>
  78. $db_title<br><i>$db_group_name</i>
  79. </td>
  80. </tr>
  81. ";
  82. }
  83. $min_grades = csv_to_array(variable_get("group_min_grades", "A,B,C,D"));
  84. $rtn .= "</table></div>
  85. " . t("Next, select properties for this group:") . "
  86. <a href='javascript: adminPopupAlertHelp(\"group_properties\");'>?</a>
  87. <div class='tenpt' style='padding-top: 5px;'>
  88. Hrs: <input type='text' name='hours' id='hours' size='2'>
  89. Min Grade: <select name='min_grade' id='min_grade'>
  90. <option value=''>--</option>
  91. ";
  92. foreach ($min_grades as $g) {
  93. $rtn .= "<option value='$g'>$g</option>";
  94. }
  95. $rtn .= "
  96. </select>
  97. Type: <select name='type' id='type'>";
  98. // Get our list of requirement types from our settings.
  99. $types = fp_get_requirement_types();
  100. foreach ($types as $code => $desc) {
  101. $rtn .= "<option value='$code'>$code - $desc</option>";
  102. }
  103. $rtn .= "
  104. </select>
  105. &nbsp; &nbsp;
  106. " . fp_render_button("Add group &raquo;", "adminPopupAddGroup2(\"$semester_num\");") . "
  107. </div>";
  108. return $rtn;
  109. }
  110. /**
  111. * This form lets the user copy a degree and all of it's tracks & concentrations.
  112. */
  113. function admin_copy_degree_form() {
  114. $de_catalog_year = admin_get_de_catalog_year();
  115. fp_set_title(t("Copy Degree for") . " $de_catalog_year");
  116. $form = array();
  117. $m = 0;
  118. $form["mark" . $m++] = array(
  119. "type" => "markup",
  120. "value" => t("Use this form to duplicate a degree plan in this catalog year."),
  121. );
  122. $form["de_catalog_year"] = array(
  123. "type" => "hidden",
  124. "value" => $de_catalog_year,
  125. );
  126. $form["source_major_code"] = array(
  127. "type" => "textfield",
  128. "size" => 35,
  129. "label" => t("Enter the SOURCE major code you wish to copy:"),
  130. "required" => TRUE,
  131. "description" => t("Ex: ART or GBUS. Do not enter any track or concentration codes here."),
  132. );
  133. $form["include_tracks"] = array(
  134. "type" => "checkboxes",
  135. "label" => t("Include tracks?"),
  136. "options" => array("yes" => "Include tracks."),
  137. "description" => t("Check this box if you wish to also copy any tracks
  138. this major code may have associated with it. If you do not check this box,
  139. only the base degree will be copied. If the major does not have
  140. tracks, leave this unchecked."),
  141. );
  142. $form["destination_major_code"] = array(
  143. "type" => "textfield",
  144. "size" => 35,
  145. "label" => t("Enter the DESTINATION major code you wish to create/overwrite:"),
  146. "required" => TRUE,
  147. "description" => t("Ex: CHEM or XYZ. Do not enter any track or concentration codes here."),
  148. );
  149. $form["allow_overwrite"] = array(
  150. "type" => "radios",
  151. "label" => t("Overwrite if major code already exists?"),
  152. "options" => array(
  153. "no" => t("No, DO NOT delete and overwrite any existing major codes & associated tracks. Instead, return here with a warning message."),
  154. "yes" => t("Yes, if my destination major already exists, overwrite <b>and delete all associated tracks</b> for this year. (Use caution with this option!)"),
  155. ),
  156. "value" => "no",
  157. );
  158. // Our submit button.
  159. $form["submit"] = array(
  160. "type" => "submit",
  161. "value" => "Submit",
  162. "prefix" => "<hr>",
  163. );
  164. return $form;
  165. }
  166. /**
  167. * Validate handler.
  168. * Make sure our allow_overwrite setting is working. Check for existing major code.
  169. */
  170. function admin_copy_degree_form_validate($form, $form_state) {
  171. $values = $form_state["values"];
  172. if ($values["allow_overwrite"] == "no") {
  173. // Check to see if destination major code already exists.
  174. $de_catalog_year = $values["de_catalog_year"];
  175. $destination_major_code = trim(strtoupper($values["destination_major_code"]));
  176. // First thing's first. Make sure the sourceMajorCode exists.
  177. $res = db_query("SELECT * FROM draft_degrees
  178. WHERE major_code = ?
  179. AND catalog_year = ? ", $destination_major_code, $de_catalog_year) ;
  180. if (db_num_rows($res) != 0) {
  181. // Meaning, it WAS be found.
  182. form_error("destination_major_code", t("The destination major, %dest, was found for %year. Since you selected not to overwrite
  183. existing majors, your submission was not processed. Please try again.", array("%dest" => $destination_major_code, "%year" => $de_catalog_year)));
  184. return;
  185. }
  186. }
  187. }
  188. function admin_copy_degree_form_submit($form, &$form_state) {
  189. global $db;
  190. $values = $form_state["values"];
  191. $de_catalog_year = $values["de_catalog_year"];
  192. $source_major_code = trim(strtoupper($values["source_major_code"]));
  193. $destination_major_code = trim(strtoupper($values["destination_major_code"]));
  194. $include_tracks = $values["include_tracks"]["yes"];
  195. // First thing's first. Make sure the sourceMajorCode exists.
  196. $res = db_query("SELECT * FROM draft_degrees
  197. WHERE (major_code = ?
  198. OR major_code LIKE ?)
  199. AND catalog_year = ? ", $source_major_code, "$source_major_code|%", $de_catalog_year) ;
  200. if (db_num_rows($res) == 0) {
  201. // Meaning, it could not be found.
  202. form_error("source_major_code", t("The source major, %source, could not be found for %year", array("%source" => $source_major_code, "%year" => $de_catalog_year)));
  203. return;
  204. }
  205. // Alright, if we got to here, we can proceed. We need to
  206. // delete everything involving the destination major.
  207. // First, get the degree_id's in a select...
  208. $res = db_query("SELECT * FROM draft_degrees
  209. WHERE (major_code = ?
  210. OR major_code LIKE ?)
  211. AND catalog_year = ? ", $destination_major_code, "$destination_major_code|%", $de_catalog_year) ;
  212. if (db_num_rows($res) > 0) {
  213. while ($cur = db_fetch_array($res)) {
  214. $degree_id = $cur["degree_id"];
  215. $res2 = db_query("DELETE FROM draft_degree_requirements
  216. WHERE degree_id='?' ", $degree_id) ;
  217. $res2 = db_query("DELETE FROM draft_degrees
  218. WHERE degree_id = '?' ", $degree_id) ;
  219. }
  220. // Now, delete the tracks.
  221. $res2 = db_query("DELETE FROM draft_degree_tracks
  222. WHERE major_code = '?'
  223. AND catalog_year='?' ", $destination_major_code, $de_catalog_year) ;
  224. }
  225. // Okay, with the destination major good and deleted, we can proceed with
  226. // the copy.
  227. // Let's build up an array of all the degrees we will be copying.
  228. $source_array = array();
  229. // First, the base degree...
  230. $res = db_query("SELECT * FROM draft_degrees
  231. WHERE major_code = '?'
  232. AND catalog_year='?' ", $source_major_code, $de_catalog_year) ;
  233. $cur = db_fetch_array($res);
  234. $source_array[] = $cur;
  235. // Now, any tracks or concentrations?
  236. if ($include_tracks == "yes") {
  237. $res = db_query("SELECT * FROM draft_degrees
  238. WHERE major_code LIKE '?'
  239. AND catalog_year='?' ", "$source_major_code|%", $de_catalog_year) ;
  240. while ($cur = db_fetch_array($res)) {
  241. $source_array[] = $cur;
  242. }
  243. // While we're here, let's go ahead and make a copy of the tracks.
  244. $res = db_query("SELECT * FROM draft_degree_tracks
  245. WHERE (major_code = '?'
  246. OR major_code LIKE '?' )
  247. AND catalog_year='?' ", $source_major_code, "$source_major_code|%", $de_catalog_year) ;
  248. while($cur = db_fetch_array($res)) {
  249. extract($cur, 3, "db");
  250. $dest_code = $destination_major_code;
  251. if (strstr($db_major_code, "|")) {
  252. // We need to adjust the destCode to match
  253. //the source.
  254. $dest_code = str_replace("$source_major_code|", "$destination_major_code|", $db_major_code);
  255. }
  256. $res2 = db_query("INSERT INTO draft_degree_tracks
  257. (catalog_year, major_code, track_code,
  258. track_title, track_short_title, track_description)
  259. VALUES
  260. ('?', '?', '?', '?', '?', '?') ",
  261. $de_catalog_year, $dest_code, $db_track_code,
  262. $db_track_title, $db_track_short_title,
  263. $db_track_description) ;
  264. }
  265. }
  266. $db = get_global_database_handler();
  267. //var_dump($source_array);
  268. // Okay, now it's time to go through the sourceArray
  269. // and duplicate them.
  270. foreach ($source_array as $src) {
  271. extract($src, 3, "src");
  272. $dest_code = $destination_major_code;
  273. if (strstr($src_major_code, "|")) {
  274. // We need to adjust the destCode to match
  275. //the source.
  276. $dest_code = str_replace("$source_major_code|", "$destination_major_code|", $src_major_code);
  277. }
  278. //var_dump($dest_code);
  279. $dest_degree_id = $db->request_new_degree_id();
  280. // Let's save our src_degree_id and dest_degree_id in $form_state, for other possible modules to use.
  281. $form_state['degrees'][] = array(
  282. 'src' => $src_degree_id,
  283. 'src_catalog_year' => $de_catalog_year,
  284. 'dest' => $dest_degree_id,
  285. 'dest_major_code' => $dest_code,
  286. 'dest_catalog_year' => $de_catalog_year,
  287. );
  288. // Create the entry in the degrees table.
  289. $res = db_query("INSERT INTO draft_degrees
  290. (degree_id, major_code, degree_type, degree_level, degree_class, title,
  291. public_note, semester_titles_csv,
  292. catalog_year, exclude, allow_dynamic, advising_weight, override_degree_hours,
  293. min_tracks, max_tracks, default_tracks, track_selection_config)
  294. VALUES
  295. (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ",
  296. $dest_degree_id, $dest_code, $src_degree_type, $src_degree_level, $src_degree_class, $src_title,
  297. $src_public_note, $src_semester_titles_csv,
  298. $de_catalog_year, $src_exclude, $src_allow_dynamic, $src_advising_weight, $src_override_degree_hours,
  299. $src_min_tracks, $src_max_tracks, $src_default_tracks, $src_track_selection_config);
  300. // Now, go through the source's degree requirements and copy those over.
  301. $res = db_query("SELECT * FROM draft_degree_requirements
  302. WHERE degree_id = '$src_degree_id' ");
  303. while ($cur = db_fetch_array($res)) {
  304. extract($cur, 3, "db");
  305. $res2 = $db->db_query("INSERT INTO draft_degree_requirements
  306. (degree_id, semester_num, group_id,
  307. group_requirement_type,
  308. group_hours_required,
  309. group_min_hours_allowed,
  310. group_min_grade, course_id,
  311. course_min_grade,
  312. course_requirement_type,
  313. data_entry_value)
  314. VALUES
  315. (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ",
  316. $dest_degree_id, $db_semester_num, $db_group_id,
  317. $db_group_requirement_type,
  318. $db_group_hours_required,
  319. $db_group_min_hours_allowed,
  320. $db_group_min_grade, $db_course_id,
  321. $db_course_min_grade,
  322. $db_course_requirement_type,
  323. $db_data_entry_value);
  324. }
  325. }
  326. // Make a - entry into the draft_instruction table so it will
  327. // remind the administrator to apply draft changes.
  328. $res = db_query("INSERT INTO draft_instructions
  329. (instruction) VALUES ('-') ");
  330. fp_add_message(t("Degree %source has been copied to %dest for %year",
  331. array("%source" => $source_major_code, "%dest" => $destination_major_code, "%year" => $de_catalog_year)));
  332. }
  333. /**
  334. * This form lets the user add a degree to the database.
  335. */
  336. function admin_add_degree_form() {
  337. $de_catalog_year = admin_get_de_catalog_year();
  338. fp_set_title(t("Add Degree for") . " " . $de_catalog_year);
  339. $form = array();
  340. $m = 0;
  341. $form["markup" . $m++] = array(
  342. "type" => "markup",
  343. "value" => t("You may use this screen to add a new degree,
  344. by entering a new degree code (Level 1 or 2) or <em>track</em> (Level-3 degree) code.
  345. <br><br><em>Note: For simplicity, FlightPath refers to Level-1 and -2 degree codes as \"major codes\" and Level-3 degree codes as \"track codes\".</e>"),
  346. );
  347. $bool_legacy_concentrations = variable_get("enable_legacy_concentrations", FALSE);
  348. $legacy_text = "";
  349. if ($bool_legacy_concentrations) {
  350. $legacy_text = " [and concentration] ";
  351. }
  352. $form["de_catalog_year"] = array(
  353. "type" => "hidden",
  354. "value" => $de_catalog_year,
  355. );
  356. $form["new_major"] = array(
  357. "type" => "radios",
  358. "label" => t("Are you entering a new major code $legacy_text,<br>
  359. or an existing major code $legacy_text (so you can add a new track)?"),
  360. "options" => array(
  361. "new" => t("Entering a <b>new</b> major code"),
  362. "existing" => t("Entering an <b>existing</b> major code (only adding a new Level-3 track)"),
  363. ),
  364. "required" => TRUE,
  365. );
  366. $desc = "Enter the Level-1 or -2 Major Code here.
  367. Do not enter any Level 3 codes (ex: Tracks or Concentrations).
  368. <br>For example, enter ACCT or ENGL. <i><b>But not ENGL|_TRKA, etc</b></i>";
  369. if ($bool_legacy_concentrations) {
  370. $desc = "To enter a concentration code, use MAJOR|CONC.
  371. The | character is call the pipe, and it should under the backspace key.
  372. If adding a new concentration to an existing major, you still put this in as a
  373. NEW major code. Do not have any spaces in this box. The concentration code
  374. is optional. If the major does not have a concentration,
  375. then simply enter the major code by itself. The combined major code and optional track
  376. code can only be 18 characters maximum.";
  377. }
  378. $form["major_code"] = array(
  379. "type" => "textfield",
  380. "size" => 15,
  381. "label" => t("Level-1 or -2 Major Code:"),
  382. "description" => t($desc),
  383. "required" => TRUE,
  384. );
  385. $form["new_track"] = array(
  386. "type" => "radios",
  387. "label" => t("Are you entering a new Level-3 track code?"),
  388. "options" => array(
  389. "new" => t("Entering a <b>new</b> track code"),
  390. "none" => t("None - Not adding a track. Leave blank"),
  391. ),
  392. "required" => TRUE,
  393. );
  394. $form["track_code"] = array(
  395. "type" => "textfield",
  396. "size" => 15,
  397. "label" => t("Level-3 Track code:"),
  398. "description" => t("Leave blank if you selected None above. This code must not contain spaces,
  399. and combined with the major code it must not exceed 18 characters."),
  400. );
  401. // Our submit button.
  402. $form["submit"] = array(
  403. "type" => "submit",
  404. "value" => "Submit",
  405. "prefix" => "<hr>",
  406. );
  407. return $form;
  408. }
  409. /**
  410. * Validate handler for add_degree_form
  411. */
  412. function admin_add_degree_form_validate($form, $form_submit) {
  413. $values = $form_submit["values"];
  414. // Make sure neither major code nor track code contains any spaces.
  415. $major_code = trim(strtoupper($values["major_code"]));
  416. $track_code = trim(strtoupper($values["track_code"]));
  417. if (strstr($major_code, " ")) {
  418. form_error("major_code", t("The major code may not contain spaces. Please enter a new one containing only letters and numbers."));
  419. return;
  420. }
  421. if (strstr($track_code, " ")) {
  422. form_error("track_code", t("The track code may not contain spaces. Please enter a new one containing only letters and numbers."));
  423. return;
  424. }
  425. // Make sure the major + |_ + track_code doesn't exceed 20 characters.
  426. if (strlen("$major_code|_$track_code") > 20) {
  427. form_error("major_code", t("The major and track code combined may not exceed 18 characters. Please shorten one or the other."));
  428. return;
  429. }
  430. }
  431. /**
  432. * Submit handler for the add_degree_form.
  433. */
  434. function admin_add_degree_form_submit($form, $form_submit) {
  435. $values = $form_submit["values"];
  436. $degree_id = -1;
  437. $de_catalog_year = $values["de_catalog_year"];
  438. // This will be used to add a new degree (and possibly track)
  439. // to the database.
  440. $major_code = trim(strtoupper($values["major_code"]));
  441. $track_code = trim(strtoupper($values["track_code"]));
  442. $new_major = $values["new_major"];
  443. $new_track = $values["new_track"];
  444. $allow_dynamic = variable_get("admin_degrees_default_allow_dynamic", "0");
  445. //////////////////////////////////////////////
  446. if ($new_track == "new" && $track_code == "") {
  447. form_error("track_code", t("You selected to add a track, but did not specify a track code."));
  448. }
  449. // Make sure user did not enter an underscore (_) in either
  450. // the track or major code!
  451. if (strstr($track_code, "_") || strstr($major_code, "_")) {
  452. form_error("major_code", t("You are not allowed to enter underscores (_) in either the track code
  453. or major code, as this character has a special meaning in FlightPath (it is used in Level-3 degree code prefixes).
  454. Please re-enter your new degree code without using an underscore."));
  455. }
  456. // make sure no pipes in major or track (if legacy not enabled)
  457. if (!variable_get("enable_legacy_concentrations", FALSE)) {
  458. if (strstr($track_code, "|") || strstr($major_code, "|")) {
  459. form_error("major_code", t("You are not allowed to enter pipes (|) in either the track code
  460. or major code, as this character has a special meaning in FlightPath (it is used in Level-3 degree code prefixes).
  461. Please re-enter your new degree code without using a pipe character."));
  462. }
  463. }
  464. // Return since we have errors all ready.
  465. if (form_has_errors()) {
  466. return;
  467. }
  468. ////////////////////////////////////////////////////
  469. // First, deal with the major/concentration.
  470. // Firstly, check to see if it already exists...
  471. $res = db_query("SELECT * FROM draft_degrees
  472. WHERE catalog_year = ?
  473. AND major_code = ? ", $de_catalog_year, $major_code);
  474. if (db_num_rows($res) > 0 && $new_major == "new") {
  475. // Meaning, it already exists, yet we are trying to add it as a new
  476. // major. This is an error!
  477. fp_add_message(t("The major code %major_code already exists for %year. You cannot add it as a new major.", array("%major_code" => $major_code, "%year" => $de_catalog_year)), "error");
  478. return;
  479. }
  480. if (db_num_rows($res) == 0 && $new_major == "existing") {
  481. // This is another error. We are trying to add a track to an existing
  482. // major code, but none was found.
  483. fp_add_message(t("The major code %major_code could not be found in the system for %year. Perhaps you need to add it first?", array("%major_code" => $major_code, "%year" => $de_catalog_year)), "error");
  484. return;
  485. }
  486. if (db_num_rows($res) == 0 && $new_major == "new") {
  487. // This means we are trying to add a new major to the degrees table.
  488. // We may proceed with this.
  489. $db2 = new DatabaseHandler();
  490. $degree_id = $db2->request_new_degree_id();
  491. $db2->db_query("INSERT INTO draft_degrees
  492. (degree_id, major_code, catalog_year, allow_dynamic, title)
  493. values (?, ?, ?, ?, ?) ", $degree_id, $major_code, $de_catalog_year, $allow_dynamic, $major_code);
  494. }
  495. if ($new_track == "new") {
  496. //////////////////////////////////////////////////
  497. // Now, let's see about adding ourself a track...
  498. // First, check to see if it exists...
  499. $res = db_query("SELECT * FROM draft_degree_tracks
  500. WHERE catalog_year = ?
  501. AND major_code = ?
  502. AND track_code = ? ", $de_catalog_year, $major_code, $track_code);
  503. if (db_num_rows($res) > 0) {
  504. // Meaning, it already existed, so we can't create it.
  505. fp_add_message(t("The major and track code %major_code already exists for %year. You cannot add it as a new major/track code.", array("%major_code" => "$major_code $track_code", "%year" => $de_catalog_year)), "error");
  506. return;
  507. }
  508. else {
  509. // We can add it to the tracks table...
  510. $db2 = new DatabaseHandler();
  511. $db2->db_query("INSERT INTO draft_degree_tracks
  512. (catalog_year, major_code, track_code)
  513. values ('?', '?', '?') ", $de_catalog_year, $major_code, $track_code);
  514. // Now, we also need to add this major & track code to the degrees table.
  515. $new_major_code = $major_code;
  516. if (strstr($major_code, "|")) {
  517. // Already has a pipe, so it has a concentration.
  518. $new_major_code .= "_$track_code";
  519. }
  520. else {
  521. // No concentration...
  522. $new_major_code .= "|_$track_code";
  523. }
  524. $degree_id = $db2->request_new_degree_id();
  525. $db2->db_query("INSERT INTO draft_degrees
  526. (degree_id, major_code, catalog_year, allow_dynamic, title)
  527. values (?, ?, ?, ?, ?) ", $degree_id, $new_major_code, $de_catalog_year, $allow_dynamic, $new_major_code);
  528. }
  529. }
  530. // Let's add some default semester blocks for this degree (0 - 3).
  531. if ($degree_id > 0) {
  532. for ($t = 0; $t <= 3; $t++) {
  533. db_query("INSERT INTO draft_degree_requirements
  534. (degree_id, semester_num, course_id, course_min_grade, course_requirement_type, data_entry_value)
  535. values (?,?,?,?,?,?) ", $degree_id, $t, 0, '', '', "#");
  536. }
  537. }
  538. // Success! We are done.
  539. fp_add_message(t("The new degree %major_code was added successfully for %year.
  540. You may add another degree, or use the menu at the top of the page to return to your list
  541. of degrees, so you may begin editing the degree.", array("%major_code" => "$major_code $track_code", "%year" => $de_catalog_year)));
  542. clear_session_form_values("admin_add_degree_form");
  543. }
  544. /*
  545. * This function lists all of our degrees on the screen, for a given year
  546. */
  547. function admin_display_degrees() {
  548. // Do this using $render array, so it can be altered
  549. // by hook_content_alter
  550. $render = array();
  551. $render['#id'] = 'admin_display_degrees';
  552. $de_catalog_year = admin_get_de_catalog_year();
  553. $rtn = "";
  554. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  555. //$rtn .= "<h2 class='title'>" . t("Degrees for @year", array("@year" => $de_catalog_year)) . "</h2>";
  556. $render['title_top'] = array(
  557. 'value' => "<h2 class='title'>" . t("Degrees for @year", array("@year" => $de_catalog_year)) . "</h2>",
  558. );
  559. /*
  560. $rtn .= "<div class='admin-degrees-upper-links'>";
  561. $rtn .= l("Add new degree plan (major, degree plan, or track)", "admin/degrees/add-degree", "de_catalog_year=$de_catalog_year");
  562. $rtn .= " &nbsp; &nbsp; | &nbsp; &nbsp; ";
  563. $rtn .= l("Copy a degree plan", "admin/degrees/copy-degree", "de_catalog_year=$de_catalog_year");
  564. $rtn .= "</div>";
  565. */
  566. $render['upper_links'] = array(
  567. 'value' => "<div class='admin-degrees-upper-links'>
  568. " . l("Add new degree plan (major, degree plan, or track)", "admin/degrees/add-degree", "de_catalog_year=$de_catalog_year") . "
  569. &nbsp; &nbsp; | &nbsp; &nbsp;
  570. " . l("Copy a degree plan", "admin/degrees/copy-degree", "de_catalog_year=$de_catalog_year") . "</div>",
  571. );
  572. $filter_class = @$_REQUEST["filter_class"];
  573. $html = "";
  574. $html .= "<div class='degrees-filter'>
  575. <form id='filter-form' action='" . fp_url("admin/degrees") . "' method='GET'>
  576. <input type='hidden' name='de_catalog_year' value='$de_catalog_year'>
  577. ";
  578. if (!variable_get("clean_urls", FALSE)) {
  579. // Clean URLs is not enabled, so add in the q=admin/degrees, to make this form work.
  580. $html .= "<input type='hidden' name='q' value='admin/degrees'>";
  581. }
  582. $html .= "
  583. <b>Filter list by...</b>
  584. <br>Class: &nbsp;
  585. <select name='filter_class' onChange='showUpdate(true);$(\"#filter-form\").submit();'>
  586. <option value=''>- Show all -</option>";
  587. // Display degree_class pulldown.
  588. $degree_classes = fp_get_degree_classifications();
  589. foreach ($degree_classes["levels"] as $level => $details) {
  590. foreach ($degree_classes["levels"][$level] as $machine_name => $title) {
  591. $sel = "";
  592. if ($machine_name == $filter_class) $sel = "selected";
  593. $html .= "<option value='$machine_name' $sel>$level - $title</option>";
  594. }
  595. }
  596. $html .= " </select>
  597. </form>
  598. </div>";
  599. $render['degrees_filter'] = array(
  600. 'value' => $html,
  601. );
  602. /*
  603. $rtn .= "<table class='degrees-table' border='0' width='100%' cellpadding='5' cellspacing='0'>
  604. <tr>
  605. <th width='8%'>Type</th>
  606. <th width='15%'>Class</th>
  607. <th width='60%'>Title</th>
  608. <th>Code</th>
  609. </tr>";
  610. */
  611. $render['degrees_table_top'] = array(
  612. 'value' => "<table class='degrees-table' border='0' width='100%' cellpadding='5' cellspacing='0'>
  613. <tr>
  614. <th width='8%'>Type</th>
  615. <th width='15%'>Class</th>
  616. <th width='60%'>Title</th>
  617. <th>Code</th>
  618. </tr>",
  619. );
  620. $res = db_query("SELECT * FROM draft_degrees
  621. WHERE catalog_year = ?
  622. ORDER BY degree_type, major_code, title ", $de_catalog_year);
  623. while($cur = db_fetch_array($res)) {
  624. $db_exclude = 0;
  625. extract($cur, 3, "db");
  626. // We filtered for a particular class, and we didn't find it, so skip.
  627. if ($filter_class != "" && $db_degree_class != $filter_class) continue;
  628. if ($db_degree_type == "NA" && strstr($db_major_code, "|")) {
  629. $db_degree_type = " -- ";
  630. }
  631. $extra_class = "";
  632. if ($db_exclude == "1") {
  633. $extra_class = "list-degree-row-excluded";
  634. }
  635. $degree_title = $db_title;
  636. // get JUST the major code...
  637. $temp = explode("|", $db_major_code);
  638. $just_major = trim(@$temp[0]);
  639. $just_conc = trim(@$temp[1]);
  640. $outside = "";
  641. //if ($just_conc != "" && strstr($just_conc, "_"))
  642. if (strstr($just_conc, "_")) {
  643. // If the concentration has an underscore, it's actually
  644. // a track. Let's get the track title...
  645. $temp2 = explode("_",$just_conc);
  646. $just_track = trim($temp2[1]);
  647. // Might need to add the first part BACK onto the major...
  648. if (trim($temp2[0]) != "")
  649. {
  650. $just_major .= "|" . trim($temp2[0]);
  651. }
  652. $res2 = db_query("SELECT * FROM draft_degree_tracks
  653. WHERE catalog_year = '?'
  654. AND major_code = '?'
  655. AND track_code = '?' ", $de_catalog_year, $just_major, $just_track);
  656. if (db_num_rows($res2) > 0) {
  657. $cur2 = db_fetch_array($res2);
  658. $db_title = trim($cur2["track_title"]);
  659. $outside = "$degree_title &raquo; ";
  660. if (strstr($just_major, "|")) {
  661. // both a conc AND a track. Denote it special.
  662. $outside = ">>" . $outside;
  663. }
  664. $db_degree_type = "";
  665. }
  666. }
  667. else if($just_conc != "") {
  668. // Meaning, this is a concentration, NOT a track.
  669. $db_degree_type = "";
  670. $outside = "&gt;&gt;";
  671. }
  672. //$base_path = $GLOBALS['system_settings']['base_path'];
  673. //$url = $base_path . "/index.php?q=admin/degrees/edit-degree/$db_major_code/$de_catalog_year&de_catalog_year=$de_catalog_year";
  674. $url = fp_url("admin/degrees/edit-degree/$db_major_code/$de_catalog_year", "de_catalog_year=$de_catalog_year", array("class" => "degree-$db_degree_class"));
  675. $class_details = fp_get_degree_classification_details($db_degree_class);
  676. $disp_class = $class_details["title"];
  677. $on_mouse_over = "
  678. onmouseover='$(this).addClass(\"selection_highlight\");'
  679. onmouseout='$(this).removeClass(\"selection_highlight\");'
  680. ";
  681. /*
  682. $rtn .= "<tr
  683. $on_mouse_over
  684. style='cursor:pointer;'
  685. onClick='window.location=\"$url\"'
  686. class='$extra_class class-$db_degree_class class-level-" . $class_details["level_num"] . " '
  687. >
  688. <td valign='top' class='degree-type'>$db_degree_type</td>
  689. <td valign='top' class='degreee-class'>$disp_class</td>
  690. <td valign='top' class='degree-title'>$outside$db_title</td>
  691. <td valign='top' class='degree-major-code'>$db_major_code</td>
  692. </tr>";
  693. */
  694. $render['degree_row_' . $db_degree_id] = array(
  695. 'value' => "<tr
  696. $on_mouse_over
  697. style='cursor:pointer;'
  698. onClick='window.location=\"$url\"'
  699. class='$extra_class class-$db_degree_class class-level-" . $class_details["level_num"] . " '
  700. >
  701. <td valign='top' class='degree-type'>$db_degree_type</td>
  702. <td valign='top' class='degreee-class'>$disp_class</td>
  703. <td valign='top' class='degree-title'>$outside$db_title</td>
  704. <td valign='top' class='degree-major-code'>$db_major_code</td>
  705. </tr>
  706. ",
  707. 'data' => array(
  708. 'degree_id' => $db_degree_id,
  709. 'major_code' => $db_major_code,
  710. 'title' => $db_title,
  711. 'catalog_year' => $db_catalog_year,
  712. 'degree_type' => $db_degree_type,
  713. 'degree_class' => $db_degree_class,
  714. 'db_row' => $cur,
  715. ),
  716. );
  717. }
  718. //$rtn .= "</table>";
  719. $render['degrees_table_bottom'] = array(
  720. 'value' => "</table>",
  721. );
  722. $rtn .= fp_render_content($render);
  723. return $rtn;
  724. }
  725. function z___admin_handle_edit_degree_submit() {
  726. $de_catalog_year = $_REQUEST["de_catalog_year"];
  727. $db = get_global_database_handler();
  728. // What courses should have their type overwritten as "x"?
  729. $ignore_courses = csv_to_array(variable_get("ignore_courses_from_hour_counts", ""));
  730. // This will UPDATE a degree in the system with the courses
  731. // and groups that the user selected.
  732. $perform_action2 = trim($_POST["perform_action2"]);
  733. if (strstr($perform_action2, "delGroup")) {
  734. $temp = explode("_",$perform_action2);
  735. $del_group = new Group();
  736. $del_group->bool_use_draft = true;
  737. $del_group->group_id = $temp[1];
  738. $del_group->assigned_to_semester_num = $temp[2];
  739. }
  740. $major_code = trim($_POST["major_code"]);
  741. if ($major_code == ""){ die("Fatal error: major_code not found.");}
  742. // Since we are making a change to the draft table(s), let's add a row
  743. // to draft instructions.
  744. $db->add_draft_instruction("-");
  745. // Let's assemble the track selection config values into one string. We need to loop through all of the POST
  746. // values, looking for each type of track.
  747. $db_track_selection_config = "";
  748. $degree_classes = fp_get_degree_classifications();
  749. foreach ($degree_classes["levels"] as $level => $details) {
  750. if (intval($level) != 3) continue; // we only care about level 3...
  751. foreach ($degree_classes["levels"][$level] as $machine_name => $title) {
  752. // Got the machine name, now let's see if we have any values for
  753. // the track selections...
  754. $min_tracks = @intval($_POST["tsc_{$machine_name}_min_tracks"]);
  755. $max_tracks = @intval($_POST["tsc_{$machine_name}_max_tracks"]);
  756. $default_tracks = @trim($_POST["tsc_{$machine_name}_default_tracks"]);
  757. $db_track_selection_config .= $machine_name . "~" . $min_tracks . "~" . $max_tracks . "~" . $default_tracks . "\n";
  758. }
  759. }
  760. $degree_id = "";
  761. // First things first, if this degree already exists in this
  762. // catalog year, then we need to delete it first.
  763. if ($degree_id = $db->get_degree_id($major_code, $de_catalog_year, true)) {
  764. $degree = new DegreePlan($degree_id, null, false, false, true);
  765. $degree->load_descriptive_data();
  766. // Delete from degree_requirements WHERE this degree_id exists.
  767. $res = db_query("DELETE FROM draft_degree_requirements
  768. WHERE degree_id = '?' ", $degree_id);
  769. // Are we trying to DELETE this degree? If so, keep deleting!
  770. if ($perform_action2 == "delete_degree" && user_has_permission("can_delete_data_entry")) {
  771. $res = db_query("DELETE FROM draft_degrees
  772. WHERE degree_id = '?' ", $degree_id);
  773. // Also need to get rid of the track, if there is one for this
  774. // degree.
  775. $res = db_query("DELETE FROM draft_degree_tracks
  776. WHERE major_code = '$degree->major_code'
  777. AND track_code = '$degree->track_code'
  778. AND catalog_year = '?' LIMIT 1", $de_catalog_year);
  779. // Okay, we have deleted everything. We need to go back to
  780. // just the list of degrees.
  781. //display_edit_degrees("<font color='green'><b>The degree $major_code ($de_catalog_year) has been deleted.</b></font>");
  782. //die;
  783. fp_add_message("The degree $major_code ($de_catalog_year) has been deleted.");
  784. fp_goto("admin/degrees", "de_catalog_year=$de_catalog_year");
  785. return;
  786. }
  787. }
  788. else {
  789. // We need to generate a new degreeID for this major_code and catalog_year,
  790. // because one does not already exist!
  791. if (!$degree_id = $db->request_new_degree_id()) {
  792. die ("Error. Could not create new degreeID.");
  793. }
  794. }
  795. // Save the entire post to the log.
  796. $errors = "";
  797. $semester_titles_csv = "";
  798. $highest_semester_num = 0; // What is the largest semester_num in the system?
  799. // Okay, now get the various courses...
  800. for ($semester_num = 0; $semester_num < 50; $semester_num++)
  801. {
  802. // Assuming no more than 50 semesters.
  803. $courses = trim(@$_POST["courses_$semester_num"]);
  804. if ($courses == "") {
  805. continue;
  806. }
  807. if ($semester_num > $highest_semester_num) {
  808. $highest_semester_num = $semester_num;
  809. }
  810. $course_rows = explode("\n",$courses);
  811. for ($t = 0; $t < count($course_rows); $t++) {
  812. $line = trim($course_rows[$t]);
  813. if ($line == "") {
  814. continue;
  815. }
  816. // Take out extra whitespace between tokens.
  817. $line = str_replace(" ", " ", $line);
  818. $line = str_replace(" ", " ", $line);
  819. $line = str_replace(" ", " ", $line);
  820. $line = str_replace(" ", " ", $line);
  821. $tokens = explode(" ", $line);
  822. $subject_id = $tokens[0];
  823. $course_num = $tokens[1];
  824. $requirement_type = strtolower(@$tokens[2]);
  825. if ($requirement_type == "") {
  826. // major type by default.
  827. $requirement_type = "m";
  828. }
  829. // If this course is in our ignore list, override it's type
  830. // to be 'x'
  831. if (in_array("$subject_id $course_num", $ignore_courses)) {
  832. $requirement_type = "x";
  833. }
  834. $min_grade = strtoupper(@$tokens[3]);
  835. if (strstr($requirement_type, "(")) {
  836. // This means there was no requirement_type specified, so it's "m",
  837. // and a min_grade was found in its place.
  838. $min_grade = strtoupper($requirement_type);
  839. $requirement_type = "m";
  840. }
  841. $min_grade = str_replace("(","",$min_grade);
  842. $min_grade = str_replace(")","",$min_grade);
  843. /////////////////////////////////////////////
  844. // Okay, we now have enough information to insert the course.
  845. // Find out what the course_id is.
  846. if ($course_id = $db->get_course_id($subject_id, $course_num, "", true)) // don't care about catalog year.
  847. {
  848. $query = "INSERT INTO draft_degree_requirements
  849. (degree_id, semester_num, course_id, course_min_grade, course_requirement_type, data_entry_value)
  850. values (?,?,?,?,?,?) ";
  851. $res = db_query($query, $degree_id, $semester_num, $course_id, $min_grade, $requirement_type, "$subject_id~$course_num");
  852. //debug_c_t($query);
  853. } else {
  854. // The course_id could not be found!
  855. $errors .= "<br><span style='color:red;'><b>Course Not Found!</b>
  856. In Block " . ($semester_num+1) . ", you specified the course
  857. <b>$subject_id $course_num</b> as a requirement, but this course
  858. could not be found.
  859. It was removed from that block.
  860. Are you sure you typed it correctly? Please go to this
  861. semester, check your spelling, and add the course again.</span>";
  862. }
  863. }
  864. }
  865. // Get the groups....
  866. foreach($_POST as $key => $value) {
  867. if (!strstr($key, "group_")) {
  868. continue;
  869. }
  870. // Only look at the groups...
  871. $temp = explode("_", $value);
  872. $group_id = $temp[0];
  873. $semester_num = $temp[1];
  874. $hours = $temp[2];
  875. $min_hours = $hours;
  876. if (strstr($hours, "-")) {
  877. // Hours has a min hour value specified. let's grab it.
  878. $tt = explode("-", $hours);
  879. $min_hours = $tt[0];
  880. $hours = $tt[1];
  881. }
  882. $type = $temp[3];
  883. $min_grade = trim($temp[4]);
  884. if ($semester_num > $highest_semester_num) {
  885. $highest_semester_num = $semester_num;
  886. }
  887. // Do not add if we are supposed to be deleting this group!
  888. if (isset($del_group) && is_object($del_group)) {
  889. if ($del_group->group_id == $group_id && $del_group->assigned_to_semester_num == $semester_num) {
  890. continue;
  891. }
  892. }
  893. $adding_group = new Group($group_id);
  894. // If this group is already saved in this degree elsewhere, and it has a different type or min_grade,
  895. // then we must display a warning message to the user.
  896. $res = db_query("SELECT * FROM draft_degree_requirements
  897. WHERE degree_id = '?'
  898. AND group_id = '?'
  899. AND (group_min_grade <> '?' OR group_requirement_type <> '?')", $degree_id, $group_id, $min_grade, $type);
  900. while ($cur = db_fetch_array($res)) {
  901. $errors .= "<br><span style='color:red;'><b>Group type or min grade mismatch!</b>
  902. In Block " . ($semester_num + 1) . ", you specified the group <em>" . $adding_group->title . "</em> ($adding_group->group_name) with a min grade of \"<em>$min_grade</em>\"
  903. and a requirement type of \"<em>$type</em>\". However, the group was previously specified in this degree plan in Block " . ($cur["semester_num"] + 1) . "
  904. with a different requirement type and/or min grade requirement. FlightPath will not perform calculations correctly for courses assigned to this group.
  905. You should either set the duplicate occurances of the group to the same type/min grade, or create a new group to handle these alternate requirements.</span>";
  906. }
  907. // We now have enough information to insert this group.
  908. //debugCT("group: $group_id $semester_num $hours $type");
  909. $query = "INSERT INTO draft_degree_requirements
  910. (degree_id, semester_num, group_id,
  911. group_requirement_type, group_hours_required, group_min_hours_allowed, group_min_grade)
  912. values (?,?,?,?,?,?,?) ";
  913. $res = db_query($query, $degree_id, $semester_num, $group_id, $type, $hours, $min_hours, $min_grade);
  914. }
  915. // Was there a group added or deleted?
  916. if (strstr($perform_action2,"addGroup")) {
  917. $temp = explode("_",$perform_action2);
  918. $group_id = $temp[1];
  919. $semester_num = $temp[2];
  920. $hours = trim($temp[3]);
  921. $min_hours = $hours;
  922. if (strstr($hours, "-")) {
  923. // Hours has a min hour value specified. let's grab it.
  924. $tt = explode("-", $hours);
  925. $min_hours = $tt[0];
  926. $hours = $tt[1];
  927. }
  928. $type = $temp[4];
  929. $min_grade = trim($temp[5]);
  930. $adding_group = new Group($group_id);
  931. // If this group is already saved in this degree elsewhere, and it has a different type or min_grade,
  932. // then we must display a warning message to the user.
  933. $res = db_query("SELECT * FROM draft_degree_requirements
  934. WHERE degree_id = '?'
  935. AND group_id = '?'
  936. AND (group_min_grade <> '?' OR group_requirement_type <> '?')", $degree_id, $group_id, $min_grade, $type);
  937. while ($cur = db_fetch_array($res)) {
  938. $errors .= "<br><span style='color:red;'><b>Group type or min grade mismatch!</b>
  939. In Block " . ($semester_num + 1) . ", you specified the group <em>" . $adding_group->title . "</em> ($adding_group->group_name) with a min grade of \"<em>$min_grade</em>\"
  940. and a requirement type of \"<em>$type</em>\". However, the group was previously specified in this degree plan in Block " . ($cur["semester_num"] + 1) . "
  941. with a different requirement type and/or min grade requirement. FlightPath will not perform calculations correctly for courses assigned to this group.
  942. You should either set the duplicate occurances of the group to the same type/min grade, or create a new group to handle these alternate requirements.</span>";
  943. }
  944. $query = "INSERT INTO draft_degree_requirements
  945. (degree_id,semester_num,group_id,
  946. group_requirement_type,group_hours_required,group_min_hours_allowed,group_min_grade)
  947. VALUES (?,?,?,?,?,?,?) ";
  948. $res = db_query($query, $degree_id, $semester_num, $group_id, $type, $hours, $min_hours, $min_grade);
  949. }
  950. // Make the semesterTitlesCSV...
  951. for ($semester_num = 0; $semester_num <= $highest_semester_num; $semester_num++) {
  952. if ($semester_num > 99) break; // some problem. Give up. Don't try to go past 99 semesters!
  953. $semester_titles_csv .= trim(@$_POST["semester_title_$semester_num"]) . ",";
  954. }
  955. // Before we UPDATE, also grab the degree title, degree_type,
  956. // and exclude value, etc....
  957. $degree_title = trim($_POST["title"]);
  958. $degree_type = trim($_POST["degree_type"]);
  959. $degree_class = trim($_POST["degree_class"]);
  960. $degree_level = strtoupper(trim($_POST["degree_level"]));
  961. $exclude = trim($_POST["exclude"]);
  962. $allow_dynamic = trim($_POST["allow_dynamic"]);
  963. $advising_weight = intval($_POST["advising_weight"]);
  964. $override_degree_hours = trim($_POST["override_degree_hours"]);
  965. $public_note = trim($_POST["public_note"]);
  966. $min_tracks = intval($_POST["min_tracks"]);
  967. $max_tracks = intval($_POST["max_tracks"]);
  968. $default_tracks = trim($_POST["default_tracks"]);
  969. $res = db_query("UPDATE draft_degrees
  970. SET semester_titles_csv = ?,
  971. title = ?,
  972. degree_type = ?,
  973. degree_class = ?,
  974. degree_level = ?,
  975. exclude = ?,
  976. allow_dynamic = ?,
  977. advising_weight = ?,
  978. override_degree_hours = ?,
  979. track_selection_config = ?,
  980. public_note = ?
  981. WHERE degree_id = ? ",
  982. $semester_titles_csv, $degree_title, $degree_type, $degree_class, $degree_level, $exclude, $allow_dynamic, $advising_weight, $override_degree_hours,
  983. $db_track_selection_config, $public_note, $degree_id);
  984. //// Was there a track title/description? If so, UPDATE that in the tracks
  985. // table...
  986. if (strstr($major_code, "_")) {
  987. // There was a track. Update track description.
  988. $temp = explode("_",$major_code);
  989. $major = trim($temp[0]);
  990. // major might now have a | at the end. If so, take it out.
  991. if (substr($major, strlen($major)-1, 1) == "|") {
  992. $major = str_replace("|","",$major);
  993. }
  994. $track = trim($temp[1]);
  995. $track_description = trim($_POST["track_description"]);
  996. $track_title = trim($_POST["track_title"]);
  997. //debugCT($track_description);
  998. $res = db_query("UPDATE draft_degree_tracks
  999. SET `track_description`='?',
  1000. `track_title`='?'
  1001. WHERE `track_code`='?'
  1002. AND `major_code`='?'
  1003. AND `catalog_year`='?' ", $track_description, $track_title, $track, $major, $de_catalog_year);
  1004. }
  1005. //$msg = "<font color='green' size='4'>Degree updated successfully at " . get_current_time() . ".</font>";
  1006. fp_add_message("Degree updated succesfully.");
  1007. $button_msg = urlencode("Degree updated successfully at " . date("H:i:s"));
  1008. $bool_scroll = $bool_button_msg = true;
  1009. if ($errors != "")
  1010. {
  1011. fp_add_message("ERRORS/WARNINGS: $errors");
  1012. $bool_scroll = $bool_button_msg = false;
  1013. $button_msg = urlencode("The degree plan was saved, but an error or warning has occured. Please see error message at the top of the page.");
  1014. $_REQUEST["scroll_top"] = 0;
  1015. }
  1016. fp_goto("admin/degrees/edit-degree", "de_catalog_year=$de_catalog_year&major_code=$major_code&scroll_top=" . $_REQUEST["scroll_top"] . "&button_msg=" . $button_msg);
  1017. return;
  1018. }
  1019. /**
  1020. * Meant to replace the old-fashioned display_edit_degree function...
  1021. */
  1022. function admin_edit_degree_form($major_code, $de_catalog_year) {
  1023. $form = array();
  1024. fp_set_title(t("Edit Degree") . " $major_code - $de_catalog_year");
  1025. // Add in our CSS and JS
  1026. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  1027. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  1028. $button_msg = trim(addslashes(@$_REQUEST["button_msg"]));
  1029. $db = get_global_database_handler();
  1030. $degree_id = intval($db->get_degree_id($major_code, $de_catalog_year, true));
  1031. // The intval says, if it's false, make it = 0. otherwise keep the number
  1032. // that is returned.
  1033. $degree = new DegreePlan($degree_id, null, false, false, true);
  1034. $degree->load_descriptive_data();
  1035. if (user_has_permission("can_view_advanced")) {
  1036. $form["markup_adv"] = array(
  1037. "value" => "<span class='tenpt deg-advanced-msg' style='background-color: yellow; margin-left: 20px;'>
  1038. Advanced: degree_id = $degree_id. catalog_year: $de_catalog_year
  1039. </span>",
  1040. );
  1041. }
  1042. $form["degree_id"] = array(
  1043. "type" => "hidden",
  1044. "value" => $degree_id,
  1045. );
  1046. $form["major_code"] = array(
  1047. "type" => "hidden",
  1048. "value" => $major_code,
  1049. );
  1050. $form["de_catalog_year"] = array(
  1051. "type" => "hidden",
  1052. "value" => $de_catalog_year,
  1053. );
  1054. $form["scroll_top"] = array(
  1055. "type" => "hidden",
  1056. "value" => '',
  1057. );
  1058. $form["perform_action2"] = array(
  1059. "type" => "hidden",
  1060. "value" => '',
  1061. );
  1062. $form["markup_degree_header"] = array(
  1063. "value" => "<h3>$degree->degree_type $degree->title<br>$major_code ($de_catalog_year)</h3>",
  1064. "weight" => 1010,
  1065. );
  1066. //////////////////////////////////////////////////////
  1067. // Top part of degree entry....
  1068. $form["degree_type"] = array(
  1069. "type" => "textfield",
  1070. "label" => t("Degree Type:"),
  1071. "size" => 3,
  1072. "value" => $degree->degree_type,
  1073. "popup_description" => t("For example: BS, BA, Ph.D, etc."),
  1074. "weight" => 1020,
  1075. );
  1076. // Display degree_class pulldown.
  1077. $options = array();
  1078. $degree_classes = fp_get_degree_classifications();
  1079. foreach ($degree_classes["levels"] as $level => $details) {
  1080. foreach ($degree_classes["levels"][$level] as $machine_name => $title) {
  1081. //$rtn .= "<option value='$machine_name' $sel>$level - $title</option>";
  1082. $options[$machine_name] = "$level - $title";
  1083. }
  1084. }
  1085. $form["degree_class"] = array(
  1086. "type" => "select",
  1087. "label" => t("Classification:"),
  1088. "options" => $options,
  1089. "value" => $degree->degree_class,
  1090. "hide_please_select" => TRUE,
  1091. "popup_description" => t("Select which classification this degree plan is listed under. The number beside the title is the 'level' of the degree classification.
  1092. 1 - Degrees which a student may graduate in. Ex: Majors.
  1093. 2 - Degree plans which are secondary to top level degree plans. Ex: Minors.
  1094. 3 - Degree plans which are only selectable as add-ons to an existing degree plan. Ex: Concentrations.
  1095. You may edit these classifications in the Configure School Data form, from the Admin Console."),
  1096. "weight" => 1030,
  1097. );
  1098. $form["degree_level"] = array(
  1099. "type" => "select",
  1100. "label" => t("Level:"),
  1101. "size" => 1,
  1102. "options" => array('UG' => 'UG - Under Grad', 'GR' => 'GR - Grad'),
  1103. "value" => $degree->degree_level,
  1104. "hide_please_select" => TRUE,
  1105. "popup_description" => t("Select the degree level code in this box. By default, it is assumed to be an \"Undergraduate\" (UG) degree.
  1106. Select \"GR\" for a degree which should only be accessible to Graduate students in What If mode.
  1107. "),
  1108. "weight" => 1040,
  1109. );
  1110. $form["advising_weight"] = array(
  1111. "type" => "textfield",
  1112. "label" => t("Advising Weight:"),
  1113. "size" => 1,
  1114. "value" => $degree->db_advising_weight,
  1115. "popup_description" => t("If this degree is ever combined with another degree, this value, the advising weight, determines
  1116. the order in which the degrees will be displayed on the View tab and in What If mode.
  1117. The default is zero (0). To place this degree above normal degrees, set it to a negative value (ex: -1, -10, etc.).
  1118. Set it higher to place it below normal degrees. (Ex: 10, 20, 30, etc).
  1119. To prevent confusion, it's recommended that a degree's tracks have the same advising weight as the main degree.
  1120. If you are unsure what to enter, leave it set to 0 (zero)."),
  1121. "weight" => 1050,
  1122. );
  1123. $form["title"] = array(
  1124. "type" => "textfield",
  1125. "label" => t("Title:"),
  1126. "size" => 80,
  1127. "maxlength" => 100,
  1128. "value" => $degree->title,
  1129. "popup_description" => t("This is the full title of the degree. Ex: Computer Science, Accounting, etc."),
  1130. "weight" => 1060,
  1131. );
  1132. $form["exclude"] = array(
  1133. "type" => "textfield",
  1134. "label" => t("Exclude:"),
  1135. "size" => 1,
  1136. "value" => intval($degree->db_exclude),
  1137. "popup_description" => t("If the Exclude value is set to 1 (the number one), then this degree will show up in gray on the list of degrees. It will also not be selectable in What If mode in FlightPath.
  1138. If you are not sure what to enter, either leave it blank or enter a 0 (zero)."),
  1139. "weight" => 1070,
  1140. );
  1141. $form["allow_dynamic"] = array(
  1142. "type" => "textfield",
  1143. "label" => t("Allow Dynamic:"),
  1144. "size" => 1,
  1145. "value" => intval($degree->db_allow_dynamic),
  1146. "popup_description" => t("If this value is set to 1 (the number one), then this degree plan is able to be combined with other degrees which are also set to Allow Dynamic.
  1147. If you are unsure what to enter, either leave blank or enter a 0 (the number zero)."),
  1148. "weight" => 1080,
  1149. );
  1150. $form["override_degree_hours"] = array(
  1151. "type" => "textfield",
  1152. "label" => t("Override Degree Hours:"),
  1153. "size" => 1,
  1154. "value" => $degree->db_override_degree_hours,
  1155. "popup_description" => t("You may specify a number of degree hours here (ex: 125). FlightPath will use this value, instead of calculating the number of hours
  1156. required for this degree. If you are unsure what to put here, leave it blank, or enter zero, for FlightPath to calculate hours normally."),
  1157. "weight" => 1090,
  1158. );
  1159. $form['below_degree_details_markup'] = array(
  1160. 'value' => "<div style='clear: both;'></div>",
  1161. "weight" => 1110,
  1162. );
  1163. // Is this a "track"?
  1164. if (strstr($major_code, "_"))
  1165. {
  1166. $form['track_info_markup'] = array(
  1167. 'value' => "<h3>" . t("Track (Level-3) Information") . "</h3>",
  1168. "weight" => 1120,
  1169. );
  1170. $form['track_title'] = array(
  1171. 'type' => 'textfield',
  1172. 'label' => t("Track (Level-3) Title:") . "&nbsp;",
  1173. 'size' => 60,
  1174. 'maxlength' => 100,
  1175. 'value' => $degree->track_title,
  1176. "weight" => 1130,
  1177. );
  1178. $form['track_description'] = array(
  1179. 'type' => 'textarea',
  1180. 'label' => t("Track (Level-3) Description:"),
  1181. 'rows' => 4,
  1182. 'cols' => 60,
  1183. 'value' => $degree->track_description,
  1184. 'description' => t("You may enter simple HTML in this field. Ex: &lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italics&lt;/i&gt;"),
  1185. 'popup_description' => t("This is where you can enter a short description of this Level-3 degree track (also called a Degree Option) which will display for the user in a pop-up when they select to change degree options.
  1186. \nTo enter a default message, which will display at the top of the selection window, begin the description with:\n DEFAULT: \nIt must be in all caps, and you must have the colon (:) after it.
  1187. By doing this in ANY of the track descriptions for a major, FP will ignore all other track descriptions and ONLY display the default.
  1188. \n\nExample of usage: DEFAULT: You may select any of these degree options."),
  1189. "weight" => 1140,
  1190. );
  1191. }
  1192. ///////////////////////////////////////
  1193. ///////////////////////////////////////
  1194. // Semester Blocks //
  1195. //////////////////////////////////////
  1196. ///////////////////////////////////////
  1197. $groups_counter = 0; // used to create unique variables for groups
  1198. $js_existing_semesters = array();
  1199. $form['blocks_top_markup'] = array(
  1200. 'value' => "<div style='clear: both;'></div>
  1201. <hr>
  1202. <div class='add-new-sem-block' style='float: right; margin-top: 5px;'>" . fp_render_button(t("Add New Semester Block"), "adminAddNewSemesterBlock();") . "</div>
  1203. <h2>Semester Blocks</h2>
  1204. ",
  1205. "weight" => 2010,
  1206. );
  1207. $base_weight = 30000;
  1208. $first_semester_num = -999;
  1209. $degree->list_semesters->reset_counter();
  1210. while ($degree->list_semesters->has_more()) {
  1211. $semester = $degree->list_semesters->get_next();
  1212. if ($semester->semester_num < 0) {
  1213. continue;
  1214. }
  1215. $js_existing_semesters["semester_" . $semester->semester_num] = $semester->semester_num;
  1216. // Record what is the first semester num we have...
  1217. if ($first_semester_num == -999) {
  1218. $first_semester_num = $semester->semester_num;
  1219. }
  1220. $sem_default_title = admin_get_semester_name($semester->semester_num);
  1221. if ($semester->title == $sem_default_title) {
  1222. $semester->title = "";
  1223. }
  1224. $form["semester_{$semester->semester_num}_very_top_markup"] = array(
  1225. "value" => "",
  1226. "weight" => $base_weight + ($semester->semester_num * 100) + 10,
  1227. );
  1228. $form['semester_title_' . $semester->semester_num] = array(
  1229. 'type' => 'textfield',
  1230. 'prefix' => "<div style='padding-bottom: 3px; margin-top:20px;'><b>Block number: " . ($semester->semester_num + 1) . "</b>
  1231. &nbsp; &nbsp;
  1232. <a href='javascript:adminDeleteSemesterBlock($semester->semester_num);'>Delete?</a>
  1233. &nbsp; &nbsp; &nbsp; Default Title: <em>$sem_default_title</em></div>",
  1234. 'label' => 'Override Title:',
  1235. 'value' => $semester->title,
  1236. 'size' => 20,
  1237. 'popup_description' => t("You may override the default title for a block. For example, if instead of Freshman Year you want it to read Pre-Pharmacy Year 1 in FlightPath,
  1238. then you would enter that in this box and hit save.
  1239. To change a title back to the default, just leave it blank."),
  1240. "weight" => $base_weight + ($semester->semester_num * 100) + 20,
  1241. );
  1242. // Show the courses for this semester...
  1243. $contents = "";
  1244. $semester->list_courses->sort_alphabetical_order();
  1245. $semester->list_courses->reset_counter();
  1246. while($semester->list_courses->has_more()) {
  1247. $course = $semester->list_courses->get_next();
  1248. $course->load_descriptive_data();
  1249. $contents .= "$course->subject_id $course->course_num $course->requirement_type";
  1250. if ($course->min_grade != "D" && $course->min_grade != "") {
  1251. $contents .= " ($course->min_grade)";
  1252. }
  1253. $contents .= "\n";
  1254. }
  1255. $form["semester_{$semester->semester_num}_top_table_markup"] = array(
  1256. "value" => "<div class='edit-degree-semester-block'>
  1257. <table border='1' width='100%' class='edit-degree-semester-block-table'>",
  1258. "weight" => $base_weight + ($semester->semester_num * 100) + 30,
  1259. );
  1260. $form['courses_' . $semester->semester_num] = array(
  1261. 'type' => 'textarea',
  1262. 'prefix' => "<td valign='top' width='30%'>",
  1263. 'label' => 'Courses: ',
  1264. 'value' => $contents,
  1265. 'rows' => 10,
  1266. 'cols' => 20,
  1267. 'popup_description' => t("Enter course requirements in this format: \n SUBJECT COURSENUM type (MINGRADE)\n\n
  1268. type - lowercase character denoting the requirement type of the course. Make sure you have a space between it and the course number. If no type is specified, it is understood to be a major requirement.\n
  1269. min grade - Place the min grade (if there is one) in parenthesis after the type. Make sure there is a space between the min grade and the type (or course number, if there is no type specified).\n Example: ACCT 110 s (C)\n\n
  1270. Repeats require no special characters or symbols. Simply enter the course again."),
  1271. 'suffix' => "</td>",
  1272. "weight" => $base_weight + ($semester->semester_num * 100) + 40,
  1273. );
  1274. // Show the groups (and option for adding groups) for this semester...
  1275. $contents = "";
  1276. $contents .= "
  1277. <table width='100%' border='0' cellspacing='5' class='edit-degree-semester-groups-table'>
  1278. <tr>
  1279. <th valign='top' class='tenpt' width='1'>&nbsp;</td>
  1280. <th valign='top' class='tenpt'>" . t("Group") . "</td>
  1281. <th valign='top' class='tenpt' width='5'>" . t("Hrs") . "</td>
  1282. <th valign='top' class='tenpt' width='5'>" . t("Grd") . "</td>
  1283. <th valign='top' class='tenpt' width='5'>" . t("Type") . "</td>
  1284. </tr>
  1285. ";
  1286. $semester->list_groups->sort_alphabetical_order();
  1287. $semester->list_groups->reset_counter();
  1288. while($semester->list_groups->has_more()) {
  1289. $group = $semester->list_groups->get_next();
  1290. $group->load_descriptive_data();
  1291. $ghours = $group->hours_required;
  1292. // If min hours are specified, set to MIN-MAX.
  1293. if ($group->has_min_hours_allowed()) {
  1294. $ghours = $group->min_hours_allowed . "-" . $ghours;
  1295. }
  1296. $contents .= "<tr>
  1297. <td valign='middle'>
  1298. <a href='javascript: adminDelGroup(\"" . $group->get_db_group_id() . "\",\"$semester->semester_num\");'><img src='" . fp_theme_location() . "/images/delete.png' border='0'></a>
  1299. </td>
  1300. <td valign='top' class='tenpt'>
  1301. $group->title<br><i>$group->group_name</i>
  1302. </td>
  1303. <td valign='top' class='tenpt'>$ghours</td>
  1304. <td valign='top' class='tenpt'>$group->min_grade</td>
  1305. <td valign='top' class='tenpt'>$group->requirement_type
  1306. </td>
  1307. </tr>";
  1308. // Let's also add a hidden form element here, for the existing group.
  1309. $groups_counter++;
  1310. $form['group_' . $group->get_db_group_id() . '_' . $groups_counter] = array(
  1311. 'type' => 'hidden',
  1312. 'value' => $group->get_db_group_id() . "_" . $semester->semester_num . "_" . $ghours . "_" . $group->requirement_type . "_" . $group->min_grade,
  1313. );
  1314. } // while semester->list_groups
  1315. $url = fp_url("admin/degrees/popup-add-group2", "semester_num=$semester->semester_num&de_catalog_year=$de_catalog_year");
  1316. $contents .= "</table>
  1317. <div style='margin-top: 10px; margin-left: 20px; font-size:0.8em;'>
  1318. <a href='javascript: adminPopupWindow(\"$url\");'>" . t("Add an elective group") . "</a>
  1319. </div>";
  1320. // Display our contents in a markup element for this semester
  1321. $form["semester_groups_" . $semester->semester_num . "_markup"] = array(
  1322. 'prefix' => "<td valign='top'>",
  1323. 'label' => t("Groups:"),
  1324. 'value' => $contents,
  1325. "weight" => $base_weight + ($semester->semester_num * 100) + 50,
  1326. );
  1327. $form["semester_{$semester->semester_num}_table_bottom_markup"] = array(
  1328. "value" => "</table>
  1329. </div> <!-- semester block -->",
  1330. "weight" => $base_weight + ($semester->semester_num * 100) + 60,
  1331. );
  1332. $form["semester_{$semester->semester_num}_below_table_markup"] = array(
  1333. "value" => "",
  1334. "weight" => $base_weight + ($semester->semester_num * 100) + 70,
  1335. );
  1336. $form["semester_{$semester->semester_num}_save_draft_markup"] = array(
  1337. "value" => fp_render_button(t("Save Draft for @year", array("@year" => $de_catalog_year)), "adminSubmitDegreeForm2();"),
  1338. "weight" => $base_weight + ($semester->semester_num * 100) + 80,
  1339. );
  1340. } // while degree->list_semesters
  1341. // Add our js_existing_semesters array to the javascript on this page, so we can check it later.
  1342. fp_add_js($js_existing_semesters, "setting");
  1343. ////////////////////////////////////////////////////////////
  1344. ////////////////////////////////////////////////////////////
  1345. ////////////////////////////////////////////////////////////
  1346. ////////////////////////////////////////////////////////////
  1347. $bool_start_closed = TRUE;
  1348. if (@$degree->public_notes_array[$degree->degree_id] != "") {
  1349. $bool_start_closed = FALSE;
  1350. }
  1351. // Advanced options
  1352. $elements = array();
  1353. $elements['public_note'] = array(
  1354. 'type' => 'textarea',
  1355. 'label' => t('Public Note'),
  1356. 'rows' => 4,
  1357. 'value' => @$degree->public_notes_array[$degree->degree_id],
  1358. 'description' => t("You may enter simple HTML in this field. Ex: &lt;b&gt;bold&lt;/b&gt; or &lt;i&gt;italics&lt;/i&gt;"),
  1359. 'popup_description' => t("A public note will appear at the top of a degree plan when pulled up in FlightPath.
  1360. Use this to pass messages to all students and advisors who pull up this degree plan.
  1361. \n\nIt will begin with the text 'Important Message': automatically."),
  1362. "weight" => 50010,
  1363. );
  1364. // min/max/default tracks
  1365. $elements['adv_if_tracks_markup'] = array(
  1366. 'type' => 'markup',
  1367. 'value' => t('If this degre has tracks, you may enter rules for track selection below, for each
  1368. type of level 3 degree (tracks). <b>You may skip classifications which do not pertain to this degree.</b>'),
  1369. "weight" => 50020,
  1370. );
  1371. $c = 10;
  1372. $degree_classes = fp_get_degree_classifications();
  1373. foreach ($degree_classes["levels"] as $level => $details) {
  1374. $c = $c + 10;
  1375. if (intval($level) != 3) continue; // we only care about level 3...
  1376. foreach ($degree_classes["levels"][$level] as $machine_name => $title) {
  1377. $min_tracks = @intval($degree->track_selection_config_array[$machine_name]["min_tracks"]);
  1378. $max_tracks = @intval($degree->track_selection_config_array[$machine_name]["max_tracks"]);
  1379. $default_tracks = @trim($degree->track_selection_config_array[$machine_name]["default_tracks"]);
  1380. if ($min_tracks > 0 || $max_tracks > 0 || $default_tracks != "") {
  1381. $bool_start_closed = FALSE;
  1382. }
  1383. $elements["tsc_{$machine_name}_min_tracks"] = array(
  1384. 'type' => 'textfield',
  1385. 'label' => t('Min:'),
  1386. 'size' => 2,
  1387. 'value' => $min_tracks,
  1388. 'prefix' => "<table width='100%' class='admin-degrees-edit-track-rules-table'>
  1389. <tr class='admin-degrees-edit-track-selection-config track-selection-config-$machine_name'>
  1390. <td valign='top' width='30%'>
  1391. <span class='track-selection-config-title'>$title</span>:
  1392. </td>
  1393. <td valign='top'>",
  1394. 'suffix' => "</td>",
  1395. 'popup_description' => t("This is the minimum number of tracks THIS degree must select. For example, if the degree requires at least one track, enter a 1 (one) in this box.\n\n
  1396. The default is zero (0), which means that no track is required for this degree. The user is not required to select any at all.\n\n
  1397. If you are unsure what to enter, leave it set to 0 (zero)."),
  1398. "weight" => 60000 + $c + 1,
  1399. );
  1400. $elements["tsc_{$machine_name}_max_tracks"] = array(
  1401. 'type' => 'textfield',
  1402. 'label' => t('Max:'),
  1403. 'size' => 2,
  1404. 'value' => $max_tracks,
  1405. 'prefix' => "<td valign='top'>",
  1406. 'suffix' => "</td>",
  1407. 'popup_description' => t("This is the maximum number of tracks THIS degree may select. For example, if the degree requires the student to have NO MORE than 1 track selected, you would enter 1 (one) in this box.\n\n
  1408. The default is zero (0), which means that there is no maximum; the user may select as many of this degree's tracks as they wish.\n\n
  1409. If you are unsure what to enter, leave it set to 0 (zero)."),
  1410. "weight" => 60000 + $c + 5,
  1411. );
  1412. $elements["tsc_{$machine_name}_default_tracks"] = array(
  1413. 'type' => 'textfield',
  1414. 'label' => t('Default Tracks:'),
  1415. 'size' => 25,
  1416. 'value' => $default_tracks,
  1417. 'prefix' => "<td valign='top'>",
  1418. 'suffix' => "</td>
  1419. </tr>
  1420. </table>",
  1421. 'popup_description' => t("If THIS degree has one or more 'default' tracks associated with it (ex: for What If mode), enter the FULL major codes here, separated by comma.\n\n
  1422. For example: ART|_SCULP, ART|_PAINT\n\n
  1423. If you are unsure what to enter, leave it blank."),
  1424. "weight" => 60000 + $c + 7,
  1425. );
  1426. } // foreach levels[$level]
  1427. } // foreach levels as level => details
  1428. // Place in our advanced options fs.
  1429. $form['advanced_options_fs'] = array(
  1430. 'type' => 'cfieldset',
  1431. 'label' => t('View advanced options'),
  1432. 'elements' => array($elements),
  1433. 'start_closed' => $bool_start_closed,
  1434. "weight" => 50100,
  1435. );
  1436. // Only show delete option based on permission
  1437. if (user_has_permission("can_delete_data_entry")) {
  1438. $form['markup_bottom_delete'] = array(
  1439. "value" => " <div align='right' class='degrees-delete-degree-wrapper'>
  1440. Delete this degree? <input type='button' value='X'
  1441. onClick='adminDeleteDegree(\"$degree_id\");'>
  1442. </div>
  1443. ",
  1444. "weight" => 90000,
  1445. );
  1446. }
  1447. return $form;
  1448. } // admin_edit_degree_form
  1449. function admin_edit_degree_form_submit($form, $form_state) {
  1450. $values = $form_state['values'];
  1451. // Set the scroll_top position, if it is set.
  1452. $scroll_top = $form_state['values']['scroll_top'];
  1453. if (@$scroll_top != "" && intval($scroll_top) > 0) {
  1454. $_SESSION['scroll_top'] = $scroll_top;
  1455. }
  1456. // Perform actual saves to database
  1457. $de_catalog_year = $values["de_catalog_year"];
  1458. $db = get_global_database_handler();
  1459. // What courses should have their type overwritten as "x"?
  1460. $ignore_courses = csv_to_array(variable_get("ignore_courses_from_hour_counts", ""));
  1461. // This will UPDATE a degree in the system with the courses
  1462. // and groups that the user selected.
  1463. $perform_action2 = trim($values["perform_action2"]);
  1464. if (strstr($perform_action2, "delGroup")) {
  1465. $temp = explode("_",$perform_action2);
  1466. $del_group = new Group();
  1467. $del_group->bool_use_draft = true;
  1468. $del_group->group_id = $temp[1];
  1469. $del_group->assigned_to_semester_num = $temp[2];
  1470. }
  1471. $major_code = trim($values["major_code"]);
  1472. if ($major_code == ""){ die("Fatal error: major_code not found.");}
  1473. // Since we are making a change to the draft table(s), let's add a row
  1474. // to draft instructions.
  1475. $db->add_draft_instruction("-");
  1476. // Let's assemble the track selection config values into one string. We need to loop through all of the POST
  1477. // values, looking for each type of track.
  1478. $db_track_selection_config = "";
  1479. $degree_classes = fp_get_degree_classifications();
  1480. foreach ($degree_classes["levels"] as $level => $details) {
  1481. if (intval($level) != 3) continue; // we only care about level 3...
  1482. foreach ($degree_classes["levels"][$level] as $machine_name => $title) {
  1483. // Got the machine name, now let's see if we have any values for
  1484. // the track selections...
  1485. $min_tracks = @intval($values["tsc_{$machine_name}_min_tracks"]);
  1486. $max_tracks = @intval($values["tsc_{$machine_name}_max_tracks"]);
  1487. $default_tracks = @trim($values["tsc_{$machine_name}_default_tracks"]);
  1488. $db_track_selection_config .= $machine_name . "~" . $min_tracks . "~" . $max_tracks . "~" . $default_tracks . "\n";
  1489. }
  1490. }
  1491. $degree_id = "";
  1492. // If this degree already exists in this
  1493. // catalog year, then we need to delete it first.
  1494. if ($degree_id = $db->get_degree_id($major_code, $de_catalog_year, true)) {
  1495. $degree = new DegreePlan($degree_id, null, false, false, true);
  1496. $degree->load_descriptive_data();
  1497. // Delete from degree_requirements WHERE this degree_id exists.
  1498. $res = db_query("DELETE FROM draft_degree_requirements
  1499. WHERE degree_id = '?' ", $degree_id);
  1500. ///////////////////////////////
  1501. // Are we trying to DELETE this degree? If so, keep deleting!
  1502. if ($perform_action2 == "delete_degree" && user_has_permission("can_delete_data_entry")) {
  1503. $res = db_query("DELETE FROM draft_degrees
  1504. WHERE degree_id = '?' ", $degree_id);
  1505. // Also need to get rid of the track, if there is one for this
  1506. // degree.
  1507. $temp = explode("_", $degree->major_code); // get only the "major" part from the full major_code (might look like ACCT|FINA_TRACK1
  1508. $just_major_part = trim($temp[0]);
  1509. $just_major_part = rtrim($just_major_part, "|"); // if there is now a trailing |, get rid of it. Ex: ACCT|
  1510. $res = db_query("DELETE FROM draft_degree_tracks
  1511. WHERE major_code = ?
  1512. AND track_code = ?
  1513. AND catalog_year = ? LIMIT 1", $just_major_part, $degree->track_code, $de_catalog_year);
  1514. // Okay, we have deleted everything. We need to go back to
  1515. // just the list of degrees.
  1516. //display_edit_degrees("<font color='green'><b>The degree $major_code ($de_catalog_year) has been deleted.</b></font>");
  1517. //die;
  1518. fp_add_message("The degree $major_code ($de_catalog_year) has been deleted.");
  1519. unset($_SESSION['scroll_top']);
  1520. unset($_REQUEST['scroll_top']);
  1521. fp_goto("admin/degrees", "de_catalog_year=$de_catalog_year");
  1522. return;
  1523. } // if perform_action2 == delete_degree
  1524. } // if degree->id = db->get_degree_id, etc
  1525. else {
  1526. // We need to generate a new degreeID for this major_code and catalog_year,
  1527. // because one does not already exist!
  1528. if (!$degree_id = $db->request_new_degree_id()) {
  1529. die ("Error. Could not create new degree_id.");
  1530. }
  1531. } // ELSE
  1532. ///////////////////////////////////////
  1533. // Are we trying to add/edit/delete a semester block?
  1534. if (strstr($perform_action2, "editSemester")) {
  1535. $temp = explode("_",$perform_action2);
  1536. $act = $temp[1];
  1537. $semester_num = $temp[2];
  1538. if ($act == "new") {
  1539. // We will add a comment to the courses box, just to keep it alive, which will be ignored later.
  1540. $values["courses_$semester_num"] = "#";
  1541. } // if act == new
  1542. if ($act == "del") {
  1543. // We will remove data for this semester block.
  1544. unset($values["courses_$semester_num"]);
  1545. unset($values["semester_title_$semester_num"]);
  1546. foreach($values as $key => $value) {
  1547. if (!strstr($key, "group_")) {
  1548. continue;
  1549. }
  1550. // Only look at the groups...
  1551. $temp = explode("_", $value);
  1552. $g_semester_num = $temp[1];
  1553. if ($g_semester_num == $semester_num) {
  1554. unset($values[$key]);
  1555. }
  1556. }
  1557. } // if act == del
  1558. } // if perform_action2 contains editSemester
  1559. ///////////////////////////////////////
  1560. // Okay, time to start actually inserting our data into the db.
  1561. $errors = "";
  1562. $semester_titles_csv = "";
  1563. $highest_semester_num = 0; // What is the largest semester_num in the system?
  1564. // Get the COURSES for each semester
  1565. foreach($values as $key => $value) {
  1566. if (!strstr($key, "courses_")) {
  1567. continue;
  1568. }
  1569. // Only look at the groups...
  1570. $temp = explode("_", $key);
  1571. $semester_num = trim($temp[1]);
  1572. $courses = trim(@$values["courses_$semester_num"]);
  1573. // Does it contain a single #? Or, is blank? If so, insert and move on.
  1574. // We do this, so we can have blank semesters until someone deletes them.
  1575. if ($courses == "#" || $courses == "") {
  1576. $query = "INSERT INTO draft_degree_requirements
  1577. (degree_id, semester_num, course_id, course_min_grade, course_requirement_type, data_entry_value)
  1578. values (?,?,?,?,?,?) ";
  1579. $res = db_query($query, $degree_id, $semester_num, 0, '', '', "#");
  1580. continue;
  1581. }
  1582. if ($semester_num > $highest_semester_num) {
  1583. $highest_semester_num = $semester_num;
  1584. }
  1585. $course_rows = explode("\n",$courses);
  1586. for ($t = 0; $t < count($course_rows); $t++) {
  1587. $line = trim($course_rows[$t]);
  1588. if ($line == "") {
  1589. continue;
  1590. }
  1591. // Take out extra whitespace between tokens.
  1592. $line = str_replace(" ", " ", $line);
  1593. $line = str_replace(" ", " ", $line);
  1594. $line = str_replace(" ", " ", $line);
  1595. $line = str_replace(" ", " ", $line);
  1596. $tokens = explode(" ", $line);
  1597. $subject_id = $tokens[0];
  1598. $course_num = $tokens[1];
  1599. $requirement_type = strtolower(@$tokens[2]);
  1600. if ($requirement_type == "") {
  1601. // major type by default.
  1602. $requirement_type = "m";
  1603. }
  1604. // If this course is in our ignore list, override it's type
  1605. // to be 'x'
  1606. if (in_array("$subject_id $course_num", $ignore_courses)) {
  1607. $requirement_type = "x";
  1608. }
  1609. $min_grade = strtoupper(@$tokens[3]);
  1610. if (strstr($requirement_type, "(")) {
  1611. // This means there was no requirement_type specified, so it's "m",
  1612. // and a min_grade was found in its place.
  1613. $min_grade = strtoupper($requirement_type);
  1614. $requirement_type = "m";
  1615. }
  1616. $min_grade = str_replace("(","",$min_grade);
  1617. $min_grade = str_replace(")","",$min_grade);
  1618. /////////////////////////////////////////////
  1619. // Okay, we now have enough information to insert the course.
  1620. // Find out what the course_id is.
  1621. if ($course_id = $db->get_course_id($subject_id, $course_num, "", true)) // don't care about catalog year.
  1622. {
  1623. $query = "INSERT INTO draft_degree_requirements
  1624. (degree_id, semester_num, course_id, course_min_grade, course_requirement_type, data_entry_value)
  1625. values (?,?,?,?,?,?) ";
  1626. $res = db_query($query, $degree_id, $semester_num, $course_id, $min_grade, $requirement_type, "$subject_id~$course_num");
  1627. //debug_c_t($query);
  1628. } else {
  1629. // The course_id could not be found!
  1630. $errors .= "<br><span style='color:red;'><b>Course Not Found!</b>
  1631. In Block " . ($semester_num+1) . ", you specified the course
  1632. <b>$subject_id $course_num</b> as a requirement, but this course
  1633. could not be found.
  1634. It was removed from that block.
  1635. Are you sure you typed it correctly? Please go to this
  1636. semester, check your spelling, and add the course again.</span>";
  1637. }
  1638. }
  1639. } // foreach values, looking for courses_
  1640. // Get the groups....
  1641. foreach($values as $key => $value) {
  1642. if (!strstr($key, "group_")) {
  1643. continue;
  1644. }
  1645. // Only look at the groups...
  1646. $temp = explode("_", $value);
  1647. $group_id = $temp[0];
  1648. $semester_num = $temp[1];
  1649. $hours = $temp[2];
  1650. $min_hours = $hours;
  1651. if (strstr($hours, "-")) {
  1652. // Hours has a min hour value specified. let's grab it.
  1653. $tt = explode("-", $hours);
  1654. $min_hours = $tt[0];
  1655. $hours = $tt[1];
  1656. }
  1657. $type = $temp[3];
  1658. $min_grade = trim($temp[4]);
  1659. if ($semester_num > $highest_semester_num) {
  1660. $highest_semester_num = $semester_num;
  1661. }
  1662. // Do not add if we are supposed to be deleting this group!
  1663. if (isset($del_group) && is_object($del_group)) {
  1664. if ($del_group->group_id == $group_id && $del_group->assigned_to_semester_num == $semester_num) {
  1665. continue;
  1666. }
  1667. }
  1668. $adding_group = new Group($group_id);
  1669. // If this group is already saved in this degree elsewhere, and it has a different type or min_grade,
  1670. // then we must display a warning message to the user.
  1671. $res = db_query("SELECT * FROM draft_degree_requirements
  1672. WHERE degree_id = '?'
  1673. AND group_id = '?'
  1674. AND (group_min_grade <> '?' OR group_requirement_type <> '?')", $degree_id, $group_id, $min_grade, $type);
  1675. while ($cur = db_fetch_array($res)) {
  1676. $errors .= "<br><span style='color:red;'><b>Group type or min grade mismatch!</b>
  1677. In Block " . ($semester_num + 1) . ", you specified the group <em>" . $adding_group->title . "</em> ($adding_group->group_name) with a min grade of \"<em>$min_grade</em>\"
  1678. and a requirement type of \"<em>$type</em>\". However, the group was previously specified in this degree plan in Block " . ($cur["semester_num"] + 1) . "
  1679. with a different requirement type and/or min grade requirement. FlightPath will not perform calculations correctly for courses assigned to this group.
  1680. You should either set the duplicate occurances of the group to the same type/min grade, or create a new group to handle these alternate requirements.</span>";
  1681. }
  1682. // We now have enough information to insert this group.
  1683. $query = "INSERT INTO draft_degree_requirements
  1684. (degree_id, semester_num, group_id,
  1685. group_requirement_type, group_hours_required, group_min_hours_allowed, group_min_grade)
  1686. values (?,?,?,?,?,?,?) ";
  1687. $res = db_query($query, $degree_id, $semester_num, $group_id, $type, $hours, $min_hours, $min_grade);
  1688. } // for each values, looking for _group
  1689. // Was there a group added?
  1690. if (strstr($perform_action2,"addGroup")) {
  1691. $temp = explode("_",$perform_action2);
  1692. $group_id = $temp[1];
  1693. $semester_num = $temp[2];
  1694. $hours = trim($temp[3]);
  1695. $min_hours = $hours;
  1696. if (strstr($hours, "-")) {
  1697. // Hours has a min hour value specified. let's grab it.
  1698. $tt = explode("-", $hours);
  1699. $min_hours = $tt[0];
  1700. $hours = $tt[1];
  1701. }
  1702. $type = $temp[4];
  1703. $min_grade = trim($temp[5]);
  1704. $adding_group = new Group($group_id);
  1705. // If this group is already saved in this degree elsewhere, and it has a different type or min_grade,
  1706. // then we must display a warning message to the user.
  1707. $res = db_query("SELECT * FROM draft_degree_requirements
  1708. WHERE degree_id = '?'
  1709. AND group_id = '?'
  1710. AND (group_min_grade <> '?' OR group_requirement_type <> '?')", $degree_id, $group_id, $min_grade, $type);
  1711. while ($cur = db_fetch_array($res)) {
  1712. $errors .= "<br><span style='color:red;'><b>Group type or min grade mismatch!</b>
  1713. In Block " . ($semester_num + 1) . ", you specified the group <em>" . $adding_group->title . "</em> ($adding_group->group_name) with a min grade of \"<em>$min_grade</em>\"
  1714. and a requirement type of \"<em>$type</em>\". However, the group was previously specified in this degree plan in Block " . ($cur["semester_num"] + 1) . "
  1715. with a different requirement type and/or min grade requirement. FlightPath will not perform calculations correctly for courses assigned to this group.
  1716. You should either set the duplicate occurances of the group to the same type/min grade, or create a new group to handle these alternate requirements.</span>";
  1717. }
  1718. $query = "INSERT INTO draft_degree_requirements
  1719. (degree_id,semester_num,group_id,
  1720. group_requirement_type,group_hours_required,group_min_hours_allowed,group_min_grade)
  1721. VALUES (?,?,?,?,?,?,?) ";
  1722. $res = db_query($query, $degree_id, $semester_num, $group_id, $type, $hours, $min_hours, $min_grade);
  1723. } // if perform_action2 == addGroup
  1724. // Make the semester_titles_csv...
  1725. for ($semester_num = 0; $semester_num <= $highest_semester_num; $semester_num++) {
  1726. if ($semester_num > 99) break; // some problem. Give up. Don't try to go past 99 semesters!
  1727. $semester_titles_csv .= trim(@$values["semester_title_$semester_num"]) . ",";
  1728. }
  1729. // Before we UPDATE, also grab the degree title, degree_type,
  1730. // and exclude value, etc....
  1731. $degree_title = trim($values["title"]);
  1732. $degree_type = trim($values["degree_type"]);
  1733. $degree_class = trim($values["degree_class"]);
  1734. $degree_level = strtoupper(trim($values["degree_level"]));
  1735. $exclude = intval($values["exclude"]);
  1736. $allow_dynamic = intval($values["allow_dynamic"]);
  1737. $advising_weight = intval($values["advising_weight"]);
  1738. $override_degree_hours = trim($values["override_degree_hours"]);
  1739. $public_note = trim($values["public_note"]);
  1740. $res = db_query("UPDATE draft_degrees
  1741. SET semester_titles_csv = ?,
  1742. title = ?,
  1743. degree_type = ?,
  1744. degree_class = ?,
  1745. degree_level = ?,
  1746. exclude = ?,
  1747. allow_dynamic = ?,
  1748. advising_weight = ?,
  1749. override_degree_hours = ?,
  1750. track_selection_config = ?,
  1751. public_note = ?
  1752. WHERE degree_id = ? ",
  1753. $semester_titles_csv, $degree_title, $degree_type, $degree_class, $degree_level, $exclude, $allow_dynamic, $advising_weight, $override_degree_hours,
  1754. $db_track_selection_config, $public_note, $degree_id);
  1755. //// Was there a track title/description? If so, UPDATE that in the tracks
  1756. // table...
  1757. if (strstr($major_code, "_")) {
  1758. // There was a track. Update track description.
  1759. $temp = explode("_",$major_code);
  1760. $major = trim($temp[0]);
  1761. // major might now have a | at the end. If so, take it out.
  1762. if (substr($major, strlen($major)-1, 1) == "|") {
  1763. $major = str_replace("|","",$major);
  1764. }
  1765. $track = trim($temp[1]);
  1766. $track_description = trim($values["track_description"]);
  1767. $track_title = trim($values["track_title"]);
  1768. // Make sure the track exists in our draft_degree_tracks table...
  1769. $track_id = db_result(db_query("SELECT track_id FROM draft_degree_tracks
  1770. WHERE major_code = ?
  1771. AND track_code = ?
  1772. AND catalog_year = ?", $major, $track, $de_catalog_year));
  1773. if (!$track_id) {
  1774. // Didn't already exist. Let's insert.
  1775. db_query("INSERT INTO draft_degree_tracks (major_code, track_code, catalog_year)
  1776. VALUES (?, ?, ?)", $major, $track, $de_catalog_year);
  1777. $track_id = db_insert_id();
  1778. }
  1779. /*
  1780. $res = db_query("UPDATE draft_degree_tracks
  1781. SET `track_description`='?',
  1782. `track_title`='?'
  1783. WHERE `track_code`='?'
  1784. AND `major_code`='?'
  1785. AND `catalog_year`='?' ", $track_description, $track_title, $track, $major, $de_catalog_year);
  1786. */
  1787. $res = db_query("UPDATE draft_degree_tracks
  1788. SET track_description = ?,
  1789. track_title = ?
  1790. WHERE track_id = ? ", $track_description, $track_title, $track_id);
  1791. }
  1792. fp_add_message("Degree updated succesfully.");
  1793. $button_msg = urlencode("Degree updated successfully at " . date("H:i:s"));
  1794. $bool_scroll = $bool_button_msg = true;
  1795. if ($errors != "")
  1796. {
  1797. fp_add_message("ERRORS/WARNINGS: $errors");
  1798. $bool_scroll = $bool_button_msg = false;
  1799. $button_msg = urlencode("The degree plan was saved, but an error or warning has occured. Please see error message at the top of the page.");
  1800. $_REQUEST["scroll_top"] = 0;
  1801. $_SESSION["scroll_top"] = 0;
  1802. }
  1803. ///////////////////////////////////////////////////////
  1804. ///////////////////////////////////////////////////////
  1805. ///////////////////////////////////////////////////////
  1806. ///////////////////////////////////////////////////////
  1807. // And we are done with the saving!
  1808. } //edit_degree_form_submit
  1809. /**
  1810. * This screen displays the form which allows the user to actually
  1811. * edit a degree.
  1812. */
  1813. function admin_display_edit_degree() {
  1814. $de_catalog_year = admin_get_de_catalog_year();
  1815. $rtn = "";
  1816. $major_code = $_REQUEST["major_code"];
  1817. $s_count = 0;
  1818. // Add in our CSS and JS
  1819. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  1820. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  1821. $button_msg = trim(addslashes(@$_REQUEST["button_msg"]));
  1822. $db = get_global_database_handler();
  1823. $degree_id = intval($db->get_degree_id($major_code, $de_catalog_year, true));
  1824. // The intval says, if it's false, make it = 0. otherwise keep the number
  1825. // that is returned.
  1826. $degree = new DegreePlan($degree_id, null, false, false, true);
  1827. $degree->load_descriptive_data();
  1828. if (user_has_permission("can_view_advanced")) {
  1829. $rtn .= " <span class='tenpt deg-advanced-msg' style='background-color: yellow; margin-left: 20px;'>
  1830. advanced: degreeID = $degree_id. catalog year: $de_catalog_year
  1831. </span>";
  1832. }
  1833. $url = fp_url("admin/degrees/handle-edit-degree-submit");
  1834. $rtn .= "<form id='mainform' action='" . $url . "' method='POST'>
  1835. <input type='hidden' name='perform_action2' id='perform_action2'>
  1836. <input type='hidden' name='de_catalog_year' value='$de_catalog_year'>
  1837. <input type='hidden' name='scroll_top' id='scroll_top' value=''>
  1838. <input type='hidden' name='major_code' value='$major_code'>
  1839. ";
  1840. $rtn .= "<div style='font-size: 16pt; font-weight:bold; padding-top: 20px;'>$degree->degree_type $degree->title<br>$major_code ($de_catalog_year)</div>";
  1841. $rtn .= "
  1842. <table border='0' class='degree-edit-top-part'>
  1843. <tr>
  1844. <td valign='top' class='tenpt td-d-type-lable' width='15%'>" . t("Degree Type:") . "</td>
  1845. <td valign='top' class='tenpt td-d-type' >
  1846. <input type='text' name='degree_type' value='$degree->degree_type' size='5' maxlength='20'>
  1847. <a href='javascript: adminPopupAlertHelp(\"degree_type\");'>?</a>
  1848. </td>
  1849. <td valign='top' class='tenpt' width=''>
  1850. " . t("Classification:") . "
  1851. <select name='degree_class' style='max-width: 120px;'> ";
  1852. //<input type='text' name='degree_class' value='$degree->degree_class' size='10' maxlength='40'>
  1853. // Display degree_class pulldown.
  1854. $degree_classes = fp_get_degree_classifications();
  1855. foreach ($degree_classes["levels"] as $level => $details) {
  1856. foreach ($degree_classes["levels"][$level] as $machine_name => $title) {
  1857. $sel = "";
  1858. if ($machine_name == $degree->degree_class) $sel = "selected";
  1859. $rtn .= "<option value='$machine_name' $sel>$level - $title</option>";
  1860. }
  1861. }
  1862. $rtn .= "</select>
  1863. <a href='javascript: adminPopupAlertHelp(\"degree_class\");'>?</a>
  1864. </td>
  1865. <td valign='top' class='tenpt td-lev-weight' >" . t("Level:") . "
  1866. <input type='text' id='edit-degree-level' name='degree_level' value='$degree->degree_level' size='1' maxlength='1'>
  1867. <a href='javascript: adminPopupAlertHelp(\"degree_level\");'>?</a>
  1868. &nbsp; &nbsp;
  1869. " . t("Advising Weight:") . "
  1870. <input type='text' id='edit-advising-weight' name='advising_weight' value='$degree->db_advising_weight' size='1' maxlength='5'>
  1871. <a href='javascript: adminPopupAlertHelp(\"advising_weight\");'>?</a>
  1872. </td>
  1873. <td valign='top'>
  1874. </td>
  1875. </tr>
  1876. <tr>
  1877. <td valign='top' class='tenpt td-title-lab'>" . t("Title:") . "</td>
  1878. <td valign='top' class='tenpt td-title-field' colspan='4'><input type='text' name='title' value='$degree->title' size='80' maxlength='100'></td>
  1879. </tr>
  1880. <tr>
  1881. <td valign='top' class='tenpt td-ex-lab'>" . t("Exclude:") . "</td>
  1882. <td valign='top' class='tenpt td-ex'>
  1883. <input type='text' name='exclude' value='$degree->db_exclude' size='2' maxlength='1'>
  1884. <a href='javascript: adminPopupAlertHelp(\"degree_exclude\");'>?</a>
  1885. </td>
  1886. <td valign='top' class='tenpt td-al-dy' >
  1887. " . t("Allow Dynamic:") . "
  1888. &nbsp;
  1889. <input type='text' name='allow_dynamic' value='$degree->db_allow_dynamic' size='2' maxlength='1'>
  1890. <a href='javascript: adminPopupAlertHelp(\"degree_allow_dynamic\");'>?</a>
  1891. </td>
  1892. <td valign='top' class='tenpt td-o-dh' >
  1893. " . t("Override Degree Hours:") . "
  1894. &nbsp;
  1895. <input type='text' name='override_degree_hours' value='$degree->db_override_degree_hours' size='3' maxlength='10'>
  1896. <a href='javascript: adminPopupAlertHelp(\"degree_override_degree_hours\");'>?</a>
  1897. </td>
  1898. <td>
  1899. </td>
  1900. </tr>
  1901. </table> ";
  1902. if (strstr($major_code, "_"))
  1903. {
  1904. $rtn .= "<b>Edit track information:</b>
  1905. <blockquote style='margin-top: 0px; margin-bottom: 0px;'>
  1906. <font size='2'>Track title: <input type='text' name='track_title' value='$degree->track_title' size='60' maxlength='100'></font><br>
  1907. <font size='2'>Track description: " . fp_get_js_alert_link(t("You may enter simple HTML in this field, like <b>bold</b> or <i>italics</i>."), t("(Help - Formatting)")) . "
  1908. <a href='javascript: adminPopupAlertHelp(\"track_description\");'>(Help - Track Descriptions)</a>
  1909. </font><br>
  1910. <textarea name='track_description' cols='60' rows='3'>" . $degree->track_description . "</textarea>
  1911. </blockquote>
  1912. ";
  1913. }
  1914. $rtn .= "<div class='tenpt' align='center'>(<a href='#bot'>Scroll to the bottom</a> of the page for advanced options)</div>
  1915. <!--PREVIOUS_SEMESTERS-->";
  1916. $first_semester_num = -999;
  1917. $degree->list_semesters->reset_counter();
  1918. while ($degree->list_semesters->has_more()) {
  1919. $semester = $degree->list_semesters->get_next();
  1920. if ($semester->semester_num < 0) {
  1921. continue;
  1922. }
  1923. // Record what is the first semester num we have...
  1924. if ($first_semester_num == -999) {
  1925. $first_semester_num = $semester->semester_num;
  1926. }
  1927. $sem_default_title = admin_get_semester_name($semester->semester_num);
  1928. if ($semester->title == $sem_default_title) {
  1929. $semester->title = "";
  1930. }
  1931. $rtn .= "<div class='elevenpt' style='padding-bottom: 30px;'>
  1932. <b>Block number: " . ($semester->semester_num +1) . "</b>
  1933. &nbsp; &nbsp; &nbsp; &nbsp;
  1934. Default title: $sem_default_title
  1935. &nbsp; &nbsp;
  1936. Override: <input type='text' name='semester_title_$semester->semester_num' value='$semester->title' size='20'>
  1937. <a href='javascript: adminPopupAlertHelp(\"semester_title\");'>?</a>
  1938. <table border='1' width='100%'>
  1939. ";
  1940. // Get the courses.
  1941. $rtn .= "<tr><td valign='top'>
  1942. <textarea name='courses_$semester->semester_num' rows='10' cols='20'>";
  1943. $semester->list_courses->sort_alphabetical_order();
  1944. $semester->list_courses->reset_counter();
  1945. while($semester->list_courses->has_more()) {
  1946. $course = $semester->list_courses->get_next();
  1947. $course->load_descriptive_data();
  1948. $rtn .= "$course->subject_id $course->course_num $course->requirement_type";
  1949. if ($course->min_grade != "D" && $course->min_grade != "") {
  1950. $rtn .= " ($course->min_grade)";
  1951. }
  1952. $rtn .= "\n";
  1953. }
  1954. $rtn .= "</textarea>
  1955. <div class='tenpt'>(<a href='javascript: adminPopupAlertHelp(\"degree_entry\");'>Help - entering requirements, min grades, and repeats</a>)</div>
  1956. </td>";
  1957. // Get the groups...
  1958. $rtn .= "<td valign='top' class='tenpt' width='100%'>
  1959. <table width='100%' border='0' cellspacing='5'>
  1960. <tr>
  1961. <td valign='top' class='tenpt' width='1'>&nbsp;</td>
  1962. <td valign='top' class='tenpt'>Group</td>
  1963. <td valign='top' class='tenpt' width='5'>hrs</td>
  1964. <td valign='top' class='tenpt' width='5'>grd</td>
  1965. <td valign='top' class='tenpt' width='5'>type</td>
  1966. </tr>";
  1967. $semester->list_groups->sort_alphabetical_order();
  1968. $semester->list_groups->reset_counter();
  1969. while($semester->list_groups->has_more()) {
  1970. $group = $semester->list_groups->get_next();
  1971. $group->load_descriptive_data();
  1972. $ghours = $group->hours_required;
  1973. // If min hours are specified, set to MIN-MAX.
  1974. if ($group->has_min_hours_allowed()) {
  1975. $ghours = $group->min_hours_allowed . "-" . $ghours;
  1976. }
  1977. $rtn .= "<tr><td valign='middle'>
  1978. <a href='javascript: adminDelGroup(\"" . $group->get_db_group_id() . "\",\"$semester->semester_num\");'><img src='" . fp_theme_location() . "/images/delete.png' border='0'></a>
  1979. <td valign='top' class='tenpt'>
  1980. $group->title<br><i>$group->group_name</i></td>
  1981. <td valign='top' class='tenpt'>$ghours</td>
  1982. <td valign='top' class='tenpt'>$group->min_grade</td>
  1983. <td valign='top' class='tenpt'>$group->requirement_type
  1984. <input type='hidden' name='group_" . $group->get_db_group_id() . "_" . rand(1,999999) . "' value='" . $group->get_db_group_id() . "" . "_$semester->semester_num" . "_$ghours" . "_$group->requirement_type" . "_$group->min_grade'>
  1985. </td>";
  1986. }
  1987. $url = fp_url("admin/degrees/popup-add-group", "semester_num=$semester->semester_num&de_catalog_year=$de_catalog_year");
  1988. $rtn .= "</table>
  1989. <div style='margin-top: 10px; margin-left: 20px;'>
  1990. <a href='javascript: adminPopupWindow(\"" . $url . "\");'>Add an elective group</a>
  1991. </div>
  1992. </td>";
  1993. $rtn .= "</table><br>
  1994. " . fp_render_button(t("Save for @year", array("@year" => $de_catalog_year)), "adminSubmitForm();") . "
  1995. <span class='admin-button-msg'>$button_msg</span>
  1996. </div>
  1997. ";
  1998. $s_count = $semester->semester_num+1;
  1999. }
  2000. // Always add an additional 4 semesters to the bottom. Also, add in any missing semesters to the top of the degree as well.
  2001. $deltas = array("top", "bottom");
  2002. foreach ($deltas as $delta) {
  2003. $html = "";
  2004. // Set for if delta == bottom.
  2005. $start_at = $s_count; // s_count was the last semester we created above.
  2006. $less_than = 4;
  2007. if ($delta == "top") {
  2008. // We are creating semesters for the top of the page, if needed.
  2009. if ($first_semester_num == -999) {
  2010. continue; // None were put at the top! We can skip it.
  2011. }
  2012. else {
  2013. $start_at = 0;
  2014. $less_than = $first_semester_num;
  2015. }
  2016. }
  2017. for ($t = 0; $t < $less_than; $t++) {
  2018. $sem = $t + $start_at;
  2019. if ($sem > 99) {
  2020. // Max number of semesters. More or less arbitrarily set number.
  2021. $html .= "<br>" . t("Maximum number of semesters created.") . "<br>";
  2022. break;
  2023. }
  2024. $html .= "<div class='elevenpt' style='padding-bottom: 30px;'>
  2025. <b>Block number: " . ($sem+1) . "</b>
  2026. &nbsp; &nbsp; &nbsp; &nbsp;
  2027. Default title: " . admin_get_semester_name($sem) . "
  2028. &nbsp; &nbsp;
  2029. Override: <input type='text' name='semester_title_$sem' value='' size='20'>
  2030. <a href='javascript: adminPopupAlertHelp(\"semester_title\");'>?</a>
  2031. <table border='1' width='100%'>
  2032. ";
  2033. $html .= "<tr><td valign='top'>
  2034. <textarea name='courses_$sem' rows='10' cols='20'>";
  2035. $html .= "</textarea></td>";
  2036. // the groups...
  2037. $html .= "<td valign='top' class='tenpt' width='100%'>
  2038. <table width='100%' border='0' cellspacing='5'>
  2039. <tr>
  2040. <td valign='top' class='tenpt' width='1'>&nbsp;</td>
  2041. <td valign='top' class='tenpt'>Group</td>
  2042. <td valign='top' class='tenpt'>hrs</td>
  2043. <td valign='top' class='tenpt'>grd</td>
  2044. <td valign='top' class='tenpt'>type</td>
  2045. </tr>";
  2046. $url = fp_url("admin/degrees/popup-add-group", "semester_num=$sem&de_catalog_year=$de_catalog_year");
  2047. $html .= "</table>
  2048. <div style='margin-top: 10px; margin-left: 20px;'>
  2049. <a href='javascript: adminPopupWindow(\"" . $url . "\");'>Add an elective group</a>
  2050. </td>";
  2051. $html .= "</table><br>
  2052. " . fp_render_button(t("Save for @year", array("@year" => $de_catalog_year)), "adminSubmitForm();") . "
  2053. <span class='admin-button-msg'>$button_msg</span>
  2054. </div>";
  2055. } // creating a blank semester block
  2056. // Add $html to wherever it needs to go.
  2057. if ($delta == "bottom") {
  2058. $rtn .= $html;
  2059. }
  2060. else if ($delta == "top") {
  2061. // Place the HTML at the top of the page by replacing our html comment.
  2062. $rtn = str_replace("<!--PREVIOUS_SEMESTERS-->", $html, $rtn);
  2063. }
  2064. } //foreach delta
  2065. $rtn .= "<div class='elevenpt'>If you need more semester boxes, simply save this page, and additional blank
  2066. boxes will appear below.</div>
  2067. <a name='bot'></a>
  2068. <br><br>
  2069. ";
  2070. $html = "";
  2071. $html .= "
  2072. <div class='elevenpt'>
  2073. Enter a public note for this degree:
  2074. <a href='javascript: adminPopupAlertHelp(\"public_note\");'>(Help - Public Note)</a>
  2075. " . fp_get_js_alert_link(t("You may enter simple HTML in this field, like <b>bold</b> or <i>italics</i>."), t("(Help - Formatting)")) . "
  2076. <br>
  2077. <textarea name='public_note' rows='4' cols='80'>" . @$degree->public_notes_array[$degree->degree_id] . "</textarea>
  2078. <br><br>
  2079. If this degree has tracks, you may enter rules for track selection below, for each type of level 3 degree (tracks) you might have.
  2080. <b>You may skip classifications which do not pertain to this degree.</b>
  2081. <br><br>
  2082. <table border='0' width='100%'>
  2083. <tr>
  2084. <th>Class:</th>
  2085. <th>Min: <a href='javascript: adminPopupAlertHelp(\"min_tracks\");'>?</a></th>
  2086. <th>Max: <a href='javascript: adminPopupAlertHelp(\"max_tracks\");'>?</a></th>
  2087. <th>Default tracks (CSV): <a href='javascript: adminPopupAlertHelp(\"default_tracks\");'>?</a></th>
  2088. </tr>
  2089. ";
  2090. $degree_classes = fp_get_degree_classifications();
  2091. foreach ($degree_classes["levels"] as $level => $details) {
  2092. if (intval($level) != 3) continue; // we only care about level 3...
  2093. foreach ($degree_classes["levels"][$level] as $machine_name => $title) {
  2094. $min_tracks = @intval($degree->track_selection_config_array[$machine_name]["min_tracks"]);
  2095. $max_tracks = @intval($degree->track_selection_config_array[$machine_name]["max_tracks"]);
  2096. $default_tracks = @trim($degree->track_selection_config_array[$machine_name]["default_tracks"]);
  2097. $html .= "<tr class='admin-degrees-edit-track-selection-config track-selection-config-$machine_name'>
  2098. <td valign='top'>
  2099. <span class='track-selection-config-title'>$title</span>:
  2100. </td>
  2101. <td valign='top'>
  2102. <input type='text' name='tsc_{$machine_name}_min_tracks' size='2' value='$min_tracks'>
  2103. </td>
  2104. <td valign='top'>
  2105. <input type='text' name='tsc_{$machine_name}_max_tracks' size='2' value='$max_tracks'>
  2106. </td>
  2107. <td valign='top'>
  2108. <input type='text' name='tsc_{$machine_name}_default_tracks' size='25' value='$default_tracks' maxlength='255'>
  2109. </td>
  2110. </tr>";
  2111. }
  2112. }
  2113. $html .= "</table>
  2114. </div>";
  2115. /*
  2116. Min:
  2117. <input type='text' name='min_tracks' size='2' value='$degree->min_tracks'>
  2118. <a href='javascript: adminPopupAlertHelp(\"min_tracks\");'>?</a>
  2119. &nbsp;&nbsp;
  2120. Max:
  2121. <input type='text' name='max_tracks' size='2' value='$degree->max_tracks'>
  2122. <a href='javascript: adminPopupAlertHelp(\"max_tracks\");'>?</a>
  2123. &nbsp;&nbsp;
  2124. Default tracks: (CSV)
  2125. <input type='text' name='default_tracks' size='15' value='$degree->default_tracks' maxlength='255'>
  2126. <a href='javascript: adminPopupAlertHelp(\"default_tracks\");'>?</a>
  2127. </div>
  2128. "; */
  2129. $rtn .= fp_render_c_fieldset($html, t("View advanced options"), TRUE);
  2130. $rtn .= "</form>";
  2131. // Only show delete option based on permission
  2132. if (user_has_permission("can_delete_data_entry")) {
  2133. $rtn .= " <div align='right' class='degrees-delete-degree-wrapper'>
  2134. Delete this degree? <input type='button' value='X'
  2135. onClick='adminDeleteDegree(\"$degree_id\");'>
  2136. </div>
  2137. ";
  2138. }
  2139. //$pC .= get_j_s();
  2140. if (@$_REQUEST["serialize"] != "")
  2141. {
  2142. print "<br><textarea rows=20 cols=80>" . serialize($degree) . "</textarea>";
  2143. }
  2144. return $rtn;
  2145. }

Functions

Namesort descending Description
admin_add_degree_form This form lets the user add a degree to the database.
admin_add_degree_form_submit Submit handler for the add_degree_form.
admin_add_degree_form_validate Validate handler for add_degree_form
admin_copy_degree_form This form lets the user copy a degree and all of it's tracks & concentrations.
admin_copy_degree_form_submit
admin_copy_degree_form_validate Validate handler. Make sure our allow_overwrite setting is working. Check for existing major code.
admin_display_degrees
admin_display_degrees_popup_add_group
admin_display_degrees_popup_add_group2
admin_display_edit_degree This screen displays the form which allows the user to actually edit a degree.
admin_edit_degree_form Meant to replace the old-fashioned display_edit_degree function...
admin_edit_degree_form_submit
z___admin_handle_edit_degree_submit