<?php

  /*

      db.php

      Contains the database connection functions for ease of use.

      Changelog:
        2006-01-14 dave: Cleaned up code for v1.0 release
        2005-07-15 arne_sf: Defined default fetchmode to be an associative
          array (previously done for every query in recordset.php)
        2005-04-27 arne_sf: Added function db_next_id, which returns next
          available ID from a sequence
        2005-04-23 arne_sf: Replaced database connect code with
          Pear::DB-specific code
        2005-04-23 arne_sf: Customized db_recordset() and db_send() to use
          Pear::DB-type query code
        
      ----

      THIS FILE HAS DATABASE SPECIFIC FUNCTIONS, therefore, if a
      database migration occurs, this page must be updated.

      ----

      Copyright (C) 2003  Central Manchester CLC
      Copyright (C) 2003  David Thorne (davethorne@gmail.com)

      This program is free software; you can redistribute it and/or
      modify it under the terms of the GNU General Public License
      as published by the Free Software Foundation version 2.

      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.

      You should have received a copy of the GNU General Public License
      along with this program; if not, write to the Free Software
      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

  */

  // Security...
  if (strpos($_SERVER["SCRIPT_NAME"], basename(__FILE__, '.php')) !== false) {
    header("location: index.php");
  }

  // Include Pear::DB
  require_once 'DB.php';
  
  // Import Database Configuration
  require_once 'config/db.conf.php';
  // Import Global Configuration
  require_once 'config/global.conf.php';

  // Connect to database
  $db =& DB::connect($conf_db['dsn'], $conf_db['options']);
  if (PEAR::isError($db)) {
    die($db->getMessage());
  }

  // Define fetchmode to be an associative array
  $db->setFetchMode(DB_FETCHMODE_ASSOC);




  /*
   * Database access functions
   */
   
  // email_admin: Send a message to the administrator (for database error messages a.s.o.)
  function email_admin($message) {
  $sendto = "root";
  $subject = "Helpdesk Error : {$_SERVER['SERVER_NAME']}";
  $header = "From: Helpdesk";
    mail($sendto, $subject, $message, $header);
  }
  
  
  // db_recordset: Create a recordset and populate it with the returned rows from the $sql query
  function db_recordset($sql) 
  {
    // Access database connection object
    global $db;
    // Query database 
    $data =& $db->getAll(filter_sql($sql));

    // Check that result is not an error
    if (PEAR::isError($data)) 
    {
        die("<b>Fatal Error: Database Query Failed.</b><br><pre>$sql</pre>
      <br>This could be because there is no valid connection, or because the query is incorrect.
      <br><pre>".$data->getMessage().email_admin("THERE HAS BEEN A DATABASE QUERY PROBLEM:
--------------------------------------
PAGE:
".$_SERVER['SCRIPT_FILENAME']."
VIA PAGE:
".__FILE__."    LINE    ".__LINE__." 
--------------------------------------
SQL:
$sql
--------------------------------------
ERROR:
".$data->getMessage()."
--------------------------------------
")."</pre><br>");
    }

    // Return complete resultset as array
    return $data;
  }
  
  
  // db_send: Send an $sql query to the database, return TRUE on success (and die() on failure)
  //          Use db_send() for INSERT, UPDATE and DELETE queries, and db_recordset() for SELECTs
  function db_send($sql) 
  {
    // Access database connection object
    global $db;
    // Query database 
    $data =& $db->query(filter_sql($sql));

    // Check that result is not an error
    if (PEAR::isError($data)) 
    {
        die("<b>Fatal Error: Database Query Failed.</b><br><pre>$sql</pre>
      <br>This could be because there is no valid connection, or because the query is incorrect.
      <br><pre>".$data->getMessage().email_admin("THERE HAS BEEN A DATABASE QUERY PROBLEM:
--------------------------------------
PAGE:
".$_SERVER['SCRIPT_FILENAME']."
VIA PAGE:
".__FILE__."    LINE    ".__LINE__." 
--------------------------------------
SQL:
$sql
--------------------------------------
ERROR:
".$data->getMessage()."
--------------------------------------
")."</pre><br>");
    }
    
    return TRUE;
  }

  
  // db_next_id: Get next id
  function db_next_id($sequence)
  {
    // Access database connection object
    global $db;
    // Get next id
    $id = $db->nextId($sequence);
    // Check that result is not an error
    if (PEAR::isError($id)) 
        die($id->getMessage());
    else
        return $id;
  } 

  // Filter a recordset for all $fields with a value of $value.
  function filter_records($recordset,$field,$value) {
    $return_array = array();
    // Reset Recordset and contruct the filtered recordset
    reset($recordset);
    foreach ($recordset as $key => $val)
      if ($val[$field] == $value) $return_array[] = $val;

    return $return_array;
  }

  
  function compact_records($recordset,$field) {
    $return_array = array();

    foreach ($recordset as $record) {
      $return_array[] = $record[$field];
    }

    return $return_array;
  }

  // Merges several recordsets into one, and removes the first occurrences of
  // records with duplicate fileds (as passed to the function)
  // First argument is the field to check on, all other arguments
  // are the arrays to be merged
  function merge_recordsets() {
    $arrays=func_get_args();
    $field = array_shift($arrays);

    $returnarray = array();
    foreach ($arrays as $array) {
        // Don't bother if the array is empty
        if (count($array) > 0) {
            // Remove any existing elements from the original array
            foreach ($array as $element) {
                foreach ($returnarray as $retindex=>$retelement) {
                    if ($retelement[$field] == $element[$field]) {
                        unset($returnarray[$retindex]);
                    }
                }
            }
        }
        $returnarray = array_merge($returnarray, $array);
    }
    return($returnarray);
  }

  function filter_sql($sql) {
    // Remove last semicolon if it's there
    $sql = rtrim($sql, ';');
    // Filters out semicolons in queries
    return(str_replace(';', '\;', $sql));
  }







  
  ## Some other random database bits and bobs
  ## these variables make up for the fact that MySQL doesnt handle views,
  ## and probably slow it down quite a lot, but MySQL is fast in the first place.

  ## But makes no sense for postgres where we use the view instead.

if ($conf_db['dsn']['phptype'] != 'pgsql') {
  $aselects= "
  tbl_Issues.id,      tbl_Issues.reportedby,      tbl_Issues.createdby,
  tbl_Issues.closedby,  tbl_Issues.assignedto,      tbl_Issues.status,
  tbl_Issues.level,    tbl_Issues.priority,      tbl_Issues.site,
  tbl_Issues.detail,    tbl_Issues.location,      tbl_Issues.contact,
  tbl_Issues.createdon,  tbl_Issues.closedon,      tbl_Issues.summary,
  tbl_Issues.description,  tbl_Issues.solution,      tbl_Issues.published,
  tbl_Issues.publishedon,  tbl_Issues.publishedby,      tbl_Issues.recalled,
  tbl_Issues.category,  tbl_Issues.domain,        t1.name AS createdbyname,
  t2.name AS reportedbyname,t3.name AS closedbyname,    t4.name AS assignedtoname,
  t5.name AS publishedbyname,tbl_Sites.site AS sitename,  tbl_Statuses.status AS statusname,
  tbl_Statuses.sortorder AS statussortorder,tbl_Priorities.priority AS priorityname,tbl_Priorities.sortorder,
  tbl_Priorities.class,  tbl_Levels.level AS levelname,  tbl_Levels.sortorder AS levelsortorder,
  tbl_ProblemDetails.description AS detailname,tbl_ProblemCategories.description AS categoryname";
  $afrom = " tbl_Issues
  LEFT JOIN tbl_Users t1 ON tbl_Issues.createdby = t1.id
  LEFT JOIN tbl_Users t2 ON tbl_Issues.reportedby = t2.id
  LEFT JOIN tbl_Users t3 ON tbl_Issues.closedby = t3.id
  LEFT JOIN tbl_Users t4 ON tbl_Issues.assignedto = t4.id
  LEFT JOIN tbl_Users t5 ON tbl_Issues.publishedby = t5.id
  LEFT JOIN tbl_Sites ON tbl_Issues.site = tbl_Sites.id
  LEFT JOIN tbl_Priorities ON tbl_Issues.priority = tbl_Priorities.id
  LEFT JOIN tbl_UserSites ON tbl_Issues.site = tbl_UserSites.site
  LEFT JOIN tbl_UserTypes ON tbl_UserSites.usertype = tbl_UserTypes.id
  LEFT JOIN tbl_Statuses ON tbl_Issues.status = tbl_Statuses.id
  LEFT JOIN tbl_Levels ON tbl_Issues.level = tbl_Levels.id
  LEFT JOIN tbl_ProblemDetails ON tbl_Issues.detail = tbl_ProblemDetails.id
  LEFT JOIN tbl_ProblemCategories ON tbl_Issues.category = tbl_ProblemCategories.id ";
 }


# Not sure which function bin these should go in, but as they are MySQL specific i will put them in here.

  function maketime($time) {
  
    $hours = substr("0" . floor($time/3600), -2);
    $mins = substr("0" . floor(($time-($hours*3600))/60), -2);
    $seconds = substr("0" . ($time-(($hours*3600)+($mins*60))), -2);
    $time = "$hours:$mins:$seconds";
    return $time;
  }
  
  function makeseconds($time) {
    $time = explode(":",$time);
  $time = ($time[0]*3600)+($time[1]*60)+$time[2];
    return $time;
  }
  
?>
