<?php

class Database {


var $server   = null; //database server
var $user     = null; //database login name
var $pass     = null; //database login password
var $database = null; //database name
var $pre      = ""; //table prefix


#######################
//internal info
var $error = "";
var $errno = 0;

//number of rows affected by SQL query
var $affected_rows = 0;

var $link_id = null;
var $query_id = null;

var $num_pages=null;


#-#############################################
# desc: constructor
function __CONSTRUCT($server, $user, $pass, $database, $pre=''){
	$this->server=$server;
	$this->user=$user;
	$this->pass=$pass;
	$this->database=$database;
	$this->pre=$pre;
}#-#constructor()


#-#############################################
# desc: connect and select database using vars above
# Param: $new_link can force connect() to open a new link, even if mysql_connect() was called before with the same parameters
function connect($new_link=false) {

	mysqli_report(MYSQLI_REPORT_OFF);
	$this->link_id=@mysqli_connect($this->server,$this->user,$this->pass,$this->database);
	//print($this->link_id);
	if (!$this->link_id) {//open failed
		return -1;
		}
	
	if(!@mysqli_select_db($this->link_id, $this->database)) {//no database
		return -1;
		}

	/*
	 * This application was originally written for the permissive SQL mode used
	 * by its PHP 7.3-era server. Its forms intentionally leave some legacy
	 * NOT NULL columns unset, and several reports use non-strict GROUP BY
	 * queries. Apply compatibility mode only to this application's connection;
	 * no global MySQL or cPanel setting is changed.
	 */
	if (!@mysqli_query($this->link_id, "SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION'")) {
		error_log('Unable to apply legacy SQL compatibility mode: ' . mysqli_error($this->link_id));
	}
	
	// unset the data so it can't be dumped

}#-#connect()


#-#############################################
# desc: close the connection
function close() {
	if($this->link_id instanceof mysqli && !@mysqli_close($this->link_id)){
		//print("-1"); exit;	
		return -1;
		//$this->oops("Connection close failed.");
	}
}#-#close()


#-#############################################
# Desc: escapes characters to be mysql ready
# Param: string
# returns: string
function escape($string) {
	return @mysqli_real_escape_string($this->link_id, (string) $string);
}#-#escape()


#-#############################################
# Desc: executes SQL query to an open connection
# Param: (MySQL query) to execute
# returns: (query_id) for fetching results etc
function query($sql) {
	// do query
	//print($sql);
	if (!($this->link_id instanceof mysqli)) {
		$this->affected_rows = 0;
		$this->error = 'Database connection is not available.';
		$this->errno = 0;
		error_log($this->error);
		return false;
	}
	$this->query_id = @mysqli_query($this->link_id, $sql);

	if (!$this->query_id) {
		$this->affected_rows = 0;
		$this->error = mysqli_error($this->link_id);
		$this->errno = mysqli_errno($this->link_id);
		error_log('Database query failed [' . $this->errno . ']: ' . $this->error);
		//print("-1"); exit;	
		//$this->oops("<b>MySQL Query fail:</b> $sql");
		return false;
	}
	
	$this->affected_rows = @mysqli_affected_rows($this->link_id);

	return $this->query_id;
}#-#query()


#-#############################################
# desc: fetches and returns results one line at a time
# param: query_id for mysql run. if none specified, last used
# return: (array) fetched record(s)
function fetch_array($query_id=-1) {
	// retrieve row
	if ($query_id instanceof mysqli_result) {
		$this->query_id=$query_id;
	}

	if ($this->query_id instanceof mysqli_result) {
		$record = @mysqli_fetch_object($this->query_id);
	}else{
		return false;
	}

	return $record;
}#-#fetch_array()


#-#############################################
# desc: returns all the results (not one row)
# param: (MySQL query) the query to run on server
# returns: assoc array of ALL fetched results
function fetch_all_array($sql,$pageno="null",$pagesize="null") {
	
	$query_id = $this->query($sql);
	$out = array();
	
		if($pageno != "null" && $pagesize != "null") {

			$num_rows = $this->affected_rows;
			$this->num_pages = intval($num_rows/$pagesize);
			if($num_rows%$pagesize) $this->num_pages++;
			
		}
		
				
		if($this->affected_rows) {
			
			$index = 0;		
			if($pageno != "null" && $pagesize != "null") {

				mysqli_data_seek($query_id,($pageno-1)*$pagesize);
				$i=1;
				while ($row = $this->fetch_array($query_id)){
					
					if($pagesize<$i++) break;
					
					$out[] = $row;
				
				} //WHILE
				
			} else {
			
				while ($row = $this->fetch_array($query_id)){
					$out[] = $row;
				}
			
			}
			
			$this->free_result($query_id);
			return $out;
			
		} else{
			
			return -1;
			
		} //if
	/*while ($row = $this->fetch_array($query_id)){
		$out[] = $row;
	}*/

	//$this->free_result($query_id);
	//return $out;
}#-#fetch_all_array()


#-#############################################
# desc: frees the resultset
# param: query_id for mysql run. if none specified, last used
function free_result($query_id=-1) {
	if ($query_id instanceof mysqli_result) {
		$this->query_id=$query_id;
	}
	if($this->query_id instanceof mysqli_result && !@mysqli_free_result($this->query_id)) {
		//print("-1"); exit;	
		return -1;
		//$this->oops("Result ID: <b>$this->query_id</b> could not be freed.");
	}
}#-#free_result()


#-#############################################
# desc: does a query, fetches the first row only, frees resultset
# param: (MySQL query) the query to run on server
# returns: array of fetched results
function query_first($query_string) {
	$query_id = $this->query($query_string);
	if (!($query_id instanceof mysqli_result)) {
		return false;
	}
	$out = $this->fetch_array($query_id);
	$this->free_result($query_id);
	return $out;
}#-#query_first()


#-#############################################
# desc: does an update query with an array
# param: table (no prefix), assoc array with data (doesn't need escaped), where condition
# returns: (query_id) for fetching results etc
function query_update($table, $data, $where='1') {
	$q="UPDATE `".$this->pre.$table."` SET ";

	foreach($data as $key=>$val) {
		if(strtolower($val)=='null') $q.= "`$key` = NULL, ";
		elseif(strtolower($val)=='now()') $q.= "`$key` = NOW(), ";
        elseif(preg_match("/^increment\((\-?\d+)\)$/i",$val,$m)) $q.= "`$key` = `$key` + $m[1], "; 
		else $q.= "`$key`='".$this->escape($val)."', ";
	}

	$q = rtrim($q, ', ') . ' WHERE '.$where.';';
	//echo $q;
	return $this->query($q);
}#-#query_update()


#-#############################################
# desc: does an insert query with an array
# param: table (no prefix), assoc array with data
# returns: id of inserted record, false if error
function query_insert($table, $data) {
//print($table);
	$q="INSERT INTO `".$this->pre.$table."` ";
	$v=''; $n='';

	foreach($data as $key=>$val) {
		$n.="`$key`, ";
		if(strtolower($val)=='null') $v.="NULL, ";
		elseif(strtolower($val)=='now()') $v.="NOW(), ";
		else $v.= "'".$this->escape($val)."', ";
	}

	$q .= "(". rtrim($n, ', ') .") VALUES (". rtrim($v, ', ') .");";
	//print($q);
	
	if($this->query($q)){
		//$this->free_result();
		return mysqli_insert_id($this->link_id);
	}
	else return false;

}#-#query_insert()


#-#############################################
# desc: throw an error message
# param: [optional] any custom error to display
function oops($msg='') {
	if($this->link_id instanceof mysqli){
		$this->error=mysqli_error($this->link_id);
		$this->errno=mysqli_errno($this->link_id);
	}
	else{
		$this->error='Database connection is not available.';
		$this->errno=0;
	}
	?>	
		<table align="center" border="1" cellspacing="0" style="background:white;color:black;width:80%;">
		<tr><th colspan=2>Database Error</th></tr>
		<tr><td align="right" valign="top">Message:</td><td><?php echo $msg; ?></td></tr>
		<?php if(!empty($this->error)) echo '<tr><td align="right" valign="top" nowrap>MySQL Error:</td><td>'.$this->error.'</td></tr>'; ?>
		<tr><td align="right">Date:</td><td><?php echo date("l, F j, Y \a\\t g:i:s A"); ?></td></tr>
		<?php if(!empty($_SERVER['REQUEST_URI'])) echo '<tr><td align="right">Script:</td><td><a href="'.$_SERVER['REQUEST_URI'].'">'.$_SERVER['REQUEST_URI'].'</a></td></tr>'; ?>
		<?php if(!empty($_SERVER['HTTP_REFERER'])) echo '<tr><td align="right">Referer:</td><td><a href="'.$_SERVER['HTTP_REFERER'].'">'.$_SERVER['HTTP_REFERER'].'</a></td></tr>'; ?>
		</table>
	<?php
}#-#oops()

#-#############################################
# desc: get total number of rows of a result set
function GetNumRows() {
	
		return $this->affected_rows;
	}
	
function GetNumberOfPages() {
		
		return $this->num_pages;
		
	}

}//CLASS Database
###################################################################################################

?>
