Skip to content
Snippets Groups Projects
Commit 5d5ba959 authored by Rajesh  D's avatar Rajesh D :speech_balloon:
Browse files

Updated Blog With Image Upload And Many Features

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 2569 additions and 0 deletions
<?php
define('ROOT','https://blog.zeal.wtf');
define('APP_NAME',"My Blog");
<?php
function query(string $query,array $data=[]) // $data can be empty that's why the array was empty
{
try {
$string = "mysql:host=" . DBHOST . ";dbname=" . DBNAME;
$con = new PDO($string, DBUSER, DBPASS);
// echo "Connected successfully";
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
// echo $query;
// echo $data;
$stm=$con->prepare($query);
$stm->execute($data);
$result=$stm->fetchAll(PDO::FETCH_ASSOC); // :: is used to provide values rather than providing in query , it prevents sql injection
if(is_array($result) && !empty($result)){
return $result;
}
return false;
}
function query_row(string $query,array $data=[]) // $data can be empty that's why the array was empty
{
try {
$string = "mysql:host=" . DBHOST . ";dbname=" . DBNAME;
$con = new PDO($string, DBUSER, DBPASS);
// echo "Connected successfully";
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
// echo $query;
// echo $data;
$stm=$con->prepare($query);
$stm->execute($data);
$result=$stm->fetchAll(PDO::FETCH_ASSOC); // :: is used to provide values rather than providing in query , it prevents sql injection
if(is_array($result) && !empty($result)){
return $result[0];
}
return false;
}
function str_to_url($url){
$url = str_replace("'","",$url);
$url = preg_replace('~[^\\pL0-9]+~u', '-', $url);
$url = trim($url, "-");
$url = iconv("utf-8", "us-ascii//TRANSLIT", $url);
$url = strtolower($url);
$url = preg_replace('~[^-a-z0-9_]+~', '', $url);
return $url;
}
function get_pagination_vars()
{
/** set pagination vars */
$page_number = $_GET['page'] ?? 1;
$page_number = empty($page_number) ? 1 : (int)$page_number;
$page_number = $page_number < 1 ? 1 : $page_number;
$current_link = $_GET['url'] ?? 'home';
$current_link = ROOT . '/' . $current_link;
$query_string = "";
foreach ($_GET as $key => $value) {
if ($key != 'url') {
$query_string .= "&".$key."=".$value;
}
}
if(!strstr($query_string, 'page=')){
$query_string .= "&page=". $page_number;
}
$query_string = trim($query_string, "&");
$current_link .= "?" . $query_string;
$current_link = preg_replace("/page=.*/", "page=".$page_number, $current_link);
$next_link = preg_replace("/page=.*/", "page=".($page_number + 1), $current_link);
$first_link = preg_replace("/page=.*/", "page=1", $current_link);
$prev_page_number = $page_number < 2 ? 1 : $page_number - 1;
$prev_link = preg_replace("/page=.*/", "page=".$prev_page_number, $current_link);
// echo $current_link;
// echo $next_link;
// echo $prev_link;
// echo $first_link;
$result = [
'current_link' => $current_link,
'next_link' => $next_link,
'prev_link' => $prev_link,
'first_link' => $first_link,
'page_number' => $page_number
];
return $result;
}
function authenticate(array $row)
{
$_SESSION['USER']=$row[0];
$_SESSION['user_id']=$row[0]['id'];
}
function user($key){
if(empty($key)){
return $_SESSION['USER'];
}
if(isset($_SESSION['USER'])){
return $_SESSION['USER'][$key];
}
return '';
}
function logged_in()
{
return isset($_SESSION['USER']);
}
function redirect(string $page)
{
header('Location: ' .$page);
die;
}
function oldvalue($key,$default='')
{
if(isset($_POST[$key])){
echo $_POST[$key];
}
else{
echo $default;
}
}
function old_checked($key,$default='')
{
if(isset($_POST[$key])){
echo 'checked';
}
return '';
}
function get_image($image)
{
if($image){
return $image;
}
return '/uploads/default.jpg';
}
function esc(string $string)
{
return htmlspecialchars($string ?? '');
}
//phpinfo();
function find($table, $id = null, $column = '*')
{
$st = "";
if (!empty($id)) {
$st = "id = '".intval($id)."' AND "; // Secure ID usage
}
$query = "SELECT $column FROM $table WHERE {$st}active = 1 LIMIT 1";
$result = query($query);
if ($result) {
return $result[0][$column] ?? ''; // Safe array access
}
return '';
}
function resize_image($filename, $max_size = 1000)
{
if (!file_exists($filename)) {
return false;
}
$type = mime_content_type($filename);
switch ($type) {
case 'image/jpeg':
$image = imagecreatefromjpeg($filename);
break;
case 'image/png':
$image = imagecreatefrompng($filename);
break;
case 'image/gif':
$image = imagecreatefromgif($filename);
break;
case 'image/webp':
$image = imagecreatefromwebp($filename);
break;
default:
return false; // Unsupported file type
}
if (!$image) {
return false; // Failed to create image
}
// Get original dimensions
$src_width = imagesx($image);
$src_height = imagesy($image);
// Calculate new dimensions
if ($src_width > $src_height) {
$new_width = min($max_size, $src_width);
$new_height = round(($src_height / $src_width) * $new_width);
} else {
$new_height = min($max_size, $src_height);
$new_width = round(($src_width / $src_height) * $new_height);
}
// Create a new resized image
$new_image = imagecreatetruecolor($new_width, $new_height);
// Preserve transparency for PNG & GIF
if ($type === 'image/png' || $type === 'image/gif') {
imagecolortransparent($new_image, imagecolorallocatealpha($new_image, 0, 0, 0, 127));
imagealphablending($new_image, false);
imagesavealpha($new_image, true);
}
imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $src_width, $src_height);
// Save the resized image
switch ($type) {
case 'image/jpeg':
imagejpeg($new_image, $filename, 90);
break;
case 'image/png':
imagepng($new_image, $filename, 9);
break;
case 'image/gif':
imagegif($new_image, $filename);
break;
case 'image/webp':
imagewebp($new_image, $filename, 90);
break;
}
imagedestroy($image);
imagedestroy($new_image);
return true;
}
function timepicker($date){
$seconds_ago = (time() - strtotime($date));
if ($seconds_ago >= 31536000) {
$date = intval($seconds_ago / 31536000) . " years ago";
} elseif ($seconds_ago >= 2419200) {
$date = intval($seconds_ago / 2419200) . " months ago";
} elseif ($seconds_ago >= 86400) {
$date = intval($seconds_ago / 86400) . " days ago";
} elseif ($seconds_ago >= 3600) {
$date = intval($seconds_ago / 3600) . " hours ago";
} elseif ($seconds_ago >= 120) {
$date = intval($seconds_ago / 60) . " minutes ago";
} elseif ($seconds_ago >= 60) {
$date = "a minute ago";
} else {
$date = "less than a minute ago";
}
return $date;
}
\ No newline at end of file
<?php
//Loads Required Files
require "config.php";
require "../../../blog/connection.php";
require "functions.php";
This diff is collapsed.
<?php
// add new
if($action == 'add'){
if(!empty($_POST))
{
$errors=[];
$query="SELECT id FROM categories WHERE category=:category and disabled=0 limit 1";
$category=query($query,['category'=>$_POST['category']]);
if(empty($_POST['category']))
{
$errors['category']="category is required";
}
elseif($category)
{
$errors['category']="category already exists";
}
elseif(strlen($_POST['category'])<3)
{
$errors['category']="category must be atleast 3 characters long";
}
$slug = str_to_url($_POST['category']);
$query = "SELECT id FROM categories WHERE slug=:slug AND disabled=0 LIMIT 1";
$existing_slug = query($query, ['slug' => $slug]);
// Ensure $slug is a string
if (!empty($existing_slug)) {
$slug .= rand(1000, 9999);
}
if (empty($errors)) {
$data = [];
$data['category'] = $_POST['category'];
$data['slug'] = $slug;
$data['disabled'] = $_POST['disabled'];
$query = "INSERT INTO categories (category, slug, disabled) VALUES (:category, :slug, :disabled)";
query($query, $data);
redirect(ROOT . '/admin/categories');
}
}
}
elseif($action=='edit'){
if(!empty($_POST))
{
$errors=[];
$query="SELECT id FROM categories WHERE category=:category AND id!=:id and active=1";
$category=query($query,['category'=>$_POST['category'],'id'=>$_POST['id']]);
if(empty($_POST['category']))
{
$errors['category']="category is required";
}
elseif($category)
{
$errors['category']="category already exists";
}
elseif(strlen($_POST['category'])<3)
{
$errors['category']="category must be atleast 3 characters long";
}
$slug = str_to_url($_POST['category']);
$query = "SELECT id FROM categories WHERE slug=:slug AND disabled=0 LIMIT 1";
$existing_slug = query($query, ['slug' => $slug]);
// Ensure $slug is a string
if (!empty($existing_slug)) {
$slug .= rand(1000, 9999);
}
if(empty($errors))
{
$data=[];
$data['category']=$_POST['category'];
$data['slug']=$slug;
$data['disabled']=$_POST['disabled'];
$data['id']=$_POST['id'];
$query="UPDATE categories SET category=:category,slug=:slug,disabled=:disabled WHERE id=:id";
query($query,$data);
redirect(ROOT.'/admin/categories');
}
}
}
?>
\ No newline at end of file
<?php if($action == 'add'):?>
<!-- Add user form or functionality here -->
<div class="w-50 mx-auto">
<form method="POST" action="<?=ROOT?>/admin/categories/add">
<h1 class="h3 mb-3 fw-normal">Create Category</h1>
<?php
if(!empty($errors))
{
echo '<div class="alert alert-danger">';
echo '<ul>';
foreach($errors as $error)
{
echo '<li>'.$error.'</li>';
}
echo '</ul>';
echo '</div>';
}
?>
<div class="alert alert-danger d-none" id="alert">
<ul id="error-list">
</ul>
</div>
<div class="form-floating">
<input value="<?oldvalue('category')?>" type="text" name=category class="form-control" id="floatingInput" placeholder="name@example.com" required>
<label for="floatingInput">Category</label>
</div>
<div class="form-floating">
<select id="dropdown1" class="form-select mb-3" name="disabled">
<option value="0" >YES</option>
<option value="1">NO</option>
</select>
<label for="floatingInput">Active</label>
</div>
<div class="d-flex justify-content-between mt-3">
<a href="<?=ROOT?>/admin/categories" class="btn btn-secondary py-2 px-4">Back</a>
<button class="btn btn-primary py-2 px-4" type="submit">Add</button>
</div>
</form>
</div>
<?php elseif($action == 'edit'):?>
<!-- Edit user form or functionality here -->
<?php
$edit_id=$url[3] ?? '';
$query="SELECT * FROM categories where id=:id and active=1";
$user=query_row($query,['id'=>$edit_id]);
if($user){
?>
<div class="w-50 mx-auto">
<form method="POST" action="<?=ROOT?>/admin/categories/edit/<?=$user['id']?>" enctype="multipart/form-data">
<h1 class="h3 mb-3 fw-normal">Edit Category</h1>
<?php
if(!empty($errors))
{
echo '<div class="alert alert-danger">';
echo '<ul>';
foreach($errors as $error)
{
echo '<li>'.$error.'</li>';
}
echo '</ul>';
echo '</div>';
}
?>
<input type="hidden" name="id" value="<?=$user['id']?>">
<div class="alert alert-danger d-none" id="alert">
<ul id="error-list">
</ul>
</div>
<div class="form-floating">
<input value="<?=oldvalue('category',$user['category'])?>"
type="text" name="category" class="form-control" id="floatingInput"
placeholder="name@example.com" required>
<label for="floatingInput">Category</label>
</div>
<div class="form-floating">
<select id="dropdown1" class="form-select mb-3" name="disabled">
<option value=0 <?= ($user['disabled'] == 0) ? 'selected' : '' ?>>Yes</option>
<option value=1 <?= ($user['disabled'] == 1) ? 'selected' : '' ?>>No</option>
</select>
<label for="floatingInput">Active</label>
</div>
<div class="d-flex justify-content-between mt-3">
<a href="<?=ROOT?>/admin/categories" class="btn btn-secondary py-2 px-4">Back</a>
<button class="btn btn-primary py-2 px-4" type="submit">Save</button>
</div>
</form>
</div>
<?php }
else{
echo '<div class="alert alert-danger">Category not found</div>';
echo '<a href="'.ROOT.'/admin/categories" class="btn btn-primary">Back to categories</a>';
}
?>
<?php elseif($action == 'delete'):?>
<!-- Delete user functionality here -->
<?php
$delete_id=$url[3];
$query="SELECT * FROM categories where id=:id";
$user=query_row($query,['id'=>$delete_id]);
if(!$user){
echo '<div class="alert alert-danger">Category not found</div>';
echo '<a href="'.ROOT.'/admin/categories" class="btn btn-primary">Back to categories</a>';
die;
}else{
$query="UPDATE categories SET active=0 where id=:id";
$user=query($query,['id'=>$delete_id]);
?>
<div class="alert alert-success">Category deleted successfully</div>
<a href="<?=ROOT?>/admin/categories" class="btn btn-primary">Back to categories</a>
<?php
}
?>
<?php else:?>
<!-- List all categories here -->
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Category</th>
<th>Slug</th>
<th>Active</th>
<th>Action</th>
</tr>
</thead>
<?php
$limit=5;
$offset=($PAGE['page_number']-1)*$limit;
$query="SELECT * FROM categories where active=1 order by id desc limit $limit offset $offset";
$categories=query($query);
?>
<tbody>
<?php if(!empty($categories)):?>
<?php foreach ($categories as $user): ?>
<tr class="align-middle">
<td><?=$user['id']?></td>
<td><?=esc($user['category'])?></td>
<td><?=$user['slug']?></td>
<td>
<? if ($user['disabled'] == 0) {
echo 'Yes';
} else {
echo 'No';
}
?>
</td>
<td>
<a href="<?=ROOT?>/admin/categories/edit/<?=$user['id']?>" class="btn btn-primary"><i class="bi bi-pencil-square"></i></a>
<a data-bs-toggle="modal" data-bs-target="#deleteModal" class="btn btn-danger"><i class="bi bi-trash"></i></a>
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteModalLabel">Confirm Deletion</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-center">
<p>Do you want to delete this Category?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<a href="<?=ROOT?>/admin/categories/delete/<?=$user['id']?>" class="btn btn-danger">Delete</a>
</div>
</div>
</div>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<div class="col-md-12 d-flex justify-content-center gap-2 mt-3 mb-3">
<a href="<?=$PAGE['first_link']?>" class="btn btn-primary">First Page</a>
<a href="<?=$PAGE['prev_link']?>" class="btn btn-primary">Previous</a>
<a href="<?=$PAGE['next_link']?>" class="btn btn-primary">Next</a>
</div>
</div>
<?php endif;?>
<div class="container text-center">
<?php
$query='SELECT COUNT(id) AS num FROM users';
$users=query($query);
$users=$users[0]['num'];
?>
<div class="row g-4 justify-content-center mb-4">
<div class="col-md-4 col-sm-6">
<a href="<?=ROOT?>/admin/users/u" class="text-decoration-none">
<div class="h-100 p-5 text-bg-dark border rounded-3 btn-outline-light category-card">
<h2 class="text-white">Total Signups</h2>
<p class="btn btn-outline-light">Total: <?=$users?></p>
</div>
</a>
</div>
<div class="col-md-4 col-sm-6">
<?php
$active = find('users','','count(id)');
?>
<a href="<?=ROOT?>/admin/users" class="text-decoration-none">
<div class="h-100 p-5 text-bg-dark border rounded-3 btn-outline-light category-card">
<h2 class="text-white">Active Users</h2>
<p class="btn btn-outline-light">Total: <?=$active?></p>
</div>
</a>
</div>
<div class="col-md-4 col-sm-6">
<?php
$query='SELECT COUNT(id) AS adm FROM users WHERE role="admin"';
$admin=query($query);
$admin=$admin[0]['adm'];
?>
<a href="<?=ROOT?>/admin/users/a" class="text-decoration-none">
<div class="h-100 p-5 text-bg-dark border rounded-3 btn-outline-light category-card">
<h2 class="text-white">Admins</h2>
<p class="btn btn-outline-light">Total: <?=$admin?></p>
</div>
</a>
</div>
<div class="col-md-4 col-sm-6">
<?php
$posts = find('posts','','count(id)');
?>
<a href="<?=ROOT?>/admin/posts" class="text-decoration-none">
<div class="h-100 p-5 text-bg-dark border rounded-3 btn-outline-light category-card">
<h2 class="text-white">Posts</h2>
<p class="btn btn-outline-light">Total: <?=$posts?></p>
</div>
</a>
</div>
<div class="col-md-4 col-sm-6">
<?php
$categories = find('categories','','count(id)');
?>
<a href="<?=ROOT?>/admin/categories" class="text-decoration-none">
<div class="h-100 p-5 text-bg-dark border rounded-3 btn-outline-light category-card">
<h2 class="text-white">Categories</h2>
<p class="btn btn-outline-light">Total: <?=$categories?></p>
</div>
</a>
</div>
</div>
</div>
<style>
.category-card {
transition: background-color 0.3s ease-in-out;
}
.category-card:hover {
background-color: #343a40 !important; /* Darker shade */
}
</style>
\ No newline at end of file
<?php
// add new
if($action == 'add'){
if(!empty($_POST))
{
$errors=[];
if(empty($_POST['title']))
{
$errors['title']="title is required";
}
elseif(strlen($_POST['title'])<3)
{
$errors['title']="title must be atleast 3 characters long";
}
if(empty($_POST['category_id']))
{
$errors['category_id']="category is required";
}
if(empty($_POST['content']))
{
$errors['content']="content is required";
}
//validate Image
$allowed = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Check if a cropped image is sent via POST
if (!empty($_POST['cropped_image'])) {
$croppedImageData = $_POST['cropped_image'];
// Remove base64 prefix
$croppedImageData = str_replace("data:image/jpeg;base64,", "", $croppedImageData);
$croppedImageData = base64_decode($croppedImageData);
// Set upload directory
$uploadDir = '/home/Iamrajesh/htdocs/blogs/public/uploads/';
$fileName = time() . '.jpg'; // Save as a JPEG file
$destination = $uploadDir . $fileName;
$savePath = '/uploads/' . $fileName;
// Save the cropped image
if (file_put_contents($destination, $croppedImageData)) {
// echo "Image uploaded successfully Cropper : " . $savePath;
resize_image($destination);
} else {
$errors['image'] = 'Error saving cropped image.';
}
}
// Handle file uploads (if not using Cropper.js)
elseif (!empty($_FILES['image']['name'])) {
$fileName = basename($_FILES['image']['name']);
$destination = $uploadDir . time() . $fileName;
$savePath = '/uploads/' . time() . $fileName;
// Validate file size
if ($_FILES['image']['size'] > 2000000) {
$errors['image'] = 'File size must be less than 2MB';
}
// Validate file type
elseif (!in_array($_FILES['image']['type'], $allowed)) {
$errors['image'] = 'File type is not allowed';
}
// Save & resize the image
else {
move_uploaded_file($_FILES['image']['tmp_name'], $destination);
resize_image($destination, 500, 500); // Resize to 500x500
echo "Image uploaded successfully Normal: " . $savePath;
}
} else {
$errors['image'] = 'No image uploaded.';
}
}
$slug = str_to_url($_POST['title']);
$query = "SELECT id FROM posts WHERE slug=:slug AND active=1 LIMIT 1";
$existing_slug = query($query, ['slug' => $slug]);
// Ensure $slug is a string
if (!empty($existing_slug)) {
$slug .= rand(1000, 9999);
}
if(empty($errors))
{
$data=[];
$data['category_id']=$_POST['category_id'];
$data['title']=$_POST['title'];
$data['content']=$_POST['content'];
$data['date']=date('Y-m-d H:i:s');
$data['image']=$savePath;
$data['user_id']=user('id');
$data['slug']=$slug;
$query="INSERT INTO posts(category_id,title,content,image,date,user_id,slug) VALUES(:category_id,:title,:content,:image,:date,:user_id,:slug)";
query($query,$data);
redirect(ROOT.'/admin/posts');
}
}
}
elseif($action=='edit'){
if(!empty($_POST))
{
$errors=[];
if(strlen($_POST['title'])<5)
{
$errors['title']="title must be atleast 5 characters long";
}
if(empty($_POST['category_id']))
{
$errors['category_id']="category is required";
}
if(empty($_POST['content']))
{
$errors['content']="content is required";
}
//validate Image
$allowed = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
if ($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_FILES['image']['name'])) {
// Check if a cropped image is sent via POST
if (!empty($_POST['cropped_image'])) {
$croppedImageData = $_POST['cropped_image'];
// Remove base64 prefix
$croppedImageData = str_replace("data:image/jpeg;base64,", "", $croppedImageData);
$croppedImageData = base64_decode($croppedImageData);
// Set upload directory
$uploadDir = '/home/Iamrajesh/htdocs/blogs/public/uploads/';
$fileName = time() . '.jpg'; // Save as a JPEG file
$destination = $uploadDir . $fileName;
$savePath = '/uploads/' . $fileName;
// Save the cropped image
if (file_put_contents($destination, $croppedImageData)) {
// echo "Image uploaded successfully Cropper : " . $savePath;
resize_image($destination);
} else {
$errors['image'] = 'Error saving cropped image.';
}
}
// Handle file uploads (if not using Cropper.js)
elseif (!empty($_FILES['image']['name'])) {
$fileName = basename($_FILES['image']['name']);
$destination = $uploadDir . time() . $fileName;
$savePath = '/uploads/' . time() . $fileName;
// Validate file size
if ($_FILES['image']['size'] > 2000000) {
$errors['image'] = 'File size must be less than 2MB';
}
// Validate file type
elseif (!in_array($_FILES['image']['type'], $allowed)) {
$errors['image'] = 'File type is not allowed';
}
// Save & resize the image
else {
move_uploaded_file($_FILES['image']['tmp_name'], $destination);
resize_image($destination, 500, 500); // Resize to 500x500
echo "Image uploaded successfully Normal: " . $savePath;
}
} else {
$errors['image'] = 'No image uploaded.';
}
}
else{
$edit_id=$url[3] ?? '';
$query="SELECT * FROM posts where id=:id and active=1";
$user=query_row($query,['id'=>$edit_id]);
$savePath=$user['image'];
}
$slug = str_to_url($_POST['title']);
$query = "SELECT id FROM posts WHERE slug=:slug AND active=1 LIMIT 1";
$existing_slug = query($query, ['slug' => $slug]);
// Ensure $slug is a string
if (!empty($existing_slug)) {
$slug .= rand(1000, 9999);
}
if(empty($errors))
{
$data=[];
$data['category_id']=$_POST['category_id'];
$data['title']=$_POST['title'];
$data['id']=$_POST['id'];
$data['slug']=$slug;
$data['image']=$savePath;
$data['content']=$_POST['content'];
$query="UPDATE posts SET category_id=:category_id,title=:title,slug=:slug,image=:image,content=:content WHERE id=:id";
query($query,$data);
redirect(ROOT.'/admin/posts');
}
}
}
?>
\ No newline at end of file
<?php if($action == 'add'):?>
<!-- Add posts form or functionality here -->
<div class="w-50 mx-auto">
<form method="POST" action="<?=ROOT?>/admin/posts/add" enctype="multipart/form-data">
<h1 class="h3 mb-3 fw-normal">Create Post</h1>
<!-- Error Messages -->
<?php if (!empty($errors)): ?>
<div class="alert alert-danger">
<ul>
<?php foreach ($errors as $error): ?>
<li><?= $error ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<div class="alert alert-danger d-none" id="alert">
<ul id="error-list"></ul>
</div>
<!-- Image Upload -->
<div class="text-center">
<label class="form-label fw-bold">Post Image</label>
<div class="mb-3">
<input type="file" name="image" id="imageUpload" class="form-control" accept="image/*">
</div>
<div class="mb-3">
<img id="previewImage"
src="<?= !empty($user['image']) ? get_image($user['image']) : '' ?>"
class="img-thumbnail rounded-circle shadow-sm"
style="width: 120px; height: 120px; object-fit: cover; <?= !empty($user['image']) ? '' : 'display: none;' ?>">
</div>
<canvas id="croppedCanvas" style="display: none;"></canvas>
</div>
<input type="hidden" name="cropped_image" id="croppedImageData">
<!-- Title -->
<div class="form-floating mt-5">
<input value="<?oldvalue('title')?>" type="text" name="title" class="form-control" id="floatingInput" placeholder="Title" required>
<label for="floatingInput">Title</label>
</div>
<!-- Content -->
<div class="mt-3">
<textarea id="customTextarea" name="content" rows="4" class="form-control custom-textarea" placeholder="Your message"><?oldvalue('content')?></textarea>
</div>
<!-- Category -->
<div class="form-floating mt-3">
<?php
$query = "SELECT * FROM categories WHERE active=1";
$categories = query($query);
?>
<select id="dropdown1" class="form-select" name="category_id">
<option value="">Select Category</option>
<?php foreach ($categories as $category): ?>
<option value="<?= $category['id'] ?>"><?= $category['category'] ?></option>
<?php endforeach; ?>
</select>
<label for="dropdown1">Category</label>
</div>
<!-- Buttons -->
<div class="d-flex justify-content-between mt-3">
<a href="<?=ROOT?>/admin/users" class="btn btn-secondary py-2 px-4">Back</a>
<button class="btn btn-primary py-2 px-4" type="submit">Add</button>
</div>
</form>
</div>
<?php elseif($action == 'edit'):?>
<!-- Edit posts form or functionality here -->
<?php
$edit_id=$url[3] ?? '';
$query="SELECT * FROM posts where id=:id and active=1";
$posts=query_row($query,['id'=>$edit_id]);
if($posts){
?>
<div class="w-50 mx-auto">
<form method="POST" action="<?=ROOT?>/admin/posts/edit/<?=$posts['id']?>" enctype="multipart/form-data">
<h1 class="h3 mb-3 fw-normal">Edit posts</h1>
<?php
if(!empty($errors))
{
echo '<div class="alert alert-danger">';
echo '<ul>';
foreach($errors as $error)
{
echo '<li>'.$error.'</li>';
}
echo '</ul>';
echo '</div>';
}
?>
<input type="hidden" name="id" value="<?=$posts['id']?>">
<div class="alert alert-danger d-none" id="alert">
<ul id="error-list">
</ul>
</div>
<!-- Image Upload + Cropper Preview -->
<div class="mb-3">
<input type="file" name="image" id="imageUpload" accept="image/*">
</div>
<div class="mb-3">
<img id="previewImage"
src="<?= !empty($posts['image']) ? get_image($posts['image']) : '' ?>"
class="img-thumbnail"
style="max-width: 100%; <?= !empty($posts['image']) ? '' : 'display: none;' ?>">
</div>
<div class="mb-3">
<canvas id="croppedCanvas" style="display: none;"></canvas>
</div>
<input type="hidden" name="cropped_image" id="croppedImageData">
<!-- <label class="upload-container mx-auto text-center">
<input type="file" name="image" id="imageUpload" accept="image/*" onchange="previewSelectedImage(event)">
<img id="previewImage" src="<?=get_image($posts['image'])?>" class="img-thumbnail mx-auto">
</label> -->
<div class="form-floating">
<input value="<?=oldvalue('title',$posts['title'])?>"
type="text" name="title" class="form-control" id="floatingInput"
placeholder="name@example.com" required>
<label for="floatingInput">Title</label>
</div>
<div class="mt-3">
<textarea id="customTextarea" name="content" rows="4" class="form-control custom-textarea" placeholder="Your message"><?oldvalue('content',$posts['content'])?></textarea>
</div>
<div class="form-floating">
<?php
$query="SELECT * FROM categories where active=1";
$categories=query($query);
?>
<select id="dropdown1" class="form-select mt-3 mb-3" name="category_id">
<option value="">Select Category</option>
<?php foreach($categories as $category):?>
<option value="<?=$category['id']?>" <?= ($posts['category_id'] == $category['id']) ? "selected" : "" ?> ><?=$category['category']?></option>
<?php endforeach;?>
</select>
<label for="floatingInput">Category</label>
</div>
<div class="d-flex justify-content-between mt-3">
<a href="<?=ROOT?>/admin/posts" class="btn btn-secondary py-2 px-4">Back</a>
<button class="btn btn-primary py-2 px-4" type="submit">Save</button>
</div>
</form>
</div>
<?php }
else{
echo '<div class="alert alert-danger">posts not found</div>';
echo '<a href="'.ROOT.'/admin/posts" class="btn btn-primary">Back to posts</a>';
}
?>
<?php elseif($action == 'delete'):?>
<!-- Delete posts functionality here -->
<?php
echo "Delete posts";
echo $delete_id=$url[3];
$query="SELECT * FROM posts where id=:id and active=1";
$posts1=query_row($query,['id'=>$delete_id]);
if(!$posts1){
echo '<div class="alert alert-danger">posts not found</div>';
echo '<a href="'.ROOT.'/admin/posts" class="btn btn-primary">Back to Posts</a>';
die;
}else{
$query="UPDATE posts SET active=0 where id=:id";
$posts=query($query,['id'=>$delete_id]);
if(file_exists('/home/Iamrajesh/htdocs/blogs/public'.$posts['image'])){
unlink('/home/Iamrajesh/htdocs/blogs/public'.$posts['image']);
}
?>
<div class="alert alert-success">Post deleted successfully</div>
<a href="<?=ROOT?>/admin/posts" class="btn btn-primary">Back to Posts</a>
<?php
}
?>
<?php else:?>
<!-- List all posts here -->
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Content</th>
<th>Slug</th>
<th>Image</th>
<th>Date</th>
<th>Action</th>
</tr>
</thead>
<?php
$limit=3;
$offset=($PAGE['page_number']-1)*$limit;
$query="SELECT * FROM posts where active=1 order by id desc limit $limit offset $offset";
$posts=query($query);
?>
<tbody>
<?php if(!empty($posts)):?>
<?php foreach ($posts as $posts): ?>
<tr class="align-middle">
<td><?=$posts['id']?></td>
<td><?=esc($posts['title'])?></td>
<td><?=esc($posts['content'])?></td>
<td><?=$posts['slug']?></td>
<td>
<img src="<?=get_image($posts['image'])?>" class="img-thumbnail" width="100" height="100">
</td>
<td><?= date('d-m-Y', strtotime($posts['date'])) ?></td>
<td>
<a href="<?=ROOT?>/admin/posts/edit/<?=$posts['id']?>" class="btn btn-primary"><i class="bi bi-pencil-square"></i></a>
<a data-bs-toggle="modal" data-bs-target="#deleteModal" class="btn btn-danger"><i class="bi bi-trash"></i></a>
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteModalLabel">Confirm Deletion</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-center">
<p>Do you want to delete this Post?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<a href="<?=ROOT?>/admin/posts/delete/<?=$posts['id']?>" class="btn btn-danger">Delete</a>
</div>
</div>
</div>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<div class="col-md-12 d-flex justify-content-center gap-2 mt-3 mb-3">
<a href="<?=$PAGE['first_link']?>" class="btn btn-primary">First Page</a>
<a href="<?=$PAGE['prev_link']?>" class="btn btn-primary">Previous</a>
<a href="<?=$PAGE['next_link']?>" class="btn btn-primary">Next</a>
</div>
</div>
<?php endif; ?>
<?php
// add new
if($action == 'add'){
if(!empty($_POST))
{
$errors=[];
$query="SELECT id FROM users WHERE username=:username and active=1 limit 1";
$username=query($query,['username'=>$_POST['username']]);
if(empty($_POST['username']))
{
$errors['username']="Username is required";
}
elseif($username)
{
$errors['username']="Username already exists";
}
elseif(preg_match('/[^a-zA-Z0-9]/',$_POST['username']))
{
$errors['username']="Username can only contain alphabets and numbers";
}
elseif(strlen($_POST['username'])<5)
{
$errors['username']="Username must be atleast 5 characters long";
}
$query="SELECT id FROM users WHERE email=:email and active=1 limit 1";
$email=query($query,['email'=>$_POST['email']]);
if(empty($_POST['email']))
{
$errors['email']="Email is required";
}
elseif($email)
{
$errors['email']="Email already exists";
}
if(empty($_POST['password']))
{
$errors['password']="Password is required";
}
elseif(strlen($_POST['password'])<5)
{
$errors['password']="Password must be atleast 5 characters long";
}
elseif($_POST['password']!=$_POST['retype_password'])
{
$errors['password']="Passwords do not match";
}
//validate Image
$allowed = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
if ($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_FILES['image']['name'])) {
// Check if a cropped image is sent via POST
if (!empty($_POST['cropped_image'])) {
$croppedImageData = $_POST['cropped_image'];
// Remove base64 prefix
$croppedImageData = str_replace("data:image/jpeg;base64,", "", $croppedImageData);
$croppedImageData = base64_decode($croppedImageData);
// Set upload directory
$uploadDir = '/home/Iamrajesh/htdocs/blogs/public/uploads/';
$fileName = time() . '.jpg'; // Save as a JPEG file
$destination = $uploadDir . $fileName;
$savePath = '/uploads/' . $fileName;
// Save the cropped image
if (file_put_contents($destination, $croppedImageData)) {
// echo "Image uploaded successfully Cropper : " . $savePath;
resize_image($destination);
} else {
$errors['image'] = 'Error saving cropped image.';
}
}
// Handle file uploads (if not using Cropper.js)
elseif (!empty($_FILES['image']['name'])) {
$fileName = basename($_FILES['image']['name']);
$destination = $uploadDir . time() . $fileName;
$savePath = '/uploads/' . time() . $fileName;
// Validate file size
if ($_FILES['image']['size'] > 2000000) {
$errors['image'] = 'File size must be less than 2MB';
}
// Validate file type
elseif (!in_array($_FILES['image']['type'], $allowed)) {
$errors['image'] = 'File type is not allowed';
}
// Save & resize the image
else {
move_uploaded_file($_FILES['image']['tmp_name'], $destination);
resize_image($destination, 500, 500); // Resize to 500x500
echo "Image uploaded successfully Normal: " . $savePath;
}
} else {
$errors['image'] = 'No image uploaded.';
}
}
else{
echo "No image";
}
if(empty($errors))
{
$data=[];
$data['email']=$_POST['email'];
$data['password']=password_hash($_POST['password'],PASSWORD_DEFAULT);
$data['username']=$_POST['username'];
$data['bio']=$_POST['bio'];
$data['role']=$_POST['role'];
$data['date']=date('Y-m-d H:i:s');
$data['image']=$savePath;
$query="INSERT INTO users(username,email,password,bio,role,image,date) VALUES(:username,:email,:password,:bio,:role,:image,:date)";
query($query,$data);
redirect(ROOT.'/admin/users');
}
}
}
elseif($action=='edit'){
if(!empty($_POST))
{
$errors=[];
$query="SELECT id FROM users WHERE username=:username AND id!=:id and active=1";
$username=query($query,['username'=>$_POST['username'],'id'=>$_POST['id']]);
if(empty($_POST['username']))
{
$errors['username']="Username is required";
}
elseif($username)
{
$errors['username']="Username already exists";
}
elseif(preg_match('/[^a-zA-Z0-9]/',$_POST['username']))
{
$errors['username']="Username can only contain alphabets and numbers";
}
elseif(strlen($_POST['username'])<5)
{
$errors['username']="Username must be atleast 5 characters long";
}
$query="SELECT id FROM users WHERE email=:email AND id!=:id and active=1";
$email=query($query,['email'=>$_POST['email'],'id'=>$_POST['id']]);
if(empty($_POST['email']))
{
$errors['email']="Email is required";
}
elseif($email)
{
$errors['email']="Email already exists";
}
if(empty($_POST['password']))
{
}
elseif(strlen($_POST['password'])<5)
{
$errors['password']="Password must be atleast 5 characters long";
}
//validate Image
$allowed = ['image/jpeg','image/jpg','image/png','image/gif','image/webp'];
$allowed = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
if ($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_FILES['image']['name'])) {
// Check if a cropped image is sent via POST
if (!empty($_POST['cropped_image'])) {
$croppedImageData = $_POST['cropped_image'];
// Remove base64 prefix
$croppedImageData = str_replace("data:image/jpeg;base64,", "", $croppedImageData);
$croppedImageData = base64_decode($croppedImageData);
// Set upload directory
$uploadDir = '/home/Iamrajesh/htdocs/blogs/public/uploads/';
$fileName = time() . '.jpg'; // Save as a JPEG file
$destination = $uploadDir . $fileName;
$savePath = '/uploads/' . $fileName;
// Save the cropped image
if (file_put_contents($destination, $croppedImageData)) {
// echo "Image uploaded successfully Cropper : " . $savePath;
resize_image($destination);
} else {
$errors['image'] = 'Error saving cropped image.';
}
}
// Handle file uploads (if not using Cropper.js)
elseif (!empty($_FILES['image']['name'])) {
$fileName = basename($_FILES['image']['name']);
$destination = $uploadDir . time() . $fileName;
$savePath = '/uploads/' . time() . $fileName;
// Validate file size
if ($_FILES['image']['size'] > 2000000) {
$errors['image'] = 'File size must be less than 2MB';
}
// Validate file type
elseif (!in_array($_FILES['image']['type'], $allowed)) {
$errors['image'] = 'File type is not allowed';
}
// Save & resize the image
else {
move_uploaded_file($_FILES['image']['tmp_name'], $destination);
resize_image($destination, 500, 500); // Resize to 500x500
echo "Image uploaded successfully Normal: " . $savePath;
}
} else {
$errors['image'] = 'No image uploaded.';
}
}
else{
$edit_id=$url[3] ?? '';
$query="SELECT * FROM users where id=:id and active=1";
$user=query_row($query,['id'=>$edit_id]);
$savePath=$user['image'];
}
if(empty($errors))
{
$data=[];
$data['email']=$_POST['email'];
$data['username']=$_POST['username'];
$data['bio']=$_POST['bio'];
$data['id']=$_POST['id'];
$data['role']=$_POST['role'];
$data['image']=$savePath;
if(empty($_POST['password']))
{
$query="UPDATE users SET username=:username,email=:email,image=:image,role=:role WHERE id=:id";
}
else
{
$data['password']=password_hash($_POST['password'],PASSWORD_DEFAULT);
$query="UPDATE users SET username=:username,email=:email,password=:password,bio=:bio,image=:image,role=:role WHERE id=:id";
}
query($query,$data);
redirect(ROOT.'/admin/users');
}
}
}
?>
\ No newline at end of file
<?php if($action == 'add'):?>
<!-- Add user form or functionality here -->
<div class="w-50 mx-auto">
<form method="POST" action="<?=ROOT?>/admin/users/add/" enctype="multipart/form-data">
<h1 class="h3 mb-3 fw-normal">Create User</h1>
<?php
if(!empty($errors))
{
echo '<div class="alert alert-danger">';
echo '<ul>';
foreach($errors as $error)
{
echo '<li>'.$error.'</li>';
}
echo '</ul>';
echo '</div>';
}
?>
<div class="alert alert-danger d-none" id="alert">
<ul id="error-list">
</ul>
</div>
<!-- Image Upload + Cropper Preview -->
<div class="mb-3">
<input type="file" name="image" id="imageUpload" accept="image/*">
</div>
<div class="mb-3">
<img id="previewImage" src="" class="img-thumbnail" style="max-width: 100%; display: none;">
</div>
<div class="mb-3">
<canvas id="croppedCanvas" style="display: none;"></canvas>
</div>
<input type="hidden" name="cropped_image" id="croppedImageData">
<div class="form-floating">
<input value="<?oldvalue('username')?>" type="text" name=username class="form-control" id="floatingInput" placeholder="name@example.com" required>
<label for="floatingInput">Username</label>
</div>
<div class="form-floating">
<input value="<?oldvalue('email')?>" type="email" name=email class="form-control" id="floatingInput" placeholder="name@example.com">
<label for="floatingInput">Email address</label>
</div>
<div class="form-floating">
<input value="<?oldvalue('bio')?>" type="text" name=bio class="form-control" id="floatingInput">
<label for="floatingInput">Bio</label>
</div>
<div class="form-floating">
<select id="dropdown1" class="form-select mb-3" name="role">
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
<label for="floatingInput">Role</label>
</div>
<div class="form-floating">
<input value="<?oldvalue('password')?>" type="password" name=password class="form-control" id="floatingPassword" placeholder="Password">
<label for="floatingPassword">Password</label>
</div>
<div class="form-floating">
<input value="<?oldvalue('retype_password')?>" type="password" name=retype_password class="form-control" id="floatingPassword" placeholder="name@example.com">
<label for="floatingInput">Retype Password</label>
</div>
<div class="d-flex justify-content-between mt-3">
<a href="<?=ROOT?>/admin/users" class="btn btn-secondary py-2 px-4">Back</a>
<button class="btn btn-primary py-2 px-4" type="submit">Add</button>
</div>
</form>
</div>
<?php elseif($action == 'edit'):?>
<!-- Edit user form or functionality here -->
<?php
$edit_id=$url[3] ?? '';
$query="SELECT * FROM users where id=:id and active=1";
$user=query_row($query,['id'=>$edit_id]);
if($user){
?>
<div class="w-50 mx-auto">
<form method="POST" action="<?=ROOT?>/admin/users/edit/<?=$user['id']?>" enctype="multipart/form-data">
<h1 class="h3 mb-3 fw-normal">Edit User</h1>
<?php
if(!empty($errors))
{
echo '<div class="alert alert-danger">';
echo '<ul>';
foreach($errors as $error)
{
echo '<li>'.$error.'</li>';
}
echo '</ul>';
echo '</div>';
}
?>
<input type="hidden" name="id" value="<?=$user['id']?>">
<div class="alert alert-danger d-none" id="alert">
<ul id="error-list">
</ul>
</div>
<!-- Image Upload -->
<div class="text-center">
<label class="form-label fw-bold">Profile Image</label>
<div class="mb-3">
<input type="file" name="image" id="imageUpload" class="form-control" accept="image/*">
</div>
<div class="mb-3">
<img id="previewImage"
src="<?= !empty($user['image']) ? get_image($user['image']) : '' ?>"
class="img-thumbnail rounded-circle shadow-sm"
style="width: 120px; height: 120px; object-fit: cover; <?= !empty($user['image']) ? '' : 'display: none;' ?>">
</div>
<canvas id="croppedCanvas" style="display: none;"></canvas>
</div>
<input type="hidden" name="cropped_image" id="croppedImageData">
<div class="form-floating mt-5">
<input value="<?=oldvalue('username',$user['username'])?>"
type="text" name="username" class="form-control" id="floatingInput"
placeholder="name@example.com" required>
<label for="floatingInput">Username</label>
</div>
<div class="form-floating">
<input value="<?=oldvalue('email',$user['email'])?>"
type="email" name="email" class="form-control" id="floatingInput"
placeholder="name@example.com" required>
<label for="floatingInput">Email address</label>
</div>
<div class="form-floating mt-5">
<input value="<?=oldvalue('bio',$user['bio'])?>"
type="text" name="bio" class="form-control" id="floatingInput"
placeholder="name@example.com" required>
<label for="floatingInput">Bio</label>
</div>
<div class="form-floating">
<input value="<?oldvalue('password')?>" type="password" name=password class="form-control" id="floatingPassword" placeholder="Password">
<label for="floatingPassword">Password</label>
</div>
<div class="form-floating">
<select id="dropdown1" class="form-select mb-3" name="role">
<option value="user" <?= ($user['role'] == 'user') ? 'selected' : '' ?>>User</option>
<option value="admin" <?= ($user['role'] == 'admin') ? 'selected' : '' ?>>Admin</option>
</select>
<label for="floatingInput">Role</label>
</div>
<div class="d-flex justify-content-between mt-3">
<a href="<?=ROOT?>/admin/users" class="btn btn-secondary py-2 px-4">Back</a>
<button class="btn btn-primary py-2 px-4" type="submit">Save</button>
</div>
</form>
</div>
<?php }
else{
echo '<div class="alert alert-danger">User not found</div>';
echo '<a href="'.ROOT.'/admin/users" class="btn btn-primary">Back to Users</a>';
}
?>
<?php elseif($action == 'delete'):?>
<!-- Delete user functionality here -->
<?php
$delete_id=$url[3];
$query="SELECT * FROM users where id=:id";
$user=query_row($query,['id'=>$delete_id]);
if(!$user){
echo '<div class="alert alert-danger">User not found</div>';
echo '<a href="'.ROOT.'/admin/users" class="btn btn-primary">Back to Users</a>';
die;
}else{
$query="UPDATE users SET active=0 where id=:id";
$user=query($query,['id'=>$delete_id]);
if(file_exists('/home/Iamrajesh/htdocs/blogs/public'.$user['image'])){
unlink('/home/Iamrajesh/htdocs/blogs/public'.$user['image']);
}
?>
<div class="alert alert-success">User deleted successfully</div>
<a href="<?=ROOT?>/admin/users" class="btn btn-primary">Back to Users</a>
<?php
}
?>
<?php else:?>
<!-- List all users here -->
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Username</th>
<th>Email</th>
<th>Role</th>
<th>Image</th>
<th>Date</th>
<th>Action</th>
</tr>
</thead>
<?php
$limit=3;
$offset=($PAGE['page_number']-1)*$limit;
if($url[2]=='u'){
$active='';
}
elseif($url[2]=='a'){
$active='where active=1 and role="admin"';
}
else{
$active = 'where active=1';
}
$query="SELECT * FROM users $active order by id desc limit $limit offset $offset";
$users=query($query);
?>
<tbody>
<?php if(!empty($users)):?>
<?php foreach ($users as $user): ?>
<tr class="align-middle">
<td><?=$user['id']?></td>
<td><?=esc($user['username'])?></td>
<td><?=$user['email']?></td>
<td><?=$user['role']?></td>
<td>
<img src="<?=get_image($user['image'])?>" class="img-thumbnail" width="100" height="100">
</td>
<td><?= date('d-m-Y', strtotime($user['date'])) ?></td>
<td>
<a href="<?=ROOT?>/admin/users/edit/<?=$user['id']?>" class="btn btn-primary"><i class="bi bi-pencil-square"></i></a>
<a data-bs-toggle="modal" data-bs-target="#deleteModal" class="btn btn-danger"><i class="bi bi-trash"></i></a>
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteModalLabel">Confirm Deletion</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-center">
<p>Do you want to delete this user?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<a href="<?=ROOT?>/admin/users/delete/<?=$user['id']?>" class="btn btn-danger">Delete</a>
</div>
</div>
</div>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<div class="col-md-12 d-flex justify-content-center gap-2 mt-3 mb-3">
<a href="<?=$PAGE['first_link']?>" class="btn btn-primary">First Page</a>
<a href="<?=$PAGE['prev_link']?>" class="btn btn-primary">Previous</a>
<a href="<?=$PAGE['next_link']?>" class="btn btn-primary">Next</a>
</div>
</div>
<?php endif; ?>
<? include 'includes/header.php';?>
<!--blog-->
<main class="mx-auto col-md-10">
<h3 class="mx-4">Blogs</h3>
<?php
$limit=3;
$offset=($PAGE['page_number']-1)*$limit;
$query = "SELECT posts.*, categories.category, users.username , users.image as image_user
FROM posts JOIN categories ON posts.category_id = categories.id
JOIN users ON posts.user_id = users.id
WHERE posts.active = 1 ORDER BY posts.id DESC limit $limit offset $offset;";
$result = query($query);
if($result){
include 'includes/post-card.php';
}
else{
echo '<div class="alert alert-danger">Post not found</div>';
echo '<a href="'.ROOT.'/blog" class="btn btn-primary">Back to Blogs</a>';
}
?>
</main>
<div class="col-md-12 d-flex justify-content-center gap-2 mt-3 mb-3">
<a href="<?=$PAGE['first_link']?>" class="btn btn-primary">First Page</a>
<a href="<?=$PAGE['prev_link']?>" class="btn btn-primary">Previous</a>
<a href="<?=$PAGE['next_link']?>" class="btn btn-primary">Next</a>
</div>
<? include 'includes/footer.php';?>
<? include 'includes/header.php';?>
<!--blog-->
<main class="mx-auto col-md-10">
<h3 class="mx-4">Category</h3>
<?php
$limit=10;
$offset=($PAGE['page_number']-1)*$limit;
$category_slug = $url[1] ?? null;
if($category_slug){
$query = "SELECT posts.*, categories.category, users.username, users.image AS image_user
FROM posts JOIN categories ON posts.category_id = categories.id
JOIN users ON posts.user_id = users.id WHERE posts.active = 1
AND posts.category_id in (select id from categories where slug = :category_slug)
ORDER BY posts.id DESC limit $limit offset $offset";
$result = query($query,['category_slug'=>$category_slug]);
if($result){
include 'includes/post-card.php';?>
<div class="col-md-12 d-flex justify-content-center gap-2 mt-3 mb-3">
<a href="<?=$PAGE['first_link']?>" class="btn btn-primary">First Page</a>
<a href="<?=$PAGE['prev_link']?>" class="btn btn-primary">Previous</a>
<a href="<?=$PAGE['next_link']?>" class="btn btn-primary">Next</a>
</div><?
}
else{
echo '<div class="alert alert-danger">Search not found</div>';
echo '<a href="'.ROOT.'" class="btn btn-primary">Back to Home</a>';
}
}
?>
</main>
<? include 'includes/footer.php';?>
\ No newline at end of file
<? include 'includes/header.php';?>
<style>
input[type="text"],
input[type="email"],
input[type="tel"],
textarea {
border: none;
border-bottom: 2px solid rgb(128, 126, 126);
outline: none;
width: 100%;
padding: 1rem 0.4rem;
}
.aside {
background-image: linear-gradient(
to left bottom,
#051937,
#002350,
#002d69,
#003684,
#01409f
);
animation: animateClr 5s infinite cubic-bezier(0.62, 0.28, 0.23, 0.99);
background-size: 400%;
}
@keyframes animateClr {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
</style>
<div class="container mt-5 mb-5 border border-2 border-primary-subtle shadow-sm" data-bs-theme="auto">
<div class="bg-body">
<div class="row">
<div class="col-lg-8 col-md-12 p-5 bg-body rounded-3">
<div class="d-flex mb-3 flex-column">
<h1 class="h5 text-capitalize my-4">What service You need?</h1>
<div class="d-flex flex-wrap">
<div class="d-flex flex-wrap justify-content-center align-items-center me-4">
<input type="checkbox" name="webdev" class="form-check-input m-0 me-3" id="webdev" />
<label for="webdev"> Web Development</label>
</div>
<div class="d-flex flex-wrap justify-content-center align-items-center me-4">
<input type="checkbox" name="webdes" class="form-check-input m-0 me-3" id="webdes" />
<label for="webdes"> Web Design</label>
</div>
<div class="d-flex flex-wrap justify-content-center align-items-center me-4">
<input type="checkbox" name="logodes" class="form-check-input m-0 me-3" id="logodes" />
<label for="logodes"> Logo Design</label>
</div>
<div class="d-flex flex-wrap justify-content-center align-items-center me-4">
<input type="checkbox" name="others" class="form-check-input m-0 me-3" id="others" />
<label for="others"> Others </label>
</div>
</div>
</div>
<form class="row mb-3">
<div class="col-md-6 p-3">
<input required placeholder="First Name" type="text" class="form-control" />
</div>
<div class="col-md-6 p-3">
<input placeholder="Last Name" type="text" class="form-control" />
</div>
<div class="col-md-6 p-3">
<input placeholder="E-mail" type="email" class="form-control" />
</div>
<div class="col-md-6 p-3">
<input required placeholder="Phone" type="tel" class="form-control" />
</div>
<div class="col-md">
<textarea required placeholder="Write your message" class="form-control" rows="3"></textarea>
</div>
<div class="text-end mt-4">
<input class="btn px-4 py-3 btn-outline-dark" type="submit" value="Send Message" />
</div>
</form>
</div>
<!-- Dark Mode Adaptable Sidebar -->
<div class="col-lg-4 col-md-12 text-white aside px-4 py-5 bg-primary-subtle">
<div class="mb-5">
<h1 class="h3">Contact Information</h1>
<p class="opacity-50">
<small>Fill out the form and we will get back to you within 24 hours.</small>
</p>
</div>
<div class="d-flex flex-column px-0">
<ul class="m-0 p-0">
<li class="d-flex justify-content-start align-items-center mb-4">
<span class="opacity-50 d-flex align-items-center me-3 fs-2">
<i class="bi bi-phone-vibrate-fill"></i>
</span>
<span>+91 9486882092</span>
</li>
<li class="d-flex align-items-center mb-4">
<span class="opacity-50 d-flex align-items-center me-3 fs-2">
<i class="bi bi-envelope-fill"></i>
</span>
<span>rajeshkannan7157@gmail.com</span>
</li>
<li class="d-flex justify-content-start align-items-center mb-4">
<span class="opacity-50 d-flex align-items-center me-3 fs-2">
<i class="bi bi-geo-alt-fill"></i>
</span>
<span>Karaikudi, <br> Sivaganga</span>
</li>
</ul>
<div class="text-muted text-center">
<div class="d-flex justify-content-center mt-4">
<a href="https://www.linkedin.com/in/rajesh-dhamotharan-9771b3246/" target="_blank" class="text-light mx-3 fs-3">
<i class="bi bi-linkedin"></i>
</a>
<a href="https://git.selfmade.ninja/Iamrajesh" target="_blank" class="text-light mx-3 fs-3">
<i class="bi bi-github"></i>
</a>
<a href="https://x.com/Raj_clover" target="_blank" class="text-light mx-3 fs-3">
<i class="bi bi-twitter"></i>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Error</title>
<link href="https://fonts.googleapis.com/css?family=Carter+One|Roboto+Condensed" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
background: #121212;
font-family: "Roboto Condensed", sans-serif;
text-align: center;
overflow: hidden;
color: white;
}
h1 {
font-size: 3rem;
font-family: "Carter One", cursive;
margin-bottom: 20px;
}
.button {
display: inline-block;
padding: 12px 25px;
background: #ff5733;
color: white;
text-decoration: none;
font-size: 1.2rem;
border-radius: 8px;
margin-top: 20px;
transition: background 0.3s ease;
}
.button:hover {
background: #d94326;
}
.compass-container {
margin-top: 50px;
width: 350px;
height: 350px;
position: relative;
}
.compass-container svg {
width: 100%;
height: 100%;
}
#Spinner {
transform-origin: center;
transition: transform 0.05s linear;
}
</style>
</head>
<body>
<div class="message">
<h1>You are lost.</h1>
<a href="<?=ROOT?>" class="button">Go Home</a>
</div>
<div class="compass-container">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 288 288">
<!-- Compass Outer Ring -->
<circle cx="144" cy="144" r="130" stroke="white" stroke-width="4" fill="none"/>
<!-- Compass Direction Markers -->
<text x="140" y="30" font-size="24" fill="white" font-weight="bold">N</text>
<text x="255" y="150" font-size="24" fill="white" font-weight="bold">E</text>
<text x="140" y="270" font-size="24" fill="white" font-weight="bold">S</text>
<text x="30" y="150" font-size="24" fill="white" font-weight="bold">W</text>
<!-- Rotation Needle -->
<g id="Spinner">
<!-- Red Top Part of Needle -->
<polygon points="144,50 154,144 134,144" fill="red"/>
<!-- White Bottom Part of Needle -->
<polygon points="144,238 154,144 134,144" fill="white"/>
<!-- Compass Center Circle -->
<circle cx="144" cy="144" r="8" fill="black" stroke="white" stroke-width="2"/>
</g>
</svg>
</div>
<script>
$(document).mousemove(function (event) {
let compass = $(".compass-container");
let compassOffset = compass.offset();
let compassCenterX = compassOffset.left + compass.width() / 2;
let compassCenterY = compassOffset.top + compass.height() / 2;
let deltaX = event.pageX - compassCenterX;
let deltaY = event.pageY - compassCenterY;
let angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI) + 90;
$("#Spinner").css("transform", `rotate(${angle}deg)`);
});
</script>
</body>
</html>
<? include 'includes/header.php';?>
<!--blog-->
<main class="container mt-5">
<h2>Your Feed</h2>
<?php
$query = "SELECT posts.*, categories.category, users.username , users.image as image_user,users.id as userid
FROM posts JOIN categories ON posts.category_id = categories.id
JOIN users ON posts.user_id = users.id
WHERE posts.active = 1 ORDER BY posts.id DESC;";
$result = query($query);
if($result){
include 'includes/post-card.php';
}
else{
echo '<div class="alert alert-danger">Post not found</div>';
echo '<a href="'.ROOT.'/admin/posts" class="btn btn-primary">Back to posts</a>';
}
?>
</main>
<? include 'includes/footer.php';?>
<div class="container">
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 border-top">
<p class="col-md-4 mb-0 text-body-secondary">© Crafted By Rajesh D</p>
<ul class="list-unstyled d-flex justify-content-center align-items-center">
<li class="ms-3"><a class="link-body-emphasis fs-3" href="https://www.linkedin.com/in/rajesh-dhamotharan-9771b3246/"><i class="bi bi-linkedin"></i></a></li>
<li class="ms-3"><a class="link-body-emphasis fs-3" href="https://git.selfmade.ninja/Iamrajesh"><i class="bi bi-github"></i></a></li>
<li class="ms-3"><a class="link-body-emphasis fs-3" href="https://x.com/Raj_clover"><i class="bi bi-twitter"></i></a></li>
</ul>
</footer>
</div>
\ No newline at end of file
<html lang="en" data-bs-theme="auto">
<script src="<?=ROOT?>/assets/js/color-modes.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<title><?=APP_NAME?></title>
<link rel="icon" type="image/x-icon" href="<?=ROOT?>/assets/images/blogger.png ">
<link rel="canonical" href="https://getbootstrap.com/docs/5.3/examples/headers/">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@3">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css">
<script src="<?=ROOT?>/assets/js/bootstrap/bootstrap.bundle.min.js"></script>
<link href="<?=ROOT?>/assets/css/bootstrap/bootstrap.min.css" rel="stylesheet">
<style>
.b-example-divider {
width: 100%;
height: 3rem;
background-color: rgba(0, 0, 0, .1);
border: solid rgba(0, 0, 0, .15);
border-width: 1px 0;
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
}
.bi {
vertical-align: -.125em;
fill: currentColor;
}
.nav {
display: flex;
flex-wrap: wrap;
padding-bottom: 1rem;
margin-top: -1px;
text-align: center;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
}
.btn-bd-primary {
--bd-violet-bg: #712cf9;
--bd-violet-rgb: 112.520718, 44.062154, 249.437846;
--bs-btn-font-weight: 600;
--bs-btn-color: var(--bs-white);
--bs-btn-bg: var(--bd-violet-bg);
--bs-btn-border-color: var(--bd-violet-bg);
--bs-btn-hover-color: var(--bs-white);
--bs-btn-hover-bg: #6528e0;
--bs-btn-hover-border-color: #6528e0;
--bs-btn-focus-shadow-rgb: var(--bd-violet-rgb);
--bs-btn-active-color: var(--bs-btn-hover-color);
--bs-btn-active-bg: #5a23c8;
--bs-btn-active-border-color: #5a23c8;
}
.bd-mode-toggle {
z-index: 1500;
}
.bd-mode-toggle .dropdown-menu .active .bi {
display: block !important;
}
.card-body{
position: relative;
}
.card-img-top {
height: auto;
object-fit: cover;
}
.category {
position: absolute;
top: 10px;
left: 10px;
background-color: orange;
color: white;
padding: 5px 10px;
font-size: 14px;
text-transform: uppercase;
border-radius: 5px;
}
.profile-img {
width: 50px;
height: 50px;
border-radius: 50%;
object-fit: cover;
}
.author a {
text-decoration: none;
color: orange;
font-weight: bold;
}
.info {
font-size: 14px;
color: #888;
}
.info i {
margin-right: 5px;
color: #555;
}
.post-image {
width: 100%;
height: auto; /* Adjust this height as needed */
object-fit: cover; /* Ensures the image fills the space properly */
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
.card {
height: 100%; /* Ensures all cards have the same height */
display: flex;
flex-direction: column;
}
.card-body {
flex-grow: 1; /* Makes sure the content expands properly */
padding: 1.25rem;
}
.category-badge {
font-size: 0.8rem;
font-weight: bold;
opacity: 0.9;
}
.like-btn {
border: none;
background: none;
cursor: pointer;
font-size: 1.5rem;
}
.like-btn .bi-heart-fill {
color: red; /* Filled heart color */
}
</style>
<!-- Custom styles for this template -->
<link href="<?=ROOT?>/assests/css/headers.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.css">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
<symbol id="check2" viewBox="0 0 16 16">
<path d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z"></path>
</symbol>
<symbol id="circle-half" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 0 8 1v14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z"></path>
</symbol>
<symbol id="moon-stars-fill" viewBox="0 0 16 16">
<path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"></path>
<path d="M10.794 3.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387a1.734 1.734 0 0 0-1.097 1.097l-.387 1.162a.217.217 0 0 1-.412 0l-.387-1.162A1.734 1.734 0 0 0 9.31 6.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387a1.734 1.734 0 0 0 1.097-1.097l.387-1.162zM13.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.156 1.156 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a1.156 1.156 0 0 0-.732-.732l-.774-.258a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732L13.863.1z"></path>
</symbol>
<symbol id="sun-fill" viewBox="0 0 16 16">
<path d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"></path>
</symbol>
</svg>
<div class="dropdown position-fixed bottom-0 end-0 mb-3 me-3 bd-mode-toggle">
<button class="btn btn-bd-primary py-2 dropdown-toggle d-flex align-items-center" id="bd-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown" aria-label="Toggle theme (auto)">
<svg class="bi my-1 theme-icon-active" width="1em" height="1em"><use href="#circle-half"></use></svg>
<span class="visually-hidden" id="bd-theme-text">Toggle theme</span>
</button>
<ul class="dropdown-menu dropdown-menu-end shadow" aria-labelledby="bd-theme-text">
<li>
<button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="light" aria-pressed="false">
<svg class="bi me-2 opacity-50" width="1em" height="1em"><use href="#sun-fill"></use></svg>
Light
<svg class="bi ms-auto d-none" width="1em" height="1em"><use href="#check2"></use></svg>
</button>
</li>
<li>
<button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="dark" aria-pressed="false">
<svg class="bi me-2 opacity-50" width="1em" height="1em"><use href="#moon-stars-fill"></use></svg>
Dark
<svg class="bi ms-auto d-none" width="1em" height="1em"><use href="#check2"></use></svg>
</button>
</li>
<li>
<button type="button" class="dropdown-item d-flex align-items-center active" data-bs-theme-value="auto" aria-pressed="true">
<svg class="bi me-2 opacity-50" width="1em" height="1em"><use href="#circle-half"></use></svg>
Auto
<svg class="bi ms-auto d-none" width="1em" height="1em"><use href="#check2"></use></svg>
</button>
</li>
</ul>
</div>
<?php
$current_page = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), "/");
?>
<header class="p-3 border-bottom">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center">
<!-- Logo -->
<a href="/" class="d-flex justify-content-left align-items-center mb-2 mb-lg-0 mx-md-5 link-body-emphasis text-decoration-none">
<img src="<?=ROOT?>/assets/images/blogger.png" alt="Logo" class="img-fluid" style="width: 50px; max-height: 50px; object-fit: contain;">
</a>
<!-- Navigation Bar -->
<ul class="nav nav-pills justify-content-center gap-3 py-2 rounded shadow-sm" id="navBar">
<li class="nav-item">
<a class="nav-link d-flex align-items-center gap-2 fw-semibold px-3 py-2 <?= ($current_page == '' || $current_page == 'index.php') ? 'active' : '' ?>"
href="<?=ROOT?>">
<i class="bi bi-house-door-fill"></i> Home
</a>
</li>
<li class="nav-item">
<a class="nav-link d-flex align-items-center gap-2 fw-semibold px-3 py-2 <?= $current_page == 'blog' ? 'active' : '' ?>"
href="<?=ROOT?>/blog">
<i class="bi bi-images"></i> Blog
</a>
</li>
<li class="nav-item">
<a class="nav-link d-flex align-items-center gap-2 fw-semibold px-3 py-2 <?= $current_page == 'contact' ? 'active' : '' ?>"
href="<?=ROOT?>/contact">
<i class="bi bi-chat-text-fill"></i> Contact
</a>
</li>
<?php if (!in_array($url[0], ['admin', 'blog', 'search', 'profile', 'post', 'contact', 'user'])): ?>
<li class="nav-item dropdown">
<a href="#" class="nav-link d-flex align-items-center justify-content-center dropdown-toggle <?= $current_page == 'category' ? 'active' : '' ?>"
data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-tags-fill"></i> Category
</a>
<?php
$query = "SELECT * FROM categories WHERE active=1";
$categories = query($query);
?>
<ul class="dropdown-menu text-small">
<?php foreach ($categories as $category): ?>
<li><a class="dropdown-item" href="<?=ROOT?>/category/<?=$category['slug']?>"><?=$category['category']?></a></li>
<?php endforeach; ?>
</ul>
</li>
<?php endif; ?>
</ul>
<!-- Search Bar & User Profile -->
<div class="d-flex align-items-center">
<!-- Search Form -->
<form action="<?=ROOT?>/search" class="d-flex align-items-center me-3 mt-3" role="search">
<div class="input-group" style="max-width: 250px;">
<input value="<?=$_GET['find'] ?? ''?>" name="find"
type="search"
class="form-control rounded-start-pill px-4 shadow-sm"
placeholder="Search..."
aria-label="Search">
<button type="submit" class="btn btn-primary rounded-end-pill">
<i class="bi bi-search"></i>
</button>
</div>
</form>
<!-- User Profile Dropdown -->
<?php if(logged_in()){
$image_user = find('users', $_SESSION['user_id'], 'image');
$role = find('users', $_SESSION['user_id'], 'role');
} ?>
<div class="dropdown text-end">
<a href="#" class="d-flex align-items-center link-body-emphasis text-decoration-none dropdown-toggle"
data-bs-toggle="dropdown" aria-expanded="false">
<img src="<?=get_image($image_user)?>" alt="User Image" class="img-fluid rounded-circle"
style="width: 50px; height: 50px; object-fit: cover;">
</a>
<ul class="dropdown-menu text-small">
<li>
<a class="dropdown-item" href="<?= ($role == 'admin') ? '/admin/posts/add' : '/user/post/add'; ?>">
New Post...
</a>
</li>
<li><a class="dropdown-item" href="<?=ROOT?>/admin">Admin</a></li>
<li><a class="dropdown-item" href="<?=ROOT?>/profile/<?=$_SESSION['user_id']?>">Profile</a></li>
<li><hr class="dropdown-divider"></li>
<?php if(!logged_in()): ?>
<li><a class="dropdown-item" href="<?=ROOT?>/login">Sign in</a></li>
<?php else: ?>
<li><a class="dropdown-item" href="<?=ROOT?>/logout">Sign out</a></li>
<?php endif; ?>
</ul>
</div>
</div> <!-- End of Search & Profile -->
</div>
</div>
</header>
<?
if($url[0]=='home')
include 'slider.php'?>
<div class="container mt-5 mb-5">
<div class="row g-4">
<?php foreach ($result as $post):
$id = $post['id'];
$title = $post['title'];
$content = $post['content'];
$image = $post['image'];
$category = $post['category'];
$username = $post['username'];
$image_user = $post['image_user'];
$userid = $post['userid'];
$seconds_ago = (time() - strtotime($post['date']));
if ($seconds_ago >= 31536000) {
$date = intval($seconds_ago / 31536000) . " years ago";
} elseif ($seconds_ago >= 2419200) {
$date = intval($seconds_ago / 2419200) . " months ago";
} elseif ($seconds_ago >= 86400) {
$date = intval($seconds_ago / 86400) . " days ago";
} elseif ($seconds_ago >= 3600) {
$date = intval($seconds_ago / 3600) . " hours ago";
} elseif ($seconds_ago >= 120) {
$date = intval($seconds_ago / 60) . " minutes ago";
} elseif ($seconds_ago >= 60) {
$date = "a minute ago";
} else {
$date = "less than a minute ago";
}
$query = "Select count(id) as num from comments where post_id = $id and active = 1";
$num_comment = query_row($query);
?>
<div class="col-md-6 col-lg-4">
<div class="card shadow-sm border-0">
<a href="<?=ROOT?>/post/<?=$post['slug']?>" class="text-decoration-none position-relative">
<img src="<?= get_image($image) ?>" class="post-image border rounded">
<div class="category-badge bg-primary text-white px-2 py-1 rounded position-absolute bottom-0 end-0 m-2">
<?= $category ?>
</div>
</a>
<div class="card-body">
<h5 class="card-title text-center">
<a href="#" class="text-dark text-decoration-none"><?= $title ?></a>
</h5>
<div class="d-flex align-items-center my-2">
<a href="<?=ROOT?>/profile/<?=$userid?>" class="text-decoration-none">
<img src="<?= get_image($image_user) ?>" class="profile-img me-2 rounded-circle" alt="Author" width="40" height="40">
</a>
<p class="mb-0">By <a href="<?=ROOT?>/profile/<?=$userid?>" class="text-muted fw-bold text-decoration-none"><?= $username ?></a></p>
</div>
<!-- Like & Comment Section -->
<?php
$query = "SELECT COUNT(*) as num FROM likes WHERE post_id = $id";
$likes = query_row($query);
$likes = $likes['num'];
// Check if the current user liked the post
$user_id = $_SESSION['user_id'] ?? 0;
$liked_query = "SELECT COUNT(*) as liked FROM likes WHERE post_id = $id AND user_id = $user_id";
$liked_result = query_row($liked_query);
$isLiked = $liked_result['liked'] > 0;
?>
<div class="d-flex justify-content-between align-items-center mt-3">
<!-- Like Button -->
<div class="d-flex align-items-center">
<button class="btn btn-link p-0 like-btn" data-post-id="<?= $id ?>">
<i class="bi <?= $isLiked ? 'bi-heart-fill text-danger' : 'bi-heart' ?> like-icon fs-5"></i>
</button>
<a href="<?=ROOT?>/post/<?=$post['slug']?>" class="text-muted text-decoration-none"><span class="ms-1 like-count"><?= $likes ?></span></a>
</div>
<!-- Comments -->
<div class="d-flex align-items-center">
<i class="bi bi-chat fs-5 me-1 text-secondary"></i>
<a href="<?=ROOT?>/post/<?=$post['slug']?>" class="text-muted text-decoration-none"><?= $num_comment['num'] ?> Comments</a>
</div>
</div>
<!-- Date at Bottom Right -->
<div class="d-flex justify-content-end mt-3">
<p class="mb-0 text-muted small"><i class="bi bi-clock me-1"></i><?= $date ?></p>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll('.like-btn').forEach(button => {
button.addEventListener('click', function() {
let postId = this.getAttribute('data-post-id');
let icon = this.querySelector('.like-icon');
let countElement = this.nextElementSibling;
let x = icon.classList.contains('bi-heart-fill');
let isLiked = icon.classList.contains('bi-heart-fill');
// Send AJAX request
fetch("<?=ROOT?>/likes", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "post_id=" + postId + "&action=" + (isLiked ? "unlike" : "like")
})
.then(response => response.json())
.then(data => {
if (data.success) {
icon.classList.toggle('bi-heart');
icon.classList.toggle('bi-heart-fill');
countElement.textContent = data.likes;
}
});
});
});
});
</script>
<style>
.carousel-container {
padding: 40px 0;
background-image: linear-gradient(to top,rgb(166, 210, 241) 0%,#0d6efd 100%);
box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.2);
text-align: center;
position: relative;
}
.carousel-title {
font-size: 32px;
font-weight: bold;
color: #fff;
margin-bottom: 20px;
text-transform: uppercase;
letter-spacing: 2px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.carousel-item img {
width: auto;
height: 450px;
object-fit: contain;
border-radius: 15px;
margin: auto;
}
.carousel-control-prev, .carousel-control-next {
width: 7%;
}
.carousel-control-prev-icon, .carousel-control-next-icon {
background-color: rgba(0, 0, 0, 0.6);
padding: 15px;
border-radius: 50%;
}
.carousel-control-prev:hover .carousel-control-prev-icon,
.carousel-control-next:hover .carousel-control-next-icon {
background-color: rgba(0, 0, 0, 0.9);
}
/* Play/Pause Button */
.audio-controls {
margin-top: 15px;
}
.audio-button {
background-color: #fff;
border: none;
padding: 10px 20px;
font-size: 16px;
font-weight: bold;
border-radius: 5px;
cursor: pointer;
transition: 0.3s;
}
.audio-button:hover {
background-color: #f1f1f1;
}
</style>
<?php if ($url[0] == 'home'): ?>
<div class="carousel-container">
<h2 class="carousel-title">Today's Highlights</h2>
<div id="imageSlider" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<?php
$query = "SELECT image AS all_images FROM users
WHERE active = 1 UNION ALL SELECT image
FROM posts WHERE active = 1 ORDER BY RAND() LIMIT 5";
$post = query($query);
?>
<?php if (!empty($post)): ?>
<?php foreach ($post as $index => $image): ?>
<div class="carousel-item <?= $index === 0 ? 'active' : '' ?>">
<img src="<?= get_image($image['all_images']) ?>" class="d-block w-100" alt="Slide <?= $index + 1 ?>">
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<!-- Left and Right Arrows -->
<button class="carousel-control-prev" type="button" data-bs-target="#imageSlider" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#imageSlider" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
<!-- Audio Player -->
<div class="audio-controls">
<button id="audioButton" class="audio-button"><i id="audioIcon" class="x`bi bi-play-btn-fill"></i></button>
<audio id="carouselAudio">
<source src="<?=ROOT?>/assets/bgm.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</div>
<script>
var myCarousel = new bootstrap.Carousel(document.querySelector('#imageSlider'), {
interval: 5000, // Auto-slide every 5 seconds
wrap: true,
pause: false
});
// Audio Play/Pause Functionality
document.addEventListener("DOMContentLoaded", function () {
let audio = document.getElementById("carouselAudio");
let audioButton = document.getElementById("audioButton");
let audioIcon = document.getElementById("audioIcon");
audioButton.addEventListener("click", function () {
if (audio.paused) {
audio.play();
audioIcon.classList.remove("bi-play-btn-fill");
audioIcon.classList.add("bi-pause-btn-fill");
} else {
audio.pause();
audioIcon.classList.remove("bi-pause-btn-fill");
audioIcon.classList.add("bi-play-btn-fill");
}
});
});
</script>
<?php endif; ?>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment