Files
controls-web/lasuca/grower-files.php
2026-02-17 09:29:34 -06:00

360 lines
14 KiB
PHP

<?php
// phpcs:ignoreFile
require_once __DIR__ . '/grower-session.php';
require_once __DIR__ . '/inc/grower_helpers.php';
$username = isset($_SESSION['myusername']) ? trim($_SESSION['myusername']) : '';
if ($username === '') {
header('Location: /grower-login.php');
exit();
}
function grower_normalize_relative_path_local($path)
{
$path = str_replace('\\', '/', $path);
$segments = explode('/', $path);
$safeSegments = array();
foreach ($segments as $segment) {
if ($segment === '' || $segment === '.') {
continue;
}
if ($segment === '..') {
array_pop($safeSegments);
continue;
}
$safeSegments[] = $segment;
}
return implode('/', $safeSegments);
}
function grower_build_web_path($username, $relativePath)
{
$segments = array_merge(array($username), explode('/', str_replace('\\', '/', $relativePath)));
$segments = array_filter($segments, 'strlen');
$encoded = array_map('rawurlencode', $segments);
return 'growers/' . implode('/', $encoded);
}
$folderParam = isset($_GET['folder']) ? $_GET['folder'] : '';
$currentRelativeFolder = '';
$errors = array();
if ($folderParam !== '') {
$decoded = base64_decode($folderParam, true);
if ($decoded === false) {
$errors[] = 'The folder path you requested is invalid.';
} else {
$currentRelativeFolder = grower_normalize_relative_path_local($decoded);
}
}
$rootDir = __DIR__;
$baseDir = realpath($rootDir . '/growers/' . $username);
if ($baseDir === false || !is_dir($baseDir)) {
$errors[] = 'We could not find your grower folder yet. Please contact support for assistance.';
}
$currentDirectory = $baseDir;
if ($currentRelativeFolder !== '' && $baseDir !== false) {
$candidate = realpath($baseDir . '/' . $currentRelativeFolder);
if ($candidate === false || strpos($candidate, $baseDir) !== 0) {
$errors[] = 'That folder is no longer available. Displaying your main folder instead.';
$currentRelativeFolder = '';
} else {
$currentDirectory = $candidate;
}
}
$directories = array();
$files = array();
$totalFileSize = 0;
if ($currentDirectory !== false && is_dir($currentDirectory)) {
$items = scandir($currentDirectory);
if ($items === false) {
$errors[] = 'We could not read the contents of this folder.';
} else {
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$absoluteItem = $currentDirectory . DIRECTORY_SEPARATOR . $item;
$relativeItem = $currentRelativeFolder === '' ? $item : $currentRelativeFolder . '/' . $item;
$relativeItem = grower_normalize_relative_path_local($relativeItem);
if (is_dir($absoluteItem)) {
$itemCount = 0;
try {
$iterator = new FilesystemIterator($absoluteItem, FilesystemIterator::SKIP_DOTS);
foreach ($iterator as $unused) {
$itemCount++;
}
} catch (UnexpectedValueException $exception) {
$itemCount = 0;
}
$directories[] = array(
'name' => $item,
'encoded' => rawurlencode(base64_encode($relativeItem)),
'webPath' => '/' . grower_build_web_path($username, $relativeItem),
'items' => $itemCount,
'modified' => @filemtime($absoluteItem)
);
} elseif (is_file($absoluteItem)) {
$size = @filesize($absoluteItem);
$modified = @filemtime($absoluteItem);
$files[] = array(
'name' => $item,
'size' => ($size === false) ? 0 : $size,
'modified' => $modified,
'webPath' => '/' . grower_build_web_path($username, $relativeItem)
);
if ($size !== false) {
$totalFileSize += $size;
}
}
}
}
}
usort($directories, function ($a, $b) {
return strcasecmp($a['name'], $b['name']);
});
usort($files, function ($a, $b) {
return strcasecmp($a['name'], $b['name']);
});
$directoryCount = count($directories);
$fileCount = count($files);
$breadcrumbs = array();
$breadcrumbs[] = array('label' => 'Home', 'url' => 'grower-files.php');
if ($currentRelativeFolder !== '') {
$segments = explode('/', $currentRelativeFolder);
$compound = array();
$lastIndex = count($segments) - 1;
foreach ($segments as $index => $segment) {
$compound[] = $segment;
$encodedPath = rawurlencode(base64_encode(implode('/', $compound)));
$breadcrumbs[] = array(
'label' => $segment,
'url' => ($index === $lastIndex) ? null : 'grower-files.php?folder=' . $encodedPath
);
}
}
$parentLink = '';
if ($currentRelativeFolder !== '') {
$segments = explode('/', $currentRelativeFolder);
array_pop($segments);
$parentRelative = implode('/', $segments);
if ($parentRelative === '') {
$parentLink = 'grower-files.php';
} else {
$parentLink = 'grower-files.php?folder=' . rawurlencode(base64_encode($parentRelative));
}
}
$pageTitle = 'Grower File Browser';
$metaDescription = 'Browse and download load reports, tickets, and documents from your LASUCA grower folder.';
?>
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8" />
<title><?php echo htmlspecialchars($pageTitle, ENT_QUOTES, 'UTF-8'); ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="<?php echo htmlspecialchars($metaDescription, ENT_QUOTES, 'UTF-8'); ?>" />
<link rel="icon" type="image/x-icon" href="/images/favicon.ico" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/new/css/styles.css" />
<link rel="stylesheet" href="/new/css/lasuca-theme.css" />
<link rel="stylesheet" href="/new/css/pages.css" />
<link rel="stylesheet" href="/new/css/grower-portal.css" />
<link rel="stylesheet" href="/new/css/grower-dashboard.css" />
</head>
<body class="lasuca-theme theme-dark grower-portal">
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container">
<a class="navbar-brand" href="/grower-dashboard.php">
<img src="/images/logo2.png" alt="LASUCA logo" />
<span>Grower Portal</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#growerNav" aria-controls="growerNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="growerNav">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item"><a class="nav-link" href="/home.php">Home</a></li>
<li class="nav-item"><a class="nav-link" href="/grower-dashboard.php">Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="/grower-files.php">Daily Reports</a></li>
<li class="nav-item"><a class="nav-link" href="/grower-account.php">Manage Account</a></li>
<li class="nav-item"><a class="nav-link" href="/grower-logout.php">Log Out</a></li>
<?php include __DIR__ . '/inc/theme-toggle.php'; ?>
</ul>
</div>
</div>
</nav>
<main>
<header class="hero hero-sub">
<div class="container">
<span class="badge">Grower portal</span>
<h1>Your grower files</h1>
<p>
Navigate your secure LASUCA folder to download daily transaction reports. Use the
buttons below to jump between folders.
</p>
</div>
</header>
<section class="page-section py-5">
<div class="container">
<div class="grower-files-card">
<div class="file-browser-header">
<div>
<p class="file-browser-summary mb-1">
Currently viewing:
<strong><?php echo $currentRelativeFolder === '' ? 'Home' : htmlspecialchars($currentRelativeFolder, ENT_QUOTES, 'UTF-8'); ?></strong>
</p>
<p class="file-browser-summary mb-0">
<?php echo $directoryCount; ?> folder<?php echo $directoryCount === 1 ? '' : 's'; ?> ·
<?php echo $fileCount; ?> file<?php echo $fileCount === 1 ? '' : 's'; ?> ·
Total size <?php echo htmlspecialchars(grower_format_filesize($totalFileSize), ENT_QUOTES, 'UTF-8'); ?>
</p>
</div>
<div class="file-browser-actions">
<?php if ($parentLink !== '') { ?>
<a class="btn btn-outline-success" href="<?php echo htmlspecialchars($parentLink, ENT_QUOTES, 'UTF-8'); ?>">&larr; Up one level</a>
<?php } ?>
</div>
</div>
<nav aria-label="Breadcrumb">
<ol class="breadcrumb mb-3">
<?php foreach ($breadcrumbs as $crumb) {
$label = htmlspecialchars($crumb['label'], ENT_QUOTES, 'UTF-8');
if ($crumb['url'] !== null) { ?>
<li class="breadcrumb-item"><a href="<?php echo htmlspecialchars($crumb['url'], ENT_QUOTES, 'UTF-8'); ?>"><?php echo $label; ?></a></li>
<?php } else { ?>
<li class="breadcrumb-item active" aria-current="page"><?php echo $label; ?></li>
<?php }
} ?>
</ol>
</nav>
<?php if (!empty($errors)) { ?>
<div class="mb-3">
<?php foreach ($errors as $error) { ?>
<div class="alert alert-warning" role="alert"><?php echo htmlspecialchars($error, ENT_QUOTES, 'UTF-8'); ?></div>
<?php } ?>
</div>
<?php } ?>
<?php if ($directoryCount === 0 && $fileCount === 0) { ?>
<div class="file-empty">
<p>We didn&rsquo;t find any items in this folder yet. Drop files into your grower directory or check back after the next reporting cycle.</p>
</div>
<?php } else { ?>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col" class="text-nowrap">Details</th>
<th scope="col" class="text-nowrap">Updated</th>
<th scope="col" class="text-end">Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($directories as $directory) {
$dirName = htmlspecialchars($directory['name'], ENT_QUOTES, 'UTF-8');
$dirUrl = 'grower-files.php?folder=' . htmlspecialchars($directory['encoded'], ENT_QUOTES, 'UTF-8');
$modifiedLabel = $directory['modified']
? htmlspecialchars(grower_format_datetime(date('Y-m-d H:i:s', $directory['modified'])), ENT_QUOTES, 'UTF-8')
: 'Unknown'; ?>
<tr>
<td class="fw-semibold">
<span class="badge bg-success-subtle text-success me-2">Folder</span>
<a class="text-decoration-none" href="<?php echo $dirUrl; ?>"><?php echo $dirName; ?></a>
</td>
<td><?php echo (int) $directory['items']; ?> item<?php echo $directory['items'] === 1 ? '' : 's'; ?></td>
<td><?php echo $modifiedLabel; ?></td>
<td class="text-end">
<a class="btn btn-sm btn-outline-success" href="<?php echo $dirUrl; ?>">Open</a>
</td>
</tr>
<?php }
foreach ($files as $file) {
$fileName = htmlspecialchars($file['name'], ENT_QUOTES, 'UTF-8');
$fileSize = htmlspecialchars(grower_format_filesize($file['size']), ENT_QUOTES, 'UTF-8');
$filePath = htmlspecialchars($file['webPath'], ENT_QUOTES, 'UTF-8');
$modifiedLabel = $file['modified']
? htmlspecialchars(grower_format_datetime(date('Y-m-d H:i:s', $file['modified'])), ENT_QUOTES, 'UTF-8')
: 'Unknown'; ?>
<tr>
<td class="fw-semibold">
<span class="badge bg-primary-subtle text-primary me-2">File</span>
<a class="text-decoration-none" href="<?php echo $filePath; ?>" target="_blank" rel="noopener">
<?php echo $fileName; ?>
</a>
</td>
<td><?php echo $fileSize; ?></td>
<td><?php echo $modifiedLabel; ?></td>
<td class="text-end">
<a class="btn btn-sm btn-outline-primary" href="<?php echo $filePath; ?>" target="_blank" rel="noopener">Download</a>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<?php } ?>
</div>
</div>
</section>
</main>
<footer class="lasuca-footer">
<div class="container">
<div class="row g-3 align-items-center">
<div class="col-md-6">
<strong>Louisiana Sugar Cane Cooperative</strong><br />
341 Sugar Mill Road &middot; St. Martinville, LA 70582
</div>
<div class="col-md-6 text-md-end">
<small>&copy; <?php echo date('Y'); ?> LASUCA. All rights reserved.</small>
</div>
</div>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="/new/js/scripts.js"></script>
</body>
</html>