From a09962c290f3061156fa6db8901db44ecf0bb0df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ricardo=20Garc=C3=ADa=20Jim=C3=A9nez?=
Date: Fri, 11 Mar 2022 17:28:07 -0600
Subject: [PATCH] =?UTF-8?q?[Registra]=20emails=20para=20suscribirse=20al?=
=?UTF-8?q?=20bolet=C3=ADn=20de=20Nabu?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
controllers/communityController.php | 90 ++++++++++++++++++++++++++++-
core/routes.php | 1 +
db/db.sql | 8 +++
models/communityModel.php | 28 +++++++++
views/emails/suscription.php | 24 ++++++++
views/pages/all-articles.php | 7 ++-
6 files changed, 153 insertions(+), 5 deletions(-)
create mode 100644 views/emails/suscription.php
diff --git a/controllers/communityController.php b/controllers/communityController.php
index d74afff..0671617 100644
--- a/controllers/communityController.php
+++ b/controllers/communityController.php
@@ -21,7 +21,7 @@ defined('NABU') || exit();
require_once 'models/communityModel.php';
class communityController {
- // Elimina un comentario.
+ // Elimina un comentario con el método GET.
static public function delete_comment() {
$view = NABU_ROUTES['home'];
@@ -50,7 +50,7 @@ class communityController {
utils::redirect(NABU_ROUTES['article'] . '&slug=' . $comment['slug']);
}
- // Registra o elimina el like de un artículo.
+ // Registra o elimina el like de un artículo con el método GET.
static public function likes() {
utils::check_session(NABU_ROUTES['login']);
@@ -85,6 +85,92 @@ class communityController {
utils::redirect(NABU_ROUTES['article'] . '&slug=' . $article['slug']);
}
+ // Cancela la suscripción de un correo con el método GET
+ // y registra un e-mail al boletín de los artículos más recientes con el método POST.
+ static public function suscription() {
+ $view = NABU_ROUTES['all-articles'];
+
+ $validations = new validations($view);
+
+ // Cancela la suscripción.
+ if (empty($_POST['suscription-form'])) {
+ // Valida los parámetros de la URL.
+ $data = $validations -> validate($_GET, array(
+ array('field' => 'email', 'trim' => true, 'min_length' => 5, 'max_length' => 255, 'not_spaces' => true),
+ array('field' => 'key', 'min_length' => 1, 'max_length' => 255)
+ ));
+
+ $email = strtolower($data['email']);
+
+ if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
+ messages::add('Por favor ingresa una dirección de correo electrónico válido');
+ utils::redirect($view);
+ }
+
+ $communityModel = new communityModel();
+
+ // Obtiene los datos de suscripción.
+ $suscription = $communityModel -> get_suscription($email);
+
+ if (empty($suscription))
+ utils::redirect($view);
+
+ messages::add('Tu suscripción se ha cancelado correctamente');
+
+ utils::redirect($view);
+ }
+
+ csrf::validate($_POST['csrf']);
+
+ // Valida el email de la suscripción.
+ $data = $validations -> validate($_POST, array(
+ array('field' => 'email', 'trim' => true, 'min_length' => 5, 'max_length' => 255, 'not_spaces' => true),
+ ));
+
+ $email = strtolower($data['email']);
+
+ if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
+ messages::add('Por favor ingresa una dirección de correo electrónico válido');
+ utils::redirect($view);
+ }
+
+ $communityModel = new communityModel();
+
+ // Obtiene los datos de suscripción.
+ $suscription = $communityModel -> get_suscription($email);
+
+ if (empty($suscription)) {
+ // Genera una llave aleatoria de cancelación de suscripción.
+ $key = bin2hex(random_bytes(32));
+
+ // Genera un hash de cancelación de suscripción.
+ $hash = hash_hmac('sha256', $email, $key);
+
+ require_once 'libs/emails.php';
+
+ $emails = new emails();
+ $emails -> prepare($email, $email);
+
+ // Genera una URL de cancelación de suscripción.
+ $url = NABU_ROUTES['suscription'] . '&email=' . urlencode($email) . '&key=' . $key;
+
+ $body = require_once 'views/emails/suscription.php';
+
+ // Envía primero un mensaje de suscripción antes de registrarlo.
+ if (!$emails -> send('¡Gracias por suscribirte!', $body))
+ messages::errors('¡Lo sentimos mucho! 😞, por el momento no podemos enviar tu mensaje de suscripción', 500);
+
+ // Registra la suscripción.
+ $communityModel -> save_suscription($email, $hash);
+
+ messages::add('Gracias por suscribirte al boletín de ' . NABU_DEFAULT['website-name']);
+ }
+ else
+ messages::add('Tu correo electrónico está suscripto al boletín de ' . NABU_DEFAULT['website-name']);
+
+ utils::redirect($view);
+ }
+
static public function favorites() {
//
}
diff --git a/core/routes.php b/core/routes.php
index ac07951..bb9a4b3 100644
--- a/core/routes.php
+++ b/core/routes.php
@@ -41,4 +41,5 @@ return array(
'registered-users' => array('route' => 'registered-users', 'controller' => 'adminController', 'view' => 'registered_users'),
'review-article' => array('route' => 'review-article', 'controller' => 'adminController', 'view' => 'review_article'),
'signup' => array('route' => 'signup', 'controller' => 'usersController', 'view' => 'signup'),
+ 'suscription' => array('route' => 'suscription', 'controller' => 'communityController', 'view' => 'suscription'),
);
diff --git a/db/db.sql b/db/db.sql
index 03f6d25..6179abb 100644
--- a/db/db.sql
+++ b/db/db.sql
@@ -97,6 +97,14 @@ CREATE TABLE IF NOT EXISTS `favorites` (
CONSTRAINT favorites_article_id_fk FOREIGN KEY(article_id) REFERENCES articles(id) ON UPDATE CASCADE ON DELETE CASCADE
);
+CREATE TABLE IF NOT EXISTS `suscriptions` (
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ `email` VARCHAR(255) NOT NULL,
+ `hash` VARCHAR(255) NOT NULL,
+ CONSTRAINT suscriptions_pk PRIMARY KEY(id),
+ CONSTRAINT suscriptions_email_uk UNIQUE(email)
+);
+
INSERT INTO roles(id, name) VALUES(1, 'ADMIN'), (2, 'MODERATOR'), (3, 'USER');
INSERT INTO users VALUES(1, 1, 'root', 'root', 'root@example.com', '$2y$12$.1ycdL5xs4nOpQ3GXga7m.IFNtfMgV5nKVe4R87B3CypgigBaJ55C', TRUE, NOW());
INSERT INTO profiles(id) VALUES(1);
diff --git a/models/communityModel.php b/models/communityModel.php
index c581318..fa4ebbb 100644
--- a/models/communityModel.php
+++ b/models/communityModel.php
@@ -109,6 +109,34 @@ class communityModel extends dbConnection {
}
}
+ // Obtiene los datos de suscripción de un e-mail.
+ public function get_suscription(string $email) {
+ $query = 'SELECT * FROM suscriptions WHERE email = ? LIMIT 1';
+
+ try {
+ $prepare = $this -> pdo -> prepare($query);
+
+ $prepare -> execute(array($email));
+
+ return $prepare -> fetch();
+ }
+ catch (PDOException $e) {
+ $this -> errors($e -> getMessage(), 'tuvimos un problema para obtener los datos de una suscripción');
+ }
+ }
+
+ // Registra una suscripción.
+ public function save_suscription(string $email, string $hash) {
+ $query = 'INSERT INTO suscriptions(email, hash) VALUES(?, ?)';
+
+ try {
+ $this -> pdo -> prepare($query) -> execute(array($email, $hash));
+ }
+ catch (PDOException $e) {
+ $this -> errors($e -> getMessage(), 'tuvimos un problema para registrar una suscripción');
+ }
+ }
+
public function __destruct() {
parent::__destruct();
$this -> pdo = null;
diff --git a/views/emails/suscription.php b/views/emails/suscription.php
new file mode 100644
index 0000000..037c424
--- /dev/null
+++ b/views/emails/suscription.php
@@ -0,0 +1,24 @@
+.
+*/
+
+defined('NABU') || exit();
+
+return 'A partir de ahora recibirás correos de parte de nuestro equipo en los que compartiremos ' .
+ 'contigo blogposts que te pudiesen interesar, así como tips para que tu escritura en medios ' .
+ 'digitales sea una de tus más grandes cualidades.
' .
+ 'Cancelar suscripción.
';
diff --git a/views/pages/all-articles.php b/views/pages/all-articles.php
index ab5cd05..f53e89a 100644
--- a/views/pages/all-articles.php
+++ b/views/pages/all-articles.php
@@ -79,9 +79,10 @@
Interesante, ¿No? 🤔
Déjanos tu e-mail y te compartiremos los posts más recientes, además de recursos para mejorar tu escritura en medios digitales. 😉
-