Post Top Ad

Your Ad Spot

jueves, 7 de mayo de 2020

Si está creando cualquier aplicación web que implique crear, leer, actualizar y eliminar información de cualquier tipo, será muy común que los privilegios para realizar estas diferentes operaciones en los datos se compartan entre sus usuarios de acuerdo con sus diferentes roles. y permisos en su solicitud. Tome una aplicación de gestión escolar, por ejemplo. Los usuarios de dicha aplicación generalmente caen dentro de las categorías: estudiantes, maestros, jefes de departamento (HOD), etc. Su solicitud NO debe permitir que un estudiante tenga el privilegio de agregar o actualizar sus resultados para los exámenes semestrales. Esa sería la función de un maestro. Y cuando se va a agregar un nuevo curso o materia al plan de estudios, es solo el trabajo del Jefe de Departamento agregar ese curso en el sistema. En dicho sistema, podemos referirnos a Estudiante, Maestro, HOD (Jefe de Departamento) como los diferentes roles en nuestra aplicación. En cuanto a acciones como agregar y actualizar los resultados de los estudiantes, agregar nuevos cursos, nos referiremos a estos como los permisos . A partir de la explicación hasta ahora, ya se puede deducir que un usuario tendrá un rol y un rol tendrá múltiples permisos. Por ejemplo, John (un usuario) tendrá un rol (Estudiante) y múltiples permisos (registrar curso, ver marcas, imprimir transcripción, etc.). Esto significa que en nuestra base de datos MySQL necesitaremos 3 tablas principales de la base de datos: usuarios , roles y permisos . Se requiere que tengamos una relación de Muchos a Uno entre los usuarios y las tablas de la base de datos de roles (Un rol pertenece a Muchos usuarios) y una relación de Muchos a Muchos entre los roles y las tablas de permisos (Se pueden asignar muchos permisos a Muchos roles) . La forma en que se refiere a estos roles depende de usted. En nuestro ejemplo, hemos estado usando Estudiante, Maestro, HOD para representar los roles porque el ejemplo era sobre una aplicación de gestión escolar. Si estaba trabajando en una aplicación de gestión hotelera, los roles pueden ser algo como Gerente, Limpiador, Recepcionista y similares. En este tutorial, estamos creando un sistema de administración de cuentas de usuario para una aplicación de blog. Por lo tanto, nos referiremos a estos roles como Autor, Editor y Administrador. Por supuesto, puede cambiarlos a su gusto, pero estos tres son casi un estándar para los sistemas de gestión de contenido. Se implementará un sistema completo de registro e inicio de sesión de administrador / usuario. Todos los usuarios iniciarán sesión a través del mismo formulario de inicio de sesión y una vez que inicien sesión, solo los usuarios administrativos (Autores, Editores, Administradores) tendrán acceso al panel de administración mientras que los usuarios normales serán redirigidos a la página de inicio pública. Crearemos una tabla de base de datos de publicaciones en nuestra base de datos para tener algo para probar nuestros permisos. Por ejemplo, un usuario con el rol de Editor podrá editar, actualizar, publicar, anular la publicación y eliminar todas y cada una de las publicaciones, mientras que un Autor solo tendrá permiso para crear, leer, actualizar y eliminar solo aquellas publicaciones que hayan sido publicadas. creado por ellos mismos. El administrador tendrá permiso para crear, actualizar, eliminar otros usuarios y roles administrativos y también para asignar / desasignar permisos a roles y roles a usuarios. NOTA: Ya hice un tutorial sobre cómo crear una aplicación de blog completa desde cero . Por lo tanto, no implementaremos realmente la creación, eliminación y actualización de publicaciones aquí. Solo demostraremos cómo funcionan estos permisos en torno a las publicaciones. Si desea aprender cómo crear un blog con publicaciones, consulte mi otro tutorial sobre cómo crear un blog en PHP. En caso de que vuelva a visitar, este tutorial se ha actualizado. ¡Disfrutar! Estructura del directorio de proyectos. Cree una carpeta de proyecto llamada cuentas de usuario y luego cree otras tres carpetas dentro de ella: admin , incluye , activos , cada una con las siguientes subcarpetas: admin : esta carpeta contiene el código fuente de la parte admin de la aplicación. En esta carpeta, cree otras tres carpetas, a saber, publicaciones , roles , usuarios . activos : contendrá archivos públicos a los que accederá el navegador, como imágenes, css, js. Entonces, dentro de los activos, cree imágenes , carpetas css y js . incluye : Esto contendrá parches de código fuente para nuestra aplicación que podemos incluir en diferentes lugares de nuestra aplicación. Dentro de esta carpeta, cree otras dos carpetas: diseños y lógica . En este punto, nuestra estructura de proyecto está lista. Ahora podemos comenzar a codificar el sistema. Lo haremos en la siguiente parte de este tutorial. Gracias por su atención y espero verte en la próxima parte .

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 opta por 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 . 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. Creemos que en nuestro incluye  carpeta y escupir este código en su interior:
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