Merge with dev
This commit is contained in:
commit
a35a3b685a
45 changed files with 608 additions and 75 deletions
2
NOTICE
2
NOTICE
|
@ -1,4 +1,4 @@
|
||||||
Nabu - A content management system (CMS) for Markdown articles, written in HTML, CSS, Javascript and PHP.
|
Nabu - A content management system (CMS) for Markdown articles, written in HTML, CSS, JavaScript and PHP.
|
||||||
|
|
||||||
Copyright (C) 2021 Ricardo García Jiménez <ricardogj08@riseup.net>
|
Copyright (C) 2021 Ricardo García Jiménez <ricardogj08@riseup.net>
|
||||||
Juan José Ramírez López <juan.ramirez.j99@gmail.com>
|
Juan José Ramírez López <juan.ramirez.j99@gmail.com>
|
||||||
|
|
44
README.md
44
README.md
|
@ -0,0 +1,44 @@
|
||||||
|
# Nabu
|
||||||
|
|
||||||
|
Un sistema gestor de contenido (CMS) para artículos en `Markdown`, escrito en `HTML`, `CSS`, `JavaScript` y `PHP`.
|
||||||
|
|
||||||
|
## Archivo de configuración de la base de datos
|
||||||
|
|
||||||
|
Por defecto, `Nabu` escanea el archivo `database-config.json` dentro de la carpeta raíz del proyecto.
|
||||||
|
|
||||||
|
Estructura del archivo de configuración:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"dbms": "mysql",
|
||||||
|
"host": "localhost",
|
||||||
|
"database": "nabu",
|
||||||
|
"user": "root",
|
||||||
|
"password": "root",
|
||||||
|
"charset": "utf8mb4"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Licencia
|
||||||
|
|
||||||
|
```text
|
||||||
|
Nabu - Un sistema gestor de contenido (CMS) para artículos en Markdown, escrito en HTML, CSS, JavaScript y PHP.
|
||||||
|
|
||||||
|
Copyright (C) 2021 Ricardo García Jiménez <ricardogj08@riseup.net>,
|
||||||
|
Juan José Ramírez López <juan.ramirez.j99@gmail.com>,
|
||||||
|
Francisco Solís Martínez <franciscosolism08@gmail.com>,
|
||||||
|
Fernando Andrés Chávez Gavaldón <fernandochg26@gmail.com>
|
||||||
|
|
||||||
|
Este programa es software libre: puedes redistribuirlo y/o modificarlo
|
||||||
|
bajo los términos de la Licencia Pública General de GNU Affero publicada por
|
||||||
|
la Free Software Foundation, ya sea la versión 3 de la Licencia, o
|
||||||
|
(a su elección) cualquier versión posterior.
|
||||||
|
|
||||||
|
Este programa se distribuye con la esperanza de que sea de utilidad,
|
||||||
|
pero SIN NINGUNA GARANTÍA; incluso sin la garantía implícita de
|
||||||
|
COMERCIABILIDAD o APTITUD PARA UN PROPÓSITO PARTICULAR. Consulte la
|
||||||
|
Licencia Pública General de GNU Affero para obtener más detalles.
|
||||||
|
|
||||||
|
Debería haber recibido una copia de la Licencia Pública General de GNU Affero
|
||||||
|
junto con este programa. De lo contrario, consulte <https://www.gnu.org/licenses/>.
|
||||||
|
```
|
BIN
assets/images/hero-desktop.png
Normal file
BIN
assets/images/hero-desktop.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
assets/images/hero.png
Executable file → Normal file
BIN
assets/images/hero.png
Executable file → Normal file
Binary file not shown.
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 11 KiB |
BIN
assets/images/hero1_5x.png
Normal file
BIN
assets/images/hero1_5x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
assets/images/hero2x.png
Normal file
BIN
assets/images/hero2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
|
@ -23,6 +23,9 @@ class adminController {
|
||||||
case 'published':
|
case 'published':
|
||||||
self::published_articles();
|
self::published_articles();
|
||||||
break;
|
break;
|
||||||
|
case 'users':
|
||||||
|
self::users();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
utils::redirect(NABU_ROUTES['admin']);
|
utils::redirect(NABU_ROUTES['admin']);
|
||||||
}
|
}
|
||||||
|
@ -48,4 +51,8 @@ class adminController {
|
||||||
static private function published_articles() {
|
static private function published_articles() {
|
||||||
require_once 'views/admin/published-articles.php';
|
require_once 'views/admin/published-articles.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static private function users() {
|
||||||
|
require_once 'views/admin/users.php';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@ defined('NABU') || exit;
|
||||||
require_once 'models/usersModel.php';
|
require_once 'models/usersModel.php';
|
||||||
|
|
||||||
class usersController {
|
class usersController {
|
||||||
|
private const cost = array('cost' => 12);
|
||||||
|
private const hash = 'sha256';
|
||||||
|
|
||||||
static public function login() {
|
static public function login() {
|
||||||
require_once 'views/pages/login.php';
|
require_once 'views/pages/login.php';
|
||||||
}
|
}
|
||||||
|
@ -14,23 +17,57 @@ class usersController {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renderiza la página de registro de usuarios
|
// Renderiza la página de registro de usuarios
|
||||||
// y registra un usuario por el método POST.
|
// y registra un usuario con el método POST.
|
||||||
static public function signup() {
|
static public function signup() {
|
||||||
if (empty($_POST['signup-submit'])) {
|
if (empty($_POST['signup-submit'])) {
|
||||||
|
$token = csrf::generate();
|
||||||
$messages = messages::get();
|
$messages = messages::get();
|
||||||
require_once 'views/pages/signup.php';
|
require_once 'views/pages/signup.php';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
csrf::validate($_POST['csrf']);
|
||||||
|
|
||||||
$validations = new validations(NABU_ROUTES['signup']);
|
$validations = new validations(NABU_ROUTES['signup']);
|
||||||
|
|
||||||
$user = $validations -> validate_form($_POST, array(
|
$data = $validations -> validate_form($_POST, array(
|
||||||
array('name', 'exists' => true, 'trim_all' => true, 'min_lenght' => 5, 'max_lenght' => 255),
|
array('name', 'exists' => true, 'trim_all' => true, 'min_lenght' => 5, 'max_lenght' => 255),
|
||||||
array('username', 'exists' => true, 'trim' => true, 'min_lenght' => 1, 'max_lenght' => 255, 'not_spaces' => true),
|
array('username', 'exists' => true, 'trim' => true, 'min_lenght' => 1, 'max_lenght' => 255, 'not_spaces' => true),
|
||||||
array('email', 'exists' => true, 'is_email' => true, 'trim' => true, 'min_lenght' => 5, 'max_lenght' => 255, 'not_spaces' => true),
|
array('email', 'exists' => true, 'is_email' => true, 'trim' => true, 'min_lenght' => 5, 'max_lenght' => 255, 'not_spaces' => true),
|
||||||
array('password', 'exists' => true, 'min_lenght' => 6, 'max_lenght' => 255, 'not_spaces' => true, 'equal' => $_POST['confirm-password'])
|
array('password', 'exists' => true, 'min_lenght' => 6, 'max_lenght' => 255, 'not_spaces' => true, 'equal' => $_POST['confirm-password'])
|
||||||
));
|
));
|
||||||
|
|
||||||
$user['email'] = strtolower($user['email']);
|
$usersModel = new usersModel();
|
||||||
|
|
||||||
|
$users = $usersModel -> find($data['username'], $data['email']);
|
||||||
|
|
||||||
|
// Genera una llave aleatoria de verificación de dirección de e-mail.
|
||||||
|
$key = bin2hex(random_bytes(32));
|
||||||
|
|
||||||
|
// Formatea en minúsculas la dirección de e-mail.
|
||||||
|
$data['email'] = strtolower($data['email']);
|
||||||
|
|
||||||
|
// Hash de verificación de e-mail.
|
||||||
|
$hash = hash_hmac(self::hash, $data['email'], $key);
|
||||||
|
|
||||||
|
// Cifra la contraseña.
|
||||||
|
$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT, self::cost);
|
||||||
|
|
||||||
|
// Define la fecha de registro.
|
||||||
|
$data['creation_date'] = utils::current_date();
|
||||||
|
|
||||||
|
// Registra el nuevo usuario.
|
||||||
|
$usersModel -> save($data);
|
||||||
|
|
||||||
|
$user = $usersModel -> get('username', $data['username']);
|
||||||
|
|
||||||
|
$verification = array(
|
||||||
|
'id' => $user['id'],
|
||||||
|
'hash' => $hash,
|
||||||
|
'expiration' => time() + 60 * 60
|
||||||
|
);
|
||||||
|
|
||||||
|
// Registra el hash de verificación de dirección de e-mail.
|
||||||
|
$usersModel -> verification($verification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,9 @@ session_start();
|
||||||
require_once 'core/config.php';
|
require_once 'core/config.php';
|
||||||
require_once 'libs/utils.php';
|
require_once 'libs/utils.php';
|
||||||
require_once 'libs/messages.php';
|
require_once 'libs/messages.php';
|
||||||
|
require_once 'libs/csrf.php';
|
||||||
require_once 'libs/validations.php';
|
require_once 'libs/validations.php';
|
||||||
|
require_once 'database/connection.php';
|
||||||
|
|
||||||
$components = require 'core/routes.php';
|
$components = require 'core/routes.php';
|
||||||
|
|
||||||
|
|
|
@ -17,13 +17,14 @@ return array(
|
||||||
'home' => array('route' => 'home', 'controller' => 'blogController', 'view' => 'home'),
|
'home' => array('route' => 'home', 'controller' => 'blogController', 'view' => 'home'),
|
||||||
'favorites' => array('route' => 'favorites', 'controller' => 'communityController', 'view' => 'favorites'),
|
'favorites' => array('route' => 'favorites', 'controller' => 'communityController', 'view' => 'favorites'),
|
||||||
'like' => array('route' => 'like', 'controller' => 'communityController', 'view' => 'like'),
|
'like' => array('route' => 'like', 'controller' => 'communityController', 'view' => 'like'),
|
||||||
'published-articles' => array('route' => 'admin§ion=published', 'controller' => 'adminController', 'view' => 'admin'),
|
|
||||||
'login' => array('route' => 'login', 'controller' => 'usersController', 'view' => 'login'),
|
'login' => array('route' => 'login', 'controller' => 'usersController', 'view' => 'login'),
|
||||||
'logout' => array('route' => 'logout', 'controller' => 'usersController', 'view' => 'logout'),
|
'logout' => array('route' => 'logout', 'controller' => 'usersController', 'view' => 'logout'),
|
||||||
'post-article' => array('route' => 'post-article', 'controller' => 'articlesController', 'view' => 'post_article'),
|
'post-article' => array('route' => 'post-article', 'controller' => 'articlesController', 'view' => 'post_article'),
|
||||||
'profile' => array('route' => 'profile', 'controller' => 'profilesController', 'view' => 'profile'),
|
'profile' => array('route' => 'profile', 'controller' => 'profilesController', 'view' => 'profile'),
|
||||||
|
'published-articles' => array('route' => 'admin§ion=published', 'controller' => 'adminController', 'view' => 'admin'),
|
||||||
'search' => array('route' => 'search', 'controller' => 'searchController', 'view' => 'search'),
|
'search' => array('route' => 'search', 'controller' => 'searchController', 'view' => 'search'),
|
||||||
'sent-articles' => array('route' => 'sent-articles', 'controller' => 'articlesController', 'view' => 'sent_articles'),
|
'sent-articles' => array('route' => 'sent-articles', 'controller' => 'articlesController', 'view' => 'sent_articles'),
|
||||||
'signup' => array('route' => 'signup', 'controller' => 'usersController', 'view' => 'signup'),
|
'signup' => array('route' => 'signup', 'controller' => 'usersController', 'view' => 'signup'),
|
||||||
|
'users' => array('route' => 'admin§ion=users', 'controller' => 'adminController', 'view' => 'admin'),
|
||||||
'verifications' => array('route' => 'verifications', 'controller' => 'verificationsController', 'view' => 'verifications'),
|
'verifications' => array('route' => 'verifications', 'controller' => 'verificationsController', 'view' => 'verifications'),
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
defined('NABU') || exit;
|
||||||
|
|
||||||
|
// Realiza la conexión con la base de datos.
|
||||||
|
class connection {
|
||||||
|
protected $pdo;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
if (!file_exists(NABU_DIRECTORY['database'])) {
|
||||||
|
exit('Create a database config file.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carga el archivo de configuración de la base de datos.
|
||||||
|
$config = file_get_contents(NABU_DIRECTORY['database']);
|
||||||
|
|
||||||
|
if ($config === false) {
|
||||||
|
exit('The database config file is invalid.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$config = json_decode($config, true);
|
||||||
|
|
||||||
|
$keys = array('dbms', 'host', 'database', 'user', 'password', 'charset');
|
||||||
|
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if (empty($config[$key])) {
|
||||||
|
exit('Set "' . $key . '" in the database config file.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parámetros de configuración de la conexión de la base de datos.
|
||||||
|
$options = array(
|
||||||
|
// Mantiene el nombre de las columnas como en la base de datos.
|
||||||
|
PDO::ATTR_CASE => PDO::CASE_NATURAL,
|
||||||
|
// Define el manejador de errores de 'PDO' por excepciones, utiliza el objeto 'PDOException'.
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
// Deshabilita las consultas preparadas de 'PDO' y utiliza el sistema nativo del SGBD.
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
|
// Define por defecto los resultados de las consultas como arrays asociativos.
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
|
||||||
|
);
|
||||||
|
|
||||||
|
// Origen de la base de datos.
|
||||||
|
$dsn = $config['dbms'] . ':host=' . $config['host'] . ';dbname=' . $config['database'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Configuración y conexión de la base de datos.
|
||||||
|
$this -> pdo = new PDO($dsn, $config['user'], $config['password'], $options);
|
||||||
|
|
||||||
|
// Define la codificación de caracteres para el cliente del SGBD y los resultados de las consultas.
|
||||||
|
$this -> pdo -> exec('SET CHARSET ' . $config['charset']);
|
||||||
|
}
|
||||||
|
catch(PDOException $e) {
|
||||||
|
exit($e -> getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function errors(string $exception, string $error) {
|
||||||
|
// error_log($exception);
|
||||||
|
|
||||||
|
messages::errors('¡Lo sentimos mucho! 😞, ' . $error . ', por favor inténtelo más tarde', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @return el alias de un 'id de role'.
|
||||||
|
protected function role_format($id) {
|
||||||
|
$role = 'user';
|
||||||
|
|
||||||
|
if ($id == 1) {
|
||||||
|
$role = 'admin';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($id == 2) {
|
||||||
|
$role = 'moderator';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $role;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finaliza la conexión con la base de datos.
|
||||||
|
public function __destruct() {
|
||||||
|
$this -> pdo = null;
|
||||||
|
}
|
||||||
|
}
|
111
database/db.sql
111
database/db.sql
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
DROP DATABASE IF EXISTS nabu;
|
||||||
|
*/
|
||||||
|
|
||||||
|
CREATE DATABASE IF NOT EXISTS nabu
|
||||||
|
CHARACTER SET = 'utf8mb4'
|
||||||
|
COLLATE = 'utf8mb4_general_ci';
|
||||||
|
|
||||||
|
USE nabu;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `roles` (
|
||||||
|
`id` TINYINT UNSIGNED NOT NULL,
|
||||||
|
`name` VARCHAR(20) NOT NULL,
|
||||||
|
CONSTRAINT roles_id_pk PRIMARY KEY(id),
|
||||||
|
CONSTRAINT roles_name_uk UNIQUE(name)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `users` (
|
||||||
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`role_id` TINYINT UNSIGNED NOT NULL DEFAULT 3,
|
||||||
|
`name` VARCHAR(255) NOT NULL,
|
||||||
|
`username` VARCHAR(255) NOT NULL,
|
||||||
|
`email` VARCHAR(255),
|
||||||
|
`password` VARCHAR(255) NOT NULL,
|
||||||
|
`activated` TINYINT(1) NOT NULL DEFAULT FALSE,
|
||||||
|
`creation_date` DATETIME(0) NOT NULL,
|
||||||
|
CONSTRAINT users_id_pk PRIMARY KEY(id),
|
||||||
|
CONSTRAINT users_username_uk UNIQUE(username),
|
||||||
|
CONSTRAINT users_email_uk UNIQUE(email),
|
||||||
|
CONSTRAINT users_role_id_fk FOREIGN KEY(role_id) REFERENCES roles(id) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `verifications` (
|
||||||
|
`id` INT UNSIGNED NOT NULL,
|
||||||
|
`hash` VARCHAR(255) NOT NULL,
|
||||||
|
`expiration` INT UNSIGNED NOT NULL,
|
||||||
|
CONSTRAINT verifications_id_pk PRIMARY KEY(id),
|
||||||
|
CONSTRAINT verifications_id_fk FOREIGN KEY(id) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `profiles` (
|
||||||
|
`id` INT UNSIGNED NOT NULL,
|
||||||
|
`avatar` VARCHAR(255),
|
||||||
|
`background` VARCHAR(255),
|
||||||
|
`description` VARCHAR(255),
|
||||||
|
CONSTRAINT profiles_id_pk PRIMARY KEY(id),
|
||||||
|
CONSTRAINT profiles_id_fk FOREIGN KEY(id) REFERENCES users(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||||
|
CONSTRAINT profiles_avatar_uk UNIQUE(avatar),
|
||||||
|
CONSTRAINT profiles_background_uk UNIQUE(background)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `articles` (
|
||||||
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`user_id` INT UNSIGNED NOT NULL,
|
||||||
|
`title` VARCHAR(246) NOT NULL,
|
||||||
|
`synopsis` VARCHAR(255) NOT NULL,
|
||||||
|
`content` MEDIUMTEXT NOT NULL,
|
||||||
|
`slug` VARCHAR(255) NOT NULL,
|
||||||
|
`cover` VARCHAR(255),
|
||||||
|
`authorized` TINYINT(1) NOT NULL DEFAULT FALSE,
|
||||||
|
`creation_date` DATETIME(0) NOT NULL,
|
||||||
|
`modification_date` DATETIME(0),
|
||||||
|
CONSTRAINT articles_id_pk PRIMARY KEY(id),
|
||||||
|
CONSTRAINT articles_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||||
|
CONSTRAINT articles_slug_uk UNIQUE(slug),
|
||||||
|
CONSTRAINT articles_cover_uk UNIQUE(cover)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `categories` (
|
||||||
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` VARCHAR(50) NOT NULL,
|
||||||
|
CONSTRAINT categories_id_pk PRIMARY KEY(id),
|
||||||
|
CONSTRAINT categories_name_uk UNIQUE(name)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `categories_article` (
|
||||||
|
`article_id` INT UNSIGNED NOT NULL,
|
||||||
|
`categorie_id` INT UNSIGNED NOT NULL,
|
||||||
|
CONSTRAINT categories_article_pk PRIMARY KEY(article_id, categorie_id),
|
||||||
|
CONSTRAINT categories_article_article_id_fk FOREIGN KEY(article_id) REFERENCES articles(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||||
|
CONSTRAINT categories_categorie_id_fk FOREIGN KEY(categorie_id) REFERENCES categories(id) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `authorizations` (
|
||||||
|
`article_id` INT UNSIGNED NOT NULL,
|
||||||
|
`user_id` INT UNSIGNED NOT NULL,
|
||||||
|
`authorization_date` DATETIME(0) NOT NULL,
|
||||||
|
CONSTRAINT authorizations_pk PRIMARY KEY(article_id, authorization_date),
|
||||||
|
CONSTRAINT authorizations_article_id_fk FOREIGN KEY(article_id) REFERENCES articles(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||||
|
CONSTRAINT authorizations_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `comments` (
|
||||||
|
`user_id` INT UNSIGNED NOT NULL,
|
||||||
|
`article_id` INT UNSIGNED NOT NULL,
|
||||||
|
`body` VARCHAR(255) NOT NULL,
|
||||||
|
`comment_date` DATETIME(0) NOT NULL,
|
||||||
|
CONSTRAINT comments_pk PRIMARY KEY(user_id, comment_date),
|
||||||
|
CONSTRAINT comments_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||||
|
CONSTRAINT comments_article_id_fk FOREIGN KEY(article_id) REFERENCES articles(id) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `favorites` (
|
||||||
|
`user_id` INT UNSIGNED NOT NULL,
|
||||||
|
`article_id` INT UNSIGNED NOT NULL,
|
||||||
|
CONSTRAINT favorites_pk PRIMARY KEY(user_id, article_id),
|
||||||
|
CONSTRAINT favorites_user_id_fk FOREIGN KEY(user_id) REFERENCES users(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||||
|
CONSTRAINT favorites_article_id_fk FOREIGN KEY(article_id) REFERENCES articles(id) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO roles(id, name) VALUES(1, 'ADMIN'), (2, 'MODERATOR'), (3, 'USER');
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
defined('NABU') || exit;
|
||||||
|
|
||||||
|
// Valida formularios contra ataques CSRF.
|
||||||
|
class csrf {
|
||||||
|
private const size = 32;
|
||||||
|
private const hash = 'sha256';
|
||||||
|
private const secret = 'rWO!KJ9&*Wk@';
|
||||||
|
private const expiration = 4; // Horas.
|
||||||
|
|
||||||
|
// Elimina la variable de sesión.
|
||||||
|
private static function destroy() {
|
||||||
|
unset($_SESSION['csrf']);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function errors(string $error) {
|
||||||
|
self::destroy();
|
||||||
|
messages::errors($error, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Genera un token en base a bytes aleatorios.
|
||||||
|
public static function generate() {
|
||||||
|
$key = bin2hex(random_bytes(self::size));
|
||||||
|
|
||||||
|
$_SESSION['csrf'] = array(
|
||||||
|
'token' => hash_hmac(self::hash, self::secret, $key),
|
||||||
|
'expiration' => time() + (60 * 60 * self::expiration)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $_SESSION['csrf']['token'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valida si un token no está expirado y es igual al generado.
|
||||||
|
public static function validate($token2) {
|
||||||
|
if (empty($_SESSION['csrf']) || empty($token2)) {
|
||||||
|
self::errors('Token inválido');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time() > $_SESSION['csrf']['expiration']) {
|
||||||
|
self::errors('El formulario ha expirado, por favor recargue la página web');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hash_equals($_SESSION['csrf']['token'], $token2)) {
|
||||||
|
self::errors('Los tokens no coinciden');
|
||||||
|
}
|
||||||
|
|
||||||
|
self::destroy();
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
defined('NABU') || exit;
|
defined('NABU') || exit;
|
||||||
|
|
||||||
// Colecciòn de herramientas propias de Nabu.
|
// Colección de herramientas propias de Nabu.
|
||||||
class utils {
|
class utils {
|
||||||
// Redirecciona a una página web y termina la ejecución de todos los scripts de PHP.
|
// Redirecciona a una página web y termina la ejecución de todos los scripts de PHP.
|
||||||
static public function redirect(string $route) {
|
static public function redirect(string $route) {
|
||||||
|
@ -10,7 +10,12 @@ class utils {
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function escape(string $str) {
|
// @return la fecha actual.
|
||||||
|
static public function current_date() {
|
||||||
|
return date('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function escape($str) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,9 +96,6 @@ class validations {
|
||||||
$data = array();
|
$data = array();
|
||||||
|
|
||||||
foreach ($options as $option) {
|
foreach ($options as $option) {
|
||||||
if (!is_array($option))
|
|
||||||
$this -> errors('The validation options are not an array');
|
|
||||||
|
|
||||||
if (empty($option[0]) || !is_string($option[0]))
|
if (empty($option[0]) || !is_string($option[0]))
|
||||||
$this -> errors('Not found field name');
|
$this -> errors('Not found field name');
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
defined('NABU') || exit;
|
defined('NABU') || exit;
|
||||||
|
|
||||||
class adminModel {
|
class adminModel extends connection {
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct() {
|
||||||
|
parent::__destruct();
|
||||||
|
$this -> pdo = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
defined('NABU') || exit;
|
defined('NABU') || exit;
|
||||||
|
|
||||||
class articlesModel {
|
class articlesModel extends connection {
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct() {
|
||||||
|
parent::__destruct();
|
||||||
|
$this -> pdo = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
defined('NABU') || exit;
|
defined('NABU') || exit;
|
||||||
|
|
||||||
class blogModel {
|
class blogModel extends connection {
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct() {
|
||||||
|
parent::__destruct();
|
||||||
|
$this -> pdo = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
defined('NABU') || exit;
|
defined('NABU') || exit;
|
||||||
|
|
||||||
class communityModel {
|
class communityModel extends connection {
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct() {
|
||||||
|
parent::__destruct();
|
||||||
|
$this -> pdo = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
defined('NABU') || exit;
|
defined('NABU') || exit;
|
||||||
|
|
||||||
class profilesModel {
|
class profilesModel extends connection {
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct() {
|
||||||
|
parent::__destruct();
|
||||||
|
$this -> pdo = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
defined('NABU') || exit;
|
defined('NABU') || exit;
|
||||||
|
|
||||||
class searchModel {
|
class searchModel extends connection {
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct() {
|
||||||
|
parent::__destruct();
|
||||||
|
$this -> pdo = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,88 @@
|
||||||
|
|
||||||
defined('NABU') || exit;
|
defined('NABU') || exit;
|
||||||
|
|
||||||
class usersModel {
|
class usersModel extends connection {
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @return un lista de arrays asociativos con los datos de usuarios.
|
||||||
|
public function find(string $username, string $email) {
|
||||||
|
$query = 'SELECT u.id, u.role_id AS role, u.username, u.email, u.password, u.activated, u.creation_date,' .
|
||||||
|
'v.hash, v.expiration AS hash_expiration FROM users AS u ' .
|
||||||
|
'LEFT JOIN verifications AS v on u.id = v.id ' .
|
||||||
|
'WHERE u.username = ? OR u.email = ? LIMIT 2';
|
||||||
|
|
||||||
|
try {
|
||||||
|
$prepare = $this -> pdo -> prepare($query);
|
||||||
|
|
||||||
|
$prepare -> execute(array($username, $email));
|
||||||
|
|
||||||
|
$users = $prepare -> fetchAll();
|
||||||
|
|
||||||
|
if (empty($users)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $users;
|
||||||
|
}
|
||||||
|
catch(PDOException $e) {
|
||||||
|
$this -> errors($e -> getMessage(), 'tuvimos un problema para validar si tu apodo y dirección de correo electrónico son únicos');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registra un nuevo usuario.
|
||||||
|
public function save(array $data) {
|
||||||
|
$query = 'INSERT INTO users(name, username, email, password, creation_date) ' .
|
||||||
|
'VALUES(:name, :username, :email, :password, :creation_date)';
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this -> pdo -> prepare($query) -> execute($data);
|
||||||
|
}
|
||||||
|
catch(PDOException $e) {
|
||||||
|
$this -> errors($e -> getMessage(), 'tuvimos un problema para registrar tu cuenta de usuario');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @return un array asociativo con los datos de un solo usuario.
|
||||||
|
public function get(string $column, $pattern) {
|
||||||
|
$query = 'SELECT u.id, u.role_id AS role, u.username, u.email, u.password, u.activated, u.creation_date,' .
|
||||||
|
'v.hash, v.expiration AS hash_expiration FROM users AS u ' .
|
||||||
|
'LEFT JOIN verifications AS v on u.id = v.id ' .
|
||||||
|
'WHERE u.' . $column . ' = ? LIMIT 1';
|
||||||
|
|
||||||
|
try {
|
||||||
|
$prepare = $this -> pdo -> prepare($query);
|
||||||
|
|
||||||
|
$prepare -> execute(array($pattern));
|
||||||
|
|
||||||
|
$user = $prepare -> fetch();
|
||||||
|
|
||||||
|
if ($user !== false) {
|
||||||
|
$user['role'] = $this -> role_format($user['role']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
catch(PDOException $e) {
|
||||||
|
$this -> errors($e -> getMessage(), 'tuvimos un problema para buscar tu cuenta de usuario');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registra el 'hash de verificación de dirección de e-mail' con tiempo de expiración.
|
||||||
|
public function verification(array $verification) {
|
||||||
|
$query = 'INSERT INTO verifications(id, hash, expiration) VALUES(:id, :hash, :expiration)';
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this -> pdo -> prepare($query) -> execute($verification);
|
||||||
|
}
|
||||||
|
catch(PDOException $e) {
|
||||||
|
$this -> errors($e -> getMessage(), 'tuvimos un problema para registrar tu clave de verificación de dirección de correo electrónico');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct() {
|
||||||
|
parent::__destruct();
|
||||||
|
$this -> pdo = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
defined('NABU') || exit;
|
defined('NABU') || exit;
|
||||||
|
|
||||||
class verificationsModel {
|
class verificationsModel extends connection {
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct() {
|
||||||
|
parent::__destruct();
|
||||||
|
$this -> pdo = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Administración' ?>
|
<?php $head_title = 'Administración' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/admin/dashboard/dashboard.css',
|
'admin/dashboard/dashboard.css',
|
||||||
NABU_DIRECTORY['styles'] . '/admin/dashboard/dashboard-desktop.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('admin/dashboard/dashboard-desktop.css', 'attributes' => ''),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
<?php require_once 'views/components/admin-navbar.php' ?>
|
<?php require_once 'views/components/admin-navbar.php' ?>
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Editar artículo' ?>
|
<?php $head_title = 'Editar artículo' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/admin/edit-article/edit-article.css',
|
'admin/edit-article/edit-article.css',
|
||||||
NABU_DIRECTORY['styles'] . '/admin/edit-article/edit-article-desktop.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('admin/edit-article/edit-article-desktop.css', 'attributes' => ''),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
<?php require_once 'views/components/admin-navbar.php' ?>
|
<?php require_once 'views/components/admin-navbar.php' ?>
|
||||||
|
|
||||||
<h1>Editar artículo</h1>
|
<h1>Editar artículo</h1>
|
||||||
|
|
||||||
<p><a href="<?= NABU_ROUTES['admin'] ?>">Volver</a></p>
|
|
||||||
|
|
||||||
<?php require_once 'views/components/messages.php' ?>
|
<?php require_once 'views/components/messages.php' ?>
|
||||||
|
|
||||||
<form method="POST" action="<?= NABU_ROUTES['edit-article'] . '&slug=' . $article['slug'] ?>" enctype="multipart/form-data">
|
<form method="POST" action="<?= NABU_ROUTES['edit-article'] . '&slug=' . $article['slug'] ?>" enctype="multipart/form-data">
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Artículos publicados' ?>
|
<?php $head_title = 'Artículos publicados' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/admin/published-articles/published-articles.css',
|
'admin/published-articles/published-articles.css',
|
||||||
NABU_DIRECTORY['styles'] . '/admin/published-articles/published-articles-desktop.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('admin/published-articles/published-articles-desktop.css', 'attributes' => ''),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
<?php require_once 'views/components/admin-navbar.php' ?>
|
<?php require_once 'views/components/admin-navbar.php' ?>
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Usuarios registrados' ?>
|
<?php $head_title = 'Usuarios registrados' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/admin/users/users.css',
|
'admin/users/users.css',
|
||||||
NABU_DIRECTORY['styles'] . '/admin/users/users-desktop.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('admin/users/users-desktop.css', 'attributes' => ''),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
<?php require_once 'views/components/admin-navbar.php' ?>
|
<?php require_once 'views/components/admin-navbar.php' ?>
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="<?= NABU_ROUTES['admin'] ?>">Artículos envíados</a></li>
|
<li><a href="<?= NABU_ROUTES['admin'] ?>">Artículos envíados</a></li>
|
||||||
<li><a href="<?= NABU_ROUTES['published-articles'] ?>">Artículos publicados</a></li>
|
<li><a href="<?= NABU_ROUTES['published-articles'] ?>">Artículos publicados</a></li>
|
||||||
|
<li><a href="<?= NABU_ROUTES['users'] ?>">Usuarios registrados</a></li>
|
||||||
<li><a href="<?= NABU_ROUTES['home'] ?>"><?= NABU_DEFAULT['website-name'] ?></a></li>
|
<li><a href="<?= NABU_ROUTES['home'] ?>"><?= NABU_DEFAULT['website-name'] ?></a></li>
|
||||||
<li><a href="<?= NABU_ROUTES['profile'] . '&user=' . urlencode($username) ?>"><?= utils::escape($username) ?></a></li>
|
<li><a href="<?= NABU_ROUTES['profile'] . '&user=' . urlencode($username) ?>"><?= utils::escape($username) ?></a></li>
|
||||||
<li><a href="<?= NABU_ROUTES['logout'] ?>">Cerrar sesión</a></li>
|
<li><a href="<?= NABU_ROUTES['logout'] ?>">Cerrar sesión</a></li>
|
||||||
|
|
|
@ -5,18 +5,25 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<!-- CSS files -->
|
<!-- Base CSS files -->
|
||||||
<link rel="icon" href="<?= NABU_DIRECTORY['images'] ?>/buho.svg" type="image/svg+xml" sizes="any">
|
<link rel="icon" href="<?= NABU_DIRECTORY['images'] ?>/buho.svg" type="image/svg+xml" sizes="any">
|
||||||
<link rel="stylesheet" href="<?= NABU_DIRECTORY['styles'] ?>/normalize.css">
|
<link rel="stylesheet" href="<?= NABU_DIRECTORY['styles'] ?>/normalize.css">
|
||||||
|
<!-- Mobile CSS files -->
|
||||||
<?php foreach ($styles as $style): ?>
|
<?php foreach ($styles as $style): ?>
|
||||||
<link rel="stylesheet" href="<?= $style ?>">
|
<link rel="stylesheet" href="<?= NABU_DIRECTORY['styles'] . '/' . $style ?>">
|
||||||
|
<?php endforeach ?>
|
||||||
|
<!-- Desktop CSS files -->
|
||||||
|
<?php foreach ($desktop_styles as $style): ?>
|
||||||
|
<link rel="stylesheet" href="<?= NABU_DIRECTORY['styles'] . '/' . $style[0] ?>" <?= $style['attributes'] ?>>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
<!-- Fonts -->
|
<!-- Fonts -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||||
<!-- JS files -->
|
<!-- JS files -->
|
||||||
<script src="<?= NABU_DIRECTORY['scripts'] ?>/main.js" defer></script>
|
<?php foreach ($scripts as $script): ?>
|
||||||
|
<script src="<?= NABU_DIRECTORY['scripts'] . '/' . $script ?>" defer></script>
|
||||||
|
<?php endforeach ?>
|
||||||
<title><?= $head_title ?></title>
|
<title><?= $head_title ?></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Muro' ?>
|
<?php $head_title = 'Muro' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/all-articles/all-articles.css',
|
'pages/all-articles/all-articles.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/all-articles/all-articles-desktop.css',
|
'components/articles/articles.css',
|
||||||
NABU_DIRECTORY['styles'] . '/components/articles/articles.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/all-articles/all-articles-desktop.css', 'attributes' => ''),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
<?php require_once 'views/components/navbar.php' ?>
|
<?php require_once 'views/components/navbar.php' ?>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Artículo' ?>
|
<?php $head_title = 'Artículo' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/article/article.css',
|
'pages/article/article.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/article/article-desktop.css',
|
'components/articles/articles.css',
|
||||||
NABU_DIRECTORY['styles'] . '/components/articles/articles.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/article/article-desktop.css', 'attributes' => ''),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
|
|
||||||
<h1><?= $article['title'] ?></h1>
|
<h1><?= $article['title'] ?></h1>
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Categoría' ?>
|
<?php $head_title = 'Categoría' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/category/category.css',
|
'pages/category/category.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/category/category-desktop.css',
|
'components/articles/articles.css',
|
||||||
NABU_DIRECTORY['styles'] . '/components/articles/articles.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/category/category-desktop.css', 'attributes' => '')
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
<?php require_once 'views/components/navbar.php' ?>
|
<?php require_once 'views/components/navbar.php' ?>
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Confirmar contraseña' ?>
|
<?php $head_title = 'Confirmar contraseña' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/confirm-password/confirm-password.css',
|
'pages/confirm-password/confirm-password.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/confirm-password/confirm-password-desktop.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/confirm-password/confirm-password-desktop.css', 'attributes' => '')
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
|
|
||||||
<h1>Confirmar contraseña</h1>
|
<h1>Confirmar contraseña</h1>
|
||||||
|
|
||||||
<p><a href="<?= $back ?>">Volver</a></p>
|
|
||||||
|
|
||||||
<?php require_once 'views/components/messages.php' ?>
|
<?php require_once 'views/components/messages.php' ?>
|
||||||
|
|
||||||
<p>Ingresa tu contraseña para completar la operación.</p>
|
<p>Ingresa tu contraseña para completar la operación.</p>
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Editar artículo' ?>
|
<?php $head_title = 'Editar artículo' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/edit-article/edit-article.css',
|
'pages/edit-article/edit-article.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/edit-article/edit-article-desktop.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/edit-article/edit-article-desktop.css', 'attributes' => '')
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
<?php require_once 'views/components/navbar.php' ?>
|
<?php require_once 'views/components/navbar.php' ?>
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Editar perfil' ?>
|
<?php $head_title = 'Editar perfil' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/edit-profile/edit-profile.css',
|
'pages/edit-profile/edit-profile.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/edit-profile/edit-profile-desktop.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/edit-profile/edit-profile-desktop.css', 'attributes' => '')
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
|
|
||||||
<h1>Editar perfil</h1>
|
<h1>Editar perfil</h1>
|
||||||
|
|
||||||
<p><a href="<?= $back ?>">Volver</a></p>
|
|
||||||
|
|
||||||
<?php require_once 'views/components/messages.php' ?>
|
<?php require_once 'views/components/messages.php' ?>
|
||||||
|
|
||||||
<form method="POST" action="<?= NABU_ROUTES['edit-profile'] ?>" enctype="multipart/form-data">
|
<form method="POST" action="<?= NABU_ROUTES['edit-profile'] ?>" enctype="multipart/form-data">
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Error' ?>
|
<?php $head_title = 'Error' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/errors/errors.css',
|
'pages/errors/errors.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/errors/errors-desktop.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/errors/errors-desktop.css', 'attributes' => '')
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
|
|
||||||
<p><a href="<?= NABU_ROUTES['home'] ?>">Volver</a></p>
|
|
||||||
|
|
||||||
<p><mark><?= $error ?>.</mark></p>
|
<p><mark><?= $error ?>.</mark></p>
|
||||||
|
|
||||||
<?php require_once 'views/components/footer.php' ?>
|
<?php require_once 'views/components/footer.php' ?>
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Artículos favoritos' ?>
|
<?php $head_title = 'Artículos favoritos' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/favorites/favorites.css',
|
'pages/favorites/favorites.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/favorites/favorites-desktop.css',
|
'components/articles/articles.css',
|
||||||
NABU_DIRECTORY['styles'] . '/components/articles/articles.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/favorites/favorites-desktop.css', 'attributes' => '')
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
<?php require_once 'views/components/navbar.php' ?>
|
<?php require_once 'views/components/navbar.php' ?>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = NABU_DEFAULT['website-name'] ?>
|
<?php $head_title = NABU_DEFAULT['website-name'] ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/home/home.css',
|
'pages/home/home.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/home/home-desktop.css',
|
'components/articles/articles.css',
|
||||||
NABU_DIRECTORY['styles'] . '/components/articles/articles.css',
|
'components/footer/footer.css',
|
||||||
NABU_DIRECTORY['styles'] . '/components/footer/footer.css',
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/home/home-desktop.css', 'attributes' => 'media="(max-width: 720px)"'),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array(
|
||||||
|
'home.js',
|
||||||
) ?>
|
) ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
|
|
||||||
|
@ -12,6 +17,7 @@
|
||||||
<?php require_once 'views/components/navbar.php' ?>
|
<?php require_once 'views/components/navbar.php' ?>
|
||||||
<div class="hero">
|
<div class="hero">
|
||||||
<picture class="hero__img-wrapper">
|
<picture class="hero__img-wrapper">
|
||||||
|
<source srcset="<?= NABU_DIRECTORY['images'] ?>/hero-desktop.png" media="(min-width: 600px)">
|
||||||
<img src="<?= NABU_DIRECTORY['images'] ?>/hero.png" alt="Imagen inspiración en cualquier momento y cualquier lugar" class="hero__img">
|
<img src="<?= NABU_DIRECTORY['images'] ?>/hero.png" alt="Imagen inspiración en cualquier momento y cualquier lugar" class="hero__img">
|
||||||
</picture>
|
</picture>
|
||||||
<h1 class="hero__CTA">Lee, inspírate y escribe</h1>
|
<h1 class="hero__CTA">Lee, inspírate y escribe</h1>
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Iniciar sesión' ?>
|
<?php $head_title = 'Iniciar sesión' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/login/login.css',
|
'pages/login/login.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/login/login-desktop.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/login/login-desktop.css', 'attributes' => ''),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
|
|
||||||
<h1>Iniciar sesión</h1>
|
<h1>Iniciar sesión</h1>
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Publicar un artículo' ?>
|
<?php $head_title = 'Publicar un artículo' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/post-article/post-article.css',
|
'pages/post-article/post-article.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/post-article/post-article-desktop.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/post-article/post-article-desktop.css', 'attributes' => ''),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
<?php require_once 'views/components/navbar.php' ?>
|
<?php require_once 'views/components/navbar.php' ?>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Perfil' ?>
|
<?php $head_title = 'Perfil' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/profile/profile.css',
|
'pages/profile/profile.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/profile/profile-desktop.css',
|
'components/articles/articles.css',
|
||||||
NABU_DIRECTORY['styles'] . '/components/articles/articles.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/profile/profile-desktop.css', 'attributes' => ''),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
<?php require_once 'views/components/navbar.php' ?>
|
<?php require_once 'views/components/navbar.php' ?>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Búsquedas' ?>
|
<?php $head_title = 'Búsquedas' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/search/search.css',
|
'pages/search/search.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/search/search-desktop.css',
|
'components/articles/articles.css',
|
||||||
NABU_DIRECTORY['styles'] . '/components/articles/articles.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/search/search-desktop.css', 'attributes' => ''),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
<?php require_once 'views/components/navbar.php' ?>
|
<?php require_once 'views/components/navbar.php' ?>
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Artículos enviados' ?>
|
<?php $head_title = 'Artículos enviados' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
NABU_DIRECTORY['styles'] . '/pages/sent-articles/sent-articles.css',
|
'pages/sent-articles/sent-articles.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/sent-articles/sent-articles-desktop.css',
|
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/sent-articles/sent-articles-desktop.css', 'attributes' => ''),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
<?php require_once 'views/components/navbar.php' ?>
|
<?php require_once 'views/components/navbar.php' ?>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
<?php defined('NABU') || exit ?>
|
<?php defined('NABU') || exit ?>
|
||||||
<?php $head_title = 'Crea una cuenta' ?>
|
<?php $head_title = 'Crea una cuenta' ?>
|
||||||
<?php $styles = array(
|
<?php $styles = array(
|
||||||
|
<<<<<<< HEAD
|
||||||
NABU_DIRECTORY['styles'] . '/pages/signup/signup.css',
|
NABU_DIRECTORY['styles'] . '/pages/signup/signup.css',
|
||||||
NABU_DIRECTORY['styles'] . '/pages/signup/signup-desktop.css',
|
NABU_DIRECTORY['styles'] . '/pages/signup/signup-desktop.css',
|
||||||
NABU_DIRECTORY['styles'] . '/components/footer/footer.css',
|
NABU_DIRECTORY['styles'] . '/components/footer/footer.css',
|
||||||
|
=======
|
||||||
|
'pages/signup/signup.css',
|
||||||
|
>>>>>>> dev
|
||||||
) ?>
|
) ?>
|
||||||
|
<?php $desktop_styles = array(
|
||||||
|
array('pages/signup/signup-desktop.css', 'attributes' => ''),
|
||||||
|
) ?>
|
||||||
|
<?php $scripts = array() ?>
|
||||||
<?php require_once 'views/components/head.php' ?>
|
<?php require_once 'views/components/head.php' ?>
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue