student_search.module

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

File

modules/student_search/student_search.module
View source
  1. <?php
  2. /**
  3. * Meant to return results of the ajax autocomplete field, for selecting a student by name or cwid.
  4. * Code inspiration from: https://www.drupal.org/node/854216
  5. *
  6. * Output format can be: default, cwid_pound_name
  7. * default = First Last (CWID)
  8. * cwid_pound_name = CWID # First Last
  9. *
  10. */
  11. function student_search_ajax_autocomplete_student($output_format = "default") {
  12. $term = $_GET['term']; // this is what the user is starting to type.
  13. // actually search based on this term. make use of the studentsearch module
  14. // Use the student_search module to query based on what we've typed so far.
  15. $_REQUEST["search_for"] = $term;
  16. $form = student_search_search_form();
  17. $matches = array();
  18. // Result will be in $form['adv_array']['value'];
  19. //watchdog('debug', pretty_print($form['adv_array']['value'], TRUE), array(), WATCHDOG_DEBUG);
  20. $adv_array = $form['adv_array']['value'];
  21. if (is_array($adv_array)) {
  22. foreach ($adv_array as $cwid => $details) {
  23. $line = "";
  24. if ($output_format == 'cwid_pound_name') {
  25. // Output like: 12345 # first last
  26. $line = "$cwid # " . $details['first_name'] . " " . $details['last_name'];
  27. }
  28. else {
  29. // default
  30. $line = $details['first_name'] . " " . $details['last_name'] . " ($cwid)";
  31. }
  32. $matches[] = $line;
  33. }
  34. }
  35. header('Content-Type: application/json');
  36. print json_encode($matches);
  37. die;
  38. }
  39. function student_search_menu() {
  40. $items = array();
  41. $items["admin/config/student-search-settings"] = array(
  42. "title" => "Student Search settings",
  43. "description" => "Configure settings for the Student Search function",
  44. "page_callback" => "fp_render_form",
  45. "page_arguments" => array("student_search_settings_form", "system_settings"),
  46. "access_arguments" => array("administer_student_search"),
  47. "page_settings" => array(
  48. "menu_icon" => fp_get_module_path('student_search') . "/icons/database_gear.png",
  49. "page_hide_report_error" => TRUE,
  50. "menu_links" => array(
  51. 0 => array(
  52. "text" => "Admin Console",
  53. "path" => "admin-tools/admin",
  54. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  55. ),
  56. ),
  57. ),
  58. "type" => MENU_TYPE_NORMAL_ITEM,
  59. "tab_parent" => "admin-tools/admin",
  60. );
  61. $items['student-search/autocomplete-student/%'] = array(
  62. 'page_callback' => 'student_search_ajax_autocomplete_student',
  63. 'page_arguments' => array(2),
  64. 'access_arguments' => array('access_logged_in_content'),
  65. 'type' => MENU_TYPE_CALLBACK,
  66. );
  67. $items["student-search"] = array(
  68. "title" => t("Advisees"),
  69. "page_callback" => "student_search_subtab_switchboard",
  70. "access_callback" => "search_user_can_search_for_some_advisees",
  71. "type" => MENU_TYPE_NORMAL_ITEM,
  72. "weight" => 20,
  73. );
  74. $items["student-select"] = array(
  75. "page_callback" => "student_search_student_select_switchboard",
  76. "access_callback" => "search_user_can_search_for_some_advisees",
  77. "type" => MENU_TYPE_NORMAL_ITEM,
  78. "weight" => 20,
  79. );
  80. $items["student-search/my-advisees"] = array(
  81. "title" => t("My Advisees"),
  82. "page_callback" => "student_search_display_my_advisees",
  83. "access_arguments" => array("display_my_advisees_subtab"),
  84. "type" => MENU_TYPE_TAB,
  85. "tab_family" => "student_search",
  86. "page_settings" => array (
  87. "screen_mode" => "not_advising",
  88. ),
  89. "weight" => 10,
  90. );
  91. $items["student-search/search"] = array(
  92. "title" => t("Search"),
  93. "page_callback" => "fp_render_form",
  94. "page_arguments" => array("student_search_search_form"),
  95. "access_arguments" => array("display_search_subtab"),
  96. "type" => MENU_TYPE_TAB,
  97. "tab_family" => "student_search",
  98. "page_settings" => array (
  99. "screen_mode" => "not_advising",
  100. "page_has_search" => TRUE,
  101. ),
  102. "weight" => 30,
  103. );
  104. return $items;
  105. }
  106. /**
  107. * The user has selected a student (clicked on a row) from the Search or My Advisees screen.
  108. *
  109. * We now decide where the user is sent to, based on their settings.
  110. * Ex: Do they go to the Student Profile page, do they go to the Degree tab, etc?
  111. */
  112. function student_search_student_select_switchboard() {
  113. // As in the advise_display_view, we need to "initialize" this student fresh...
  114. global $user, $fp, $degree_plan, $screen, $current_student_id;
  115. // Do we need to rebuild the course inventory cache?
  116. if (system_check_course_inventory_should_be_reloaded()) {
  117. system_reload_and_cache_course_inventory();
  118. }
  119. $GLOBALS["fp_advising"]["advising_what_if"] = "no";
  120. $_REQUEST["advising_what_if"] = "no";
  121. // Initialize everything we need to initialize for this advising session.
  122. advise_init_screen();
  123. $_SESSION["last_student_selected"] = $current_student_id;
  124. // At this point, we decide where they are going to be redirected to, using fp_goto.
  125. $goto_tab = @$user->settings['default_student_load_tab'];
  126. if (!$goto_tab || $goto_tab == "") {
  127. // No specific setting, so use the system's default setting.
  128. $goto_tab = variable_get('system_default_student_load_tab', 'profile');
  129. }
  130. ////////////////////////
  131. // Make sure the "goto_tab" has not been disabled in the System Settings. If it has, we will default to "degree".
  132. $disabled_tabs = variable_get('system_disable_student_tabs', array());
  133. if (($disabled_tabs[$goto_tab] ?? '') == $goto_tab) {
  134. $goto_tab = 'degree';
  135. }
  136. if ($goto_tab == "profile") {
  137. fp_goto("student-profile");
  138. }
  139. if ($goto_tab == 'engagements') {
  140. fp_goto("engagements");
  141. }
  142. if ($goto_tab == "degree") {
  143. // Do we mean their normal "view" URL, or do we mean What If?
  144. $query = "";
  145. $path = "view";
  146. if (@$_REQUEST['what_if_major_code'] != "") {
  147. $path = "what-if";
  148. //&what_if_major_code=$what_if_major_code&what_if_track_code=$what_if_track_code&what_if_catalog_year=$what_if_catalog_year
  149. $query = "what_if_major_code=" . filter_untrusted_input(@$_REQUEST['what_if_major_code']) . "&what_if_track_code=" . filter_untrusted_input(@$_REQUEST['what_if_track_code']) . "&what_if_catalog_year=" . filter_untrusted_input(@$_REQUEST['what_if_catalog_year']);
  150. }
  151. fp_goto($path, $query);
  152. }
  153. return "";
  154. }
  155. /**
  156. * This is a system_settings form for configuring our module.
  157. *
  158. */
  159. function student_search_settings_form() {
  160. $form = array();
  161. $form["extra_student_search_conditions"] = array(
  162. "type" => "textarea",
  163. "label" => t("Extra student search conditions:"),
  164. "value" => variable_get("extra_student_search_conditions", ""),
  165. "description" => t("This is mysql which will get appended to end of the WHERE clause of every query
  166. relating to searching for students. It is so you can easily add global conditions,
  167. especially if you are overriding the student_search module. For example,
  168. to check that the students are admitted or enrolled. If you are unsure what to do, leave this blank."),
  169. );
  170. // TODO: This setting isn't really necessary anymore. We should just add is_active = 1 to the stats/report that uses it.
  171. $form["enrolled_student_search_conditions"] = array(
  172. "type" => "textarea",
  173. "label" => t("Enrolled student search conditions:"),
  174. "value" => variable_get("enrolled_student_search_conditions", " AND is_active = 1 "),
  175. "description" => t("<b>Soon to be deprecated.</b> Similar to the one above it, this is a clause which will only bring up students
  176. who are enrolled at the university, and taking courses. This might be identical to the
  177. one above it. At the moment, this is only being used in the Stats module, and not
  178. for any logic in FlightPath, so you should consider it optional.
  179. <br>Default is: AND is_active = 1 "),
  180. );
  181. return $form;
  182. }
  183. /**
  184. * The primary purpose of this function is to decide which
  185. * "sub tab" function to send the user off to. This is based
  186. * on whatever their previous selection was.
  187. */
  188. function student_search_subtab_switchboard() {
  189. //$last_tab = $_SESSION["student_search_last_tab"];
  190. $last_tab = $_SESSION["student_search_last_tab"] ?? '';
  191. if ($last_tab == "") {
  192. $last_tab = 'search';
  193. // TODO: If the user has a setting for this, use that instead.
  194. }
  195. fp_goto("student-search/$last_tab");
  196. }
  197. /**
  198. * This is meant to be called directly from the theme template, to draw
  199. * the small search box in the corner of the screen.
  200. *
  201. * As such, we need to include any javascript we need here, rather than using
  202. * fp_add_js.
  203. */
  204. function student_search_render_small_search() {
  205. global $current_student_id;
  206. $rtn = "";
  207. $url = fp_url("student-search/search");
  208. $rtn .= "<form action='" . $url . "' method='post' id='small-search-form' >
  209. <input type='text' class='smallinput' name='search_for' id='search_bar_value' autocomplete='off' placeholder = '" . t("Search students by name or CWID") . "'>
  210. <a href='javascript:void(0);' class='small-search-submit' onClick='this.closest(\"form\").submit();'><i class='fa fa-search'></i></a>
  211. <input type='hidden' name='current_student_id' value='$current_student_id'>
  212. <input type='hidden' name='did_search' value='true'>
  213. </form>
  214. ";
  215. return $rtn;
  216. }
  217. /**
  218. * Displays this user's advisees, if there are any assigned.
  219. */
  220. function student_search_display_my_advisees($bool_only_return_adv_array = FALSE, $use_cwid = NULL, $force_school_id = NULL, $limit = 20) {
  221. global $user, $pager_total_items;
  222. $rtn = "";
  223. fp_set_title('');
  224. $_SESSION["student_search_last_tab"] = "my-advisees";
  225. if ($use_cwid == NULL) {
  226. $faculty_cwid = $user->cwid;
  227. }
  228. else {
  229. $faculty_cwid = $use_cwid;
  230. }
  231. // Get all the school ids this user is allowed to search.
  232. $school_ids = student_search_get_school_ids_user_is_allowed_to_search();
  233. $school_id_list = join(",", $school_ids);
  234. if ($force_school_id != NULL) $school_id_list = intval($force_school_id);
  235. $query = "SELECT u.user_id, f_name, u.cwid, l_name, major_code, rank_code, a.catalog_year, priority_value, u.school_id
  236. FROM (users u, students a, advisor_student c, student_degrees d)
  237. LEFT JOIN student_priority ON (student_priority.student_id = u.cwid)
  238. WHERE
  239. c.faculty_id = :faculty_cwid
  240. AND c.student_id = a.cwid
  241. AND c.student_id = d.student_id
  242. AND u.cwid = a.cwid
  243. AND u.school_id IN ($school_id_list)
  244. AND u.is_student = 1
  245. AND u.is_disabled = 0
  246. AND rank_code IN %RANKIN%
  247. %EXTRA_STUDENTSEARCH_CONDITIONS%
  248. GROUP BY u.cwid
  249. %ORDERBY%
  250. ";
  251. $adv_array = student_search_query_advisees($query, array(":faculty_cwid" => $faculty_cwid), $limit, $bool_only_return_adv_array);
  252. if ($bool_only_return_adv_array) return $adv_array;
  253. $s = (count($adv_array) == 1) ? "" : "s";
  254. $rtn .= "<div class='student-search-my-advisees'>" . student_search_render_advisees($adv_array, t("My Advisees Results") . " &nbsp; ({$pager_total_items[0]} " . t("student$s") . ")") . "</div>";
  255. return $rtn;
  256. }
  257. /**
  258. * Basically, can the user see the "Advisees" tab at all?
  259. * The answer is TRUE if they have any of the permissions that let them do so.
  260. */
  261. function search_user_can_search_for_some_advisees() {
  262. if (user_has_permission("display_search_subtab")) return TRUE;
  263. if (user_has_permission("display_my_advisees_subtab")) return TRUE;
  264. return FALSE;
  265. }
  266. /**
  267. * Implementation of hook_perm
  268. *
  269. * @return array
  270. */
  271. function student_search_perm() {
  272. return array(
  273. "administer_student_search" => array(
  274. "title" => t("Administer Student Search"),
  275. "description" => t("Configure settings for the student search module."),
  276. ),
  277. "display_search_subtab" => array(
  278. "title" => t("Display Search subtab"),
  279. "description" => t("The user may view the Search subtab under the Advisees tab."),
  280. ),
  281. "display_my_advisees_subtab" => array(
  282. "title" => t("Display My Advisees subtab"),
  283. "description" => t("The user may view the My Advisees subtab under the Advisees tab."),
  284. ),
  285. /*
  286. "display_my_majors_subtab" => array(
  287. "title" => t("Display My Majors subtab"),
  288. "description" => t("The user may view the My Majors subtab under the Advisees tab."),
  289. ),
  290. "display_majors_subtab" => array(
  291. "title" => t("Display Majors subtab"),
  292. "description" => t("The user may view the Majors (search) subtab under the Advisees tab."),
  293. ),
  294. *
  295. */
  296. );
  297. }
  298. function student_search_get_school_ids_user_is_allowed_to_search($account = NULL) {
  299. global $user;
  300. if ($account == NULL) $account = $user;
  301. $rtn = array();
  302. $rtn[] = intval($account->school_id);
  303. // Go through permissions for what we are allowed to search
  304. if (module_enabled("schools")) {
  305. $defs = schools_get_school_definitions();
  306. foreach ($defs as $school_id => $name) {
  307. if (user_has_permission("search_students_$school_id")) {
  308. if (!in_array(intval($school_id), $rtn)) {
  309. $rtn[] = intval($school_id);
  310. }
  311. }
  312. }
  313. }
  314. if (!in_array(0, $rtn)) {
  315. $rtn[] = 0;
  316. }
  317. return $rtn;
  318. }
  319. /**
  320. * Returns an array of majors from the database, suitable for use with our Form API.
  321. */
  322. function student_search_get_majors_for_fapi() {
  323. global $user;
  324. $rtn = array();
  325. $extra_line = "";
  326. // Get all the school ids this user is allowed to search.
  327. $school_ids = student_search_get_school_ids_user_is_allowed_to_search();
  328. $school_id_list = join(",", $school_ids);
  329. $params = array();
  330. // Removing "group by major_code" line, as duplicate major codes in more than one school were not showing correctly in the select list.
  331. $res = db_query("SELECT * FROM degrees
  332. WHERE exclude = 0
  333. AND school_id IN ($school_id_list)
  334. $extra_line
  335. ORDER BY school_id, title
  336. ", $params);
  337. while ($cur = db_fetch_object($res)) {
  338. $degree_class_details = fp_get_degree_classification_details($cur->degree_class);
  339. // Exclude major codes if they are "degree options", meaning, the code has an
  340. // underscore in it.
  341. if (strpos($cur->major_code, "_")) continue;
  342. // If the title is risking being too long, let's truncate it
  343. $title = $cur->title;
  344. $max_chars = 50;
  345. if (strlen($title) > $max_chars) {
  346. $title = trim(substr($title, 0, $max_chars)) . "...";
  347. }
  348. $school_name = "";
  349. if (module_enabled("schools")) {
  350. $school_name = schools_get_school_name_for_id($cur->school_id);
  351. // Getting fancy. We are going to have optgroup in this set of options.
  352. $rtn[$school_name][$cur->major_code . "~~school_" . $cur->school_id] = "$cur->major_code : $title ({$degree_class_details["title"]})";
  353. }
  354. else {
  355. $rtn[$cur->major_code . "~~school_" . $cur->school_id] = "$cur->major_code : $title ({$degree_class_details["title"]})";
  356. }
  357. }
  358. return $rtn;
  359. }
  360. /**
  361. * Display the majors search sub-tab, where we can select a major and see the students
  362. * assigned to it.
  363. *
  364. */
  365. function student_search_display_majors_search($limit = 20) {
  366. global $user;
  367. $rtn = "";
  368. $_SESSION["student_search_last_tab"] = "majors-search";
  369. // Get the $major_code from the REQUEST, or from the user's saved settings.
  370. $major_code = fp_trim(@$_REQUEST["major_code"]);
  371. if ($major_code == "") {
  372. // Get from their settings
  373. $major_code = db_get_user_setting($user->id, "major_search");
  374. }
  375. else {
  376. // They did set something in the post. Save it to their settings.
  377. db_set_user_setting($user->id, "major_search", $major_code);
  378. }
  379. $url = fp_url("student-search/majors-search");
  380. $rtn .= "
  381. <form method='POST' action='" . $url . "'
  382. class='major-search-form'>
  383. <label>" . t("Select an available major from the list below:") . "</label>
  384. <br><select name='major_code'>
  385. <option value=''>- " . t("Please Select") . " -</option>
  386. ";
  387. // Do we have any extra settings for this search?
  388. $current_catalog_year = variable_get("current_catalog_year", 2006);
  389. $cur_only = variable_get("student_search_major_search_cur_year", FALSE);
  390. $extra_line = "";
  391. $params = array();
  392. if ($cur_only == TRUE) {
  393. $extra_line = " AND catalog_year = :cur_cat_year ";
  394. $params[":cur_cat_year"] = $current_catalog_year;
  395. }
  396. $res = db_query("SELECT * FROM degrees
  397. WHERE exclude = '0'
  398. $extra_line
  399. GROUP BY major_code
  400. ORDER BY title
  401. ", $params);
  402. while ($cur = db_fetch_object($res)) {
  403. $sel = ($major_code == $cur->major_code) ? "selected" : "";
  404. $degree_class_details = fp_get_degree_classification_details($cur->degree_class);
  405. // Exclude major codes if they are "degree options", meaning, the code has an
  406. // underscore in it.
  407. if (strpos($cur->major_code, "_")) continue;
  408. // If the title is risking being too long, let's truncate it
  409. $title = $cur->title;
  410. $max_chars = 50;
  411. if (strlen($title) > $max_chars) {
  412. $title = trim(substr($title, 0, $max_chars)) . "...";
  413. }
  414. $rtn .= "<option value='$cur->major_code' $sel>$cur->major_code : $title ({$degree_class_details["title"]})</option>";
  415. }
  416. $rtn .= "
  417. </select>
  418. <input type='submit' value='" . t("Search") . "'>
  419. </form>";
  420. $rtn .= student_search_get_advanced_search_tips();
  421. // Update the query to search for exact major code.
  422. $query = "SELECT u.user_id, f_name, l_name, u.cwid, major_code, rank_code, a.catalog_year
  423. FROM users u, students a, student_degrees b
  424. WHERE
  425. major_code = :major_code
  426. AND u.cwid = a.cwid
  427. AND u.cwid = b.student_id
  428. AND u.is_student = 1
  429. AND u.is_disabled = 0
  430. AND rank_code IN %RANKIN%
  431. %EXTRA_STUDENTSEARCH_CONDITIONS%
  432. ORDER BY %ORDERBY%
  433. ";
  434. $adv_array = student_search_query_advisees($query, array(":major_code" => $major_code), $limit);
  435. $s = (count($adv_array) == 1) ? "" : "s";
  436. $rtn .= student_search_render_advisees($adv_array, t("Major @major Results", array("@major" => $major_code)) . " &nbsp; ( " . count($adv_array) . " " . t("student$s") . " )");
  437. return $rtn;
  438. }
  439. /**
  440. * Displays students belonging to the current user's major code.
  441. */
  442. function student_search_display_my_majors() {
  443. global $user;
  444. $rtn = "";
  445. $_SESSION["student_search_last_tab"] = "my-majors";
  446. $adv_array = array();
  447. // Figure out this user's major_code from the faculty table.
  448. $db = get_global_database_handler();
  449. $faculty_user_major_code_csv = $db->get_faculty_major_code_csv($user->cwid);
  450. $temp = explode(",", $faculty_user_major_code_csv);
  451. foreach ($temp as $major_code) {
  452. $major_code = trim($major_code);
  453. if ($major_code == "") continue;
  454. $query = "SELECT u.user_id, f_name, l_name, u.cwid, major_code, rank_code, a.catalog_year
  455. FROM users u, students a, student_degrees b
  456. WHERE
  457. substring_index(major_code, '|', 1) = :major_code
  458. AND u.cwid = a.cwid
  459. AND u.cwid = b.student_id
  460. AND u.is_student = 1
  461. AND u.is_disabled = 0
  462. AND rank_code IN %RANKIN%
  463. %EXTRA_STUDENTSEARCH_CONDITIONS%
  464. GROUP BY u.cwid
  465. %ORDERBY%
  466. ";
  467. $adv_array = student_search_query_advisees($query, array(":major_code" => $major_code));
  468. $s = (count($adv_array) == 1) ? "" : "s";
  469. $rtn .= student_search_render_advisees($adv_array, t("Major @major Results", array("@major" => $major_code)) . " &nbsp; ( " . count($adv_array) . " " . t("student$s") . " )");
  470. }
  471. return $rtn;
  472. }
  473. function student_search_search_form() {
  474. $form = array();
  475. global $pager_total_items;
  476. fp_add_css(fp_get_module_path("student_search") . "/css/student_search.css");
  477. // Keep up with our last-visited tab
  478. $_SESSION["student_search_last_tab"] = "search";
  479. fp_set_title('');
  480. $search_for = '';
  481. if (isset($_REQUEST['search_for'])) {
  482. $search_for = trim($_REQUEST["search_for"]);
  483. }
  484. if ($search_for == "" && isset($_SESSION["student_search_for"])) {
  485. $search_for = trim($_SESSION["student_search_for"]);
  486. }
  487. else {
  488. $_SESSION['student_search_for'] = $search_for;
  489. }
  490. $o_search_for = $search_for;
  491. $major_code = '';
  492. if (isset($_REQUEST['major_code'])) {
  493. $major_code = trim($_REQUEST["major_code"]);
  494. }
  495. if ($major_code == "") {
  496. if (isset($_SESSION["student_search_major_code"])) {
  497. $major_code = trim($_SESSION["student_search_major_code"]);
  498. }
  499. }
  500. $selected_school_id = -1;
  501. $o_major_code = "";
  502. if ($major_code != "") {
  503. $o_major_code = $major_code;
  504. $temp = explode("~~school_", $major_code);
  505. $major_code = $temp[0];
  506. if (isset($temp[1])) {
  507. $selected_school_id = intval($temp[1]);
  508. }
  509. }
  510. $form['search_for'] = array(
  511. 'label' => t('Search for students by name or CWID:'),
  512. 'type' => 'search',
  513. 'value' => $o_search_for,
  514. );
  515. // Also show the majors as a list.
  516. $options = array('' => t(" - All Majors -")) + student_search_get_majors_for_fapi();
  517. $form['major_code'] = array(
  518. 'label' => t('Search within major:'),
  519. 'type' => 'select',
  520. 'options' => $options,
  521. 'value' => $o_major_code,
  522. 'hide_please_select' => TRUE,
  523. );
  524. $form['submit_btn'] = array(
  525. 'type' => 'submit',
  526. 'value' => t("Search"),
  527. );
  528. $form['reset_btn'] = array(
  529. 'type' => 'submit',
  530. 'value' => t("Reset"),
  531. );
  532. $search_options = @$_SESSION["student_search_search_options"];
  533. $form['search_options'] = array(
  534. 'label' => 'Options:',
  535. 'type' => 'checkboxes',
  536. 'options' => array('inactive' => t('Include inactive students')),
  537. 'value' => $search_options,
  538. );
  539. /////////////////////////////////////////
  540. // Logic to query for searched students
  541. /////////////////////////////////////////
  542. $mark = "";
  543. // If the user entered an asterisk with their search, we will
  544. // skip the extra search conditions (and show more results).
  545. $bool_bypass_extra_search_conditions = FALSE;
  546. if (strstr($search_for, "*")) {
  547. $bool_bypass_extra_search_conditions = TRUE;
  548. $search_for = trim(str_replace("*", "", $search_for));
  549. }
  550. // If the user entered an =, then remove all spaces from the query.
  551. if (strstr($search_for, "=")) {
  552. $search_for = trim(str_replace(" ", "", $search_for));
  553. }
  554. // remove trouble characters
  555. $search_for = str_replace("'","",$search_for);
  556. $search_for = str_replace('"','',$search_for);
  557. $search_action = '';
  558. $adv_array = array();
  559. //Get my list of advisees...
  560. // This time, we want to specify an SQL statement that will perform
  561. // our search.
  562. $params = array();
  563. if(strlen($search_for) > 2 || $major_code != "")
  564. { // If they typed something greater than 2 chars...
  565. if ($search_for) {
  566. $search_action = " AND (u.cwid LIKE :like_search_for1
  567. OR l_name LIKE :like_search_for2
  568. OR f_name LIKE :like_search_for3 )
  569. ";
  570. $params[":like_search_for1"] = "%$search_for%";
  571. $params[":like_search_for2"] = "%$search_for%";
  572. $params[":like_search_for3"] = "%$search_for%";
  573. $temp = explode(" ",$search_for);
  574. if (isset($temp[1]) && fp_trim(@$temp[1]) != "")
  575. {
  576. $fn = trim($temp[0]);
  577. $ln = trim($temp[1]);
  578. // If there was a comma, then these should be reversed,
  579. // as they probably entered last, first.
  580. if (strstr($search_for, ",")) {
  581. $ln = trim($temp[0]);
  582. $fn = trim($temp[1]);
  583. $ln = trim(str_replace(",", "", $ln)); // remove comma
  584. $fn = trim(str_replace(",", "", $fn)); // remove comma
  585. }
  586. $search_action = " AND (l_name LIKE :like_ln
  587. AND f_name LIKE :like_fn )
  588. ";
  589. $params[":like_ln"] = "%$ln%";
  590. $params[":like_fn"] = "%$fn%";
  591. // Remove unneeded like_search_for index.
  592. unset($params[":like_search_for1"]);
  593. unset($params[":like_search_for2"]);
  594. unset($params[":like_search_for3"]);
  595. }
  596. }
  597. $other_table = "";
  598. $major_search = "";
  599. if ($major_code != "")
  600. {
  601. $mjsearch = $major_code;
  602. $other_table = ", degrees b";
  603. $major_search = " AND substring_index(c.major_code,'|',1) = b.major_code
  604. AND b.school_id = :b_school_id
  605. AND (b.major_code LIKE :like_mjsearch ) ";
  606. $params[":like_mjsearch"] = "%$mjsearch%";
  607. $params[":b_school_id"] = $selected_school_id;
  608. //unset($params[':like_search_for']);
  609. }
  610. $group_by = " GROUP BY u.cwid ";
  611. ///////////////////////////////////////
  612. // Now THIS is odd... what is this strange piece of code here?
  613. // I'm no cryptographic genius, but it looks like it is set to display a message when
  614. // you search for "info=production" on the Students search...
  615. if (hash('sha256', (strtolower(@$search_for)))=="5b260fa2e077d779082ce7e5e7869554a7be02d537ae235a61a4387a9c853981"){
  616. $mark .= base64_decode("PHA+CjxiPlRoZSBvcmlnaW5hbCBGbGlnaHRQYXRoIFByb2R1Y3Rpb24gVGVhbSAodmVyc2lvbiAxLjApLCBjaXJjYSAyMDA3LCBhdCBUaGUgVW5pdmVyc2l0eSBvZiBMb3Vpc2lhbmEgTW9ucm9lOjwvYj4KPHVsPgo8bGk+UmljaGFyZCBQZWFjb2NrIC0gUHJvamVjdCBsZWFkIGFuZCBwcm9ncmFtbWVyLjwvbGk+CjxsaT5Kb2UgTWFuc291ciAtIFVMTSBtYWluZnJhbWUgZGF0YSBjb29yZGluYXRvci48L2xpPgo8bGk+Sm9hbm4gUGVycmVyIC0gVUxNIERhdGEgZW50cnkgYW5kIHRlc3RpbmcuPC9saT4KPGxpPlBhdWwgR3VsbGV0dGUgLSBDbGFzc2ljIHRoZW1lIGRlc2lnbmVyICh1c2VkIGJ5IHZlcnNpb25zIDEuMCB0aHJvdWdoIDQuMCkuPC9saT4KPGxpPjxiPk90aGVyIGNvbnRyaWJ1dGluZyBzdGFmZiBmcm9tIFVMTTwvYj46IEJhcmJhcmEgTWljaGFlbGlkZXMsIEFuZ2VsYSBSb2JpbnNvbiwgQ2hhcmxlcyBGcm9zdCwgQnJpYW4gVGF5bG9yLCBSb2IgR2xhemUuPC9saT4KPC91bD4KPHA+SW4gTWFyY2ggb2YgMjAxMywgdGhlIFVMTSBhZG1pbmlzdHJhdGlvbiBkZWNpZGVkIHRvIHJlbGVhc2UgRmxpZ2h0UGF0aCBhcyBvcGVuIHNvdXJjZSBpbiBvcmRlciB0byBlbnJpY2ggc2Nob29scyBhbmQgaW5zdGl0dXRpb25zIGFyb3VuZCB0aGUgd29ybGQuICBPdmVyIHRoZSB5ZWFycywgRmxpZ2h0UGF0aCBoYXMgYmVlbiByZS13cml0dGVuIGZyb20gc2NyYXRjaCA8Yj50d2ljZTwvYj4gYnkgUmljaGFyZCBQZWFjb2NrLCB3aG8gcmVtYWlucyB0aGUgcHJpbWFyeSBkZXZlbG9wZXIgb2YgdGhlIG9wZW4tc291cmNlIHZlcnNpb24sIGF2YWlsYWJsZSBhdCBodHRwczovL2dldGZsaWdodHBhdGguY29tLgo8YnI+PGJyPgpUbyBldmVyeW9uZSB3aG8gaGVscGVkIG1ha2UgRmxpZ2h0UGF0aCBwb3NzaWJsZTogPGVtPlRoYW5rIFlvdTwvZW0+Lgo8L3A+");
  617. }
  618. ///////////////////////////////////////
  619. // Get all the school ids this user is allowed to search.
  620. $school_ids = student_search_get_school_ids_user_is_allowed_to_search();
  621. $school_id_list = join(",", $school_ids);
  622. if ($selected_school_id !== -1) {
  623. // Meaning, a specific school was selected. So, we only want to return results of students from THAT school.
  624. $school_id_list = intval($selected_school_id);
  625. }
  626. $query = "SELECT u.user_id, f_name, l_name, u.cwid, rank_code, a.catalog_year, u.school_id, priority_value
  627. FROM (users u, students a, student_degrees c $other_table)
  628. LEFT JOIN student_priority ON (student_priority.student_id = u.cwid)
  629. WHERE
  630. u.cwid = a.cwid
  631. AND u.cwid = c.student_id
  632. AND u.is_student = 1
  633. AND u.school_id IN ($school_id_list)
  634. AND u.is_disabled = 0
  635. $search_action
  636. $major_search
  637. AND rank_code IN %RANKIN%
  638. %EXTRA_STUDENTSEARCH_CONDITIONS%
  639. ";
  640. if (!isset($search_options['inactive'])) {
  641. $query .= " AND is_active = 1 ";
  642. }
  643. $query .= "
  644. $group_by
  645. %ORDERBY%
  646. ";
  647. $adv_array = student_search_query_advisees($query, $params);
  648. }
  649. $s = (count($adv_array) == 1) ? "" : "s";
  650. $form['adv_array'] = array(
  651. 'type' => 'do_not_render',
  652. 'value' => $adv_array,
  653. );
  654. $student_count = @intval($pager_total_items[0]);
  655. $mark .= student_search_render_advisees($adv_array, t("Search Results") . " &nbsp; ($student_count " . t("student$s") . ")");
  656. $form['mark_search_results'] = array(
  657. 'type' => 'markup',
  658. 'value' => $mark,
  659. );
  660. return $form;
  661. } // search_form
  662. function student_search_search_form_submit($form, $form_state) {
  663. if (@$form_state['values']['reset_btn'] != "") {
  664. unset($_SESSION["student_search_for"]);
  665. unset($_SESSION["last_student_selected"]);
  666. unset($_SESSION["student_search_major_code"]);
  667. unset($_SESSION["student_search_search_options"]);
  668. return;
  669. }
  670. // Special for the search options (checkboxes). If none are checked, then
  671. // set it to _none=_none. This fixes a bug where checking to see if it isset() was always failing.
  672. if (@$form_state['values']['search_options'] == '') {
  673. $form_state['values']['search_options'] = array('_none' => '_none');
  674. }
  675. // Save values in session for next time.
  676. $_SESSION["student_search_for"] = @$form_state['values']['search_for'];
  677. $_SESSION["student_search_major_code"] = @$form_state['values']['major_code'];
  678. $_SESSION["student_search_search_options"] = @$form_state['values']['search_options'];
  679. fp_goto('student-search/search', 'did_search=true');
  680. } // search_form_submit
  681. /**
  682. * Simply returns the HTML to display the "advanced search tips" collapsible fieldset
  683. * and instructions.
  684. *
  685. */
  686. function student_search_get_advanced_search_tips() {
  687. $rtn = "";
  688. // Display advanced tips
  689. $advanced_tips_html = "
  690. <div class='student-search-advanced-tips'>
  691. " . t("@FlightPath displays students who are currently enrolled or are newly admitted for
  692. an upcoming term. Use the following tips to expand your search options:", array("@FlightPath" => variable_get("system_name", "FlightPath"))) . "
  693. <ul>
  694. <li>" . t("To search for inactive students, as well as active, add an asterisk (*)
  695. after your search.
  696. <br>&nbsp; &nbsp; &nbsp;
  697. Ex: <em>smith*</em> &nbsp; &nbsp; or &nbsp; &nbsp; <em>10035744*</em>") . "
  698. </li>
  699. <li>" . t("Search by major by typing major=CODE in the search box.
  700. <br>&nbsp; &nbsp; &nbsp;
  701. Ex: <em>major=ENGL</em> &nbsp; &nbsp; or &nbsp; &nbsp; <em>major=ENGL*</em>") . "
  702. </li>
  703. </ul>
  704. </div>";
  705. $rtn .= "<div class='student-search-advanced-tips-wrapper'>
  706. <label>" . t("Can't find the student you're looking for?") . "</label>
  707. " . fp_render_c_fieldset($advanced_tips_html, t("View advanced search tips"), TRUE) . "
  708. </div>";
  709. return $rtn;
  710. }
  711. function student_search_get_advisee_table_headers($bool_show_priority = TRUE) {
  712. $table_headers = array();
  713. $table_headers[] = array("label" => "&nbsp;");
  714. $table_headers[] = array("label" => t("CWID"), "field" => "u.cwid");
  715. $table_headers[] = array("label" => "Student", 'field' => 'l_name');
  716. if (module_enabled("schools")) {
  717. $table_headers[] = array("label" => "School");
  718. }
  719. $table_headers[] = array("label" => "Major");
  720. $table_headers[] = array("label" => "Rank", "field" => 'a.rank_code');
  721. $table_headers[] = array("label" => "Catalog<span class='mobile-hidden'> Year</span>", "field" => "a.catalog_year");
  722. if ($bool_show_priority) {
  723. $table_headers[] = array("label" => "<span class='mobile-hidden'>Academic </span>Priority", "field" => "priority_value");
  724. }
  725. return $table_headers;
  726. }
  727. function student_search_render_advisees($adv_array, $title) {
  728. $rtn = "";
  729. fp_add_css(fp_get_module_path("student_search") . "/css/student_search.css");
  730. fp_add_css(fp_get_module_path('student_profile') . '/css/style.css');
  731. $bool_redirect_one = FALSE;
  732. $url = '';
  733. if (count($adv_array) == 1 && @$_REQUEST["did_search"] == "true")
  734. {
  735. // Since there was only 1 result, we want to redirect this person directly.
  736. // Draw this person's name...
  737. $details = reset($adv_array);
  738. $student_id = $details["student_id"];
  739. $first_name = $details["first_name"];
  740. $last_name = $details["last_name"];
  741. $rtn .= "<div class='hypo' style='border: 1px solid black;
  742. margin: 10px 0px 10px 0px; padding: 10px;
  743. font-size: 12pt; font-weight: bold;'>
  744. " .t("Loading") . " $first_name $last_name ($student_id).
  745. &nbsp; " . t("Please wait...") . "
  746. </div>";
  747. $bool_redirect_one = TRUE;
  748. }
  749. $rtn .= fp_render_section_title($title, "search-results");
  750. // If we have disabled the student profile tab, then we will not display the Academic Priority here.
  751. $bool_show_priority = TRUE;
  752. $disabled_tabs = variable_get('system_disable_student_tabs', array());
  753. if (($disabled_tabs['profile'] ?? '') == 'profile') $bool_show_priority = FALSE;
  754. $table_headers = student_search_get_advisee_table_headers($bool_show_priority);
  755. $rtn .= "<table border='0' class='advisee-search-results-table'>";
  756. // Draw our our table headers, with links....
  757. $rtn .= theme_table_header_sortable($table_headers);
  758. $db = get_global_database_handler();
  759. foreach ($adv_array as $t => $details) {
  760. $student_id = $adv_array[$t]["student_id"];
  761. $first_name = $adv_array[$t]["first_name"];
  762. $last_name = $adv_array[$t]["last_name"];
  763. $major = $adv_array[$t]["major"];
  764. $school_id = $adv_array[$t]["school_id"];
  765. $priority_value = floatval($adv_array[$t]["priority_value"]);
  766. $advising_what_if = @$adv_array[$t]["advising_what_if"];
  767. $what_if_major_code = @$adv_array[$t]["what_if_major_code"];
  768. $what_if_track_code = @$adv_array[$t]["what_if_track_code"];
  769. $what_if_catalog_year = @$adv_array[$t]["what_if_catalog_year"];
  770. $degree_id = @$adv_array[$t]["degree_id"];
  771. $rank = @$adv_array[$t]["rank"];
  772. $catalog_year = @$adv_array[$t]["catalog_year"];
  773. // There is no $screen variable-- old code?
  774. //if ($screen->page_is_mobile) {
  775. // $catalog_year = get_shorter_catalog_year_range($catalog_year, false, true);
  776. //}
  777. $advising_session_id = $adv_array[$t]["advising_session_id"];
  778. $advised_image = $adv_array[$t]["advised_image"];
  779. $on_mouse = "
  780. onmouseover='$(this).addClass(\"selection_highlight\");'
  781. onmouseout='$(this).removeClass(\"selection_highlight\");'
  782. ";
  783. // Build up the URL we want to go to when we click this row.
  784. $path = 'student-select';
  785. /*
  786. $path = "view";
  787. $advising_what_if = "no";
  788. if ($what_if_major_code != "") {
  789. $path = "what-if";
  790. $advising_what_if = "yes";
  791. }
  792. */
  793. // Add in the query part.
  794. $query = "";
  795. $query .= "advising_student_id=$student_id&current_student_id=$student_id&advising_major_code=$major&advising_what_if=$advising_what_if";
  796. $query .= "&what_if_major_code=$what_if_major_code&what_if_track_code=$what_if_track_code&what_if_catalog_year=$what_if_catalog_year&advising_load_active=yes&clear_session=yes";
  797. $url = fp_url($path, $query);
  798. // old onCLick:
  799. //<!-- onClick='selectStudent(\"$student_id\",\"$major\",\"$what_if_major_code\",\"$what_if_track_code\")' -->
  800. $disp_major = "";
  801. $temp = csv_to_array($major);
  802. foreach ($temp as $code) {
  803. $csscode = fp_get_machine_readable($code);
  804. // Was this a track code or not? Meaning, did it contain |_
  805. $is_track = "no";
  806. if (strstr($code, "|_")) {
  807. $is_track = "yes";
  808. }
  809. $disp_major .= "<div class='ss-major-code ss-major-code-$csscode ss-major-code-is-track-$is_track'>$code</div>";
  810. }
  811. $student_name = "<span class='student-first-name student-fnf'>$first_name</span><span class='student-last-name'>$last_name</span>";
  812. $priority = t("N/A");
  813. if ($bool_show_priority && $priority_value > 0) {
  814. $temp = student_priority_get_student_academic_priority_label($priority_value);
  815. $machine = $temp['machine'];
  816. $label = $temp['label'];
  817. $priority = "<span class='profile-priority-bar priority-$machine'><span class='desc'>$label</desc></span>";
  818. }
  819. $rtn .= "
  820. <tr class='search-result-row' $on_mouse onClick='showUpdate(true); window.location=\"$url\"; '>
  821. <td class='ss-advised-image'>$advised_image</td>
  822. <td class='ss-student-id'>$student_id</td>
  823. <td class='ss-student-name'>$student_name</td>";
  824. if (module_enabled("schools")) {
  825. $rtn .= "<td class='ss-student-school'>" . schools_get_school_code_for_id($school_id) . "</td>";
  826. }
  827. $rtn .= "
  828. <td class='ss-student-major'>$disp_major</td>
  829. <td class='ss-student-rank'>$rank</td>
  830. <td class='ss-student-catalog-year'>$catalog_year</td>";
  831. if ($bool_show_priority) {
  832. $rtn .= "<td class='ss-student-priority-value'>$priority</td>";
  833. }
  834. $rtn .= "
  835. </tr>
  836. ";
  837. } // for t advisee array
  838. $rtn .= "</table>";
  839. $rtn .= theme_pager();
  840. if ($bool_redirect_one) {
  841. // There was only one result, and it was a search, so we want to redirect
  842. // this person.
  843. // We will use the URL we created in the foreach loop above. It will still contain exactly
  844. // what we need.
  845. $rtn .= "<script type='text/javascript'>
  846. $(document).ready(function() {
  847. setTimeout('fp_show_loading(\"" . t("Loading...") . "\");window.location=\"$url\";', 0);
  848. });
  849. </script>";
  850. }
  851. return $rtn;
  852. }
  853. /**
  854. * The limit is how many we will query, and also how many will appear on the page at one time.
  855. */
  856. function student_search_query_advisees($sql, $params = array(), $limit = 20, $bool_only_return_adv_array = FALSE) {
  857. $db = get_global_database_handler();
  858. $rank_in = "( '" . join("', '", csv_to_array(variable_get("allowed_student_ranks",''))) . "' )";
  859. $order_by = "";
  860. if (!$bool_only_return_adv_array) {
  861. $table_headers = student_search_get_advisee_table_headers();
  862. // Set our initial sort, if none is already set.
  863. theme_table_header_sortable_set_initial_sort('l_name', 'ASC');
  864. // Get our order by clause based on selected table header, if any.
  865. $order_by = theme_table_header_sortable_order_by($table_headers);
  866. }
  867. // Replace the replacement portion with our derrived variables.
  868. $sql = str_replace("%RANKIN%", $rank_in, $sql);
  869. $sql = str_replace("%ORDERBY%", $order_by, $sql); // now handled by the table header sortable function
  870. // By default, the extra_studentsearch_conditions will be adding nothing to the query. But, the user may override this
  871. // in the settings.
  872. $extra_student_search_conditions = variable_get("extra_student_search_conditions", "");
  873. $sql = str_replace("%EXTRA_STUDENTSEARCH_CONDITIONS%", $extra_student_search_conditions, $sql);
  874. // Returns an array of all of this teacher's advisees.
  875. $rtn_array = array();
  876. $r = 0;
  877. $faculty_advisees = advise_get_advisees();
  878. //$result = db_query($sql, $params);
  879. // Now, we are going to search for these students, in the form of a pager query.
  880. $result = pager_query($sql, $params, $limit, 0, NULL, "SELECT COUNT(DISTINCT(u.cwid))");
  881. while ($cur = db_fetch_array($result))
  882. {
  883. $student_id = trim($cur["cwid"]);
  884. // If this user does NOT have the "view any advising session" and DOES have the "view advisee advising sessions only",
  885. // then see if this student is in their advisees list before continuing.
  886. if (!user_has_permission("view_any_advising_session") && user_has_permission("view_advisee_advising_session")) {
  887. if (!in_array($student_id, $faculty_advisees)) {
  888. // Nope, this student is NOT one of their advisees! Skip it.
  889. continue;
  890. }
  891. }
  892. $rtn_array[$student_id]["student_id"] = $student_id;
  893. $rtn_array[$student_id]["school_id"] = intval($cur['school_id']);
  894. $rtn_array[$student_id]["first_name"] = ucwords(strtolower($cur["f_name"]));
  895. $rtn_array[$student_id]["last_name"] = ucwords(strtolower($cur["l_name"]));
  896. $rtn_array[$student_id]["rank"] = $cur["rank_code"];
  897. $rtn_array[$student_id]["catalog_year"] = $cur["catalog_year"];
  898. $rtn_array[$student_id]["priority_value"] = $cur["priority_value"];
  899. //$rtn_array[$r]["major"] = $cur["major_code"];
  900. // Need to get the major_code_csv for this student.
  901. // Are there more majors for this user?
  902. $major = "";
  903. // Get a CSV of this student's majors
  904. $major = fp_get_student_majors($student_id, TRUE, FALSE, FALSE);
  905. $rtn_array[$student_id]["major"] = $major;
  906. // We should also mark if the student has been advised for this semester
  907. // or not.
  908. // Get the current default advising term id.
  909. $term_id = variable_get_for_school("advising_term_id", "", $cur['school_id']);
  910. $advised_image = "";
  911. $advising_session_id = "";
  912. $res2 = db_query("SELECT * FROM advising_sessions WHERE
  913. student_id = ? AND
  914. term_id = ?
  915. AND is_draft = 0
  916. AND is_empty = 0
  917. AND delete_flag = 0
  918. ORDER BY posted DESC", $student_id, $term_id);
  919. if (db_num_rows($res2) > 0) {
  920. $cur = db_fetch_array($res2);
  921. $advised_image = "<img src='" . fp_theme_location() . "/images/small_check.gif' class='advisedImage'>";
  922. if ($cur["is_whatif"] == "1")
  923. { // Last advising was a What If advising.
  924. $advised_image = "<span title='This student was last advised in What If mode.'><img src='" . fp_theme_location() . "/images/small_check.gif'><sup>wi</sup></span>";
  925. $db_major_code_csv = $cur["major_code_csv"];
  926. $rtn_array[$student_id]["what_if_major_code"] = $db_major_code_csv;
  927. // Capture the catalog year that was saved with what_if
  928. $rtn_array[$student_id]["what_if_catalog_year"] = $cur["catalog_year"];
  929. $rtn_array[$student_id]["last_advised_what_if"] = TRUE;
  930. }
  931. }
  932. $rtn_array[$student_id]["advising_session_id"] = $advising_session_id;
  933. $rtn_array[$student_id]["advised_image"] = $advised_image;
  934. $r++;
  935. }
  936. return $rtn_array;
  937. }

Functions

Namesort descending Description
search_user_can_search_for_some_advisees Basically, can the user see the "Advisees" tab at all? The answer is TRUE if they have any of the permissions that let them do so.
student_search_ajax_autocomplete_student Meant to return results of the ajax autocomplete field, for selecting a student by name or cwid. Code inspiration from: https://www.drupal.org/node/854216
student_search_display_majors_search Display the majors search sub-tab, where we can select a major and see the students assigned to it.
student_search_display_my_advisees Displays this user's advisees, if there are any assigned.
student_search_display_my_majors Displays students belonging to the current user's major code.
student_search_get_advanced_search_tips Simply returns the HTML to display the "advanced search tips" collapsible fieldset and instructions.
student_search_get_advisee_table_headers
student_search_get_majors_for_fapi Returns an array of majors from the database, suitable for use with our Form API.
student_search_get_school_ids_user_is_allowed_to_search
student_search_menu
student_search_perm Implementation of hook_perm
student_search_query_advisees The limit is how many we will query, and also how many will appear on the page at one time.
student_search_render_advisees
student_search_render_small_search This is meant to be called directly from the theme template, to draw the small search box in the corner of the screen.
student_search_search_form
student_search_search_form_submit
student_search_settings_form This is a system_settings form for configuring our module.
student_search_student_select_switchboard The user has selected a student (clicked on a row) from the Search or My Advisees screen.
student_search_subtab_switchboard The primary purpose of this function is to decide which "sub tab" function to send the user off to. This is based on whatever their previous selection was.