Message:
" . $msg . "

Query:
" . $query . "

Error:
" . mysql_error($_PAGE_INFO['mysql_db_resource'][$purpose]) . "

Actions:
" . current_action(TRUE) . "

Backtrace:
" . calltrace("text/html", 1) . "

", "", "", 1 ); } return TRUE; } function db_report_slow_query($msg, $query, $t, $n, $send_mail, $purpose) { global $_PAGE_INFO, $_RELEASE; $release = (is_ReleaseCandidate() ? "rc" : "release"); error_log("MySQL slow query: " . $msg . ": " . ($query ? ($query . ": ") : "") . ", " . sprintf("%.3f", $t) . " s, " . $n . " rows"); if( $send_mail && $_RELEASE[$release]['e-mail'] && $_RELEASE[$release]['e-mail']['mysql slow query'] ) { send_mail( $_RELEASE[$release]['e-mail']['mysql slow query'], "", "", "slow@dualinventive.com", "MTinfo MySQL Slow Query (" . php_uname("n") . ", " . sprintf("%.3f", $t) . " s)", "

Message

:
" . $msg . "

Query:
" . $query . "

Details

:
Time: " . sprintf("%.3f", $t) . " s
Result: " . $n . " rows

Actions:
" . current_action(TRUE) . "

Backtrace:
" . calltrace("text/html", 1) . "

