stats.module

  1. 7.x modules/stats/stats.module
  2. 6.x modules/stats/stats.module
  3. 5.x modules/stats/stats.module

This module displays statistics and reports for FlightPath

File

modules/stats/stats.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * This module displays statistics and reports for FlightPath
  5. *
  6. */
  7. /**
  8. * Implementation of hook_menu
  9. *
  10. * @return array
  11. */
  12. function stats_menu() {
  13. $items = array();
  14. $items["stats"] = array(
  15. "title" => "Analytics & Reports",
  16. "page_callback" => "stats_display_main",
  17. "access_arguments" => array("can_access_stats"),
  18. "page_settings" => array(
  19. "page_show_title" => TRUE,
  20. ),
  21. "type" => MENU_TYPE_NORMAL_ITEM,
  22. );
  23. $items["stats/select-school"] = array(
  24. "title" => "Select School",
  25. "page_callback" => "fp_render_form",
  26. "page_arguments" => array("stats_select_school_form"),
  27. "access_arguments" => array("can_access_stats"),
  28. "page_settings" => array(
  29. "page_show_title" => TRUE,
  30. "bool_print" => FALSE,
  31. "menu_links" => array(
  32. 0 => array(
  33. "text" => t("Analytics"),
  34. "path" => "stats",
  35. ),
  36. ),
  37. ),
  38. "type" => MENU_TYPE_CALLBACK,
  39. );
  40. $items["stats/reports/access"] = array(
  41. "title" => "Access Stats",
  42. "description" => "See recent access within the system. This can be useful to see if anyone is currently using the system.",
  43. "page_callback" => "stats_report_access_stats",
  44. "access_arguments" => array("can_access_stats"),
  45. "page_settings" => array(
  46. "page_show_title" => TRUE,
  47. "menu_links" => array(
  48. 0 => array(
  49. "text" => t("Analytics"),
  50. "path" => "stats",
  51. ),
  52. ),
  53. ),
  54. "type" => MENU_TYPE_NORMAL_ITEM,
  55. "weight" => 100,
  56. );
  57. $items["stats/reports/major-counts"] = array(
  58. "title" => "Major Counts",
  59. "description" => "Displays the number of students within each major or major/concentration.",
  60. "page_callback" => "stats_report_major_counts",
  61. "access_arguments" => array("can_access_stats"),
  62. "page_settings" => array(
  63. "page_show_title" => TRUE,
  64. "menu_links" => array(
  65. 0 => array(
  66. "text" => t("Analytics"),
  67. "path" => "stats",
  68. ),
  69. ),
  70. ),
  71. "type" => MENU_TYPE_NORMAL_ITEM,
  72. "weight" => 150,
  73. );
  74. $items["stats/reports/major-students-progress"] = array(
  75. "title" => "Major Students Progress",
  76. "description" => "Students in a major, and their progress percentages in that major.",
  77. "page_callback" => "fp_render_form",
  78. "page_arguments" => array("stats_report_major_students_progress_form"),
  79. "access_arguments" => array("can_access_stats"),
  80. "page_settings" => array(
  81. "bool_print" => FALSE,
  82. "menu_links" => array(
  83. 0 => array(
  84. "text" => t("Analytics"),
  85. "path" => "stats",
  86. ),
  87. ),
  88. ),
  89. "type" => MENU_TYPE_NORMAL_ITEM,
  90. "weight" => 170,
  91. "file" => menu_get_module_path("stats") . "/reports.major-students-progress.inc",
  92. );
  93. $items["stats/reports/advisor-use"] = array(
  94. "title" => "Advisor Use",
  95. "description" => "How many students an advisor has advised over a specified time range.",
  96. "page_callback" => "stats_report_advisor_use",
  97. "access_arguments" => array("can_access_stats"),
  98. "page_settings" => array(
  99. "page_show_title" => TRUE,
  100. "bool_print" => FALSE,
  101. "menu_links" => array(
  102. 0 => array(
  103. "text" => t("Analytics"),
  104. "path" => "stats",
  105. ),
  106. ),
  107. ),
  108. "type" => MENU_TYPE_NORMAL_ITEM,
  109. "weight" => 250,
  110. );
  111. $system_name = variable_get("system_name", "FlightPath");
  112. $items["stats/reports/student-course-list"] = array(
  113. "title" => "Student Course List",
  114. "description" => "List courses a student has taken, which $system_name is aware of.",
  115. "page_callback" => "stats_report_student_course_list",
  116. "access_arguments" => array("can_access_stats"),
  117. "page_settings" => array(
  118. "page_show_title" => TRUE,
  119. "menu_links" => array(
  120. 0 => array(
  121. "text" => t("Analytics"),
  122. "path" => "stats",
  123. ),
  124. ),
  125. ),
  126. "type" => MENU_TYPE_NORMAL_ITEM,
  127. "weight" => 300,
  128. );
  129. $items["stats/reports/flightpath-use-summary"] = array(
  130. "title" => "$system_name Use Summary",
  131. "description" => "A detailed report on how $system_name is being used over a specified time range.",
  132. "page_callback" => "stats_report_flightpath_use_summary",
  133. "access_arguments" => array("can_access_stats"),
  134. "page_settings" => array(
  135. "page_show_title" => TRUE,
  136. "menu_links" => array(
  137. 0 => array(
  138. "text" => t("Analytics"),
  139. "path" => "stats",
  140. ),
  141. ),
  142. ),
  143. "type" => MENU_TYPE_NORMAL_ITEM,
  144. "weight" => 350,
  145. );
  146. $items["stats/reports/course-use-summary"] = array(
  147. "title" => "Course Use Summary",
  148. "description" => "A report of everywhere a particular course is used in $system_name (groups or degrees).",
  149. "page_callback" => "stats_report_course_use_summary",
  150. "access_arguments" => array("can_access_stats"),
  151. "page_settings" => array(
  152. "page_show_title" => TRUE,
  153. "menu_links" => array(
  154. 0 => array(
  155. "text" => t("Analytics"),
  156. "path" => "stats",
  157. ),
  158. ),
  159. ),
  160. "type" => MENU_TYPE_NORMAL_ITEM,
  161. "weight" => 450,
  162. );
  163. // Lets the user download a CSV file where the contents are stored in the batch_queue table itself, with a batch_id.
  164. $items["stats/download-csv-from-batch/%"] = array(
  165. "page_callback" => "stats_download_csv_from_batch",
  166. "page_arguments" => array(2),
  167. "access_arguments" => array("can_access_stats"),
  168. "type" => MENU_TYPE_CALLBACK,
  169. );
  170. // Lets the user download a CSV file stored in a FILE, in the files/private directory, with a batch_id.
  171. $items["stats/download-csv-from-batch-file/%"] = array(
  172. "page_callback" => "stats_download_csv_from_batch_file",
  173. "page_arguments" => array(2),
  174. "access_arguments" => array("can_access_stats"),
  175. "type" => MENU_TYPE_CALLBACK,
  176. );
  177. return $items;
  178. }
  179. /**
  180. * Lets the user download a CSV file from a completed batch.
  181. *
  182. * There are no permissions on this, except the can_access_stats permission.
  183. *
  184. * @param int $batch_id
  185. */
  186. function stats_download_csv_from_batch($batch_id) {
  187. $filename = fp_get_machine_readable(strtolower($_REQUEST["filename"]));
  188. $batch = batch_get($batch_id);
  189. if (!$batch) {
  190. print "Error trying to download CSV.";
  191. die;
  192. }
  193. watchdog('stats', "download_csv_from_batch batch_id:$batch_id, filename:$filename.csv", array());
  194. // Give it to the browser...
  195. header('Content-type: text/csv');
  196. header('Content-Disposition: attachment; filename="' . $filename . '.csv"');
  197. print $batch["csv"];
  198. die;
  199. }
  200. /**
  201. * Lets the user download a CSV file from a completed batch, from a file created during the batch operation.
  202. *
  203. *
  204. * @param int $batch_id
  205. */
  206. function stats_download_csv_from_batch_file($batch_id) {
  207. $filename = fp_get_machine_readable(strtolower($_REQUEST["filename"]));
  208. $batch = batch_get($batch_id);
  209. watchdog('stats', "download_csv_from_batch_file batch_id:$batch_id, filename:$filename.csv", array());
  210. // calcuate the full path to the file...
  211. $private_path = fp_get_files_path() . "/private";
  212. $batch_id = $batch['batch_id'];
  213. $created = $batch['created'];
  214. $filepath = $private_path . '/batch_' . $batch_id . '__' . $created . '.csv.tmp';
  215. // Give it to the browser...
  216. header('Content-type: text/csv');
  217. header('Content-Disposition: attachment; filename="' . $filename . '.csv"');
  218. // Read directly from the server...
  219. readfile($filepath);
  220. die;
  221. }
  222. /**
  223. * Implementation of hook_perm().
  224. * Expects to return an array of permissions recognized by
  225. * this module.
  226. *
  227. * Ex: $a = array(
  228. * "deCanDoSomething" => array (
  229. * "title" => "Can Do Something",
  230. * "description" => "Allow the user to do something."
  231. * )
  232. * );
  233. *
  234. */
  235. function stats_perm() {
  236. $perms = array (
  237. "can_access_stats" => array(
  238. "title" => t("Access/view stats & analytics"),
  239. "description" => t("This allows the user to access the stats module, letting them run
  240. reports on usage."),
  241. ),
  242. );
  243. return $perms;
  244. }
  245. /**
  246. * Return the HTML for a pulldown containing the catalog years available for selection.
  247. *
  248. * @param string $selected
  249. * @param bool $display_submit
  250. */
  251. function stats_draw_catalog_year_pulldown($selected = "", $display_submit = FALSE) {
  252. $rtn = "";
  253. $rtn .= "
  254. <table border='0'>
  255. <td valign='middle'>
  256. <select name='catalog_year' id='catalog_year'><option value=''>
  257. " . t("Please select a catalog year") . "</option>
  258. <option value=''>-----------------------------------</option>";
  259. $current_catalog_year = variable_get("current_catalog_year", ""); // TODO: school_id?
  260. if ($selected == "") $selected = $current_catalog_year;
  261. $res = db_query("SELECT DISTINCT (catalog_year) FROM degrees
  262. WHERE exclude = '0'
  263. ORDER BY catalog_year DESC");
  264. while ($cur = db_fetch_array($res)) {
  265. $sel = ($cur["catalog_year"] == $selected) ? "selected=selected" : "";
  266. $rtn .= "<option value='{$cur["catalog_year"]}' $sel>{$cur["catalog_year"]}-" . ($cur["catalog_year"] + 1) . "</option>";
  267. }
  268. $rtn .= " </select> </td>";
  269. if ($display_submit == true)
  270. {
  271. $rtn .= "<td valign='middle'><input type='submit' value='" . t("Select") . "'></td>";
  272. }
  273. $rtn .= "</table>";
  274. return $rtn;
  275. }
  276. /**
  277. * This report will display everywhere a particular course is used in FlightPath (groups and degrees)
  278. *
  279. */
  280. function stats_report_course_use_summary() {
  281. $rtn = "";
  282. $draft = "";
  283. $use_draft = FALSE;
  284. $school_id = 0; // TODO: school is selectable / based on user's school?
  285. $subject_id = $course_num = $draft_check = "";
  286. if (isset($_GET["subject_id"])) {
  287. $subject_id = trim($_GET["subject_id"]);
  288. $course_num = trim($_GET["course_num"]);
  289. // $school_id = intval($_GET["school_id"]); // TODO: not supported yet.
  290. if (isset($_GET['draft'])) {
  291. $draft_check = $_GET["draft"];
  292. }
  293. }
  294. if ($draft_check == "checked") {
  295. $draft = "draft_";
  296. $use_draft = TRUE;
  297. }
  298. $rtn .= "<form action='" . fp_url("stats/reports/course-use-summary") . "' method='GET' >";
  299. $rtn .= "Please enter a course's subject ID and course number to search:<br>";
  300. if (module_enabled("schools")) {
  301. $options = schools_get_schools_for_fapi();
  302. $rtn .= "<select name='school_id'>";
  303. foreach ($options as $k => $v) {
  304. $sel = "";
  305. if (intval($k) === $school_id) $sel = "selected";
  306. $rtn .= "<option value='$k' $sel>" . t("School: ") . $v . "</option>";
  307. }
  308. $rtn .= "</select> &nbsp; ";
  309. }
  310. $rtn .= "
  311. <input type='text' name='subject_id' placeholder='Subject ID' size='10' value='$subject_id'> &nbsp;
  312. <input type='text' name='course_num' placeholder='Course Num' size='10' value='$course_num'> &nbsp;
  313. <input type='checkbox' name='draft' value='checked' $draft_check>Check draft tables? &nbsp;
  314. <input type='submit' value='Search'>
  315. <br><b>Note:</b> This may take up to a minute to run, please be patient.";
  316. $rtn .= "</form>";
  317. if ($subject_id && $course_num) {
  318. $rtn .= "<hr>";
  319. // First, look up this course's ID.
  320. $db = get_global_database_handler();
  321. $course_id = $db->get_course_id($subject_id, $course_num, '', $use_draft, $school_id);
  322. if ($course_id) {
  323. $rtn .= "<h2>Course $subject_id $course_num (id is $course_id)</h2>";
  324. // Groups
  325. $rtn .= "<div><b>Groups:</b></div>
  326. <table border='1'>
  327. <tr>
  328. <th>ID</th>
  329. <th>Name</th>
  330. <th>Title</th>
  331. <th>Year</th>
  332. </tr>";
  333. $res = db_query("SELECT * FROM {$draft}group_requirements WHERE course_id = ?
  334. order by `id`", $course_id);
  335. while ($cur = db_fetch_array($res)) {
  336. $group_id = $cur["group_id"];
  337. $group = new Group($group_id, $db, -1, false, $use_draft);
  338. if (!$group->title) {
  339. // This is possibly a child group. Look for its parent.
  340. $res2 = db_query("SELECT * FROM {$draft}group_requirements WHERE child_group_id = ?", $group_id);
  341. $cur2 = db_fetch_array($res2);
  342. if ($cur2["group_id"] != "") {
  343. $group_id = $cur2["group_id"];
  344. $group = new Group($group_id, $db, -1, false, $use_draft);
  345. }
  346. }
  347. $rtn .= "<tr>
  348. <td>$group_id</td>
  349. <td>$group->group_name</td>
  350. <td>$group->title</td>
  351. <td>$group->catalog_year</td>
  352. </tr>";
  353. }
  354. $rtn .= "</table>";
  355. // Now, look for degrees...
  356. $rtn .= "<br><br><br>
  357. <b>Degrees:</b>
  358. <table border='1'>
  359. <tr>
  360. <th>ID</th>
  361. <th>Title</th>
  362. <th>MAJR</th>
  363. <th>Track</th>
  364. <th>Sem</th>
  365. <th>Year</th>
  366. </tr>";
  367. $res = db_query("SELECT * FROM {$draft}degree_requirements WHERE course_id = ? ORDER BY `id`", $course_id);
  368. while ($cur = db_fetch_array($res)) {
  369. $degree_id = $cur["degree_id"];
  370. $degree = new DegreePlan($degree_id, $db, TRUE, FALSE, $use_draft);
  371. $rtn .= "<tr>
  372. <td>$degree_id</td>
  373. <td>$degree->title</td>
  374. <td>$degree->major_code</td>
  375. <td>$degree->track_code</td>
  376. <td>" . $cur["semester_num"] . "</td>
  377. <td>$degree->catalog_year</td>
  378. </tr>";
  379. }
  380. $rtn .= '</table>';
  381. } // if course_id
  382. else {
  383. $rtn .= "<div>Course could not be found. Check spelling.";
  384. }
  385. }
  386. watchdog('stats', "report_course_use_summary subject_id:$subject_id, course_num:$course_num, school_id:$school_id, draft_check:$draft_check", array());
  387. return $rtn;
  388. }
  389. /**
  390. * Display a major selection pulldown, used by other reports.
  391. *
  392. * If bool_only_majors_with_tracks == TRUE, then we will only display the majors which
  393. * have tracks associated with them.
  394. *
  395. * If bool_exclude_tracks == TRUE, then we will skip over any major_code with a "_" in it,
  396. * meaning, this code describes a track and not the base major.
  397. *
  398. * If bool_only_current_catalog_year == TRUE, then only degrees from the current catalog year
  399. * will be displayed.
  400. *
  401. */
  402. function stats_draw_majors_pulldown($smajor = "", $display_submit = FALSE, $bool_only_majors_with_tracks = FALSE, $label = "Please select a major", $bool_exclude_tracks = FALSE, $bool_only_current_catalog_year = TRUE, $bool_return_options_array = FALSE, $school_id = 0)
  403. {
  404. $rtn = "";
  405. $db = get_global_database_handler();
  406. $major_array = array();
  407. $options_array = array();
  408. $current_catalog_year = variable_get_for_school("current_catalog_year", "", $school_id);
  409. $m_a_count = 0;
  410. if ($bool_only_current_catalog_year) {
  411. $query = "SELECT * FROM degrees
  412. WHERE catalog_year = ?
  413. AND school_id = ?
  414. AND `exclude`='0'
  415. ORDER BY major_code ";
  416. $result = db_query($query, $current_catalog_year, $school_id);
  417. }
  418. else { // current catalog year not important.
  419. $query = "SELECT * FROM degrees
  420. WHERE `exclude`='0'
  421. AND school_id = ?
  422. GROUP BY major_code
  423. ORDER BY major_code ";
  424. $result = db_query($query, $school_id);
  425. }
  426. while ($cur_row = $db->db_fetch_array($result)) {
  427. $major = trim($cur_row["major_code"]);
  428. if ($bool_exclude_tracks && strpos($major, "_")) {
  429. continue;
  430. }
  431. if ($bool_only_majors_with_tracks && !$db->get_degree_tracks($major, $current_catalog_year))
  432. { // only get majors that also have tracks!
  433. continue;
  434. }
  435. $description = trim($cur_row["title"]);
  436. $type = trim($cur_row["degree_type"]);
  437. $school_id = intval($cur_row['school_id']);
  438. $major_array[$m_a_count]["description"] = $description;
  439. $major_array[$m_a_count]["major"] = $major;
  440. $major_array[$m_a_count]["type"] = $type;
  441. $major_array[$m_a_count]["school_id"] = $school_id;
  442. if (module_enabled("schools")) {
  443. $major_array[$m_a_count]["school_name"] = t("School: ") . schools_get_school_name_for_id($school_id);
  444. }
  445. $m_a_count++;
  446. }
  447. $rtn .= "
  448. <table border='0'>
  449. <td valign='middle'>
  450. <select name='major' id='major'>
  451. <option value=''>" . $label . "</option>
  452. <option value=''>-----------------------------------</option>";
  453. for ($t = 0; $t < $m_a_count; $t++)
  454. {
  455. $sel = "";
  456. if ($major_array[$t]["major"] == $smajor && $smajor != "")
  457. {
  458. $sel = "selected";
  459. }
  460. $hyph = "-";
  461. if ($major_array[$t]["type"] == "" || $major_array[$t]["type"] == "NA")
  462. {
  463. $hyph = "";
  464. $major_array[$t]["type"] = "";
  465. }
  466. $rtn .= "<option value='" . $major_array[$t]["major"] . "' $sel>(" . $major_array[$t]["major"] . ")
  467. " . $major_array[$t]["description"] . " $hyph " . $major_array[$t]["type"] . "
  468. </option>";
  469. if (module_enabled("schools")) {
  470. // Create an options array multi-dimentional, organized by school name.
  471. $options_array[$major_array[$t]["school_name"]][$major_array[$t]["major"]] = "(" . $major_array[$t]["major"] . ") " . $major_array[$t]["description"] . " $hyph " . $major_array[$t]["type"];
  472. }
  473. else {
  474. // Just create a "flat" options array
  475. $options_array[$major_array[$t]["major"]] = "(" . $major_array[$t]["major"] . ") " . $major_array[$t]["description"] . " $hyph " . $major_array[$t]["type"];
  476. }
  477. }
  478. $rtn .= " </select> </td>";
  479. if ($display_submit == true)
  480. {
  481. $rtn .= "<td valign='middle'><input type='submit' value='" . t("Select") . "'></td>";
  482. }
  483. $rtn .= "</table>";
  484. if ($bool_return_options_array) return $options_array;
  485. return $rtn;
  486. }
  487. function stats_select_school_form() {
  488. $form = array();
  489. if (isset($_REQUEST['title'])) {
  490. fp_set_title(strip_tags($_REQUEST['title']));
  491. }
  492. $redirect_path = $_REQUEST['redirect'];
  493. $options = schools_get_schools_for_fapi();
  494. $form['school_id'] = array(
  495. 'type' => 'select',
  496. 'label' => t("Please select a school:"),
  497. 'options' => $options,
  498. 'hide_please_select' => TRUE,
  499. );
  500. $form['select_school'] = array(
  501. 'type' => 'hidden',
  502. 'value' => 'yes',
  503. );
  504. $form['redirect'] = array(
  505. 'type' => 'hidden',
  506. 'value' => base64_encode($redirect_path),
  507. );
  508. $form['submit_btn'] = array(
  509. 'type' => 'submit',
  510. 'value' => t("Continue"),
  511. );
  512. // change breadcrumbs based on REQUEST
  513. if (isset($_REQUEST['crumbs'])) {
  514. $crumbs = unserialize(base64_decode($_REQUEST['crumbs']));
  515. fp_set_breadcrumbs($crumbs);
  516. }
  517. return $form;
  518. }
  519. function stats_select_school_form_submit($form, $form_state) {
  520. // We are simply trying to select the school. Return to the form with our selection.
  521. $school_id = intval($form_state['values']['school_id']);
  522. $redirect_path = base64_decode($form_state['values']['redirect']);
  523. fp_goto($redirect_path, 'school_id=' . $school_id);
  524. return;
  525. }
  526. /**
  527. * This report shows how many students are in each major.
  528. *
  529. * @return string
  530. */
  531. function stats_report_major_counts() {
  532. $rtn = "";
  533. $rtn .= "<p>" . t("This report shows number of students in each major or concentration, as defined in FlightPath.") . "</p>";
  534. $rtn .= "<table border='1'>
  535. <tr>";
  536. if (module_enabled('schools')) {
  537. $rtn .= "<th>" . t("School") . "</th>";
  538. }
  539. $rtn .= "
  540. <th>" . t("Major") . "</th>
  541. <th>" . t("Count") . "</th>
  542. <th colspan='2'>" . t("Description") . "</th>
  543. </tr>";
  544. $total = 0;
  545. $res_array = array();
  546. $result = db_query("SELECT * FROM degrees
  547. GROUP BY major_code
  548. ORDER BY school_id, major_code, title ");
  549. while ($cur = db_fetch_array($result)) {
  550. $count = 0;
  551. $major_code = $cur["major_code"];
  552. $title = $cur["title"];
  553. $degree_type = $cur["degree_type"];
  554. $school_id = intval($cur['school_id']);
  555. $school_code = "#$school_id";
  556. if ($school_id === 0) $school_code = "-";
  557. if (module_enabled("schools")) {
  558. $school_code = schools_get_school_code_for_id($school_id);
  559. }
  560. // Find out how many students have this major code.
  561. $sql = "SELECT count(cwid) AS count FROM students a, student_degrees b
  562. WHERE b.major_code = ?
  563. AND a.cwid = b.student_id
  564. AND rank_code IN %RANKIN%
  565. %EXTRA_STUDENTSEARCH_CONDITIONS% ";
  566. $rank_in = "( '" . join("', '", csv_to_array(variable_get("allowed_student_ranks", "FR,SO,JR,SR"))) . "' )";
  567. $sql = str_replace("%RANKIN%", $rank_in, $sql);
  568. $sql = str_replace("%EXTRA_STUDENTSEARCH_CONDITIONS%", variable_get("extra_student_search_conditions",""), $sql);
  569. $res2 = db_query($sql, $major_code);
  570. $cur2 = db_fetch_array($res2);
  571. if (is_numeric($cur2["count"])) {
  572. $total += $cur2["count"];
  573. }
  574. $res_array[$major_code]["count"] = $cur2["count"] * 1;
  575. $res_array[$major_code]["desc"] = $title;
  576. $res_array[$major_code]["type"] = $degree_type;
  577. $res_array[$major_code]["school_code"] = $school_code;
  578. }
  579. if (count($res_array) > 0) {
  580. foreach($res_array as $major => $value) {
  581. $rtn .= "<tr>";
  582. if (module_enabled('schools')) {
  583. $rtn .= "<td valign='top' class='tenpt'>{$value["school_code"]}</td>";
  584. }
  585. $rtn .= "
  586. <td valign='top' class='tenpt'>$major</td>
  587. <td valign='top' class='tenpt'>{$value["count"]}</td>
  588. <td valign='top' class='tenpt'>{$value["type"]}</td>
  589. <td valign='top' class='tenpt'>{$value["desc"]}</td>
  590. </tr>";
  591. }
  592. }
  593. $rtn .= "</table>
  594. " . t("Total student records:") . " $total.";
  595. watchdog('stats', "report_major_counts", array());
  596. return $rtn;
  597. }
  598. /**
  599. * This report shows common usages in FlightPath by all users.
  600. *
  601. * This is a helpful report for determining which functionality is most popular
  602. * in FlightPath
  603. *
  604. * @return string
  605. */
  606. function stats_report_flightpath_use_summary() {
  607. $rtn = "";
  608. $start_date = @$_REQUEST["start_date"];
  609. $end_date = @$_REQUEST["end_date"];
  610. $rtn .= stats_draw_date_range_form("stats/reports/flightpath-use-summary", $start_date, $end_date);
  611. if ($start_date == "" || $end_date == "") {
  612. return $rtn;
  613. }
  614. $start_date .= " 00:00:00"; // make it start at midnight of the startDate.
  615. $end_date .= " 23:59:59"; // make it go through to midnight of the endDate.
  616. // Okay, now we get our various counts....
  617. // Logins...
  618. $u_student = stats_get_log_count("display_dashboard","",true,$start_date,$end_date,true);
  619. $t_student = stats_get_log_count("display_dashboard","",false,$start_date,$end_date,true);
  620. $u_staff = stats_get_log_count("display_dashboard","",true,$start_date,$end_date,false);
  621. $t_staff = stats_get_log_count("display_dashboard","",false,$start_date,$end_date,false);
  622. $rtn .= "<b>System Logins / Access</b>
  623. <blockquote>
  624. Unique student logins: $u_student<br>
  625. Total student views of dashboard: $t_student<br>
  626. ------- <br>
  627. Unique faculty/staff logins: $u_staff<br>
  628. Total faculty/staff views of dashboard: $t_staff
  629. </blockquote>
  630. ";
  631. // Advisings...
  632. /* // This legacy code is not accurate. Going to use the "advisor use report" to get this data". - RP 11/30/2023
  633. $regular_advisings = stats_get_log_count("save_adv_active","",false,$start_date,$end_date,false);
  634. $wi_advisings = stats_get_log_count("save_adv_active_whatif","",false,$start_date,$end_date,false);
  635. $total_advisings = $regular_advisings + $wi_advisings;
  636. $rtn .= "<b>Advisings</b>
  637. <blockquote>
  638. Total student advisings: $total_advisings <br>
  639. ------- <br>
  640. Regular advisings: $regular_advisings<br>
  641. What If advisings: $wi_advisings
  642. </blockquote>
  643. ";
  644. */
  645. // Advisings
  646. $_REQUEST['report_type'] = 'unique';
  647. $_REQUEST['is_whatif'] = 'no';
  648. $regular_advisings = stats_report_advisor_use(TRUE);
  649. $_REQUEST['report_type'] = 'unique';
  650. $_REQUEST['is_whatif'] = 'yes';
  651. $wi_advisings = stats_report_advisor_use(TRUE);
  652. $total_advisings = intval($regular_advisings) + intval($wi_advisings);
  653. $rtn .= "<b>Advisings</b>
  654. <blockquote>
  655. Total unique student advisings: $total_advisings <br>
  656. ------- <br>
  657. Regular unique advisings: $regular_advisings<br>
  658. What If advisings: $wi_advisings
  659. </blockquote>
  660. ";
  661. // Comments...
  662. $total = stats_get_log_count("save_comment","",false,$start_date,$end_date,false);
  663. $unique = stats_get_log_count("save_comment","",true,$start_date,$end_date,false);
  664. $rtn .= "<b>Comments</b>
  665. <blockquote>
  666. Total comments saved: $total <br>
  667. ------- <br>
  668. Unique faculty/staff commentors: $unique
  669. </blockquote>
  670. ";
  671. // Course search...
  672. $u_student = stats_get_log_count("course_search","",true,$start_date,$end_date,true);
  673. //$um_student = stats_get_log_count("course_search","",true,$start_date,$end_date,true,true);
  674. $t_student = stats_get_log_count("course_search","",false,$start_date,$end_date,true);
  675. //$tm_student = stats_get_log_count("course_search","",false,$start_date,$end_date,true, true);
  676. $u_staff = stats_get_log_count("course_search","",true,$start_date,$end_date,false);
  677. $t_staff = stats_get_log_count("course_search","",false,$start_date,$end_date,false);
  678. //$tm_staff = stats_get_log_count("course_search","",false,$start_date,$end_date,false, true);
  679. $rtn .= "<b>Course Search</b>
  680. <blockquote>
  681. Unique student users: $u_student <br>
  682. Total student uses: $t_student <br>
  683. ------- <br>
  684. Unique faculty/staff users: $u_staff<br>
  685. Total faculty/staff (and anonymous) uses: $t_staff </span>
  686. </blockquote>
  687. ";
  688. // Degree search...
  689. $u_student = stats_get_log_count("blank_degrees","",true,$start_date,$end_date,true);
  690. //$um_student = stats_get_log_count("blank_degrees","",true,$start_date,$end_date,true,true);
  691. $t_student = stats_get_log_count("blank_degrees","",false,$start_date,$end_date,true);
  692. //$tm_student = stats_get_log_count("blank_degrees","",false,$start_date,$end_date,true, true);
  693. $u_staff = stats_get_log_count("blank_degrees","",true,$start_date,$end_date,false);
  694. $t_staff = stats_get_log_count("blank_degrees","",false,$start_date,$end_date,false);
  695. //$tm_staff = stats_get_log_count("blank_degrees","",false,$start_date,$end_date,false, true);
  696. $rtn .= "<b>Degree Search (blank degrees)</b>
  697. <blockquote>
  698. Unique student users: $u_student <br>
  699. Total student uses: $t_student <br>
  700. ------- <br>
  701. Unique faculty/staff users: $u_staff<br>
  702. Total faculty/staff (and anonymous) uses: $t_staff </span>
  703. </blockquote>
  704. ";
  705. // View preferences
  706. $t_student_y = stats_get_log_count("view_by_year","",false,$start_date,$end_date,true);
  707. //$tm_student_y = stats_get_log_count("view_by_year","",false,$start_date,$end_date,true, true);
  708. $u_student_y = stats_get_log_count("view_by_year","",true,$start_date,$end_date,true);
  709. //$um_student_y = stats_get_log_count("view_by_year","",true,$start_date,$end_date,true, true);
  710. $t_staff_y = stats_get_log_count("view_by_year","",false,$start_date,$end_date,false);
  711. $t_student_t = stats_get_log_count("view_by_type","",false,$start_date,$end_date,true);
  712. //$tm_student_t = stats_get_log_count("view_by_type","",false,$start_date,$end_date,true, true);
  713. $u_student_t = stats_get_log_count("view_by_type","",true,$start_date,$end_date,true);
  714. //$um_student_t = stats_get_log_count("view_by_type","",true,$start_date,$end_date,true, true);
  715. $t_staff_t = stats_get_log_count("view_by_type","",false,$start_date,$end_date,false);
  716. $rtn .= "<b>View Preferences</b>
  717. <blockquote>
  718. Unique student view-by-year: $u_student_y <br>
  719. Total student view-by-year: $t_student_y <br>
  720. Total faculty/staff view-by-year: $t_staff_y<br>
  721. ------- <br>
  722. Unqiue student view-by-type: $u_student_t <br>
  723. Total student view-by-type: $t_student_t <br>
  724. Total faculty/staff view-by-type: $t_staff_t<br>
  725. </blockquote>
  726. ";
  727. // Substitutions
  728. $t_staff = stats_get_log_count("save_substitution","",false,$start_date,$end_date,false);
  729. $u_staff = stats_get_log_count("save_substitution","",true,$start_date,$end_date,false);
  730. $rtn .= "<b>Substitutions</b>
  731. <blockquote>
  732. Unique substitutors: $u_staff<br>
  733. Total substitutions: $t_staff<br>
  734. </blockquote>
  735. ";
  736. watchdog('stats', "report_flightpath_use_summary start_date:$start_date, end_date:$end_date", array());
  737. return $rtn;
  738. }
  739. /**
  740. * Used by the use_summary report. This function will simply return log counts
  741. * for the specified parameters in the watchdog table.
  742. *
  743. * @param string $action
  744. * @param mixed $action_array
  745. * @param bool $bool_distinct
  746. * @param string $start_date
  747. * @param string $end_date
  748. * @param bool $bool_students
  749. * @param bool $bool_mobile_only
  750. * @return int
  751. */
  752. function stats_get_log_count($action = "", $action_array = NULL, $bool_distinct = FALSE, $start_date = '', $end_date = '', $bool_students = true, $bool_mobile_only = false)
  753. {
  754. $action_line = " `type` = '$action' ";
  755. if (is_array($action_array) && count($action_array) > 1)
  756. {
  757. $action_line = "";
  758. $action_line .= "( ";
  759. foreach($action_array as $action)
  760. {
  761. $action_line .= " `type`='$action' OR";
  762. }
  763. $action_line = substr($action_line, 0, -2);
  764. $action_line .= ") ";
  765. }
  766. $count = "count(wid)";
  767. if ($bool_distinct)
  768. {
  769. $count = "count(distinct `user_id`)";
  770. }
  771. $user_type = "";
  772. if ($bool_students)
  773. {
  774. $user_type = " `is_student` = '1' ";
  775. } else {
  776. $user_type = " `is_faculty` = '1' ";
  777. }
  778. if ($bool_mobile_only) {
  779. $action_line .= " AND is_mobile = '1' ";
  780. }
  781. $start_ts = strtotime($start_date);
  782. $end_ts = strtotime($end_date);
  783. $res = db_query("SELECT $count AS count FROM watchdog
  784. WHERE
  785. `timestamp` > '$start_ts' AND `timestamp` < '$end_ts'
  786. AND $user_type
  787. AND
  788. $action_line
  789. ");
  790. $cur = db_fetch_array($res);
  791. return intval($cur["count"]) * 1;
  792. }
  793. /**
  794. * Displays the HTML for the date range form used by several reports.
  795. * $path is what is the form's ACTION sending to.
  796. *
  797. * start and end date expected in YYYY-MM-DD format
  798. *
  799. */
  800. function stats_draw_date_range_form($path, $start_date = "", $end_date = "", $additional_form_elements = "") {
  801. $rtn = "";
  802. $rtn .= "<form action='" . fp_url($path) . "' method='GET' >
  803. " . t("Select a date range to begin:") . "
  804. <br>
  805. " . t("Start date:") . "
  806. <span class='form-element element-type-date element-size-smaller'>
  807. <input type='date' name='start_date' value='$start_date' id='start_date'>
  808. </span>
  809. &nbsp; &nbsp;
  810. " . t("End date:") . "
  811. <span class='form-element element-type-date'>
  812. <input type='date' name='end_date' value='$end_date' id='end_date'>
  813. </span>
  814. &nbsp; &nbsp;";
  815. if ($additional_form_elements != "") {
  816. $rtn .= $additional_form_elements;
  817. }
  818. fp_add_css(fp_get_module_path("system") . "/css/style.css");
  819. fp_add_js(fp_get_module_path("system") . "/js/spinner.js");
  820. $name = fp_get_machine_readable($path);
  821. $rtn .= "
  822. <span class='buttons form-element element-type-submit'>
  823. <input type='submit' value='" . t("Submit") . "' onclick='$(\".loading-spinner\").show();'>
  824. </span>
  825. <span class='loading-spinner loading-spinner-$name' style='display:none;'></span>
  826. </form> <hr>
  827. ";
  828. return $rtn;
  829. }
  830. /**
  831. * This report shows which advisors are using FlightPath most often.
  832. *
  833. *
  834. * @return string|int
  835. */
  836. function stats_report_advisor_use($bool_only_return_total_number = FALSE) {
  837. $rtn = "";
  838. $start_date = $end_date = $report_type = $whatif = $report_type = "";
  839. if (isset($_REQUEST["start_date"])) {
  840. $start_date = fp_trim(addslashes((string) @$_REQUEST["start_date"]));
  841. $end_date = fp_trim(addslashes((string) @$_REQUEST["end_date"]));
  842. $report_type = fp_trim(addslashes((string) @$_REQUEST["report_type"]));
  843. }
  844. if (isset($_REQUEST['is_whatif'])) {
  845. $whatif = fp_trim((string) @$_REQUEST['is_whatif']);
  846. }
  847. $selall = $selunique = "";
  848. if ($report_type == 'unique') $selunique = 'selected';
  849. $additional_form_elements = t("Report Type:") . "
  850. <span class='form-element element-type-select-smaller'>
  851. <select name='report_type' id='report_type'>
  852. <option value='all' $selall>" . t("All saved advisings") . "</option>
  853. <option value='unique' $selunique>" . t("Unique student advisings") . "</option>
  854. </select>
  855. </span>
  856. &nbsp; &nbsp;";
  857. $rtn .= stats_draw_date_range_form("stats/reports/advisor-use", $start_date, $end_date, $additional_form_elements);
  858. if ($start_date == "" || $end_date == "") {
  859. return $rtn;
  860. }
  861. $start_date .= " 00:00:00"; // make it start at midnight of the startDate.
  862. $end_date .= " 23:59:59"; // make it go through to midnight of the endDate.
  863. $start_ts = strtotime($start_date);
  864. $end_ts = strtotime($end_date);
  865. // Now, what we're doing here is we want the names of the advisors,
  866. // and how many advisings they actually completed for each,
  867. // as well as which college or department they belong to. They need
  868. // to be sorted by college/department.
  869. $f_array = array();
  870. $s_array = array();
  871. $terms = array();
  872. $already_found_student_and_term = array();
  873. // TODO: get by school that user belongs to?
  874. $departments = fp_get_departments();
  875. $s_array = array();
  876. $whatif_line = "";
  877. if ($whatif == 'yes') {
  878. $whatif_line = "AND a.is_whatif = 1 ";
  879. }
  880. else if ($whatif == 'no') {
  881. $whatif_line = "AND a.is_whatif != 1 ";
  882. }
  883. $res = db_query("SELECT *
  884. FROM advising_sessions a, users u, faculty f
  885. WHERE
  886. (`posted` > ? AND `posted` < ?)
  887. AND a.is_empty != 1
  888. AND a.is_draft != 1
  889. AND a.delete_flag != 1
  890. $whatif_line
  891. AND is_faculty = 1
  892. AND a.faculty_id = u.cwid
  893. AND u.cwid = f.cwid
  894. ORDER BY l_name, f_name
  895. ", array($start_ts, $end_ts));
  896. while ($cur = db_fetch_array($res)) {
  897. $faculty_id = $cur['faculty_id'];
  898. $student_id = $cur['student_id'];
  899. $term_id = $cur['term_id'];
  900. $is_whatif = intval($cur['is_whatif']);
  901. if ($report_type == 'unique') {
  902. if (in_array("$faculty_id~$student_id~$term_id~$is_whatif", $already_found_student_and_term)) continue;
  903. $already_found_student_and_term[] = "$faculty_id~$student_id~$term_id~$is_whatif";
  904. }
  905. if (!isset($f_array[$faculty_id])) $f_array[$faculty_id] = 0;
  906. $school_id = intval($cur['school_id']);
  907. $dept_name = @$departments[$cur['department_code']];
  908. if (!$dept_name) $dept_name = $cur['department_code'];
  909. $f_array[$faculty_id] = intval($f_array[$faculty_id]); // make it a number.
  910. $f_array[$faculty_id]++;
  911. $s_array[$faculty_id]["dept_name"] = $dept_name;
  912. $s_array[$faculty_id]["college_name"] = ucwords(strtolower(trim($cur["college"])));
  913. $s_array[$faculty_id]["school_id"] = $school_id;
  914. $s_array[$faculty_id]["name"] = ucwords(strtolower(trim($cur["f_name"]) . " " . trim($cur["l_name"]))) . " ($faculty_id)";
  915. if (!isset($s_array[$faculty_id][$term_id])) $s_array[$faculty_id][$term_id] = 0;
  916. $s_array[$faculty_id][$term_id]++;
  917. $terms[$term_id] = get_term_description($term_id);
  918. }
  919. ksort($terms);
  920. // Sort based on who has advised the most...
  921. //arsort($f_array);
  922. $start_date = trim(addslashes($_REQUEST["start_date"]));
  923. $end_date = trim(addslashes($_REQUEST["end_date"]));
  924. $grand_total = 0;
  925. // Now, output the results...
  926. if ($report_type == 'all') {
  927. $rtn .= "<p><b>Note:</b> This Report Type (selected above) shows the total number of advising sessions saved by the advisor, <em>including</em> sessions which were saved
  928. more than once. Deleted advising sessions are not counted.</p>";
  929. }
  930. else if ($report_type == 'unique') {
  931. $rtn .= "<p><b>Note:</b> This Report Type (selected above) shows the number of advising sessions saved by the advisor,
  932. <em>unique to a student AND What If mode</em>. It ignores sessions which were saved
  933. more than once, unless the second time was in What If mode. Deleted advising sessions are not counted.</p>";
  934. }
  935. $rtn .= "
  936. <table border='1' cellpadding='10' style='min-width:700px;'>
  937. <tr>";
  938. if (module_enabled('schools')) {
  939. $rtn .= "<th>" . t("School") . "</th>";
  940. }
  941. $rtn .= "<th>" . t("Name") . "</th>
  942. <th>" . t("Dept") . "</th>
  943. <th>Total #</th>";
  944. // loop through and add in the terms
  945. foreach ($terms as $term_id => $term_desc) {
  946. $rtn .= "<td>$term_desc</td>";
  947. }
  948. $rtn .= "</tr>";
  949. foreach($f_array as $faculty_id => $value)
  950. {
  951. $name = $s_array[$faculty_id]["name"];
  952. $college_name = $s_array[$faculty_id]["college_name"];
  953. $dept_name = $s_array[$faculty_id]["dept_name"];
  954. $school_id = $s_array[$faculty_id]["school_id"];
  955. $grand_total = $grand_total + intval($value);
  956. $rtn .= "<tr>";
  957. if (module_enabled('schools')) {
  958. $rtn .= "<td valign='top'>" . schools_get_school_name_for_id($school_id) . "</td>";
  959. }
  960. $rtn .= "
  961. <td valign='top'>$name</td>
  962. <td valign='top'>$dept_name</td>
  963. <td valign='top' align='center'>$value</td>";
  964. // loop through and add in the terms
  965. foreach ($terms as $term_id => $term_desc) {
  966. $rtn .= "<td align='center'>" . fp_trim(@$s_array[$faculty_id][$term_id]) . "</td>";
  967. }
  968. $rtn .= "
  969. </tr>
  970. ";
  971. }
  972. $rtn .= "</table>";
  973. $rtn .= "<p><b>Total in selected date range:</b> $grand_total</p>";
  974. if ($bool_only_return_total_number) {
  975. return intval($grand_total);
  976. }
  977. return $rtn;
  978. }
  979. /**
  980. * This report shows recent activity in FlightPath. It can also be used to see
  981. * if anyone is "online" in that they would have activity less than 5 minutes old.
  982. *
  983. * @return string
  984. */
  985. function stats_report_access_stats() {
  986. $rtn = "";
  987. fp_add_css(fp_get_module_path("admin") . '/css/admin.css');
  988. $min = intval(@$_REQUEST["min"]);
  989. if ($min < 1 || $min > 2000)
  990. {
  991. $min = "20";
  992. }
  993. $rtn .= "
  994. <form action='" . fp_url("stats/reports/access") . "' method='GET'>
  995. " . t("Activity over the last") . "
  996. <input type='text' name='min' value='$min' size='2'>
  997. ";
  998. $rtn .= t("minutes") . ": <input type='submit' value='&gt;'>
  999. </form>
  1000. " . t("Unique students in time frame") . ": <!--STUDENTS-->. " . t("Unique faculty/staff in time frame") . ": <!--STAFF--> <br>";
  1001. $rtn .= "<hr>
  1002. <table class='watchdog-table' cellspacing='0' cellpadding='4'>
  1003. <tr>
  1004. <th>" . t("ID") . "</th>
  1005. <th>" . t("User") . "</th>
  1006. <th>" . t("User Type") . "</th>
  1007. <th>" . t("Action") . "</th>
  1008. <th>" . t("Msg") . "</th>
  1009. <th>" . t("Time") . "</th>
  1010. </tr>";
  1011. $cwid_array = array();
  1012. $student_actions = $staff_actions = 0;
  1013. $interval = time() - ($min * 60);
  1014. $pol = "";
  1015. $res = db_query("SELECT * FROM watchdog
  1016. WHERE `timestamp` > ?
  1017. ORDER BY `timestamp` DESC
  1018. ", $interval);
  1019. while ($cur = db_fetch_array($res)) {
  1020. // extract ($cur, 3, "db");
  1021. $wid = $cur['wid'];
  1022. $account = fp_load_user($cur['user_id']);
  1023. $pol = ($pol == "even") ? "odd" : "even";
  1024. $minago = round((time() - $cur['timestamp']) / 60, 0);
  1025. $vars = @unserialize($cur['variables']);
  1026. if (!$vars) $vars = '';
  1027. $message = strip_tags(t($cur['message'], $vars));
  1028. if (strlen($message) > 100) {
  1029. $message = trim(substr($message, 0, 100)) . "...";
  1030. }
  1031. $pretty_date = format_date(convert_time($cur['timestamp']));
  1032. $user_type = "";
  1033. if ($account->is_student) {
  1034. $user_type .= "<span>" . t("Student") . "</span>";
  1035. }
  1036. if ($account->is_faculty) {
  1037. $user_type .= "<span style='background-color: lightyellow;'>" . t("Faculty") . "</span>";
  1038. }
  1039. $rtn .= "<tr class='row-$pol'>
  1040. <td valign='top'>" . l($wid, "admin/config/watchdog/$wid") . "</td>
  1041. <td valign='top'>$account->name</td>
  1042. <td valign='top'>$user_type</td>
  1043. <td valign='top'>{$cur['type']}</td>
  1044. <td valign='top'>$message</td>
  1045. <td valign='top'>$minago " . t("min ago") . " &nbsp; <em>($pretty_date)</em></td>
  1046. </tr>";
  1047. // Let's increase our counters, if this is a new CWID.
  1048. if (!in_array($cur['user_id'], $cwid_array)) {
  1049. $cwid_array[] = $cur['user_id'];
  1050. if ($account->is_student) {
  1051. $student_actions++;
  1052. } else if ($account->is_faculty) {
  1053. $staff_actions++;
  1054. }
  1055. }
  1056. }
  1057. // Add in our student and staff action counts
  1058. $rtn = str_replace("<!--STUDENTS-->",$student_actions,$rtn);
  1059. $rtn = str_replace("<!--STAFF-->",$staff_actions,$rtn);
  1060. $rtn .= "</table>";
  1061. return $rtn;
  1062. }
  1063. /**
  1064. * This report shows a list of all of a student's courses which FlightPath is aware of.
  1065. *
  1066. * @return string
  1067. */
  1068. function stats_report_student_course_list() {
  1069. $rtn = "";
  1070. $student_cwid = "";
  1071. if (isset($_REQUEST["student_cwid"])) {
  1072. $student_cwid = fp_get_machine_readable(trim(addslashes($_REQUEST["student_cwid"])));
  1073. }
  1074. $student_pidm = 0;
  1075. //$rtn .= stats_draw_student_cwid_form("stats/reports/student-course-list", $student_cwid);
  1076. $rtn .= "<form action='" . fp_url("stats/reports/student-course-list") . "' method='GET' >
  1077. " . t("Enter a student's CWID to see their courses:") . "
  1078. <br>
  1079. <span class='form-element element-type-textfield'>
  1080. <input type='textfield' value='$student_cwid' name='student_cwid'>
  1081. </span>
  1082. <span class='buttons form-element element-type-submit'>
  1083. <input type='submit' value='" . t("Submit") . "'>
  1084. </span>
  1085. </form> <hr>";
  1086. if ($student_cwid == "") {
  1087. return $rtn;
  1088. }
  1089. // If we have the banner_integration module installed, then get the pidm from banner too
  1090. if (function_exists("fpl_banner_integration_get_pidm_for_cwid")) {
  1091. $student_pidm = intval(fpl_banner_integration_get_pidm_for_cwid($student_cwid));
  1092. }
  1093. $student_name = fp_get_student_name($student_cwid);
  1094. $student = new Student($student_cwid);
  1095. $school_id = db_get_school_id_for_student_id($student_cwid);
  1096. $school_name = "";
  1097. if (module_enabled("schools")) {
  1098. $school_name = schools_get_school_name_for_id($school_id);
  1099. }
  1100. $rtn .= "
  1101. <style>
  1102. .zebra-even {
  1103. background-color: white;
  1104. }
  1105. .zebra-odd {
  1106. background-color: #eee;
  1107. }
  1108. </style>
  1109. <h2>$student_name ($student_cwid)
  1110. ";
  1111. if ($student_pidm > 0) {
  1112. $rtn .= "<br>PIDM: $student_pidm";
  1113. }
  1114. if ($school_name) {
  1115. $rtn .= "<br>" . t("School:") . "<em>$school_name</em>";
  1116. }
  1117. $rtn .= "</h2>
  1118. <table border='0' cellspacing='0' cellpadding='6'>
  1119. <tr>
  1120. <th>Subject</th>
  1121. <th>Number</th>
  1122. <th>Grade</th>
  1123. <th>Hours</th>
  1124. <th>Term</th>
  1125. <th>Transfer?</th>
  1126. </tr>";
  1127. // So that we can sort our list of courses, we will add them to
  1128. // 2 arrays, one for local courses, one for transfer.
  1129. $local_array = array();
  1130. $transfer_array = array();
  1131. $pol = "even";
  1132. $local_hours = 0;
  1133. $transfer_hours = 0;
  1134. while($student->list_courses_taken->has_more()) {
  1135. $course = $student->list_courses_taken->get_next();
  1136. $subjectID = $course->subject_id;
  1137. $courseNum = $course->course_num;
  1138. $grade = $course->grade;
  1139. $hours = $course->get_hours_awarded();
  1140. $rnd = mt_rand(0,9999);
  1141. if (is_object($course->course_transfer)) {
  1142. $subjectID = $course->course_transfer->subject_id;
  1143. $courseNum = $course->course_transfer->course_num;
  1144. $grade = $course->course_transfer->grade;
  1145. $hours = $course->course_transfer->get_hours_awarded();
  1146. $transfer_hours += $hours;
  1147. }
  1148. else {
  1149. // local course
  1150. $local_hours += $hours;
  1151. }
  1152. $html_line = "
  1153. <td>$subjectID</td>
  1154. <td>$courseNum</td>
  1155. <td>$grade</td>
  1156. <td>$hours</td>
  1157. <td>$course->term_id</td>
  1158. <td>" . (($course->bool_transfer) ? "T" : "") . "</td>
  1159. ";
  1160. if ($course->bool_transfer) {
  1161. // The $rnd makes sure this is unique, in case a course is showing as repeated in the same term.
  1162. $transfer_array["$course->term_id~$subjectID~$courseNum~$rnd"] = $html_line;
  1163. }
  1164. else {
  1165. // The $rnd makes sure this is unique, in case a course is showing as repeated in the same term.
  1166. $local_array["$course->term_id~$subjectID~$courseNum~$rnd"] = $html_line;
  1167. }
  1168. }
  1169. // Okay, now let's sort our arrays and display them.
  1170. ksort($transfer_array);
  1171. ksort($local_array);
  1172. foreach($local_array as $line) {
  1173. $rtn .= "<tr class='zebra-$pol'>$line</tr>";
  1174. $pol = ($pol == "even")?"odd":"even";
  1175. }
  1176. foreach($transfer_array as $line) {
  1177. $rtn .= "<tr class='zebra-$pol'>$line</tr>";
  1178. $pol = ($pol == "even")?"odd":"even";
  1179. }
  1180. $rtn .= "</table>
  1181. <hr>
  1182. ";
  1183. $rtn .= "<p>" . count($local_array) . " local courses, with $local_hours hours.</p>";
  1184. $rtn .= "<p>" . count($transfer_array) . " transfer courses, with $transfer_hours hours.</p>";
  1185. watchdog('stats', "report_student_course_list student_id:$student_cwid, school_id:$school_id, student_name:$student_name", array());
  1186. return $rtn;
  1187. }
  1188. /**
  1189. * Main menu screen for this module.
  1190. *
  1191. * We will simply display the "menu block" for "stats/reports". That is,
  1192. * any path that begins with stats/reports will show up here.
  1193. *
  1194. * You can create a report in your custom module, and as long as the url begins
  1195. * with stats/reports, and the menu item is of type "MENU_TYPE_NORMAL_ITEM"
  1196. * it will appear on this page. Set the weight to be > 1000 to appear below this list,
  1197. * set weight < 100 to appear above.
  1198. *
  1199. * @return string
  1200. */
  1201. function stats_display_main() {
  1202. $rtn = "";
  1203. $rtn .= "<div class='stats-main-menu'>";
  1204. $rtn .= fp_render_menu_block("System Reports", "stats/reports");
  1205. $rtn .= "</div>";
  1206. // If we have other reports which have been exposed using the hook_stats_additional_menublocks function,
  1207. // display them here.
  1208. $reports = invoke_hook('stats_additional_menublocks');
  1209. if ($reports) {
  1210. foreach ($reports as $module_name => $temp) {
  1211. $extraclass = "";
  1212. $extraclass .= "stats-menublock-path-" . strtolower(fp_get_machine_readable(current($reports[$module_name])));
  1213. $rtn .= "<div class='stats-main-menu stats-additional-menublocks $extraclass'>";
  1214. foreach($reports[$module_name] as $title => $menu_block_path) {
  1215. $rtn .= fp_render_menu_block($title, $menu_block_path);
  1216. }
  1217. $rtn .= "</div>";
  1218. }
  1219. }
  1220. return $rtn;
  1221. }

Functions

Namesort descending Description
stats_display_main Main menu screen for this module.
stats_download_csv_from_batch Lets the user download a CSV file from a completed batch.
stats_download_csv_from_batch_file Lets the user download a CSV file from a completed batch, from a file created during the batch operation.
stats_draw_catalog_year_pulldown Return the HTML for a pulldown containing the catalog years available for selection.
stats_draw_date_range_form Displays the HTML for the date range form used by several reports. $path is what is the form's ACTION sending to.
stats_draw_majors_pulldown Display a major selection pulldown, used by other reports.
stats_get_log_count Used by the use_summary report. This function will simply return log counts for the specified parameters in the watchdog table.
stats_menu Implementation of hook_menu
stats_perm Implementation of hook_perm(). Expects to return an array of permissions recognized by this module.
stats_report_access_stats This report shows recent activity in FlightPath. It can also be used to see if anyone is "online" in that they would have activity less than 5 minutes old.
stats_report_advisor_use This report shows which advisors are using FlightPath most often.
stats_report_course_use_summary This report will display everywhere a particular course is used in FlightPath (groups and degrees)
stats_report_flightpath_use_summary This report shows common usages in FlightPath by all users.
stats_report_major_counts This report shows how many students are in each major.
stats_report_student_course_list This report shows a list of all of a student's courses which FlightPath is aware of.
stats_select_school_form
stats_select_school_form_submit