admin.groups.inc

Functions & methods

NameDescription
admin_array_diffI had to create my own version of array_diff, because the built-in PHP version has a nasty bug where it doesn't work after a certain number of elements.
admin_display_groupsThis function will display a list of all our groups.
admin_display_groups_popup_edit_definition
admin_display_groups_popup_select_iconThis popup is called from the edit group page. It lets the user select an icon to assign to a group.
admin_display_groups_popup_show_group_useDisplays a popup showing where a particular group is being used in FlightPath.
admin_edit_group_formThis function lets the user edit a group.
admin_edit_group_form_submit
admin_get_courses_from_definition
admin_get_course_array_from_course_id_array
admin_get_course_array_from_definition_data
admin_get_course_id_array_from_course_array
admin_get_group_coursesReturn back the courses in a group, suitable for the edit-group form.
admin_process_all_definitions_form
admin_process_all_definitions_form_submitActually perform the refreshing of definitions.

File

modules/admin/admin.groups.inc
View source
  1. <?php
  2. /* This include file deals with Groups editing for FlightPath */
  3. function admin_edit_group_form_submit(&$form, $form_submit) {
  4. $values = $form_submit["values"];
  5. $de_catalog_year = $values["de_catalog_year"];
  6. $db = get_global_database_handler();
  7. $db2 = new DatabaseHandler();
  8. $group_id = $values["group_id"];
  9. // Okay, we are trying to save the details of this group.
  10. // First thing we need to do is UPDATE the title, group_name,
  11. // priority, icon and comment.
  12. $group_name = trim($values["group_name"]);
  13. $title = trim($values["title"]);
  14. $priority = trim($values["priority"]);
  15. $icon_filename = trim($values["icon_filename"]);
  16. $data_entry_comment = trim($values["data_entry_comment"]);
  17. // Save the entire post to the log.
  18. // Since we are making a change to the draft table(s), let's add a row
  19. // to draft instructions.
  20. $db->add_draft_instruction("-");
  21. // Are we trying to delete this group?
  22. if ($_POST["perform_action2"] == "delete_group") {
  23. $res = db_query("UPDATE draft_groups
  24. SET delete_flag = '1'
  25. WHERE group_id = '?'
  26. AND catalog_year = '?'
  27. ", $group_id, $de_catalog_year);
  28. fp_add_message(t("The group @title (%name) has been deleted successfully for @year", array("@title" => $title, "%name" => $group_name, "@year" => $de_catalog_year)));
  29. fp_goto("admin/groups", "de_catalog_year=$de_catalog_year");
  30. return;
  31. }
  32. // If the $group_id == new then create a new one.
  33. if ($group_id == "new") {
  34. $group_id = $db->request_new_group_id();
  35. $res = db_query("INSERT INTO draft_groups(group_id, catalog_year)
  36. values ('?','?') ", $group_id, $de_catalog_year);
  37. $values["group_id"] = $group_id;
  38. // Let's reset where we should redirect to after the form submits.
  39. $form["#redirect"] = array(
  40. "path" => "admin/groups/edit-group",
  41. "query" => "group_id=$group_id&de_catalog_year=$de_catalog_year",
  42. );
  43. }
  44. $res = db_query("UPDATE draft_groups
  45. SET group_name = '?',
  46. title = '?',
  47. priority = '?',
  48. icon_filename = '?',
  49. data_entry_comment = '?'
  50. WHERE
  51. group_id = '?' ",
  52. $group_name, $title, $priority, $icon_filename, $data_entry_comment, $group_id);
  53. // We need to delete all the existing course & subgroup requirements from this group.
  54. // That entails first seeing what subgroups were required and deleting them,
  55. // then deleting the parent group's requirements.
  56. // First, find and delete the branches (child groups):
  57. $res = db_query("SELECT * FROM draft_group_requirements
  58. WHERE group_id = '?'
  59. AND child_group_id != '0' ", $group_id);
  60. while ($cur = db_fetch_array($res)) {
  61. $cg_id = $cur["child_group_id"];
  62. $res2 = db_query("DELETE FROM draft_group_requirements
  63. WHERE group_id = '?' ", $cg_id);
  64. }
  65. // Now delete the course requirements...
  66. $res = db_query("DELETE FROM draft_group_requirements
  67. WHERE group_id = '?' ", $group_id);
  68. $courses = trim($values["courses"]);
  69. // If a definition was set, then we will ignore what is in the POST
  70. // for the course requrements, and instead use the definition.
  71. if (trim($values["set_definition"] != "")) {
  72. $def = urldecode(trim($values["set_definition"]));
  73. //$cc = trim(get_courses_from_definition($def, $de_catalog_year));
  74. $temp2 = admin_get_courses_from_definition($def);
  75. $cc = trim($temp2["text"]);
  76. if ($cc != "") {
  77. $courses = $cc;
  78. // UPDATE this group's definition!
  79. $res = db_query("UPDATE draft_groups
  80. SET definition = '?'
  81. WHERE
  82. group_id = '?' ", $def, $group_id);
  83. }
  84. //print_pre($cc);
  85. }
  86. else {
  87. // In other words, the setDefinition WAS blank.
  88. // Let's update the table. This is to fix a bug where they were unable
  89. // to clear definitions.
  90. $res = db_query("UPDATE draft_groups
  91. SET definition = ''
  92. WHERE
  93. group_id = '?' ", $group_id);
  94. }
  95. // Okay, now we look at the actual "courses" box and assemble the group
  96. // in the database.
  97. $lines = explode("\n", $courses);
  98. for ($t = 0; $t < count($lines); $t++) {
  99. $line = trim($lines[$t]);
  100. if ($line == "") { continue; }
  101. // Get rid of extra whitespace.
  102. $line = str_replace(" ", " ", $line);
  103. $line = str_replace(" ", " ", $line);
  104. $line = str_replace(" ", " ", $line);
  105. // Does this line contain at least one & symbol? If it does,
  106. // then this is a subgroup (branch). If not, then we can insert
  107. // the course as-is.
  108. if (strstr($line, "&")) {
  109. // This line DOES have an ampersand (&), so this is a sub group
  110. // within this group.
  111. // First, we need to request a new branchID for this new group.
  112. if (!$branch_id = $db->request_new_group_id()) {
  113. die ("Error. Could not create new group (branch) ID.");
  114. }
  115. else {
  116. // Add this branch to the list of requirements for this group.
  117. $query = "INSERT INTO draft_group_requirements
  118. (group_id, child_group_id)
  119. values ('?','?') ";
  120. $res = db_query($query, $group_id, $branch_id);
  121. }
  122. $c_tokes = explode("&",$line);
  123. for ($cT = 0; $cT < count($c_tokes); $cT++)
  124. {
  125. $tokens = explode(" ", trim($c_tokes[$cT]));
  126. $subject_id = trim($tokens[0]);
  127. $course_num = trim($tokens[1]);
  128. $min_grade = trim($tokens[2]);
  129. $course_repeats = trim($tokens[3]);
  130. if (strstr($min_grade, "[")) {
  131. // This is actually a specified repeat, not a min grade.
  132. $course_repeats = $min_grade;
  133. $min_grade = "";
  134. }
  135. $min_grade = str_replace("(","",$min_grade);
  136. $min_grade = str_replace(")","",$min_grade);
  137. $course_repeats = str_replace("[","",$course_repeats);
  138. $course_repeats = str_replace("]","",$course_repeats);
  139. $course_repeats--;
  140. if ($course_repeats < 0) { $course_repeats = 0; }
  141. // If the subject_id had a _A_ in it, convert this back
  142. // to an ampersand.
  143. $subject_id = str_replace("_A_", "&", $subject_id);
  144. // Commenting out, because we do not care about catalog_year
  145. // when specifying courses...
  146. if ($course_id = $db->get_course_id($subject_id, $course_num, "", true)) {
  147. $query = "INSERT INTO draft_group_requirements
  148. (group_id, course_id,
  149. course_min_grade, course_repeats, data_entry_value)
  150. values ('?','?','?','?','?~?') ";
  151. $res = db_query($query, $branch_id, $course_id, $min_grade, $course_repeats, $subject_id, $course_num);
  152. }
  153. else {
  154. // The course_id could not be found!
  155. form_error("courses", t("Course Not Found!
  156. You specified the course
  157. <b>%course</b> as a requirement, but this course
  158. could not be found in the catalog.
  159. It was removed from the list of requirements.
  160. Are you sure you typed it correctly? Please check
  161. your spelling, and add the course again.", array("%course" => "$subject_id $course_num")));
  162. }
  163. }
  164. }
  165. else {
  166. // Did NOT contain an ampersand (&), so this goes in the
  167. // regular course requirements.
  168. $tokens = explode(" ", $line);
  169. $subject_id = trim($tokens[0]);
  170. $course_num = trim($tokens[1]);
  171. $min_grade = trim($tokens[2]);
  172. $course_repeats = trim($tokens[3]);
  173. if (strstr($min_grade, "[")) {
  174. // This is actually a specified repeat, not a min grade.
  175. $course_repeats = $min_grade;
  176. $min_grade = "";
  177. }
  178. $min_grade = str_replace("(","",$min_grade);
  179. $min_grade = strtoupper(str_replace(")","",$min_grade));
  180. $course_repeats = str_replace("[","",$course_repeats);
  181. $course_repeats = str_replace("]","",$course_repeats);
  182. $course_repeats--;
  183. if ($course_repeats < 0) { $course_repeats = 0; }
  184. // If the subject_id had a _A_ in it, convert this back
  185. // to an ampersand.
  186. $subject_id = str_replace("_A_", "&", $subject_id);
  187. // We don't care about catalog year anymore...
  188. if ($course_id = $db->get_course_id($subject_id, $course_num, "", true)) {
  189. $query = "INSERT INTO draft_group_requirements
  190. (group_id, course_id,
  191. course_min_grade, course_repeats, data_entry_value)
  192. values ('?','?','?','?','?~?') ";
  193. $res = db_query($query, $group_id, $course_id, $min_grade, $course_repeats, $subject_id, $course_num);
  194. }
  195. else {
  196. // The course_id could not be found!
  197. form_error("courses", t("Course Not Found!
  198. You specified the course
  199. <b>%course</b> as a requirement, but this course
  200. could not be found in the catalog.
  201. It was removed from the list of requirements.
  202. Are you sure you typed it correctly? Please check
  203. your spelling, and add the course again.", array("%course" => "$subject_id $course_num")));
  204. }
  205. }
  206. }
  207. fp_add_message("Group successfully updated.");
  208. // Clear previous values to make sure the Required Courses box gets updated,
  209. // even if its set to readonly.
  210. clear_session_form_values("admin_edit_group_form");
  211. }
  212. /**
  213. * This function lets the user edit a group.
  214. */
  215. function admin_edit_group_form() {
  216. $form = array();
  217. $de_catalog_year = admin_get_de_catalog_year();
  218. $group_id = $_REQUEST["group_id"];
  219. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  220. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  221. $form["#redirect"] = array(
  222. "path" => "admin/groups/edit-group",
  223. "query" => "group_id=$group_id&de_catalog_year=$de_catalog_year",
  224. );
  225. if (user_has_permission("can_view_advanced")) {
  226. $form["mark" . $m++] = array(
  227. "type" => "markup",
  228. "value" => " <span class='tenpt' style='background-color: yellow; margin-left: 20px;'>
  229. adv: group_id = $group_id.
  230. Used by:
  231. <a href='javascript: adminPopupWindow(\"" . fp_url("admin/groups/popup-show-group-use", "group_id=$group_id") . "\");'>[degrees]</a>
  232. </span>",
  233. );
  234. }
  235. $group = new Group($group_id, null, -1, false, true);
  236. //print_pre($group->to_string());
  237. $group->load_descriptive_data();
  238. fp_set_title(t("Edit Group:") . " $group->title ($de_catalog_year)");
  239. $form["perform_action2"] = array(
  240. "type" => "hidden",
  241. "value" => "",
  242. );
  243. $form["set_definition"] = array(
  244. "type" => "hidden",
  245. "value" => urlencode($group->definition),
  246. );
  247. $form["scroll_top"] = array(
  248. "type" => "hidden",
  249. "value" => "",
  250. );
  251. $form["group_id"] = array(
  252. "type" => "hidden",
  253. "value" => $group_id,
  254. );
  255. $form["de_catalog_year"] = array(
  256. "type" => "hidden",
  257. "value" => $de_catalog_year,
  258. );
  259. // Actually draw the form out.
  260. $form["title"] = array(
  261. "type" => "textfield",
  262. "label" => t("Group title:"),
  263. "value" => $group->title,
  264. "maxlength" => 100,
  265. "popup_description" => t("This is what FlightPath uses to refer to this group in screens and popups.
  266. Ex: Free Electives, Art Electives, Core Humanities, etc."),
  267. );
  268. $form["group_name"] = array(
  269. "type" => "textfield",
  270. "label" => t("Internal group name:"),
  271. "value" => $group->group_name,
  272. "maxlength" => 100,
  273. "popup_description" => t("The \"group's name\" is internal to FlightPath, and is never seen by the average user.
  274. You may use this to distinguish between groups with the same title. Ex:
  275. major_electives_sr and major_electives_jr. The field may be considered
  276. optional, but it is highly recommended you enter something here for your
  277. own clarity later on. It is OK to have the same group title and name."),
  278. );
  279. $form["priority"] = array(
  280. "type" => "textfield",
  281. "label" => t("Priority:"),
  282. "value" => $group->priority,
  283. "maxlength" => 10,
  284. "size" => 10,
  285. "popup_description" => t("This should be a number, and it is very important, because it determines the
  286. order in which courses are assigned to groups in FlightPath.
  287. Higher numbers fill in FIRST! So a group with a priority of 100 would fill in before
  288. a group with a priority of 30."),
  289. );
  290. $form["icon_filename"] = array(
  291. "type" => "hidden",
  292. "label" => t("Icon:"),
  293. "value" => $group->icon_filename,
  294. "suffix" => "
  295. <img src='" . fp_theme_location() . "/images/icons/$group->icon_filename' width='19'>
  296. $group->icon_filename
  297. &nbsp; &nbsp;
  298. <a href='javascript: adminPopupWindow(\"" . base_path() . "/admin/groups/popup-select-icon&group_id=$group_id\");'>[select another]</a>
  299. ",
  300. );
  301. $form["definition"] = array(
  302. "type" => "markup",
  303. "label" => t("Definition:"),
  304. "value" => "<label>" . t("Definition:") . "</label><i>" . nl2br($group->definition) . "</i>",
  305. "prefix" => "<div style='overflow: auto; max-height: 150px;' class='admin-groups-show-definition'>",
  306. "suffix" => "</div><a href='javascript: adminPopupWindow(\"" . base_path() . "/admin/groups/popup-edit-definition&de_catalog_year=$de_catalog_year&group_id=$group_id\");'
  307. >[" . t("edit definition") . "]</a>",
  308. );
  309. $form["mark" . $m++] = array(
  310. "type" => "markup",
  311. "value" => "<hr>",
  312. );
  313. $courses = admin_get_group_courses($group);
  314. $form["courses"] = array(
  315. "type" => "textarea",
  316. "label" => t("Required Courses:"),
  317. "rows" => 17,
  318. "cols" => 80,
  319. "value" => $courses,
  320. );
  321. // if a definition was specified, we need to disable the courses textarea.
  322. if (trim($group->definition)) {
  323. $form["courses"]["attributes"] = "readonly=readonly style='background-color: #ccc;' ";
  324. $form["courses"]["prefix"] = "<div class='admin-groups-courses-disabled'>
  325. " . t("Note: Because a definition was specified, you cannot directly
  326. edit the Required Courses. Manage these courses using the
  327. Edit Definition popup window.") . "</div>";
  328. }
  329. $form["data_entry_comment"] = array(
  330. "type" => "textarea",
  331. "label" => t("Optional Comment: (only seen by other FlightPath administrators)"),
  332. "rows" => 3,
  333. "cols" => 80,
  334. "value" => $group->data_entry_comment,
  335. );
  336. $form["submit"] = array(
  337. "type" => "submit",
  338. "value" => "Submit",
  339. "prefix" => "<hr>",
  340. );
  341. $form["mark" . $m++] = array(
  342. "type" => "markup",
  343. "value" => "<div align='right'>
  344. " . t("Delete this group?") . " <input type='button' value='X'
  345. onClick='adminDeleteGroup(\"$group_id\");'>
  346. </div>",
  347. );
  348. return $form;
  349. }
  350. function admin_display_groups_popup_edit_definition() {
  351. $rtn = "";
  352. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  353. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  354. $group_id = trim($_REQUEST["group_id"]);
  355. $de_catalog_year = admin_get_de_catalog_year();
  356. $group = new Group($group_id, null, -1, false, true);
  357. $group->load_descriptive_data();
  358. if (isset($_REQUEST["definition"])) {
  359. $definition = trim($_REQUEST["definition"]);
  360. }
  361. else {
  362. $definition = $group->definition;
  363. }
  364. $results = admin_get_courses_from_definition($definition);
  365. // This text will be used to describe how the definition works in a javascript alert box:
  366. $tdef .= t("Definitions provide a very quick way to add or remove many courses from a group. For example, to add all CSCI courses, enter:") . "\n";
  367. $tdef .= " add CSCI.*\n";
  368. $tdef .= t("The . is used to seperate the subject from the course number. The * means \"any value.\" You may also use it in the subject. For example, ");
  369. $tdef .= t("to add all CSCI and any course with a subject that begins with A, enter:") . "\n";
  370. $tdef .= " add CSCI.*\n add A*.*\n";
  371. $tdef .= t("Removing courses is done the same way. For example, you can add all courses, then remove any course with a number lower than 400:") . "\n";
  372. $tdef .= " add *.*\n rem *.1*\n rem *.2*\n rem *.3*\n";
  373. $tdef .= "\n\n" . t("It should be stated that add statements will include courses which have been marked as \"exclude.\" This is normal. Those courses will not") . " ";
  374. $tdef .= t("show up in group selection screens, but they will be added to a group if a student has completed that course in the past.");
  375. $rtn .= "<b>Edit Definition for $group->title ($de_catalog_year)<br><i>$group->group_name</i></b>
  376. <br><br><form action='" . base_path() . "/admin/groups/popup-edit-definition&de_catalog_year=$de_catalog_year&group_id=$group_id' method='POST' id='mainform'>
  377. <table border='0'>
  378. <tr>
  379. <td valign='top' align='right'>
  380. <div class='tenpt' align='left'>Working Definition:
  381. " . fp_get_js_alert_link($tdef, "[?]") . "</div>
  382. <textarea name='definition' id='definition' rows='10' cols='15' >$definition</textarea>
  383. <br>
  384. <input type='button' value='Generate ->'
  385. onClick='showUpdate(); document.getElementById(\"mainform\").submit();'>
  386. </td>
  387. <td valign='top' align='right' class='tenpt'>
  388. <div class='tenpt' align='left'>Results:" . " (" . $results["count"] . ")</div>
  389. <textarea rows='10' cols='35' readonly=readonly
  390. style='background-color: lightgray;'>{$results["text"]}</textarea>
  391. <br>
  392. (loads courses from all catalog years)
  393. </td>
  394. </tr>
  395. </table>
  396. </form>
  397. " . t("If you are satisfied with the results of this definition,
  398. click the Save to Group button. Otherwise, simply close this window.") . "
  399. <input type='button' value='Save to Group' onClick='adminPopupSaveDefinition(\"\");'>
  400. ";
  401. return $rtn;
  402. }
  403. function admin_get_course_array_from_course_id_array($course_idArray) {
  404. // Convert an array of course_id's into their subject_id ~~ course_num format.
  405. // Pick non-excluded courses over excluded courses, when you have the option.
  406. $rtn_array = array();
  407. $db = new DatabaseHandler();
  408. // MUST use foreach since we used array_unique earlier. Can't use
  409. // count($arr) after you use array_unique!!
  410. foreach($course_idArray as $t => $value) {
  411. $new_course = new Course();
  412. $new_course->bool_use_draft = true;
  413. $new_course->db = $db;
  414. $new_course->course_id = $course_idArray[$t];
  415. $new_course->load_descriptive_data(false);
  416. array_push($rtn_array, "$new_course->subject_id ~~ $new_course->course_num");
  417. }
  418. return $rtn_array;
  419. }
  420. function admin_get_courses_from_definition($definition, $catalog_year = "") {
  421. $group_array = array();
  422. // Okay, first things first, let's trim this sucker and remove extra whitespace.
  423. $definition = trim($definition);
  424. $definition = str_replace(" "," ",$definition);
  425. $definition = str_replace(" "," ",$definition);
  426. $definition = str_replace(" "," ",$definition);
  427. // Okay, now let's break this up into lines...
  428. $d_lines = explode("\n",$definition);
  429. foreach($d_lines as $line)
  430. {
  431. $line = trim($line);
  432. // Let's get each of the parts... the instruction, and the course data.
  433. $tokens = explode(" ", $line);
  434. $instruction = strtolower(trim($tokens[0]));
  435. $course_data = trim($tokens[1]);
  436. // We know that the course data can also be broken up, by the .
  437. $c_tokens = explode(".", $course_data);
  438. $subject_data = trim(strtoupper($c_tokens[0]));
  439. $course_numData = trim(strtoupper($c_tokens[1]));
  440. // Okay, so now, for this line, we have an instruction,
  441. // and some course data (possibly wild cards) to act on.
  442. //debugCT("$instruction $subject_data $course_numData");
  443. $t_array = admin_get_course_array_from_definition_data($subject_data, $course_numData, $catalog_year);
  444. // Okay, we got our list. Now what do we do with them?
  445. if ($instruction == "add" || $instruction == "+")
  446. {
  447. $group_array = array_merge($group_array, $t_array);
  448. $group_array = array_unique($group_array);
  449. }
  450. if ($instruction == "remove" || $instruction == "rem" || $instruction == "-" || $instruction == "del")
  451. {
  452. //print "<pre>" . print_r($t_array) . "</pre>";
  453. //debug_c_t(count($group_array));
  454. //$group_array = array_diff($group_array, $t_array);
  455. $group_array = admin_array_diff($group_array, $t_array);
  456. $group_array = array_unique($group_array);
  457. //debug_c_t(count($group_array));
  458. }
  459. }
  460. // Here's what we need to do:
  461. // In groupArray, we have the subject_id and course_num of every course in this definition.
  462. // We need to convert them to course_id's from the table,
  463. // and make sure we do not have duplicates.
  464. // First, get an array of course_id from the groupArray...
  465. $course_idArray = $group_array;
  466. // Take out duplicate entries (caused by eqv courses)...
  467. $course_idArray = array_unique($course_idArray);
  468. //print_r($course_idArray);
  469. //debugCT(sizeof($course_idArray));
  470. // Now, convert BACK into the "groupArray" structure (subject_id and course_num)...
  471. $group_array2 = admin_get_course_array_from_course_id_array($course_idArray);
  472. //print_r($group_array);
  473. // Place in alphabetical order.
  474. sort($group_array2);
  475. //var_dump($group_array2);
  476. $rtn = array();
  477. $count = 1;
  478. // Now that we have the groupArray, we will turn it into a string...
  479. for ($t = 0; $t < count($group_array2); $t++)
  480. {
  481. $line = trim($group_array2[$t]);
  482. if ($line == "~~" || $line == "") continue;
  483. $count++;
  484. $temp = explode(" ~~ ", $line);
  485. $si = trim($temp[0]);
  486. $cn = trim($temp[1]);
  487. $rtn["text"] .= "$si $cn\n";
  488. }
  489. $rtn["text"] = str_replace("&", "_A_", $rtn["text"]);
  490. //debug_c_t(count($group_array));
  491. $rtn["count"] = $count;
  492. return $rtn;
  493. }
  494. function admin_get_course_id_array_from_course_array($course_array) {
  495. $rtn_array = array();
  496. $db = new DatabaseHandler();
  497. // MUST use foreach instead of for since we did
  498. // array_unique! Can't trust count($arr)!
  499. foreach($course_array as $t => $value) {
  500. $line = trim($course_array[$t]);
  501. if ($line == "~~" || $line == "") continue;
  502. $count++;
  503. $temp = explode(" ~~ ", $line);
  504. $si = trim($temp[0]);
  505. $cn = trim($temp[1]);
  506. $course_id = $db->get_course_id($si, $cn, "", true);
  507. $rtn_array[] = "$course_id"; // force into a string.
  508. }
  509. return $rtn_array;
  510. }
  511. function admin_get_course_array_from_definition_data($subject_data, $course_numData, $catalog_year = "") {
  512. // Looks at the subjectData and course_numData fields, and constructs
  513. // a query to pull our every course which matches it.
  514. $rtn_array = array();
  515. $si = str_replace("*","%",$subject_data);
  516. $cn = str_replace("*","%",$course_numData);
  517. $catalog_line = "";
  518. if ($catalog_year != "") {
  519. $catalog_line = "AND catalog_year = '$catalog_year'";
  520. }
  521. $query = "SELECT * FROM draft_courses
  522. WHERE
  523. subject_id LIKE '?'
  524. AND course_num LIKE '?'
  525. AND course_id > 0
  526. $catalog_line
  527. GROUP BY subject_id, course_num
  528. ";
  529. $res = db_query($query, $si, $cn) ;
  530. while ($cur = db_fetch_array($res)) {
  531. $course_id = $cur["course_id"];
  532. if (in_array($course_id, $rtn_array)) continue;
  533. $rtn_array[] = $course_id;
  534. }
  535. return $rtn_array;
  536. }
  537. /**
  538. * I had to create my own version of array_diff, because the built-in PHP
  539. * version has a nasty bug where it doesn't work after a certain number of elements.
  540. */
  541. function admin_array_diff($array1, $array2) {
  542. // Return an array of values from array1 that
  543. // are NOT in array2.
  544. // This is my (Richard Peacock) own implementation of array_diff,
  545. // because something is broken with it, so I am programming
  546. // my own.
  547. $rtn = array();
  548. //for ($t = 0; $t < count($array1); $t++)
  549. // MUST use foreach instead of for(count($arr))
  550. // because I did array_unique on it!
  551. foreach($array1 as $t => $value)
  552. {
  553. if (in_array($array1[$t], $array2))
  554. {
  555. continue;
  556. } else {
  557. $rtn[] = $array1[$t];
  558. }
  559. }
  560. return $rtn;
  561. }
  562. /**
  563. * This popup is called from the edit group page. It lets the user
  564. * select an icon to assign to a group.
  565. */
  566. function admin_display_groups_popup_select_icon() {
  567. $rtn = "";
  568. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  569. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  570. $group_id = $_REQUEST["group_id"];
  571. $group = new Group();
  572. $group->group_id = $group_id;
  573. $group->bool_use_draft = true;
  574. $group->load_descriptive_data();
  575. $rtn = "<b>Please Select an Icon to use for $group->title (<i>$group->group_name</i>):</b>
  576. <div class='tenpt'>Current icon: <img src='" . fp_theme_location() . "/images/icons/$group->icon_filename' width='19'>
  577. $group->icon_filename.
  578. <br><br>
  579. Available Icons:
  580. <blockquote>";
  581. $handle = opendir(fp_theme_location(FALSE) . "/images/icons/.");
  582. $files = array();
  583. $accepted_exts = array("jpg", "gif", "png", "bmp", "JPG", "GIF", "PNG", "BMP", "jpeg");
  584. while($file = readdir($handle)) {
  585. if ($file != "." && $file != "..") {
  586. // Make sure it's extension is an image file.
  587. // Find out it's ext first.
  588. $temp = explode(".", $file);
  589. $ext = $temp[count($temp) - 1];
  590. if (in_array($ext, $accepted_exts)) {
  591. $files[] = $file;
  592. }
  593. }
  594. }
  595. // make sure they are alphabetized.
  596. sort($files);
  597. foreach($files as $file) {
  598. $rtn .= "<div style='padding: 5px;'>
  599. <input type='button' value='Select -> ' onClick='adminPopupSelectIcon(\"$file\");' >
  600. &nbsp; &nbsp;
  601. <img src='" . fp_theme_location() . "/images/icons/$file' width='19'>
  602. $file</div>";
  603. }
  604. $rtn .= "</blockquote></div>";
  605. return $rtn;
  606. }
  607. /**
  608. * Return back the courses in a group, suitable for the edit-group form.
  609. */
  610. function admin_get_group_courses(Group $group) {
  611. // Returns a plain text list of the courses in a group's requirements
  612. // for use in the editSpecificGroup page.
  613. $rtn = "";
  614. // courses not in branches...
  615. $courses = array();
  616. $c_count = 0;
  617. $group->list_courses->load_course_descriptive_data();
  618. $group->list_courses->sort_alphabetical_order();
  619. $group->list_courses->reset_counter();
  620. while($group->list_courses->has_more())
  621. {
  622. $c = $group->list_courses->get_next();
  623. if (strstr($c->subject_id , "&"))
  624. {
  625. $c->subject_id = str_replace("&", "_A_", $c->subject_id);
  626. }
  627. $course_line = "$c->subject_id $c->course_num";
  628. //$rtn .= "$c->subject_id $c->course_num";
  629. if ($c->min_grade != "" && $c->min_grade != "D")
  630. {
  631. //$rtn .= " ($c->min_grade)";
  632. $course_line .= " ($c->min_grade)";
  633. }
  634. //$rtn .= "\n";
  635. if ($courses[$course_line] == "")
  636. {
  637. $courses[$course_line] = 0;
  638. }
  639. // This is to check for specified repeats.
  640. $courses[$course_line]++;
  641. }
  642. // Go through the $courses array to check for specified repeats.
  643. foreach($courses as $course => $rep_count)
  644. {
  645. $rep_line = " [$rep_count]";
  646. if ($rep_count == 1)
  647. {
  648. $rep_line = "";
  649. }
  650. $rtn .= "$course$rep_line\n";
  651. }
  652. // Now, get them branches!
  653. if (!$group->list_groups->is_empty)
  654. {
  655. $group->list_groups->reset_counter();
  656. while ($group->list_groups->has_more())
  657. {
  658. $g = $group->list_groups->get_next();
  659. $g->list_courses->load_course_descriptive_data();
  660. $g->list_courses->sort_alphabetical_order();
  661. $g->list_courses->reset_counter();
  662. while($g->list_courses->has_more())
  663. {
  664. $c = $g->list_courses->get_next();
  665. if (strstr($c->subject_id , "&"))
  666. {
  667. $c->subject_id = str_replace("&", "_A_", $c->subject_id);
  668. }
  669. $rtn .= "$c->subject_id $c->course_num";
  670. if ($c->min_grade != "" && $c->min_grade != "D")
  671. {
  672. $rtn .= " ($c->min_grade)";
  673. }
  674. $rtn .= " & ";
  675. }
  676. // Take off the last &.
  677. $rtn = trim($rtn);
  678. $rtn = substr($rtn,0,-1);
  679. $rtn = trim($rtn);
  680. $rtn .= "\n";
  681. }
  682. }
  683. return $rtn;
  684. }
  685. /**
  686. * This function will display a list of all our groups.
  687. */
  688. function admin_display_groups() {
  689. $rtn = "";
  690. $de_catalog_year = admin_get_de_catalog_year();
  691. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  692. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  693. $db2 = new DatabaseHandler();
  694. fp_set_title(t("Edit Groups for") . " $de_catalog_year");
  695. $rtn .= "
  696. <h2 class='title'>" . t("Edit Groups for @de_catalog_year", array("@de_catalog_year" => $de_catalog_year)) . "</h2>
  697. Options:
  698. <ul style='margin-top: 5px;'>
  699. <li>" . l(t("Add a new group to this year"), "admin/groups/edit-group", "de_catalog_year=$de_catalog_year&group_id=new") . "</li>
  700. <li>" . l(t("Process all group definitions for this year"), "admin/groups/process-all-definitions", "de_catalog_year=$de_catalog_year") . "</li>
  701. </li>
  702. </ul>
  703. <div align='center'>" . t("Hint: use CTRL-F to search groups quickly") . "</div>
  704. <table border='0' cellpadding='2' width='100%' class='admin-groups-list'>
  705. <tr>
  706. <th>" . t("Title") . "</th>
  707. <th>" . t("Internal Name") . "</th>
  708. <th align='center'>Pri</th>
  709. <th align='center'>i</th>
  710. <th align='center'>" . t("Used") . "</th>
  711. </tr>
  712. ";
  713. $on_mouse_over = " onmouseover=\"style.backgroundColor='#FFFF99'\"
  714. onmouseout=\"style.backgroundColor='white'\" ";
  715. $res = db_query("SELECT * FROM draft_groups
  716. WHERE catalog_year = '?'
  717. AND delete_flag = '0'
  718. ORDER BY title, group_name ", $de_catalog_year);
  719. while($cur = db_fetch_array($res)) {
  720. extract($cur, 3, "db");
  721. $use_count = 0;
  722. // Find out how many degree plans are using this particular group...
  723. $res2 = db_query("SELECT count(id) AS count FROM draft_degree_requirements
  724. WHERE group_id = '?' ", $db_group_id);
  725. if (db_num_rows($res2) > 0) {
  726. $cur2 = db_fetch_array($res2);
  727. $use_count = $cur2["count"];
  728. }
  729. $def_flag = "";
  730. if (trim($db_definition) != "") {
  731. $def_flag = " (*)";
  732. }
  733. if ($db_title == "") {
  734. $db_title = "[" . t("NO TITLE SPECIFIED") . "]";
  735. }
  736. $rtn .= "<tr $on_mouse_over>
  737. <td valign='top' class='tenpt'><a name='group_$db_group_id'></a>
  738. " . l($db_title, "admin/groups/edit-group", "group_id=$db_group_id&de_catalog_year=$de_catalog_year") . "
  739. </td>
  740. <td valign='top' class='tenpt'>
  741. <i>$db_group_name</i>$def_flag
  742. </td>
  743. <td valign='top' class='tenpt'>
  744. $db_priority
  745. </td>
  746. <td valign='top' class='tenpt'>
  747. <img src='" . fp_theme_location() . "/images/icons/$db_icon_filename' width='19'>
  748. </td>
  749. <td valign='top' class='tenpt'>
  750. $use_count <a href='javascript: adminPopupWindow(\"" . base_path() . "/admin/groups/popup-show-group-use&group_id=$db_group_id\");'><img src='" . fp_theme_location() . "/images/popup.gif' border='0'></a>
  751. </td>
  752. </tr>";
  753. }
  754. $rtn .= "</table>";
  755. return $rtn;
  756. }
  757. function admin_process_all_definitions_form() {
  758. $form = array();
  759. $de_catalog_year = admin_get_de_catalog_year();
  760. fp_set_title(t("Process all definitions for @year", array("@year" => $de_catalog_year)));
  761. $form["mark" . $m++] = array(
  762. "type" => "markup",
  763. "value" => t("This will cause all of the groups with definitions to be cleared, and their
  764. definitions re-run. This process can take several minutes, depending
  765. on how many groups with definitions you have."),
  766. );
  767. $form["de_catalog_year"] = array(
  768. "type" => "hidden",
  769. "value" => $de_catalog_year,
  770. );
  771. $form["submit"] = array(
  772. "type" => "submit",
  773. "value" => t("Process definitions"),
  774. "description" => t("Can take several minutes to run! Only click ONCE!"),
  775. );
  776. return $form;
  777. }
  778. /**
  779. * Actually perform the refreshing of definitions.
  780. */
  781. function admin_process_all_definitions_form_submit($form, $form_submit) {
  782. $values = $form_submit["values"];
  783. $db = get_global_database_handler();
  784. $de_catalog_year = $values["de_catalog_year"];
  785. // This function will go through every group for this year and
  786. // re-run it's definition, saving the result.
  787. // First, find every group which has a definition set.
  788. $res = db_query("SELECT * FROM draft_groups
  789. WHERE definition != ''
  790. AND catalog_year = '?'
  791. AND delete_flag = 0 ", $de_catalog_year);
  792. while($cur = db_fetch_array($res)) {
  793. $def = $cur["definition"];
  794. $group_id = $cur["group_id"];
  795. $group_name = $cur["group_name"];
  796. $temp = admin_get_courses_from_definition($def);
  797. $courses = trim($temp["text"]);
  798. $ccount = 0;
  799. fp_add_message(t("Working on %name", array("%name" => $group_name)));
  800. // Remove all the existing group requirements for this group first.
  801. $res2 = db_query("DELETE FROM draft_group_requirements
  802. WHERE group_id = ? ", $group_id);
  803. $lines = explode("\n", $courses);
  804. for ($t = 0; $t < count($lines); $t++) {
  805. $line = trim($lines[$t]);
  806. if ($line == "") { continue; }
  807. // Get rid of extra whitespace.
  808. $line = str_replace(" ", " ", $line);
  809. $line = str_replace(" ", " ", $line);
  810. $line = str_replace(" ", " ", $line);
  811. // Does this line contain at least one & symbol? If it does,
  812. // then this is a subgroup (branch). If not, then we can insert
  813. // the course as-is.
  814. if (!strstr($line, "&")) {
  815. // Did NOT contain an ampersand (&), so this goes in the
  816. // regular course requirements.
  817. $tokens = explode(" ", $line);
  818. $subject_id = trim($tokens[0]);
  819. $course_num = trim($tokens[1]);
  820. $min_grade = trim($tokens[2]);
  821. $course_repeats = trim($tokens[3]);
  822. if (strstr($min_grade, "[")) {
  823. // This is actually a specified repeat, not a min grade.
  824. $course_repeats = $min_grade;
  825. $min_grade = "";
  826. }
  827. $min_grade = str_replace("(","",$min_grade);
  828. $min_grade = strtoupper(str_replace(")","",$min_grade));
  829. $course_repeats = str_replace("[","",$course_repeats);
  830. $course_repeats = str_replace("]","",$course_repeats);
  831. $course_repeats--;
  832. if ($course_repeats < 0) { $course_repeats = 0; }
  833. // If the subject_id had a _A_ in it, convert this back
  834. // to an ampersand.
  835. $subject_id = str_replace("_A_", "&", $subject_id);
  836. // We don't care about catalog year anymore...
  837. if ($course_id = $db->get_course_id($subject_id, $course_num, "", true)) {
  838. $query = "INSERT INTO draft_group_requirements
  839. (`group_id`,`course_id`,
  840. `course_min_grade`,`course_repeats`,`data_entry_value`)
  841. values ('?','?',
  842. '?','?','?~?') ";
  843. $res2 = db_query($query, $group_id, $course_id, $min_grade, $course_repeats, $subject_id, $course_num);
  844. $ccount++;
  845. }
  846. else {
  847. // The course_id could not be found!
  848. fp_add_message(t("Course not found! You specified %course as a requirement in %gname,
  849. but this course could not be found in the catalog. It was removed from
  850. the list of requirements. Are you sure you typed it correctly? Please
  851. check your spelling, and add the course again.", array("%course" => "$subject_id $course_num", "%gname" => $group_name)), "error");
  852. }
  853. }
  854. }
  855. fp_add_message(t("%name definition processed. %count courses added.", array("%name" => $group_name, "%count" => $ccount)));
  856. }
  857. fp_add_message(t("Group definitions have be re-run for @year", array("@year" => $de_catalog_year)));
  858. }
  859. /**
  860. * Displays a popup showing where a particular group is being used in FlightPath.
  861. */
  862. function admin_display_groups_popup_show_group_use() {
  863. $rtn = "";
  864. $group_id = $_REQUEST["group_id"];
  865. $group = new Group();
  866. $group->group_id = $group_id;
  867. $group->bool_use_draft = true;
  868. $group->load_descriptive_data();
  869. $rtn .= "<b>" . t("Degrees using @group_title (%group_name):", array("@group_title"=>$group->title, "%group_name" => $group->group_name)) . "</b>
  870. <br><br>
  871. <table border='0' cellspacing='5'>
  872. <tr>
  873. <th>" . t("Degree") . "</th>
  874. <th>" . t("Code") . "</th>
  875. <th>" . t("Semester") . "</th>
  876. <th>" . t("Year") . "</th>
  877. </tr>
  878. ";
  879. $res = db_query("SELECT * FROM draft_degrees a,
  880. draft_degree_requirements b
  881. WHERE a.degree_id = b.degree_id
  882. AND b.group_id = '?'
  883. ORDER BY a.title, a.major_code, b.semester_num ", $group_id);
  884. while($cur = db_fetch_array($res))
  885. {
  886. extract($cur, 3, "db");
  887. $rtn .= "<tr>
  888. <td valign='top' class='tenpt' width='200'>
  889. $db_title
  890. </td>
  891. <td valign='top' class='tenpt' width='100'>
  892. $db_major_code
  893. </td>
  894. <td valign='top' class='tenpt' align='center'>
  895. " . admin_get_semester_name($db_semester_num) . "
  896. </td>
  897. <td valign='top' class='tenpt' width='100'>
  898. $db_catalog_year
  899. </td>
  900. </tr>
  901. ";
  902. }
  903. $rtn .= "</table>";
  904. return $rtn;
  905. }