audit.module

  1. 7.x modules/audit/audit.module
  2. 6.x modules/audit/audit.module

This is the Audit module, which provides functionality relating to degree audits.

File

modules/audit/audit.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * This is the Audit module, which provides functionality relating to degree audits.
  5. */
  6. /**
  7. * Implementation of hook_menu
  8. *
  9. */
  10. function audit_menu() {
  11. $items = array();
  12. $items["audit"] = array(
  13. "title" => "Audit",
  14. "page_callback" => "audit_display_audit",
  15. "access_callback" => "audit_can_access_audit", //should the audit tab show up right now, for this user?
  16. "tab_family" => "system",
  17. "page_settings" => array (
  18. "display_currently_advising" => TRUE,
  19. ),
  20. "weight" => 100,
  21. "type" => MENU_TYPE_TAB,
  22. );
  23. // Settings screen
  24. $items["admin/config/audit-settings"] = array(
  25. "title" => "Audit settings",
  26. "description" => "Configure settings for the Audit tab",
  27. "page_callback" => "fp_render_form",
  28. "page_arguments" => array("audit_settings_form", "system_settings"),
  29. "access_arguments" => array("administer_audit"),
  30. "page_settings" => array(
  31. "page_hide_report_error" => TRUE,
  32. "menu_links" => array(
  33. 0 => array(
  34. "text" => "Admin Console",
  35. "path" => "admin-tools/admin",
  36. ),
  37. ),
  38. "menu_icon" => fp_get_module_path('system') . "/icons/report.png",
  39. ),
  40. "type" => MENU_TYPE_NORMAL_ITEM,
  41. "tab_parent" => "admin-tools/admin",
  42. );
  43. // The edit-approval popup...
  44. // audit/popup-edit-approval/TYPE/STUDENT CWID
  45. $items["audit/popup-edit-approval/%/%"] = array(
  46. "title" => "Edit Approval",
  47. "page_callback" => "fp_render_form",
  48. "page_arguments" => array("audit_popup_edit_approval_form", "normal", 2, 3),
  49. "access_arguments" => array("edit_audit_approvals"),
  50. "page_settings" => array(
  51. "page_is_popup" => TRUE,
  52. "page_hide_report_error" => TRUE,
  53. ),
  54. "type" => MENU_TYPE_CALLBACK,
  55. );
  56. return $items;
  57. }
  58. function audit_settings_form($school_id = 0) {
  59. $form = array();
  60. $school_id = intval($school_id);
  61. $fs = ""; // The field name suffix. We will add this to the end of all of our field names. If this is the default school, leave blank.
  62. if (module_enabled("schools")) {
  63. $school_name = schools_get_school_name_for_id($school_id);
  64. fp_set_title(t("Configure %school Audit settings", array('%school' => $school_name)));
  65. if ($school_id !== 0) {
  66. $fs = "~~school_" . $school_id;
  67. }
  68. }
  69. $form['school_id'] = array(
  70. 'type' => 'hidden',
  71. 'value' => $school_id,
  72. );
  73. $form["audit_approval_types" . $fs] = array(
  74. "label" => t("Enter approval type definitions, one per line:"),
  75. "type" => "textarea",
  76. "rows" => 10,
  77. "value" => variable_get_for_school("audit_approval_types", "coursework ~ Coursework\nmajor_gpa ~ Major GPA\ngraduation_gpa ~ Graduation GPA", $school_id, TRUE),
  78. "description" => t("Enter definitions for the approval types, one per line, like so:
  79. <br>&nbsp;&nbsp;&nbsp; TYPE ~ Title ~ Description
  80. <br>- The TYPE must be unique, and contain ONLY letters, numbers, and underscore (_), and must be no more than 60 characters long. Ex: coursework
  81. <br>- The Title should be relatively short, but has no character limit. Ex: Coursework Requirement
  82. <br>- The Description can be any length, but contain NO line breaks. It can, however, contain HTML.
  83. <br>
  84. <b>You may skip lines between definitions.</b>
  85. <br>Example:
  86. <br>
  87. &nbsp;&nbsp;&nbsp; coursework ~ Coursework ~ The student must complete all coursework.
  88. <br>&nbsp;&nbsp;&nbsp; major_gpa ~ Major GPA ~ The student's major GPA should be at least 2.5.
  89. <br>&nbsp;&nbsp;&nbsp; graduation_gpa ~ Graduation GPA ~ The student's graduation GPA must be at least 2.5."),
  90. );
  91. $school_initials = variable_get_for_school("school_initials", "DEMO", $school_id);
  92. $form["audit_requirement_types" . $fs] = array(
  93. "label" => t("Enter requirement types & labels to display on Audit tab, one per line:"),
  94. "type" => "textarea",
  95. "rows" => 15,
  96. "value" => variable_get_for_school("audit_requirement_types", "g ~ General Requirements\nc ~ Core\nm ~ Major\ndegree ~ Degree", $school_id, TRUE),
  97. "description" => "Enter definitions for the requirement types to display, one per line, like so:
  98. <br>&nbsp;&nbsp;&nbsp; type_code ~ Label
  99. <br>The type_code is one of the 'requirement types' that a course can be defined as. Ex: m, c, etc.
  100. <br><b>Important:</b> The pseudo-code 'degree' must be defined, and it will display totals for the entire degree.
  101. <br><b>Important:</b> To see ONLY local (non-transfer) courses, add _local to the end of the type code. Ex: c_local for Core, not fulfilled by transfer credits.
  102. <br>
  103. For ex:
  104. <br>
  105. &nbsp;&nbsp;&nbsp;g ~ General Requirements
  106. <br>&nbsp;&nbsp;&nbsp;c ~ Core
  107. <br>&nbsp;&nbsp;&nbsp;m ~ Major
  108. <br>&nbsp;&nbsp;&nbsp;degree ~ Degree
  109. <br>&nbsp;&nbsp;&nbsp;c_local ~ Core ($school_initials Courses)
  110. <br>&nbsp;&nbsp;&nbsp;degree_local ~ Degree ($school_initials Courses)
  111. <br>
  112. <b>To insert a BLANK row</b>, for appearances on the Audit tab,
  113. give the entry a unique type_code, and set the label to BLANK (all caps).
  114. Ex:
  115. <br> &nbsp;&nbsp;&nbsp;BLANK_1 ~ BLANK
  116. <br> &nbsp;&nbsp;&nbsp;BLANK_2 ~ BLANK
  117. ",
  118. );
  119. return $form;
  120. }
  121. function audit_settings_form_validate($form, $form_state) {
  122. // The main thing I want to do here is make sure that the key_codes are acceptable machine names.
  123. $val = $form_state["values"]["audit_approval_types"];
  124. $lines = explode("\n", $val);
  125. foreach ($lines as $line) {
  126. if (trim($line) == "") continue;
  127. $temp = explode("~", $line);
  128. $key = trim($temp[0]);
  129. $desc = trim($temp[1]);
  130. // Make sure key and desc both have values.
  131. if (strlen($key) < 2 || strlen($desc) < 2) {
  132. form_error("audit_approval_types", t("KEY_CODEs and Descriptions must be at least 2 characters long. Please revise."));
  133. return;
  134. }
  135. if (strlen($key) > 40) {
  136. form_error("audit_approval_types", t("KEY_CODEs may not be longer than 40 characters. Please revise."));
  137. return;
  138. }
  139. // Make sure that key_code is machine name.
  140. if (fp_get_machine_readable($key) != $key) {
  141. form_error("audit_approval_types", t("KEY_CODEs must only contain letters, numbers, and underscores (_). Please revise."));
  142. return;
  143. }
  144. }
  145. }
  146. /**
  147. * Return an assoc array of approval types.
  148. *
  149. */
  150. function audit_get_approval_types($school_id = 0) {
  151. $rtn = array();
  152. $val = variable_get_for_school("audit_approval_types", "coursework ~ Coursework\nmajor_gpa ~ Major GPA\ngraduation_gpa ~ Graduation GPA", '', $school_id);
  153. $lines = explode("\n", $val);
  154. foreach ($lines as $line) {
  155. if (trim($line) == "") continue;
  156. $temp = explode("~", $line);
  157. $key = trim($temp[0]);
  158. $title = trim($temp[1]);
  159. @$desc = trim($temp[2]);
  160. $rtn[$key] = array (
  161. "title" => $title,
  162. "description" => $desc,
  163. );
  164. }
  165. // invoke hook to modify approval types, defined by other modules.
  166. $params = array(&$rtn, $school_id);
  167. invoke_hook('audit_modify_approval_types', $params);
  168. return $rtn;
  169. }
  170. function audit_get_approval_record($student_id, $approval_type) {
  171. $res = db_query("SELECT * FROM audit_approvals
  172. WHERE student_id = '?'
  173. AND approval_type = '?' ", $student_id, $approval_type);
  174. $cur = db_fetch_array($res);
  175. return $cur;
  176. }
  177. /**
  178. * Returns a simple array of the available approval options in the popup.
  179. *
  180. *
  181. */
  182. function audit_get_approval_options() {
  183. return array("not_complete" => t("Not Complete"), "in_progress" => t("In Progress"), "complete" => t("Complete"), "not_applicable" => t("Not Applicable"));
  184. }
  185. /**
  186. * This is the actual form that will be used to change an audit approval for a student.
  187. *
  188. * @param unknown_type $approval_type
  189. * @param unknown_type $student_id
  190. */
  191. function audit_popup_edit_approval_form($approval_type, $student_id) {
  192. $form = array();
  193. fp_add_css(fp_get_module_path("audit") . "/css/audit.css");
  194. fp_add_js(fp_get_module_path("audit") . "/js/audit.js");
  195. $school_id = db_get_school_id_for_student_id($student_id);
  196. $types = audit_get_approval_types($school_id);
  197. $details = $types[$approval_type];
  198. $approval_type_title = $details["title"];
  199. if ($approval_type_title == "") $approval_type_title = $approval_type;
  200. fp_set_title("Edit approval for " . fp_get_student_name($student_id) . " ($student_id)");
  201. // Get current value from the database
  202. $current_value = "";
  203. $cur = audit_get_approval_record($student_id, $approval_type);
  204. if ($cur && isset($cur['approval_value'])) {
  205. $current_value = $cur["approval_value"];
  206. }
  207. if ($current_value == "") $current_value = "not_complete";
  208. $options = audit_get_approval_options();
  209. $options["in_progress"] = t("In Progress - will be completed when the student's enrolled courses are completed");
  210. $form["approval"] = array(
  211. "type" => "radios",
  212. "label" => t("Please set the completion status for this type:<br><em style='padding-left: 20px;'>$approval_type_title</em>"),
  213. "options" => $options,
  214. "value" => $current_value,
  215. "no_please_select" => TRUE,
  216. /*
  217. "description" => "Legend:<div style='padding-left: 10px;'>Complete - The requirement has been completed.
  218. <br>Not Complete - The requirement has not been completed yet.
  219. <br>In Progress - The requirement will be completed when the student's enrolled courses are completed.",
  220. */
  221. );
  222. $form["comment"] = array(
  223. "type" => "textarea",
  224. "label" => t("Optional comment:"),
  225. "rows" => 3,
  226. "attributes" => array("style" => "width: 90%;"),
  227. "description" => t("When you save this form, a brief entry will be made to the audit comment history.
  228. If you wish, you may add an optional comment at this time to explain your
  229. selection."),
  230. );
  231. $form["submit_btn"] = array(
  232. "type" => "submit",
  233. "value" => "Submit",
  234. );
  235. $form["#attributes"] = array("onSubmit" => "return auditPopupEditApprovalFormSubmit(\"$approval_type\",\"$student_id\");");
  236. watchdog("audit", "popup_edit_approval student_id:$student_id, approval_type:$approval_type", array(), WATCHDOG_DEBUG);
  237. return $form;
  238. }
  239. function audit_display_audit() {
  240. global $current_student_id, $user, $fp, $degree_plan, $screen;
  241. fp_set_title('');
  242. $rtn = "";
  243. fp_add_css(fp_get_module_path("comments") . "/css/comments.css");
  244. fp_add_css(fp_get_module_path("audit") . "/css/audit.css");
  245. fp_add_js(fp_get_module_path("audit") . "/js/audit.js");
  246. // We will re-use code from the advise module, to pre-initialize all of our information for the student.
  247. $temp = advise_display_view();
  248. // We will get rid of the sub tabs and other values we've added.
  249. fp_set_page_sub_tabs(array());
  250. $screen->screen_mode = "not_advising"; // do this so the mini profile doesn't get any options added to it from the advise module.
  251. $student = $fp->student;
  252. $school_id = $student->school_id;
  253. // Get this from settings
  254. $audit_requirement_types = array();
  255. $tlines = explode("\n", variable_get_for_school("audit_requirement_types", "g ~ General Requirements\nc ~ Core\nm ~ Major\ndegree ~ Degree", '', $school_id));
  256. foreach ($tlines as $tline) {
  257. $temp = explode("~", trim($tline));
  258. if (trim($temp[0]) != "") {
  259. $audit_requirement_types[trim($temp[0])] = trim($temp[1]);
  260. }
  261. }
  262. $pol = "";
  263. $rtn .= " <table class='audit-table'> ";
  264. $degree_plan->calculate_progress_hours(TRUE);
  265. $degree_plan->calculate_progress_quality_points(TRUE);
  266. foreach ($degree_plan->gpa_calculations as $gpa_degree_id => $gpa_details) {
  267. if ($gpa_degree_id == 0) {
  268. // This is "overall"
  269. $rtn .= "<tr class='audit-req audit-req-new-degree-title audit-row-$pol audit-req-degree-title-OVERALL'>
  270. <td colspan='3'>" . t("Overall:") . "</td>
  271. </tr>";
  272. $pol = ""; // start over after a blank row
  273. }
  274. else {
  275. // This is a degree.
  276. $dtitle = fp_get_degree_title($gpa_degree_id, TRUE, TRUE);
  277. $rtn .= "<tr class='audit-req audit-req-new-degree-title audit-row-$pol audit-req-degree-title-member-degree'>
  278. <td colspan='3'>$dtitle:</td>
  279. </tr>";
  280. $pol = ""; // start over after a blank row
  281. }
  282. foreach ($audit_requirement_types as $type => $desc) {
  283. $gpa = "";
  284. if ($pol != "even") {
  285. $pol = "even";
  286. }
  287. else {
  288. $pol = "odd";
  289. }
  290. if (@$degree_plan->gpa_calculations[$gpa_degree_id][$type]["qpts_hours"] > 0) {
  291. $gpa = fp_truncate_decimals($degree_plan->gpa_calculations[$gpa_degree_id][$type]["qpts"] / $degree_plan->gpa_calculations[$gpa_degree_id][$type]["qpts_hours"], 3);
  292. }
  293. $percent = "0";
  294. if (@$degree_plan->gpa_calculations[$gpa_degree_id][$type]["total_hours"] > 0) {
  295. $percent = fp_truncate_decimals(($degree_plan->gpa_calculations[$gpa_degree_id][$type]["fulfilled_hours"] / $degree_plan->gpa_calculations[$gpa_degree_id][$type]["total_hours"]) * 100, 2);
  296. }
  297. // Are we trying to judt have a blank row?
  298. if ($desc == "BLANK") { // if description is BLANK, then yes, make this row blank.
  299. $rtn .= "<tr class='audit-req audit-req-BLANK audit-row-$pol audit-row-blank'>
  300. <td colspan='3'>&nbsp; &nbsp;</td>
  301. </tr>";
  302. $pol = ""; // start over after a blank row
  303. continue;
  304. }
  305. // Okay, let's display our row normally now:
  306. $rtn .= "
  307. <tr class='audit-req audit-req-$type audit-row-$pol'>
  308. <td width='25%'>$desc:</td>
  309. <td class='audit-req-hours-percent'><span class='audit-hours'><span class='audit-completed-hours'>{$degree_plan->gpa_calculations[$gpa_degree_id][$type]["fulfilled_hours"]}</span>
  310. / <span class='audit-total-hours'>{$degree_plan->gpa_calculations[$gpa_degree_id][$type]["total_hours"]} hrs</span>
  311. </span>
  312. <span class='audit-percent-completed'>($percent%)</span>
  313. </td>
  314. <td class='audit-req-gpa'>GPA: $gpa ({$degree_plan->gpa_calculations[$gpa_degree_id][$type]["qpts"]} qpts
  315. / {$degree_plan->gpa_calculations[$gpa_degree_id][$type]["qpts_hours"]} qhrs)</td>
  316. </tr>";
  317. } // foreach audit_requirements
  318. } // foreach degreeplan->gpa_calculations
  319. // invoke hook to check for more "overall" / calculations information for audit tab
  320. $res = invoke_hook('audit_get_additional_overall_calculations', array($student, $school_id));
  321. if (is_array($res) && count($res) > 0) {
  322. $pol = "";
  323. $rtn .= "<tr class='audit-req audit-req-new-degree-title audit-row-$pol audit-req-degree-title-OVERALL'>
  324. <td colspan='3'>" . t("Additional:") . "</td>
  325. </tr>";
  326. foreach ($res as $module_name => $thow_away) {
  327. if (isset($res[$module_name]) && is_array($res[$module_name])) {
  328. foreach ($res[$module_name] as $c => $calcs) {
  329. if ($pol != "even") {
  330. $pol = "even";
  331. }
  332. else {
  333. $pol = "odd";
  334. }
  335. $title = $calcs['title'];
  336. $sec_1 = $calcs['section_1_html'];
  337. $sec_2 = $calcs['section_2_html'];
  338. $rtn .= "
  339. <tr class='audit-req audit-req-additional-from-hook audit-row-$pol'>
  340. <td width='25%'>$title</td>
  341. <td class='audit-req-hours-percent'>$sec_1</td>
  342. <td class='audit-req-gpa'>$sec_2</td>
  343. </tr>";
  344. }
  345. }
  346. }
  347. // Add a blank row at the end to make it easier to read.
  348. $rtn .= "<tr class='audit-req audit-req-BLANK audit-row-$pol '>
  349. <td colspan='3'>&nbsp; &nbsp;</td>
  350. </tr>";
  351. $pol = ""; // start over after a blank row
  352. }
  353. $rtn .= "
  354. <tr>
  355. <td valign='top'>Footnotes & Messages:</td>
  356. <td colspan='2'><table border='0' width='100%'>
  357. " . $screen->build_footnotes(FALSE) . "
  358. </table>
  359. </td>
  360. </tr>
  361. ";
  362. $rtn .= "
  363. <tr>
  364. <td valign='top'>Approvals:</td>
  365. <td colspan='2'>
  366. <table border='0' class='approvals' width='100%'>
  367. ";
  368. // Get approval types from our setting
  369. $types = audit_get_approval_types($school_id);
  370. $options = audit_get_approval_options();
  371. // Go through our types, displaying completed or not completed lines...
  372. foreach ($types as $approval_type => $approval_details) {
  373. $approval_title = $approval_details["title"];
  374. $approval_description = $approval_details["description"];
  375. $approval_value = '';
  376. $faculty_id = '';
  377. $posted = 0;
  378. $cur = audit_get_approval_record($student->student_id, $approval_type);
  379. if ($cur) {
  380. $posted = $cur['posted'];
  381. $faculty_id = $cur['faculty_id'];
  382. $approval_value = $cur['approval_value'];
  383. }
  384. $dt = date("m/d/Y", $posted);
  385. $faculty_name = fp_get_faculty_name($faculty_id);
  386. if ($approval_value == "") {
  387. $approval_value = "not_complete";
  388. $dt = $faculty_name = " -- ";
  389. }
  390. $approval_value_desc = $options[$approval_value];
  391. if ($approval_value_desc == "") @$approval_value_desc = $approval_value;
  392. $rtn .= "<tr class='audit-approval-row audit-approval-row-" . $approval_value . "'>";
  393. $rtn .= "
  394. <td><div class='audit-approval-title audit-approval-" . $approval_value . "'>$approval_title</div>
  395. <td class='audit-approval-value audit-approval-desc-" . $approval_value . "'>" . $approval_value_desc . "</td>
  396. <td class='audit-approval-datetime'>" . $dt . "</td>
  397. <td class='audit-approval-faculty'>" . $faculty_name . "</td>";
  398. $rtn .= "
  399. <td>
  400. <a class='approval-edit' href='javascript:popupSmallIframeDialog(\"" . fp_url("audit/popup-edit-approval/$approval_type/$student->student_id") . "\",\"" . t("Edit Approval") . "\",\"\");'><i class='fa fa-pencil'></i> Edit</a>
  401. </td>
  402. ";
  403. $rtn .= "</tr>";
  404. // If the is an approval_description, show it in a new row....
  405. if ($approval_description != "") {
  406. $rtn .= "<tr>
  407. <td colspan='5' class='audit-approval-description audit-approval-description=" . $approval_value . "'><div>$approval_description</div></td>
  408. </tr>";
  409. }
  410. } // foreach types => approval_type
  411. $rtn .= "
  412. </table> <!-- class approvals -->
  413. </td>
  414. </tr>
  415. </table> <!-- class audit-table -->";
  416. $rtn .= "
  417. <hr>
  418. <h2>" . t("Audit Comments") . "</h2>
  419. " . t("These comments will be visible to individuals with access to this tab.") . "
  420. ";
  421. // Add our audit comments form in the page. The extra code is about not making the title show
  422. // up twice.
  423. $temp_title = $GLOBALS["fp_set_title"];
  424. $GLOBALS["fp_set_title"] = ""; // prevent page title from showing up here
  425. $form = fp_render_form("audit_comment_form", "normal", $student->student_id, $user->cwid);
  426. $GLOBALS["fp_set_title"] = $temp_title;
  427. $rtn .= fp_render_c_fieldset($form, t("Click to enter audit comment"), TRUE, 'enter-audit-comment-fs');
  428. $comments = comments_get_comments($student->student_id, FALSE, array("audit private"));
  429. foreach($comments as $comment) {
  430. $delete_link = "";
  431. // Should we present a "delete link" to the user for this comment?
  432. if (user_has_permission("can_delete_own_comments_3_months")) {
  433. // See if this comment is younger than 3 months.
  434. $del_range = strtotime("-3 month");
  435. $then = $comment["posted"];
  436. if ($then > $del_range) {
  437. // We will use the comment module's delete function for this, and tell it to
  438. // redirect back here by setting the destination=audit.
  439. $js_action = 'window.location=FlightPath.settings.basePath + "/comments/delete-comment&current_student_id=' . $student->student_id . '&comment_id=' . $comment['id'] . '&destination=audit";';
  440. $delete_link = fp_get_js_confirm_link(t("Are you sure you wish to delete this comment?\nThis action cannot be undone."), $js_action, "Delete?");
  441. }
  442. }
  443. $rtn .= comments_render_comment($comment, $delete_link);
  444. }
  445. // We wish to add our hidden form, so the approval popup can write its values to this page,
  446. // and then submit them.
  447. $temp_title = $GLOBALS["fp_set_title"];
  448. $GLOBALS["fp_set_title"] = ""; // prevent page title from showing up here
  449. $rtn .= fp_render_form("audit_hidden_approval_form");
  450. $GLOBALS["fp_set_title"] = $temp_title;
  451. watchdog("audit", "display_audit $student->student_id", array());
  452. return $rtn;
  453. }
  454. function audit_comment_form($student_id, $faculty_id) {
  455. $form = array();
  456. $form["student_id"] = array(
  457. "type" => "hidden",
  458. "value" => $student_id,
  459. );
  460. $form["faculty_id"] = array(
  461. "type" => "hidden",
  462. "value" => $faculty_id,
  463. );
  464. $form["comment"] = array(
  465. "type" => "textarea",
  466. );
  467. $form["submit"] = array(
  468. "type" => "submit",
  469. "value" => t("Save"),
  470. );
  471. return $form;
  472. }
  473. function audit_comment_form_submit($form, $form_state) {
  474. global $user, $current_student_id;
  475. $faculty_id = $form_state["values"]["faculty_id"];
  476. $student_id = $form_state["values"]["student_id"];
  477. $type = "audit private";
  478. $comment = trim($form_state["values"]["comment"]);
  479. // Perform the save!
  480. if ($comment) {
  481. db_query("INSERT INTO advising_comments
  482. (student_id, faculty_id, term_id,
  483. comment, posted, access_type)
  484. VALUES
  485. (?, ?, ?, ?, ?, ?)
  486. ", array($student_id, $faculty_id, 0, $comment, time(), $type));
  487. fp_add_message(t("Audit comment saved successfully."));
  488. }
  489. watchdog("audit", "Audit comment saved. student_id:$student_id, comment:$comment");
  490. }
  491. function audit_hidden_approval_form() {
  492. $form = array();
  493. $form["approval_type"] = array(
  494. "type" => "text",
  495. );
  496. $form["approval_student_id"] = array(
  497. "type" => "text",
  498. );
  499. $form["approval_value"] = array(
  500. "type" => "text",
  501. );
  502. $form["approval_comment"] = array(
  503. "type" => "textarea",
  504. );
  505. return $form;
  506. }
  507. function audit_hidden_approval_form_submit($form, $form_state) {
  508. global $user;
  509. $values = $form_state["values"];
  510. $faculty_id = $user->cwid;
  511. $student_id = $values["approval_student_id"];
  512. $approval_type = $values["approval_type"];
  513. $approval_value = $values["approval_value"];
  514. $comment = trim($values["approval_comment"]);
  515. $school_id = db_get_school_id_for_student_id($student_id);
  516. // Check that we have permission to edit the approval for this person?
  517. if (!user_has_permission("edit_audit_approvals") || !audit_can_access_audit($student_id)) {
  518. fp_add_message(t("You do not have permission to edit audit approvals for this student"), "error");
  519. return FALSE;
  520. }
  521. $types = audit_get_approval_types($school_id);
  522. $details = $types[$approval_type];
  523. $approval_type_title = $details["title"];
  524. if ($approval_type_title == "") $approval_type_title = $approval_type;
  525. // Okay, let's save the approval status to our table.
  526. // Begin by deleting what's there for this approval type and student.
  527. db_query("DELETE FROM audit_approvals
  528. WHERE student_id = '?'
  529. AND approval_type = '?' ", $student_id, $approval_type);
  530. // Now, add our values
  531. $now = time();
  532. db_query("INSERT INTO audit_approvals
  533. (student_id, uid, faculty_id, approval_type, approval_value, posted)
  534. VALUES ('?', '?', '?', '?', '?', '?')
  535. ", $student_id, $user->id, $faculty_id, $approval_type, $approval_value, $now);
  536. fp_add_message(t("Approval value has been successfully updated for type %title.", array("%type" => $approval_type, "%title" => $approval_type_title)));
  537. // Also write to our comments table, and include the comment.
  538. //$approval_desc = ($approval_value == "no_approve") ? t("Not approved") : t("Approved");
  539. $options = audit_get_approval_options();
  540. $approval_desc = $options[$approval_value];
  541. if ($approval_desc == "") $approval_desc = $approval_value;
  542. $new_comment = " -- " . t("Automated Audit Comment") . " --<br><br>
  543. " . t("Approval status updated for:") . " <b>$approval_type_title</b>. " . t("New value:") . " <b>$approval_desc</b>.";
  544. if ($comment != "") {
  545. $new_comment .= "<br><br>" . t("Additional comment:") . " <br>-----------<br><em>" . nl2br($comment) . "</em>";
  546. }
  547. $new_values = array(
  548. "student_id" => $student_id,
  549. "faculty_id" => $faculty_id,
  550. "comment" => $new_comment,
  551. );
  552. audit_comment_form_submit(array(), array("values" => $new_values));
  553. }
  554. /**
  555. * Used by the menu to determine if the user can see the Audit tab at all.
  556. *
  557. * Basically, have we selected a student? AND, do we have the correct
  558. * permission?
  559. */
  560. function audit_can_access_audit($student_id = "") {
  561. global $current_student_id, $user;
  562. if ($student_id == "") $student_id = $current_student_id;
  563. // must be logged in first...
  564. if (!user_has_permission("access_logged_in_content")) return FALSE;
  565. if ($student_id != "") {
  566. // yes, a student has been selected. Do we have permission to view audits for THIS student?
  567. if (user_has_permission("view_student_audits") && advise_can_access_view($student_id)) return TRUE;
  568. }
  569. return FALSE;
  570. }
  571. /**
  572. * Implementation of hook_perm
  573. *
  574. */
  575. function audit_perm() {
  576. return array(
  577. "administer_audit" => array(
  578. "title" => t("Administer audit module settings"),
  579. ),
  580. "view_student_audits" => array(
  581. "title" => t("View student audits"),
  582. "description" => t("View the Audit tab for selected student, including audit comments."),
  583. ),
  584. "edit_audit_approvals" => array(
  585. "title" => t("Edit audit approvals"),
  586. "description" => t("Allows user to edit the 'approvals' for a student audit. Ex: faculty or other user types."),
  587. ),
  588. );
  589. }

Functions

Namesort descending Description
audit_can_access_audit Used by the menu to determine if the user can see the Audit tab at all.
audit_comment_form
audit_comment_form_submit
audit_display_audit
audit_get_approval_options Returns a simple array of the available approval options in the popup.
audit_get_approval_record
audit_get_approval_types Return an assoc array of approval types.
audit_hidden_approval_form
audit_hidden_approval_form_submit
audit_menu Implementation of hook_menu
audit_perm Implementation of hook_perm
audit_popup_edit_approval_form This is the actual form that will be used to change an audit approval for a student.
audit_settings_form
audit_settings_form_validate