<?php
$doc = (trim($_SERVER['DOCUMENT_ROOT']) > '' ? trim($_SERVER['DOCUMENT_ROOT']) : '..');
if (!isset($config)) require_once('common_cadline_libraries/crm_config.db.php');

if (!defined('_DB_HOST') && isset($config['db_host'])) define('_DB_HOST', $config['db_host']);
if (!defined('_DB_NAME') && isset($config['db_user'])) define('_DB_NAME', $config['db_user']);
if (!defined('_DB_USER') && isset($config['db_user'])) define('_DB_USER', $config['db_user']);
if (!defined('_DB_PASS') && isset($config['db_pass'])) define('_DB_PASS', $config['db_pass']);

class MySqlHelper
{
	public static $msh;
	public $writelog;


	private $host;
	private $name;
	private $user;
	private $pass;

	private $connection;

	private $queryString;
	private $queryResult;

	public function __construct()
	{
		$this->connection = false;
		$this->host = '';
		$this->user = '';
		$this->pass = '';
		$this->name = '';
		$this->writelog = FALSE;
	}

	/**
	 * Return the instance
	 *
	 * @return MySqlHelper
	 */
	public static function getInstance()
	{
		if (!empty(self::$msh)) return self::$msh;
		self::$msh = new MySqlHelper();
		self::$msh->init();
		return self::$msh;
	}

	public static function escapeString($str = "")
	{
		$ret = mysqli_real_escape_string($this->connection, $str);
		return ($ret);
	}

	public function init($host = _DB_HOST, $name = _DB_NAME, $user = _DB_USER, $pass = _DB_PASS)
	{
		$this->host = $host;
		$this->name = $name;
		$this->user = $user;
		$this->pass = $pass;
	}

	private function connect()
	{
		if ($this->connection) return;

		$this->connection = mysqli_connect($this->host, $this->user, $this->pass);

		if (false === $this->connection) throw new Exception('Can\'t connect to db');

		mysqli_select_db($this->connection, $this->name);
		mysqli_query($this->connection, 'SET CHARACTER SET UTF8');
		mysqli_query($this->connection, 'SET NAMES \'UTF8\' ');
		mysqli_set_charset($this->connection, 'utf8');

		if (mysqli_error($this->connection)) throw new Exception(mysqli_error($this->connection));
	}

