<?php
class FronkDB {

	public $link;
	private $result;
	private $lastError;
  private $log;

	private static $instance;

	public function __construct($host=false,$user=false,$pass=false,$db=false) {
		$this->host=$host;
		$this->user=$user;
		$this->pass=$pass;
		$this->db=$db;
		
		if(!$host) $this->host=FRONKDB_DBHOST;
		if(!$user) $this->user=FRONKDB_DBUSER;
		if(!$pass) $this->pass=FRONKDB_DBPASS;
		if(!$db) $this->db=FRONKDB_DBNAME;
		
		$this->connect();
    $this->log = mfLoghandler::singleton();
	}
	
	public static function singleton($host=false,$user=false,$pass=false,$db=false) {
			if(!isset(self::$instance)) {
			$c=__CLASS__;
			self::$instance=new $c($host,$user,$pass,$db);
		}
		return self::$instance;
	}
	
	private function connect() {
		if(!$this->link) {
			$this->link=mysqli_connect($this->host,$this->user,$this->pass,$this->db) or die("Error connecting to database...".mysqli_error($this->link));
		}
		mysqli_select_db($this->link,$this->db) or die("Error connecting to database...".mysqli_error($this->link));
		if(function_exists("mysqli_set_charset")) {
			mysqli_set_charset($this->link,'utf8');
		} else {
			$this->query("SET NAMES utf8");
		}
	}
	
	public function disconnect() {
		if($this->link) {
			mysqli_close($this->link);
			$this->link=false;
		}
	}
	
	public function escape($string) {
			return mysqli_real_escape_string($this->link,$string);
	}
	
	public function query($sql,$print_error=false) {
		if(!$this->link) {
			$this->connect();
		}

		if(FRONKDB_SQLDEBUG==true) {
			echo "$sql\n";
		}
		
		if($this->result=mysqli_query($this->link,$sql)) {
			return $this->result;
		} else {
			$this->lastError=mysqli_error($this->link);
			if($print_error) {
				echo "Error in SQL-query:<br />\n".$sql."<br />\n".$this->lastError."<br />\n";
			}
      $this->log->warn("SQL Query failed: $sql");
			return false;
		}
	}

	public function getLastError() {
		return $this->lastError;
	}

	public function num_rows($_res=false) {
		$rows=false;
		$res=$this->result;

		if($_res)
			$res=$_res;

		if(!$res)
			return 0;

		if($rows=mysqli_num_rows($res))
			return $rows;

		return 0;
	}

	public function fetch_array($_res=false) {
		$array=false;
		$res=$this->result;

		if($_res)
			$res=$_res;

		if(!$res)
			return false;

		if($array=mysqli_fetch_assoc($res))
			return $array;

		return false;
	}

	public function fetch_object($_res=false) {
		$obj=false;
		$res=$this->result;

		if($_res)
			$res=$_res;

		if(!$res)
			return false;

		if($obj=mysqli_fetch_object($res))
			return $obj;

		return false;
	}

	public function insert($_table,$_data,$_forcestr=array(),$options=array()) {
		if(empty($_table)) {
			$this->lastError="Error constructing INSERT: tablename ommited";
			return false;
		}

		$table=$_table;

		$fields="";
		$values="";
		$STRINGS=$_forcestr;

		// Build INSERT

		foreach ($_data as $f=>$v) {
			$_Q="'";
			if(is_string($v)) {
				$v=$this->escape($v);
			}
			if(is_numeric($v)) {
				if(!in_array($f,$STRINGS)) {
					$_Q="";
				}
			}
      if($v === null) {
        $_Q = '';
        $v = "NULL";
      }

			$fields.=",`$f`";
			$values.=",".$_Q.$v.$_Q;
		}

		$fields=preg_replace('/^,/','',$fields);
		$values=preg_replace('/^,/','',$values);

		$SQLstr="INSERT INTO `$table` ($fields) VALUES($values)";

		if(!$this->query($SQLstr)) {
			return false;
		}

		return true;
	}

	public function update($_table,$_data,$_where,$_forcestr=array()) {
		if(empty($_table)) {
			$this->lastError="Error constructing UPDATE: tablename ommited";
			return false;
		}

		if(empty($_where)) {
			$this->lastError="Security breach on all decks! UPDATE without WHERE clause.";
			return false;
		}

		$table=$_table;

		$Pairs="";
		$where="WHERE $_where";
		$STRINGS=$_forcestr;


		// Build field/value pairs string

		foreach($_data as $f => $v)
		{
			$_Q="'";
			if(is_string($v)) {
				$v=$this->escape($v);
			}
			if(is_numeric($v)) {
				if(!in_array($f,$STRINGS)) {
					$_Q='';
				}
			}
      if($v === null) {
        $_Q = '';
        $v = "NULL";
      }

			$Pairs.=", `$f`=".$_Q.$v.$_Q;
		}

		$Pairs=preg_replace('/^,/','',$Pairs);

		$SQLstr="UPDATE `$table` SET $Pairs $where";
		
		if(!$this->query($SQLstr)) {
			return false;
		}

		return true;

	}

	public function select($_table,$_fields="*",$_where="") {
		$table=$_table;
		$fields=$_fields;
		$where="";

		if(!empty($_where)) {
			$where="WHERE $_where";
		}

		if(empty($_table)) {
			$this->lastError="No table specified";
			return false;
		}

		if(empty($_fields))
		$fields="*";

		if(!is_array($fields)) {
			$fields=preg_split('/ ?, ?/',$fields);
		}

		foreach($fields as $f)
		{
			$fstr.=",`$f`";
			if($f=="*") $fstr="*";
		}

		$fstr=preg_replace('/^,/','',$fstr);
		$SQLstr="SELECT $fstr FROM `$table` $where";
		
		if($res=$this->query($SQLstr)) {
			return $res;
		}

		return false;

	}
	
	public function delete($_table,$_where,$_limit=false) {
		if(empty($_where)) {
			$this->lastError="Security breach on all decks! DELETE without WHERE clause!";
			return false;
		}
		
		if(empty($_table)) {
			$this->lastError="Keine Tabelle angegeben!";
			return false;
		}
			
		$table=$_table;
		$where=$_where;
		$limit="";
		if($_limit) {
			$limit="LIMIT $_limit";
		}
		
		$sql="DELETE FROM `$table` WHERE $where $limit";
		//echo $sql;
		if($this->query($sql)) {
			return true;
		} else {
			return false;
		}
	}
}
