<?php

abstract class Conexion{
    protected $_servidor;
    protected $_driver;
    protected $_usuario;
    protected $_contrasena;
    protected $_bd;

    private $_conexion;
    private $_sql;
    private $_query;
    private $_parametros;
    private $_mensaje;

    function __construct(){
        $this->Conectar();
    }

    private function Conectar(){
        if(empty($this->_servidor))
            $this->_servidor = '127.0.0.1';

        if(empty($this->_driver))
            $this->_driver = 'mysql';

        if(empty($this->_usuario))
            $this->_usuario = _USUARIO_;

        if(empty($this->_contrasena))
            $this->_contrasena = _CONTRASENA_;

        if(empty($this->_bd))
            $this->_bd = _BD_;

        $arr_attr = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);

        switch($this->_driver){
            case 'mysql':
                $driver = "mysql:host={$this->_servidor};dbname={$this->_bd};charset=utf8";
                $arr_attr[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES utf8';
            break;
            case 'mssql':
                $driver = "sqlsrv:server={$this->_servidor};Database={$this->_bd};ColumnEncryption=Enabled";
            break;
        }

        try{
            $this->_conexion = new PDO(
                $driver,
                $this->_usuario,
                $this->_contrasena,
                $arr_attr
            );

            unset($driver, $arr_attr);
        }catch(PDOException $e){
            errorLogSQL("[{$this->_driver}] " . $e->getMessage(), 'Conexion a BD');
        }
    }

    private function Desconectar(){
        $this->_sql         = NULL;
        $this->_conexion    = NULL;
    }

    function __destruct(){
        $this->Desconectar();
    }

    protected function Asignar($query, $mensaje, $parametros = array()){
        if(count($parametros) > 0){
            $cont = 0;
            foreach($parametros as $p){
                ++$cont;

                if(is_object($p) || is_array($p)){
                    $dato       = json_encode($p);
                    $contenido  = 'Algunos parametros no tienen el formato correcto.<br>'
                        . "<b>Detectado :</b> &nbsp; ({$cont}) {$dato}<br>"
                        . '<b>Parámetros :</b> &nbsp; ' . json_encode($parametros);

                    unset($parametros, $p, $dato);
                    errorLogSQL($contenido, $mensaje);
                    exit;
                }
            }
        }

        $this->_query       = $query;
        $this->_mensaje     = $mensaje;
        $this->_parametros  = $parametros;
    }

    private function Consulta(){
        $this->_sql = NULL;

        try{
            $this->_sql = $this->_conexion->prepare($this->_query);

            if(!$this->_sql->execute($this->_parametros))
                errorLogSQL('No se pudo ejecutar la consulta. [' . $this->_sql->errorCode() . '] ' . implode(',', $this->_conexion->errorInfo()), $this->_mensaje, $this->_parametros);
        }catch(PDOException $e){
            errorLogSQL($e->getMessage(), $this->_mensaje, $this->_parametros);
        }
    }

    private function LiberarMemoria(){
        $this->_sql->closeCursor();
    }

    protected function Filas(){
        $this->Consulta();
        $filas = ($this->_driver == 'mysql')? $this->_sql->rowCount() : count($this->_sql->fetchAll(PDO::FETCH_OBJ));
        $this->LiberarMemoria();
        return $filas;
    }

    protected function ConsultaIndividual(){
        $this->Consulta();

        $filas      = $this->_sql->rowCount();
        $filas_aux  = 0;

        if($this->_driver == 'mssql'){
            try{
                $filas_aux  = count($this->_sql->fetchAll());
            }catch(Exception $e){ }
        }
        $this->LiberarMemoria();

        return ($filas > 0 || $filas_aux > 0);
    }

    protected function ConsultaIndividual2(){
        //$this->Consulta();
        print_r($this->Consulta());

        $filas      = $this->_sql->rowCount();
        $filas_aux  = 0;

        if($this->_driver == 'mssql'){
            try{
                $filas_aux  = count($this->_sql->fetchAll());
            }catch(Exception $e){ }
        }
        $this->LiberarMemoria();

        return ($filas > 0 || $filas_aux > 0);
    }

    protected function ResultadoConsulta(){
        return $this->ConsultaIndividual();
    }

    protected function ObtenerID(){
        $this->Consulta();
        $id = $this->_conexion->lastInsertId();
        $this->LiberarMemoria();

        return $id;
    }

    protected function DatoUnico($formato = false){
        $this->Consulta();
        $dato = ($formato)? utf8_encode($this->_sql->fetchColumn()) : $this->_sql->fetchColumn();
        $this->LiberarMemoria();
        return ($dato != '')? $dato : false;
    }

    protected function FilaUnica($formato = false){
        $this->Consulta();

        $campos = $this->_sql->fetch(PDO::FETCH_OBJ);

        if(!empty($campos)){
            $fila = sClass();

            foreach($campos as $k => $v)
                $fila->$k = ($formato)? utf8_encode($v) : $v;

        }else
            $fila = false;

        unset($campos, $formato);

        $this->LiberarMemoria();
        return $fila;
    }

    protected function ListarDatos($formato = false){
        $filas = array();
        $this->Consulta();

        foreach($this->_sql->fetchAll(PDO::FETCH_OBJ) as $r){
            $fila = sClass();

            foreach($r as $k => $v)
                $fila->$k = ($formato)? utf8_encode($v) : $v;

            $filas[] = $fila;
            unset($fila);
        }

        unset($formato);
        $this->LiberarMemoria();
        return $filas;
    }
}
