Post Top Ad

Your Ad Spot

jueves, 7 de mayo de 2020

Cómo crear un blog en una base de datos PHP y MySQL: diseño de base de datos

La base de datos

Esta es la segunda parte de una serie sobre Cómo crear un blog con PHP y MySQL. Puedes obtener la primera parte aquí
Continuaremos donde lo dejamos en el último tutorial. En esta sección trabajaremos en el diseño de nuestra base de datos y la autenticación del usuario (registro e inicio de sesión). Cree una base de datos llamada complete-blog-php . En esta base de datos, cree 2 tablas:  publicaciones  y usuarios con los siguientes campos.
publicaciones :
+----+-----------+--------------+------------+
|     field      |     type     | specs      |
+----+-----------+--------------+------------+
|  id            | INT(11)      |            |
|  user_id       | INT(11)      |            |
|  title         | VARCHAR(255) |            |
|  slug          | VARCHAR(255) | UNIQUE     |
|  views         | INT(11)      |            |
|  image         | VARCHAR(255) |            |
|  body          | TEXT         |            |
|  published     | boolean      |            |
|  created_at    | TIMESTAMP    |            |
|  updated_at    | TIMESTAMP    |            |
+----------------+--------------+------------+
usuarios :
+----+-----------+------------------------+------------+
|     field      |     type               | specs      |
+----+-----------+------------------------+------------+
|  id            | INT(11)                |            |
|  username      | VARCHAR(255)           | UNIQUE     |
|  email         | VARCHAR(255)           | UNIQUE     |
|  role          | ENUM("Admin","Author") |            |
|  password      | VARCHAR(255)           |            |
|  created_at    | TIMESTAMP              |            |
|  updated_at    | TIMESTAMP              |            |
+----------------+--------------+---------+------------+
Puede crear estas tablas con estos comandos.
usuarios :
CREATE TABLE `users` (
  `id` int(11) AUTO_INCREMENT PRIMARY KEY NOT NULL,
  `username` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `role` enum('Author','Admin') DEFAULT NULL,
  `password` varchar(255) NOT NULL,
  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
publicaciones :
CREATE TABLE `posts` (
 `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
 `user_id` int(11) DEFAULT NULL,
 `title` varchar(255) NOT NULL,
 `slug` varchar(255) NOT NULL UNIQUE,
 `views` int(11) NOT NULL DEFAULT '0',
 `image` varchar(255) NOT NULL,
 `body` text NOT NULL,
 `published` tinyint(1) NOT NULL,
 `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Puede ejecutar estos scripts utilizando el símbolo del sistema de SQL o PHPMyAdmin. En PHPMyAdmin, haga clic / seleccione la base de datos en la que desea crear estas tablas (en este caso complete-blog-php ), luego haga clic en la pestaña SQL en la barra de navegación en algún lugar en la parte superior de la página. Si ve algún script SQL en el espacio a continuación, elimínelo y péguelo en el espacio provisto y haga clic en 'Ir' para crear las tablas.
Si elige crear estas tablas manualmente, recuerde hacer que el campo slug en la tabla de publicación sea ÚNICO, y recuerde establecer el campo user_id de la tabla de publicaciones como la clave externa que hace referencia a la identificación en la tabla de usuarios . Establezca NO ACTION como el valor para las opciones ON DELETE y ON UPDATE para que cuando un usuario se elimine o actualice, sus publicaciones permanezcan en la tabla de publicaciones y no se eliminen.
Ahora inserte algunos usuarios en la tabla de usuarios y algunas publicaciones en la tabla de publicaciones . Puede hacerlo ejecutando estas consultas SQL para insertar:
usuarios:
INSERT INTO `users` (`id`, `username`, `email`, `role`, `password`, `created_at`, `updated_at`) VALUES
(1, 'Awa', 'info@codewithawa.com', 'Admin', 'mypassword', '2018-01-08 12:52:58', '2018-01-08 12:52:58')
publicaciones: 
INSERT INTO `posts` (`id`, `user_id`, `title`, `slug`, `views`, `image`, `body`, `published`, `created_at`, `updated_at`) VALUES
(1, 1, '5 Habits that can improve your life', '5-habits-that-can-improve-your-life', 0, 'banner.jpg', 'Read every day', 1, '2018-02-03 07:58:02', '2018-02-01 19:14:31'),
(2, 1, 'Second post on LifeBlog', 'second-post-on-lifeblog', 0, 'banner.jpg', 'This is the body of the second post on this site', 0, '2018-02-02 11:40:14', '2018-02-01 13:04:36')
Vamos a conectarnos a la base de datos, consultar estas publicaciones y mostrarlas en la página web.
En config. php , agreguemos código para conectar nuestra aplicación a la base de datos. Después de agregar el código, nuestro archivo config.php se verá así:
<?php 
 session_start();
 // connect to database
 $conn = mysqli_connect("localhost", "root", "", "complete-blog-php");

 if (!$conn) {
  die("Error connecting to database: " . mysqli_connect_error());
 }
    // define global constants
 define ('ROOT_PATH', realpath(dirname(__FILE__)));
 define('BASE_URL', 'http://localhost/complete-blog-php/');
?>
Esto devuelve un objeto de conectividad de base de datos $ conn que podemos usar en toda nuestra aplicación para consultar la base de datos.
Esta aplicación se ha estructurado de manera que el código PHP esté lo más separado posible del HTML. Las operaciones como consultar la base de datos y realizar cierta lógica en los datos se realizan en funciones PHP y los resultados se envían a HTML para que se muestren. Por lo tanto, para obtener todas las publicaciones de la base de datos, lo haremos en una función y devolveremos los resultados como una matriz asociativa para que se repita y se muestre en la página.
Por lo tanto, cree un archivo llamado  public_functions.php  en la carpeta de inclusiones . Este archivo contendrá todas nuestras funciones PHP para el área pública. Todas las páginas que utilizan cualquiera de las funciones de este archivo deben tener este archivo incluido en la sección superior de la página.
Creemos nuestra primera función en nuestro public_functions.php recién creado Llamaremos a la función getPublishedPosts () y recuperará todas las publicaciones de la tabla de publicaciones en la base de datos y las devolverá como una matriz asociativa:
public_functions.php:
<?php 
/* * * * * * * * * * * * * * *
* Returns all published posts
* * * * * * * * * * * * * * */
function getPublishedPosts() {
 // use global $conn object in function
 global $conn;
 $sql = "SELECT * FROM posts WHERE published=true";
 $result = mysqli_query($conn, $sql);

 // fetch all posts as an associative array called $posts
 $posts = mysqli_fetch_all($result, MYSQLI_ASSOC);

 return $posts;
}

// more functions to come here ...
?>
En la sección superior del archivo index.php , justo debajo de la línea que incluye config. php , agregue este código para consultar la base de datos:
<!-- config.php should be here as the first include  -->

<?php require_once( ROOT_PATH . '/includes/public_functions.php') ?>

<!-- Retrieve all posts from database  -->
<?php $posts = getPublishedPosts(); ?>
Agregamos dos líneas de código. El primero incluye el archivo public_functions.php  (que contiene las funciones) a nuestro archivo index.php . La segunda línea de código llama a la función getPublishedPosts () que consulta la base de datos y devuelve las publicaciones recuperadas de la base de datos en una variable llamada $ posts . Ahora recorramos y visualicemos estas publicaciones en la página index.php .
Abra nuestro famoso archivo index.php nuevamente. En la sección de contenido en algún lugar en el medio, encontrará una etiqueta <hr> y un comentario que indica dónde vendrá más contenido. En el espacio, justo debajo de la etiqueta <hr> , agregue este código:
<hr>
<!-- more content still to come here ... -->

<!-- Add this ... -->
<?php foreach ($posts as $post): ?>
 <div class="post" style="margin-left: 0px;">
  <img src="<?php echo BASE_URL . '/static/images/' . $post['image']; ?>" class="post_image" alt="">
  <a href="single_post.php?post-slug=<?php echo $post['slug']; ?>">
   <div class="post_info">
    <h3><?php echo $post['title'] ?></h3>
    <div class="info">
     <span><?php echo date("F j, Y ", strtotime($post["created_at"])); ?></span>
     <span class="read_more">Read more...</span>
    </div>
   </div>
  </a>
 </div>
<?php endforeach ?>
De acuerdo, por favor, no vuelvas a cargar la página todavía. Agreguemos estilo a este listado de publicaciones. Abra public_styling.css y agregue este código:
/* CONTENT */
.content {
 margin: 5px auto;
 border-radius: 5px;
 min-height: 400px;
}
.content:after {
 content: "";
 display: block;
 clear: both;
}
.content .content-title {
 margin: 10px 0px;
 color: #374447;
 font-family: 'Averia Serif Libre', cursive;
}
.content .post {
 width: 335px;
 margin: 9px;
 min-height: 320px;
 float: left;
 border-radius: 2px;
 border: 1px solid #b3b3b3;
 position: relative;
}
.content .post .category {
 margin-top: 0px;
 padding: 3px 8px;
 color: #374447;
 background: white;
 display: inline-block;
 border-radius: 2px;
 border: 1px solid #374447;
 box-shadow: 3px 2px 2px;
 position: absolute;
 left: 5px; top: 5px;
 z-index: 3;
}
.content .post .category:hover {
 box-shadow: 3px 2px 2px;
 color: white;
 background: #374447;
 transition: .4s;
 opacity: 1;
}
.content .post .post_image {
 height: 260px;
 width: 100%;
 background-size: 100%;
}
.content .post .post_image {
 width: 100%;
 height: 260px;
}
.content .post .post_info {
 height: 100%;
 padding: 0px 5px;
 font-weight: 200;
    font-family: 'Noto Serif', serif;
}
.content .post .post_info {
 color: #222;
}
.content .post .post_info span {
 color: #A6A6A6;
 font-style: italic;
}
.content .post .post_info span.read_more {
 position: absolute;
 right: 5px; bottom: 5px;
}
Ahora puedes recargar la página.
Si todo salió bien, verá una sola publicación con el estilo de una miniatura debajo del título "Artículos recientes". Recuerde que habíamos insertado dos registros en la base de datos, pero solo se muestra uno. Esto es así porque uno de los registros tenía su campo publicado establecido en falso (es decir, 0), y dado que solo se muestran los artículos publicados, solo vemos uno, el publicado.
Pero nuestras publicaciones a partir de ahora no están clasificadas en ningún tema. Creemos una tabla de temas y formemos una relación de muchos a muchos entre las publicaciones y la tabla de temas . Para hacer esto, crearemos dos tablas nuevas: temas para almacenar temas y tabla post_topic para manejar la relación entre publicaciones y temas.
temas:
+----+-----------+------------------------+------------+
|     field      |     type               | specs      |
+----+-----------+------------------------+------------+
|  id            | INT(11)                |            |
|  name          | VARCHAR(255)           |            |
|  slug          | VARCHAR(255)           | UNIQUE     |
+----------------+--------------+---------+------------+
post_topic:
+----+-----------+------------------------+------------+
|     field      |     type               | specs      |
+----+-----------+------------------------+------------+
|  id            | INT(11)                |            |
|  post_id       | INT(11)                |  UNIQUE    |
|  topic_id      | INT(11)                |            |
+----------------+--------------+---------+------------+
Lo que realmente nos interesa es la tabla post_topic . Esta es la tabla que maneja la relación entre publicaciones y temas. Cuando se crea una publicación bajo un tema en particular, la identificación de esa publicación ( post_id ), así como la identificación del tema ( topic_id ) bajo el cual se crea esa publicación, se insertan en la tabla post_topic . 
Establezcamos esta relación para que cuando se elimine una publicación, su entrada en la tabla post_topic también se elimine automáticamente; no quieres mantener información sobre la relación de una publicación cuando la publicación no existe, ¿verdad?
Haga clic / seleccione la tabla post_topic , luego haga clic en la pestaña de estructura de la barra de navegación PHPMyAdmin. A continuación, haga clic en Vista de relación  justo debajo de la pestaña de estructura (se puede encontrar en otro lugar dependiendo de su versión de PHPMyAdmin). Luego complete el siguiente formulario de la siguiente manera:
Consejo: El enlace + Agregar restricción se usa para agregar una nueva restricción.
ON DELETE y ON UPDATE están configurados en CASCADE y NO ACTION respectivamente, de modo que cuando se elimina una publicación o un tema, su información de relación en la tabla post_topic también se elimina automáticamente. (En la imagen cometí un error al establecer ON UPDATE en CASCADE en lugar de NO ACTION, lo siento).
Haga clic en guardar y listo. Las tablas ahora están relacionadas. Sin embargo, para establecer una relación entre mensajes y temas, necesitamos poblar el temas mesa con temas y, finalmente, la post_topic mesa, que es la información actual relación.
Ahora insertemos algunas entradas en las dos tablas:
temas:
INSERT INTO `topics` (`id`, `name`, `slug`) VALUES
(1, 'Inspiration', 'inspiration'),
(2, 'Motivation', 'motivation'),
(3, 'Diary', 'diary')
post_topic:
INSERT INTO `post_topic` (`id`, `post_id`, `topic_id`) VALUES
(1, 1, 1),
(2, 2, 2)
La relación definida en la  tabla post_topic dice que el tema con id 1 en la tabla de temas pertenece a la publicación con id 1  en la tabla de posts . Lo mismo es cierto para el tema con id 2 y publicar con id 2 .
En cada publicación de la lista en la página index.php , vamos a mostrar el tema bajo el cual se crea la publicación. 
Para hacer esto, tenemos que modificar nuestros getPublishedPosts () que creamos dentro de public_functions.php para consultar el tema de cada publicación de la base de datos y devolver la publicación junto con su tema. 
Modifique el archivo public_functions.php para que se vea así:
<?php 
/* * * * * * * * * * * * * * *
* Returns all published posts
* * * * * * * * * * * * * * */
function getPublishedPosts() {
 // use global $conn object in function
 global $conn;
 $sql = "SELECT * FROM posts WHERE published=true";
 $result = mysqli_query($conn, $sql);
 // fetch all posts as an associative array called $posts
 $posts = mysqli_fetch_all($result, MYSQLI_ASSOC);

 $final_posts = array();
 foreach ($posts as $post) {
  $post['topic'] = getPostTopic($post['id']); 
  array_push($final_posts, $post);
 }
 return $final_posts;
}
/* * * * * * * * * * * * * * *
* Receives a post id and
* Returns topic of the post
* * * * * * * * * * * * * * */
function getPostTopic($post_id){
 global $conn;
 $sql = "SELECT * FROM topics WHERE id=
   (SELECT topic_id FROM post_topic WHERE post_id=$post_id) LIMIT 1";
 $result = mysqli_query($conn, $sql);
 $topic = mysqli_fetch_assoc($result);
 return $topic;
}
?>
Ahora ve al archivo index.php . Dentro del bucle foreach, directamente debajo de la etiqueta de imagen <img /> , agregue la instrucción if para mostrar el tema. Su bucle foreach debería verse así después de modificar:
<?php foreach ($posts as $post): ?>
 <div class="post" style="margin-left: 0px;">
  <img src="<?php echo BASE_URL . '/static/images/' . $post['image']; ?>" class="post_image" alt="">
        <!-- Added this if statement... -->
  <?php if (isset($post['topic']['name'])): ?>
   <a 
    href="<?php echo BASE_URL . 'filtered_posts.php?topic=' . $post['topic']['id'] ?>"
    class="btn category">
    <?php echo $post['topic']['name'] ?>
   </a>
  <?php endif ?>

  <a href="single_post.php?post-slug=<?php echo $post['slug']; ?>">
   <div class="post_info">
    <h3><?php echo $post['title'] ?></h3>
    <div class="info">
     <span><?php echo date("F j, Y ", strtotime($post["created_at"])); ?></span>
     <span class="read_more">Read more...</span>
    </div>
   </div>
  </a>
 </div>
<?php endforeach ?>
Ahora vuelva a cargar la página y verá el tema que se muestra en la publicación.
Dentro de este bucle foreach, observa que hay dos enlaces que cuando se hace clic, le llevará a dos páginas: filtered_posts.php y single_post.php . 
filter_posts.php es una página que enumera todas las publicaciones bajo un tema en particular cuando el usuario hace clic en ese tema.
single_post.php es una página que muestra la publicación completa en detalle junto con los comentarios cuando el usuario hace clic en la miniatura de la publicación.
Estos dos archivos necesitan algunas funciones de nuestro archivo public_functions.php . filter_posts.php necesita dos funciones llamadas  getPublishedPostsByTopic ()  y  getTopicNameById ()  mientras single_posts.php necesita getPost () y getAllTopics () .
Comencemos con el archivo filter_posts.php . Abra public_functions.php y agregue estas dos funciones a la lista de funciones:
/* * * * * * * * * * * * * * * *
* Returns all posts under a topic
* * * * * * * * * * * * * * * * */
function getPublishedPostsByTopic($topic_id) {
 global $conn;
 $sql = "SELECT * FROM posts ps 
   WHERE ps.id IN 
   (SELECT pt.post_id FROM post_topic pt 
    WHERE pt.topic_id=$topic_id GROUP BY pt.post_id 
    HAVING COUNT(1) = 1)";
 $result = mysqli_query($conn, $sql);
 // fetch all posts as an associative array called $posts
 $posts = mysqli_fetch_all($result, MYSQLI_ASSOC);

 $final_posts = array();
 foreach ($posts as $post) {
  $post['topic'] = getPostTopic($post['id']); 
  array_push($final_posts, $post);
 }
 return $final_posts;
}
/* * * * * * * * * * * * * * * *
* Returns topic name by topic id
* * * * * * * * * * * * * * * * */
function getTopicNameById($id)
{
 global $conn;
 $sql = "SELECT name FROM topics WHERE id=$id";
 $result = mysqli_query($conn, $sql);
 $topic = mysqli_fetch_assoc($result);
 return $topic['name'];
}
Primero creemos el archivo filter_posts.php en la carpeta raíz de nuestra aplicación (es decir, complete- blog- php /filtered_posts.php ). Continuaré y pegaré el código completo de esta página dentro del archivo:
filter_posts.php :
<?php include('config.php'); ?>
<?php include('includes/public_functions.php'); ?>
<?php include('includes/head_section.php'); ?>
<?php 
 // Get posts under a particular topic
 if (isset($_GET['topic'])) {
  $topic_id = $_GET['topic'];
  $posts = getPublishedPostsByTopic($topic_id);
 }
?>
 <title>LifeBlog | Home </title>
</head>
<body>
<div class="container">
<!-- Navbar -->
 <?php include( ROOT_PATH . '/includes/navbar.php'); ?>
<!-- // Navbar -->
<!-- content -->
<div class="content">
 <h2 class="content-title">
  Articles on <u><?php echo getTopicNameById($topic_id); ?></u>
 </h2>
 <hr>
 <?php foreach ($posts as $post): ?>
  <div class="post" style="margin-left: 0px;">
   <img src="<?php echo BASE_URL . '/static/images/' . $post['image']; ?>" class="post_image" alt="">
   <a href="single_post.php?post-slug=<?php echo $post['slug']; ?>">
    <div class="post_info">
     <h3><?php echo $post['title'] ?></h3>
     <div class="info">
      <span><?php echo date("F j, Y ", strtotime($post["created_at"])); ?></span>
      <span class="read_more">Read more...</span>
     </div>
    </div>
   </a>
  </div>
 <?php endforeach ?>
</div>
<!-- // content -->
</div>
<!-- // container -->

<!-- Footer -->
 <?php include( ROOT_PATH . '/includes/footer.php'); ?>
<!-- // Footer -->
Ahora actualice la página, haga clic en el tema y si lo lleva a una página que muestra publicaciones debajo de ese tema, entonces está haciendo lo correcto.
Hagamos lo mismo con single_post.php . Abra public_functions.php y agregue estas 2 funciones:
/* * * * * * * * * * * * * * *
* Returns a single post
* * * * * * * * * * * * * * */
function getPost($slug){
 global $conn;
 // Get single post slug
 $post_slug = $_GET['post-slug'];
 $sql = "SELECT * FROM posts WHERE slug='$post_slug' AND published=true";
 $result = mysqli_query($conn, $sql);

 // fetch query results as associative array.
 $post = mysqli_fetch_assoc($result);
 if ($post) {
  // get the topic to which this post belongs
  $post['topic'] = getPostTopic($post['id']);
 }
 return $post;
}
/* * * * * * * * * * * *
*  Returns all topics
* * * * * * * * * * * * */
function getAllTopics()
{
 global $conn;
 $sql = "SELECT * FROM topics";
 $result = mysqli_query($conn, $sql);
 $topics = mysqli_fetch_all($result, MYSQLI_ASSOC);
 return $topics;
}
Ahora cree el archivo complete- blog- php /single_post.php  y pegue este código en él:
<?php  include('config.php'); ?>
<?php  include('includes/public_functions.php'); ?>
<?php 
 if (isset($_GET['post-slug'])) {
  $post = getPost($_GET['post-slug']);
 }
 $topics = getAllTopics();
?>
<?php include('includes/head_section.php'); ?>
<title> <?php echo $post['title'] ?> | LifeBlog</title>
</head>
<body>
<div class="container">
 <!-- Navbar -->
  <?php include( ROOT_PATH . '/includes/navbar.php'); ?>
 <!-- // Navbar -->
 
 <div class="content" >
  <!-- Page wrapper -->
  <div class="post-wrapper">
   <!-- full post div -->
   <div class="full-post-div">
   <?php if ($post['published'] == false): ?>
    <h2 class="post-title">Sorry... This post has not been published</h2>
   <?php else: ?>
    <h2 class="post-title"><?php echo $post['title']; ?></h2>
    <div class="post-body-div">
     <?php echo html_entity_decode($post['body']); ?>
    </div>
   <?php endif ?>
   </div>
   <!-- // full post div -->
   
   <!-- comments section -->
   <!--  coming soon ...  -->
  </div>
  <!-- // Page wrapper -->

  <!-- post sidebar -->
  <div class="post-sidebar">
   <div class="card">
    <div class="card-header">
     <h2>Topics</h2>
    </div>
    <div class="card-content">
     <?php foreach ($topics as $topic): ?>
      <a 
       href="<?php echo BASE_URL . 'filtered_posts.php?topic=' . $topic['id'] ?>">
       <?php echo $topic['name']; ?>
      </a> 
     <?php endforeach ?>
    </div>
   </div>
  </div>
  <!-- // post sidebar -->
 </div>
</div>
<!-- // content -->

<?php include( ROOT_PATH . '/includes/footer.php'); ?>
Ahora apliquemos estilo a esto. Abra public_styling.css y agregue este código de estilo:
/* * * * * * * * *
* SINGLE PAGE 
* * * * * * * * */
.content .post-wrapper {
 width: 70%;
 float: left;
 min-height: 250px;
}
.full-post-div {
 min-height: 300px;
 padding: 20px;
 border: 1px solid #e4e1e1;
 border-radius: 2px;
}
.full-post-div h2.post-title {
 margin: 10px auto 20px;
 text-align: center;
}
.post-body-div {
 font-family: 'Noto Serif', serif;
 font-size: 1.2em;
}
.post-body-div p {
 margin:20px 0px;
}
.post-sidebar {
 width: 24%;
 float: left;
 margin-left: 5px;
 min-height: 400px;
}
.content .post-comments {
 margin-top: 25px;
 border-radius: 2px;
 border-top: 1px solid #e4e1e1;
 padding: 10px;
}
.post-sidebar .card {
 width: 95%;
 margin: 10px auto;
 border: 1px solid #e4e1e1;
 border-radius: 10px 10px 0px 0px;
}
.post-sidebar .card .card-header {
 padding: 10px;
 text-align: center;
 border-radius: 3px 3px 0px 0px;
 background: #3E606F;
}
.post-sidebar .card .card-header h2 {
 color: white;
}
.post-sidebar .card .card-content a {
 display: block;
 box-sizing: border-box;
 padding: 8px 10px;
 border-bottom: 1px solid #e4e1e1;
 color: #444;
}
.post-sidebar .card .card-content a:hover {
 padding-left: 20px;
 background: #F9F9F9;
 transition: 0.1s;
}
Se ve bien ahora ¿verdad?
Una última cosa que hacer y habremos terminado con el área pública: implementaremos el registro de usuario y el inicio de sesión. 

Registro de usuario e inicio de sesión

Debido a que ya hice  un tutorial sobre el registro y el inicio de sesión de los usuarios , estaré al punto con esta parte y no explicaré mucho.
Cree dos archivos en su carpeta raíz llamada register.php y login.php . Abra cada uno de ellos y coloque este código en ellos:
register.php:
<?php  include('config.php'); ?>
<!-- Source code for handling registration and login -->
<?php  include('includes/registration_login.php'); ?>

<?php include('includes/head_section.php'); ?>

<title>LifeBlog | Sign up </title>
</head>
<body>
<div class="container">
 <!-- Navbar -->
  <?php include( ROOT_PATH . '/includes/navbar.php'); ?>
 <!-- // Navbar -->

 <div style="width: 40%; margin: 20px auto;">
  <form method="post" action="register.php" >
   <h2>Register on LifeBlog</h2>
   <?php include(ROOT_PATH . '/includes/errors.php') ?>
   <input  type="text" name="username" value="<?php echo $username; ?>"  placeholder="Username">
   <input type="email" name="email" value="<?php echo $email ?>" placeholder="Email">
   <input type="password" name="password_1" placeholder="Password">
   <input type="password" name="password_2" placeholder="Password confirmation">
   <button type="submit" class="btn" name="reg_user">Register</button>
   <p>
    Already a member? <a href="login.php">Sign in</a>
   </p>
  </form>
 </div>
</div>
<!-- // container -->
<!-- Footer -->
 <?php include( ROOT_PATH . '/includes/footer.php'); ?>
<!-- // Footer -->
login.php:  
<?php  include('config.php'); ?>
<?php  include('includes/registration_login.php'); ?>
<?php  include('includes/head_section.php'); ?>
 <title>LifeBlog | Sign in </title>
</head>
<body>
<div class="container">
 <!-- Navbar -->
 <?php include( ROOT_PATH . '/includes/navbar.php'); ?>
 <!-- // Navbar -->

 <div style="width: 40%; margin: 20px auto;">
  <form method="post" action="login.php" >
   <h2>Login</h2>
   <?php include(ROOT_PATH . '/includes/errors.php') ?>
   <input type="text" name="username" value="<?php echo $username; ?>" value="" placeholder="Username">
   <input type="password" name="password" placeholder="Password">
   <button type="submit" class="btn" name="login_btn">Login</button>
   <p>
    Not yet a member? <a href="register.php">Sign up</a>
   </p>
  </form>
 </div>
</div>
<!-- // container -->

<!-- Footer -->
 <?php include( ROOT_PATH . '/includes/footer.php'); ?>
<!-- // Footer -->
En las secciones superiores de ambos archivos, incluimos un archivo llamado  registration_login.php  para manejar la lógica de registro e inicio de sesión. Este es el archivo al que se enviará la información del formulario de inicio de sesión y registro y se realizará la comunicación con la base de datos. Vamos a crearlo en nuestra  carpeta incluye y escupir este código dentro de él:
complete-blog- php /includes/registration_login.php:
<?php 
 // variable declaration
 $username = "";
 $email    = "";
 $errors = array(); 

 // REGISTER USER
 if (isset($_POST['reg_user'])) {
  // receive all input values from the form
  $username = esc($_POST['username']);
  $email = esc($_POST['email']);
  $password_1 = esc($_POST['password_1']);
  $password_2 = esc($_POST['password_2']);

  // form validation: ensure that the form is correctly filled
  if (empty($username)) {  array_push($errors, "Uhmm...We gonna need your username"); }
  if (empty($email)) { array_push($errors, "Oops.. Email is missing"); }
  if (empty($password_1)) { array_push($errors, "uh-oh you forgot the password"); }
  if ($password_1 != $password_2) { array_push($errors, "The two passwords do not match");}

  // Ensure that no user is registered twice. 
  // the email and usernames should be unique
  $user_check_query = "SELECT * FROM users WHERE username='$username' 
        OR email='$email' LIMIT 1";

  $result = mysqli_query($conn, $user_check_query);
  $user = mysqli_fetch_assoc($result);

  if ($user) { // if user exists
   if ($user['username'] === $username) {
     array_push($errors, "Username already exists");
   }
   if ($user['email'] === $email) {
     array_push($errors, "Email already exists");
   }
  }
  // register user if there are no errors in the form
  if (count($errors) == 0) {
   $password = md5($password_1);//encrypt the password before saving in the database
   $query = "INSERT INTO users (username, email, password, created_at, updated_at) 
       VALUES('$username', '$email', '$password', now(), now())";
   mysqli_query($conn, $query);

   // get id of created user
   $reg_user_id = mysqli_insert_id($conn); 

   // put logged in user into session array
   $_SESSION['user'] = getUserById($reg_user_id);

   // if user is admin, redirect to admin area
   if ( in_array($_SESSION['user']['role'], ["Admin", "Author"])) {
    $_SESSION['message'] = "You are now logged in";
    // redirect to admin area
    header('location: ' . BASE_URL . 'admin/dashboard.php');
    exit(0);
   } else {
    $_SESSION['message'] = "You are now logged in";
    // redirect to public area
    header('location: index.php');    
    exit(0);
   }
  }
 }

 // LOG USER IN
 if (isset($_POST['login_btn'])) {
  $username = esc($_POST['username']);
  $password = esc($_POST['password']);

  if (empty($username)) { array_push($errors, "Username required"); }
  if (empty($password)) { array_push($errors, "Password required"); }
  if (empty($errors)) {
   $password = md5($password); // encrypt password
   $sql = "SELECT * FROM users WHERE username='$username' and password='$password' LIMIT 1";

   $result = mysqli_query($conn, $sql);
   if (mysqli_num_rows($result) > 0) {
    // get id of created user
    $reg_user_id = mysqli_fetch_assoc($result)['id']; 

    // put logged in user into session array
    $_SESSION['user'] = getUserById($reg_user_id); 

    // if user is admin, redirect to admin area
    if ( in_array($_SESSION['user']['role'], ["Admin", "Author"])) {
     $_SESSION['message'] = "You are now logged in";
     // redirect to admin area
     header('location: ' . BASE_URL . '/admin/dashboard.php');
     exit(0);
    } else {
     $_SESSION['message'] = "You are now logged in";
     // redirect to public area
     header('location: index.php');    
     exit(0);
    }
   } else {
    array_push($errors, 'Wrong credentials');
   }
  }
 }
 // escape value from form
 function esc(String $value)
 { 
  // bring the global db connect object into function
  global $conn;

  $val = trim($value); // remove empty space sorrounding string
  $val = mysqli_real_escape_string($conn, $value);

  return $val;
 }
 // Get user info from user id
 function getUserById($id)
 {
  global $conn;
  $sql = "SELECT * FROM users WHERE id=$id LIMIT 1";

  $result = mysqli_query($conn, $sql);
  $user = mysqli_fetch_assoc($result);

  // returns user in an array format: 
  // ['id'=>1 'username' => 'Awa', 'email'=>'a@a.com', 'password'=> 'mypass']
  return $user; 
 }
?>
Vaya a  y verá un error que indica que no se encontró el archivo errors.php . http : // localhost complete blog php register php
El archivo errors.php es el archivo con código para mostrar errores de validación de formularios. Crea errors.php dentro de complete-blog- php / includes  y pega este código en él:
<?php if (count($errors) > 0) : ?>
  <div class="message error validation_errors" >
   <?php foreach ($errors as $error) : ?>
     <p><?php echo $error ?></p>
   <?php endforeach ?>
  </div>
<?php endif ?>
Una vez más, abra public_styling.css agreguemos este último código de estilo para este archivo errors.php y algunos otros elementos:
/* NOTIFICATION MESSAGES */
.message {
 width: 100%; 
 margin: 0px auto; 
 padding: 10px 0px; 
 color: #3c763d; 
 background: #dff0d8; 
 border: 1px solid #3c763d;
 border-radius: 5px; 
 text-align: center;
}
.error {
 color: #a94442; 
 background: #f2dede; 
 border: 1px solid #a94442; 
 margin-bottom: 20px;
}
.validation_errors p {
 text-align: left;
 margin-left: 10px;
}
.logged_in_info {
 text-align: right; 
 padding: 10px;
}
Y ahora el mensaje de error se ha ido. Haga clic en el botón de registro sin completar el formulario y verá hermosos mensajes de error. 
Creemos un nuevo usuario rellenando el formulario en la página register.php y haciendo clic en el botón de registro. Puede proporcionar cualquier información válida para el nombre de usuario, correo electrónico y contraseña; solo asegúrese de recordarlos porque los usaremos para iniciar sesión muy pronto en la página de inicio de sesión.
Cuando un usuario inicia sesión, definitivamente necesitará poder cerrar sesión. En la carpeta raíz de la aplicación, cree un archivo llamado logout.php. 
complete-blog-php / logout.php: 
<?php 
 session_start();
 session_unset($_SESSION['user']);
 session_destroy();
 header('location: index.php');
?>
Además, cuando un usuario inicia sesión, queremos mostrar su nombre y un enlace o botón para que hagan clic para cerrar sesión. Para el área pública, lo haremos en el archivo banner.php que incluimos. Abra el archivo banner.php y modifique el código para que se vea así:
complete-blog-php / incluye / banner.php:
<?php if (isset($_SESSION['user']['username'])) { ?>
 <div class="logged_in_info">
  <span>welcome <?php echo $_SESSION['user']['username'] ?></span>
  |
  <span><a href="logout.php">logout</a></span>
 </div>
<?php }else{ ?>
 <div class="banner">
  <div class="welcome_msg">
   <h1>Today's Inspiration</h1>
   <p> 
       One day your life <br> 
       will flash before your eyes. <br> 
       Make sure it's worth watching. <br>
    <span>~ Gerard Way</span>
   </p>
   <a href="register.php" class="btn">Join us!</a>
  </div>

  <div class="login_div">
   <form action="<?php echo BASE_URL . 'index.php'; ?>" method="post" >
    <h2>Login</h2>
    <div style="width: 60%; margin: 0px auto;">
     <?php include(ROOT_PATH . '/includes/errors.php') ?>
    </div>
    <input type="text" name="username" value="<?php echo $username; ?>" placeholder="Username">
    <input type="password" name="password"  placeholder="Password"> 
    <button class="btn" type="submit" name="login_btn">Sign in</button>
   </form>
  </div>
 </div>
<?php } ?>
Comprueba la sesión para ver si hay un usuario disponible (conectado). Si inició sesión, el nombre de usuario se muestra con el enlace de cierre de sesión. Cuando hay un usuario conectado, el banner no se muestra ya que es una especie de pantalla de bienvenida para los usuarios invitados.
Observa que el banner tiene un formulario de inicio de sesión y este banner está incluido dentro del archivo index.php . Por lo tanto, debemos incluir el código que maneja el registro y el inicio de sesión dentro de nuestro archivo index.php también. Abra index.php y agregue esta línea directamente debajo de include para public_functions.php:
sección superior de complete- blog- php /index.php:
<?php require_once( ROOT_PATH . '/includes/registration_login.php') ?>
Y eso es todo con el registro de usuario y el inicio de sesión. En la siguiente sección, comenzamos a trabajar en el área de administración.
Muchas gracias por quedarse hasta este punto. Espero que lo haya encontrado util. Si tiene alguna preocupación, déjela en los comentarios a continuación. Sus comentarios siempre son muy útiles y si tiene algún error en su código, haré todo lo posible para ayudarlo.
Me alegrará mucho crear más de estos tutoriales con una calidad mejorada si comparte, se suscribe a mi sitio y lo recomienda a sus amigos.

No hay comentarios.:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

outbrain

Páginas