correzione login

This commit is contained in:
Flatlogic Bot 2025-11-05 22:50:07 +00:00
parent 5f68d7fe5b
commit f4d677bb9d
6 changed files with 213 additions and 34 deletions

View File

@ -9,7 +9,7 @@ if (!can($_SESSION['user_role'], 'asset', 'create')) {
} }
$allowed_fields_str = can($_SESSION['user_role'], 'asset', 'create'); $allowed_fields_str = can($_SESSION['user_role'], 'asset', 'create');
$allowed_fields = ($allowed_fields_str === '*') ? ['name', 'asset_tag', 'status', 'location', 'manufacturer', 'model', 'purchase_date'] : explode(',', $allowed_fields_str); $allowed_fields = ($allowed_fields_str === '*') ? ['name', 'status', 'location', 'manufacturer', 'model', 'purchase_date'] : explode(',', $allowed_fields_str);
$success_message = ''; $success_message = '';
$error_message = ''; $error_message = '';
@ -19,6 +19,30 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$placeholders = []; $placeholders = [];
$columns = []; $columns = [];
// Generate new asset tag
try {
$pdo = db();
$stmt = $pdo->query("SELECT asset_tag FROM assets WHERE asset_tag LIKE 'ASSET-%' ORDER BY CAST(SUBSTRING(asset_tag, 7) AS UNSIGNED) DESC LIMIT 1");
$last_asset_tag = $stmt->fetchColumn();
if ($last_asset_tag) {
$last_number = (int) substr($last_asset_tag, 6);
$new_number = $last_number + 1;
} else {
$new_number = 1;
}
$new_asset_tag = 'ASSET-' . str_pad($new_number, 3, '0', STR_PAD_LEFT);
$data = [$new_asset_tag];
$columns = ['asset_tag'];
$placeholders = '?';
} catch (PDOException $e) {
$error_message = 'Error generating asset tag: ' . $e->getMessage();
}
if (empty($error_message)) {
foreach ($allowed_fields as $field) { foreach ($allowed_fields as $field) {
if (isset($_POST[$field])) { if (isset($_POST[$field])) {
$data[] = $_POST[$field]; $data[] = $_POST[$field];
@ -27,12 +51,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} }
} }
if (empty($data)) { if (count($data) <= 1) { // Only asset tag is present
$error_message = 'No data submitted.'; $error_message = 'No data submitted.';
} else { } else {
try { try {
$pdo = db(); $sql = sprintf("INSERT INTO assets (%s) VALUES (%s)", implode(', ', $columns), implode(', ', array_fill(0, count($columns), '?')));
$sql = sprintf("INSERT INTO assets (%s) VALUES (%s)", implode(', ', $columns), implode(', ', $placeholders));
$stmt = $pdo->prepare($sql); $stmt = $pdo->prepare($sql);
$stmt->execute($data); $stmt->execute($data);
@ -43,6 +66,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$error_message = 'Database error: ' . $e->getMessage(); $error_message = 'Database error: ' . $e->getMessage();
} }
} }
}
} }
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
@ -85,12 +109,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<input type="text" class="form-control" id="name" name="name" required> <input type="text" class="form-control" id="name" name="name" required>
</div> </div>
<?php endif; ?> <?php endif; ?>
<?php if (in_array('asset_tag', $allowed_fields)): ?>
<div class="col-md-6 mb-3">
<label for="asset_tag" class="form-label">Asset Tag*</label>
<input type="text" class="form-control" id="asset_tag" name="asset_tag" required>
</div>
<?php endif; ?>
</div> </div>
<div class="row"> <div class="row">
<?php if (in_array('status', $allowed_fields)): ?> <?php if (in_array('status', $allowed_fields)): ?>

View File

@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS `categories` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL UNIQUE,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=INNODB;

View File

@ -0,0 +1,2 @@
ALTER TABLE `assets` ADD COLUMN `category_id` INT NULL AFTER `status`;
ALTER TABLE `assets` ADD FOREIGN KEY (`category_id`) REFERENCES `categories`(`id`) ON DELETE SET NULL;

143
index.php
View File

