<?PHP

/*
 *	W-AGORA 4.0
 *	-----------
 *	$Id: mssql7.php,v 1.28 2006/02/10 14:17:14 mdruilhe Exp $
 *	Usage:	include file - Database access functions (MSSQL)
 *	Author:	Iver Odin Kvello <iver@musite.com>
 *      Based on mysql.php
 */

if (!defined('_GLOBALS')) {
	die('Hacking attempt');
}

if (!defined("_MSSQL_ACCESS")) {
 define("_MSSQL_ACCESS", 1);

if (!defined("_DBACCESS")) {
	include ("$inc_dir/dbaccess.$ext");
}

class mssql7_access extends DBaccess {

/* private: link and query handles */
var $dblink;
var $Query_ID;

var $Auto_Free     = 0;     ## Set to 1 for automatic mssql_free_result()

/**
 * Constructor.
 * @return	void
 */
function mssql7_access () {
	$this->dbtype = "mssql7";
} // end func


/*
 *    	------------------------------------------------------------------
 *		General Database access implementation (cf  : phplib)
 *	  	Copyright (c) 1998,1999 SH Online Dienst GmbH
 *              Boris Erdmann, Kristian Koehntopp
 *	------------------------------------------------------------------
 */

/* public: perform a query */
function query($Query_String) {

	if ($this->Query_ID) {
		@mssql_free_result($this->Query_ID);
		$this->Query_ID = 0;
	}

	$ti = explode(" ", microtime());
	$start = (float)$ti[0]+(float)$ti[1];

	// substitute the 'LIMIT' clause from the query
	if (preg_match("/ LIMIT (.*)/mi", $Query_String, $match)) {
		$limit = trim($match[1]);						// save the limit value
		if (ereg(",", $limit) ) {
			list($start,$count) = split(',', $limit);
			$limit = $start + $count;
		}
		$Query_String = str_replace($match[0], "", $Query_String);	// and remove the LIMIT clause from the query
		$Query_String = preg_replace("/select /i", "SELECT TOP $limit ", $Query_String );
	}

	ini_set("track_errors", "on"); // no way of retrieving error from MSSQL
	$php_errormsg = "";
	$this->Query_ID = @mssql_query($Query_String, $this->dblink);

	$this->query_count++;
	$ti = explode(" ", microtime());
	$stop = (float)$ti[0]+(float)$ti[1];
	$elapsed = $stop - $start;
	$this->sql_time += $elapsed;

	if ($php_errormsg) {
		// do some error handling
		$this->Errno = -3;
		$this->Error = $php_errormsg;  // assume error_tracking
		$this->halt("Invalid SQL: ".$Query_String."<br>$php_errormsg");
	} else if (! $this->Query_ID ) {
		if ($this->debug) {
			echo "Warning: bogus query id but successful query for $Query_String.";
		}
		// return true but bogus entry - mssql simply returns this for updates, deletes..
		$this->Query_ID = 1;
	}

	if ($this->debug) {
		printf("<tt>Debug: [query %d] %s (exec. time = %.3f ms)</tt><br />\n", $this->query_count, $Query_String, $elapsed*1000);
		flush();
	}

	$this->Errno = 0;
	$this->Error = "";

	$this->Row   = 0;
	return $this->Query_ID;
}

/* public: walk result set */
function next_record() {

	$ti = explode(" ", microtime());
	$start = (float)$ti[0]+(float)$ti[1];

	ini_set("track_errors", "on");
	$php_errormsg = "";
	$this->Record = @mssql_fetch_array($this->Query_ID);
	$this->Row   += 1;
	if ($php_errormsg) {
		$this->Errno  = -1;
		$this->Error  = $php_errormsg;
	} else {
		$this->Errno = 0;
		$this->Error = "";
	}

	$stat = is_array($this->Record);
	if (!$stat && $this->Auto_Free) {
		@mssql_free_result($this->Query_ID);
		$this->Query_ID = 0;
	}

	$ti = explode(" ", microtime());
	$stop = (float)$ti[0]+(float)$ti[1];
	$this->sql_time += ($stop - $start);

	return $stat;
}

/* public: position in result set */
function seek($pos = 0) {
	$status = @mssql_data_seek($this->Query_ID, $pos);
	if ($status)
		$this->Row = $pos;
	else
		$this->halt("seek($pos) failed: result has ".$this->num_rows()." rows");
	return;
}

function affected_rows() {
//	$result = mssql_query("SELECT @@ROWCOUNT");
//	list($affected) = mssql_fetch_row($result);
//	return $affected;
	return @mssql_rows_affected ($this->dblink);
}

function num_rows() {
	return @mssql_num_rows($this->Query_ID);
}

function num_fields() {
	return @mssql_num_fields($this->Query_ID);
}

#	------------------------------------------------------------------
#				End of PHPLIB copyright
#	------------------------------------------------------------------

#	------------------------------------------------------------------
#				General database access functions
#	------------------------------------------------------------------

// MSSQL uses auto-increment (IDENTITY) fields
function nextId ($seqname, $table="") {
	$this->query ("SET IDENTITY_INSERT $table ON"); 
	$result = $this->query ("select max(IDENTITYCOL) as id from $table");
	$this->autoID[$seqname] = @mssql_result ($result, 0, 'id');
	mssql_free_result($result);
	$this->autoID[$seqname] += 1;
	return $this->autoID[$seqname];
}

/**
 * return the auto-generated ID returned by the last INSERT query performed
 * @returns		the id of the last autoincremented field
 */
function lastId($seqname, $table="") {
	$result = $this->query ("select max(IDENTITYCOL) as id from $table");
	$this->autoID[$seqname] = @mssql_result ($result, 0, 'id');
	mssql_free_result($result);
	return $this->autoID[$seqname];
}

function preserveQuotes($str) {
	return str_replace ("'", "''", $str);
}

function _openDB ($dbhost, $dbport="", $dbuser, $dbpassword, $dbname, $persistent=0) {

	if (!function_exists('mssql_connect') ) {
		$this->Error = sprintf (ERROR_DB_NOT_SUPPORTED, 'MSSQL7');
		$this->halt("mssql_connect()");
		return ERR_ACCESS;
	}

	// Use this feature to handle MS-SQL errors
	ini_set("track_errors", "On");

	if (!empty($dbport) ) {
		$dbhost .= ",$dbport";
	}
	if ($persistent == 1) {
		$this->dblink = mssql_pconnect ($dbhost, $dbuser, $dbpassword);
	} else {
		$this->dblink = mssql_connect  ($dbhost, $dbuser, $dbpassword);
	}

	if (empty($this->dblink)) {
		$this->Error = @mssql_get_last_message();
		$this->halt("MS-SQL connection failed (server:$dbhost - user: $dbuser)");
		return ERR_ACCESS;
	}

	if (!@mssql_select_db ($dbname, $this->dblink)) {
		$this->Error = @mssql_get_last_message();
		$this->halt(" MS-SQL could not select database: '$dbname' on server '$dbhost'");
		return ERR_ACCESS;
	}

	return 0;
}

function _closeDB () {
	return @mssql_close($this->dblink);
}

function createTable ($table, $field_defs, $pk="") {
	global $php_errormsg;

	ini_set("track_errors", "On");

	$tmp = $this->Halt_On_Error;
	$this->Halt_On_Error = "report";

	// Check if table exists
	// ---------------------
	$result = mssql_query("Exec sp_tables");
	if (!$result) {
		echo "MS-SQL error: $php_errormsg<BR>";
		$this->Halt_On_Error = $tmp;
		return -3;
	}

	$count = mssql_num_rows ($result);
	$i=0;
	while ($i < $count) {
		if ($table == mssql_result ($result, $i, "TABLE_NAME")) {
			$this->Halt_On_Error = $tmp;
			return -1;	/*  table already exist */
		}
		$i++;
	}

	// Create Table
	// ------------
	if (!is_array ($field_defs)) {
		$this->Halt_On_Error = $tmp;
		return -4;
	}

	reset ($field_defs);
	while (list($col, $size) = each($field_defs)) {
		if (ereg ("^[0-9+]+$", $size) ) {
			if ($size>255) {
				$desc .= ", $col TEXT";
			} else {
				$desc .= ", $col VARCHAR($size) NOT NULL DEFAULT ''";
			}
		} else {
			$type = strtoupper($size);
			switch ($type) {
			  case "INT":
				$desc .= ", $col INT NOT NULL DEFAULT 0";
				break;
			  case "TIMESTAMP":
				$desc .= ", $col DATETIME DEFAULT GETDATE()";
				break;
			  case "AUTO":
				$desc .= ", $col int identity(1,1)";
				break;
			  default:
				$desc .= ", $col $type";
				break;
			}
		}
	}

	if(!empty($pk)) {
		$pkname = $table. '_pk';
		$desc .= ", CONSTRAINT $pkname PRIMARY KEY ($pk)";
	}

	$desc = ereg_replace ("^, ", "", $desc);
	$php_errormsg = "";
	$ret = mssql_query("CREATE TABLE $table ($desc)", $this->dblink);
	// weird-ass errorhandling forced by mssql returning 0 when successful
	// in creating, updating, deleting..
	if (!$ret || $php_errormsg!="") {
		$this->Errno = -3;
		$this->Error = $php_errormsg;
		$this->Halt_On_Error = $tmp;
		return -3;
	}

	$this->Errno = 0;
	$this->Error = "";
	$this->Halt_On_Error = $tmp;
	return 0;
}

function updateTable ($table, &$fields, $where="") {
  ini_set("track_errors", "On");

  if (!is_array ($fields) ) {
    echo "warning: updateTable(): item to update is not an array";
    return -3;
  }

  //	gets fields name and type from table
  //	------------------------------------
  $result = @mssql_query("Exec sp_columns @table_name='$table'", $this->dblink);
  if (!$result) { /* access problem */
    $this->halt("could not list fields from $table: $php_errormsg");
    return -3;
  }

  //	build columns/values list (set all matching column names)
  //	---------------------------------------------------------
  while ($db_field = mssql_fetch_array($result)) {
    $colname = $db_field["COLUMN_NAME"];
    $coltype = $db_field["TYPE_NAME"];
    $colsize = $db_field["CHAR_OCTET_LENGTH"];
    if (isset($fields[$colname])) {
      if (!$colsize) {
	$values .= ", $colname=" . intVal($fields[$colname]);
      } else {
	$val = $this->preserveQuotes($fields[$colname]);
	$values .= ", $colname='$val'";
      }
    }
  }
  $values = ereg_replace ("^, ", "", $values);

  if (empty($values) ) {
    echo "warning: updateTable(): no value to update";
    return -3;
  }

  $q = "UPDATE $table SET $values";
  if (!empty($where) ) {
    $q .= " WHERE $where";
  }

	$result = $this->query($q);
	if (!$result) {
		return -3;
	}
	return 0;
}

function insertRow ($table, &$fields) {
  ini_set("track_errors", "On");

  if (!is_array ($fields) ) {
    $this->Errno = -3;
    $this->Error = "warning: insertRow(): item to insert is not an array";
    return -3;
  }

  //	gets fields name and type from table
  //	------------------------------------
  $result = @mssql_query("Exec sp_columns @table_name='$table'", $this->dblink);
  if (!$result) { /* access problem */
    $this->halt("could not list fields from $table");
    return -3;
  }


  //	build columns/values list (set all matching column names)
  //	---------------------------------------------------------
  $cols = "";
  $values = "";
  while ($db_field = mssql_fetch_array($result)) {
    $colname = $db_field["COLUMN_NAME"];
    $coltype = $db_field["TYPE_NAME"];
    $colsize = $db_field["CHAR_OCTET_LENGTH"];
    if (isset($fields[$colname])) {
      $cols .= ", $colname";
      if (!$colsize) {
	// only things other than ints have CHAR_OCTET_LENGTH defined
	$values .= ", " . IntVal($fields[$colname]);
      } else {
	$val = $this->preserveQuotes($fields[$colname]);
	$values .= ", '$val'";
      }
    }
  }

  if (empty($values) ) {
    $this->Errno = -3;
    $this->Error = "warning: insertRow(): no value to update";
    return -3;
  }

  $cols = ereg_replace ("^, ", "", $cols);
  $values = ereg_replace ("^, ", "", $values);

  $q = "INSERT INTO $table ($cols) VALUES($values)";

  if ($this->debug)
    printf("Debug: query = %s<br>\n", $q);

  $php_errormsg = "";
  $result = @mssql_query($q, $this->dblink);
  if ($php_errormsg) {
    $this->Errno = -3;
    $this->Error = $php_errormsg;
    $this->halt("MSSQL-error: $php_errormsg");
    echo "MS-SQL error $php_errormsg<BR>";
    return -3;
  }

  $this->Errno = 0;
  $this->Error = "";

  return 0;
}

/**
 * drop a column (field) from the specified table
 *
 * @param	string	$table	the table where the field must be deleted
 * @param	string	$col	the name of the field
 * @since	4.1
 * @access	public
 * @see		addField
 * @return	void
 */
function dropField ($table, $name) {
	$this->query ("ALTER TABLE $table DROP COLUMN $col");
}


 //	------------------------------------------------------------------
 //				users management functions
 //	------------------------------------------------------------------

/**
 * returns the latest registered user from the site user database
 *
 * @param	string 	$site		The site where to find the user
 * @returns	array	"userid"	The user's id
 *			"username"	The user's name
 *			"useraddress"	The user's email address
 */
function getNewestUser($site) {

	$query = "SELECT TOP 1 userid,username,useraddress FROM ${site}_users WHERE lastlogin>0 ORDER BY unixdate DESC";
	$this->Query_ID = @mssql_query($query, $this->dblink);
	return @mssql_fetch_array($this->Query_ID);
}


 //	------------------------------------------------------------------
 //			Messages (notes) management functions
 //	------------------------------------------------------------------

function listThreads ($forum, $first=0, $last=0, $where="", $expanded=1, $limit=0, $showhidden=false) {
	global $list_var;

	if (empty($forum)) {
	  echo "DBaccess error: listThreads() : forum not defined";
	  return -3;
	}

	settype ($first, "integer");
	settype ($last, "integer");
	settype ($limit, "integer");

//	1) gets total count # of notes satisfying the query
//	---------------------------------------------------
	if ($showhidden) {
		$whereClause = (empty($where)) ? '' : "WHERE ($where)";
	} else {
		$whereClause = (empty($where)) ? "WHERE hidden=0" : "WHERE hidden=0 AND ($where)";
	}
	$result = $this->query("SELECT count(*) as total FROM $forum $whereClause");
	$this->next_record();
	$ret["total"] = $this->Record["total"];

	if ($ret["total"] == 0) {
		return ($ret);
	}

//	2) Find the first (and last) thread to be displayed in the page
//	and gets number of notes per thread
//	----------------------------------------------------------------
	if (!$last) {
		$order="DESC";
		$last = ($showhidden) ? 0 : 1;
	} else {
		$order="ASC";
	}

	$whereClause = "WHERE newest>=$last"; // $last default to 1: don't display hidden notes
	if ($first>0) {
		$whereClause .= " AND newest<=$first";
	}
	if (!$showhidden) {
		$whereClause .= " AND hidden=0";
	}
	if (!empty($where)) {
		$whereClause .= " AND ($where)";
	}

	// Set # of threads to be returned
	// -------------------------------
	$limitClause = (empty($limit)) ? "" : "TOP $limit";

	$query = "SELECT $limitClause thread, newest, count(*) FROM $forum $whereClause GROUP BY thread, newest ORDER BY newest $order";
	if ($this->debug) printf("Debug: query = %s<br>\n", $query);
	$result = $this->query($query);
	$tcount = $this->num_rows($result);

	if ($tcount > 0) {
	  if ($order=="DESC") {
	    $tfirst  = mssql_result ($result, 0, "newest");
	    $tlast = mssql_result ($result, $tcount-1 , "newest");
	  } else {
	    $tlast  = mssql_result ($result, 0, "newest");
	    $tfirst = mssql_result ($result, $tcount-1, "newest");
	  }

	  mssql_data_seek($result, 0);

	  $whereClause = "WHERE thread IN (";
	  $ncount=0;

	  while ($row = mssql_fetch_row($result)) {
	    $t = $row[0];
	    $whereClause .= "$t,";
	    $replies[$t] = $row[2] - 1;
	    $ncount += $row[2];
	  }
	  $whereClause = ereg_replace (",$", ")", $whereClause);
	}

	$ret["notes"]=$ncount;		// number of notes displayed
	$ret["threads"]=$tcount;	// number of threads displayed
	$ret["first"]=$tfirst;
	$ret["last"]=$tlast;

	if ($tcount < 1) {
	  $ret["next"] = 0;
	  $ret["prev"] = 0;
	  return $ret;
	}

	//	3) gets all threads
	//	-------------------
	if (!$showhidden) {
		$whereClause .= " AND hidden=0";
	}

	if (!empty($where) ) {
		$whereClause .= " AND ($where)";
	}

	if ($expanded == 1) {
		$limitClause = "TOP $ncount";
	} else {
		$whereClause .= " AND parent=0";
		$limitClause = "TOP $tcount";
	}

	$cols = "cle,parent,childs,thread,newest";
	reset($list_var);
	while (list($var,$val) = each($list_var)) {
		if ($val==1) $cols.=",$var";
	}

	$query = "SELECT $limitClause $cols FROM $forum $whereClause ORDER BY newest DESC,unixdate ASC";
	if ($this->debug) printf("Debug: query = %s<br>\n", $query);
	$result = $this->query($query);

	reset ($this->entries);
	reset ($this->children);
	if (isset($this->children[0]) ) {
		unset($this->children[0]);
	}

	while ($row = mssql_fetch_array($result)) {
		$key = (int) $row["cle"];
		$parent = (int) $row["parent"];
		if ($parent==0) {
			$row["replies"] = $replies[$key];
		}
		$this->entries[$key] = $row;
		$this->children[$parent][] = $key;
	}
	mssql_free_result($result);

	//	4) gets next/previous count
	//	---------------------------
	$whereClause = "WHERE newest>$tfirst";
	if (!$showhidden) {
		$whereClause .= " AND hidden=0";
	}
	if (!empty($where)) {
		$whereClause .= " AND ($where)";
	}
	$result = $this->query("SELECT count(*) AS prev FROM $forum $whereClause");
	$ret["prev"]  = @mssql_result ($result, 0, "prev");
	mssql_free_result($result);

	$whereClause = "WHERE newest<$tlast";
	if (!$showhidden) {
		$whereClause .= " AND hidden=0";
	}
	if (!empty($where)) {
		$whereClause .= " AND ($where)";
	}
	$result = $this->query("SELECT count(*) AS next FROM $forum $whereClause");
	$ret["next"]  = @mssql_result ($result, 0, "next");

	mssql_free_result($result);
	return $ret;
}

function listNotes ($forum, $first=0, $last=0, $sort="", $where="", $limit) {
	global $list_var;

	if (empty($forum)) {
		echo "DBaccess error: listNotes() : forum not defined";
		return -3;
	}

	settype ($first, "integer");
	settype ($last, "integer");
	settype ($limit, "integer");

	//	1) gets total count # of notes satisfying the query
	//	---------------------------------------------------
	// skip administrative note (old format)
	// don't skip hidden notes (listed in moderate_notes.php)
	$whereClause = "WHERE cle<>0";
	if (!empty($where)) {
		$whereClause .= " AND ($where)";
	}
	$result = $this->query("SELECT count(*) as total FROM $forum $whereClause");

	$ret["total"] = @mssql_result ($result, 0, "total");
	if ($ret["total"] == 0) {
		return $ret;
	}
	mssql_free_result($result);

	//	2) gets all notes sorted by $sort
	//	---------------------------------
	$whereClause = "WHERE cle>0"; // skip administrative record
	if (!empty($where)) {
		$whereClause .= " AND ($where)";
	}

	$orderClause = (empty ($sort)) ? "ORDER BY unixdate DESC" : "ORDER BY $sort";

	// Set first thread and # of threads to be returned
	// ------------------------------------------------
	// We have to do this somewhat roundabout. Number of
	// msgs to grab is equal to the start-message +
	// the limit  (number of msgs to view). Then we
	// grab this number of messages using TOP and data_seek
	// to the starting position. The arithmetic is somewhat
	// simpler than MySQL's LIMIT clause here.
	if ($limit>0) {
		if ($last > 0) {
			$start = ($last-$limit);
			$start = ($start<0) ? 0 : $start;
		} else {
			$start = $first;
		}
		// We use TOP to grab the correct number of threads,
		// thence we need to use mssql_data_seek to get to the
		// start
		$tograb = $limit + $start;
		$limitClause = "TOP $tograb";
	} else {
		$start=0;
		$limitClause="";
	}

	$cols = "cle,parent,childs,thread,newest";
	reset ($list_var);
	while (list($var,$val) = each($list_var)) {
		if ($val==1) $cols.=",$var";
	}

	$query = "SELECT $limitClause $cols FROM $forum $whereClause $orderClause";
	$result = $this->query("$query");
	if ($start) {
		mssql_data_seek($result, $start);
	}

	reset ($this->entries);
	reset ($this->children);
	$tcount=0;
	while ($row = mssql_fetch_array($result)) {
		$key = $row["cle"];
		$row["parent"]=0;
		$this->entries[$key] = $row;
		$this->children[0][] = $key;
		$tcount++;
	}
	mssql_free_result($result);

	$ret["notes"] = $tcount;
	$ret["threads"] = $tcount;
	$ret["first"] = $start;
	$ret["last"] = $start + $tcount;

	//	3) set next/previous (1 if TRUE)
	//	--------------------------------
	$ret["next"] = ($ret["total"] > $ret["last"]) ? 1 : 0;
	$ret["prev"] = ($ret["first"] > 1) ? 1 : 0;


	return $ret;
}

/**
 * insert attachment reference in database 
 *
 * @param     string $note_id	id of the associated note
 * @param     string $name
 * @param     string $path
 * @param     string $inline	requested display mode
 * @param     string $size
 * @param     string $type
 * @param     string $state		state of attachement (1: active, 0, inactive, P: pending, D: Deleted)
 * @param     string $hidden
 * @access    public
 * @return    integer			The id of the attachment >0 if OK, a negative value in case of error
 */
function insertAttachment ($forum, $note_id, $name, $path, $inline="A", $size=0, $type="", $state='1', $hidden=0) {

	$upload_table = $this->site . "_attachments";

	$fields["unixdate"] = time();
	$fields["note_id"]  = $note_id;
	$fields["bn_name"]  = $forum;
	$fields["att_name"] = $name;
	$fields["att_path"] = $path;
	$fields["att_size"] = empty ($size) ? filesize($path) : $size;
	$fields["att_type"] = empty ($type) ? "application/octet-stream" : $type;
	$fields["state"]    = $state;
	$fields["hidden"]   = $hidden;
	$fields["inline"]   = $inline;
	$ret = $this->insertRow($upload_table, $fields);
	if ($ret != 0) {
		return -1;
	}

	$result = $this->query ("select att_id from $upload_table WHERE note_id='$note_id' and bn_name='$forum' and att_name='$name'");
	$att_id = @mssql_result ($result, 0, "att_id");
	mssql_free_result($result);

	return $att_id;
}

/**
 * Build the where clause used in the search function
 *
 * @param	string	$pattern		The patetrn to search
 * @param	array	$search_fields	An array that contain the fields name to be searched
 * @param	integer	$search_type	search mode : 0= all words, 1=any word, 2=exact phrase
 * @param	integer	$casesensitive	Case sensitive search (1 = yes, default: 0 = no)
 * @param	string	$where			An optional where clause
 *
 * @access  public
 * @return	string	the where clause
 */
function buildSearchWhereClause ($pattern, &$search_fields, $search_type, $casesensitive=0, $where="") {

 # build the search terms arrays
 # -----------------------------
	if ($search_type == 2) {
		// search exact phrase
		$terms[]=$pattern;
	} else {
		// strip all extra spaces
		$pattern = ereg_replace ("[[:space:]]+", " ", trim($pattern));

		if ( strstr ($pattern, '"' ) ) {
			//first pull out all the double quoted strings
			if (strstr ($pattern, "\"")) {
				$search_string = $pattern;
				while (ereg('-*"[^"]*"', $search_string, $match)) {
					$terms[]=trim(str_replace("\"", "", $match[0]));
					$search_string=substr(strstr($search_string, $match[0]), strlen($match[0]));
				}
			}
			$pattern = ereg_replace('-*"[^"]*"', '', $pattern );
		}
		$terms = explode (" ", $pattern);
	}

 # build the query
 # ---------------
	$whereclause = "hidden=0";

	// Generate a pattern of [pP][aA] and so forth for insensitive search
	$canonical = strtolower($pattern);
	$insensitive = preg_replace("/([[:alpha:]])/e", "'[\\1' . strtoupper('\\1]')", $canonical);

	// for each term to search...
	reset ($terms);
	while (list (, $term) = each ($terms)) {
		if (!empty($term) ) {
			$term = $this->preserveQuotes($term);
			if(substr($term, 0, 1) == "-") {
				$term =substr($term, 1);
				$like = "NOT LIKE";
			} else {
				$like = "LIKE";
			}
			// ... select the columns to look in
			if ($casesensitive) {
				// this is assuming MSSQL-server was installed with a case-sensitive
				// sort order. Elsehow, you get case-insensitive searches anyway.
				$expr="LIKE '%$pattern%'";
			} else {
				$expr="LIKE '%$insensitive%'";
			}

			// this is assuming MSSQL-server was installed with a case-sensitive
			// sort order. Elsehow, you get case-insensitive searches anyway.
			if ($casesensitive) {
				$searchterms[] = "(" . implode ($search_fields, " $like '%$term%' OR ") . " $like '%$term%')";
			} else {
				$searchterms[] = "(" . implode ($search_fields, " $like '%$insensitive%' OR ") . " $like '%$term%')";
			}
		}
	}

	// now build the complete query, merging all partial term search clauses
	if (is_array ($searchterms) ) {
		$cmp = ($search_type==0) ? "AND" : "OR";
		$whereclause .= " AND (" . implode (" $cmp ", $searchterms) . ") ";
	}

	if (!empty($where) ) {
		$whereclause .= " AND ($where)";
	}
	return $whereclause;

} // end func

}; // end class

} // defined MSSQL_ACCESS
?>
