_DatabaseHandler.php

  1. 5.x classes/_DatabaseHandler.php
  2. 4.x classes/_DatabaseHandler.php

Classes

NameDescription
_DatabaseHandler

File

classes/_DatabaseHandler.php
View source
  1. <?php
  2. class _DatabaseHandler extends stdClass
  3. {
  4. //
  5. public $dbc; // OLD. DEPRECATED
  6. public $pdo;
  7. function __construct()
  8. {
  9. $db_host = @$GLOBALS["fp_system_settings"]["db_host"];
  10. $db_port = @$GLOBALS["fp_system_settings"]["db_port"];
  11. $db_user = @$GLOBALS["fp_system_settings"]["db_user"];
  12. $db_pass = @$GLOBALS["fp_system_settings"]["db_pass"];
  13. $db_name = @$GLOBALS["fp_system_settings"]["db_name"];
  14. if ($db_host == "") return; // some problem, do not proceed with the attempt to construct.
  15. $db_host_ip = $db_host; // set as same as db_host for now.
  16. //$this->dbc = mysql_connect ($db_host, $db_user, $db_pass) or die('Could not connect to database: ' . mysql_error());
  17. //mysql_select_db ($db_name);
  18. // Connection by IP address is fastest, so let's always try to do that.
  19. // It can be time-consuming to convert our hostname to IP address. Cache it in our SESSION
  20. if (isset($_SESSION["fp_db_host_ip"])) {
  21. $db_host_ip = $_SESSION["fp_db_host_ip"];
  22. if (!$db_host_ip) $db_host_ip = $db_host;
  23. }
  24. else {
  25. // Convert our db_host into an IP address, then save to simple SESSION cache.
  26. $db_host_ip = trim(gethostbyname($db_host));
  27. if (!$db_host_ip) $db_host_ip = $db_host;
  28. $_SESSION["fp_db_host_ip"] = $db_host_ip;
  29. }
  30. // Connect using PDO
  31. if (!$this->pdo) {
  32. $this->pdo = new PDO("mysql:host=$db_host_ip;port=$db_port;dbname=$db_name;charset=utf8", $db_user, $db_pass,
  33. array(
  34. PDO::MYSQL_ATTR_LOCAL_INFILE => true,
  35. ));
  36. // Set our error handling... (using "silent" so I can catch errors in try/catch and display them, email, etc, if wanted.)
  37. $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  38. }
  39. }
  40. /**
  41. * This is a PHP "magic" function. Called during a serialize command.
  42. * Basically, we aren't trying to save any local variables.
  43. * In fact, we will get a fatal exception if we try to serialize our PDO connection.
  44. */
  45. function __sleep() {
  46. return array();
  47. }
  48. /**
  49. * This function is called when this objectis unserialized. We want to reconnect to the database, so we'll call our constructor.
  50. */
  51. function __wakeup() {
  52. $this->__construct();
  53. }
  54. function z__get_help_page($i)
  55. {
  56. depricated_message();
  57. $rtn_array = array();
  58. $res = $this->db_query("SELECT * FROM help WHERE `id`='?' ", $i);
  59. $cur = $this->db_fetch_array($res);
  60. $rtn_array["title"] = trim($cur["title"]);
  61. $rtn_array["body"] = trim($cur["body"]);
  62. return $rtn_array;
  63. }
  64. function z__add_to_log($action, $extra_data = "", $notes = "")
  65. {
  66. depricated_message();
  67. // Add a row to the log table.
  68. $ip = $_SERVER["REMOTE_ADDR"];
  69. $url = mysql_real_escape_string($_SERVER["REQUEST_URI"]);
  70. $user_id = $_SESSION["fp_user_id"];
  71. $user_type = $_SESSION["fp_user_type"];
  72. $user_name = mysql_real_escape_string($_SESSION["fp_user_name"]);
  73. $action = mysql_real_escape_string($action);
  74. $extra_data = mysql_real_escape_string($extra_data);
  75. $notes = mysql_real_escape_string($notes);
  76. if ($GLOBALS["fp_page_is_mobile"]) {
  77. $notes = "M:" . $notes;
  78. }
  79. // This needs to be mysql_query, instead of "this->db_query", because
  80. // otherwise it might get into an infinite loop.
  81. $now = time();
  82. $query = "INSERT INTO log (user_id,
  83. user_name, user_type, action, extra_data, notes,
  84. ip, posted, from_url) VALUES (
  85. '$user_id','$user_name','$user_type','$action','$extra_data',
  86. '$notes',
  87. '$ip', '$now' ,'$url') ";
  88. $res = mysql_query($query) or die(mysql_error() . " - " . $query);
  89. }
  90. /**
  91. * Sets the maintenance mode. $val should be either 0 (off) or 1 (on)
  92. *
  93. * @param integer $val
  94. */
  95. function set_maintenance_mode($val)
  96. {
  97. // Convenience function for setting maintenance mode. 0 = off, 1 = on.
  98. $this->set_settings_variable("maintenance_mode", $val);
  99. }
  100. function get_substitution_details($sub_id)
  101. {
  102. // Simply returns an associative array containing
  103. // the details of a substitution. The subID specified
  104. // is the actual id of the row of the database in
  105. // flightpath.student_substitutions.
  106. $rtn_array = array();
  107. $res = $this->db_query("SELECT * FROM student_substitutions
  108. WHERE id = '?' ", $sub_id);
  109. if ($this->db_num_rows($res) > 0)
  110. {
  111. $cur = $this->db_fetch_array($res);
  112. $rtn_array["faculty_id"] = $cur["faculty_id"];
  113. $rtn_array["remarks"] = trim($cur["sub_remarks"]);
  114. $rtn_array["sub_hours"] = $cur["sub_hours"];
  115. $rtn_array["required_course_id"] = $cur["required_course_id"];
  116. $rtn_array["required_group_id"] = $cur["required_group_id"];
  117. $rtn_array["posted"] = $cur["posted"];
  118. $rtn_array["required_degree_id"] = $cur["required_degree_id"];
  119. $rtn_array["db_record"] = $cur;
  120. }
  121. return $rtn_array;
  122. }
  123. function update_user_settings_from_post($user_id)
  124. {
  125. // This will retrieve various user settings from the POST
  126. // and write them to the user_settings table as XML.
  127. $db = new DatabaseHandler();
  128. if ($user_id*1 < 1)
  129. {
  130. return false;
  131. }
  132. // First, we need to GET the user's settings array...
  133. if (!$user_settings_array = $this->get_user_settings($user_id))
  134. {
  135. // No existing userSettingsArray, or it's corrupted.
  136. // Make a new one.
  137. $user_settings_array = array();
  138. }
  139. // Now, update values in the settingsArray, if they are
  140. // present in the POST.
  141. if (trim($_POST["hide_charts"]) != "")
  142. {
  143. $user_settings_array["hide_charts"] = trim($_POST["hide_charts"]);
  144. }
  145. // Now, write it back to the settings table...
  146. $res = $this->db_query("REPLACE INTO user_settings(user_id,
  147. settings, posted)
  148. VALUES ('?','?', '?' )", $user_id, serialize($user_settings_array), time());
  149. watchdog("update_user_settings", "Hide charts set to: @hide", array("@hide" => $user_settings_array["hide_charts"]));
  150. return true;
  151. }
  152. function get_user_settings($user_id)
  153. {
  154. // return an array of this user's current settings.
  155. $res = $this->db_query("SELECT * FROM user_settings
  156. WHERE
  157. user_id = '?' ", $user_id);
  158. $cur = $this->db_fetch_array($res);
  159. if (!$rtn = unserialize($cur["settings"])) {
  160. $rtn = array();
  161. }
  162. return $rtn;
  163. }
  164. function get_developmental_requirements($student_cwid)
  165. {
  166. // returns an array which states whether or not the student
  167. // requires any developmental requirements.
  168. $rtn_array = array();
  169. $res = $this->db_query("SELECT * FROM student_developmentals
  170. WHERE student_id = '?' ", $student_cwid);
  171. while($cur = $this->db_fetch_array($res)) {
  172. $rtn_array[] = $cur["requirement"];
  173. }
  174. return $rtn_array;
  175. }
  176. function z__get_table_transfer_data_string($table_name, $table_structure, $where_clause = "")
  177. {
  178. // This function will return a string of all the data
  179. // in a particular table, formatted with delimeters.
  180. // %R~ separates rows, %C~ separates columns.
  181. // We expect the tableStructure to be a csv of the
  182. // column names.
  183. $rtn = "";
  184. $res = mysql_query("select $table_structure from $table_name $where_clause") or die_and_mail(mysql_error());
  185. while ($cur = mysql_fetch_row($res))
  186. {
  187. $new_row = "";
  188. foreach($cur as $key => $value)
  189. { // put all the values returned together...
  190. $new_row .= $value . "%C~";
  191. }
  192. // Remove last %C%...
  193. $new_row = substr($new_row, 0, -3);
  194. // Add it to the rtn...
  195. $rtn .= $new_row . "%R~";
  196. }
  197. // Remove the last %R%...
  198. $rtn = substr($rtn, 0, -3);
  199. return $rtn;
  200. }
  201. /**
  202. * This is a simple helper function which "escapes" the question marks (?) in
  203. * the string, by changing them to "??". This makes it suitable for use
  204. * within db_query(), but not necessary if used as an argument. Ex:
  205. * db_query("INSERT ... '" . $db->escape_question_marks($xml) . "' "); is good.
  206. * db_query("INSERT ... '?' ", $xml); is good. This function not needed.
  207. *
  208. * @param unknown_type $str
  209. */
  210. function escape_question_marks($str) {
  211. $rtn = str_replace("?", "??", $str);
  212. return $rtn;
  213. }
  214. /**
  215. * This function is used to perform a database query. It uses PDO execute, which will
  216. * take automatically replace ? with variables you supply as the arguments to this function,
  217. * or as an array to this function. Either will work.
  218. * Do this by using ?, or naming the variable like :name or :age.
  219. *
  220. * For example:
  221. * $result = $db->db_query("SELECT * FROM table WHERE name = ? and age = ? ", $name, $temp_age);
  222. * or
  223. * $result = $db->db_query("SELECT * FROM table WHERE name = ? AND age = ? ", array($name, $temp_age));
  224. * or
  225. * $result = $db->db_query("SELECT * FROM table WHERE name = :name ", array(":name" => $name));
  226. *
  227. * @param unknown_type $sql_query
  228. * @return unknown
  229. */
  230. function db_query($sql_query, $args = array()) {
  231. // If there were any arguments to this function, then we must first apply
  232. // replacement patterns.
  233. $args = func_get_args();
  234. array_shift($args);
  235. if (isset($args[0]) && is_array($args[0])) {
  236. // If the first argument was an array, it means we passed an array of values instead
  237. // of passing them directly. So use them directly as our args.
  238. $args = $args[0];
  239. // If we were supplied an array, then we need to see if the NEW args[0] is an array... If it is, grab the first element AGAIN.
  240. if (isset($args[0]) && is_array($args[0])) {
  241. $args = $args[0];
  242. }
  243. }
  244. // We need to make sure that arguments are passed without being contained in single quotes ('?'). Should be just ?
  245. $sql_query = str_replace("'?'", "?", $sql_query);
  246. // If $c (number of replacements performed) does not match the number of replacements
  247. // specified, warn the user.
  248. /*
  249. * Don't do this anymore, as it might throw off queries that don't use ?'s, but instead use :var as the replacements.
  250. *
  251. if (substr_count($sql_query, "?") != count($args)) {
  252. fpm("<br><b>WARNING:</b> Replacement count does not match what was supplied to query: $sql_query<br><br>");
  253. }
  254. */
  255. //////////////////////////////////////////////
  256. // Run the sqlQuery and return the result set.
  257. if (!isset($this->pdo) || $this->pdo == NULL) fpm(debug_backtrace());
  258. try {
  259. $result = $this->pdo->prepare($sql_query);
  260. $result->execute($args);
  261. $_SESSION["fp_last_insert_id"] = $this->pdo->lastInsertId(); // capture last insert id, in case we ask for it later.
  262. return $result;
  263. }
  264. catch (Exception $ex) {
  265. // Some error happened!
  266. $this->db_error($ex);
  267. }
  268. /*
  269. $result = mysql_query($sql_query, $this->dbc);
  270. if ($result)
  271. {
  272. return $result;
  273. } else {
  274. // Meaning, the query failed...
  275. // Do nothing. Do not attempt to log anything, as that could cause an infinite loop.
  276. // Display the error on screen
  277. $this->db_error();
  278. }
  279. **/
  280. } // db_query
  281. /**
  282. * Draw out the error onto the screen.
  283. *
  284. */
  285. function db_error(Exception $ex)
  286. {
  287. global $user;
  288. $arr = $ex->getTrace();
  289. $when_ts = time();
  290. $when_english = format_date($when_ts);
  291. $message = $ex->getMessage();
  292. // If the message involves a complaint about the sql_mode, point the user to a
  293. // help page about setting the sql_mode.
  294. if (stristr($message, "sql_mode=")) {
  295. $message .= "<br><br><b>" . t("It appears this error is being caused because of your server's sql_mode setting.") . "</b> ";
  296. $message .= t("To set your sql_mode for MySQL, please see the following help page: <a href='http://getflightpath.com/node/1161' target='_blank'>http://getflightpath.com/node/1161</a>");
  297. }
  298. $file = $arr[2]["file"];
  299. if (strlen($file) > 50) {
  300. $file = "..." . substr($file, strlen($file) - 50);
  301. }
  302. $file_and_line = "Line " . $arr[2]["line"] . ": " . $file;
  303. // If we are on production, email someone!
  304. if (@$GLOBALS["fp_system_settings"]["notify_mysql_error_email_address"] != "")
  305. {
  306. $server = $_SERVER["SERVER_NAME"];
  307. $email_msg = t("A MYSQL error has occured in FlightPath.") . "
  308. Server: $server
  309. Timestamp: $when_ts ($when_english)
  310. Error:
  311. $message
  312. Location:
  313. $file_and_line
  314. Backtrace:
  315. " . print_r($arr, true) . "
  316. ";
  317. fp_mail($GLOBALS["fp_system_settings"]["notify_mysql_error_email_address"], "FlightPath MYSQL Error Reported on $server", $email_msg);
  318. }
  319. fpm(t("A MySQL error has occured:") . " $message<br><br>Location: $file_and_line<br><br>" . t("The backtrace:"));
  320. fpm($arr);
  321. if (@$GLOBALS["fp_die_mysql_errors"] == TRUE) {
  322. print "\n<br>The script has stopped executing because of a MySQL error:
  323. $message<br>
  324. Location: $file_and_line<br>\n
  325. Please fix the error and try again.<br>\n";
  326. print "<br><br>Timestamp: $when_ts ($when_english)
  327. <br><br>Program backtrace:
  328. <pre>" . print_r($arr, true) . "</pre>";
  329. die;
  330. }
  331. // Also, check to see if the mysql_err is because of a lost connection, as in, the
  332. // server went down. In that case, we should also terminate immediately, rather
  333. // than risk spamming an email recipient with error emails.
  334. if (stristr($message, "Lost connection to MySQL server")
  335. || stristr($message, "MySQL server has gone away")) {
  336. print "<h2 style='font-family: Arial, sans serif;'>Database Connection Error</h2>
  337. <br>
  338. <div style='font-size: 1.2em; font-family: Arial, sans serif; padding-left: 30px;
  339. padding-right: 30px;'>
  340. Sorry, but it appears the database is currently unavailable. This may
  341. simply be part of scheduled maintenance to the database server. Please
  342. try again in a few minutes. If the problem persists for longer
  343. than an hour, contact your technical support
  344. staff.
  345. </div>
  346. ";
  347. // DEV: Comment out when not needed.
  348. print "<pre>" . print_r($arr, TRUE) . "</pre>";
  349. die;
  350. }
  351. } // db_error
  352. /**
  353. * This function is used to perform a database query. It can take simple replacement patterns,
  354. * by using ?. If you actually need to have a ? in the query, you can escape it with ??.
  355. * For example:
  356. * $result = $db->db_query("SELECT * FROM table WHERE name = '?' and age = ? ", $name, $temp_age);
  357. *
  358. * @param unknown_type $sql_query
  359. * @return unknown
  360. */
  361. function z__db_query($sql_query) {
  362. // If there were any arguments to this function, then we must first apply
  363. // replacement patterns.
  364. $args = func_get_args();
  365. array_shift($args);
  366. if (isset($args[0]) && is_array($args[0])) {
  367. // If the first argument was an array, it means we passed an array of values instead
  368. // of passing them directly. So use them directly as our args.
  369. $args = $args[0];
  370. }
  371. // The query may contain an escaped ?, meaning "??", so I will replace that with something
  372. // else first, then change it back afterwards.
  373. $sql_query = str_replace("??", "~ESCAPED_Q_MARK~", $sql_query);
  374. // If $c (number of replacements performed) does not match the number of replacements
  375. // specified, warn the user.
  376. if (substr_count($sql_query, "?") != count($args)) {
  377. fpm("<br><b>WARNING:</b> Replacement count does not match what was supplied to query: $sql_query<br><br>");
  378. }
  379. if (count($args) > 0) {
  380. // Replace each occurance of "?" with what's in our array.
  381. foreach ($args as $replacement) {
  382. // Escape the replacement...
  383. // The replacement might ALSO have a question mark in it. Escape that too.
  384. if (strpos($replacement, "?") !== 0) {
  385. $replacement = str_replace("?", "~ESCAPED_Q_MARK~", $replacement);
  386. }
  387. // Because mysql_real_escape_string will allow \' to pass through, I am going to
  388. // first use mysql_real_escape_string on all slashes.
  389. $replacement = str_replace("\\" , mysql_real_escape_string("\\"), $replacement);
  390. // Okay, perform the replacement
  391. $replacement = mysql_real_escape_string($replacement);
  392. // If we have a $ followed by a number (like $99), preg_replace will remove it. So, let's escape the $ if so.
  393. /// if so.
  394. $replacement = addcslashes($replacement, '$');
  395. $sql_query = preg_replace("/\?/", $replacement, $sql_query, 1);
  396. }
  397. }
  398. $sql_query = str_replace("~ESCAPED_Q_MARK~", "?", $sql_query);
  399. //////////////////////////////////////////////
  400. // Run the sqlQuery and return the result set.
  401. if (!is_resource($this->dbc)) fpm(debug_backtrace());
  402. $result = mysql_query($sql_query, $this->dbc);
  403. if ($result)
  404. {
  405. return $result;
  406. } else {
  407. // Meaning, the query failed...
  408. // Do nothing. Do not attempt to log anything, as that could cause an infinite loop.
  409. // Display the error on screen
  410. $this->db_error();
  411. }
  412. }
  413. /**
  414. * Draw out the error onto the screen.
  415. *
  416. * @param unknown_type $sql
  417. */
  418. function z__db_error($msg = "")
  419. {
  420. $arr = debug_backtrace();
  421. $when_ts = time();
  422. $when_english = format_date($when_ts);
  423. $mysql_err = mysql_error();
  424. // If we are on production, email someone!
  425. if (@$GLOBALS["fp_system_settings"]["notify_mysql_error_email_address"] != "")
  426. {
  427. $server = $_SERVER["SERVER_NAME"];
  428. $email_msg = t("A MYSQL error has occured in FlightPath.") . "
  429. Server: $server
  430. Timestamp: $when_ts ($when_english)
  431. Error:
  432. $mysql_err
  433. Comments:
  434. $msg
  435. Backtrace:
  436. " . print_r($arr, true) . "
  437. ";
  438. fp_mail($GLOBALS["fp_system_settings"]["notify_mysql_error_email_address"], "FlightPath MYSQL Error Reported on $server", $email_msg);
  439. }
  440. fpm(t("A MySQL error has occured:") . " $mysql_err<br><br>" . t("The backtrace:"));
  441. fpm($arr);
  442. if (@$GLOBALS["fp_die_mysql_errors"] == TRUE) {
  443. print "\n<br>The script has stopped executing because of a MySQL error:
  444. $mysql_err<br>\n
  445. Please fix the error and try again.<br>\n";
  446. print "<br><br>Timestamp: $when_ts ($when_english)
  447. <br><br>Program backtrace:
  448. <pre>" . print_r($arr, true) . "</pre>";
  449. die;
  450. }
  451. // Also, check to see if the mysql_err is because of a lost connection, as in, the
  452. // server went down. In that case, we should also terminate immediately, rather
  453. // than risk spamming an email recipient with error emails.
  454. if (stristr($mysql_err, "Lost connection to MySQL server")
  455. || stristr($mysql_err, "MySQL server has gone away")) {
  456. print "<h2 style='font-family: Arial, sans serif;'>Database Connection Error</h2>
  457. <br>
  458. <div style='font-size: 1.2em; font-family: Arial, sans serif; padding-left: 30px;
  459. padding-right: 30px;'>
  460. Sorry, but it appears the database is currently unavailable. This may
  461. simply be part of scheduled maintenance to the database server. Please
  462. try again in a few minutes. If the problem persists for longer
  463. than an hour, contact your technical support
  464. staff.
  465. </div>
  466. ";
  467. die;
  468. }
  469. }
  470. function request_new_group_id()
  471. {
  472. // Return a valid new group_id...
  473. for ($t = 0; $t < 100; $t++)
  474. {
  475. $id = mt_rand(1,9999999);
  476. // Check for collisions...
  477. $res4 = $this->db_query("SELECT * FROM draft_group_requirements
  478. WHERE group_id = '$id' LIMIT 1");
  479. if ($this->db_num_rows($res4) == 0)
  480. { // Was not in the table already, so use it!
  481. return $id;
  482. }
  483. }
  484. return false;
  485. }
  486. function request_new_course_id()
  487. {
  488. // Return a valid new course_id...
  489. for ($t = 0; $t < 100; $t++)
  490. {
  491. $id = mt_rand(1,9999999);
  492. // Check for collisions...
  493. $res4 = $this->db_query("SELECT * FROM draft_courses
  494. WHERE course_id = '$id' LIMIT 1");
  495. if ($this->db_num_rows($res4) == 0)
  496. { // Was not in the table already, so use it!
  497. return $id;
  498. }
  499. }
  500. return false;
  501. }
  502. function load_course_descriptive_data($course = null, $course_id = 0)
  503. {
  504. $current_catalog_year = variable_get("current_catalog_year", "2006");
  505. $catalog_year = $current_catalog_year; // currentCatalogYear.
  506. if ($course != null)
  507. {
  508. $course_id = $course->course_id;
  509. $catalog_year = $course->catalog_year;
  510. }
  511. $cache_catalog_year = $catalog_year;
  512. $cache_catalog_year = 0;
  513. $array_valid_names = array();
  514. /* NOTE: This was never running it seems, so commenting it out.
  515. // First-- is this course in our GLOBALS cache for courses?
  516. // If it is, then load from that.
  517. if ($bool_load_from_global_cache == true &&
  518. $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["subject_id"] != "")
  519. {
  520. $subject_id = $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["subject_id"];
  521. $course_num = $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["course_num"];
  522. $title = $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["title"];
  523. $description = $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["description"];
  524. $min_hours = $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["min_hours"];
  525. $max_hours = $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["max_hours"];
  526. $repeat_hours = $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["repeat_hours"];
  527. $db_exclude = $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["db_exclude"];
  528. $array_valid_names = $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["array_valid_names"];
  529. // load this into the course object, if not null.
  530. return;
  531. }
  532. */
  533. if ($course_id != 0)
  534. {
  535. $res = $this->db_query("SELECT * FROM courses
  536. WHERE course_id = '?'
  537. AND catalog_year = '?'
  538. AND catalog_year <= '?'
  539. AND delete_flag = '0'
  540. AND exclude = '0' ", $course_id, $catalog_year, $current_catalog_year);
  541. $cur = $this->db_fetch_array($res);
  542. if ($this->db_num_rows($res) < 1)
  543. {
  544. // No results found, so instead pick the most recent
  545. // catalog year that is not excluded (keeping below the
  546. // current catalog year from the settings)
  547. //$this2 = new DatabaseHandler();
  548. $res2 = $this->db_query("SELECT * FROM courses
  549. WHERE `course_id`='?'
  550. AND `subject_id`!=''
  551. AND `delete_flag` = '0'
  552. AND `exclude`='0'
  553. AND `catalog_year` <= '?'
  554. ORDER BY `catalog_year` DESC LIMIT 1", $course_id, $current_catalog_year);
  555. $cur = $this->db_fetch_array($res2);
  556. if ($this->db_num_rows($res2) < 1)
  557. {
  558. // Meaning, there were no results found that didn't have
  559. // the exclude flag set. So, as a last-ditch effort,
  560. // go ahead and try to retrieve any course, even if it has
  561. // been excluded. (keeping below the
  562. // current catalog year from the settings)
  563. //$this3 = new DatabaseHandler();
  564. //
  565. $res3 = $this->db_query("SELECT * FROM courses
  566. WHERE course_id = '?'
  567. AND subject_id != ''
  568. AND delete_flag = '0'
  569. AND catalog_year <= '?'
  570. ORDER BY catalog_year DESC LIMIT 1", $course_id, $current_catalog_year);
  571. $cur = $this->db_fetch_array($res3);
  572. }
  573. }
  574. $title = $cur["title"];
  575. $description = trim($cur["description"]);
  576. $subject_id = trim(strtoupper($cur["subject_id"]));
  577. $course_num = trim(strtoupper($cur["course_num"]));
  578. $min_hours = $cur["min_hours"];
  579. $max_hours = $cur["max_hours"];
  580. $repeat_hours = $cur["repeat_hours"];
  581. if ($repeat_hours*1 < 1)
  582. {
  583. $repeat_hours = $max_hours;
  584. }
  585. $db_exclude = $cur["exclude"];
  586. $data_entry_comment = $cur["data_entry_comment"];
  587. // Now, lets get a list of all the valid names for this course.
  588. // In other words, all the non-excluded names. For most
  589. // courses, this will just be one name. But for cross-listed
  590. // courses, this will be 2 or more (probably just 2 though).
  591. // Example: MATH 373 and CSCI 373 are both valid names for that course.
  592. $res = $this->db_query("SELECT * FROM courses
  593. WHERE course_id = '?'
  594. AND exclude = '0' ", $course_id);
  595. while($cur = $this->db_fetch_array($res))
  596. {
  597. $si = $cur["subject_id"];
  598. $cn = $cur["course_num"];
  599. if (in_array("$si~$cn", $array_valid_names))
  600. {
  601. continue;
  602. }
  603. $array_valid_names[] = "$si~$cn";
  604. }
  605. }
  606. if ($description == "")
  607. {
  608. $description = "There is no course description available at this time.";
  609. }
  610. if ($title == "")
  611. {
  612. $title = "$subject_id $course_num";
  613. }
  614. // Now, to reduce the number of database calls in the future, save this
  615. // to our GLOBALS cache...
  616. $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["subject_id"] = $subject_id;
  617. $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["course_num"] = $course_num;
  618. $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["title"] = $title;
  619. $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["description"] = $description;
  620. $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["min_hours"] = $min_hours;
  621. $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["max_hours"] = $max_hours;
  622. $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["repeat_hours"] = $repeat_hours;
  623. $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["db_exclude"] = $db_exclude;
  624. $GLOBALS["fp_course_inventory"][$course_id][$cache_catalog_year]["array_valid_names"] = $array_valid_names;
  625. $GLOBALS["cache_course_inventory"] = true; // rebuild this cache before it closes.
  626. // Should we put all this into our course object?
  627. }
  628. function duplicate_course_for_year($course = null, $catalog_year)
  629. {
  630. // Duplicate the course for the given catalog_year.
  631. // If it already exists for that catalog_year, delete it from the
  632. // table.
  633. // In other words, copy all course data from some valid year into this
  634. // new year.
  635. $c = $course;
  636. $course_id = $c->course_id;
  637. $min_hours = $c->min_hours;
  638. $max_hours = $c->max_hours;
  639. if (@$c->bool_ghost_min_hour) {
  640. $min_hours = 0;
  641. }
  642. if (@$c->bool_ghost_hour) {
  643. $max_hours = 0;
  644. }
  645. $res = $this->db_query("DELETE FROM draft_courses WHERE
  646. course_id = '?' AND catalog_year = '?'
  647. AND subject_id = '?'
  648. AND course_num = '?' ", $course_id, $catalog_year, $c->subject_id, $c->course_num);
  649. $res2 = $this->db_query("INSERT INTO draft_courses(course_id,
  650. subject_id, course_num, catalog_year,
  651. title, description, min_hours, max_hours,
  652. repeat_hours, exclude) values (
  653. '?','?','?','?','?','?','?','?','?','?')
  654. ", $course_id, $c->subject_id,$c->course_num,$catalog_year,$c->title,$c->description,$min_hours,$max_hours,$c->repeat_hours,$c->db_exclude);
  655. }
  656. function update_course_requirement_from_name($subject_id, $course_num, $new_course_id)
  657. {
  658. // This will convert all instances of subject_id/course_num
  659. // to use the newCourseID. It looks through the requirements tables
  660. // that may have listed it as a requirement. We will
  661. // look specifically at the data_entry_value to do some of them.
  662. // ************ IMPORTANT ****************
  663. // This is used only by dataentry. It is intentionally
  664. // not doing the draft tables!
  665. $res = $this->db_query("UPDATE degree_requirements
  666. set `course_id`='?'
  667. where `data_entry_value`= ? ", $new_course_id, "$subject_id~$course_num") ;
  668. $res = $this->db_query("UPDATE group_requirements
  669. SET `course_id`='?'
  670. WHERE `data_entry_value`= ? ", $new_course_id, "$subject_id~$course_num") ;
  671. // Also update substitutions....
  672. $res = $this->db_query("UPDATE student_substitutions
  673. SET `sub_course_id`='?'
  674. WHERE `sub_entry_value`= ? ", $new_course_id, "$subject_id~$course_num") ;
  675. $res = $this->db_query("UPDATE student_substitutions
  676. SET `required_course_id`='?'
  677. WHERE `required_entry_value`= ? ", $new_course_id, "$subject_id~$course_num") ;
  678. // Also the advising histories....
  679. $res = $this->db_query("UPDATE advised_courses
  680. SET `course_id`='?'
  681. WHERE `entry_value`= ? ", $new_course_id, "$subject_id~$course_num") ;
  682. }
  683. function add_draft_instruction($text)
  684. {
  685. // Adds a new "instruction" to the draft_instructions table.
  686. // Simple insert.
  687. $res = $this->db_query("INSERT INTO draft_instructions
  688. (instruction) VALUES ('?') ", $text);
  689. }
  690. function update_course_id($from_course_id, $to_course_id, $bool_draft = false)
  691. {
  692. // This will convert *all* instances of "fromCourseID"
  693. // across every table that it is used, to toCourseID.
  694. // Use this function when you want to change a course's
  695. // course_id in the database.
  696. $table_array = array("advised_courses",
  697. "courses",
  698. "degree_requirements",
  699. "group_requirements",
  700. "student_unassign_group");
  701. if ($bool_draft)
  702. { // only do the draft tables...
  703. $table_array = array(
  704. "draft_courses",
  705. "draft_degree_requirements",
  706. "draft_group_requirements",
  707. );
  708. }
  709. // Do the tables where it's named "course_id"...
  710. foreach($table_array as $table_name)
  711. {
  712. $res = $this->db_query("UPDATE $table_name
  713. SET course_id = '?'
  714. WHERE course_id = '?' ", $to_course_id, $from_course_id);
  715. }
  716. $res = $this->db_query("update student_substitutions
  717. set `required_course_id`='?'
  718. where `required_course_id`='?' ", $to_course_id, $from_course_id);
  719. $res = $this->db_query("update student_substitutions
  720. set `sub_course_id`='?'
  721. where `sub_course_id`='?'
  722. and `sub_transfer_flag`='0' ", $to_course_id, $from_course_id);
  723. $res = $this->db_query("update transfer_eqv_per_student
  724. set `local_course_id`='?'
  725. where `local_course_id`='?' ", $to_course_id, $from_course_id);
  726. }
  727. /**
  728. * Given an advising_session_id, create a duplicate of it as a new session_id (and return the new session_id).
  729. *
  730. * All the values can be left blank to mean "keep what is in there". If they have values supplied in the arguments to this function,
  731. * then the new values will be used.
  732. */
  733. function duplicate_advising_session($advising_session_id, $faculty_id = "", $student_id = "", $term_id = "", $degree_id = "", $is_whatif = "", $is_draft = "") {
  734. $now = time();
  735. // First, get the details of this particular advising session....
  736. $res = db_query("SELECT * FROM advising_sessions WHERE advising_session_id = ?", $advising_session_id);
  737. $cur = db_fetch_array($res);
  738. // Get our values....
  739. $db_student_id = ($student_id == "") ? $cur["student_id"] : $student_id;
  740. $db_faculty_id = ($faculty_id == "") ? $cur["faculty_id"] : $faculty_id;
  741. $db_term_id = ($term_id == "") ? $cur["term_id"] : $term_id;
  742. $db_degree_id = ($degree_id == "") ? $cur["degree_id"] : $degree_id;
  743. $db_major_code_csv = $cur["major_code_csv"];
  744. $db_catalog_year = $cur["catalog_year"];
  745. $db_posted = $now;
  746. $db_is_whatif = ($is_whatif == "") ? $cur["is_whatif"] : $is_whatif;
  747. $db_is_draft = ($is_draft == "") ? $cur["is_draft"] : $is_draft;
  748. $db_is_empty = $cur["is_empty"];
  749. // Okay, let's INSERT this record, and capture the new advising_session_id...
  750. $res = db_query("INSERT INTO advising_sessions
  751. (student_id, faculty_id, term_id, degree_id, major_code_csv, catalog_year, posted, is_whatif, is_draft, is_empty)
  752. VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  753. ", $db_student_id, $db_faculty_id, $db_term_id, $db_degree_id, $db_major_code_csv, $db_catalog_year, $db_posted, $db_is_whatif, $db_is_draft, $db_is_empty);
  754. $new_asid = db_insert_id();
  755. // Okay, now pull out the advised_courses, and insert again under the new_asid...
  756. $res = db_query("SELECT * FROM advised_courses WHERE advising_session_id = ?", $advising_session_id);
  757. while ($cur = db_fetch_array($res)) {
  758. db_query("INSERT INTO advised_courses (advising_session_id, course_id, entry_value, semester_num, group_id, var_hours, term_id, degree_id)
  759. VALUES (?, ?, ?, ?, ?, ?, ?, ?)", $new_asid, $cur["course_id"], $cur["entry_value"], $cur["semester_num"], $cur["group_id"], $cur["var_hours"], $cur["term_id"], $cur["degree_id"]);
  760. }
  761. // Finished!
  762. return $new_asid;
  763. }
  764. function get_advising_session_id($faculty_id = "", $student_id = "", $term_id = "", $degree_id = "", $bool_what_if = false, $bool_draft = true, $bool_load_any_active_if_faculty_id_not_found = TRUE)
  765. {
  766. $is_what_if = "0";
  767. $is_draft = "0";
  768. $draft_line = " and `is_draft`='$is_draft' ";
  769. $faculty_line = " and `faculty_id`='$faculty_id' ";
  770. $advising_session_id = 0; // init
  771. if ($faculty_id == 0 || $faculty_id == "")
  772. { // If no faculty is specified, just get the first one to come up.
  773. $faculty_line = "";
  774. }
  775. if ($bool_what_if == true){$is_what_if = "1";}
  776. if ($bool_draft == true)
  777. {
  778. $is_draft = "1";
  779. $draft_line = "";
  780. // If we are told to pull up draft, we can safely
  781. // assume we just want the most recent save, whether it
  782. // is saved as a draft or not.
  783. }
  784. $query = "select * from advising_sessions
  785. where
  786. student_id = ?
  787. $faculty_line
  788. and term_id = ?
  789. and degree_id = ?
  790. and is_whatif = ?
  791. $draft_line
  792. order by `posted` desc limit 1";
  793. $result = $this->db_query($query, array($student_id, $term_id, $degree_id, $is_what_if)) ;
  794. if ($this->db_num_rows($result) > 0)
  795. {
  796. $cur = $this->db_fetch_array($result);
  797. $advising_session_id = $cur["advising_session_id"];
  798. return $advising_session_id;
  799. }
  800. if (intval($advising_session_id) < 1 && $bool_load_any_active_if_faculty_id_not_found) {
  801. // Meaning, we couldn't find a record for the supplied faculty_id. Let's just load the most recent active one, regardless
  802. // of faculty_id. Meaning, we need to make sure that is_draft = 0
  803. $query = "select * from advising_sessions
  804. where
  805. student_id = ?
  806. and term_id = ?
  807. and degree_id = ?
  808. and is_whatif = ?
  809. and is_draft = 0
  810. order by `posted` desc limit 1";
  811. $result = $this->db_query($query, array($student_id, $term_id, $degree_id, $is_what_if)) ;
  812. if ($this->db_num_rows($result) > 0) {
  813. $cur = $this->db_fetch_array($result);
  814. $advising_session_id = $cur["advising_session_id"];
  815. return $advising_session_id;
  816. }
  817. }
  818. return 0;
  819. }
  820. /**
  821. * Returns the group_id for the given group name, or FALSE
  822. */
  823. function get_group_name($group_id) {
  824. $temp = explode("_", $group_id);
  825. $group_id = trim(@$temp[0]);
  826. // If it's already in our static cache, just return that.
  827. static $group_name_cache = array();
  828. if (isset($group_name_cache[$group_id])) {
  829. return $group_name_cache[$group_id];
  830. }
  831. $res7 = $this->db_query("SELECT group_name FROM groups
  832. WHERE group_id = ?
  833. AND delete_flag = 0
  834. LIMIT 1 ", $group_id) ;
  835. if ($this->db_num_rows($res7) > 0)
  836. {
  837. $cur7 = $this->db_fetch_array($res7);
  838. // Save to our cache before returning.
  839. $group_name_cache[$group_id] = $cur7['group_name'];
  840. return $cur7['group_name'];
  841. }
  842. return FALSE;
  843. }
  844. function get_group_id($group_name, $catalog_year) {
  845. if ($catalog_year < $GLOBALS["fp_system_settings"]["earliest_catalog_year"])
  846. {
  847. $catalog_year = $GLOBALS["fp_system_settings"]["earliest_catalog_year"];
  848. }
  849. // If it's already in our static cache, just return that.
  850. static $group_id_cache = array();
  851. if (isset($group_id_cache[$group_name][$catalog_year])) {
  852. return $group_id_cache[$group_name][$catalog_year];
  853. }
  854. $res7 = $this->db_query("SELECT group_id FROM groups
  855. WHERE group_name = ?
  856. AND catalog_year = ?
  857. AND delete_flag = 0
  858. LIMIT 1 ", $group_name, $catalog_year) ;
  859. if ($this->db_num_rows($res7) > 0)
  860. {
  861. $cur7 = $this->db_fetch_array($res7);
  862. // Save to our cache
  863. $group_id_cache[$group_name][$catalog_year] = $cur7['group_id'];
  864. return $cur7['group_id'];
  865. }
  866. return false;
  867. }
  868. function request_new_degree_id()
  869. {
  870. // Return a valid new id...
  871. for ($t = 0; $t < 100; $t++)
  872. {
  873. $id = mt_rand(1,9999999);
  874. // Check for collisions...
  875. $res4 = $this->db_query("SELECT * FROM draft_degrees
  876. WHERE `degree_id`='?' limit 1", $id);
  877. if ($this->db_num_rows($res4) == 0)
  878. { // Was not in the table already, so use it!
  879. return $id;
  880. }
  881. }
  882. return false;
  883. }
  884. function get_institution_name($institution_id)
  885. {
  886. // Return the name of the institution...
  887. $res = $this->db_query("SELECT * FROM transfer_institutions
  888. where institution_id = '?' ", $institution_id);
  889. $cur = $this->db_fetch_array($res);
  890. return trim($cur['name']);
  891. }
  892. /**
  893. * Retrieve a value from the variables table.
  894. *
  895. * @param string $name
  896. */
  897. function get_variable($name, $default_value = "") {
  898. $res = $this->db_query("SELECT value FROM variables
  899. WHERE name = '?' ", $name);
  900. $cur = $this->db_fetch_array($res);
  901. $val = $cur["value"];
  902. if ($val == "") {
  903. $val = $default_value;
  904. }
  905. return $val;
  906. }
  907. /**
  908. * Sets a variable's value in the variables table.
  909. *
  910. * @param unknown_type $name
  911. * @param unknown_type $value
  912. */
  913. function set_variable($name, $value) {
  914. $res2 = $this->db_query("REPLACE INTO variables (name, value)
  915. VALUES ('?', '?') ", $name, $value);
  916. }
  917. function get_course_id($subject_id, $course_num, $catalog_year = "", $bool_use_draft = false)
  918. {
  919. // Ignore the colon, if there is one.
  920. if (strpos($course_num,":"))
  921. {
  922. //$course_num = substr($course_num,0,-2);
  923. $temp = explode(":", $course_num);
  924. $course_num = trim($temp[0]);
  925. }
  926. // Always override if the global variable is set.
  927. if (@$GLOBALS["fp_advising"]["bool_use_draft"] == true) {
  928. $bool_use_draft = true;
  929. }
  930. $catalog_line = "";
  931. if ($catalog_year != "")
  932. {
  933. $catalog_line = "and `catalog_year`='$catalog_year' ";
  934. }
  935. $table_name = "courses";
  936. if ($bool_use_draft){$table_name = "draft_$table_name";}
  937. $res7 = $this->db_query("SELECT course_id FROM $table_name
  938. WHERE subject_id = ?
  939. AND course_num = ?
  940. $catalog_line
  941. ORDER BY catalog_year DESC LIMIT 1 ", $subject_id, $course_num) ;
  942. if ($this->db_num_rows($res7) > 0)
  943. {
  944. $cur7 = $this->db_fetch_array($res7);
  945. return $cur7["course_id"];
  946. }
  947. return FALSE;
  948. }
  949. function get_student_settings($student_cwid)
  950. {
  951. // This returns an array (from the xml) of a student's
  952. // settings in the student_settings table. It will
  953. // return FALSE if the student was not in the table.
  954. $res = $this->db_query("SELECT settings FROM student_settings
  955. WHERE student_id = '?' ", $student_cwid) ;
  956. if ($this->db_num_rows($res) < 1)
  957. {
  958. return false;
  959. }
  960. $cur = $this->db_fetch_array($res);
  961. if (!$rtn = unserialize($cur["settings"])) {
  962. $rtn = array();
  963. }
  964. return $rtn;
  965. }
  966. function get_student_cumulative_hours($student_cwid) {
  967. // Let's perform our queries.
  968. $res = $this->db_query("SELECT cumulative_hours FROM students
  969. WHERE cwid = '?' ", $student_cwid);
  970. $cur = $this->db_fetch_array($res);
  971. return $cur["cumulative_hours"];
  972. }
  973. function get_student_gpa($student_cwid) {
  974. // Let's perform our queries.
  975. $res = $this->db_query("SELECT gpa FROM students
  976. WHERE cwid = '?' ", $student_cwid);
  977. $cur = $this->db_fetch_array($res);
  978. return $cur["gpa"];
  979. }
  980. function get_student_catalog_year($student_cwid) {
  981. // Let's perform our queries.
  982. $res = $this->db_query("SELECT catalog_year FROM students
  983. WHERE cwid = '?' ", $student_cwid);
  984. $cur = $this->db_fetch_array($res);
  985. $catalog = $cur["catalog_year"];
  986. $temp = explode("-", $catalog);
  987. return trim($temp[0]);
  988. }
  989. /**
  990. * Returns whatever is in the Rank field for this student.
  991. * Ex: JR, SR, FR, etc.
  992. *
  993. * @param unknown_type $student_id
  994. * @return unknown
  995. */
  996. function get_student_rank($student_cwid) {
  997. // Let's perform our queries.
  998. $res = $this->db_query("SELECT rank_code FROM students
  999. WHERE cwid = '?' ", $student_cwid);
  1000. $cur = $this->db_fetch_array($res);
  1001. $rank = $cur["rank_code"];
  1002. return trim($rank);
  1003. }
  1004. /**
  1005. * Returns the student's first and last name, put together.
  1006. * Ex: John Smith or John W Smith.
  1007. *
  1008. * @param int $student_id
  1009. * @return string
  1010. */
  1011. function get_student_name($cwid) {
  1012. // Let's perform our queries.
  1013. $res = $this->db_query("SELECT f_name, l_name FROM users
  1014. WHERE cwid = '?'
  1015. AND is_student = 1 ", $cwid);
  1016. $cur = $this->db_fetch_array($res);
  1017. $name = $cur["f_name"] . " " . $cur["l_name"];
  1018. // Force into pretty capitalization.
  1019. // turns JOHN SMITH into John Smith
  1020. $name = ucwords(strtolower($name));
  1021. return trim($name);
  1022. }
  1023. /**
  1024. * Returns the faculty's first and last name, put together.
  1025. * Ex: John Smith or John W Smith.
  1026. *
  1027. * @param int $faculty_id
  1028. * @return string
  1029. */
  1030. function get_faculty_name($cwid) {
  1031. // Let's pull the needed variables out of our settings, so we know what
  1032. // to query, because this is a non-FlightPath table.
  1033. //$tsettings = $GLOBALS["fp_system_settings"]["extra_tables"]["human_resources:faculty_staff"];
  1034. //$tf = (object) $tsettings["fields"]; //Convert to object, makes it easier to work with.
  1035. //$table_name = $tsettings["table_name"];
  1036. // Let's perform our queries.
  1037. $res = $this->db_query("SELECT f_name, l_name FROM users
  1038. WHERE cwid = '?'
  1039. AND is_faculty = '1' ", $cwid);
  1040. $cur = $this->db_fetch_array($res);
  1041. $name = $cur["f_name"] . " " . $cur["l_name"];
  1042. // Force into pretty capitalization.
  1043. // turns JOHN SMITH into John Smith
  1044. $name = ucwords(strtolower($name));
  1045. return trim($name);
  1046. }
  1047. /**
  1048. * Looks in our extra tables to find out what major code, if any, has been assigned
  1049. * to this faculty member.
  1050. *
  1051. */
  1052. function get_faculty_major_code_csv($faculty_cwid) {
  1053. // Let's pull the needed variables out of our settings, so we know what
  1054. // to query, because this is a non-FlightPath table.
  1055. $res = $this->db_query("SELECT major_code_csv FROM faculty WHERE cwid = '?' ", $faculty_cwid);
  1056. $cur = $this->db_fetch_array($res);
  1057. return @$cur["major_code_csv"];
  1058. }
  1059. // Deprecated, use the "_csv" version of this function instead.
  1060. function get_faculty_major_code($faculty_cwid) {
  1061. depricated_message("db->get_faculty_major_code() is deprecated. Use get_faculty_major_code_csv() instead.");
  1062. return $this->get_faculty_major_code_csv($faculty_cwid);
  1063. }
  1064. function get_student_major_from_db($student_cwid)
  1065. {
  1066. depricated_message("db->get_student_major_from_db() is deprecated. use get_student_major*s* instead.");
  1067. // Returns the student's major code from the DB. Does not
  1068. // return the track code.
  1069. // Let's perform our queries.
  1070. $res = $this->db_query("SELECT * FROM students
  1071. WHERE cwid = '?' ", $student_cwid);
  1072. $cur = $this->db_fetch_array($res);
  1073. return trim($cur["major_code"]);
  1074. }
  1075. /**
  1076. * Returns an array (or CSV string) of major_codes from the student_degrees table for this student.
  1077. *
  1078. * If bool_check_for_allow_dynaic is TRUE, it means that, if the student has more than one degree returned, we will make sure that they all
  1079. * have allow_dynamic = TRUE. If they do not, we will use the first is_editable degree we find ONLY. We do this because that means the student
  1080. * had a situation like we see in FlightPath 4x, where only one degree may be selected at a time, and the is_editiable degree is the track/option they
  1081. * selected.
  1082. *
  1083. *
  1084. */
  1085. function get_student_majors_from_db($student_cwid, $bool_return_as_full_record = FALSE, $perform_join_with_degrees = TRUE, $bool_skip_directives = TRUE, $bool_check_for_allow_dynamic = TRUE) {
  1086. // Looks in the student_degrees table and returns an array of major codes.
  1087. $rtn = array();
  1088. // Keep track of degrees which have is_editable set to 1.
  1089. $is_editable_true = array();
  1090. $is_editable_false = array();
  1091. if ($perform_join_with_degrees) {
  1092. $catalog_year = $this->get_student_catalog_year($student_cwid);
  1093. $res = $this->db_query("SELECT * FROM student_degrees a, degrees b
  1094. WHERE student_id = ?
  1095. AND a.major_code = b.major_code
  1096. AND b.catalog_year = ?
  1097. ORDER BY b.advising_weight, b.major_code
  1098. ", $student_cwid, $catalog_year);
  1099. }
  1100. else {
  1101. // No need to join with degrees table...
  1102. $res = $this->db_query("SELECT * FROM student_degrees a
  1103. WHERE student_id = ?
  1104. ORDER BY major_code
  1105. ", $student_cwid);
  1106. }
  1107. while ($cur = $this->db_fetch_array($res)) {
  1108. if ($bool_skip_directives && strstr($cur["major_code"], "~")) continue;
  1109. if ($bool_return_as_full_record) {
  1110. $rtn[$cur["major_code"]] = $cur;
  1111. }
  1112. else {
  1113. $rtn[$cur["major_code"]] = $cur["major_code"];
  1114. }
  1115. if ($bool_check_for_allow_dynamic && !isset($cur['allow_dynamic']) && isset($cur['degree_id'])) {
  1116. $cur['allow_dynamic'] = $this->get_degree_allow_dynamic($cur['degree_id']);
  1117. }
  1118. if ($cur['is_editable'] == 1) {
  1119. $is_editable_true[] = $cur;
  1120. }
  1121. else {
  1122. $is_editable_false[] = $cur;
  1123. }
  1124. }
  1125. if ($bool_check_for_allow_dynamic && count($rtn) > 1) {
  1126. // This means that we have more than one degree selected, and we have been asked to make sure that if any of the degrees have allow_dynamic = 0, then we will
  1127. // only select the is_editable degree.
  1128. foreach ($is_editable_false as $major) {
  1129. if (isset($major['allow_dynamic']) && $major['allow_dynamic'] == 0) {
  1130. // Meaning, allow dynamic is NOT allowed. So, if we have ANYTHING in is_editable_true, then use THAT, else, use THIS.
  1131. if (count($is_editable_true) > 0) {
  1132. // Only get out 1 major.
  1133. $x = $is_editable_true[0];
  1134. $new_rtn[$x['major_code']] = $rtn[$x['major_code']];
  1135. $rtn = $new_rtn;
  1136. }
  1137. else {
  1138. $x = $major;
  1139. $new_rtn[$x['major_code']] = $rtn[$x['major_code']];
  1140. $rtn = $new_rtn;
  1141. }
  1142. }
  1143. }
  1144. } // if bool_check_for_allow_dynamic
  1145. return $rtn;
  1146. }
  1147. function get_flightpath_settings()
  1148. {
  1149. // Returns an array of everything in the flightpath_settings table.
  1150. $rtn_array = array();
  1151. $res = $this->db_query("SELECT * FROM flightpath_settings ") ;
  1152. while($cur = $this->db_fetch_array($res))
  1153. {
  1154. $rtn_array[$cur["variable_name"]] = trim($cur["value"]);
  1155. }
  1156. return $rtn_array;
  1157. }
  1158. function get_degrees_in_catalog_year($catalog_year, $bool_include_tracks = false, $bool_use_draft = false, $bool_undergrad_only = TRUE, $only_level_nums = array(1,2))
  1159. {
  1160. // Returns an array of all the degrees from a particular year
  1161. // which are entered into FlightPath.
  1162. $undergrad_line = $degree_class_line = "";
  1163. $table_name = "degrees";
  1164. if ($bool_use_draft){$table_name = "draft_$table_name";}
  1165. // change this to be whatever the graduate code actually is.
  1166. if ($bool_undergrad_only) $undergrad_line = "AND degree_level != 'GR' ";
  1167. $degree_class_line = "";
  1168. if (count($only_level_nums) > 0) {
  1169. $classes = fp_get_degree_classifications();
  1170. foreach ($only_level_nums as $num) {
  1171. foreach ($classes["levels"][$num] as $machine_name => $val) {
  1172. $degree_class_line .= " degree_class = '" . addslashes($machine_name) . "' OR";
  1173. }
  1174. }
  1175. // Remove training "OR" from degree_class_line
  1176. $degree_class_line = substr($degree_class_line, 0, strlen($degree_class_line) - 2);
  1177. }
  1178. if ($degree_class_line != "") {
  1179. $degree_class_line = "AND ($degree_class_line)";
  1180. }
  1181. $rtn_array = array();
  1182. $res = $this->db_query("SELECT degree_id, major_code, title, degree_class FROM $table_name
  1183. WHERE exclude = '0'
  1184. AND catalog_year = ?
  1185. $undergrad_line
  1186. $degree_class_line
  1187. ORDER BY title, major_code ", $catalog_year);
  1188. if ($this->db_num_rows($res) < 1)
  1189. {
  1190. return false;
  1191. }
  1192. while ($cur = $this->db_fetch_array($res))
  1193. {
  1194. $degree_id = $cur["degree_id"];
  1195. $major = trim($cur["major_code"]);
  1196. $title = trim($cur["title"]);
  1197. $track_code = "";
  1198. $major_code = $major;
  1199. // The major may have a track specified. If so, take out
  1200. // the track and make it seperate.
  1201. if (strstr($major, "_"))
  1202. {
  1203. $temp = explode("_", $major);
  1204. $major_code = trim($temp[0]);
  1205. $track_code = trim($temp[1]);
  1206. // The major_code might now have a | at the very end. If so,
  1207. // get rid of it.
  1208. if (substr($major_code, strlen($major_code)-1, 1) == "|")
  1209. {
  1210. $major_code = str_replace("|","",$major_code);
  1211. }
  1212. }
  1213. // Leave the track in if requested.
  1214. if ($bool_include_tracks == true)
  1215. {
  1216. // Set it back to what we got from the db.
  1217. $major_code = $major;
  1218. $temp_degree = $this->get_degree_plan($major, $catalog_year, true);
  1219. if ($temp_degree->track_code != "")
  1220. {
  1221. $title .= " - " . $temp_degree->track_title;
  1222. }
  1223. }
  1224. $rtn_array[$major_code]["title"] = $title;
  1225. $rtn_array[$major_code]["degree_id"] = $degree_id;
  1226. $rtn_array[$major_code]["degree_class"] = trim(strtoupper($cur["degree_class"]));
  1227. }
  1228. return $rtn_array;
  1229. }
  1230. function get_degree_tracks($major_code, $catalog_year)
  1231. {
  1232. // Will return an array of all the tracks that a particular major
  1233. // has. Must match the major_code in degree_tracks table.
  1234. // Returns FALSE if there are none.
  1235. $rtn_array = array();
  1236. static $degree_tracks_data_cache = array();
  1237. if (isset($degree_tracks_data_cache[$catalog_year][$major_code])) {
  1238. return $degree_tracks_data_cache[$catalog_year][$major_code];
  1239. }
  1240. $res = $this->db_query("SELECT * FROM degree_tracks
  1241. WHERE major_code = ?
  1242. AND catalog_year = ? ", $major_code, $catalog_year);
  1243. if ($this->db_num_rows($res) < 1)
  1244. {
  1245. $degree_tracks_data_cache[$catalog_year][$major_code] = false;
  1246. return FALSE;
  1247. }
  1248. while($cur = $this->db_fetch_array($res))
  1249. {
  1250. extract($cur, 3, "db");
  1251. $rtn_array[] = $db_track_code;
  1252. }
  1253. $degree_tracks_data_cache[$catalog_year][$major_code] = $rtn_array;
  1254. return $rtn_array;
  1255. }
  1256. function get_degree_plan($major_and_track_code, $catalog_year = "", $bool_minimal = false)
  1257. {
  1258. // Returns a degreePlan object from the supplied information.
  1259. // If catalog_year is blank, use whatever the current catalog year is, loaded from our settings table.
  1260. if ($catalog_year == "") {
  1261. $catalog_year = variable_get("current_catalog_year", "2006");
  1262. }
  1263. $degree_id = $this->get_degree_id(trim($major_and_track_code), $catalog_year);
  1264. $dp = new DegreePlan($degree_id,null,$bool_minimal);
  1265. if ($dp->major_code == "")
  1266. {
  1267. $dp->major_code = trim($major_and_track_code);
  1268. }
  1269. return $dp;
  1270. }
  1271. /**
  1272. * Returns the value of a degree's allow_dynamic field in the database.
  1273. *
  1274. * Returns boolean FALSE if it cannot find the degree.
  1275. *
  1276. * @param unknown_type $degree_id
  1277. * @param unknown_type $bool_use_draft
  1278. */
  1279. function get_degree_allow_dynamic($degree_id, $bool_use_draft = FALSE) {
  1280. $table_name = "degrees";
  1281. if ($bool_use_draft){$table_name = "draft_$table_name";}
  1282. $res7 = $this->db_query("SELECT allow_dynamic FROM $table_name
  1283. WHERE degree_id = ?
  1284. ", $degree_id) ;
  1285. if ($this->db_num_rows($res7) > 0)
  1286. {
  1287. $cur7 = $this->db_fetch_array($res7);
  1288. return $cur7["allow_dynamic"];
  1289. }
  1290. return false;
  1291. }
  1292. function get_degree_id($major_and_track_code, $catalog_year, $bool_use_draft = FALSE)
  1293. {
  1294. // This function expects the major_code and track_code (if it exists)
  1295. // to be joined using |_. Example:
  1296. // GSBA|_123 or KIND|EXCP_231.
  1297. // In other words, all in one.
  1298. // Always override if the global variable is set.
  1299. if (@$GLOBALS["fp_advising"]["bool_use_draft"] == true) {
  1300. $bool_use_draft = true;
  1301. }
  1302. if ($catalog_year < $GLOBALS["fp_system_settings"]["earliest_catalog_year"])
  1303. { // Lowest possible year.
  1304. $catalog_year = $GLOBALS["fp_system_settings"]["earliest_catalog_year"];
  1305. }
  1306. $table_name = "degrees";
  1307. if ($bool_use_draft){$table_name = "draft_$table_name";}
  1308. $res7 = $this->db_query("SELECT degree_id FROM $table_name
  1309. WHERE major_code = ?
  1310. AND catalog_year = ?
  1311. LIMIT 1 ", trim($major_and_track_code), $catalog_year) ;
  1312. if ($this->db_num_rows($res7) > 0)
  1313. {
  1314. $cur7 = $this->db_fetch_array($res7);
  1315. return $cur7["degree_id"];
  1316. }
  1317. return false;
  1318. }
  1319. // Returns a simple array of all degree_id's which match this major code, any catalog year.
  1320. function get_degree_ids($major_code) {
  1321. $rtn = array();
  1322. $bool_use_draft = FALSE;
  1323. // Always override if the global variable is set.
  1324. if (@$GLOBALS["fp_advising"]["bool_use_draft"] == true) {
  1325. $bool_use_draft = true;
  1326. }
  1327. $table_name = "degrees";
  1328. if ($bool_use_draft){$table_name = "draft_$table_name";}
  1329. $res7 = $this->db_query("SELECT degree_id FROM $table_name
  1330. WHERE major_code = ?
  1331. ", trim($major_code)) ;
  1332. while ($cur7 = $this->db_fetch_array($res7)) {
  1333. $rtn[$cur7["degree_id"]] = $cur7["degree_id"];
  1334. }
  1335. return $rtn;
  1336. } // get_degree_ids
  1337. function db_fetch_array($result) {
  1338. if (!is_object($result)) return FALSE;
  1339. return $result->fetch(PDO::FETCH_ASSOC);
  1340. }
  1341. function db_fetch_object($result) {
  1342. if (!is_object($result)) return FALSE;
  1343. return $result->fetch(PDO::FETCH_OBJ);
  1344. }
  1345. function db_num_rows($result) {
  1346. if (!is_object($result)) return FALSE;
  1347. return $result->rowCount();
  1348. }
  1349. function db_affected_rows($result) {
  1350. return db_num_rows($result);
  1351. }
  1352. function db_insert_id() {
  1353. //fpm($this->pdo->lastInsertId());
  1354. //return $this->pdo->lastInsertId();
  1355. return $_SESSION["fp_last_insert_id"];
  1356. }
  1357. function db_close() {
  1358. return $this->pdo = NULL; // this is all you need to do to close a PDO connection.
  1359. }
  1360. ///////////////////////////////////////////////////
  1361. ///////////////////////////////////////////////////
  1362. ///////////////////////////////////////////////////
  1363. function z__db_num_rows($result) {
  1364. return mysql_num_rows($result);
  1365. }
  1366. function z__db_affected_rows() {
  1367. return mysql_affected_rows();
  1368. }
  1369. function z__db_insert_id() {
  1370. return mysql_insert_id();
  1371. }
  1372. function z__db_fetch_array($result) {
  1373. return mysql_fetch_array($result);
  1374. }
  1375. function z__db_fetch_object($result) {
  1376. return mysql_fetch_object($result);
  1377. }
  1378. function z__db_close() {
  1379. return mysql_close($this->dbc);
  1380. }
  1381. /////////////////////////////////////////////
  1382. /////////////////////////////////////////////
  1383. /////////////////////////////////////////////
  1384. }