All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog,
and this project adheres to Semantic Versioning.
- Optional HTTP security headers (PHP) —
security_headers_mode:off(default),recommended, orstrict(adds CSP tuned for this codebase, including Activity chart CDN). Documented in README; example snippets inexamples/nginx-security-headers.confandexamples/apache-security-headers.conf. - Environment override —
DATADOCK_SECURITY_HEADERS=off|recommended|strict(seeincludes/settings_loader.php). - “Remember this device” (login) — Optional longer session cookie only (no separate token store); respects idle timeout. Configurable in Admin → Site Settings (
remember_device.enabled,cookie_days). Registration still uses a normal session finalize without remember. - Idle session expiry UX — After idle timeout, users are redirected to login with a clear notice (
?reason=idle).
- Session cookie parameters — Removed an eager
session_start()inincludes/auth.phpthat ran beforesession_set_cookie_params(), sohttponly,secure,SameSite, and lifetime from Site Settings now apply.
- Session hardening —
session.use_strict_mode,session.use_only_cookies, HTTPS detection viaX-Forwarded-Proto,session_regenerate_id(true)on successful login (and registration), and coordinatedsession.gc_maxlifetimewhen remember-device is available.
- Markdown parser links —
basic_markdown()now parses standard markdown links more reliably in updater/release-note content, including relative links (not just absolutehttp(s)URLs). - Absolute URL resolution — Relative markdown links are now resolved against a configured base URL in the admin updater/changelog view, so links remain clickable and correct outside the repository context.
- Changelog reference — Full notes: see CHANGELOG.md.
- UI hotfix (v2.4.1) — Repaired corrupted
assets/style.cssand related frontend rendering regressions introduced afterv2.4.0. - Docker bootstrap reliability — Added
docker-entrypoint.shruntime bootstrapping soconfig/db.phpis created from the example when missing and refreshed for Docker-basedDATADOCK_DB_*setups. - Container install defaults — Installer DB prefill now reads generated runtime DB config (
config/.db-runtime.php) or environment values so Docker installs avoid incorrect localhost/socket defaults.
- Database configuration fallback —
includes/db.phpandhealth.phpnow gracefully fall back toconfig/db.php.exampleand return clearer guidance when DB config is missing. - Docker CI/CD tagging — Docker publish workflow now builds on pushes to
main/master(rollingdev+ SHA tags), while SemVer andlatesttags remain release-driven. - Container templates/docs — Updated Docker and compose examples (
Dockerfile,docker-compose*.yml,config/db.php.example) and added runtime config generation scriptscripts/generate-db-runtime.php.
- Temporary share folders — Select multiple files on the dashboard → bulk action Create share folder link; optional title, expiry, and recipient note per file (shown on the public page only). Public URL:
share_folder.php?t=…; downloads usedownload.php?sf=…&id=…. Thumbnails honor the samesftoken. Revoke links from the dashboard. Expired bundles are removed by the cron purge (or--no-share-foldersto skip). - Read-only / archive mode — Admin → Site Settings (or
DATADOCK_READ_ONLY=1): blocks uploads, registration, guest uploads, signup-token generation, and file mutations; downloads and viewing remain. Nav hides Upload/Register when appropriate. - Environment-based config —
includes/settings_loader.phpmergesDATADOCK_*env vars overconfig/settings.phpat runtime (seeconfig/settings.php.example). - CLI installer —
scripts/datadock-install.phpfor non-interactive installs (--db-host=…,--admin-password=…, orDD_*env vars). Webinstall.phpuses sharedincludes/install_lib.php. - Docker —
Dockerfileanddocker-compose.example.yml(PHP 8.2 + Apache + MySQL example). GitHub Actions (.github/workflows/docker-publish.yml) builds and pushes to Docker Hub when a Release is published; set secretsDOCKERHUB_USERNAMEandDOCKERHUB_TOKEN. Optional variableDOCKERHUB_IMAGEoverrides the defaultUSERNAME/datadockimage name. - Health check —
health.phpreturns JSON:status,version,database(503 if DB unreachable).
- New tables
share_folders,share_folder_files. Site reset deletesshare_folders.
- Per-file download password & IP allowlist — Optional
access_password_hashandip_allowliston Edit file; anonymous downloads (public listing, token links, signed links) enforce IP rules; password gate with session unlock viadownload.phpPOST. Thumbnails respect the same rules for anonymous users. - Share link (token) — Replaces one-shot-only tokens:
download_tokensgainsexpires_at,max_uses, anduse_count. Create share link (create_onetime.php) configures time window and max downloads. - Signed link (HMAC) —
create_signed.phpbuilds time-limiteddownload.php?id=&exp=&sig=URLs validated with a server secret inapp_secrets(no extra token row). IP allowlist still applies; signed links bypass the optional file password (the URL is the capability). - Per-download log —
file_download_events(IP, optional country fromCF-IPCountrywhen present) for transparency on who fetched your files. - Activity & storage —
activity.php: storage-over-time chart (user_storage_snapshots, at most one sample per user per hour), recent download events, uploads list.export_data.php: JSON export of account fields, file metadata, activity log rows where you are the actor, and download events for files you own.
- Migrations add
files.access_password_hash,files.ip_allowlist, extenddownload_tokens, new tablesapp_secrets,file_download_events,user_storage_snapshots. Site reset clearsapp_secretsanduser_storage_snapshots.
- User file reporting — New
report_file.phpflow for logged-in users to report accessible non-owned files (shared or public) with reason + optional details. Reports are persisted in new tablefile_reports(open,dismissed,actioned) and duplicate open reports by the same user for the same file are prevented. - Admin moderation queue — New Admin → Reports & moderation section with status filters, pagination, reporter/file context, and review notes. Open reports can be dismissed, quarantined, or deleted to trash.
- Moderation actions logged — Activity log now records
report_file,admin_report_dismiss, andadmin_report_actionevents for auditability.
- Public file list (
index.php) and dashboard shared file actions now include Report entry points for signed-in users. - Site reset now clears
file_reports.
- Activity / audit log — New
activity_logtable andincludes/audit_log.php. Records uploads, downloads (including public and one-time links), ZIP downloads, one-time link creation, share add/remove, trash/permanent delete, bulk delete to trash, restore, admin purge actions, checksum re-hash runs, and quarantine approval. Admin → Activity log lists recent events with actor, file, detail JSON, and IP; optional purge of entries older than N days. - Storage & quota alerts — Site Settings → Operational alerts: enable warnings when a storage partition’s filesystem is above a usage threshold, or when users or guest sessions approach file-count or storage quotas. Shown on Admin → Overview alongside existing notices.
- Backup / export — Admin → Backup & integrity:
backup_download.php(admin-only) streams a full SQL dump (all tables,FOREIGN_KEY_CHECKSdisabled for restore) or a JSON export offilesmetadata for DR planning. - Background purge via cron —
scripts/datadock-cron-purge.phppurges expired files and trash past retention (same logic as Admin → File Management). Optional flags--no-trashand--no-expired. Admin UI purge uses shared helpers inincludes/purge_ops.php. - Disk usage integrity checker — Backup & integrity → scan uploads vs database: lists DB files missing on disk and on-disk blobs not referenced by the DB (per storage partition).
- File integrity verification — Verify stored MD5/SHA256 against bytes on disk (optional row limit). Re-hash from disk recomputes checksums and updates the database (optional limit); intended after storage repair or corruption checks.
- Reset site clears
activity_logwhen present. - Default
settings.phptemplate includesops_alerts(new installs andwrite_default_settings_file()).
- Hotlink log — Optional logging when downloads, ZIP downloads, thumbnails, or avatars are requested with a
Refererfrom another hostname (Admin → Hotlink log). Same-site and empty referers are skipped. Site Settings: Hotlink monitoring (enable/disable, extra trusted hostnames for CDNs). Tablehotlink_log; migrations and reset site clear it.
- Folders — Nested folders per user (
parent_idwith0= root). Dashboard breadcrumb, subfolder links, create folder, and move file via the Actions menu. Filter bar preserves folder scope; uploads can target the current folder (upload.php?folder=or “Upload to this folder”). - Tags — Comma-separated tags on Edit file; optional tag filter on the dashboard when tags exist. Settings can disable tags or folders independently.
- Storage partitions — Multiple storage roots (
storage_partitions); each root uses the same layout as the site default (uploads/,thumbnails/). Empty partition root inherits Custom Storage Base Path from Site Settings. Admin Storage partitions lists usage and sets the default partition. User Management assigns a user to a partition (new uploads use that root; existing files stay where they are until moved by re-upload or admin tooling). - Deduplication — Optional SHA-256 deduplication per partition (
storage_objects+files.storage_object_id): identical content reuses one on-disk file and increments reference counts. Site setting Deduplicate by SHA-256 (with hidden-field safe defaults). Deletes and purges decrement refs and remove the blob when the last reference is gone. - Disk path resolution —
includes/storage.phpcentralizes partition-aware paths for downloads, thumbnails, ZIP, one-time links, delete/purge, and uploads.
- Database migrations add
storage_partitions,storage_objects,folders,tags,file_tags, and extendfiles/users. Fresh installs pick this up on first DB connection after deploy. - Reset site clears
storage_objectsandfolders/tags, and empties uploads/thumbnails under every partition root. - Delete user (admin) releases on-disk storage for that user’s files before removing the account.
- Dashboard folder create and file move use same-page POST (
includes/dashboard_actions.php) so subdirectories and servers with oddSCRIPT_NAME/ rewrites do not 404 on separate endpoints.
- Upload hardening — Rejects filenames where any dotted segment is an executable/server extension (e.g.
evil.php.jpg). For common image extensions, requires MIME + magic bytes to match the extension, and scans image/SVG bodies (first 512KB–1MB) for embedded<?php/<?=/ short open tags (blocks GIF/JPEG polyglot webshells). Expanded forbidden extension list (e.g.phps,pht,ashx,jspf). Client-side upload UI mirrors segment checks.
- File search and filter — Dashboard filter bar: search by filename or description; filter by upload date range, file type (MIME), visibility (public/private when public browsing is on), and expiry (has expiry / no expiry). Uses a shared query helper reused for metadata and trash.
- File metadata editing — Edit in file actions opens
edit_file.php: change display name, optional description (max 500 chars), and expiry (Never, Keep current, or preset durations). File on disk is unchanged. - Soft delete / trash — Deleting a file (single or bulk) moves it to Trash instead of removing it. Trash page lists deleted files with Restore and Delete permanently. Restore returns the file to Your Files. Site setting Trash retention (days) (default 30): files older than that are eligible for Purge Trash in Admin → File Management. Set to 0 to keep trash until manually purged.
- Database:
files.description(VARCHAR 500, optional),files.deleted_at(DATETIME NULL, indexed). Migrations and fresh installs include the new columns. - All file lists and download/share/one-time flows exclude trashed files (
deleted_at IS NULL). Quota and stats count only non-trashed files. - Admin File Management: list excludes trashed by default; Purge Trash button runs retention-based purge (or purges all trashed if retention is 0). Purge Expired Files only purges non-trashed expired files.
- Admin Site Settings: Trash retention (days) under Upload & Session (0–3650). Default 30.
- Nav: Trash link for logged-in users. Config/settings:
trash_retention_daysinconfig/settings.php.exampleand default settings writer.
- Rate limiting on uploads — Configurable per-IP and per-user upload throttling. Site setting Upload Rate Limiting with window (minutes), max uploads per IP, and max uploads per user. When exceeded, uploads are blocked with a short message.
- Per-IP upload throttling — Upload events logged in
upload_rate_log; throttle applies by IP for guests and by IP + user for logged-in users. - Adaptive cooldown for failed logins — Progressive lockout by IP across usernames. After repeated failed logins from the same IP (in a configurable window), lockout duration increases (e.g. 5 → 15 → 60 minutes). Site setting Adaptive cooldown under Brute Force; per-IP failure window and steps configurable. Failed attempts now store
ip_addressinlogin_attempts. - Content-Disposition enforcement — Risky MIME types (HTML, SVG, JS, PDF, etc.) are always served with
Content-Disposition: attachmentto prevent inline execution in the browser. Helperis_risky_mime_for_inline()andsend_download_disposition()in download flow. - Optional file extension rewriting — Site setting Store files without original extension: files are stored on disk without the original extension (e.g.
uuidonly); original filename is restored on download. Reduces risk of executing uploaded files by extension on the server. - Upload quarantine mode — Site setting Upload quarantine: new uploads are stored with
quarantine_status = 'pending'and are invisible in public/one-time flows until an admin approves them in File Management. Pending files do not appear on the public index even if marked public. Uploaders see their own pending files on the dashboard with a “Pending approval” badge; Download, Share, One-time link, and Make public are disabled until approved. Admins see Pending / Approved and an Approve action. - Automatic MIME anomaly detection — On upload, extension vs detected MIME is compared; if they don’t match expected mapping, the file is flagged with
mime_anomalyfor admin review. Admin File Management shows a MIME? badge on such files. - Upload page: Accepted file types — Expandable section on the upload page (“Accepted file types”) that lists allowed types by category (Images, Documents, Spreadsheets, Presentations, Archives, Audio, Video, Data & code) with extensions, plus a reminder of the forbidden list. Uses native
<details>/<summary>; no JavaScript required.
- Database migrations:
login_attempts.ip_address, tableupload_rate_log,files.quarantine_status,files.mime_anomaly. New installs and reset get the full schema. - Admin File Management: Status column (Pending/Approved), MIME anomaly badge, Approve button for pending files. Reset Site clears
upload_rate_log. - Dashboard, shared files, download, one-time, public download, share, create-onetime, and download ZIP respect quarantine (only approved files visible or allowed for non-admins). Public index (
index.php) shows only approved files. approve_file.phpadded for admin to approve a single quarantined file.- Known file types expanded — Support for many additional common types across MIME anomaly detection, friendly type labels, and file icons: Images (bmp, tiff, tif, ico, heic, avif), Documents (rtf, odt, epub), Spreadsheets (ods, csv), Presentations (ppt, pptx, odp), Archives (rar, 7z, tar, gz), Audio (ogg, flac, m4a), Video (mov, webm, mkv, avi). Reduces false “MIME?” flags and improves display of file type and icon in lists.
- User profile & account settings — Profile page (
profile.php) with view and edit for username, email, and optional display name; change-password form (current password required). Profile link added to main nav when logged in. - Profile statistics — Private profile shows: files currently stored, storage used, total files/size (all time), expired files count, total downloads, public files count, average file size, files shared with you / shared by you, oldest and newest upload, and top file types and extensions by MIME and extension.
- Public user profile — Public profile page (
user.php?username=…) viewable without login: display name (or username), @username, optional avatar and bio, member since, public file stats (count, total size, total downloads, most common type), and a table of the user’s public files with download link when public browsing is enabled. Usernames across the site (homepage, dashboard, share page, admin user/file management, header) link to the corresponding public profile. - Avatar & bio — Optional profile picture: set by URL (http/https) or upload (JPEG, PNG, GIF, WebP; max 2 MB). Optional bio (max 500 characters). Both editable on profile and shown on public profile. Avatars served via
avatar.php; uploads stored underuploads/avatars/. - Profile completion reminder — When display name, bio, and avatar are all empty, profile page shows a warning flash encouraging users to complete their public profile.
- Invite-only registration — Site setting Invite-only registration in User Permissions. When enabled, new users must use a signup link; admins generate single-use, 7-day tokens from User Management. Table
signup_tokensstores tokens; register flow validates token and marks it used on success. - Password reset flow — Forgot password link on login page; user enters email and receives a one-time reset link (shown on page; no email sent). Reset password page sets new password from token. Admins can generate a reset link for any user from User Management (Copy reset link); table
password_reset_tokenswith 1-hour expiry.
- Skip link — “Skip to main content” link at top of page; visible on keyboard focus for screen-reader and keyboard users.
- ARIA & semantics —
role="banner"on header,aria-label="Main navigation"on nav,id="main-content"androle="main"on main content; flash messages userole="alert"andaria-live="polite"; theme toggle and close buttons havearia-label. - Keyboard focus — Visible focus ring (
:focus-visible) on links, buttons, and form controls; nav links use high-contrast outline. CSS variables--focus-ringand--focus-offsetfor theming.
- Database migrations add
display_name,avatar, andbiotousers, and createsignup_tokensandpassword_reset_tokenstables. New installs get defaultinvite_only_registrationin settings; existing installs receive the new setting via migration/defaults. - Profile stat values use header background colour for consistency. Bio on public profile appears in a dedicated "Bio" card matching other sections. Bio textarea on profile matches width and background of other form fields. Nav "Logout (username)" spacing fixed so the username link has no extra gap (valid HTML and CSS for logout wrap).
- Bulk actions on dashboard — Multi-select files for Zip download, Toggle public/private, and Delete; bulk action dropdown with confirmation for delete.
- File size and storage units in Site Settings — Max file size and max storage per user can be set in bytes, KB, MB, or GB via unit selector; live byte-size hints and server limit display.
- Optional server PHP limit override — New "Server PHP Limits" card in Site Settings: optionally write a
.user.iniin the project root to overrideupload_max_filesizeandpost_max_size; option to remove overrides (delete.user.ini). Effective on next request where supported.
- File display — Dashboard and admin file lists show human-readable dates and sizes; dashboard shows checksum (MD5/SHA256) with copy buttons and file sharing (Share, Public/Private) per file.
- Documentation — Added CONTRIBUTING.md (fork, branch naming, PR workflow), ROADMAP.md (feature checklist and plans), and PRIVACY.md (data handling, no telemetry). ROADMAP legend updated for clearer status symbols (✓ / —).
- Custom storage path support — Configurable
storage_base_pathin Site Settings; uploads and thumbnails can be stored outside the project root (e.g./var/data/datadock). - Public file browsing — Optional anonymous access to uploads; when enabled, files marked "public" appear on the homepage and can be downloaded without logging in.
- User-to-user file sharing — Share files with specific users by username; "Shared with You" section on dashboard; shared users can download and add shared files to ZIP downloads.
- Flat SVG icons — Replaced emoji icons with flat SVG icons across the site (upload, folder, theme toggle, file types, copy, lock, etc.); icons use
assets/icons.svgsprite. - Redesigned upload page — Hero section, improved drop zone with hover/dragover states, card-style options block, refined preview and progress display.
- Responsive sizing — Page sections, titles, and descriptions use
clamp()for better fit at various screen resolutions; file lists have appropriate min-widths and horizontal scroll on small screens. - Admin Site Settings — Card-based layout with grouped sections (General, User Permissions, Storage, Brute Force, etc.); live byte-size hints for storage inputs.
- Admin File Management — Summary bar with file count and total size; cleaner toolbar and table layout.
- Updater & Changelog — Displays only the most recent changelog section; proper semver comparison (shows "up to date" when current version ≥ latest release, e.g. development v1.6.0 vs. stable v1.4.1).
- Thumbnails now served via
thumbnail.phpfor compatibility with custom storage paths. - Upload form shows "Make public" checkbox when public browsing is enabled.
- Dashboard shows Public/Private toggle and Share button per file when applicable.
- File table columns (Downloads, Uploaded) no longer wrap awkwardly; 8-column layout for public browsing with Download button.
- Database migrations add
is_publiccolumn tofilesand createfile_sharestable.
- Site stats overview — Admin panel Overview section: total uploads, storage used, user count, file type breakdown, and files expiring soon.
- Maintenance mode — Block non-admins when enabled; admins can still access the site and log in via login.php.
- Debug mode toggle — Control PHP error reporting and display in Site Settings (disable in production).
- Log file path and verbosity — File-based logging with configurable path and level (debug, info, warning, error).
- Custom logo and favicon URLs — Branding settings for logo image and favicon; templates updated.
- Welcome banner or message — Editable message on homepage.
- Dark mode / light mode toggle — Theme switcher (☀️/🌙) in header; preference saved via cookie; dark theme added.
- Custom file icons — Per-type icon mapping for file lists; defaults for PDF, images, audio, video, etc.; JSON override in settings.
- Admin panel defaults to Overview section; sidebar includes new Overview link.
- File lists (homepage, dashboard, admin) show type-specific icons next to filenames.
- Download counter per file — Count and display downloads in dashboard, admin file management, and homepage.
- File checksum display — MD5 and SHA256 computed on upload; shown with copy buttons in dashboard.
- Zip multiple files for download — Multi-select files on dashboard and download as a single .zip.
- One-time download links — Generate shareable links that expire after one use; token stored in
download_tokenstable. - Download as QR code — One-time link page includes a QR code for easy mobile sharing (via api.qrserver.com).
- Terms of Service / Acceptable Use — Configurable ToS text and checkbox in Site Settings; users must accept before uploading.
- Database migrations run automatically via
includes/db.php; new installs and upgrades adddownload_count,checksum_md5,checksum_sha256columns anddownload_tokenstable. - Dashboard reorganized with select-all checkbox, zip download, and one-time link actions.
- Default file expiry duration — Site setting for upload form; admins can set 1 min, 30 min, 1 hr, 6 hr, 1 day, 1 week, 1 month, 1 year, or never.
- Thumbnail generation toggle — Enable/disable thumbnail creation for image uploads in Site Settings; when off, thumbnails are skipped.
- Configurable session timeout — Site setting for session lifetime in minutes; 0 = until browser close.
- Install.php warning toggle — Option in Site Settings to disable the security warning when
install.phpstill exists. - Admin contact email — Optional field in Site Settings; shown in footer as “Contact Admin” and in Admin Panel sidebar when set.
- Enforce unique email toggle — Toggle strict (disallow duplicate emails) vs relaxed (only username must be unique) in registration. When relaxed, the email UNIQUE constraint is dropped for existing installs; new installs use a non-unique email column.
- Index page now checks for
thumbnail_pathbefore displaying thumbnail, so images without thumbnails (when disabled) render correctly.
- 🛠️ Added
init_session()todownload.phpanddelete.phpso logged-in users can successfully download and delete files. - 🛠️ Corrected settings key mismatch:
upload.phpnow readsuser_limits(withmax_files_enabled,max_storage_enabled) so per-user quotas apply when configured in Site Settings. - 🛠️ Admin can now download and delete any file from the File Management panel (ownership check bypassed for admin role).
- 🛠️ Admin file list and homepage now include guest uploads via
LEFT JOIN; guest files display "Guest" as the user. - 🛠️ Theme map in
header.phpnow only references existing theme files (default,light). - 🛠️ Removed unused
login_ip_attemptstable from installer.
- 🧠 AJAX upload now parses JSON response and displays errors inline instead of blindly redirecting; users see which files failed and why, with redirect delayed on success.
- 🧠 Admin delete from File Management now redirects back to
admin.php?section=filesinstead of dashboard.
- 🛠️ Extraction bug causing
admin_sections/to spill into the root folder. - 🛠️ Subfolders like
includes/andassets/not updating properly after running updater. - 🛠️ Recursive update path incorrectly using first-level folder instead of project root.
- 🛠️ Error thrown when
index.phpwas not found due to invalid root detection. - 🛠️ Dry run would sometimes show inaccurate overwrite targets.
- 🧠 Project root detection now based on
index.phppresence. - 🧪 Dry-run simulation logs enhanced for clarity.
- 🧩 Smart fallback to
.tar.gzwhen.zipisn’t found in release assets. - 🧼 Cleaned up extracted content properly after update.
- ✅ Update now properly skips sensitive directories (
uploads/,config/, etc.) and only touches necessary files.
- Added one-click GitHub updater for automated project updates via Admin Panel.
- Implemented dry-run mode for safe testing of update behavior before applying changes.
- Added release notes viewer using GitHub's latest release API.
- Integrated full changelog viewer, rendering Markdown beautifully inside the admin panel.
- Created custom basic Markdown parser to safely render GitHub-style release notes (supports bold, italic, links, lists, horizontal rules, code blocks).
- Display current version in the admin panel for transparency.
- Changelog box now wraps long lines to prevent overflow.
- Markdown viewer formatting improved to support lists, links, and code blocks with styling.
- Version comparison now strips
vprefix for accurate matching (e.g.,v1.2.0==1.2.0). - Admin panel sidebar updated to include new updater link.
- All version/update-related features are modular and maintainable.
- Global flash messaging system supporting multiple
success,error, andwarningmessages across all pages. - Visual breakdown and display of purged files in File Management (with filetype summary).
- Inline flash message system for Admin Panel (site settings, user management, file management, reset).
- JavaScript-based UTC → local time conversion across dashboard, admin, and homepage.
- Flash success message on file upload (redirects to dashboard).
- Flash success message on logout via
logout_successflag (preserved via query param). CHANGELOG.mdand version tracking.
- Merged all Admin Panel sections (Site Settings, User Management, File Management, Reset Site) into a single
admin.phpcontroller with sectioned includes. - Switched from URL-based success indicators (
?uploaded=1,?deleted=file) to flash message system. - Improved security by preventing direct access to admin section includes.
- Site Settings form now uses
sectionhidden input to route POST submissions. - Refactored session handling order for consistent messaging display.
logout.phpno longer loses flash messages due tosession_destroy()timing.- Fixed
<code>tag in flash message appearing as literal text instead of rendering as HTML. - Fixed missing variable initialization warnings in
site_settings.php.