admin.groups.inc

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

File

modules/admin/admin.groups.inc
View source
  1. <?php
  2. /* This include file deals with Groups editing for FlightPath */
  3. /**
  4. * Validate handler for edit group form.
  5. */
  6. function admin_edit_group_form_validate(&$form, &$form_state) {
  7. $values = $form_state["values"];
  8. $group_name = trim($values["group_name"]);
  9. $group_id = $values["group_id"];
  10. $de_catalog_year = $values["de_catalog_year"];
  11. // We want to make sure the group_name is in a machine-name format,
  12. // and we need to make sure it is unique for this catalog year!
  13. $group_name = fp_get_machine_readable(strtolower($group_name));
  14. $form_state['values']['group_name'] = $group_name;
  15. // Check that group_name is unique (but exclude the current group_id from the check)
  16. $mycount = db_query("SELECT count(*) as mycount FROM draft_groups
  17. WHERE group_name = ?
  18. AND group_id != ?
  19. AND delete_flag = '0'
  20. AND catalog_year = ?", $group_name, $group_id, $de_catalog_year)->fetchColumn();
  21. if ($mycount > 0) {
  22. form_error("group_name", t("The 'Internal group machine name' %gn is already in use in FlightPath by another group
  23. in the catalog year %cy.
  24. Please change to a different name, and submit again. <b>Your work has NOT been saved.</b>
  25. ", array("%gn" => $group_name, "%cy" => $de_catalog_year)));
  26. return;
  27. }
  28. }
  29. function admin_edit_group_form_submit(&$form, $form_state) {
  30. $values = $form_state["values"];
  31. $de_catalog_year = $values["de_catalog_year"];
  32. $db = get_global_database_handler();
  33. $db2 = new DatabaseHandler();
  34. $group_id = $values["group_id"];
  35. // Okay, we are trying to save the details of this group.
  36. // First thing we need to do is UPDATE the title, group_name,
  37. // priority, icon and comment.
  38. $group_name = trim($values["group_name"]);
  39. $title = trim($values["title"]);
  40. $priority = intval(trim($values["priority"]));
  41. $icon_filename = trim($values["icon_filename"]);
  42. $data_entry_comment = trim($values["data_entry_comment"]);
  43. $catalog_repeat = intval(trim($values["catalog_repeat"]));
  44. // Save the entire post to the log.
  45. // Since we are making a change to the draft table(s), let's add a row
  46. // to draft instructions.
  47. $db->add_draft_instruction("-");
  48. // Are we trying to delete this group?
  49. if ($_POST["perform_action2"] == "delete_group" && user_has_permission("can_delete_data_entry")) {
  50. $res = db_query("UPDATE draft_groups
  51. SET delete_flag = '1'
  52. WHERE group_id = '?'
  53. AND catalog_year = '?'
  54. ", $group_id, $de_catalog_year);
  55. fp_add_message(t("The group @title (%name) has been deleted successfully for @year", array("@title" => $title, "%name" => $group_name, "@year" => $de_catalog_year)));
  56. fp_goto("admin/groups", "de_catalog_year=$de_catalog_year");
  57. return;
  58. }
  59. // If the $group_id == new then create a new one.
  60. if ($group_id == "new") {
  61. $group_id = $db->request_new_group_id();
  62. $res = db_query("INSERT INTO draft_groups(group_id, catalog_year)
  63. values ('?','?') ", $group_id, $de_catalog_year);
  64. $values["group_id"] = $group_id;
  65. // Let's reset where we should redirect to after the form submits.
  66. $form["#redirect"] = array(
  67. "path" => "admin/groups/edit-group",
  68. "query" => "group_id=$group_id&de_catalog_year=$de_catalog_year",
  69. );
  70. }
  71. $res = db_query("UPDATE draft_groups
  72. SET group_name = '?',
  73. title = '?',
  74. priority = '?',
  75. icon_filename = '?',
  76. catalog_repeat = '?',
  77. data_entry_comment = '?'
  78. WHERE
  79. group_id = '?' ",
  80. $group_name, $title, $priority, $icon_filename, $catalog_repeat, $data_entry_comment, $group_id);
  81. // We need to delete all the existing course & subgroup requirements from this group.
  82. // That entails first seeing what subgroups were required and deleting them,
  83. // then deleting the parent group's requirements.
  84. // First, find and delete the branches (child groups):
  85. $res = db_query("SELECT * FROM draft_group_requirements
  86. WHERE group_id = '?'
  87. AND child_group_id != '0' ", $group_id);
  88. while ($cur = db_fetch_array($res)) {
  89. $cg_id = $cur["child_group_id"];
  90. $res2 = db_query("DELETE FROM draft_group_requirements
  91. WHERE group_id = '?' ", $cg_id);
  92. }
  93. // Now delete the course requirements...
  94. $res = db_query("DELETE FROM draft_group_requirements
  95. WHERE group_id = '?' ", $group_id);
  96. $courses = trim($values["courses"]);
  97. // If a definition was set, then we will ignore what is in the POST
  98. // for the course requrements, and instead use the definition.
  99. if (trim($values["set_definition"] != "")) {
  100. $def = urldecode(trim($values["set_definition"]));
  101. //$cc = trim(get_courses_from_definition($def, $de_catalog_year));
  102. $temp2 = admin_get_courses_from_definition($def);
  103. $cc = trim($temp2["text"]);
  104. if ($cc != "") {
  105. $courses = $cc;
  106. // UPDATE this group's definition!
  107. $res = db_query("UPDATE draft_groups
  108. SET definition = '?'
  109. WHERE
  110. group_id = '?' ", $def, $group_id);
  111. }
  112. //print_pre($cc);
  113. }
  114. else {
  115. // In other words, the setDefinition WAS blank.
  116. // Let's update the table. This is to fix a bug where they were unable
  117. // to clear definitions.
  118. $res = db_query("UPDATE draft_groups
  119. SET definition = ''
  120. WHERE
  121. group_id = '?' ", $group_id);
  122. }
  123. // If catalog_repeat == 1, then we need to perform that operation on the $courses text.
  124. if ($catalog_repeat == 1) {
  125. $courses = admin_process_catalog_repeats_for_group_courses_text($courses, $de_catalog_year);
  126. }
  127. // Okay, now we look at the actual "courses" box and assemble the group
  128. // in the database.
  129. $lines = explode("\n", $courses);
  130. for ($t = 0; $t < count($lines); $t++) {
  131. $line = trim($lines[$t]);
  132. if ($line == "") { continue; }
  133. // Get rid of extra whitespace.
  134. $line = str_replace(" ", " ", $line);
  135. $line = str_replace(" ", " ", $line);
  136. $line = str_replace(" ", " ", $line);
  137. // Does this line contain at least one & symbol? If it does,
  138. // then this is a subgroup (branch). If not, then we can insert
  139. // the course as-is.
  140. if (strstr($line, "&")) {
  141. // This line DOES have an ampersand (&), so this is a sub group
  142. // within this group.
  143. // First, we need to request a new branchID for this new group.
  144. if (!$branch_id = $db->request_new_group_id()) {
  145. die ("Error. Could not create new group (branch) ID.");
  146. }
  147. else {
  148. // Add this branch to the list of requirements for this group.
  149. $query = "INSERT INTO draft_group_requirements
  150. (group_id, child_group_id)
  151. values ('?','?') ";
  152. $res = db_query($query, $group_id, $branch_id);
  153. }
  154. $c_tokes = explode("&",$line);
  155. for ($cT = 0; $cT < count($c_tokes); $cT++)
  156. {
  157. $tokens = explode(" ", trim($c_tokes[$cT]));
  158. $subject_id = trim($tokens[0]);
  159. $course_num = trim($tokens[1]);
  160. $min_grade = @trim($tokens[2]);
  161. $course_repeats = @trim($tokens[3]);
  162. if (strstr($min_grade, "[")) {
  163. // This is actually a specified repeat, not a min grade.
  164. $course_repeats = $min_grade;
  165. $min_grade = "";
  166. }
  167. $min_grade = str_replace("(","",$min_grade);
  168. $min_grade = str_replace(")","",$min_grade);
  169. $course_repeats = str_replace("[","",$course_repeats);
  170. $course_repeats = str_replace("]","",$course_repeats);
  171. $course_repeats--;
  172. if ($course_repeats < 0) { $course_repeats = 0; }
  173. // If the subject_id had a _A_ in it, convert this back
  174. // to an ampersand.
  175. $subject_id = str_replace("_A_", "&", $subject_id);
  176. // Commenting out, because we do not care about catalog_year
  177. // when specifying courses...
  178. if ($course_id = $db->get_course_id($subject_id, $course_num, "", true)) {
  179. $query = "INSERT INTO draft_group_requirements
  180. (group_id, course_id,
  181. course_min_grade, course_repeats, data_entry_value)
  182. values ('?','?','?','?', ?) ";
  183. $res = db_query($query, $branch_id, $course_id, $min_grade, $course_repeats, "$subject_id~$course_num");
  184. }
  185. else {
  186. // The course_id could not be found!
  187. form_error("courses", t("Course Not Found!
  188. You specified the course
  189. <b>%course</b> as a requirement, but this course
  190. could not be found in the catalog.
  191. It was removed from the list of requirements.
  192. Are you sure you typed it correctly? Please check
  193. your spelling, and add the course again.", array("%course" => "$subject_id $course_num")));
  194. }
  195. }
  196. }
  197. else {
  198. // Did NOT contain an ampersand (&), so this goes in the
  199. // regular course requirements.
  200. $tokens = explode(" ", $line);
  201. $subject_id = @trim($tokens[0]);
  202. $course_num = @trim($tokens[1]);
  203. $min_grade = @trim($tokens[2]);
  204. $course_repeats = @trim($tokens[3]);
  205. if (strstr($min_grade, "[")) {
  206. // This is actually a specified repeat, not a min grade.
  207. $course_repeats = $min_grade;
  208. $min_grade = "";
  209. }
  210. $min_grade = str_replace("(","",$min_grade);
  211. $min_grade = strtoupper(str_replace(")","",$min_grade));
  212. $course_repeats = str_replace("[","",$course_repeats);
  213. $course_repeats = str_replace("]","",$course_repeats);
  214. $course_repeats--;
  215. if ($course_repeats < 0) { $course_repeats = 0; }
  216. // If the subject_id had a _A_ in it, convert this back
  217. // to an ampersand.
  218. $subject_id = str_replace("_A_", "&", $subject_id);
  219. // We don't care about catalog year anymore...
  220. if ($course_id = $db->get_course_id($subject_id, $course_num, "", true)) {
  221. $query = "INSERT INTO draft_group_requirements
  222. (group_id, course_id,
  223. course_min_grade, course_repeats, data_entry_value)
  224. values (?,?,?,?,?) ";
  225. $res = db_query($query, $group_id, $course_id, $min_grade, $course_repeats, "$subject_id~$course_num");
  226. }
  227. else {
  228. // The course_id could not be found!
  229. form_error("courses", t("Course Not Found!
  230. You specified the course
  231. <b>%course</b> as a requirement, but this course
  232. could not be found in the catalog.
  233. It was removed from the list of requirements.
  234. Are you sure you typed it correctly? Please check
  235. your spelling, and add the course again.", array("%course" => "$subject_id $course_num")));
  236. }
  237. }
  238. }
  239. fp_add_message("Group successfully updated.");
  240. // Clear previous values to make sure the Required Courses box gets updated,
  241. // even if its set to readonly.
  242. clear_session_form_values("admin_edit_group_form");
  243. }
  244. /**
  245. * This function will accept the $courses text (textarea) from a group, which spells out
  246. * all of the courses, and then assign specified repeats based on what is set for that course
  247. * in the course catalog.
  248. */
  249. function admin_process_catalog_repeats_for_group_courses_text($courses, $catalog_year) {
  250. $rtn = "";
  251. // Okay, now we look at the actual "courses" box and assemble the group
  252. // in the database.
  253. $lines = explode("\n", $courses);
  254. for ($t = 0; $t < count($lines); $t++) {
  255. $line = trim($lines[$t]);
  256. if ($line == "") { continue; }
  257. // Get rid of extra whitespace.
  258. $line = str_replace(" ", " ", $line);
  259. $line = str_replace(" ", " ", $line);
  260. $line = str_replace(" ", " ", $line);
  261. $new_line = "";
  262. // Does this line contain at least one & symbol? If it does,
  263. // then this is a subgroup (branch), and we need to look at all the courses
  264. // on that branch.
  265. if (strstr($line, "&")) {
  266. // If this branch contains an ampersand, I don't think I should attempt to process it at all.
  267. $new_line = $line;
  268. /*
  269. $c_tokes = explode("&",$line);
  270. for ($cT = 0; $cT < count($c_tokes); $cT++)
  271. {
  272. $tokens = explode(" ", trim($c_tokes[$cT]));
  273. $subject_id = trim($tokens[0]);
  274. $course_num = trim($tokens[1]);
  275. $min_grade = @trim($tokens[2]);
  276. $course_repeats = @trim($tokens[3]);
  277. if (strstr($min_grade, "[")) {
  278. // This is actually a specified repeat, not a min grade.
  279. $course_repeats = $min_grade;
  280. $min_grade = "";
  281. }
  282. $min_grade = str_replace("(","",$min_grade);
  283. $min_grade = str_replace(")","",$min_grade);
  284. $course_repeats = str_replace("[","",$course_repeats);
  285. $course_repeats = str_replace("]","",$course_repeats);
  286. $course_repeats--;
  287. if ($course_repeats < 0) { $course_repeats = 0; }
  288. // If the subject_id had a _A_ in it, convert this back
  289. // to an ampersand.
  290. $subject_id = str_replace("_A_", "&", $subject_id);
  291. // Okay, we now have a subject_id and course_number. Let's find out how many times
  292. // it can be repeated for credit.
  293. $max_cat_repeats = fp_get_max_catalog_repeats_for_course($subject_id, $course_num, $catalog_year, TRUE);
  294. // Okay, now, let's rebuild this line.
  295. $subject_id = str_replace("&", "_A_", $subject_id);
  296. $new_line .= "$subject_id $course_num";
  297. // Was there a min grade?
  298. if ($min_grade != "") {
  299. $new_line .= " ($min_grade)";
  300. }
  301. // Specified repeats?
  302. if ($max_cat_repeats > 0) {
  303. $new_line .= " [$max_cat_repeats]";
  304. }
  305. // Put ampersand back at the end?
  306. if ($cT < count($c_tokes) - 1) {
  307. $new_line .= " & ";
  308. }
  309. else {
  310. // This is the last part. No need to add an ampersand, but
  311. // leave blank, as we will add a \n to the very end later.
  312. }
  313. } // for $cT
  314. */
  315. }
  316. else {
  317. // Did NOT contain an ampersand (&), so this goes in the
  318. // regular course requirements.
  319. $tokens = explode(" ", $line);
  320. $subject_id = @trim($tokens[0]);
  321. $course_num = @trim($tokens[1]);
  322. $min_grade = @trim($tokens[2]);
  323. $course_repeats = @trim($tokens[3]);
  324. if (strstr($min_grade, "[")) {
  325. // This is actually a specified repeat, not a min grade.
  326. $course_repeats = $min_grade;
  327. $min_grade = "";
  328. }
  329. $min_grade = str_replace("(","",$min_grade);
  330. $min_grade = strtoupper(str_replace(")","",$min_grade));
  331. $course_repeats = str_replace("[","",$course_repeats);
  332. $course_repeats = str_replace("]","",$course_repeats);
  333. $course_repeats--;
  334. if ($course_repeats < 0) { $course_repeats = 0; }
  335. // If the subject_id had a _A_ in it, convert this back
  336. // to an ampersand.
  337. $subject_id = str_replace("_A_", "&", $subject_id);
  338. // Okay, we now have a subject_id and course_number. Let's find out how many times
  339. // it can be repeated for credit.
  340. $max_cat_repeats = fp_get_max_catalog_repeats_for_course($subject_id, $course_num, $catalog_year, TRUE);
  341. // Okay, now, let's rebuild this line.
  342. $subject_id = str_replace("&", "_A_", $subject_id);
  343. $new_line .= "$subject_id $course_num";
  344. // Was there a min grade?
  345. if ($min_grade != "") {
  346. $new_line .= " ($min_grade)";
  347. }
  348. // Specified repeats?
  349. if ($max_cat_repeats > 0) {
  350. $new_line .= " [$max_cat_repeats]";
  351. }
  352. } // else (does not contain &)
  353. // Add to our $rtn
  354. $rtn .= $new_line . "\n";
  355. } // for lines...
  356. return $rtn;
  357. } // admin_process_catalog_repeats_for_group_courses_text
  358. /**
  359. * This function lets the user edit a group.
  360. */
  361. function admin_edit_group_form() {
  362. $form = array();
  363. $m = 0;
  364. $de_catalog_year = admin_get_de_catalog_year();
  365. $group_id = $_REQUEST["group_id"];
  366. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  367. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  368. $form["#redirect"] = array(
  369. "path" => "admin/groups/edit-group",
  370. "query" => "group_id=$group_id&de_catalog_year=$de_catalog_year",
  371. );
  372. if (user_has_permission("can_view_advanced")) {
  373. $form["mark" . $m++] = array(
  374. "type" => "markup",
  375. "value" => " <span class='tenpt' style='background-color: yellow; margin-left: 20px;'>
  376. adv: group_id = $group_id.
  377. Used by:
  378. <a href='javascript: adminPopupWindow(\"" . fp_url("admin/groups/popup-show-group-use", "group_id=$group_id") . "\");'>[degrees]</a>
  379. </span>",
  380. "weight" => 0,
  381. );
  382. }
  383. $group = new Group($group_id, null, -1, false, true);
  384. //print_pre($group->to_string());
  385. $group->load_descriptive_data();
  386. fp_set_title(t("Edit Group:") . " $group->title ($de_catalog_year)");
  387. $form["perform_action2"] = array(
  388. "type" => "hidden",
  389. "value" => "",
  390. );
  391. $form["set_definition"] = array(
  392. "type" => "hidden",
  393. "value" => urlencode($group->definition),
  394. );
  395. $form["scroll_top"] = array(
  396. "type" => "hidden",
  397. "value" => "",
  398. );
  399. $form["group_id"] = array(
  400. "type" => "hidden",
  401. "value" => $group_id,
  402. );
  403. $form["de_catalog_year"] = array(
  404. "type" => "hidden",
  405. "value" => $de_catalog_year,
  406. );
  407. // Actually draw the form out.
  408. $form["title"] = array(
  409. "type" => "textfield",
  410. "label" => t("Group title:"),
  411. "value" => $group->title,
  412. "maxlength" => 100,
  413. "required" => TRUE,
  414. "popup_description" => t("This is what FlightPath uses to refer to this group in screens and popups.
  415. Ex: Free Electives, Art Electives, Core Humanities, etc."),
  416. "weight" => 10,
  417. );
  418. $form["group_name"] = array(
  419. "type" => "textfield",
  420. "label" => t("Internal group machine name:"),
  421. "value" => $group->group_name,
  422. "maxlength" => 100,
  423. "required" => TRUE,
  424. "popup_description" => t("The group's \"internal machine name\" is internal to FlightPath, and is never seen by the average user.
  425. You may use this to distinguish between groups with the same title. Ex:
  426. major_electives_sr and major_electives_jr. The field must be unique within each catalog year, and
  427. consist of only letters, numbers, and underscores. FlightPath will make
  428. sure it is unique when you save, and give you a chance to change it if it
  429. is not."),
  430. "weight" => 20,
  431. );
  432. $form["priority"] = array(
  433. "type" => "textfield",
  434. "label" => t("Priority:"),
  435. "value" => $group->priority,
  436. "maxlength" => 10,
  437. "size" => 10,
  438. "popup_description" => t("This should be a number, and it is very important, because it determines the
  439. order in which courses are assigned to groups in FlightPath.
  440. Higher numbers fill in FIRST! So a group with a priority of 100 would fill in before
  441. a group with a priority of 30."),
  442. "weight" => 30,
  443. );
  444. $form["icon_filename"] = array(
  445. "type" => "hidden",
  446. "label" => t("Icon:"),
  447. "value" => $group->icon_filename,
  448. "suffix" => "
  449. <img src='" . fp_theme_location() . "/images/icons/$group->icon_filename' width='19'>
  450. $group->icon_filename
  451. &nbsp; &nbsp;
  452. <a href='javascript: adminPopupWindow(\"" . fp_url("admin/groups/popup-select-icon", "group_id=$group_id") . "\");'>[select another]</a>
  453. ",
  454. "weight" => 40,
  455. );
  456. $form["definition"] = array(
  457. "type" => "markup",
  458. "label" => t("Definition:"),
  459. "value" => "<i>" . nl2br($group->definition) . "</i>",
  460. "prefix" => "<div style='overflow: auto; max-height: 150px;' class='admin-groups-show-definition'>",
  461. "suffix" => "</div><a href='javascript: adminPopupWindow(\"" . fp_url("admin/groups/popup-edit-definition", "de_catalog_year=$de_catalog_year&group_id=$group_id") . "\");'
  462. >[" . t("edit definition") . "]</a>",
  463. "weight" => 50,
  464. );
  465. $form["mark" . $m++] = array(
  466. "type" => "markup",
  467. "value" => "<hr>",
  468. "weight" => 60,
  469. );
  470. $courses = admin_get_group_courses($group);
  471. $form["courses"] = array(
  472. "type" => "textarea",
  473. "label" => t("Required Courses:"),
  474. "rows" => 17,
  475. "cols" => 80,
  476. "value" => $courses,
  477. "weight" => 70,
  478. );
  479. // if a definition was specified, we need to disable the courses textarea.
  480. if (trim($group->definition)) {
  481. $form["courses"]["attributes"] = "readonly=readonly style='background-color: #ccc;' ";
  482. $form["courses"]["prefix"] = "<div class='admin-groups-courses-disabled'>
  483. " . t("Note: Because a definition was specified, you cannot directly
  484. edit the Required Courses. Manage these courses using the
  485. Edit Definition popup window.") . "</div>";
  486. }
  487. $form["catalog_repeat"] = array(
  488. "type" => "checkbox",
  489. "label" => t("Set Catalog Repeats"),
  490. "value" => $group->db_catalog_repeat,
  491. "popup_description" => t("If checked, this group will automatically assign specified repeats to courses
  492. which are determined to be repeatable for this catalog year.
  493. For example, if you enter
  494. ART 101, and in the course catalog that course may be taken two times, then
  495. when you save this group the line will be changed to ART 101 [2].
  496. This will work with definitions, but will not work in groups with branches.
  497. If you are unsure what to select, leave this box unchecked."),
  498. "weight" => 80,
  499. );
  500. $form["data_entry_comment"] = array(
  501. "type" => "textarea",
  502. "label" => t("Optional Comment: (only seen by other FlightPath administrators)"),
  503. "rows" => 3,
  504. "cols" => 80,
  505. "value" => $group->data_entry_comment,
  506. "weight" => 90,
  507. );
  508. $form["submit"] = array(
  509. "type" => "submit",
  510. "value" => "Submit",
  511. "prefix" => "<hr>",
  512. "weight" => 100,
  513. );
  514. // Only show delete option based on permission
  515. if (user_has_permission("can_delete_data_entry")) {
  516. $form["mark" . $m++] = array(
  517. "type" => "markup",
  518. "value" => "<div align='right' class='groups-delete-group-wrapper'>
  519. " . t("Delete this group?") . " <input type='button' value='X'
  520. onClick='adminDeleteGroup(\"$group_id\");'>
  521. </div>",
  522. "weight" => 200,
  523. );
  524. }
  525. return $form;
  526. }
  527. function admin_display_groups_popup_edit_definition() {
  528. $rtn = $tdef = "";
  529. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  530. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  531. $group_id = trim($_REQUEST["group_id"]);
  532. $de_catalog_year = admin_get_de_catalog_year();
  533. $group = new Group($group_id, null, -1, false, true);
  534. $group->load_descriptive_data();
  535. if (isset($_REQUEST["definition"])) {
  536. $definition = trim($_REQUEST["definition"]);
  537. }
  538. else {
  539. $definition = $group->definition;
  540. }
  541. $results = admin_get_courses_from_definition($definition);
  542. // This text will be used to describe how the definition works in a javascript alert box:
  543. $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";
  544. $tdef .= " add CSCI.*\n";
  545. $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, ");
  546. $tdef .= t("to add all CSCI and any course with a subject that begins with A, enter:") . "\n";
  547. $tdef .= " add CSCI.*\n add A*.*\n";
  548. $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";
  549. $tdef .= " add *.*\n rem *.1*\n rem *.2*\n rem *.3*\n";
  550. $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") . " ";
  551. $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.");
  552. $rtn .= "<b>Edit Definition for $group->title ($de_catalog_year)<br><i>$group->group_name</i></b>
  553. <br><br><form action='" . fp_url("admin/groups/popup-edit-definition", "de_catalog_year=$de_catalog_year&group_id=$group_id") . "' method='POST' id='mainform'>
  554. <table border='0'>
  555. <tr>
  556. <td valign='top' align='right'>
  557. <div class='tenpt' align='left'>Working Definition:
  558. " . fp_get_js_alert_link($tdef, "[?]") . "</div>
  559. <textarea name='definition' id='definition' rows='10' cols='15' >$definition</textarea>
  560. <br>
  561. <input type='button' value='Generate ->'
  562. onClick='showUpdate(); document.getElementById(\"mainform\").submit();'>
  563. </td>
  564. <td valign='top' align='right' class='tenpt'>
  565. <div class='tenpt' align='left'>Results:" . " (" . $results["count"] . ")</div>
  566. <textarea rows='10' cols='35' readonly=readonly
  567. style='background-color: lightgray;'>{$results["text"]}</textarea>
  568. <br>
  569. (loads courses from all catalog years)
  570. </td>
  571. </tr>
  572. </table>
  573. </form>
  574. " . t("If you are satisfied with the results of this definition,
  575. click the Save to Group button. Otherwise, simply close this window.") . "
  576. <input type='button' value='Save to Group' onClick='adminPopupSaveDefinition(\"\");'>
  577. ";
  578. return $rtn;
  579. }
  580. function admin_get_course_array_from_course_id_array($course_idArray) {
  581. // Convert an array of course_id's into their subject_id ~~ course_num format.
  582. // Pick non-excluded courses over excluded courses, when you have the option.
  583. $rtn_array = array();
  584. $db = new DatabaseHandler();
  585. // MUST use foreach since we used array_unique earlier. Can't use
  586. // count($arr) after you use array_unique!!
  587. foreach($course_idArray as $t => $value) {
  588. $new_course = new Course();
  589. $new_course->bool_use_draft = true;
  590. $new_course->db = $db;
  591. $new_course->course_id = $course_idArray[$t];
  592. $new_course->load_descriptive_data(false);
  593. array_push($rtn_array, "$new_course->subject_id ~~ $new_course->course_num");
  594. }
  595. return $rtn_array;
  596. }
  597. function admin_get_courses_from_definition($definition, $catalog_year = "") {
  598. $group_array = array();
  599. // Okay, first things first, let's trim this sucker and remove extra whitespace.
  600. $definition = trim($definition);
  601. $definition = str_replace(" "," ",$definition);
  602. $definition = str_replace(" "," ",$definition);
  603. $definition = str_replace(" "," ",$definition);
  604. // Okay, now let's break this up into lines...
  605. $d_lines = explode("\n",$definition);
  606. foreach($d_lines as $line)
  607. {
  608. $line = trim($line);
  609. // Let's get each of the parts... the instruction, and the course data.
  610. $tokens = explode(" ", $line);
  611. $instruction = strtolower(trim($tokens[0]));
  612. @$course_data = trim($tokens[1]);
  613. // We know that the course data can also be broken up, by the .
  614. $c_tokens = explode(".", $course_data);
  615. $subject_data = trim(strtoupper($c_tokens[0]));
  616. @$course_numData = trim(strtoupper($c_tokens[1]));
  617. // Okay, so now, for this line, we have an instruction,
  618. // and some course data (possibly wild cards) to act on.
  619. //debugCT("$instruction $subject_data $course_numData");
  620. $t_array = admin_get_course_array_from_definition_data($subject_data, $course_numData, $catalog_year);
  621. // Okay, we got our list. Now what do we do with them?
  622. if ($instruction == "add" || $instruction == "+")
  623. {
  624. $group_array = array_merge($group_array, $t_array);
  625. $group_array = array_unique($group_array);
  626. }
  627. if ($instruction == "remove" || $instruction == "rem" || $instruction == "-" || $instruction == "del")
  628. {
  629. //print "<pre>" . print_r($t_array) . "</pre>";
  630. //debug_c_t(count($group_array));
  631. //$group_array = array_diff($group_array, $t_array);
  632. $group_array = admin_array_diff($group_array, $t_array);
  633. $group_array = array_unique($group_array);
  634. //debug_c_t(count($group_array));
  635. }
  636. }
  637. // Here's what we need to do:
  638. // In groupArray, we have the subject_id and course_num of every course in this definition.
  639. // We need to convert them to course_id's from the table,
  640. // and make sure we do not have duplicates.
  641. // First, get an array of course_id from the groupArray...
  642. $course_idArray = $group_array;
  643. // Take out duplicate entries (caused by eqv courses)...
  644. $course_idArray = array_unique($course_idArray);
  645. //print_r($course_idArray);
  646. //debugCT(sizeof($course_idArray));
  647. // Now, convert BACK into the "groupArray" structure (subject_id and course_num)...
  648. $group_array2 = admin_get_course_array_from_course_id_array($course_idArray);
  649. //print_r($group_array);
  650. // Place in alphabetical order.
  651. sort($group_array2);
  652. //var_dump($group_array2);
  653. $rtn = array();
  654. $rtn["text"] = "";
  655. $count = 1;
  656. // Now that we have the groupArray, we will turn it into a string...
  657. for ($t = 0; $t < count($group_array2); $t++)
  658. {
  659. $line = trim($group_array2[$t]);
  660. if ($line == "~~" || $line == "") continue;
  661. $count++;
  662. $temp = explode(" ~~ ", $line);
  663. $si = trim($temp[0]);
  664. $cn = trim($temp[1]);
  665. @$rtn["text"] .= "$si $cn\n";
  666. }
  667. $rtn["text"] = str_replace("&", "_A_", $rtn["text"]);
  668. //debug_c_t(count($group_array));
  669. $rtn["count"] = $count;
  670. return $rtn;
  671. }
  672. function admin_get_course_id_array_from_course_array($course_array) {
  673. $rtn_array = array();
  674. $db = new DatabaseHandler();
  675. // MUST use foreach instead of for since we did
  676. // array_unique! Can't trust count($arr)!
  677. foreach($course_array as $t => $value) {
  678. $line = trim($course_array[$t]);
  679. if ($line == "~~" || $line == "") continue;
  680. $count++;
  681. $temp = explode(" ~~ ", $line);
  682. $si = trim($temp[0]);
  683. $cn = trim($temp[1]);
  684. $course_id = $db->get_course_id($si, $cn, "", true);
  685. $rtn_array[] = "$course_id"; // force into a string.
  686. }
  687. return $rtn_array;
  688. }
  689. function admin_get_course_array_from_definition_data($subject_data, $course_numData, $catalog_year = "") {
  690. // Looks at the subjectData and course_numData fields, and constructs
  691. // a query to pull our every course which matches it.
  692. $rtn_array = array();
  693. $si = str_replace("*","%",$subject_data);
  694. $cn = str_replace("*","%",$course_numData);
  695. $catalog_line = "";
  696. if ($catalog_year != "") {
  697. $catalog_line = "AND catalog_year = '$catalog_year'";
  698. }
  699. $query = "SELECT * FROM draft_courses
  700. WHERE
  701. subject_id LIKE '?'
  702. AND course_num LIKE '?'
  703. AND course_id > 0
  704. $catalog_line
  705. GROUP BY subject_id, course_num
  706. ";
  707. $res = db_query($query, $si, $cn) ;
  708. while ($cur = db_fetch_array($res)) {
  709. $course_id = $cur["course_id"];
  710. if (in_array($course_id, $rtn_array)) continue;
  711. $rtn_array[] = $course_id;
  712. }
  713. return $rtn_array;
  714. }
  715. /**
  716. * I had to create my own version of array_diff, because the built-in PHP
  717. * version has a nasty bug where it doesn't work after a certain number of elements.
  718. */
  719. function admin_array_diff($array1, $array2) {
  720. // Return an array of values from array1 that
  721. // are NOT in array2.
  722. // This is my (Richard Peacock) own implementation of array_diff,
  723. // because something is broken with it, so I am programming
  724. // my own.
  725. $rtn = array();
  726. //for ($t = 0; $t < count($array1); $t++)
  727. // MUST use foreach instead of for(count($arr))
  728. // because I did array_unique on it!
  729. foreach($array1 as $t => $value)
  730. {
  731. if (in_array($array1[$t], $array2))
  732. {
  733. continue;
  734. } else {
  735. $rtn[] = $array1[$t];
  736. }
  737. }
  738. return $rtn;
  739. }
  740. /**
  741. * This popup is called from the edit group page. It lets the user
  742. * select an icon to assign to a group.
  743. */
  744. function admin_display_groups_popup_select_icon() {
  745. $rtn = "";
  746. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  747. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  748. $group_id = $_REQUEST["group_id"];
  749. $group = new Group();
  750. $group->group_id = $group_id;
  751. $group->bool_use_draft = true;
  752. $group->load_descriptive_data();
  753. $rtn = "<b>Please Select an Icon to use for $group->title (<i>$group->group_name</i>):</b>
  754. <div class='tenpt'>Current icon: <img src='" . fp_theme_location() . "/images/icons/$group->icon_filename' width='19'>
  755. $group->icon_filename.
  756. <br><br>
  757. Available Icons:
  758. <blockquote>";
  759. $handle = opendir(fp_theme_location(FALSE) . "/images/icons/.");
  760. $files = array();
  761. $accepted_exts = array("jpg", "gif", "png", "bmp", "JPG", "GIF", "PNG", "BMP", "jpeg");
  762. while($file = readdir($handle)) {
  763. if ($file != "." && $file != "..") {
  764. // Make sure it's extension is an image file.
  765. // Find out it's ext first.
  766. $temp = explode(".", $file);
  767. $ext = $temp[count($temp) - 1];
  768. if (in_array($ext, $accepted_exts)) {
  769. $files[] = $file;
  770. }
  771. }
  772. }
  773. // make sure they are alphabetized.
  774. sort($files);
  775. foreach($files as $file) {
  776. $rtn .= "<div style='padding: 5px;'>
  777. <input type='button' value='Select -> ' onClick='adminPopupSelectIcon(\"$file\");' >
  778. &nbsp; &nbsp;
  779. <img src='" . fp_theme_location() . "/images/icons/$file' width='19'>
  780. $file</div>";
  781. }
  782. $rtn .= "</blockquote></div>";
  783. return $rtn;
  784. }
  785. /**
  786. * Return back the courses in a group, suitable for the edit-group form.
  787. */
  788. function admin_get_group_courses(Group $group) {
  789. // Returns a plain text list of the courses in a group's requirements
  790. // for use in the edit_group_form.
  791. $rtn = "";
  792. // courses not in branches...
  793. $courses = array();
  794. $c_count = 0;
  795. $group->list_courses->load_course_descriptive_data();
  796. $group->list_courses->sort_alphabetical_order();
  797. $group->list_courses->reset_counter();
  798. while($group->list_courses->has_more())
  799. {
  800. $c = $group->list_courses->get_next();
  801. if (strstr($c->subject_id , "&"))
  802. {
  803. $c->subject_id = str_replace("&", "_A_", $c->subject_id);
  804. }
  805. $course_line = "$c->subject_id $c->course_num";
  806. //$rtn .= "$c->subject_id $c->course_num";
  807. if ($c->min_grade != "" && $c->min_grade != "D")
  808. {
  809. //$rtn .= " ($c->min_grade)";
  810. $course_line .= " ($c->min_grade)";
  811. }
  812. //$rtn .= "\n";
  813. if (!isset($courses[$course_line]))
  814. {
  815. $courses[$course_line] = 0;
  816. }
  817. // This is to check for specified repeats.
  818. $courses[$course_line]++;
  819. }
  820. // Go through the $courses array to check for specified repeats.
  821. foreach($courses as $course => $rep_count)
  822. {
  823. $rep_line = " [$rep_count]";
  824. if ($rep_count == 1)
  825. {
  826. $rep_line = "";
  827. }
  828. $rtn .= "$course$rep_line\n";
  829. }
  830. // Now, get them branches!
  831. if (!$group->list_groups->is_empty)
  832. {
  833. $group->list_groups->reset_counter();
  834. while ($group->list_groups->has_more())
  835. {
  836. $g = $group->list_groups->get_next();
  837. $g->list_courses->load_course_descriptive_data();
  838. $g->list_courses->sort_alphabetical_order();
  839. $g->list_courses->reset_counter();
  840. while($g->list_courses->has_more())
  841. {
  842. $c = $g->list_courses->get_next();
  843. if (strstr($c->subject_id , "&"))
  844. {
  845. $c->subject_id = str_replace("&", "_A_", $c->subject_id);
  846. }
  847. $rtn .= "$c->subject_id $c->course_num";
  848. if ($c->min_grade != "" && $c->min_grade != "D")
  849. {
  850. $rtn .= " ($c->min_grade)";
  851. }
  852. $rtn .= " & ";
  853. }
  854. // Take off the last &.
  855. $rtn = trim($rtn);
  856. $rtn = substr($rtn,0,-1);
  857. $rtn = trim($rtn);
  858. $rtn .= "\n";
  859. }
  860. }
  861. return $rtn;
  862. }
  863. /**
  864. * This function will display a list of all our groups.
  865. */
  866. function admin_display_groups() {
  867. $rtn = "";
  868. // Do this using $render array, so it can be altered
  869. // by hook_content_alter
  870. $render = array();
  871. $render['#id'] = 'admin_display_groups';
  872. $de_catalog_year = admin_get_de_catalog_year();
  873. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  874. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  875. $db2 = new DatabaseHandler();
  876. //fp_set_title(t("Edit Groups for") . " $de_catalog_year");
  877. $render['title_top'] = array(
  878. 'value' => "<h2 class='title'>" . t("Edit Groups for @de_catalog_year", array("@de_catalog_year" => $de_catalog_year)) . "</h2>",
  879. );
  880. $render['upper_links'] = array(
  881. 'value' => " Options:
  882. <ul style='margin-top: 5px;'>
  883. <li>" . l(t("Add a new group to this year"), "admin/groups/edit-group", "de_catalog_year=$de_catalog_year&group_id=new") . "</li>
  884. <li>" . l(t("Process all group definitions & catalog repeats for this year"), "admin/groups/process-all-definitions", "de_catalog_year=$de_catalog_year") . "</li>
  885. </li>
  886. </ul>
  887. <div align='center'>" . t("Hint: use CTRL-F to search groups quickly") . "</div>
  888. ",
  889. );
  890. /*
  891. $rtn .= "
  892. <h2 class='title'>" . t("Edit Groups for @de_catalog_year", array("@de_catalog_year" => $de_catalog_year)) . "</h2>
  893. Options:
  894. <ul style='margin-top: 5px;'>
  895. <li>" . l(t("Add a new group to this year"), "admin/groups/edit-group", "de_catalog_year=$de_catalog_year&group_id=new") . "</li>
  896. <li>" . l(t("Process all group definitions & catalog repeats for this year"), "admin/groups/process-all-definitions", "de_catalog_year=$de_catalog_year") . "</li>
  897. </li>
  898. </ul>
  899. <div align='center'>" . t("Hint: use CTRL-F to search groups quickly") . "</div>
  900. <table border='0' cellpadding='2' width='100%' class='admin-groups-list'>
  901. <tr>
  902. <th>" . t("Title") . "</th>
  903. <th>" . t("Internal Name") . "</th>
  904. <th align='center'>Pri</th>
  905. <th align='center'>i</th>
  906. <th align='center'>" . t("Used") . "</th>
  907. </tr>
  908. ";
  909. */
  910. $render['groups_table_top'] = array(
  911. 'value' => "<table border='0' cellpadding='2' width='100%' class='admin-groups-list'>
  912. <tr>
  913. <th>" . t("Title") . "</th>
  914. <th>" . t("Internal Name") . "</th>
  915. <th align='center'>Pri</th>
  916. <th align='center'>i</th>
  917. <th align='center'>" . t("Used") . "</th>
  918. </tr>",
  919. );
  920. $on_mouse_over = " onmouseover=\"style.backgroundColor='#FFFF99'\"
  921. onmouseout=\"style.backgroundColor='white'\" ";
  922. $res = db_query("SELECT * FROM draft_groups
  923. WHERE catalog_year = '?'
  924. AND delete_flag = '0'
  925. ORDER BY title, group_name ", $de_catalog_year);
  926. while($cur = db_fetch_array($res)) {
  927. extract($cur, 3, "db");
  928. $use_count = 0;
  929. // Find out how many degree plans are using this particular group...
  930. $res2 = db_query("SELECT count(id) AS count FROM draft_degree_requirements
  931. WHERE group_id = '?' ", $db_group_id);
  932. if (db_num_rows($res2) > 0) {
  933. $cur2 = db_fetch_array($res2);
  934. $use_count = $cur2["count"];
  935. }
  936. $def_flag = "";
  937. if (trim($db_definition) != "") {
  938. $def_flag = " (*)";
  939. }
  940. if ($db_title == "") {
  941. $db_title = "[" . t("NO TITLE SPECIFIED") . "]";
  942. }
  943. /*
  944. $rtn .= "<tr $on_mouse_over>
  945. <td valign='top' class='tenpt'><a name='group_$db_group_id'></a>
  946. " . l($db_title, "admin/groups/edit-group", "group_id=$db_group_id&de_catalog_year=$de_catalog_year") . "
  947. </td>
  948. <td valign='top' class='tenpt'>
  949. <i>$db_group_name</i>$def_flag
  950. </td>
  951. <td valign='top' class='tenpt'>
  952. $db_priority
  953. </td>
  954. <td valign='top' class='tenpt'>
  955. <img src='" . fp_theme_location() . "/images/icons/$db_icon_filename' width='19'>
  956. </td>
  957. <td valign='top' class='tenpt'>
  958. $use_count <a href='javascript: adminPopupWindow(\"" . fp_url("admin/groups/popup-show-group-use", "group_id=$db_group_id") . "\");'><img src='" . fp_theme_location() . "/images/popup.gif' border='0'></a>
  959. </td>
  960. </tr>";
  961. */
  962. $render['group_row_' . $db_group_id] = array(
  963. 'value' => "<tr $on_mouse_over>
  964. <td valign='top' class='tenpt'><a name='group_$db_group_id'></a>
  965. " . l($db_title, "admin/groups/edit-group", "group_id=$db_group_id&de_catalog_year=$de_catalog_year") . "
  966. </td>
  967. <td valign='top' class='tenpt'>
  968. <i>$db_group_name</i>$def_flag
  969. </td>
  970. <td valign='top' class='tenpt'>
  971. $db_priority
  972. </td>
  973. <td valign='top' class='tenpt'>
  974. <img src='" . fp_theme_location() . "/images/icons/$db_icon_filename' width='19'>
  975. </td>
  976. <td valign='top' class='tenpt'>
  977. $use_count <a href='javascript: adminPopupWindow(\"" . fp_url("admin/groups/popup-show-group-use", "group_id=$db_group_id") . "\");'><img src='" . fp_theme_location() . "/images/popup.gif' border='0'></a>
  978. </td>
  979. </tr>
  980. ",
  981. 'data' => array(
  982. 'group_id' => $db_group_id,
  983. 'db_row' => $cur,
  984. 'use_count' => $use_count,
  985. 'def_flag' => $def_flag,
  986. ),
  987. );
  988. }
  989. $render['groups_table_bottom'] = array(
  990. 'value' => "</table>",
  991. );
  992. $rtn .= fp_render_content($render);
  993. return $rtn;
  994. }
  995. function admin_process_all_definitions_form() {
  996. $form = array();
  997. $de_catalog_year = admin_get_de_catalog_year();
  998. fp_set_title(t("Process all group definitions and settings for @year", array("@year" => $de_catalog_year)));
  999. $m = 0;
  1000. $form["mark" . $m++] = array(
  1001. "type" => "markup",
  1002. "value" => t("This will cause all of the groups with definitions and other settings (ex: catalog repeats) to be cleared, and their
  1003. course requirements re-processed. This function can take several minutes, depending
  1004. on how many groups with definitions you have."),
  1005. );
  1006. $form["de_catalog_year"] = array(
  1007. "type" => "hidden",
  1008. "value" => $de_catalog_year,
  1009. );
  1010. $form["submit"] = array(
  1011. "type" => "submit",
  1012. "value" => t("Process groups"),
  1013. "description" => t("Can take several minutes to run. Only click once!"),
  1014. );
  1015. return $form;
  1016. }
  1017. /**
  1018. * Actually perform the refreshing of definitions.
  1019. */
  1020. function admin_process_all_definitions_form_submit($form, $form_submit) {
  1021. $values = $form_submit["values"];
  1022. $db = get_global_database_handler();
  1023. $de_catalog_year = $values["de_catalog_year"];
  1024. // Okay, set up the batch....
  1025. $batch = array(
  1026. "operation" => array("admin_process_all_definitions_perform_batch_operation", array($de_catalog_year)),
  1027. "title" => t("Process all group definitions & settings for %year", array("%year" => $de_catalog_year)),
  1028. "file" => menu_get_module_path("admin") . "/admin.groups.inc",
  1029. "progress_message" => "Processing group @current of @total",
  1030. "display_percent" => TRUE,
  1031. );
  1032. // Set the batch...
  1033. batch_set($batch);
  1034. /*
  1035. // This function will go through every group for this year and
  1036. // re-run it's definition, saving the result.
  1037. // First, find every group which has a definition set.
  1038. $res = db_query("SELECT * FROM draft_groups
  1039. WHERE definition != ''
  1040. AND catalog_year = '?'
  1041. AND delete_flag = 0 ", $de_catalog_year);
  1042. while($cur = db_fetch_array($res)) {
  1043. $def = $cur["definition"];
  1044. $group_id = $cur["group_id"];
  1045. $group_name = $cur["group_name"];
  1046. $temp = admin_get_courses_from_definition($def);
  1047. $courses = trim($temp["text"]);
  1048. $ccount = 0;
  1049. fp_add_message(t("Working on %name", array("%name" => $group_name)));
  1050. // Remove all the existing group requirements for this group first.
  1051. $res2 = db_query("DELETE FROM draft_group_requirements
  1052. WHERE group_id = ? ", $group_id);
  1053. $lines = explode("\n", $courses);
  1054. for ($t = 0; $t < count($lines); $t++) {
  1055. $line = trim($lines[$t]);
  1056. if ($line == "") { continue; }
  1057. // Get rid of extra whitespace.
  1058. $line = str_replace(" ", " ", $line);
  1059. $line = str_replace(" ", " ", $line);
  1060. $line = str_replace(" ", " ", $line);
  1061. // Does this line contain at least one & symbol? If it does,
  1062. // then this is a subgroup (branch). If not, then we can insert
  1063. // the course as-is.
  1064. if (!strstr($line, "&")) {
  1065. // Did NOT contain an ampersand (&), so this goes in the
  1066. // regular course requirements.
  1067. $tokens = explode(" ", $line);
  1068. $subject_id = trim($tokens[0]);
  1069. $course_num = trim($tokens[1]);
  1070. @$min_grade = trim($tokens[2]);
  1071. @$course_repeats = trim($tokens[3]);
  1072. if (strstr($min_grade, "[")) {
  1073. // This is actually a specified repeat, not a min grade.
  1074. $course_repeats = $min_grade;
  1075. $min_grade = "";
  1076. }
  1077. $min_grade = str_replace("(","",$min_grade);
  1078. $min_grade = strtoupper(str_replace(")","",$min_grade));
  1079. $course_repeats = str_replace("[","",$course_repeats);
  1080. $course_repeats = str_replace("]","",$course_repeats);
  1081. $course_repeats--;
  1082. if ($course_repeats < 0) { $course_repeats = 0; }
  1083. // If the subject_id had a _A_ in it, convert this back
  1084. // to an ampersand.
  1085. $subject_id = str_replace("_A_", "&", $subject_id);
  1086. // We don't care about catalog year anymore...
  1087. if ($course_id = $db->get_course_id($subject_id, $course_num, "", true)) {
  1088. $query = "INSERT INTO draft_group_requirements
  1089. (`group_id`,`course_id`,
  1090. `course_min_grade`,`course_repeats`,`data_entry_value`)
  1091. values (?, ?, ?, ?, ?) ";
  1092. $res2 = db_query($query, $group_id, $course_id, $min_grade, $course_repeats, "$subject_id~$course_num");
  1093. $ccount++;
  1094. }
  1095. else {
  1096. // The course_id could not be found!
  1097. fp_add_message(t("Course not found! You specified %course as a requirement in %gname,
  1098. but this course could not be found in the catalog. It was removed from
  1099. the list of requirements. Are you sure you typed it correctly? Please
  1100. check your spelling, and add the course again.", array("%course" => "$subject_id $course_num", "%gname" => $group_name)), "error");
  1101. }
  1102. }
  1103. }
  1104. fp_add_message(t("%name definition processed. %count courses added.", array("%name" => $group_name, "%count" => $ccount)));
  1105. }
  1106. fp_add_message(t("Group definitions have been re-run for @year", array("@year" => $de_catalog_year)));
  1107. */
  1108. }
  1109. /**
  1110. * This actually is the batch operation for processing all of our group definitions.
  1111. */
  1112. function admin_process_all_definitions_perform_batch_operation(&$batch, $de_catalog_year) {
  1113. //////////////////////////// FIRST TIME ///////////////////////////////
  1114. // If this is our first time through, let's init our values.
  1115. if (!isset($batch["results"]["total"])) {
  1116. // Our first time through. Let's start up.
  1117. $batch["results"]["current"] = 0;
  1118. $batch["results"]["finished"] = FALSE;
  1119. // Change to count how many groups with definitions OR "catalog_repeat" set.
  1120. // We need a count of how many groups in this year have definitions to process.
  1121. $res = db_query("SELECT count(*) as `count` FROM draft_groups
  1122. WHERE (definition != '' OR catalog_repeat = 1)
  1123. AND catalog_year = '?'
  1124. AND delete_flag = 0 ", $de_catalog_year);
  1125. $cur = db_fetch_array($res);
  1126. $batch["results"]["total"] = $cur["count"];
  1127. }
  1128. ////////////////////////////////////////////////////////////////////////
  1129. // Okay, we can now begin the actual batch process.
  1130. $current = $batch["results"]["current"];
  1131. $total = $batch["results"]["total"];
  1132. $limit = 1; // how many definitions to process per run of THIS function
  1133. $c = 0; // count of records.
  1134. $db = get_global_database_handler();
  1135. // Change to count how many groups with definitions OR "catalog_repeat" set.
  1136. // First, find every group which has a definition set.
  1137. $res = db_query("SELECT * FROM draft_groups
  1138. WHERE (definition != '' OR catalog_repeat = 1)
  1139. AND catalog_year = '?'
  1140. AND delete_flag = 0
  1141. limit $current, $limit", $de_catalog_year);
  1142. while($cur = db_fetch_array($res)) {
  1143. if ($c >= $limit) {
  1144. break;
  1145. }
  1146. $def = trim($cur["definition"]);
  1147. $group_id = $cur["group_id"];
  1148. $group_name = $cur["group_name"];
  1149. $catalog_repeat = intval($cur['catalog_repeat']);
  1150. // Only do definitions if there IS a definition.
  1151. if ($def != "") {
  1152. $temp = admin_get_courses_from_definition($def);
  1153. $courses = trim($temp["text"]);
  1154. }
  1155. else {
  1156. // If there are no definitions, assemble a $courses string. admin_get_group_courses(Group $group)
  1157. $g = new Group($group_id, null, -1, false, true); // make sure we are loading from draft.
  1158. $courses = admin_get_group_courses($g);
  1159. }
  1160. // If the catalog_repeat flag is set, process that.
  1161. if ($catalog_repeat == 1) {
  1162. $courses = admin_process_catalog_repeats_for_group_courses_text($courses, $de_catalog_year);
  1163. }
  1164. $ccount = 0;
  1165. fp_add_message(t("Working on %name", array("%name" => $group_name)));
  1166. // We need to delete all the existing course & subgroup requirements from this group.
  1167. // That entails first seeing what subgroups were required and deleting them,
  1168. // then deleting the parent group's requirements.
  1169. // First, find and delete the branches (child groups):
  1170. $res2 = db_query("SELECT * FROM draft_group_requirements
  1171. WHERE group_id = ?
  1172. AND child_group_id != '0' ", $group_id);
  1173. while ($cur2 = db_fetch_array($res2)) {
  1174. $cg_id = $cur2["child_group_id"];
  1175. $res22 = db_query("DELETE FROM draft_group_requirements
  1176. WHERE group_id = ? ", $cg_id);
  1177. }
  1178. // Now delete the course requirements...
  1179. $res2 = db_query("DELETE FROM draft_group_requirements
  1180. WHERE group_id = ? ", $group_id);
  1181. $lines = explode("\n", $courses);
  1182. for ($t = 0; $t < count($lines); $t++) {
  1183. $line = trim($lines[$t]);
  1184. if ($line == "") { continue; }
  1185. // Get rid of extra whitespace.
  1186. $line = str_replace(" ", " ", $line);
  1187. $line = str_replace(" ", " ", $line);
  1188. $line = str_replace(" ", " ", $line);
  1189. // Does this line contain at least one & symbol? If it does,
  1190. // then this is a subgroup (branch). If not, then we can insert
  1191. // the course as-is.
  1192. if (!strstr($line, "&")) {
  1193. // Did NOT contain an ampersand (&), so this goes in the
  1194. // regular course requirements.
  1195. $tokens = explode(" ", $line);
  1196. $subject_id = trim($tokens[0]);
  1197. $course_num = trim($tokens[1]);
  1198. @$min_grade = trim($tokens[2]);
  1199. @$course_repeats = trim($tokens[3]);
  1200. if (strstr($min_grade, "[")) {
  1201. // This is actually a specified repeat, not a min grade.
  1202. $course_repeats = $min_grade;
  1203. $min_grade = "";
  1204. }
  1205. $min_grade = str_replace("(","",$min_grade);
  1206. $min_grade = strtoupper(str_replace(")","",$min_grade));
  1207. $course_repeats = str_replace("[","",$course_repeats);
  1208. $course_repeats = str_replace("]","",$course_repeats);
  1209. $course_repeats--;
  1210. if ($course_repeats < 0) { $course_repeats = 0; }
  1211. // If the subject_id had a _A_ in it, convert this back
  1212. // to an ampersand.
  1213. $subject_id = str_replace("_A_", "&", $subject_id);
  1214. // We don't care about catalog year anymore...
  1215. if ($course_id = $db->get_course_id($subject_id, $course_num, "", true)) {
  1216. $query = "INSERT INTO draft_group_requirements
  1217. (`group_id`,`course_id`,
  1218. `course_min_grade`,`course_repeats`,`data_entry_value`)
  1219. values (?, ?, ?, ?, ?) ";
  1220. $res2 = db_query($query, $group_id, $course_id, $min_grade, $course_repeats, "$subject_id~$course_num");
  1221. $ccount++;
  1222. }
  1223. else {
  1224. // The course_id could not be found!
  1225. fp_add_message(t("Course not found! You specified %course as a requirement in %gname,
  1226. but this course could not be found in the catalog. It was removed from
  1227. the list of requirements. Are you sure you typed it correctly? Please
  1228. check your spelling, and add the course again.", array("%course" => "$subject_id $course_num", "%gname" => $group_name)), "error");
  1229. }
  1230. } // if line does not contain &
  1231. else {
  1232. // ELSE, this was a branch! Insert it as well.
  1233. // This line DOES have an ampersand (&), so this is a sub group
  1234. // within this group.
  1235. // First, we need to request a new branchID for this new group.
  1236. if (!$branch_id = $db->request_new_group_id()) {
  1237. die ("Error. Could not create new group (branch) ID.");
  1238. }
  1239. else {
  1240. // Add this branch to the list of requirements for this group.
  1241. $query = "INSERT INTO draft_group_requirements
  1242. (group_id, child_group_id)
  1243. values ('?','?') ";
  1244. $res2 = db_query($query, $group_id, $branch_id);
  1245. }
  1246. $c_tokes = explode("&",$line);
  1247. for ($cT = 0; $cT < count($c_tokes); $cT++)
  1248. {
  1249. $tokens = explode(" ", trim($c_tokes[$cT]));
  1250. $subject_id = trim($tokens[0]);
  1251. $course_num = trim($tokens[1]);
  1252. $min_grade = @trim($tokens[2]);
  1253. $course_repeats = @trim($tokens[3]);
  1254. if (strstr($min_grade, "[")) {
  1255. // This is actually a specified repeat, not a min grade.
  1256. $course_repeats = $min_grade;
  1257. $min_grade = "";
  1258. }
  1259. $min_grade = str_replace("(","",$min_grade);
  1260. $min_grade = str_replace(")","",$min_grade);
  1261. $course_repeats = str_replace("[","",$course_repeats);
  1262. $course_repeats = str_replace("]","",$course_repeats);
  1263. $course_repeats--;
  1264. if ($course_repeats < 0) { $course_repeats = 0; }
  1265. // If the subject_id had a _A_ in it, convert this back
  1266. // to an ampersand.
  1267. $subject_id = str_replace("_A_", "&", $subject_id);
  1268. // Commenting out, because we do not care about catalog_year
  1269. // when specifying courses...
  1270. if ($course_id = $db->get_course_id($subject_id, $course_num, "", true)) {
  1271. $query = "INSERT INTO draft_group_requirements
  1272. (group_id, course_id,
  1273. course_min_grade, course_repeats, data_entry_value)
  1274. values ('?','?','?','?', ?) ";
  1275. $res2 = db_query($query, $branch_id, $course_id, $min_grade, $course_repeats, "$subject_id~$course_num");
  1276. }
  1277. else {
  1278. // The course_id could not be found!
  1279. fp_add_message(t("Course not found! You specified %course as a requirement in %gname,
  1280. but this course could not be found in the catalog. It was removed from
  1281. the list of requirements. Are you sure you typed it correctly? Please
  1282. check your spelling, and add the course again.", array("%course" => "$subject_id $course_num", "%gname" => $group_name)), "error");
  1283. }
  1284. } // for $cT
  1285. } // else it does contain &
  1286. } // for t < count lines
  1287. fp_add_message(t("%name processed. %count courses added.", array("%name" => $group_name, "%count" => $ccount)) . "<br><br>");
  1288. $c++;
  1289. } // while cur = db_fetch_array($res)
  1290. // Update our $batch results variables
  1291. $batch["results"]["current"] = $current + $c;
  1292. if ($batch["results"]["current"] >= $total) {
  1293. // We are finished!
  1294. $batch["results"]["finished"] = TRUE;
  1295. fp_add_message("<br><br><br>" . t("Group definitions have been processed for %year", array("%year" => $de_catalog_year)));
  1296. }
  1297. } // admin_process....batch_operation
  1298. /**
  1299. * Displays a popup showing where a particular group is being used in FlightPath.
  1300. */
  1301. function admin_display_groups_popup_show_group_use() {
  1302. $rtn = "";
  1303. $group_id = $_REQUEST["group_id"];
  1304. $group = new Group();
  1305. $group->group_id = $group_id;
  1306. $group->bool_use_draft = true;
  1307. $group->load_descriptive_data();
  1308. $rtn .= "<b>" . t("Degrees using @group_title (%group_name):", array("@group_title"=>$group->title, "%group_name" => $group->group_name)) . "</b>
  1309. <br><br>
  1310. <table border='0' cellspacing='5'>
  1311. <tr>
  1312. <th>" . t("Degree") . "</th>
  1313. <th>" . t("Code") . "</th>
  1314. <th>" . t("Semester") . "</th>
  1315. <th>" . t("Year") . "</th>
  1316. </tr>
  1317. ";
  1318. $res = db_query("SELECT * FROM draft_degrees a,
  1319. draft_degree_requirements b
  1320. WHERE a.degree_id = b.degree_id
  1321. AND b.group_id = '?'
  1322. ORDER BY a.title, a.major_code, b.semester_num ", $group_id);
  1323. while($cur = db_fetch_array($res))
  1324. {
  1325. extract($cur, 3, "db");
  1326. $rtn .= "<tr>
  1327. <td valign='top' class='tenpt' width='200'>
  1328. $db_title
  1329. </td>
  1330. <td valign='top' class='tenpt' width='100'>
  1331. $db_major_code
  1332. </td>
  1333. <td valign='top' class='tenpt' align='center'>
  1334. " . admin_get_semester_name($db_semester_num) . "
  1335. </td>
  1336. <td valign='top' class='tenpt' width='100'>
  1337. $db_catalog_year
  1338. </td>
  1339. </tr>
  1340. ";
  1341. }
  1342. $rtn .= "</table>";
  1343. return $rtn;
  1344. }

Functions

Namesort descending Description
admin_array_diff I 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_groups This function will display a list of all our groups.
admin_display_groups_popup_edit_definition
admin_display_groups_popup_select_icon This 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_use Displays a popup showing where a particular group is being used in FlightPath.
admin_edit_group_form This function lets the user edit a group.
admin_edit_group_form_submit
admin_edit_group_form_validate Validate handler for edit group form.
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_courses Return back the courses in a group, suitable for the edit-group form.
admin_process_all_definitions_form
admin_process_all_definitions_form_submit Actually perform the refreshing of definitions.
admin_process_all_definitions_perform_batch_operation This actually is the batch operation for processing all of our group definitions.
admin_process_catalog_repeats_for_group_courses_text This function will accept the $courses text (textarea) from a group, which spells out all of the courses, and then assign specified repeats based on what is set for that course in the course catalog.