diff --git a/config.php b/config.php index e97f4d7..10b93cd 100644 --- a/config.php +++ b/config.php @@ -1,4 +1,5 @@ diff --git a/src/Libs/Middleware.php b/src/Libs/Middleware.php index b63df10..c74cd59 100644 --- a/src/Libs/Middleware.php +++ b/src/Libs/Middleware.php @@ -1,4 +1,7 @@ ['*'], 'where' => '', 'from' => '', @@ -39,7 +39,7 @@ class Model { 'innerJoin' => '', 'orderBy' => '', 'groupBy' => '', - 'limit' => '' + 'limit' => '', ]; /** @@ -49,12 +49,12 @@ class Model { */ protected static function db(): PDO { - if (DB_TYPE == 'sqlite') + if (DB_TYPE == 'sqlite') { return Database::getInstance( - type: DB_TYPE, - name: DB_NAME + type: DB_TYPE, + name: DB_NAME ); - else + } else { return Database::getInstance( DB_TYPE, DB_HOST, @@ -62,6 +62,7 @@ class Model { DB_USER, DB_PASS ); + } } /** @@ -83,10 +84,11 @@ class Model { */ public static function rollBack(): bool { - if ( static::db()->inTransaction()) + if (static::db()->inTransaction()) { return static::db()->rollBack(); - else + } else { return true; + } } /** @@ -97,28 +99,29 @@ class Model { */ public static function commit(): bool { - if (static::db()->inTransaction()) + if (static::db()->inTransaction()) { return static::db()->commit(); - else + } else { return true; + } } /** * Ejecuta una sentencia SQL en la base de datos. * * @param string $query - * Contiene la sentencia SQL que se desea ejecutar. + * Contiene la sentencia SQL que se desea ejecutar. * * @throws Exception - * En caso de que la sentencia SQL falle, devolverá un error en - * pantalla y hará rolllback en caso de estar dentro de una - * transacción (ver método beginTransacction). + * En caso de que la sentencia SQL falle, devolverá un error en + * pantalla y hará rolllback en caso de estar dentro de una + * transacción (ver método beginTransacction). * * @param bool $resetQuery - * Indica si el query debe reiniciarse o no (por defecto es true). + * Indica si el query debe reiniciarse o no (por defecto es true). * * @return array - * Contiene el resultado de la llamada SQL . + * Contiene el resultado de la llamada SQL . */ protected static function query(string $query, bool $resetQuery = true): array { @@ -128,8 +131,9 @@ class Model { $prepared = $db->prepare($query); $prepared->execute(static::$queryVars); } catch (PDOException $e) { - if ($db->inTransaction()) + if ($db->inTransaction()) { $db->rollBack(); + } $vars = json_encode(static::$queryVars); @@ -143,8 +147,9 @@ class Model { $result = $prepared->fetchAll(); - if ($resetQuery) + if ($resetQuery) { static::resetQuery(); + } return $result; } @@ -164,7 +169,7 @@ class Model { 'innerJoin' => '', 'orderBy' => '', 'groupBy' => '', - 'limit' => '' + 'limit' => '', ]; static::$queryVars = []; } @@ -174,37 +179,45 @@ class Model { * construída, llama a resetQuery. * * @return string - * Contiene la sentencia SQL. + * Contiene la sentencia SQL. */ protected static function buildQuery(): string { - $sql = 'SELECT '.join(', ', static::$querySelect['select']); + $sql = 'SELECT ' . join(', ', static::$querySelect['select']); - if (static::$querySelect['from'] != '') - $sql .= ' FROM '.static::$querySelect['from']; - else - $sql .= ' FROM '.static::table(); + if (static::$querySelect['from'] != '') { + $sql .= ' FROM ' . static::$querySelect['from']; + } else { + $sql .= ' FROM ' . static::table(); + } - if(static::$querySelect['innerJoin'] != '') + if (static::$querySelect['innerJoin'] != '') { $sql .= static::$querySelect['innerJoin']; + } - if (static::$querySelect['leftJoin'] != '') + if (static::$querySelect['leftJoin'] != '') { $sql .= static::$querySelect['leftJoin']; + } - if(static::$querySelect['rightJoin'] != '') + if (static::$querySelect['rightJoin'] != '') { $sql .= static::$querySelect['rightJoin']; + } - if (static::$querySelect['where'] != '') - $sql .= ' WHERE '.static::$querySelect['where']; + if (static::$querySelect['where'] != '') { + $sql .= ' WHERE ' . static::$querySelect['where']; + } - if (static::$querySelect['groupBy'] != '') - $sql .= ' GROUP BY '.static::$querySelect['groupBy']; + if (static::$querySelect['groupBy'] != '') { + $sql .= ' GROUP BY ' . static::$querySelect['groupBy']; + } - if (static::$querySelect['orderBy'] != '') - $sql .= ' ORDER BY '.static::$querySelect['orderBy']; + if (static::$querySelect['orderBy'] != '') { + $sql .= ' ORDER BY ' . static::$querySelect['orderBy']; + } - if (static::$querySelect['limit'] != '') - $sql .= ' LIMIT '.static::$querySelect['limit']; + if (static::$querySelect['limit'] != '') { + $sql .= ' LIMIT ' . static::$querySelect['limit']; + } return $sql; } @@ -215,14 +228,14 @@ class Model { * parámetro de sustitución y devuelve este último. * * @param string $value - * Valor a vincular. + * Valor a vincular. * * @return string - * Parámetro de sustitución. + * Parámetro de sustitución. */ private static function bindValue(string $value): string { - $index = ':v_'.count(static::$queryVars); + $index = ':v_' . count(static::$queryVars); static::$queryVars[$index] = $value; return $index; } @@ -231,26 +244,27 @@ class Model { * Crea una instancia del objeto actual a partir de un arreglo. * * @param mixed $elem - * Puede recibir un arreglo o un objeto que contiene los valores - * que tendrán sus atributos. + * Puede recibir un arreglo o un objeto que contiene los valores + * que tendrán sus atributos. * * @return static - * Retorna un objeto de la clase actual. + * Retorna un objeto de la clase actual. */ protected static function getInstance(array $elem = []): static { $class = get_called_class(); - $instance = new $class; + $instance = new $class(); $reflection = new ReflectionClass($instance); $properties = $reflection->getProperties(); $propertyNames = array_column($properties, 'name'); foreach ($elem as $key => $value) { $index = array_search($key, $propertyNames); - if (is_numeric($index) && enum_exists($properties[$index]->getType()->getName())) + if (is_numeric($index) && enum_exists($properties[$index]->getType()->getName())) { $instance->$key = $properties[$index]->getType()->getName()::tryfrom($value); - else + } else { $instance->$key = $value; + } } return $instance; @@ -263,7 +277,7 @@ class Model { * que sean private o protected pero estén en static::$forceSave. * * @return array - * Contiene los atributos indexados del objeto actual. + * Contiene los atributos indexados del objeto actual. */ protected function getVars(): array { @@ -271,23 +285,28 @@ class Model { $properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC); $result = []; - foreach($properties as $property) + foreach ($properties as $property) { $result[$property->name] = isset($this->{$property->name}) ? $this->{$property->name} : null; + } - foreach (static::$ignoreSave as $del) + foreach (static::$ignoreSave as $del) { unset($result[$del]); + } - foreach (static::$forceSave as $value) + foreach (static::$forceSave as $value) { $result[$value] = isset($this->$value) - ? $this->$value: null; + ? $this->$value : null; + } foreach ($result as $i => $property) { - if (gettype($property) == 'boolean') + if (gettype($property) == 'boolean') { $result[$i] = $property ? '1' : '0'; + } - if ($property instanceof \UnitEnum) + if ($property instanceof \UnitEnum) { $result[$i] = $property->value; + } } return $result; @@ -297,12 +316,13 @@ class Model { * Devuelve el nombre de la clase actual aunque sea una clase extendida. * * @return string - * Devuelve el nombre de la clase actual. + * Devuelve el nombre de la clase actual. */ public static function className(): string { return substr( - strrchr(get_called_class(), '\\'), 1 + strrchr(get_called_class(), '\\'), + 1 ); } @@ -315,15 +335,17 @@ class Model { */ protected static function table(): string { - if (isset(static::$table)) + if (isset(static::$table)) { return static::$table; + } return strtolower( preg_replace( - '/(? $value) { if (isset($value)) { - if (in_array($key, $this->toNull)) - $set[]="$key=NULL"; - else { - $set[]="$key=:$key"; - static::$queryVars[':'.$key] = $value; + if (in_array($key, $this->toNull)) { + $set[] = "$key=NULL"; + } else { + $set[] = "$key=:$key"; + static::$queryVars[':' . $key] = $value; } } else { - if (in_array($key, $this->toNull)) - $set[]="$key=NULL"; + if (in_array($key, $this->toNull)) { + $set[] = "$key=NULL"; + } } } $table = static::table(); $pk = static::$primaryKey; $pkv = $this->$pk; - $sql = "UPDATE $table SET ".join(', ', $set)." WHERE $pk='$pkv'"; + $sql = "UPDATE $table SET " . join(', ', $set) . " WHERE $pk='$pkv'"; static::query($sql); } @@ -374,7 +397,7 @@ class Model { } $table = static::table(); - $sql = "INSERT INTO $table (".join(', ', $into).") VALUES (".join(', ', $values).")"; + $sql = "INSERT INTO $table (" . join(', ', $into) . ") VALUES (" . join(', ', $values) . ")"; static::query($sql); $pk = static::$primaryKey; @@ -389,17 +412,19 @@ class Model { public function save(): void { $pk = static::$primaryKey; - if (isset($this->$pk)) + if (isset($this->$pk)) { $this->update(); - else + } else { $this->add(); + } } /** * Elimina el objeto actual de la base de datos. * @return void */ - public function delete(): void { + public function delete(): void + { $table = static::table(); $pk = static::$primaryKey; $sql = "DELETE FROM $table WHERE $pk=:$pk"; @@ -412,7 +437,7 @@ class Model { * Define SELECT en la sentencia SQL. * * @param array $columns - * Columnas que se selecionarán en la consulta SQL. + * Columnas que se selecionarán en la consulta SQL. * * @return static */ @@ -427,7 +452,7 @@ class Model { * Define FROM en la sentencia SQL. * * @param array $tables - * Tablas que se selecionarán en la consulta SQL. + * Tablas que se selecionarán en la consulta SQL. * * @return static */ @@ -442,27 +467,26 @@ class Model { * Define el WHERE en la sentencia SQL. * * @param string $column - * La columna a comparar. + * La columna a comparar. * * @param string $operatorOrValue - * El operador o el valor a comparar como igual en caso de que $value no se defina. + * El operador o el valor a comparar como igual en caso de que $value no se defina. * * @param string|null $value - * (opcional) El valor a comparar en la columna. + * (opcional) El valor a comparar en la columna. * * @param bool $no_filter - * (opcional) Se usa cuando $value es una columna o un valor que no requiere filtros - * contra ataques SQLI (por defeco es false). + * (opcional) Se usa cuando $value es una columna o un valor que no requiere filtros + * contra ataques SQLI (por defeco es false). * * @return static */ public static function where( - string $column, - string $operatorOrValue, - ?string $value = null, - bool $no_filter = false - ): static - { + string $column, + string $operatorOrValue, + ?string $value = null, + bool $no_filter = false + ): static { return static::and( $column, $operatorOrValue, @@ -475,39 +499,40 @@ class Model { * Define AND en la sentencia SQL (se puede anidar). * * @param string $column - * La columna a comparar. + * La columna a comparar. * * @param string $operatorOrValue - * El operador o el valor a comparar como igual en caso de que $value no se defina. + * El operador o el valor a comparar como igual en caso de que $value no se defina. * * @param string|null $value - * (opcional) El valor el valor a comparar en la columna. + * (opcional) El valor el valor a comparar en la columna. * * @param bool $no_filter - * (opcional) Se usa cuando $value es una columna o un valor que no requiere filtros - * contra ataques SQLI (por defecto es false). + * (opcional) Se usa cuando $value es una columna o un valor que no requiere filtros + * contra ataques SQLI (por defecto es false). * * @return static */ public static function and( - string $column, - string $operatorOrValue, - ?string $value = null, - bool $no_filter = false - ): static - { + string $column, + string $operatorOrValue, + ?string $value = null, + bool $no_filter = false + ): static { if (is_null($value)) { $value = $operatorOrValue; $operatorOrValue = '='; } - if (!$no_filter) + if (!$no_filter) { $value = static::bindValue($value); + } - if (static::$querySelect['where'] == '') + if (static::$querySelect['where'] == '') { static::$querySelect['where'] = "$column $operatorOrValue $value"; - else + } else { static::$querySelect['where'] .= " AND $column $operatorOrValue $value"; + } return new static(); } @@ -516,39 +541,40 @@ class Model { * Define OR en la sentencia SQL (se puede anidar). * * @param string $column - * La columna a comparar. + * La columna a comparar. * * @param string $operatorOrValue - * El operador o el valor a comparar como igual en caso de que $value no se defina. + * El operador o el valor a comparar como igual en caso de que $value no se defina. * * @param string|null $value - * (opcional) El valor el valor a comparar en la columna. + * (opcional) El valor el valor a comparar en la columna. * * @param bool $no_filter - * (opcional) Se usa cuando $value es una columna o un valor que no requiere filtros - * contra ataques SQLI (por defecto es false). + * (opcional) Se usa cuando $value es una columna o un valor que no requiere filtros + * contra ataques SQLI (por defecto es false). * * @return static */ public static function or( - string $column, - string $operatorOrValue, - ?string $value = null, - bool $no_filter = false - ): static - { + string $column, + string $operatorOrValue, + ?string $value = null, + bool $no_filter = false + ): static { if (is_null($value)) { $value = $operatorOrValue; $operatorOrValue = '='; } - if (!$no_filter) + if (!$no_filter) { $value = static::bindValue($value); + } - if (static::$querySelect['where'] == '') + if (static::$querySelect['where'] == '') { static::$querySelect['where'] = "$column $operatorOrValue $value"; - else + } else { static::$querySelect['where'] .= " OR $column $operatorOrValue $value"; + } return new static(); } @@ -557,36 +583,37 @@ class Model { * Define WHERE usando IN en la sentencia SQL. * * @param string $column - * La columna a comparar. + * La columna a comparar. * * @param array $arr - * Arreglo con todos los valores a comparar con la columna. + * Arreglo con todos los valores a comparar con la columna. * * @param bool $in - * Define si se tienen que comprobar negativa o positivamente. + * Define si se tienen que comprobar negativa o positivamente. * * @return static */ - public static function where_in( + public static function whereIn( string $column, array $arr, bool $in = true - ): static - { + ): static { $arrIn = []; - foreach($arr as $value) { + foreach ($arr as $value) { $arrIn[] = static::bindValue($value); } - if ($in) - $where_in = "$column IN (".join(', ', $arrIn).")"; - else - $where_in = "$column NOT IN (".join(', ', $arrIn).")"; + if ($in) { + $where_in = "$column IN (" . join(', ', $arrIn) . ")"; + } else { + $where_in = "$column NOT IN (" . join(', ', $arrIn) . ")"; + } - if (static::$querySelect['where'] == '') + if (static::$querySelect['where'] == '') { static::$querySelect['where'] = $where_in; - else + } else { static::$querySelect['where'] .= " AND $where_in"; + } return new static(); } @@ -595,26 +622,26 @@ class Model { * Define LEFT JOIN en la sentencia SQL. * * @param string $table - * Tabla que se va a juntar a la del objeto actual. + * Tabla que se va a juntar a la del objeto actual. * * @param string $columnA - * Columna a comparar para hacer el join. + * Columna a comparar para hacer el join. * * @param string $operatorOrColumnB - * Operador o columna a comparar como igual para hacer el join en caso de que $columnB no se defina. + * Operador o columna a comparar como igual para hacer + * el join en caso de que $columnB no se defina. * * @param string|null $columnB - * (opcional) Columna a comparar para hacer el join. + * (opcional) Columna a comparar para hacer el join. * * @return static */ public static function leftJoin( - string $table, - string $columnA, - string $operatorOrColumnB, + string $table, + string $columnA, + string $operatorOrColumnB, ?string $columnB = null - ): static - { + ): static { if (is_null($columnB)) { $columnB = $operatorOrColumnB; $operatorOrColumnB = '='; @@ -629,26 +656,26 @@ class Model { * Define RIGHT JOIN en la sentencia SQL. * * @param string $table - * Tabla que se va a juntar a la del objeto actual. + * Tabla que se va a juntar a la del objeto actual. * * @param string $columnA - * Columna a comparar para hacer el join. + * Columna a comparar para hacer el join. * * @param string $operatorOrColumnB - * Operador o columna a comparar como igual para hacer el join en caso de que $columnB no se defina. + * Operador o columna a comparar como igual para hacer + * el join en caso de que $columnB no se defina. * * @param string|null $columnB - * (opcional) Columna a comparar para hacer el join. + * (opcional) Columna a comparar para hacer el join. * * @return static */ public static function rightJoin( - string $table, - string $columnA, - string $operatorOrColumnB, + string $table, + string $columnA, + string $operatorOrColumnB, ?string $columnB = null - ): static - { + ): static { if (is_null($columnB)) { $columnB = $operatorOrColumnB; $operatorOrColumnB = '='; @@ -663,26 +690,26 @@ class Model { * Define INNER JOIN en la sentencia SQL. * * @param string $table - * Tabla que se va a juntar a la del objeto actual. + * Tabla que se va a juntar a la del objeto actual. * * @param string $columnA - * Columna a comparar para hacer el join. + * Columna a comparar para hacer el join. * * @param string $operatorOrColumnB - * Operador o columna a comparar como igual para hacer el join en caso de que $columnB no se defina. + * Operador o columna a comparar como igual para hacer + * el join en caso de que $columnB no se defina. * * @param string|null $columnB - * (opcional) Columna a comparar para hacer el join. + * (opcional) Columna a comparar para hacer el join. * * @return static */ public static function innerJoin( - string $table, - string $columnA, - string $operatorOrColumnB, + string $table, + string $columnA, + string $operatorOrColumnB, ?string $columnB = null - ): static - { + ): static { if (is_null($columnB)) { $columnB = $operatorOrColumnB; $operatorOrColumnB = '='; @@ -697,7 +724,7 @@ class Model { * Define GROUP BY en la sentencia SQL. * * @param array $arr - * Columnas por las que se agrupará. + * Columnas por las que se agrupará. * * @return static */ @@ -711,19 +738,20 @@ class Model { * Define LIMIT en la sentencia SQL. * * @param int $offsetOrQuantity - * Define el las filas a ignorar o la cantidad a tomar en - * caso de que $quantity no esté definido. + * Define el las filas a ignorar o la cantidad a tomar en + * caso de que $quantity no esté definido. * @param int $quantity - * Define la cantidad máxima de filas a tomar. + * Define la cantidad máxima de filas a tomar. * * @return static */ public static function limit(int $offsetOrQuantity, ?int $quantity = null): static { - if (is_null($quantity)) + if (is_null($quantity)) { static::$querySelect['limit'] = $offsetOrQuantity; - else - static::$querySelect['limit'] = $offsetOrQuantity.', '.$quantity; + } else { + static::$querySelect['limit'] = $offsetOrQuantity . ', ' . $quantity; + } return new static(); } @@ -732,11 +760,11 @@ class Model { * Define ORDER BY en la sentencia SQL. * * @param string $value - * Columna por la que se ordenará. + * Columna por la que se ordenará. * * @param string $order - * (opcional) Define si el orden será de manera ascendente (ASC), - * descendente (DESC) o aleatorio (RAND). + * (opcional) Define si el orden será de manera ascendente (ASC), + * descendente (DESC) o aleatorio (RAND). * * @return static */ @@ -747,10 +775,11 @@ class Model { return new static(); } - if (!(strtoupper($order) == 'ASC' || strtoupper($order) == 'DESC')) + if (!(strtoupper($order) == 'ASC' || strtoupper($order) == 'DESC')) { $order = 'ASC'; + } - static::$querySelect['orderBy'] = $value.' '.$order; + static::$querySelect['orderBy'] = $value . ' ' . $order; return new static(); } @@ -759,32 +788,35 @@ class Model { * Retorna la cantidad de filas que hay en un query. * * @param bool $resetQuery - * (opcional) Indica si el query debe reiniciarse o no (por defecto es true). + * (opcional) Indica si el query debe reiniciarse o no (por defecto es true). * * @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). + * (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(bool $resetQuery = true, bool $useLimit = false): int { - if (!$resetQuery) + if (!$resetQuery) { $backup = [ 'select' => static::$querySelect['select'], 'limit' => static::$querySelect['limit'], - 'orderBy' => static::$querySelect['orderBy'] + 'orderBy' => static::$querySelect['orderBy'], ]; + } if ($useLimit && static::$querySelect['limit'] != '') { static::$querySelect['select'] = ['1']; static::$querySelect['orderBy'] = ''; - $sql = 'SELECT COUNT(1) AS quantity FROM ('.static::buildQuery().') AS counted'; + $sql = 'SELECT COUNT(1) AS quantity FROM (' . static::buildQuery() . ') AS counted'; $queryResult = static::query($sql, $resetQuery); $result = $queryResult[0]['quantity']; } else { - static::$querySelect['select'] = ["COUNT(".static::table().".".static::$primaryKey.") as quantity"]; + static::$querySelect['select'] = [ + "COUNT(" . static::table() . "." . static::$primaryKey . ") as quantity", + ]; static::$querySelect['limit'] = '1'; static::$querySelect['orderBy'] = ''; @@ -819,10 +851,10 @@ class Model { * Realiza una búsqueda en la tabla de la instancia actual. * * @param string $search - * Contenido a buscar. + * Contenido a buscar. * * @param array|null $in - * (opcional) Columnas en las que se va a buscar (null para buscar en todas). + * (opcional) Columnas en las que se va a buscar (null para buscar en todas). * * @return static */ @@ -836,18 +868,22 @@ class Model { $search = static::bindValue($search); $where = []; - if (DB_TYPE == 'sqlite') - foreach($in as $row) + if (DB_TYPE == 'sqlite') { + foreach ($in as $row) { $where[] = "$row LIKE '%' || $search || '%'"; - else - foreach($in as $row) + } + } else { + foreach ($in as $row) { $where[] = "$row LIKE CONCAT('%', $search, '%')"; + } + } - if (static::$querySelect['where']=='') + if (static::$querySelect['where'] == '') { static::$querySelect['where'] = join(' OR ', $where); - else - static::$querySelect['where'] = static::$querySelect['where'] .' AND ('.join(' OR ', $where).')'; + } else { + static::$querySelect['where'] = static::$querySelect['where'] . ' AND (' . join(' OR ', $where) . ')'; + } return new static(); } @@ -856,10 +892,10 @@ class Model { * Obtener los resultados de la consulta SQL. * * @param bool $resetQuery - * (opcional) Indica si el query debe reiniciarse o no (por defecto es true). + * (opcional) Indica si el query debe reiniciarse o no (por defecto es true). * * @return array - * Arreglo con instancias del la clase actual resultantes del query. + * Arreglo con instancias del la clase actual resultantes del query. */ public static function get(bool $resetQuery = true): array { @@ -879,10 +915,10 @@ class Model { * El primer elemento de la consulta SQL. * * @param bool $resetQuery - * (opcional) Indica si el query debe reiniciarse o no (por defecto es true). + * (opcional) Indica si el query debe reiniciarse o no (por defecto es true). * * @return static|null - * Puede retornar una instancia de la clase actual o null. + * Puede retornar una instancia de la clase actual o null. */ public static function getFirst(bool $resetQuery = true): ?static { @@ -895,17 +931,18 @@ class Model { * Obtener todos los elementos del la tabla de la instancia actual. * * @return array - * Contiene un arreglo de instancias de la clase actual. + * Contiene un arreglo de instancias de la clase actual. */ public static function all(): array { - $sql = 'SELECT * FROM '.static::table(); + $sql = 'SELECT * FROM ' . static::table(); $result = static::query($sql); $instances = []; - foreach ($result as $row) + foreach ($result as $row) { $instances[] = static::getInstance($row); + } return $instances; } @@ -915,21 +952,23 @@ class Model { * Sólo funciona para actualizar un elemento de la BD, no para insertar. * * @param string|array $atts - * Atributo o arreglo de atributos que se definirán como nulos. + * Atributo o arreglo de atributos que se definirán como nulos. * * @return void */ public function setNull(string|array $atts): void { if (is_array($atts)) { - foreach ($atts as $att) - if (!in_array($att, $this->toNull)) + foreach ($atts as $att) { + if (!in_array($att, $this->toNull)) { $this->toNull[] = $att; + } + } return; } - if (!in_array($atts, $this->toNull)) + if (!in_array($atts, $this->toNull)) { $this->toNull[] = $atts; + } } } -?> diff --git a/src/Libs/Neuron.php b/src/Libs/Neuron.php index 3c78242..a45463e 100644 --- a/src/Libs/Neuron.php +++ b/src/Libs/Neuron.php @@ -1,27 +1,27 @@ $value) + foreach ($data as $key => $value) { $this->{$key} = $value; + } } /** * __get * - * @param string $index + * @param string $index * @return null */ public function __get(string $index): null @@ -50,5 +54,3 @@ class Neuron { return null; } } - -?> diff --git a/src/Libs/Request.php b/src/Libs/Request.php index b2b29c9..d220a98 100644 --- a/src/Libs/Request.php +++ b/src/Libs/Request.php @@ -1,4 +1,7 @@ body = file_get_contents("php://input"); $contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : ''; - if ($contentType === "application/json") + if ($contentType === "application/json") { $this->json = new Neuron( (object) json_decode(trim($this->body), false) ); - else { + } else { $this->json = new Neuron(); - if (in_array($_SERVER['REQUEST_METHOD'], ['PUT', 'PATCH', 'DELETE']) && - preg_match('/^[^;?\/:@&=+$,]{1,255}[=]/', $this->body, $matches)) { // Con la expresión regular verificamos que sea un http query string válido y evitamos errores de memoria en caso de que el body tenga algo más grande que eso. + if ( + in_array($_SERVER['REQUEST_METHOD'], ['PUT', 'PATCH', 'DELETE']) && + preg_match('/^[^;?\/:@&=+$,]{1,255}[=]/', $this->body, $matches) + ) { + // Con la expresión regular verificamos que sea un http + // query string válido y evitamos errores de memoria en caso + // de que el body tenga algo más grande que eso. parse_str($this->body, $input_vars); $this->{strtolower($_SERVER['REQUEST_METHOD'])} = new Neuron($input_vars); } @@ -64,8 +70,9 @@ class Request extends Neuron { */ public function handle(): mixed { - if ($this->validate()) + if ($this->validate()) { return Middleware::next($this); + } return null; } @@ -77,21 +84,23 @@ class Request extends Neuron { */ public function validate(): bool { - $actual = match($_SERVER['REQUEST_METHOD']) { + $actual = match ($_SERVER['REQUEST_METHOD']) { 'POST', 'PUT', 'PATCH', 'DELETE' => $this->{strtolower($_SERVER['REQUEST_METHOD'])}, default => $this->get }; - if (Validator::validateList(static::paramRules(), $this->params) && - Validator::validateList(static::getRules(), $this->get ) && - Validator::validateList(static::rules(), $actual)) + if ( + Validator::validateList(static::paramRules(), $this->params) && + Validator::validateList(static::getRules(), $this->get) && + Validator::validateList(static::rules(), $actual) + ) { return true; + } - if (isset(static::messages()[Validator::$lastFailed])) + if (isset(static::messages()[Validator::$lastFailed])) { $error = static::messages()[Validator::$lastFailed]; - else { - - $error = 'Error: validation failed of '.preg_replace('/\./', ' as ', Validator::$lastFailed, 1); + } else { + $error = 'Error: validation failed of ' . preg_replace('/\./', ' as ', Validator::$lastFailed, 1); } static::onInvalid($error); @@ -103,7 +112,8 @@ class Request extends Neuron { * * @return array */ - public function rules(): array { + public function rules(): array + { return []; } @@ -112,7 +122,8 @@ class Request extends Neuron { * * @return array */ - public function paramRules(): array { + public function paramRules(): array + { return []; } @@ -121,7 +132,8 @@ class Request extends Neuron { * * @return array */ - public function getRules(): array { + public function getRules(): array + { return []; } @@ -130,7 +142,8 @@ class Request extends Neuron { * * @return array */ - public function messages(): array { + public function messages(): array + { return []; } diff --git a/src/Libs/Router.php b/src/Libs/Router.php index d729cc4..5367372 100644 --- a/src/Libs/Router.php +++ b/src/Libs/Router.php @@ -1,4 +1,7 @@ Error 404 - Página no encontrada'; @@ -37,21 +38,23 @@ class Router { /** * __construct */ - private function __construct() {} + private function __construct() + { + } /** * Parsea para deectar las pseudovariables (ej: {variable}) * * @param string $path - * Ruta con pseudovariables. + * Ruta con pseudovariables. * * @param callable $callback - * Callback que será llamado cuando la ruta configurada en $path coincida. + * Callback que será llamado cuando la ruta configurada en $path coincida. * * @return array - * Arreglo con 2 índices: - * path - Contiene la ruta con las pseudovariables reeplazadas por expresiones regulares. - * callback - Contiene el callback en formato Namespace\Clase::Método. + * Arreglo con 2 índices: + * 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(string $path, callable $callback): array { @@ -62,12 +65,13 @@ class Router { $path = preg_replace( ['/\\\{\w+\\\}/s'], ['([^\/]+)'], - $path); + $path + ); return [ 'path' => $path, 'callback' => [$callback], - 'paramNames' => $paramNames + 'paramNames' => $paramNames, ]; } @@ -82,8 +86,9 @@ class Router { */ public static function basePath(): string { - if (defined('SITE_URL') && !empty(SITE_URL)) - return rtrim(parse_url(SITE_URL, PHP_URL_PATH), '/').'/'; + if (defined('SITE_URL') && !empty(SITE_URL)) { + return rtrim(parse_url(SITE_URL, PHP_URL_PATH), '/') . '/'; + } return str_replace($_SERVER['DOCUMENT_ROOT'], '/', ROOT_DIR); } @@ -91,7 +96,7 @@ class Router { * Redirije a una ruta relativa interna. * * @param string $path - * La ruta relativa a la ruta base. + * La ruta relativa a la ruta base. * * Ej: Si nuesto sistema está en "https://ejemplo.com/duckbrain" * llamamos a Router::redirect('/docs'), entonces seremos @@ -100,7 +105,7 @@ class Router { */ public static function redirect(string $path): void { - header('Location: '.static::basePath().ltrim($path, '/')); + header('Location: ' . static::basePath() . ltrim($path, '/')); exit; } @@ -109,25 +114,27 @@ class Router { * Solo se puede usar un middleware a la vez. * * @param callable $callback - * @param int $prioriry + * @param int $prioriry * * @return static - * Devuelve la instancia actual. + * Devuelve la instancia actual. */ public static function middleware(callable $callback, ?int $priority = null): static { - if (!isset(static::$last)) + if (!isset(static::$last)) { return new static(); + } $method = static::$last[0]; $index = static::$last[1]; - if (isset($priority) && $priority <= 0) + if (isset($priority) && $priority <= 0) { $priority = 1; + } - if (is_null($priority) || $priority >= count(static::$$method[$index]['callback'])) + if (is_null($priority) || $priority >= count(static::$$method[$index]['callback'])) { static::$$method[$index]['callback'][] = $callback; - else { + } else { static::$$method[$index]['callback'] = array_merge( array_slice(static::$$method[$index]['callback'], 0, $priority), [$callback], @@ -147,8 +154,9 @@ class Router { */ public static function reconfigure(callable $callback): static { - if (empty(static::$last)) + if (empty(static::$last)) { return new static(); + } $method = static::$last[0]; $index = static::$last[1]; @@ -165,10 +173,10 @@ class Router { * solo configura la ruta como la última configurada * siempre y cuando la misma haya sido configurada previamente. * - * @param string $method - * Método http. - * @param string $path - * Ruta con pseudovariables. + * @param string $method + * Método http. + * @param string $path + * Ruta con pseudovariables. * @param callable|null $callback * * @return @@ -181,32 +189,34 @@ class Router { $path = preg_replace( ['/\\\{\w+\\\}/s'], ['([^\/]+)'], - $path); + $path + ); - foreach(static::$$method as $index => $router) + foreach (static::$$method as $index => $router) { if ($router['path'] == $path) { static::$last = [$method, $index]; break; } + } return new static(); } static::$$method[] = static::parse($path, $callback); - static::$last = [$method, count(static::$$method)-1]; + static::$last = [$method, count(static::$$method) - 1]; return new static(); } /** * Define los routers para el método GET. * - * @param string $path - * Ruta con pseudovariables. + * @param string $path + * Ruta con pseudovariables. * @param callable|null $callback - * Callback que será llamado cuando la ruta configurada en $path coincida. + * Callback que será llamado cuando la ruta configurada en $path coincida. * * @return static - * Devuelve la instancia actual. + * Devuelve la instancia actual. */ public static function get(string $path, ?callable $callback = null): static { @@ -216,13 +226,13 @@ class Router { /** * Define los routers para el método POST. * - * @param string $path - * Ruta con pseudovariables. + * @param string $path + * Ruta con pseudovariables. * @param callable|null $callback - * Callback que será llamado cuando la ruta configurada en $path coincida. + * Callback que será llamado cuando la ruta configurada en $path coincida. * * @return static - * Devuelve la instancia actual. + * Devuelve la instancia actual. */ public static function post(string $path, ?callable $callback = null): static { @@ -232,13 +242,13 @@ class Router { /** * Define los routers para el método PUT. * - * @param string $path - * Ruta con pseudovariables. + * @param string $path + * Ruta con pseudovariables. * @param callable|null $callback - * Callback que será llamado cuando la ruta configurada en $path coincida. + * Callback que será llamado cuando la ruta configurada en $path coincida. * * @return static - * Devuelve la instancia actual + * Devuelve la instancia actual */ public static function put(string $path, ?callable $callback = null): static @@ -249,13 +259,13 @@ class Router { /** * Define los routers para el método PATCH. * - * @param string $path - * Ruta con pseudovariables. + * @param string $path + * Ruta con pseudovariables. * @param callable|null $callback - * Callback que será llamado cuando la ruta configurada en $path coincida. + * Callback que será llamado cuando la ruta configurada en $path coincida. * * @return static - * Devuelve la instancia actual + * Devuelve la instancia actual */ public static function patch(string $path, ?callable $callback = null): static { @@ -265,13 +275,13 @@ class Router { /** * Define los routers para el método DELETE. * - * @param string $path - * Ruta con pseudovariables + * @param string $path + * Ruta con pseudovariables * @param callable|null $callback - * Callback que será llamado cuando la ruta configurada en $path coincida. + * Callback que será llamado cuando la ruta configurada en $path coincida. * * @return static - * Devuelve la instancia actual + * Devuelve la instancia actual */ public static function delete(string $path, ?callable $callback = null): static { @@ -283,10 +293,14 @@ class Router { * * @return string */ - public static function currentPath() : string + public static function currentPath(): string { - return preg_replace('/'.preg_quote(static::basePath(), '/').'/', - '/', strtok($_SERVER['REQUEST_URI'], '?'), 1); + return preg_replace( + '/' . preg_quote(static::basePath(), '/') . '/', + '/', + strtok($_SERVER['REQUEST_URI'], '?'), + 1 + ); } /** @@ -299,7 +313,7 @@ class Router { public static function apply(?string $path = null): void { $path = $path ?? static::currentPath(); - $routers = match($_SERVER['REQUEST_METHOD']) { // Según el método selecciona un arreglo de routers + $routers = match ($_SERVER['REQUEST_METHOD']) { // Según el método selecciona un arreglo de routers 'POST' => static::$post, 'PUT' => static::$put, 'PATCH' => static::$patch, @@ -308,7 +322,7 @@ class Router { }; foreach ($routers as $router) { // revisa todos los routers para ver si coinciden con la ruta actual - if (preg_match_all('/^'.$router['path'].'\/?$/si',$path, $matches, PREG_PATTERN_ORDER)) { + if (preg_match_all('/^' . $router['path'] . '\/?$/si', $path, $matches, PREG_PATTERN_ORDER)) { unset($matches[0]); // Objtener un reflection del callback @@ -316,14 +330,16 @@ class Router { if ($lastCallback instanceof \Closure) { // si es función anónima $reflectionCallback = new \ReflectionFunction($lastCallback); } else { - if (is_string($lastCallback)) + if (is_string($lastCallback)) { $lastCallback = preg_split('/::/', $lastCallback); + } // Revisamos su es un método o solo una función - if (count($lastCallback) == 2) + if (count($lastCallback) == 2) { $reflectionCallback = new \ReflectionMethod($lastCallback[0], $lastCallback[1]); - else + } else { $reflectionCallback = new \ReflectionFunction($lastCallback[0]); + } } // Obtener los parámetros @@ -334,22 +350,23 @@ class Router { // Verificamos si la clase está o no tipada if (empty($argumentClass)) { - $request = new Request; + $request = new Request(); } else { - $request = new $argumentClass; + $request = new $argumentClass(); // Verificamos que sea instancia de Request (requerimiento) - if (!($request instanceof Request)) + if (!($request instanceof Request)) { throw new \Exception('Bad argument type on router callback.'); + } } } else { - $request = new Request; + $request = new Request(); } // Comprobando y guardando los parámetros variables de la ruta if (isset($matches[1])) { foreach ($matches as $index => $match) { - $paramName = $router['paramNames'][$index-1]; + $paramName = $router['paramNames'][$index - 1]; $request->params->$paramName = urldecode($match[0]); } } @@ -369,6 +386,6 @@ class Router { } // Si no hay router que coincida llamamos a $notFoundCallBack - call_user_func_array(static::$notFoundCallback, [new Request]); + call_user_func_array(static::$notFoundCallback, [new Request()]); } } diff --git a/src/Libs/Validator.php b/src/Libs/Validator.php index e9fb438..8ec22b9 100644 --- a/src/Libs/Validator.php +++ b/src/Libs/Validator.php @@ -1,4 +1,7 @@ $rules) { $rules = preg_split('/\|/', $rules); foreach ($rules as $rule) { - if (static::checkRule($haystack->{$target}, $rule)) + if (static::checkRule($haystack->{$target}, $rule)) { continue; - static::$lastFailed = $target.'.'.$rule; + } + static::$lastFailed = $target . '.' . $rule; return false; } } @@ -71,10 +73,11 @@ class Validator { $rule = [static::class, $arguments[0]]; $arguments[0] = $subject; - if (is_callable($rule)) + if (is_callable($rule)) { return call_user_func_array($rule, $arguments); + } - throw new \Exception('Bad rule: "'.preg_split('/::/', $rule)[1].'"' ); + throw new \Exception('Bad rule: "' . preg_split('/::/', $rule)[1] . '"'); } /** diff --git a/src/Libs/View.php b/src/Libs/View.php index 19a44b5..8ccaa81 100644 --- a/src/Libs/View.php +++ b/src/Libs/View.php @@ -1,4 +1,7 @@ index) - * @param string|null $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/". - * @param string $extension (opcional) Extensión del archivo. + * @param string $viewName Ruta relativa y el nommbre sin extensión del archivo. + * @param array|Neuron $params (opcional) Arreglo que podrá ser usado en la vista + * mediante $view ($param['index'] se usaría así: $view->index) + * @param string|null $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/". + * @param string $extension (opcional) Extensión del archivo. * * @return void */ public static function render( string $viewName, array|Neuron $params = [], - ?string $viewPath = null, - string $extension = 'php' - ): void - { + ?string $viewPath = null, + string $extension = 'php' + ): void { $instance = new View($params); $instance->html($viewName, $viewPath, $extension); } @@ -64,17 +64,17 @@ class View extends Neuron { * Renderiza las vistas HTML * * @param string $viewName Ruta relativa y el nommbre sin extensión del archivo ubicado en src/Views - * @param string|null $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/". + * @param string|null $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/". * @param string $extension (opcional) Extensión del archivo. * * @return void */ public function html( - string $viewName, - ?string $viewPath = null, - string $extension = 'php' - ): void - { + string $viewName, + ?string $viewPath = null, + string $extension = 'php' + ): void { $this->include( $viewName, $viewPath, @@ -86,17 +86,17 @@ class View extends Neuron { * Renderiza código CSS. * * @param string $viewName Ruta relativa y el nommbre sin extensión del archivo ubicado en src/Views - * @param string|null $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/". + * @param string|null $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/". * @param string $extension (opcional) Extensión del archivo. * * @return void */ public function css( - string $viewName, - ?string $viewPath = null, - string $extension = 'css' - ): void - { + string $viewName, + ?string $viewPath = null, + string $extension = 'css' + ): void { header("Content-type: text/css"); $this->include($viewName, $viewPath, $extension); } @@ -105,17 +105,17 @@ class View extends Neuron { * Renderiza código Javascript. * * @param string $viewName Ruta relativa y el nommbre sin extensión del archivo ubicado en src/Views - * @param string|null $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/". + * @param string|null $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/". * @param string $extension (opcional) Extensión del archivo. * * @return void */ public function js( - string $viewName, - ?string $viewPath = null, - string $extension = 'js' - ): void - { + string $viewName, + ?string $viewPath = null, + string $extension = 'js' + ): void { header("Content-type: application/javascript"); $this->include($viewName, $viewPath, $extension); } @@ -155,10 +155,10 @@ class View extends Neuron { */ public static function route(string $path = '/'): string { - if (defined('SITE_URL') && !empty(SITE_URL)) - return rtrim(SITE_URL, '/').'/'.ltrim($path, '/'); + if (defined('SITE_URL') && !empty(SITE_URL)) { + return rtrim(SITE_URL, '/') . '/' . ltrim($path, '/'); + } return $path; } } -?>