	public function query($query)
	{
		$this->connect();
		$this->queryString = $query;

		if ($this->is_write_type($query) === TRUE) {
			$boolWrite = TRUE;
			$arrSkip = array('h_aktivalas_infok', 'h_history', 'u_history', 'u_userstatus_history', 'cl_hlusers.userstats2013', 'cl_hlusers.switch', 'cl_hlusers.writelog');
			foreach ($arrSkip as $tabla) {
				if (strpos($query, $tabla)) {
					$boolWrite = FALSE;
					break;
				}
			}

			if ($boolWrite == TRUE) {
				mysqli_query($this->connection, "INSERT INTO `cl_hlusers`.`writelog` (`user`,`datum`,`ip`,`url`,`func`,`sql`) VALUES (
          '" . (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'www.archlinexp.com') . "',
          '" . date("Y-m-d H:i:s", time()) . "',
          '" . (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1') . "',
          '" . (isset($_SERVER['SERVER_NAME']) ? addslashes($_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']) : '') . "',
          '" . addslashes("function: " . __FUNCTION__ . " method: " . __METHOD__) . "','" . addslashes($query) . "');");
			}
		}

		$this->queryResult = mysqli_query($this->connection, $query);
		if (mysqli_error($this->connection)) throw new Exception(mysqli_error($this->connection) . ' Query: ' . $this->queryString);
	}

	public function fetchNext()
	{
		$back = array();
		if ($row = mysqli_fetch_assoc($this->queryResult)) {
			foreach ($row as $key => $value) {
				$row[$key] = stripslashes($value);
			}
			$back = $row;
			return $back;
		}

		return false;
	}

	public function fetchAssoc()
	{
		$back = array();
		while ($row = mysqli_fetch_assoc($this->queryResult)) {
			foreach ($row as $key => $value) {
				$row[$key] = stripslashes($value);
			}
			$back[] = $row;
		}

		return $back;
	}

	public function getInsertedId()
	{
		return mysqli_insert_id($this->connection);
	}

	public function select($table, $where = false, $offset = false, $limit = false, $order = false)
	{
		$whereStr = '';
		$limitStr = '';
		$orderStr = '';

		if (is_array($where)) $whereStr = 'WHERE ' . $this->whereMakerPriv($where);
		elseif ($where) $whereStr = 'WHERE ' . $where;

		if (($offset !== false and $offset !== null) && ($limit !== false and $limit !== null)) {
			$limitStr = 'LIMIT ' . $offset . ', ' . $limit;
		}

		if (is_array($order)) {
			$orderStr = 'ORDER BY ';
			foreach ($order as $key => $value) {
				$orderStr .= $key . ' ' . $value . ' ';
			}
		} elseif ($order) $orderStr = 'ORDER BY ' . $order;

		return $this->query('SELECT * FROM ' . $table . ' ' . $whereStr . ' ' . $orderStr . ' ' . $limitStr);
	}

	public function getProp($table, $func, $field, $where = false)
	{
		$whereStr = '';
		if (is_array($where)) $whereStr = 'WHERE ' . $this->whereMakerPriv($where);
		elseif ($where) $whereStr = 'WHERE ' . $where;

		$this->query('SELECT ' . $func . '(' . $field . ') as p FROM ' . $table . ' ' . $whereStr);

		$arr = $this->fetchAssoc();

		return $arr[0]['p'];
	}

	public function getCount($table, $field = 'id', $where = false)
	{
		return $this->getProp($table, 'COUNT', $field, $where);
	}

	public function getSum($table, $field = 'id', $where = false)
	{
		return $this->getProp($table, 'SUM', $field, $where);
	}

	public function getAvg($table, $field = 'id', $where = false)
	{
		return $this->getProp($table, 'AVG', $field, $where);
	}

	public function delete($table, $where = false)
	{
		$whereStr = '';
		if (is_array($where)) $whereStr = 'WHERE ' . $this->whereMakerPriv($where);
		elseif ($where) $whereStr = 'WHERE ' . $where;

		return $this->query('DELETE FROM ' . $table . ' ' . $whereStr);
	}

	public function update($table, $infoArr, $where = false)
	{
		if (!is_array($infoArr)) {
			return false;
		}

		$whereStr = '';
		$dataArr = array();
		$data = '';
		if (is_array($where)) $whereStr = 'WHERE ' . $this->whereMakerPriv($where);
		elseif ($where) $whereStr = 'WHERE ' . $where;

		foreach ($infoArr as $key => $value) {
			$dataArr[] = '`' . $key . '`="' . mysqli_real_escape_string($this->connection, $value) . '" ';
		}
		$data = implode(',', $dataArr);

		return $this->query('UPDATE ' . $table . ' SET ' . $data . ' ' . $whereStr);
	}

	public function insert($table, $infoArr)
	{
		$this->connect();
		$columArr = array();
		$valueArr = array();
		$colums = '';
		$values = '';

		foreach ($infoArr as $key => $value) {
			$columArr[] = '`' . $key . '`';
			$valueArr[] = '"' . mysqli_real_escape_string($this->connection, $value) . '"';
		}

		$colums = implode(',', $columArr);
		$values = implode(',', $valueArr);

		return $this->query('INSERT INTO ' . $table . ' (' . $colums . ') VALUES (' . $values . ');');
	}

	public function affectedRows()
	{
		return mysqli_affected_rows($this->connection);
	}

	public function whereMakerPriv($where)
	{
		if (!is_array($where)) return 1;
		$this->connect();
		$back = '1 ';
		foreach ($where as $key => $value) {
			if (is_array($value)) $back .= 'AND `' . $key . '`' . $value[0] . '"' . $value[1] . '" ';
			else $back .= 'AND `' . $key . '`="' . mysqli_real_escape_string($this->connection, $value) . '" ';
		}
		return $back;
	}

	public static function whereMaker($where)
	{
		if (!is_array($where)) return 1;
		$back = '1 ';
		foreach ($where as $key => $value) {
			if (is_array($value)) $back .= 'AND `' . $key . '`' . $value[0] . '"' . $value[1] . '" ';
			else $back .= 'AND `' . $key . '`="' . $value . '" ';
		}
		return $back;
	}

	public function is_write_type($sql)
	{
		if (!preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql)) {
			return FALSE;
		}
		return TRUE;
	}

	public function getConnection()
	{
		return ($this->connection);
	}

	public function setConnect()
	{
		$this->connect();
	}
}