", "", "", 1 ); } } /** * Get database configuration (when available */ function db_get_config($config, &$host, &$db, &$user, &$password) { GLOBAL $_DATABASE; // Get defaults $host = $_DATABASE[$config]['host']; $db = $_DATABASE[$config]['db']; $user = $_DATABASE[$config]['user']; $password = $_DATABASE[$config]['passwd']; $config_file = $_DATABASE[$config]['config']; // Get configuration if (file_exists($config_file)) { $handle = fopen($config_file, "r"); if ($handle) { while (($line = fgets($handle, 4096)) !== false) { // Skip remarks (starting with #) if (($line[0] != '#') && (strlen($line))) { // Split line (value and config) $line_part = explode("=", $line); // Remove remark at the end of the line $value = explode("#", $line_part[1]); // Only index 0 is interresting, and trim this value to remove white spaces at the end // "Bug" php, it is not possible to return index immediatellty $value = trim($value[0]); // Parse config switch(trim(strtolower($line_part[0]))) { case "host": $host = $value; break; case "database": $db = $value; break; case "user": $user = $value; break; case "passwd": $password = $value; break; default: break; } } } // Close configuration fclose($handle); return TRUE; } else return FALSE; } else { DBG("Config file: " . $config_file . " does not exist!"); return FALSE; } } /** * Set up the database connection */ function db_connect($config = "default", $purpose = NULL) { global $_PAGE_INFO; // Set all handles when no specific purpose has been defined if( ($copy_db_handle = !$purpose) ) { $purpose = "default"; } else if( !$config ) { // close the connection (per recommendation, 'mysql_close()' is not used) $_PAGE_INFO['mysql_db_resource'][$purpose] = NULL; return TRUE; } // Get database config (or use defaults form definitions.php) if( !db_get_config($config, $db_host, $db, $user, $password) ) return FALSE; // Connect and get new indentifier $_PAGE_INFO['mysql_db_resource'][$purpose] = mysql_connect($db_host, $user, $password, TRUE); // Check db connection if (!$_PAGE_INFO['mysql_db_resource'][$purpose]) { db_report_mysql_error("Cannot connect to database \"" . $config . "\"", NULL, TRUE, $purpose); die("At this moment have some interference. For further questions, please contact Dual Inventive!"); } // Check if db can be opened else if(!mysql_select_db($db, $_PAGE_INFO['mysql_db_resource'][$purpose])) { db_report_mysql_error("Cannot open database", NULL, TRUE, $purpose); return FALSE; } if( $copy_db_handle ) { // Copy the handle to all other purposes, except the purpose "session" $purposes = array("log"); foreach( $purposes as $other_purpose ) { $_PAGE_INFO['mysql_db_resource'][$other_purpose] = $_PAGE_INFO['mysql_db_resource']['default']; } } return $_PAGE_INFO['mysql_db_resource'][$purpose]; } /** * Get database connection (link identifier) */ function db_get_connection($purpose = "default") { global $_PAGE_INFO; return $_PAGE_INFO['mysql_db_resource'][$purpose]; } /** * Fetch data from database * * Inputs: * - query: Query which must be executed * - purpose * - check_rows: Check fetched number of rows (optional) * - fetch Return the data rows (default behaviour) * * Return: multidimensional array containing fetched data */ function db_fetch_data($query, $purpose = "default", $check_rows = FALSE, $fetch = TRUE, $key = FALSE) { global $_PAGE_INFO; // Initial return value $result = FALSE; // Old style call? if( $purpose == NULL || is_numeric($purpose) ) { $fetch = 1; $check_rows = $purpose; $purpose = "default"; } // Get starting time $query_start = microtime_float(); // Execute query to retrieve data $query_result = mysql_query($query, $_PAGE_INFO['mysql_db_resource'][$purpose]); // Check result if( $query_result ) { // Row check? $nmr_rows = mysql_num_rows($query_result); // NB: the 'check_rows' is quite silly; 'db_fetch_data()' will always return // all data rows if there are any or FALSE if there are no data rows for the // query (we _don't_ return an empty array in that case as this might break // some older functions that check for errors with 'is_array()') if( !is_numeric($check_rows) || ($nmr_rows == $check_rows) || ($nmr_rows) ) { // Success; fetch the data rows $result = array(); if( $fetch ) { // Fetch data for($i = 0; $i < $nmr_rows; $i++) { $row = mysql_fetch_assoc($query_result); if( $key ) $result[$row[$key]] = $row; else $result[$i] = $row; } } else { $result['nr_rows'] = $nmr_rows; $result['result'] = $query_result; } } } // Get end time $query_end = microtime_float(); // Determine total time $query_total = $query_end - $query_start; // Display query history/Find slow queries if( $query_result ) { if( $query_total > 1 ) { // Show slow query db_report_slow_query("Slow query", $query, $query_total, $nmr_rows, $query_total > 10, $purpose); } else if( (LOG_SQL_HISTORY) || ($query_total > 1) ) { // Store history DBG("mysql history, query: " . $query . ", time: " . $query_total . ", result: " . $nmr_rows . ", error: " . $query_error); } } else { // error db_report_mysql_error("Error in query", $query, TRUE, $purpose); } // Return result return $result; } function db_fetch_data_array($key, $query, $purpose = "default", $check_rows = FALSE, $fetch = TRUE) { return db_fetch_data($query, $purpose, $check_rows, $fetch, $key); } /** * Wrapper for 'db_fetch_data' to fetch a single field from the database. * * Inputs: * - query * - purpose * * Returns: * - Data item (first column of the first row) or FALSE on error */ function db_fetch_item($query, $purpose = "default") { $result = db_fetch_data($query, $purpose); if( $result && count($result) >= 1 ) { return array_shift(array_shift($result)); } else { // error, or no data return FALSE; } } /** * Store data in database * * Inputs: * - query: Query which must be executed * * Return: Boolean: Success (TRUE) or error (FALSE) */ function db_store_data($query, $purpose = "default") { global $_PAGE_INFO; // Initial return value $result = FALSE; // Get starting time $query_start = microtime_float(); // Execute query to store data $query_result = mysql_query($query, $_PAGE_INFO['mysql_db_resource'][$purpose]); // Get end time $query_end = microtime_float(); // Determine total time $query_total = $query_end - $query_start; // Display query history and find slow queries if( $query_result ) { // Success // print statistics if ($query_total > 1) { // Show slow query db_report_slow_query("Slow query", $query, $query_total, mysql_affected_rows($_PAGE_INFO['mysql_db_resource'][$purpose]), $query_total > 10, $purpose); } else if (LOG_SQL_HISTORY) { // Store history DBG("mysql history, query: " . $query . ", time: " . $query_total . ", result: " . mysql_affected_rows($_PAGE_INFO['mysql_db_resource'][$purpose]) . ", error: " . $query_error); } return TRUE; } else { // Error db_report_mysql_error("Error in query", $query, TRUE, $purpose); return FALSE; } } /** * Collect data over all databases * * Inputs: * - query: Query which must be executed * - databases: Array with databases (strings for 'db_connect') * - merge: Expression to merge the row (see below; optional) * * Return: Multidimensional array containing fetched data * * Notes: * - The data rows can be merged using an array of expressions in '$merge' * (only applicable if more than one database is selected) * Variables to use in the expressions: * - old Row from the existing data (i.e. previous database(s)) * - new Row from the result set of the last query (i.e. "this" database) * - database This database * Returns: Row to put in the output array (usually 'old' or 'new') * - All results will be concatenated when 'merge' is empty */ function db_collect_data($query, $databases = null, $merge = null) { global $_PAGE_INFO; if( is_array($databases) ) { // multiple database; collect data over all databases $result = array(); foreach( $databases as $database ) { db_connect($database, "collect"); if( !$merge ) { $result = array_merge($result, db_fetch_data($query, "collect")); } else { $db_data = db_fetch_data($query, "collect"); for( $i = 0; $i < count($db_data); $i++ ) { $old = $result[$i]; $new = $db_data[$i]; $result[$i] = eval($merge); } } } } else { // no databases (i.e. the currently selected database) or a single database; // nothing to merge if( $databases ) { db_connect($databases, "collect"); $result = db_fetch_data($query, "collect"); } else { $result = db_fetch_data($query); } } // close the (temporary) database connection if( $databases) db_connect(null, "collect"); return $result; } /** * Start transaction * * Returns: Boolean (TRUE on success, FALSE on error) */ function db_start_transaction($purpose = "default") { // Start transaction return db_store_data("START TRANSACTION", $purpose); } /** * Commit transaction * * Returns: Boolean (TRUE on success, FALSE on error) */ function db_commit_transaction($purpose = "default") { global $_PAGE_INFO; if (mysql_error($_PAGE_INFO['mysql_db_resource'][$purpose])) { // Roll back; error is reported by the offending query db_store_data("ROLLBACK", $purpose); // Error return FALSE; } else { // Commit transaction $query_result = mysql_query("COMMIT", $_PAGE_INFO['mysql_db_resource'][$purpose]); // Check result if (!$query_result) { db_report_mysql_error("Error in query", $query, TRUE, $purpose); return FALSE; } else { // Success return TRUE; } } } /** * Determine last id inserted * * Return: last id inserted */ function db_fetch_last_id($purpose = "default") { // Initial return value $result = ""; // Fetch customer info $id = db_fetch_data("SELECT LAST_INSERT_ID();", $purpose); // Parse into result if (!empty($id)) { $result = $id[0]['LAST_INSERT_ID()']; } // Return result return $result; } /** * Fetch all available values for key * * Inputs: * - table: The table from which the data set must be fetched * - key: The key which must be fetched, or FALSE to fetch all fields * * Return: When a 'key' is set, either an array with set values or a * multi-dimensional array when the 'key' is a pattern, or an * array with all field names of the table when 'key' is not set * NB: in the latter case, the array contains the field names * only; use 'db_fetch_fields()' go retrievall all details * about the database columsn/fields. */ function db_fetch_set($table, $key = FALSE) { // Query to retrieve data set id (unique) $query = "SHOW COLUMNS FROM " . $table; if( $key ) { // convert dos-style pattern $like_pattern = str_replace(array("*","?"), array("%","_"), $key); $query .= " LIKE '" . $like_pattern . "'"; } if( !($row = db_fetch_data($query)) ) return FALSE; // Parse into result if (strlen($key)) { if( count($row) == 1 ) { // Remove "set(" and ")" $values = str_replace(array("enum(","set(",")","'") , "", $row[0]['Type']); // Split string return explode("," ,$values); } else { // multiple columns $result = array(); foreach( $row as $column ) { // Remove "set(" and ")" $values = str_replace(array("enum(","set(",")","'") , "", $column['Type']); // Split string $result[$column['Field']] = explode("," ,$values); } return $result; } } else { $result = array(); foreach($row as $item) { array_push($result,$item['Field']); } return $result; } } /** * Fetch all table field of type * * Inputs: * - table: The table from which the type entries must be searched * - type: Requested type * * Return: Array containing all values */ function db_fetch_fields($table, $type = "", $purpose = NULL) { // Query to retrieve data set id (unique) $row = db_fetch_data("SHOW COLUMNS FROM " . $table, $purpose); // Parse into result if( $row ) { $result = array(); foreach( $row as $item ) if( !strlen($type) || ($item['Type'] == $type) ) $result[] = $item['Field']; return $result; } else return FALSE; } /** * Fetch all user or customer rights */ function db_fetch_rights($table, $flatten_data = FALSE) { $rights = db_fetch_set($table, "rechten*"); // TO DO: remove the following when the 'rechten' field is completely // up-to-date (i.e. when the rights in 'rechtion:*' are removed) // add rights not yet present in the database $rights['rechten'][] = "menu:service"; if( $flatten_data ) { $rights_array = $rights; $rights = array(); foreach( $rights_array as $right ) { $rights = array_merge($rights, $right); } // TO DO: removed the next line when the 'rechten' field is up-to-date // (i.e., no double rights in the old and new columns) $rights = array_unique($rights); // END TO DO } return $rights; } /** * Merge the different user or customer rights arrays */ function db_merge_rights($table, &$db_data) { // already expanded? if( !isset($db_data['rechten']) ) { return FALSE; } else if( is_array($db_data['rechten']) ) { // already expanded? return $db_data['rechten']; } $right_fields = db_fetch_rights($table); $db_data['rechten'] = explode(",", $db_data['rechten']); // TO DO: removed the next line when the 'rechten' field is up-to-date // add rights for menu access that are not part of the original array if( $db_data['rechten:service'] ) $db_data['rechten'][] = "menu:service"; // END TO DO foreach( $right_fields as $field => $rights ) { if( $field != 'rechten' ) { $db_data['rechten'] = array_merge($db_data['rechten'], explode(",", $db_data[$field])); unset($db_data[$field]); } } // for older scripts if( in_array('menu:service:productie', $db_data['rechten']) ) { $db_data['rechten'][] = "productie"; } // remove duplicates (may be removed when 'rechten' is up-to-date) return array_unique($db_data['rechten']); } /** * String user right verification (at least one rigth must be valid) * * Inputs: * - user_id: User Database id * - menu_rights: The string which contains the user right which must be checked (CSV) * * Return: 1 (OK)/ 0(Error) */ function db_ver_rights_user_one_valid($user_id, $menu_rights) { // Initial return value $result = FALSE; // split string $menu_right_array = explode("," ,$menu_rights); if (is_array($menu_right_array)) { foreach ($menu_right_array as $menu_right) { if (!$result) { // find & char => and if (stristr($menu_right, "&") !== FALSE) { // split string $menu_right_subarray = explode("&" ,$menu_right); if (is_array($menu_right_subarray)) { // initial right $result = TRUE; // verify all foreach($menu_right_subarray as $right) { if (!db_ver_right_user($user_id, trim($right),1)) { $result = FALSE; } } } } else { if (db_ver_right_user($user_id, trim($menu_right), 1)) { $result = TRUE; } } } } } return $result; } /** * Verify user rights for the user currently logged in * * Inputs: * - menu_rights: The string which contains the user right which must be checked (CSV) * * Returns: Boolean: user has sufficient rights */ function db_ver_rights($menu_rights, $user_rights = NULL) { // use this user's rights unless specified global $_PAGE_INFO; if( !$user_rights ) $user_rights = $_PAGE_INFO['user']['rights']; if( !$user_rights ) { // user doesn't have any rights return FALSE; } // Initial return value $result = FALSE; // split string $menu_right_array = explode("," ,$menu_rights); if (is_array($menu_right_array)) { foreach ($menu_right_array as $menu_right) { if (!$result) { // find & char => and if (stristr($menu_right, "&") !== FALSE) { // split string $menu_right_subarray = explode("&" ,$menu_right); if (is_array($menu_right_subarray)) { // initial right $result = TRUE; // verify all foreach($menu_right_subarray as $right) { if( !in_array(trim($right), $user_rights) ) { $result = FALSE; } } } } else { if( in_array(trim($menu_right), $user_rights) ) { $result = TRUE; } } } } } return $result; } /** * Verify username/password/customer & store db id user/customer * * Inputs: * - user: The user which must be verified * - password: The password which must be verified * - customer: The customer which must be verified * * Return: 1 (OK)/ 0(Error) */ function db_ver_user_info($user, $password, $customer) { GLOBAL $_PAGE_INFO; // Initial return value $result = ""; // Query to retrieve klantnaam id (unique) $row_customer = db_fetch_data("SELECT * FROM klant WHERE klantnaam='" . specialchars($customer) . "'", "default"); if (!empty($row_customer)) { // Query to retrieve password of klantnaam + username (unique) $row_user = db_fetch_data("SELECT * FROM gebruiker WHERE klant='" . $row_customer[0]['id'] . "' AND gebruikersnaam='" . specialchars($user) . "'", "default"); if (!empty($row_user)) { // Check password $passwd_type = CheckPassword($password, $row_user[0]['paswoord'], $row_user[0]['id']); if( $passwd_type ) { // Result OK $result = array(user => $row_user[0]['id'], cust => $row_customer[0]['id']); if( $passwd_type < PASSWD_RECOMMENDED_ENCRYPTION ) { // upgrade the user's password, as this is about the only place where we have // the user's unencrypted (plain text) password db_update_user_password($row_user[0]['id'], HashPassword($password, $row_user[0]['id'])); $result['password_upgrade'] = TRUE; DBG("user " . $row_user[0]['gebruikersnaam'] . ": password upgraded"); } } } } return $result; } /** * Log user info to database (table log_gebruiker) * * Inputs: * - menu: The active menu * - formdata: extra logging info (optional) * * Return: id (OK)/ 0(Error) */ function db_log_user($menu, $formdata = "") { GLOBAL $_PAGE_INFO; // Initial return value $result = 0; // Log data? if ((LOG) && (!empty($menu))) { if( is_array($formdata) ) $formdata = serialize($formdata); // Query to store user info $query = "INSERT INTO log_gebruiker (gebruiker, tijd, menu, formdata, session_id) VALUES"; $query .= "('" . $_PAGE_INFO['login']['user']['id'] . "','" . date('Y-m-d H:i:s') . "','" . ($menu) . "',"; $query .= "'" . addslashes($formdata) . "','" . (session_id() . "_" . $_PAGE_INFO['id']) . "')"; if (db_store_data($query)) { // Result OK $result = db_fetch_last_id(); } } return $result; } /** * Log user-project info to database (table log_gebruiker_project) * * Inputs: * - project_id: Project id * - menu: The active menu * - formdata: extra logging info (optional) * - orig_data: Original project data => used for log_gebruiker_project * * Return: id (OK)/ 0(Error) */ function db_log_user_project($project_id, $menu = "", $formdata = "", $orig_data = "") { // Initial return value $result = 0; if (LOG) { // Store user action db_log_user($menu, $formdata); // Get last inserted $last_id = db_fetch_last_id(); // Store user project action $result = db_update_project_version($last_id, $project_id, $orig_data); if ($result) { $result = $last_id; } } return $result; } /** * Log user-customer info to database (table log_gebruiker_klant) * * Inputs: * - customer_id: Customer id * - menu: The active menu * - formdata: extra logging info (optional) * * Return: id (OK)/ 0(Error) */ function db_log_user_customer($customer_id, $menu = "", $formdata = "") { // Initial return value $result = 0; if (LOG) { // Store user action db_log_user($menu, $formdata); // Query to store user info $query = "INSERT INTO log_gebruiker_klant (id,klant) VALUES (LAST_INSERT_ID(),'" . $customer_id . "')"; if (db_store_data($query)) { // Result OK $result = db_fetch_last_id; } } return $result; } /** * Log user-lance info to database (table log_gebruiker_zkl) * * Inputs: * - lance_id: Lance id * - menu: The active menu * - formdata: extra logging info (optional) * * Return: 1 (OK)/ 0(Error) */ function db_log_user_lance($lance_id, $menu = "", $formdata = "") { // Initial return value $result = 0; if (LOG) { // Store user action db_log_user($menu, $formdata); // Query to store user info $query = "INSERT INTO log_gebruiker_zkl (id,zkl) VALUES (LAST_INSERT_ID(),'" . $lance_id . "')"; if (db_store_data($query)) { // Result OK $result = 1; } } return $result; } /** * Log user-lance and user-project info to database (table log_gebruiker_zkl and log_gebruiker_project) * * Inputs: * - lance_id: Lance id * - project_id: Project id * - menu: The active menu * - formdata: extra logging info (optional) * * Return: 1 (OK)/ 0(Error) */ function db_log_user_lance_project($lance_id, $project_id, $menu = "", $formdata = "", $orig_data = "") { // Initial return value $result = 0; if (LOG) { // Store user action db_log_user($menu, $formdata); $last_insert = db_fetch_last_id(); // Query to store lance info $query = "INSERT INTO log_gebruiker_zkl (id,zkl) VALUES ('" . $last_insert . "','" . $lance_id . "')"; if (db_store_data($query)) { $result = db_update_project_version($last_insert, $project_id, $orig_data); } } return $result; } /** * Log user-user info to database (table log_gebruiker_gebruiker) * * Inputs: * - user_id: User id * - menu: The active menu * - formdata: extra logging info (optional) * * Return: id (OK)/ 0(Error) */ function db_log_user_user($user_id, $menu = "", $formdata = "", $part = "") { // Initial return value $result = 0; if (LOG) { // Store user action db_log_user($menu, $formdata); // Query to store user info $query = "INSERT INTO log_gebruiker_gebruiker (id, gebruiker"; if (strlen($part)) { $query .= ",rol"; } $query .= ") VALUES (LAST_INSERT_ID(),'" . $user_id . "'"; if (strlen($part)) { $query .= ",'" . $part . "'"; } $query .= ")"; if (db_store_data($query)) { // Result OK $result = db_fetch_last_id; } } return $result; } /** * Fetch data from database * * Inputs: * - table: Table * - selection: Table selection * - where: Where condition * * Return: multidimensional array containing fetched data */ function db_fetch($table, $selection="*", $where="") { // Initial return value $result = ""; // Query $query = "SELECT " . $selection . " FROM " . $table . " "; // Where condition? if (strlen($where)) { $query .= "WHERE " . $where; } // Fetch data $data_result = db_fetch_data($query); // Parse result if (!empty($data_result)) { $result = $data_result; } return $result; } /** * Insert data into database * * Inputs: * - table: Table * - values: Array with values (key, item) * * Return: 1 (OK)/ 0(Error) */ function db_store($table, $keys, $items) { // Initial return value $result = ""; $key = ""; $item = ""; // Fetch new keys if (is_array($keys)) { for($i=0; $i