DSP Project first push, date: 29/01/2026
This commit is contained in:
341
data_user/browse_datasources.php
Normal file
341
data_user/browse_datasources.php
Normal file
@@ -0,0 +1,341 @@
|
||||
<?php
|
||||
|
||||
// data_user/browse_datasources.php
|
||||
// This page allows users (including guests) to browse available data sources.
|
||||
|
||||
// Enable detailed error reporting for debugging purposes (log only)
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 0);
|
||||
|
||||
// Check if a session is not already active before starting one.
|
||||
// This prevents the "session already active" notice.
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
// Use __DIR__ to get the absolute path to this file's directory,
|
||||
// ensuring the path to the required files is always correct.
|
||||
require_once(__DIR__ . '/../config.php');
|
||||
require_once(__DIR__ . '/../includes/auth.php');
|
||||
require_once(__DIR__ . '/../classes/DataSource.php');
|
||||
require_once(__DIR__ . '/../classes/Classifications.php');
|
||||
require_once(__DIR__ . '/../classes/User.php');
|
||||
require_once(__DIR__ . '/../classes/Permission.php'); // Correctly include the Permission class
|
||||
|
||||
// Check if user is logged in
|
||||
$is_logged_in = isset($_SESSION['user_id']);
|
||||
$user_id = $_SESSION['user_id'] ?? null;
|
||||
$person_id = $_SESSION['person_id'] ?? null;
|
||||
$username = $_SESSION['username'] ?? null;
|
||||
$usernameLabel = $username ? htmlspecialchars($username, ENT_QUOTES, 'UTF-8') : 'Guest';
|
||||
|
||||
$currentPage = basename($_SERVER['PHP_SELF']);
|
||||
|
||||
// Instantiate classes
|
||||
$dataSourceManager = new DataSource($pdo);
|
||||
$classificationManager = new Classifications($pdo);
|
||||
$userManager = new User($pdo);
|
||||
$permissionManager = new Permission($pdo); // Instantiate the Permission class
|
||||
|
||||
// Get user details if logged in
|
||||
$currentUserDetails = $is_logged_in ? $userManager->getUserDetails($user_id) : null;
|
||||
|
||||
$uploadsWebPath = '../uploads/datasources/';
|
||||
|
||||
// Get filter parameters from GET request
|
||||
$filter_category_id = $_GET['category_id'] ?? null;
|
||||
if ($filter_category_id !== null) {
|
||||
$filter_category_id = filter_var($filter_category_id, FILTER_VALIDATE_INT);
|
||||
if ($filter_category_id === false) {
|
||||
$filter_category_id = null;
|
||||
}
|
||||
}
|
||||
$search_query = htmlspecialchars($_GET['search'] ?? '', ENT_QUOTES, 'UTF-8');
|
||||
|
||||
// Fetch data sources based on filters
|
||||
$data_sources = [];
|
||||
try {
|
||||
$data_sources = $dataSourceManager->getDataSources(
|
||||
null, // No owner filter for public browsing
|
||||
'Active',
|
||||
$filter_category_id,
|
||||
$search_query
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
set_message('Error retrieving data sources: ' . $e->getMessage(), 'danger');
|
||||
}
|
||||
|
||||
// Fetch all categories for the filter dropdown
|
||||
$all_categories = [];
|
||||
try {
|
||||
$all_categories = $classificationManager->getAllCategories();
|
||||
} catch (Exception $e) {
|
||||
error_log("Error fetching categories for browse_datasources: " . $e->getMessage());
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!-- Header -->
|
||||
<?php
|
||||
// Include header file for admin pages
|
||||
include_once("../includes/header_user.php");
|
||||
?>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<!-- Sidebar -->
|
||||
<?php
|
||||
// Include header file for admin pages
|
||||
include_once("../includes/nav_user.php");
|
||||
?>
|
||||
<!-- Page Content -->
|
||||
<div class="main-content">
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light mb-4 rounded-3">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#"> Browse All Data</a>
|
||||
<div class="d-flex">
|
||||
<span class="navbar-text me-3">
|
||||
Welcome, <?php echo $usernameLabel; ?>!
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<?php if (isset($_SESSION['message'])): ?>
|
||||
<div class="alert alert-<?= $_SESSION['message_type'] ?> alert-dismissible fade show rounded" role="alert">
|
||||
<?= $_SESSION['message'] ?>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<?php
|
||||
unset($_SESSION['message']);
|
||||
unset($_SESSION['message_type']);
|
||||
?>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Filter and Search Form -->
|
||||
<div class="card shadow-sm rounded mb-4 p-3">
|
||||
<div class="card-body">
|
||||
<form action="browse_datasources.php" method="GET" class="row g-3 align-items-end">
|
||||
<div class="col-md-4">
|
||||
<label for="categoryFilter" class="form-label">Filter by Category:</label>
|
||||
<select class="form-select rounded" id="categoryFilter" name="category_id">
|
||||
<option value="">All Categories</option>
|
||||
<?php foreach ($all_categories as $category): ?>
|
||||
<option value="<?php echo htmlspecialchars($category['pkdspscate_id']); ?>"
|
||||
<?php echo ($filter_category_id == $category['pkdspscate_id']) ? 'selected' : ''; ?>>
|
||||
<?php echo htmlspecialchars($category['dspscate_title_en']); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<label for="searchQuery" class="form-label">Search by Title/Description:</label>
|
||||
<input type="text" class="form-control rounded" id="searchQuery" name="search"
|
||||
value="<?php echo htmlspecialchars($search_query); ?>" placeholder="Enter keywords...">
|
||||
</div>
|
||||
<div class="col-md-3 d-grid">
|
||||
<button type="submit" class="btn btn-primary rounded">
|
||||
<i class="fas fa-filter me-2"></i> Apply Filters
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Data Sources List -->
|
||||
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4 mt-4">
|
||||
<?php if (!empty($data_sources)): ?>
|
||||
<?php foreach ($data_sources as $ds): ?>
|
||||
<div class="col">
|
||||
<div class="card h-100 shadow-sm rounded">
|
||||
<div class="card-body d-flex flex-column">
|
||||
<h5 class="card-title text-primary"><?php echo htmlspecialchars($ds['dspsds_title_en']); ?></h5>
|
||||
<h6 class="card-subtitle mb-2 text-muted">Category: <?php echo htmlspecialchars($ds['category_name']); ?></h6>
|
||||
<h6 class="card-subtitle mb-2 text-muted">Type: <?php echo htmlspecialchars($ds['data_type_name']); ?></h6>
|
||||
<p class="card-text flex-grow-1"><?php echo htmlspecialchars(substr($ds['dspsds_description'], 0, 150)) . (strlen($ds['dspsds_description']) > 150 ? '...' : ''); ?></p>
|
||||
<div class="mt-auto">
|
||||
<ul class="list-unstyled small text-muted">
|
||||
<li><i class="fas fa-user me-1"></i> Data Owner: <?php echo htmlspecialchars($ds['isp_firstname_en'] . ' ' . $ds['isp_lastname_en']); ?></li>
|
||||
<li><i class="fas fa-calendar-alt me-1"></i> Published:
|
||||
<?php if (!empty($ds['dspsds_public_date'])): ?>
|
||||
<?= htmlspecialchars(date('M d, Y', strtotime($ds['dspsds_public_date']))); ?>
|
||||
<?php else: ?>
|
||||
Not specified
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
</ul>
|
||||
<?php
|
||||
$supportingFiles = [
|
||||
'dspsds_filename1' => ['label' => 'Questionnaire / Data Dictionary', 'icon' => 'fa-clipboard-list'],
|
||||
'dspsds_filename2' => ['label' => 'Protocol / User Guide', 'icon' => 'fa-book'],
|
||||
'dspsds_filename3' => ['label' => 'Other Supporting Document', 'icon' => 'fa-file-alt'],
|
||||
];
|
||||
?>
|
||||
<div class="bg-light-subtle border rounded p-3 mb-3">
|
||||
<span class="d-block text-uppercase text-muted fw-semibold small mb-2">Supporting Documents</span>
|
||||
<ul class="list-unstyled mb-0 small">
|
||||
<?php foreach ($supportingFiles as $column => $meta): ?>
|
||||
<?php
|
||||
$fileName = $ds[$column] ?? '';
|
||||
$label = $meta['label'];
|
||||
$icon = $meta['icon'];
|
||||
?>
|
||||
<li class="mb-2">
|
||||
<i class="fas <?= htmlspecialchars($icon, ENT_QUOTES, 'UTF-8') ?> me-1"></i>
|
||||
<?php if (!empty($fileName)): ?>
|
||||
<?php
|
||||
$isUrl = preg_match('/^https?:\/\//i', $fileName) === 1;
|
||||
$linkTarget = $isUrl ? $fileName : $uploadsWebPath . rawurlencode($fileName);
|
||||
?>
|
||||
<a href="<?= htmlspecialchars($linkTarget, ENT_QUOTES, 'UTF-8') ?>" target="_blank" rel="noopener">
|
||||
<?= htmlspecialchars($label) ?>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<span class="text-muted"><?= htmlspecialchars($label) ?> (Not provided)</span>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php if ($is_logged_in): ?>
|
||||
<?php
|
||||
$has_read_permission = false;
|
||||
$has_download_permission = false;
|
||||
try {
|
||||
$has_read_permission = $permissionManager->hasPermission($person_id, $ds['pkdspsds_id'], 'Read');
|
||||
$has_download_permission = $permissionManager->hasPermission($person_id, $ds['pkdspsds_id'], 'Download');
|
||||
} catch (Exception $e) {
|
||||
error_log("Permission check error for user " . $person_id . " on DS " . $ds['pkdspsds_id'] . ": " . $e->getMessage());
|
||||
}
|
||||
?>
|
||||
<?php if ($has_read_permission): ?>
|
||||
<a href="#" class="btn btn-sm btn-outline-success rounded me-2 disabled">
|
||||
<i class="fas fa-check-circle me-1"></i> Read Access Granted
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<button type="button" class="btn btn-sm btn-success rounded me-2" data-bs-toggle="modal" data-bs-target="#requestPermissionModal"
|
||||
data-ds-id="<?php echo htmlspecialchars($ds['pkdspsds_id']); ?>"
|
||||
data-ds-title="<?php echo htmlspecialchars($ds['dspsds_title_en']); ?>"
|
||||
data-permission-type="Read">
|
||||
<i class="fas fa-file-alt me-1"></i> Request Read Access
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($has_download_permission): ?>
|
||||
<a href="download.php?dspsds_id=<?php echo htmlspecialchars($ds['pkdspsds_id']); ?>" class="btn btn-sm btn-outline-primary rounded">
|
||||
<i class="fas fa-download me-1"></i> Download File
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<button type="button" class="btn btn-sm btn-primary rounded" data-bs-toggle="modal" data-bs-target="#requestPermissionModal"
|
||||
data-ds-id="<?php echo htmlspecialchars($ds['pkdspsds_id']); ?>"
|
||||
data-ds-title="<?php echo htmlspecialchars($ds['dspsds_title_en']); ?>"
|
||||
data-permission-type="Download">
|
||||
<i class="fas fa-cloud-download-alt me-1"></i> Request Download
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<button type="button" class="btn btn-sm btn-secondary rounded" data-bs-toggle="modal" data-bs-target="#loginModal">
|
||||
<i class="fas fa-sign-in-alt me-1"></i> Login to Request Access
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<div class="col-12">
|
||||
<div class="alert alert-info rounded text-center">
|
||||
No active data sources found matching your criteria.
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Request Permission Modal -->
|
||||
<div class="modal fade" id="requestPermissionModal" tabindex="-1" aria-labelledby="requestPermissionModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content rounded shadow-lg">
|
||||
<div class="modal-header bg-success text-white rounded-top">
|
||||
<h5 class="modal-title" id="requestPermissionModalLabel">Request Data Access Permission</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body p-4">
|
||||
<form action="../data_user/process_request_permission.php" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="data_source_id" id="modalDataSourceId">
|
||||
<input type="hidden" name="permission_type" id="modalPermissionType">
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="modalDataSourceTitle" class="form-label">Data Source</label>
|
||||
<input type="text" class="form-control rounded" id="modalDataSourceTitle" readonly>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="modalRequestedPermission" class="form-label">Requested Permission</label>
|
||||
<input type="text" class="form-control rounded" id="modalRequestedPermission" readonly>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="requestNotes" class="form-label">Reason for Request (Required)</label>
|
||||
<textarea class="form-control rounded-3" id="requestNotes" name="notes" rows="4" placeholder="Please explain why you need this data and how you plan to use it." required></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="proofFile" class="form-label">Upload Proof (PDF only)</label>
|
||||
<input type="file" class="form-control rounded" id="proofFile" name="proof_file" accept="application/pdf" required>
|
||||
<div class="form-text">Attach an official letter, approval memo, or supporting document in PDF format (max 10 MB).</div>
|
||||
</div>
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-success rounded">Submit Request</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Login Modal for guests -->
|
||||
<div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="loginModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content rounded shadow-lg">
|
||||
<div class="modal-header bg-primary text-white rounded-top">
|
||||
<h5 class="modal-title" id="loginModalLabel">Login Required</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center p-4">
|
||||
<p>You must be logged in to request access to data sources.</p>
|
||||
<a href="../index.php?page=login" class="btn btn-primary rounded me-2">Login</a>
|
||||
<a href="../index.php?page=register" class="btn btn-outline-primary rounded">Register</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<?php
|
||||
// Include Footer file for owner pages
|
||||
include_once("../includes/footer_user.php");
|
||||
?>
|
||||
<script>
|
||||
// JavaScript to populate the permission request modal
|
||||
var requestPermissionModal = document.getElementById('requestPermissionModal');
|
||||
if (requestPermissionModal) {
|
||||
requestPermissionModal.addEventListener('show.bs.modal', function (event) {
|
||||
var button = event.relatedTarget; // Button that triggered the modal
|
||||
var dsId = button.getAttribute('data-ds-id');
|
||||
var dsTitle = button.getAttribute('data-ds-title');
|
||||
var permissionType = button.getAttribute('data-permission-type');
|
||||
|
||||
var modalDataSourceId = requestPermissionModal.querySelector('#modalDataSourceId');
|
||||
var modalDataSourceTitle = requestPermissionModal.querySelector('#modalDataSourceTitle');
|
||||
var modalPermissionType = requestPermissionModal.querySelector('#modalPermissionType');
|
||||
var modalRequestedPermission = requestPermissionModal.querySelector('#modalRequestedPermission');
|
||||
|
||||
modalDataSourceId.value = dsId;
|
||||
modalDataSourceTitle.value = dsTitle;
|
||||
modalPermissionType.value = permissionType;
|
||||
modalRequestedPermission.value = permissionType; // Display the type in the modal
|
||||
requestPermissionModal.querySelector('#requestNotes').value = ''; // Clear notes on new open
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user