diff --git a/system/database/autoload.php b/system/database/autoload.php index aa9270a..1da6f69 100644 --- a/system/database/autoload.php +++ b/system/database/autoload.php @@ -7,18 +7,167 @@ */ +namespace Phacil\Framework; -if(!defined('DIR_DATABASE')) - define('DIR_DATABASE', (__DIR__)."/"); +final class Database { + /** + * + * @var object + */ + private $driver; + + /** + * + * @var string + */ + private $cachePrefix = "SQL_"; + + /** + * @param string $driver + * @param string $hostname + * @param string $username + * @param string $password + * @param string $database + * @return void + */ + public function __construct($driver, $hostname, $username, $password, $database) { -include DIR_DATABASE."/library/db.php"; + $driverClass = "\\Phacil\\Framework\\Databases\\".$driver; -use Phacil\Framework; + try { + $this->driver = new $driverClass($hostname, $username, $password, $database); + } catch (Exception $th) { + throw new Exception('Error: Could not load database file ' . $driver . '!'); + //exit('Error: Could not load database file ' . $driver . '!'); + } + + } + + /** + * @param string $sql + * @param bool $cacheUse + * @return object|\Phacil\Framework\DB::Cache + * @throws PhpfastcacheInvalidArgumentException + */ + public function query($sql, $cacheUse = true) { + + if(defined('SQL_CACHE') && SQL_CACHE == true && $cacheUse == true) { + + return $this->Cache($sql); + + } else { + + return $this->driver->query($sql); + } + + } + + /** + * @param string $value + * @return mixed + */ + public function escape($value) { + return $this->driver->escape($value); + } + + /** @return int */ + public function countAffected() { + return $this->driver->countAffected(); + } -if(defined('DB_DRIVER')) { + /** @return mixed */ + public function getLastId() { + return $this->driver->getLastId(); + } + + /** + * @param string $sql + * @param int $pageNum_exibe + * @param int $maxRows_exibe + * @param bool $cache + * @param mixed|null $sqlTotal + * @return object + * @throws PhpfastcacheInvalidArgumentException + */ + public function pagination($sql, $pageNum_exibe = 1, $maxRows_exibe = 10, $cache = true, $sqlTotal = null){ + + if (($pageNum_exibe >= 1)) { + $pageNum_exibe = $pageNum_exibe-1; + } + $startRow_exibe = $pageNum_exibe * $maxRows_exibe; + + $query_exibe = $sql; + + $query_limit_exibe = sprintf("%s LIMIT %d, %d", $query_exibe, $startRow_exibe, $maxRows_exibe); + + $exibe = $this->query($query_limit_exibe, $cache); + + $re = '/^(SELECT \*)/i'; + + $all_exibe_query = ($sqlTotal != null) ? $sqlTotal : ((preg_match($re, $query_exibe)) ? preg_replace($re, "SELECT COUNT(*) as __TOTALdeREG_DB_Pagination", $query_exibe) : $query_exibe); + + $all_exibe = $this->query($all_exibe_query, $cache); + $totalRows_exibe = (isset($all_exibe->row['__TOTALdeREG_DB_Pagination'])) ? $all_exibe->row['__TOTALdeREG_DB_Pagination'] : $all_exibe->num_rows; + + if($totalRows_exibe <= 0){ + $all_exibe_query = $query_exibe; + $all_exibe = $this->query($all_exibe_query, $cache); + $totalRows_exibe = (isset($all_exibe->row['__TOTALdeREG_DB_Pagination'])) ? $all_exibe->row['__TOTALdeREG_DB_Pagination'] : $all_exibe->num_rows; + } + + $totalPages_exibe = ceil($totalRows_exibe/$maxRows_exibe); + + $exibe->totalPages_exibe = $totalPages_exibe; + $exibe->totalRows_exibe = $totalRows_exibe; + $exibe->pageNum_exibe = $pageNum_exibe+1; + + return $exibe; + } + + /** + * @param string $sql + * @return object + * @throws PhpfastcacheInvalidArgumentException + */ + private function Cache($sql) { + if(class_exists('Caches')) { + $cache = new Caches(); + + if (stripos($sql, "select") !== false) { + + if($cache->check($this->cachePrefix.md5($sql))) { + + return $cache->get($this->cachePrefix.md5($sql)); + + } else { + $cache->set($this->cachePrefix.md5($sql), $this->driver->query($sql)); + + return $this->driver->query($sql); + } + } else { + return $this->driver->query($sql); + } + } else { + return $this->driver->query($sql); + } + } + + /** + * @param string $nome + * @param object $object + * @return void + */ + public function createSubBase($nome, $object) { + + $this->$nome = $object; + } +} + + +/* if(defined('DB_DRIVER')) { global $db; $db = new Phacil\Framework\DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE); } else { global $db; $db = new Phacil\Framework\DB('nullStatement', NULL, NULL, NULL, NULL); -} +} */ diff --git a/system/database/database/dbmysqli.php b/system/database/database/dbmysqli.php deleted file mode 100644 index 30cc6e2..0000000 --- a/system/database/database/dbmysqli.php +++ /dev/null @@ -1,51 +0,0 @@ -connection = new \mysqli($hostname, $username, $password, $database, $port); - if ($this->connection->connect_error) { - throw new \Exception('Error: ' . $this->connection->error . '
Error No: ' . $this->connection->errno); - } - $this->connection->set_charset($charset); - $this->connection->query("SET SQL_MODE = ''"); - } - public function query($sql) { - $query = $this->connection->query($sql); - if (!$this->connection->errno) { - if ($query instanceof \mysqli_result) { - $data = array(); - while ($row = $query->fetch_assoc()) { - $data[] = $row; - } - $result = new \stdClass(); - $result->num_rows = $query->num_rows; - $result->row = isset($data[0]) ? $data[0] : array(); - $result->rows = $data; - $query->close(); - return $result; - } else { - return true; - } - } else { - throw new \Exception('Error: ' . $this->connection->error . '
Error No: ' . $this->connection->errno . '
' . $sql); - } - } - public function escape($value) { - return $this->connection->real_escape_string($value); - } - - public function countAffected() { - return $this->connection->affected_rows; - } - public function getLastId() { - return $this->connection->insert_id; - } - - public function isConnected() { - return $this->connection->ping(); - } - - public function __destruct() { - $this->connection->close(); - } -} diff --git a/system/database/databases/dbmysqli.php b/system/database/databases/dbmysqli.php new file mode 100644 index 0000000..151c0ca --- /dev/null +++ b/system/database/databases/dbmysqli.php @@ -0,0 +1,13 @@ +connection = null; + unset($this->connection); } } \ No newline at end of file diff --git a/system/database/database/mssql.php b/system/database/databases/mssql.php similarity index 79% rename from system/database/database/mssql.php rename to system/database/databases/mssql.php index 4c83f7a..b557417 100644 --- a/system/database/database/mssql.php +++ b/system/database/databases/mssql.php @@ -1,4 +1,18 @@ connection); } } -?> \ No newline at end of file diff --git a/system/database/databases/mysql.php b/system/database/databases/mysql.php new file mode 100644 index 0000000..c5410cc --- /dev/null +++ b/system/database/databases/mysql.php @@ -0,0 +1,18 @@ +connection); } } -?> \ No newline at end of file diff --git a/system/database/database/db_pdo.php b/system/database/databases/mysql_pdo.php similarity index 83% rename from system/database/database/db_pdo.php rename to system/database/databases/mysql_pdo.php index ac52a85..4674e2a 100644 --- a/system/database/database/db_pdo.php +++ b/system/database/databases/mysql_pdo.php @@ -1,13 +1,14 @@ PDO::ERRMODE_SILENT + 'PDO::ATTR_ERRMODE' => \PDO::ERRMODE_SILENT ); /** * The number of rows affected by the last operation @@ -46,7 +47,7 @@ final class DB_PDO */ public function __construct($host, $user, $pass, $name, $port = '3306', $charset = 'utf8mb4') { - $this->params = new stdClass; + $this->params = new \stdClass; # keep connection data $this->params->host = $host; $this->params->user = $user; @@ -64,11 +65,11 @@ final class DB_PDO public function connect() { try { - $this->dbh = new PDO($this->params->connstr, $this->params->user, $this->params->pass, $this->options); + $this->dbh = new \PDO($this->params->connstr, $this->params->user, $this->params->pass, $this->options); if (version_compare(PHP_VERSION, '5.3.6', '<=')) { $this->dbh->exec($this->options['PDO::MYSQL_ATTR_INIT_COMMAND']); } - } catch (PDOException $exception) { + } catch (\PDOException $exception) { trigger_error($exception->getMessage()); } } @@ -81,7 +82,7 @@ final class DB_PDO public function query($sql = null) { if ($this->dbh) { - $data = new stdClass; + $data = new \stdClass; $sth=$this->dbh->prepare($sql); $sth->execute(); @@ -129,7 +130,7 @@ final class DB_PDO */ public function getDriverName() { - return $this->dbh ? $this->dbh->getAttribute(PDO::ATTR_DRIVER_NAME) : null; + return $this->dbh ? $this->dbh->getAttribute(\PDO::ATTR_DRIVER_NAME) : null; } /** * Get information about the version of the client libraries that are used by the PDO driver @@ -138,7 +139,7 @@ final class DB_PDO */ public function getVersion() { - return $this->dbh ? $this->dbh->getAttribute(PDO::ATTR_CLIENT_VERSION) : null; + return $this->dbh ? $this->dbh->getAttribute(\PDO::ATTR_CLIENT_VERSION) : null; } /** * Closing a database connection diff --git a/system/database/databases/mysqli.php b/system/database/databases/mysqli.php new file mode 100644 index 0000000..74baa80 --- /dev/null +++ b/system/database/databases/mysqli.php @@ -0,0 +1,117 @@ +connection = @new \MySQLi($hostname, $username, $password, $database, $port); + } catch (\mysqli_sql_exception $e) { + throw new \Exception('Error: ' . $this->connection->error . '
Error No: ' . $this->connection->errno); + } + + if (!$this->connection->connect_errno) { + $this->connection->report_mode = MYSQLI_REPORT_ERROR; + $this->connection->set_charset($charset); + //$this->connection->query("SET SESSION sql_mode = 'NO_ZERO_IN_DATE,NO_ENGINE_SUBSTITUTION'"); + $this->connection->query("SET SQL_MODE = ''"); + } else { + throw new \Exception('Error: Could not make a database link using ' . $username . '@' . $hostname . '!'); + } + + } + + /** + * Execute the SQL Query. + * + * @param string $sql + * @return stdClass|true + * @throws Exception + */ + public function query($sql) { + $query = $this->connection->query($sql); + if (!$this->connection->errno) { + if ($query instanceof \mysqli_result) { + $data = array(); + while ($row = $query->fetch_assoc()) { + $data[] = $row; + } + $result = new \stdClass(); + $result->num_rows = $query->num_rows; + $result->row = isset($data[0]) ? $data[0] : array(); + $result->rows = $data; + $query->close(); + return $result; + } else { + return true; + } + } else { + throw new \Exception('Error: ' . $this->connection->error . '
Error No: ' . $this->connection->errno . '
' . $sql); + } + } + + /** + * Important escape to prevent SQL injection. + * + * @param string $value + * @return string + */ + public function escape($value) { + return $this->connection->real_escape_string($value); + } + + /** + * Number of affected rows + * + * @return int */ + public function countAffected() { + return $this->connection->affected_rows; + } + + /** @return int|string */ + public function getLastId() { + return $this->connection->insert_id; + } + + /** @return bool */ + public function isConnected() { + return $this->connection->ping(); + } + + /** @return void */ + public function __destruct() { + $this->connection->close(); + } +} diff --git a/system/database/database/nullStatement.php b/system/database/databases/nullStatement.php similarity index 60% rename from system/database/database/nullStatement.php rename to system/database/databases/nullStatement.php index 4b85126..0cd6f7b 100644 --- a/system/database/database/nullStatement.php +++ b/system/database/databases/nullStatement.php @@ -1,9 +1,23 @@ connection = NULL; + //$this->connection = NULL; } public function query($sql) { @@ -30,4 +44,3 @@ final class nullStatement { return NULL; } } -?> \ No newline at end of file diff --git a/system/database/database/oracle.php b/system/database/databases/oracle.php similarity index 62% rename from system/database/database/oracle.php rename to system/database/databases/oracle.php index b53ddf9..8138684 100644 --- a/system/database/database/oracle.php +++ b/system/database/databases/oracle.php @@ -1,8 +1,39 @@ connection = oci_connect($username, $password, $hostname."/".$database, $charset); if (!$this->connection) { @@ -11,10 +42,16 @@ final class Oracle{ throw new \Exception(trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR)); } oci_set_client_info($this->connection, "Administrator"); - oci_set_module_name($this->connection, $module); - oci_set_client_identifier($this->connection, $cid); + //oci_set_module_name($this->connection, $module); + //oci_set_client_identifier($this->connection, $cid); } + + /** + * @param string $sql + * @return stdClass + * @throws Exception + */ public function query($sql) { $stid = oci_parse($this->connection, $sql); oci_execute($stid); @@ -33,6 +70,7 @@ final class Oracle{ throw new \Exception('Error: ' . oci_error() . '
' . $sql); } } + public function escape($value) { return str_replace("'", "", $value); } diff --git a/system/database/database/postgre.php b/system/database/databases/postgre.php similarity index 67% rename from system/database/database/postgre.php rename to system/database/databases/postgre.php index 61d05ad..ac9e5f6 100644 --- a/system/database/database/postgre.php +++ b/system/database/databases/postgre.php @@ -1,6 +1,31 @@ link = pg_connect('host=' . $hostname . ' port=' . $port . ' user=' . $username . ' password=' . $password . ' dbname=' . $database)) { throw new \Exception('Error: Could not make a database link using ' . $username . '@' . $hostname); @@ -10,6 +35,12 @@ final class Postgre { } pg_query($this->link, "SET CLIENT_ENCODING TO '".$charset."'"); } + + /** + * @param string $sql + * @return stdClass|true + * @throws Exception + */ public function query($sql) { $resource = pg_query($this->link, $sql); if ($resource) { @@ -34,16 +65,30 @@ final class Postgre { throw new \Exception('Error: ' . pg_result_error($this->link) . '
' . $sql); } } + + /** + * @param string $value + * @return string + */ public function escape($value) { return pg_escape_string($this->link, $value); } + + /** @return int */ public function countAffected() { return pg_affected_rows($this->link); } + + /** + * @return mixed + * @throws Exception + */ public function getLastId() { $query = $this->query("SELECT LASTVAL() AS `id`"); return $query->row['id']; } + + /** @return void */ public function __destruct() { pg_close($this->link); } diff --git a/system/database/database/sqlite3_db.php b/system/database/databases/sqlite3_db.php similarity index 70% rename from system/database/database/sqlite3_db.php rename to system/database/databases/sqlite3_db.php index a0f3f97..ec4c7f9 100644 --- a/system/database/database/sqlite3_db.php +++ b/system/database/databases/sqlite3_db.php @@ -1,17 +1,38 @@ connection = new SQLite3($hostname.$database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $password); + $this->connection = new \SQLite3($hostname.$database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $password); if (!$this->connection) { throw new \Exception('Error: ' . $this->connection->lastErrorMsg() . '
Error No: ' . $this->connection->lastErrorCode()); } } + /** + * @param string $sql + * @return true|stdClass + * @throws Exception + */ public function query($sql){ //$query = $this->connection->query($sql); @@ -40,21 +61,30 @@ final class Sqlite3_db { } + /** + * @param string $value + * @return string + */ public function escape($value) { return $this->connection->escapeString($value); } + /** @return int */ public function countAffected() { return $this->connection->changes(); } + + /** @return int */ public function getLastId() { return $this->connection->lastInsertRowID(); } + /** @return bool */ public function isConnected() { return ($this->connection) ? true : false; } + /** @return void */ public function __destruct() { $this->connection->close(); } diff --git a/system/database/database/sqlsrv.php b/system/database/databases/sqlsrv.php similarity index 75% rename from system/database/database/sqlsrv.php rename to system/database/databases/sqlsrv.php index b848c1d..fcbc664 100644 --- a/system/database/database/sqlsrv.php +++ b/system/database/databases/sqlsrv.php @@ -1,14 +1,31 @@ link, "SET CHARACTER SET utf8"); } + /** + * @param string $sql + * @return stdClass|true + */ public function query($sql) { $resource = \sqlsrv_query($this->link, $sql); @@ -42,7 +63,7 @@ final class SQLSRV { $data = array(); - while ($result = \sqlsrv_fetch_array($resource, SQLSRV_FETCH_ASSOC)) { + while ($result = \sqlsrv_fetch_array($resource, \SQLSRV_FETCH_ASSOC)) { $data[$i] = $result; $i++; @@ -67,16 +88,22 @@ final class SQLSRV { } } + /** + * @param string $value + * @return string + */ public function escape($value) { $unpacked = unpack('H*hex', $value); return '0x' . $unpacked['hex']; } + /** @return int */ public function countAffected() { return \sqlsrv_rows_affected($this->link); } + /** @return false|int */ public function getLastId() { $last_id = false; @@ -91,6 +118,7 @@ final class SQLSRV { return $last_id; } + /** @return void */ public function __destruct() { \sqlsrv_close($this->link); } diff --git a/system/database/database/sqlsrvpdo.php b/system/database/databases/sqlsrvpdo.php similarity index 73% rename from system/database/database/sqlsrvpdo.php rename to system/database/databases/sqlsrvpdo.php index 3fdfe93..ddfa80e 100644 --- a/system/database/database/sqlsrvpdo.php +++ b/system/database/databases/sqlsrvpdo.php @@ -1,12 +1,33 @@ connection = new \PDO("sqlsrv:Server=" . $hostname . ";Database=" . $database, $username, $password, array(\PDO::SQLSRV_ATTR_DIRECT_QUERY => true)); + $this->connection = new PDONative("sqlsrv:Server=" . $hostname . ";Database=" . $database, $username, $password, array(\PDO::SQLSRV_ATTR_DIRECT_QUERY => true)); } catch(\PDOException $e) { throw new \Exception('Failed to connect to database. Reason: \'' . $e->getMessage() . '\''); } @@ -14,10 +35,21 @@ final class sqlsrvPDO { } + /** + * @param string $sql + * @return void + */ public function prepare($sql) { $this->statement = $this->connection->prepare($sql); } + /** + * @param mixed $parameter + * @param mixed $variable + * @param int $data_type + * @param int $length + * @return void + */ public function bindParam($parameter, $variable, $data_type = \PDO::PARAM_STR, $length = 0) { if ($length) { $this->statement->bindParam($parameter, $variable, $data_type, $length); @@ -26,6 +58,10 @@ final class sqlsrvPDO { } } + /** + * @return never + * @throws Exception + */ public function execute() { try { if ($this->statement && $this->statement->execute()) { @@ -45,6 +81,12 @@ final class sqlsrvPDO { } } + /** + * @param string $sql + * @param array $params + * @return stdClass + * @throws Exception + */ public function query($sql, $params = array()) { $this->statement = $this->connection->prepare($sql); @@ -78,10 +120,15 @@ final class sqlsrvPDO { } } + /** + * @param string $value + * @return string + */ public function escape($value) { return str_replace(array("\\", "\0", "\n", "\r", "\x1a", "'", '"'), array("\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"'), $value); } + /** @return int */ public function countAffected() { if ($this->statement) { return $this->statement->rowCount(); @@ -90,10 +137,12 @@ final class sqlsrvPDO { } } + /** @return string */ public function getLastId() { return $this->connection->lastInsertId(); } + /** @return bool */ public function isConnected() { if ($this->connection) { return true; @@ -102,7 +151,8 @@ final class sqlsrvPDO { } } + /** @return void */ public function __destruct() { - $this->connection = null; + unset($this->connection); } } \ No newline at end of file diff --git a/system/engine/autoload.php b/system/engine/autoload.php index b9c5115..b3686ec 100644 --- a/system/engine/autoload.php +++ b/system/engine/autoload.php @@ -38,6 +38,20 @@ spl_autoload_register(function ($class) { $classNative = ($namespace[0] == "Phacil") ? str_replace('phacil\\framework\\', '', strtolower( $class)) : $class; + if($namespace[0] == 'Phacil' && isset($namespace[2]) && $namespace[2] == 'Databases'){ + if(!defined('DIR_DATABASE')) + define('DIR_DATABASE', DIR_SYSTEM."database/"); + + try { + require_once(DIR_DATABASE . str_replace("\\", "/", $classNative).'.php'); + return; + } catch (\Exception $th) { + $log = new \Phacil\Framework\Log(DIR_LOGS."exception.log"); + $log->write($class.' not loaded!'); + throw new \Phacil\Framework\Exception("Class '$class' not loaded."); + } + } + $allowed = [ 'log', 'front', diff --git a/system/engine/exception.php b/system/engine/exception.php new file mode 100644 index 0000000..c4f2fb9 --- /dev/null +++ b/system/engine/exception.php @@ -0,0 +1,22 @@ +write($this->getMessage()); + } + +} diff --git a/system/engine/loader.php b/system/engine/loader.php index 63457e8..45f5f12 100644 --- a/system/engine/loader.php +++ b/system/engine/loader.php @@ -157,7 +157,7 @@ final class Loader implements \Phacil\Framework\Interfaces\Loader { if (file_exists($file)) { //include_once($file); - $this->db->createSubBase($database_name, new DB($driver, $hostname, $username, $password, $database)); + $this->db->createSubBase($database_name, new Database($driver, $hostname, $username, $password, $database)); return $database_name; } else { diff --git a/system/system.php b/system/system.php index c88c71d..9af0065 100644 --- a/system/system.php +++ b/system/system.php @@ -246,7 +246,8 @@ $engine->registry->set('load', $loader); $config = new Config(); $engine->registry->set('config', $config); -$engine->registry->set('db', new DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE)); +if(defined('DB_DRIVER')) + $engine->registry->set('db', new Database(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE)); // Settings if(!empty($configs)){ @@ -257,7 +258,7 @@ if(!empty($configs)){ if(USE_DB_CONFIG === true) { - $query = (defined('CUSTOM_DB_CONFIG')) ? $db->query(CUSTOM_DB_CONFIG) : $db->query("SELECT * FROM settings ORDER BY setting_id ASC"); + $query = (defined('CUSTOM_DB_CONFIG')) ? $engine->db->query(CUSTOM_DB_CONFIG) : $engine->db->query("SELECT * FROM settings ORDER BY setting_id ASC"); foreach ($query->rows as $setting) { if (!$setting['serialized']) {