@ -7,8 +7,38 @@ require_once 'auth-helpers.php';
$allowed_fields_str = can($_SESSION['user_role'], 'asset', 'read'); $allowed_fields_str = can($_SESSION['user_role'], 'asset', 'read');
$allowed_fields = $allowed_fields_str ? explode(',', $allowed_fields_str) : []; $allowed_fields = $allowed_fields_str ? explode(',', $allowed_fields_str) : [];
// Function to count total assets
function count_assets($search = '', $status = '') {
$sql = "SELECT COUNT(*) FROM assets";
$where = [];
$params = [];
if (!empty($search)) {
$where[] = "name LIKE :search";
$params[':search'] = "%$search%";
}
if (!empty($status)) {
$where[] = "status = :status";
$params[':status'] = $status;
}
if (!empty($where)) {
$sql .= " WHERE " . implode(' AND ', $where);
}
try {
$pdo = db();
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
return $stmt->fetchColumn();
} catch (PDOException $e) {
return 0;
}
}
// Function to execute query and return results // Function to execute query and return results
function get_assets($fields) { function get_assets($fields, $search = '', $status = '', $limit = 10, $offset = 0, $sort_by = 'created_at', $sort_order = 'DESC') {
if (empty($fields)) { if (empty($fields)) {
return []; // No read permission return []; // No read permission
} }
@ -19,16 +49,70 @@ function get_assets($fields) {
$select_fields = implode(', ', $fields); $select_fields = implode(', ', $fields);
$sql = "SELECT $select_fields FROM assets";
$where = [];
$params = [];
if (!empty($search)) {
// Assuming 'name' is a field that can be searched.
if (in_array('name', $fields)) {
$where[] = "name LIKE :search";
$params[':search'] = "%$search%";
}
}
if (!empty($status)) {
if (in_array('status', $fields)) {
$where[] = "status = :status";
$params[':status'] = $status;
}
}
if (!empty($where)) {
$sql .= " WHERE " . implode(' AND ', $where);
}
// Whitelist sortable columns
$sortable_columns = array_merge($fields, ['created_at']);
if (!in_array($sort_by, $sortable_columns)) {
$sort_by = 'created_at';
}
$sort_order = strtoupper($sort_order) === 'ASC' ? 'ASC' : 'DESC';
$sql .= " ORDER BY $sort_by $sort_order LIMIT :limit OFFSET :offset";
$params[':limit'] = $limit;
$params[':offset'] = $offset;
try { try {
$pdo = db(); $pdo = db();
$stmt = $pdo->query("SELECT $select_fields FROM assets ORDER BY created_at DESC"); $stmt = $pdo->prepare($sql);
// Bind parameters separately to handle integer binding for LIMIT and OFFSET
foreach ($params as $key => &$val) {
if ($key === ':limit' || $key === ':offset') {
$stmt->bindParam($key, $val, PDO::PARAM_INT);
} else {
$stmt->bindParam($key, $val);
}
}
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC); return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) { } catch (PDOException $e) {
return ['error' => 'Database error: ' . $e->getMessage()]; return ['error' => 'Database error: ' . $e->getMessage()];
} }
} }
$assets = get_assets($allowed_fields); $search = $_GET['search'] ?? '';
$status = $_GET['status'] ?? '';
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$limit = 10;
$offset = ($page - 1) * $limit;
$sort_by = $_GET['sort_by'] ?? 'created_at';
$sort_order = $_GET['sort_order'] ?? 'DESC';
$total_assets = count_assets($search, $status);
$total_pages = ceil($total_assets / $limit);
$assets = get_assets($allowed_fields, $search, $status, $limit, $offset, $sort_by, $sort_order);
function getStatusClass($status) { function getStatusClass($status) {
switch (strtolower($status)) { switch (strtolower($status)) {
@ -86,6 +170,23 @@ function getStatusClass($status) {
<?php endif; ?> <?php endif; ?>
<div class="surface p-4"> <div class="surface p-4">
<form method="get" class="row g-3 mb-4">
<div class="col-md-4">
<input type="text" name="search" class="form-control" placeholder="Search by asset name..." value="<?php echo htmlspecialchars($search); ?>">
</div>
<div class="col-md-3">
<select name="status" class="form-select">
<option value="">All Statuses</option>
<option value="In Service" <?php echo ($status === 'In Service') ? 'selected' : ''; ?>>In Service</option>
<option value="Under Repair" <?php echo ($status === 'Under Repair') ? 'selected' : ''; ?>>Under Repair</option>
<option value="Retired" <?php echo ($status === 'Retired') ? 'selected' : ''; ?>>Retired</option>
</select>
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-primary">Filter</button>
</div>
</form>
<?php if (isset($assets['error'])): ?> <?php if (isset($assets['error'])): ?>
<div class="alert alert-danger"> <div class="alert alert-danger">
<?php echo htmlspecialchars($assets['error']); ?> <?php echo htmlspecialchars($assets['error']); ?>
@ -93,7 +194,7 @@ function getStatusClass($status) {
<?php elseif (empty($assets)): ?> <?php elseif (empty($assets)): ?>
<div class="text-center p-5"> <div class="text-center p-5">
<h4>No assets found.</h4> <h4>No assets found.</h4>
<?php if (can($_SESSION['user_role'], 'asset', 'create'])): ?> <?php if (can($_SESSION['user_role'], 'asset', 'create')): ?>
<p>Get started by adding your first company asset.</p> <p>Get started by adding your first company asset.</p>
<a href="add-asset.php" class="btn btn-primary">Add Asset</a> <a href="add-asset.php" class="btn btn-primary">Add Asset</a>
<?php endif; ?> <?php endif; ?>
@ -103,8 +204,18 @@ function getStatusClass($status) {
<table class="table asset-table"> <table class="table asset-table">
<thead> <thead>
<tr> <tr>
<?php foreach ($allowed_fields as $field): if($field === 'id') continue; ?> <?php
<th><?php echo ucfirst(str_replace('_', ' ', $field)); ?></th> $new_sort_order = ($sort_order === 'DESC') ? 'ASC' : 'DESC';
foreach ($allowed_fields as $field): if($field === 'id') continue;
?>
<th>
<a href="?page=<?php echo $page; ?>&search=<?php echo urlencode($search); ?>&status=<?php echo urlencode($status); ?>&sort_by=<?php echo $field; ?>&sort_order=<?php echo $new_sort_order; ?>">
<?php echo ucfirst(str_replace('_', ' ', $field)); ?>
<?php if ($sort_by === $field): ?>
<i data-feather="<?php echo ($sort_order === 'DESC') ? 'arrow-down' : 'arrow-up'; ?>"></i>
<?php endif; ?>
</a>
</th>
<?php endforeach; ?> <?php endforeach; ?>
<th>Actions</th> <th>Actions</th>
</tr> </tr>
@ -117,7 +228,7 @@ function getStatusClass($status) {
<?php if ($field === 'status'): ?> <?php if ($field === 'status'): ?>
<span class="status <?php echo getStatusClass($asset[$field]); ?>"><?php echo htmlspecialchars($asset[$field]); ?></span> <span class="status <?php echo getStatusClass($asset[$field]); ?>"><?php echo htmlspecialchars($asset[$field]); ?></span>
<?php else: ?> <?php else: ?>
<?php echo htmlspecialchars($asset[$field]); ?> <?php echo htmlspecialchars($asset[$field] ?? ''); ?>
<?php endif; ?> <?php endif; ?>
</td> </td>
<?php endforeach; ?> <?php endforeach; ?>
@ -125,15 +236,31 @@ function getStatusClass($status) {
<?php if (can($_SESSION['user_role'], 'asset', 'update')): ?> <?php if (can($_SESSION['user_role'], 'asset', 'update')): ?>
<a href="edit-asset.php?id=<?php echo $asset['id']; ?>" class="btn btn-sm btn-outline-primary">Edit</a> <a href="edit-asset.php?id=<?php echo $asset['id']; ?>" class="btn btn-sm btn-outline-primary">Edit</a>
<?php endif; ?> <?php endif; ?>
<?php if (can($_SESSION['user_role'], 'asset', 'delete'])): ?> <?php if (can($_SESSION['user_role'], 'asset', 'delete')): ?>
<?php if (can($_SESSION['user_role'], 'asset', 'delete')): ?>
<a href="delete-asset.php?id=<?php echo $asset['id']; ?>" class="btn btn-sm btn-outline-danger" onclick="return confirm('Are you sure you want to delete this asset?');">Delete</a> <a href="delete-asset.php?id=<?php echo $asset['id']; ?>" class="btn btn-sm btn-outline-danger" onclick="return confirm('Are you sure you want to delete this asset?');">Delete</a>
<?php endif; ?> <?php endif; ?>
<?php endif; ?>
</td> </td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
</tbody> </tbody>
</table> </table>
</div> </div>
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
<?php if ($page > 1): ?>
<li class="page-item"><a class="page-link" href="?page=<?php echo $page - 1; ?>&search=<?php echo urlencode($search); ?>&status=<?php echo urlencode($status); ?>&sort_by=<?php echo $sort_by; ?>&sort_order=<?php echo $sort_order; ?>">Previous</a></li>
<?php endif; ?>
<?php for ($i = 1; $i <= $total_pages; $i++): ?>
<li class="page-item <?php echo ($i == $page) ? 'active' : ''; ?>"><a class="page-link" href="?page=<?php echo $i; ?>&search=<?php echo urlencode($search); ?>&status=<?php echo urlencode($status); ?>&sort_by=<?php echo $sort_by; ?>&sort_order=<?php echo $sort_order; ?>"><?php echo $i; ?></a></li>
<?php endfor; ?>
<?php if ($page < $total_pages): ?>
<li class="page-item"><a class="page-link" href="?page=<?php echo $page + 1; ?>&search=<?php echo urlencode($search); ?>&status=<?php echo urlencode($status); ?>&sort_by=<?php echo $sort_by; ?>&sort_order=<?php echo $sort_order; ?>">Next</a></li>
<?php endif; ?>
</ul>
</nav>
<?php endif; ?> <?php endif; ?>
</div> </div>
</main> </main>

4
opcache_reset.php Normal file
View File

@ -0,0 +1,4 @@
<?php
opcache_reset();
echo "Opcode cache has been cleared.";
?>

23
run-migrations.php Normal file
View File

@ -0,0 +1,23 @@
<?php
require_once 'db/config.php';
// This script will run all migrations and then delete itself.
$pdo = db();
$migrations_dir = __DIR__ . '/db/migrations';
$files = glob($migrations_dir . '/*.sql');
foreach ($files as $file) {
$sql = file_get_contents($file);
try {
$pdo->exec($sql);
echo "Successfully ran migration: " . basename($file) . "<br>";
} catch (PDOException $e) {
echo "Error running migration: " . basename($file) . " - " . $e->getMessage() . "<br>";
}
}
// Self-destruct
unlink(__FILE__);
echo "<br>All migrations have been processed. This script has been deleted.";