admin.courses.inc

Functions & methods

NameDescription
admin_display_coursesThis function displays all of our courses for us to edit.
admin_edit_course_formThis form lets the user edit details about a course.
admin_edit_course_form_submit

File

modules/admin/admin.courses.inc
View source
  1. <?php
  2. /* Functions related to working with Course data in FP */
  3. /**
  4. * This function displays all of our courses for us to edit.
  5. */
  6. function admin_display_courses() {
  7. $rtn = "";
  8. $de_catalog_year = admin_get_de_catalog_year();
  9. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  10. $cc = 1;
  11. $show_hidden = trim($_GET["show_hidden"]);
  12. if ($show_hidden != "") {
  13. $_SESSION["dehidden"] = $show_hidden;
  14. }
  15. else {
  16. $show_hidden = $_SESSION["dehidden"];
  17. }
  18. // Get the "upper range" (UR) and
  19. // lower range (LR) of the courses in question...
  20. $ur = trim($_GET["ur"]);
  21. $lr = trim($_GET["lr"]);
  22. if ($ur == "") {
  23. // meaning, no range was set. Use A - AZZZZZ, so, all of the A's.
  24. $ur = $_SESSION["dec_ur"];
  25. $lr = $_SESSION["dec_lr"];
  26. if ($ur == "") {
  27. // if still blank, assign it..
  28. $ur = "A";
  29. $lr = "AZZZZ";
  30. }
  31. }
  32. $_SESSION["dec_ur"] = $ur;
  33. $_SESSION["dec_lr"] = $lr;
  34. fp_set_title(t("Courses for @year", array("@year" => $de_catalog_year)));
  35. $rtn .= "<h2 class='title'>" . t("Courses for @year", array("@year" => $de_catalog_year)) . "</h2>";
  36. $letter_ranges = array(
  37. "A" => array("A", "AZZZZ"),
  38. "B" => array("B", "BZZZZ"),
  39. "C-CN" => array("C", "CNZZZ"),
  40. "CO-CZ" => array("CO", "CZZZZ"),
  41. "D" => array("D", "DZZZZ"),
  42. "E" => array("E", "EZZZZ"),
  43. "F" => array("F", "FZZZZ"),
  44. "G" => array("G", "GZZZZ"),
  45. "H" => array("H", "HZZZZ"),
  46. "I-L" => array("I", "LZZZZ"),
  47. "M-MR" => array("M", "MRZZZ"),
  48. "MS-MZ" => array("MS", "MZZZZ"),
  49. "N-O" => array("N", "OZZZZ"),
  50. "P" => array("P", "PZZZZ"),
  51. "Q-R" => array("Q", "RZZZZ"),
  52. "S-SO" => array("S", "SOZZZ"),
  53. "SP-SZ" => array("SP", "SZZZZ"),
  54. "T-Z" => array("T", "ZZZZZ"),
  55. );
  56. $rtn .= "<div class='admin-courses-select-letter-bar'>
  57. ";
  58. foreach($letter_ranges as $disp => $vals) {
  59. $rtn .= l($disp, "admin/courses", "de_catalog_year=$de_catalog_year&ur=" . $vals[0] . "&lr=" . $vals[1], array("class" => "admin-courses-letter-link")) . " &nbsp; ";
  60. }
  61. $rtn .= "</div>
  62. <div class='tenpt'>
  63. <div style='padding: 5px;'>
  64. " . l(t("Add a course for @year", array("@year" => $de_catalog_year)), "admin/courses/edit-course", "course_id=new&de_catalog_year=$de_catalog_year") . "
  65. </div>
  66. Legend: <br>&nbsp; &nbsp;[e] = Course has at least one add'l excluded name.
  67. &nbsp; &nbsp;[v] = Course has at least one add'l valid name.
  68. </div>
  69. ";
  70. $exclude_line = "and exclude != 1";
  71. if ($show_hidden == "yes") {
  72. $rtn .= "<div class='tenpt'><b>" . t("Showing excluded courses.") . " ";
  73. $rtn .= l(t("Hide?"), "admin/courses", "de_catalog_year=$de_catalog_year&show_hidden=no");
  74. $rtn .= "</b></div>";
  75. $exclude_line = "";
  76. }
  77. else {
  78. $rtn .= "<div class='tenpt'><b>" . t("Hiding excluded courses.") . " ";
  79. $rtn .= l(t("Show?"), "admin/courses", "de_catalog_year=$de_catalog_year&show_hidden=yes");
  80. $rtn .= "</b></div>";
  81. }
  82. $rtn .= "<hr><br>
  83. <table border='0' cellpadding='3' cellspacing='0'>";
  84. $q = "SELECT * FROM draft_courses
  85. WHERE
  86. catalog_year = '?'
  87. AND subject_id BETWEEN '?' AND '?'
  88. AND delete_flag = '0'
  89. $exclude_line
  90. ORDER BY subject_id, course_num";
  91. $result = db_query($q, $de_catalog_year, $ur, $lr);
  92. while ($cur = db_fetch_array($result)) {
  93. extract($cur, 3, "db");
  94. $ex_names = "";
  95. $val_names = "";
  96. // Check to see if this course has more than one name...
  97. // removed AND `catalog_year`='$de_catalog_year' from query,
  98. // because we don't care what other cat year it came from.
  99. $res2 = db_query("SELECT * FROM draft_courses
  100. WHERE course_id = '?'
  101. ", $db_course_id);
  102. while ($cur2 = db_fetch_array($res2)) {
  103. if ($cur2["subject_id"] == $db_subject_id && $cur2["course_num"] == $db_course_num) {
  104. continue;
  105. }
  106. if ($cur2["exclude"] == "1") {
  107. $ex_names = "[e]";
  108. }
  109. else {
  110. $val_names = "[v]";
  111. }
  112. }
  113. $spanstyle = "";
  114. if ($db_exclude == "1") {
  115. $spanstyle = "background-color: #ddd;";
  116. }
  117. $temp_course = new Course();
  118. $db_title = $temp_course->fix_title($db_title);
  119. $hrs = $db_min_hours;
  120. if (trim($db_min_hours) != trim($db_max_hours)) {
  121. $hrs .= " - $db_max_hours";
  122. }
  123. $hrs .= " hrs.";
  124. $rep_hours = "";
  125. if ($db_repeat_hours > $db_min_hours) {
  126. $rep_hours = " rep to $db_repeat_hours hrs.";
  127. }
  128. // remove special chars from subject_id...
  129. $display_subject_id = $db_subject_id;
  130. $db_subject_id = str_replace("&","_A_",$db_subject_id);
  131. $rtn .= "<tr style='$spanstyle'>
  132. <td valign='top' width='90%'><a name='course_$db_course_id'></a>";
  133. $rtn .= "<div style='$spanstyle padding:3px;'>";
  134. //<a href='admin.php?performAction=editSpecificCourse&course_id=$db_course_id&subject_id=$db_subject_id&course_num=$db_course_num&de_catalog_year=$de_catalog_year'>$display_subject_id $db_course_num - $db_title</a> - $hrs$rep_hours</div>";
  135. $rtn .= l("$display_subject_id $db_course_num - $db_title", "admin/courses/edit-course", "course_id=$db_course_id&subject_id=$db_subject_id&course_num=$db_course_num&de_catalog_year=$de_catalog_year") . " - $hrs$rep_hours</div>";
  136. $rtn .= "</td>
  137. <td valign='top' width='5%'>
  138. $ex_names
  139. </td>
  140. <td valign='top' width='5%'>
  141. $val_names
  142. </td>
  143. </tr>";
  144. } // while
  145. $rtn .= "</table>";
  146. return $rtn;
  147. }
  148. /**
  149. * This form lets the user edit details about a course.
  150. */
  151. function admin_edit_course_form() {
  152. $form = array();
  153. $de_catalog_year = admin_get_de_catalog_year();
  154. $course_id = $_REQUEST["course_id"];
  155. $subject_id = $_REQUEST["subject_id"];
  156. $subject_id = str_replace("_A_","&",$subject_id);
  157. $course_num = $_REQUEST["course_num"];
  158. fp_set_title(t("Edit Course @course", array("@course" => "$subject_id $course_num ($de_catalog_year)")));
  159. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  160. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  161. $form["de_catalog_year"] = array(
  162. "type" => "hidden",
  163. "value" => $de_catalog_year,
  164. );
  165. $form["course_id"] = array(
  166. "type" => "hidden",
  167. "value" => $course_id,
  168. );
  169. $form["subject_id"] = array(
  170. "type" => "hidden",
  171. "value" => $subject_id,
  172. );
  173. $form["course_num"] = array(
  174. "type" => "hidden",
  175. "value" => $course_num,
  176. );
  177. $form["perform_action2"] = array(
  178. "type" => "hidden",
  179. "value" => "",
  180. );
  181. // Begin the form...
  182. // TODO: implement this!
  183. if ($_SESSION["de_advanced_mode"] == true)
  184. {
  185. $pC .= " <span class='tenpt' style='background-color: yellow; margin-left: 20px;'>
  186. adv: course_id = $course_id. Used by:
  187. <a href='javascript: popupWindow(\"admin.php?performAction=popup_degrees_using_course&course_id=$course_id\")'>[degrees]</a>
  188. <a href='javascript: popupWindow(\"admin.php?performAction=popup_groups_using_course&course_id=$course_id\")'>[groups]</a>
  189. <a href='javascript: popupWindow(\"admin.php?performAction=popup_students_using_course&course_id=$course_id\")'>[students]</a>
  190. </span>";
  191. }
  192. $course = new Course($course_id,false,null,false,$de_catalog_year, true);
  193. $course->catalog_year = $de_catalog_year; // Since it may be 1900, force it!
  194. $course->load_descriptive_data(false, true, false, true, true);
  195. $course->catalog_year = $de_catalog_year; // Since it may be 1900, force it!
  196. $all_names = $course->get_all_names(true);
  197. $warn_eqv = "";
  198. if (strstr($all_names, ",")) {
  199. $warn_eqv = "yes";
  200. }
  201. // Correct ghosthours, if they exist.
  202. if ($course->bool_ghost_hour) {
  203. $course->max_hours = 0;
  204. }
  205. if ($course->bool_ghost_min_hour) {
  206. $course->min_hours = 0;
  207. }
  208. $form["course_names"] = array(
  209. "type" => "textfield",
  210. "label" => t("Course names(s):"),
  211. "required" => TRUE,
  212. "value" => $all_names,
  213. "popup_description" => t("These are the possible display names for this course. Typically,
  214. there will be only one name. Ex: ACCT 110. You must place a space
  215. between the subject ID and course number.
  216. If this course is known by another name (has an eqv course)
  217. then enter it as well using a comma.
  218. Ex: ACCT 110, MATH 110A
  219. Add the word 'exclude' to prevent it from showing in course
  220. selection windows in FlightPath.
  221. Ex: ACCT 110, MATH 110A exclude
  222. IMPORTANT: Course names are updated for ALL YEARS of a course."),
  223. );
  224. $form["title"] = array(
  225. "type" => "textfield",
  226. "label" => t("Title:"),
  227. "value" => $course->title,
  228. "popup_description" => t("The title of the course displayed in FlightPath."),
  229. );
  230. $form["min_hours"] = array(
  231. "type" => "textfield",
  232. "label" => t("Min hours:"),
  233. "size" => 10,
  234. "value" => $course->min_hours,
  235. "popup_description" => t("The min and max hours for a course will usually be the same
  236. number. Ex: 3. If they differ, it means the course has
  237. variable hours.
  238. For example, if you have a course
  239. worth 1-6 hours, enter 1 for min, and 6 for max."),
  240. );
  241. $form["max_hours"] = array(
  242. "type" => "textfield",
  243. "label" => t("Max hours:"),
  244. "size" => 10,
  245. "value" => $course->max_hours,
  246. "popup_description" => t("The min and max hours for a course will usually be the same
  247. number. Ex: 3. If they differ, it means the course has
  248. variable hours.
  249. For example, if you have a course
  250. worth 1-6 hours, enter 1 for min, and 6 for max."),
  251. );
  252. $form["repeat_hours"] = array(
  253. "type" => "textfield",
  254. "label" => t("Repeat hours:"),
  255. "size" => 10,
  256. "value" => $course->repeat_hours,
  257. "popup_description" => t("This is the number of hours a course may be repeated for credit.
  258. For example, if a course is worth 3 hours, but may be repeated
  259. for up to 9 hours of credit, enter a 9 in this box.
  260. If a course CANNOT be repeated for credit, this would
  261. be the same number as the min and max, or simply blank.
  262. If you are unsure what to enter, leave it blank."),
  263. );
  264. $form["description"] = array(
  265. "type" => "textarea",
  266. "label" => t("Description"),
  267. "value" => $course->description,
  268. "rows" => 4,
  269. "cols" => 80,
  270. );
  271. $form["all_years"] = array(
  272. "type" => "checkboxes",
  273. "label" => t("Update for all years?"),
  274. "options" => array("yes" => t("Update title, description, and hour info for all years of this course.")),
  275. "popup_description" => t("Check this box and press Submit to update title, description, and hour information
  276. for all available years of this course. Note that course name is automatically
  277. updated for all years, regardless if you check this box or not."),
  278. );
  279. $form["data_entry_comment"] = array(
  280. "type" => "textarea",
  281. "label" => t("Optional Comment: (only seen by other FlightPath administrators)"),
  282. "rows" => 3,
  283. "cols" => 80,
  284. "value" => $course->data_entry_comment,
  285. );
  286. $form["submit"] = array(
  287. "type" => "submit",
  288. "value" => t("Save for @year", array("@year" => $de_catalog_year)),
  289. "prefix" => "<hr>",
  290. );
  291. $form["mark" . $m++] = array(
  292. "type" => "markup",
  293. "value" => "<div align='right'>
  294. " . t("Delete this course?") . " <input type='button' value='X'
  295. onClick='adminDeleteCourse(\"$course_id\",\"$de_catalog_year\",\"$warn_eqv\");'>
  296. </div>",
  297. );
  298. return $form;
  299. }
  300. function admin_edit_course_form_submit(&$form, $form_submit) {
  301. $values = $form_submit["values"];
  302. $de_catalog_year = $values["de_catalog_year"];
  303. $course_id = trim($values["course_id"]);
  304. $course_names = trim($values["course_names"]);
  305. $db = get_global_database_handler();
  306. if ($course_names == "") {
  307. $course_names = $values["subject_id"] . " " . $values["course_num"];
  308. }
  309. $title = trim($values["title"]);
  310. $min_hours = trim($values["min_hours"]);
  311. $max_hours = trim($values["max_hours"]);
  312. $repeat_hours = trim($values["repeat_hours"]);
  313. //$exclude = trim($_POST["exclude"]);
  314. $description = trim($values["description"]);
  315. $data_entry_comment = trim($values["data_entry_comment"]);
  316. // Since we are making a change to the draft table(s), let's add a row
  317. // to draft instructions.
  318. $db->add_draft_instruction("-");
  319. // Unlike the degrees and the groups, course_ids are not
  320. // unique. Only a course_id + catalog_year pair are unique. This
  321. // is so we can handle equivalent courses more gracefully.
  322. // So, the first thing we need to do is delete *all* courses with the
  323. // course_id and catalog_year listed above. For most courses, this will
  324. // only be one row. For eqv courses, this will delete more than one row.
  325. if ($course_id != "new") {
  326. // Don't delete! Temporarily transfer to a temporary course_id.
  327. // Will possibly delete later.
  328. $res = db_query("UPDATE draft_courses
  329. SET course_id = '-12345'
  330. WHERE course_id = '?'
  331. AND catalog_year = '?' ", $course_id, $de_catalog_year);
  332. }
  333. if ($values["perform_action2"] == "delete_course") {
  334. // That's it. All we wanted to do was delete the course.
  335. $query = "DELETE FROM draft_courses
  336. WHERE course_id = '-12345'
  337. ";
  338. $res = db_query($query);
  339. fp_add_message(t("Course %course successfully deleted for %year", array("%course" => $course_names, "%year" => $de_catalog_year)));
  340. // Redirect us to the list of courses.
  341. $form["#redirect"] = array(
  342. "path" => "admin/courses",
  343. "query" => "de_catalog_year=$de_catalog_year",
  344. );
  345. return;
  346. }
  347. // If the $course_id == new then create a new one.
  348. if ($course_id == "new") {
  349. $course_id = $db->request_new_course_id();
  350. $values["course_id"] = $course_id;
  351. // change the $form redirect so we get sent to the new course on save.
  352. $form["#redirect"] = array(
  353. "path" => "admin/courses/edit-course",
  354. "query" => "de_catalog_year=$de_catalog_year&course_id=$course_id",
  355. );
  356. }
  357. // Now, we will split the courseNames on commas, and for each
  358. // token, we will insert a row into the database.
  359. $courses = explode(",", $course_names);
  360. foreach($courses as $course) {
  361. $course = str_replace(" ", " ", $course);
  362. $course = str_replace(" ", " ", $course);
  363. $course = str_replace(" ", " ", $course);
  364. $course = trim($course);
  365. if ($course == "") { continue; }
  366. $temp = explode(" ", $course);
  367. $subject_id = trim($temp[0]);
  368. $course_num = trim($temp[1]);
  369. ////////////
  370. /// Error conditions...
  371. if (strtolower($course_num) == "exclude" || $course_num == "") {
  372. form_error("course_names", t("It appears you specified an excluded course
  373. without a course number. You entered %course.
  374. Notice there is no course number. Please re-enter.", array("%course" => "$subject_id $course_num")));
  375. continue;
  376. }
  377. ////////////////
  378. $exclude = 0;
  379. // Do we exclude?
  380. if (strtolower(trim($temp[2])) == "exclude") {
  381. $exclude = 1;
  382. // Set ALL courses with this subject_id and course_num to exclude!
  383. $res = db_query("UPDATE draft_courses
  384. SET exclude = '1'
  385. WHERE subject_id = '?'
  386. AND course_num = '?'
  387. ", $subject_id, $course_num);
  388. }
  389. else {
  390. // Aet all courses with this subject_id and course_num to NOT exclude!
  391. $res = db_query("UPDATE draft_courses
  392. SET exclude = '0'
  393. WHERE subject_id = '?'
  394. AND course_num = '?'
  395. ", $subject_id, $course_num);
  396. }
  397. // Did the user specify a course which already exists? If so,
  398. // mark that course's ID as -12345...
  399. $res = db_query("UPDATE draft_courses
  400. SET course_id = '-12345'
  401. WHERE subject_id = '?'
  402. AND course_num = '?'
  403. AND catalog_year = '?' ", $subject_id, $course_num, $de_catalog_year);
  404. // We now have enough information to make an insertion into
  405. // the table.
  406. $query = "INSERT INTO draft_courses
  407. (`course_id`,`subject_id`,`course_num`,`catalog_year`,
  408. `title`,`description`,`min_hours`,`max_hours`,`repeat_hours`,
  409. `exclude`,`data_entry_comment`)
  410. values ('?','?','?','?','?','?','?','?','?','?','?') ";
  411. //debug_c_t($query);
  412. $res = db_query($query, $course_id,$subject_id,$course_num,$de_catalog_year,
  413. $title,$description,$min_hours,$max_hours,$repeat_hours,
  414. $exclude,$data_entry_comment);
  415. // Now, this part is tricky. Are there any courses which already
  416. // existed with this subject_id and course_num, but not this course_id?
  417. // This would happen if we add an eqv for a course that already existed
  418. // elsewhere. We want to change that existing course's ID to match the
  419. // new one, but we also need to update EVERY table that used the old
  420. // course_id with the new course_id, including degree plans, groups,
  421. // substitutions, etc.
  422. // query for subject_id and course_num but != course_id.
  423. // get oldCourseID.
  424. // call function update_course_id(oldCourseID, newCourseID)
  425. $res2 = db_query("SELECT * FROM draft_courses WHERE
  426. subject_id = '?'
  427. AND course_num = '?'
  428. AND course_id != '?'
  429. AND course_id != '-12345' ", $subject_id, $course_num, $course_id);
  430. while ($cur2 = db_fetch_array($res2)) {
  431. $old_course_id = $cur2["course_id"];
  432. // Now, update all the existing references to $old_course_id
  433. // with the new course_id.
  434. $db2 = new DatabaseHandler();
  435. $db2->update_course_id($old_course_id, $course_id, true);
  436. // Now, add it to our list of things to update when we apply
  437. // the draft changes...
  438. $db2->add_draft_instruction("update_course_id,$old_course_id,$course_id");
  439. }
  440. }
  441. // We have to accomodate the situation that there used to be an
  442. // eqv set up (multiple course names were set) but now there is not.
  443. // In other words, someone wanted to undo an eqv.
  444. // We used to have: ACCT 101, MATH 101
  445. // But they took out the comma. So, only ACCT 101 just got written
  446. // to the database, while MATH 101 has been marked as -12345 and is
  447. // destined to be deleted.
  448. // -- we need to give MATH 101 a new course_id and update that course_id
  449. // for all years.
  450. // Then, we need to go through all our tables and update where it was
  451. // actually spelled out that "MATH 101" be used with the new course_id.
  452. // -- This process will ensure that no previous existing courses
  453. // will get deleted. That they will remain as their own unique
  454. // courses.
  455. // First thing's first. Go through all the courses with the course_id
  456. // of -12345. If we find one that does not have the same subject_id
  457. // and course_num with the new ID, then this is a removed eqv, and
  458. // that is our cue that it should be it's own course.
  459. $res = db_query("SELECT * FROM draft_courses
  460. WHERE course_id = '-12345' ");
  461. while ($cur = db_fetch_array($res)) {
  462. $found_s_i = $cur["subject_id"];
  463. $found_c_n = $cur["course_num"];
  464. $db2 = new DatabaseHandler();
  465. $res2 = $db2->db_query("SELECT * FROM draft_courses
  466. WHERE course_id = '?'
  467. AND subject_id = '?'
  468. AND course_num = '?'
  469. AND catalog_year = '?' ", $course_id, $found_s_i, $found_c_n, $de_catalog_year);
  470. if ($db2->db_num_rows($res2) == 0) {
  471. // Meaning, this course name is not listed with the course_id,
  472. // so this is a broken eqv.
  473. // We should make a new course_id and all that for this course,
  474. // for all available years.
  475. $new_course_id = $db2->request_new_course_id();
  476. $db3 = new DatabaseHandler();
  477. $res3 = $db3->db_query("UPDATE draft_courses
  478. SET course_id = '?'
  479. WHERE subject_id = '?'
  480. AND course_num = '?' ", $new_course_id, $found_s_i, $found_c_n);
  481. // removed WHERE `course_id`='-12345' from query. We want to UPDATE
  482. // this across all years for this course.
  483. // And also UPDATE every other table that specified foundSI &CN
  484. // as a requirement.
  485. $db3->update_course_requirement_from_name($found_s_i, $found_c_n, $new_course_id);
  486. $db3->add_draft_instruction("update_course_requirement_from_name,$found_s_i,$found_c_n,$new_course_id");
  487. }
  488. }
  489. // Was the "all_years" box checked? If it was, then update all instances
  490. // of this course, across all available catalog years.
  491. if (is_array($values["all_years"]) && $values["all_years"]["yes"] == "yes") {
  492. $res = db_query("UPDATE draft_courses
  493. SET title = '?',
  494. description = '?',
  495. min_hours = '?',
  496. max_hours = '?',
  497. repeat_hours = '?'
  498. WHERE course_id = '?' ", $title, $description, $min_hours, $max_hours, $repeat_hours, $course_id);
  499. }
  500. // Clean up. Delete the temporary course_id...
  501. $res = db_query("DELETE FROM draft_courses WHERE course_id = '-12345' ");
  502. fp_add_message("Course updated successfully.");
  503. }