diff --git a/src/Libs/Database.php b/src/Libs/Database.php index 215bbb2..865381a 100644 --- a/src/Libs/Database.php +++ b/src/Libs/Database.php @@ -2,7 +2,7 @@ /* * DuckBrain - Microframework * - * Clase diseñada para crear y devolver una única instancia mysqli. + * Clase diseñada para crear y devolver una única instancia mysqli (database). * Depende de manera forzada de que estén definidas las constantes: * dbhost, dbname, dbpass y dbuser * @@ -12,15 +12,21 @@ */ namespace Libs; +use mysqli; -class Database { +class Database extends \mysqli { static private $db; private function __construct() {} - static public function getConnection() { + /** + * Devuelve una instancia homogénea (singlenton) a la base de datos. + * + * @return mysqli + */ + static public function getConnection() : mysqli { if (!isset(self::$db)) { - self::$db = new \mysqli(dbhost, dbuser, dbpass, dbname); + self::$db = new mysqli(dbhost, dbuser, dbpass, dbname); if (self::$db->connect_errno) { echo ''; throw new \Exception('No se ha podido conectar a la base de datos.'); diff --git a/src/Libs/ModelMySQL.php b/src/Libs/ModelMySQL.php index e9ae67f..93c1422 100644 --- a/src/Libs/ModelMySQL.php +++ b/src/Libs/ModelMySQL.php @@ -13,6 +13,7 @@ namespace Libs; use Libs\Database; +use mysqli; class ModelMySQL { @@ -44,7 +45,7 @@ class ModelMySQL { * * @return mysqli */ - protected static function db() { + protected static function db() : mysqli { if (is_null(static::$db)) static::$db = Database::getConnection(); @@ -63,7 +64,7 @@ class ModelMySQL { * @return mysqli_result * Contiene el resultado de la llamada SQL. */ - protected static function query($query) { + protected static function query($query) : mysqli_result { $db = static::db(); $result = $db->query($query); @@ -103,13 +104,13 @@ class ModelMySQL { * Construye la sentencia SQL a partir static::$querySelect y una vez * construída, llama a resetQuery. * - * @param boolean $resetQuery + * @param bool $resetQuery * Indica si el query debe reiniciarse o no (por defecto es true). * * @return string * Contiene la sentencia SQL. */ - protected static function buildQuery($resetQuery = true) { + protected static function buildQuery(bool $resetQuery = true) : string { if (static::$querySelect['sql_calc_found_rows']) $sql = 'SELECT SQL_CALC_FOUND_ROWS '.join(', ', static::$querySelect['select']); else @@ -169,7 +170,7 @@ class ModelMySQL { * @return ModelMySQL * Retorna un objeto de la clase actual. */ - protected static function getInstance($elem = []) { + protected static function getInstance(array $elem = []) : ModelMySQL { $class = get_called_class(); $instance = new $class; @@ -181,10 +182,15 @@ class ModelMySQL { } /** + * Devuelve los atributos a guardar de la case actual. + * Los atributos serán aquellos que seran public y + * no esten excluidos en static::$ignoresave y aquellos + * que sean private o protected pero estén en static::$forceSave. + * * @return array * Contiene los atributos indexados del objeto actual. */ - protected function getVars() { + protected function getVars() : array { $reflection = new \ReflectionClass($this); $properties = $reflection->getProperties(\ReflectionProperty::IS_PUBLIC); $result = []; @@ -206,10 +212,12 @@ class ModelMySQL { } /** + * Devuelve el nombre de la clase actual aunque sea una clase extendida. + * * @return string * Devuelve el nombre de la clase actual. */ - public static function className() { + public static function className() : string { return strtolower(substr(strrchr(get_called_class(), '\\'), 1)); } @@ -220,7 +228,7 @@ class ModelMySQL { * * @return string */ - protected static function table() { + protected static function table() : string { if (isset(static::$table)) return static::$table; return static::className().static::$tableSufix; @@ -310,8 +318,10 @@ class ModelMySQL { * * @param array $columns * Columnas que se selecionarán en la consulta SQL. + * + * @return ModelMySQL */ - public static function select($columns) { + public static function select(array $columns) : ModelMySQL { $db = static::db(); $select = []; foreach($columns as $column) { @@ -328,8 +338,10 @@ class ModelMySQL { * * @param array $tables * Tablas que se selecionarán en la consulta SQL. + * + * @return ModelMySQL */ - public static function from($tables) { + public static function from(array $tables) : ModelMySQL { $db = static::db(); $from = []; foreach($tables as $table) { @@ -353,11 +365,12 @@ class ModelMySQL { * @param string $value * (opcional) El valor el valor a comparar en la columna. * - * @param boolean $no_quote + * @param bool $no_quote * (opcional) Se usa cuando $value es una columna o un valor que no requiere comillas. * + * @return ModelMySQL */ - public static function where($column, $operator, $value=null, $no_quote = false) { + public static function where(string $column, string $operator, string $value=null, bool $no_quote = false) : ModelMySQL { if (is_null($value)) { $value = $operator; $operator = '='; @@ -382,10 +395,12 @@ class ModelMySQL { * @param array $arr * Arreglo con todos los valores a comparar con la columna. * - * @param boolean $in - * (opcional) Define si se usará IN o NOT IN en la sentencia SQL. + * @param bool $in + * Define si se tienen que comprobar negativa o positivamente. + * + * @return ModelMySQL */ - public static function where_in($column, $arr, $in = true) { + public static function where_in(string $column, array $arr, bool $in = true) : ModelMySQL { foreach($arr as $index => $value) { $arr[$index] = static::db()->real_escape_string($value); } @@ -412,8 +427,10 @@ class ModelMySQL { * * @param string $columnB * (opcional) Columna a comparar para hacer el join. + * + * @return ModelMySQL */ - public static function leftJoin($table, $columnA, $operator, $columnB = null) { + public static function leftJoin(string $table, string $columnA, string $operator, string $columnB = null) : ModelMySQL { if (is_null($columnB)) { $columnB = $operator; $operator = '='; @@ -443,8 +460,9 @@ class ModelMySQL { * @param string $columnB * (opcional) Columna a comparar para hacer el join. * + * @return ModelMySQL */ - public static function rightJoin($table, $columnA, $operator, $columnB = null) { + public static function rightJoin(string $table, string $columnA, string $operator, string $columnB = null) : ModelMySQL { if (is_null($columnB)) { $columnB = $operator; $operator = '='; @@ -472,8 +490,10 @@ class ModelMySQL { * * @param string $columnB * (opcional) Columna a comparar para hacer el join. + * + * @return ModelMySQL */ - public static function innerJoin($table, $columnA, $operator, $columnB = null) { + public static function innerJoin(string $table, string $columnA, string $operator, string $columnB = null) : ModelMySQL { if (is_null($columnB)) { $columnB = $operator; $operator = '='; @@ -499,11 +519,12 @@ class ModelMySQL { * @param string $value * (opcional) El valor el valor a comparar en la columna. * - * @param $no_quote + * @param bool $no_quote * (opcional) Se usa cuando $value es una columna o un valor que no requiere comillas. * + * @return ModelMySQL */ - public static function and($column, $operator, $value=null, $no_quote = false) { + public static function and(string $column, string $operator, string $value=null, bool $no_quote = false) : ModelMySQL { if (is_null($value)) { $value = $operator; $operator = '='; @@ -531,10 +552,12 @@ class ModelMySQL { * @param string $value * (opcional) El valor el valor a comparar en la columna. * - * @param $no_quote + * @param bool $no_quote * (opcional) Se usa cuando $value es una columna o un valor que no requiere comillas. + * + * @return ModelMySQL */ - public static function or($column, $operator, $value=null, $no_quote = false) { + public static function or(string $column, string $operator, string $value=null, bool $no_quote = false) : ModelMySQL { if (is_null($value)) { $value = $operator; $operator = '='; @@ -555,16 +578,23 @@ class ModelMySQL { * * @param array $arr * Columnas por las que se agrupará. + * + * @return ModelMySQL */ - public static function groupBy($arr) { + public static function groupBy(array $arr) : ModelMySQL { static::$querySelect['groupBy'] = join(', ', $arr); return new static(); } - public static function limit($initial, $final = 0) { - $initial = (int)$initial; - $final = (int)$final; - + /** + * Define LIMIT en la sentencia SQL. + * + * @param int $initial + * @param int $final + * + * @return ModelMySQL + */ + public static function limit(int $initial, int $final = 0) : ModelMySQL { if ($final==0) static::$querySelect['limit'] = $initial; else @@ -582,8 +612,10 @@ class ModelMySQL { * @param string $order * (opcional) Define si el orden será de manera ascendente (ASC), * descendente (DESC) o aleatorio (RAND). + * + * @return ModelMySQL */ - public static function orderBy($value, $order = 'ASC') { + public static function orderBy(string $value, string $order = 'ASC') : ModelMySQL { if ($value == "RAND") { static::$querySelect['orderBy'] = 'RAND()'; return new static(); @@ -602,15 +634,15 @@ class ModelMySQL { /** * Retorna la cantidad de filas que hay en un query. * - * @param boolean $resetQuery + * @param bool $resetQuery * (opcional) Indica si el query debe reiniciarse o no (por defecto es true). * - * @param boolean $useLimit + * @param bool $useLimit * (opcional) Permite usar limit para estabecer un máximo inical y final para contar. Requiere que se haya definido antes el límite (por defecto en false). * * @return int */ - public static function count($resetQuery = true, $useLimit = false) { + public static function count(bool $resetQuery = true, bool $useLimit = false) : int { if (!$resetQuery) $backup = [ 'select' => static::$querySelect['select'], @@ -653,7 +685,7 @@ class ModelMySQL { * * @return int */ - public static function found_row() { + public static function found_row() : int { $result = static::query('SELECT FOUND_ROWS() AS quantity')->fetch_assoc(); return $result['quantity']; } @@ -663,7 +695,7 @@ class ModelMySQL { * * @return ModelMySQL */ - public static function sql_calc_found_rows() { + public static function sql_calc_found_rows() : ModelMySQL { static::$querySelect['sql_calc_found_rows'] = true; return new static(); } @@ -674,7 +706,7 @@ class ModelMySQL { * @param mixed $id * @return ModelMySQL */ - public static function getById($id) { + public static function getById($id) : ModelMySQL { return static::where(static::$primaryKey, $id)->getFirst(); } @@ -686,8 +718,10 @@ class ModelMySQL { * * @param array $in * (opcional) Columnas en las que se va a buscar (null para buscar en todas). + * + * @return ModelMySQL */ - public static function search($search, $in = null) { + public static function search(string $search, array $in = null) : ModelMySQL { if ($in == null) { $className = get_called_class(); $in = array_keys((new $className())->getVars()); @@ -714,12 +748,13 @@ class ModelMySQL { /** * Obtener los resultados de la consulta SQL. * - * @param boolean $resetQuery + * @param bool $resetQuery * (opcional) Indica si el query debe reiniciarse o no (por defecto es true). * - * @return ModelMySQL[] + * @return array + * Contiene un arreglo de instancias de la clase actual. */ - public static function get($resetQuery = true) { // Devuelve array vacío si no encuentra nada. + public static function get(bool $resetQuery = true) : array { // Devuelve array vacío si no encuentra nada. $sql = static::buildQuery($resetQuery); $result = static::query($sql); @@ -735,13 +770,13 @@ class ModelMySQL { /** * El primer elemento de la consulta SQL. * - * @param boolean $resetQuery + * @param bool $resetQuery * (opcional) Indica si el query debe reiniciarse o no (por defecto es true). * * @return mixed * Puede retornar un objeto ModelMySQL o null. */ - public static function getFirst($resetQuery = true) { // Devuelve null si no encuentra nada. + public static function getFirst(bool $resetQuery = true) { // Devuelve null si no encuentra nada. static::limit(1); $instances = static::get($resetQuery); return empty($instances) ? null : $instances[0]; @@ -750,9 +785,10 @@ class ModelMySQL { /** * Obtener todos los elementos del la tabla de la instancia actual. * - * @return ModelMySQL[] + * @return array + * Contiene un arreglo de instancias de la clase actual. */ - public static function all() { + public static function all() : array { $sql = 'SELECT * FROM '.static::table(); $result = static::query($sql); @@ -770,9 +806,12 @@ class ModelMySQL { * Permite definir como nulo el valor de un atributo. * Sólo funciona para actualizar un elemento de la BD, no para insertar. * + * @trows \Exception + * Devolverá un error en caso de usarse en un insert. + * * @param array $atts */ - public function setNull($atts) { + public function setNull(array $atts) { if (!isset($this->id)) throw new \Exception( "\nEl método setNull sólo funciona para actualizar, no al insertar." diff --git a/src/Libs/Router.php b/src/Libs/Router.php index fac0753..8b50b3d 100644 --- a/src/Libs/Router.php +++ b/src/Libs/Router.php @@ -34,7 +34,7 @@ class Router { * @param string $path * Ruta con pseudovariables. * - * @param callable $callback + * @param mixed $callback * Callback que será llamado cuando la ruta configurada en $path coincida. * * @return array @@ -42,7 +42,7 @@ class Router { * path - Contiene la ruta con las pseudovariables reeplazadas por expresiones regulares. * callback - Contiene el callback en formato Namespace\Clase::Método. */ - private static function parse($path, $callback) { + private static function parse(string $path, $callback) : array { preg_match_all('/{(\w+)}/s', $path, $matches, PREG_PATTERN_ORDER); $paramNames = $matches[1]; @@ -69,8 +69,10 @@ class Router { * * Ej: Si la url del sistema está en "https://ejemplo.com/duckbrain" * entonces la ruta base sería "/duckbrain" + * + * @return string */ - public static function basePath() { + public static function basePath() : string { if (defined('SITE_URL')) return parse_url(SITE_URL, PHP_URL_PATH); return str_replace($_SERVER['DOCUMENT_ROOT'], '/', ROOT_DIR); @@ -86,7 +88,7 @@ class Router { * llamamos a Router::redirect('/docs'), entonces seremos * redirigidos a "https://ejemplo.com/duckbrain/docs". */ - public static function redirect($path) { + public static function redirect(string $path) { header('Location: '.static::basePath().substr($path,1)); } @@ -94,14 +96,14 @@ class Router { * Añade un middleware a la última ruta usada. * Solo se puede usar un middleware a la vez. * - * @param string $callback + * @param mixed $callback * - * @return static + * @return Router * Devuelve un enlace estático. */ - public static function middleware($callback){ + public static function middleware($callback) : Router{ if (!isset(static::$last)) - return; + return new static(); $method = static::$last[0]; $index = static::$last[1]; @@ -116,15 +118,15 @@ class Router { } /* - * @return object + * @return Neuron * Devuelve un objeto que contiene los atributos: * post - Donde se encuentran los valores enviados por $_POST. * get - Donde se encuentran los valores enviados por $_GET. * json - Donde se encuentran los valores JSON enviados en el body. * */ - private static function getReq() { - $req = (object) ''; + private static function getReq() : Neuron { + $req = new Neuron(); $req->get = new Neuron($_GET); $req->post = new Neuron($_POST); $req->json = new Neuron(static::get_json()); @@ -137,7 +139,7 @@ class Router { * @return object * Devuelve un objeto con los datos recibidos en JSON. */ - private static function get_json() { + private static function get_json() : object { $contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : ''; if ($contentType === "application/json") { return json_decode(trim(file_get_contents("php://input"))); @@ -151,13 +153,13 @@ class Router { * @param string $path * Ruta con pseudovariables. * - * @param callable $callback + * @param mixed $callback * Callback que será llamado cuando la ruta configurada en $path coincida. * - * @return static + * @return Router * Devuelve un enlace estático. */ - public static function get($path, $callback) { + public static function get(string $path, $callback) { static::$get[] = static::parse($path, $callback); static::$last = ['get', count(static::$get)-1]; return new static(); @@ -169,13 +171,13 @@ class Router { * @param string $path * Ruta con pseudovariables. * - * @param callable $callback + * @param mixed $callback * Callback que será llamado cuando la ruta configurada en $path coincida. * - * @return static + * @return Router * Devuelve un enlace estático. */ - public static function post($path, $callback) { + public static function post(string $path, $callback) : Router { static::$post[] = static::parse($path, $callback); static::$last = ['post', count(static::$post)-1]; return new static(); @@ -187,14 +189,14 @@ class Router { * @param string $path * Ruta con pseudovariables. * - * @param callable $callback + * @param mixed $callback * Callback que será llamado cuando la ruta configurada en $path coincida. * - * @return static + * @return Router * Devuelve un enlace estático */ - public static function put($path, $callback) { + public static function put(string $path, $callback) : Router { static::$put[] = static::parse($path, $callback); static::$last = ['put', count(static::$put)-1]; return new static(); @@ -212,7 +214,7 @@ class Router { * @return static * Devuelve un enlace estático */ - public static function delete($path, $callback) { + public static function delete(string $path, $callback) : Router { static::$delete[] = static::parse($path, $callback); static::$last = ['delete', count(static::$delete)-1]; return new static(); @@ -220,8 +222,10 @@ class Router { /* * Devuelve la ruta actual. + * + * @return string */ - public static function currentPath() { + public static function currentPath() : string { return preg_replace('/'.preg_quote(static::basePath(), '/').'/', '/', strtok($_SERVER['REQUEST_URI'], '?'), 1); } diff --git a/src/Libs/View.php b/src/Libs/View.php index 9967242..35d2c8a 100644 --- a/src/Libs/View.php +++ b/src/Libs/View.php @@ -25,7 +25,7 @@ class View { * @param string $viewPath * (opcional) Ruta donde se encuentra la vista. En caso de que la vista no se encuentre en esa ruta, se usará la ruta por defecto "src/Views/". */ - public static function render($viewName, $params = [], $viewPath = null) { + public static function render(string $viewName, array $params = [], string $viewPath = null) { $view = new Neuron($params); unset($params);