<?php
//echo "Testing DB.";
Class Mysql {
    private $host = 'localhost'; 
	private $user = 'database-user';
	private $pass = 'database-pass';
	private $db   = 'database-name';

    private static $instance = NULL;

    public $conditions = array();
    public $joins = array();
    public $order;
    public $group;
    public $limit;
    public $last_query;
    public $offset = null;
    public $having = null;
	private $conn;

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

    public static function getInstance() {
        if (is_null(self::$instance) ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __clone(){
    }
	
	function testconnection(){
		return "it works";
	}
	
	function connection(){
		$dbcon = mysqli_connect($this->host, $this->user, $this->pass);
		return $dbcon;
	}	

    function connect() {
		// ORIGINAL WORKING METHOD
        //$dbcon = mysqli_connect($this->host, $this->user, $this->pass);
		//return mysqli_select_db($dbcon,$this->db);
		$dbcon = mysqli_connect($this->host, $this->user, $this->pass,$this->db);
		$this->conn=$dbcon;	
    }
  
    function db(){
		return $this->db;
    }    

    function ping() {
		mysqli_ping($this->conn);
    }       

    function query($q) {
		$dbcon = mysqli_connect($this->host, $this->user, $this->pass);
		$db_select = mysqli_select_db($dbcon,$this->db);

		if (!$dbcon) {
			die("Database connection failed");
		} 

		if (!$db_select) {
			die("Database selection failed: " . mysqli_error($dbcon));
		} else {
			$this->last_query = $q;
		}
		$r = mysqli_query($dbcon, $q) or die("Error occured : ".mysqli_error($dbcon));
		return $r;
    }

    function where($condition, $value = null) {
        if (gettype($value) == 'array') {
            foreach ($value as $index => $val) {
                if (!is_numeric($val)) {
                    $value[$index] = "'$val'";
                }
            }
            $value = implode(',', $value);
        }
        elseif (is_null($value))
            $value = "";
        elseif (!is_numeric($value))
            $value = "'" . addslashes($value) . "'";

        $condition = str_replace('?', $value, $condition);

        $this->conditions[] = $condition;
        return $this;
    }

    function having($cond) {
        $this->having = $cond;
        return $this;
    }

    function order_by($by) {
        $this->order = $by;
        return $this;
    }

    function group_by($by) {
        $this->group = $by;
        return $this;
    }

    function limit($max) {
        $this->limit = $max;
        return $this;
    }

    function offset($idx) {
        $this->offset = $idx;
        return $this;
    }

    function join($table, $on, $type = "") {
        if (!empty($type))
            $type = strtoupper(trim($type)) . " ";

        $this->joins[] = array($table, $on, $type);
        return $this;
    }

    function select($table, $fields = '*', $key = '', $debug = false) {
        if (!empty($this->conditions)) {
            $conditions = 'WHERE ' . implode(' AND ', $this->conditions) . "\n";
        } else {
            $conditions = '';
        }

        if (gettype($fields) != 'string') {
            if (gettype($fields) == 'array') {
                $fields = implode(',', $fields);
            } else {
                die('not going to happen');
            }
        }

        $sql = "SELECT $fields FROM $table\n";

        if (!empty($this->joins)) {
            foreach ($this->joins as $join) {
                $sql .= "{$join[2]}JOIN {$join[0]} ON {$join[1]}\n";
            }
        }

        $sql .= $conditions;

        if (isset($this->having)) {
            $sql .= "HAVING {$this->having}\n";
        }

        if ($this->group) {
            $sql .= "GROUP BY {$this->group}\n";
        }

        if ($this->order) {
            $sql .= "ORDER BY {$this->order}\n";
        }

        if ($this->limit) {
            $sql .= " LIMIT {$this->limit}" . (isset($this->offset) ? " OFFSET {$this->offset}" : "");
        }

        if ($debug) {var_dump($sql);die;}

        $r = $this->query($sql);
        if (empty($r))
            return [];

        $output = array();
        while ($row = mysqli_fetch_assoc($r)) {
            if ($key && isset($row[$key])) {
                $output[$row[$key]] = $row;
            } else {
                $output[] = $row;
            }
        }
        $this->conditions = array();
        $this->joins = array();
        $this->order = '';
        $this->limit = '';
        $this->offset= null;
        $this->group = '';
        $this->having= null;
        return $output;
    }

    function update($table, $data) {
        if (!empty($data)) {
            if (!empty($this->conditions)) {
                $conditions = 'WHERE ' . implode(' AND ', $this->conditions) . "\n";
            } else {
                $conditions = '';
            }

            $fields = array();
            
            if (gettype($data) == 'array') {
                foreach ($data as $field => $value) {
                    $value = addslashes($value);
                    $fields[] = "`$field` = '$value'";
                }
                $fields = implode(', ', $fields);
            } else {
                $fields = $data;
            }

            $sql = "UPDATE $table SET $fields ";

            $sql .= $conditions;

            if ($this->limit) {
                $sql .= " LIMIT {$this->limit}";
            }

            $r = $this->query($sql);
        }

        $this->conditions = array();
        $this->joins = array();
        $this->order = '';
        $this->limit = '';
        return $r;
    }

    function delete($table) {
        if (!empty($this->conditions)) {
            $conditions = 'WHERE ' . implode(' AND ', $this->conditions) . "\n";
        } else {
            $conditions = '';
        }

        $sql = "DELETE FROM $table\n";

        if (!empty($this->joins)) {
            foreach ($this->joins as $join) {
                $sql .= "{$join[2]}JOIN {$join[0]} ON {$join[1]}\n";
            }
        }

        $sql .= $conditions;

        if ($this->limit) {
            $sql .= " LIMIT {$this->limit}";
        }

        $r = $this->query($sql);

        $this->conditions = array();
        $this->joins = array();
        $this->order = '';
        $this->limit = '';

        return $r;
    }

    function select_one($table, $fields = '*') {
        $this->limit = 1;
        $res = $this->select($table, $fields);
        if ($res) {
            return $res[0];
        } else {
            return 0;
        }
    }

    function insert($table, $data) {
		if (empty($data)) {
			return 0;
		}

		$fields = array();
		foreach ($data as $field => $value) {
			if (!is_array($value)) {
				$value = addslashes($value);
			} else {
				$value = $value;
			}

			$fields[] = "`$field` = '$value'";
		}

		$sql = "INSERT IGNORE INTO `$table` SET " . implode(', ', $fields) ;

		$con=$this->conn;
		if ($result = mysqli_query($con, $sql)) {
			return mysqli_insert_id($con);
		}  
    }

    function affected_rows() {
        $con=$this->conn;
        return mysqli_affected_rows($con);        
    }

    function insert_id() {
        $dbcon=$this->conn;
        
        if (mysqli_connect_errno()) {
          echo "Failed to connect to MySQL: " . mysqli_connect_error();
          exit();
        }
        return mysqli_insert_id($dbcon);
    }
}