Files
xamxam/app/public/admin
Pontoporeia 3cecee10c9 fix: prevent file deletion on relink + restore button now visible + OOB-style in-place update
Two critical fixes:

1. Relink flow no longer destroys/recreates FilePond instances:
   The relink (XamxamRelinkFile) and PeerTube relink (XamxamRelinkPeerTube)
   previously refreshed the entire fichiers fragment via HTMX after
   pond.addFile(). This triggered destroyFilePondsIn on ALL pools, which
   could fire server.remove callbacks and move existing files to corbeille.
   Now just closes the modal — the file is already added to the pool in-place,
   and syncOrderInput creates the hidden form input.

2. Cleanup page « Corbeille (restaurable) » now actually shows files:
   _cleanup-stats-data.php previously classified trash files by checking if
   the thesis_files DB row still existed. But both deleteThesisFileToTrash
   and FilepondHandler::handleRemove DELETE the DB row. So ALL trash files
   appeared as `stale` (not restorable). Now uses the JSON sidecar file
   presence as the classification criterion — if the sidecar exists and is
   recent, the file is restorable regardless of DB row state.

Also removed unused DB query from _cleanup-stats-data.php.
2026-07-10 16:29:04 +02:00
..

Admin Panel Structure

This directory contains the admin panel for managing XAMXAM thesis database.

Directory Structure

public/admin/
├── index.php          # List all theses (main page)
├── add.php            # Add new thesis form
├── edit.php           # Edit existing thesis form
├── import.php         # CSV import form
├── recapitulatif.php  # Recap page after submission
├── actions/           # Backend processing scripts (no HTML output)
│   ├── formulaire.php # Process thesis submission from add.php
│   └── publish.php    # Toggle publish/unpublish status
├── inc/               # Shared templates
│   ├── head.php       # HTML head, CSS, navigation
│   └── footer.php     # HTML footer
└── data/              # Upload directory (not in git)
    ├── theses/        # PDF files
    └── covers/        # Cover images

File Types

User-Facing Templates (Root Directory)

Files that display HTML to users:

  • index.php - Lists all theses with filters and bulk actions
  • add.php - Form to add a new thesis
  • edit.php - Form to edit an existing thesis
  • import.php - CSV import interface
  • recapitulatif.php - Success confirmation page

Backend Scripts (actions/)

Files that process forms and redirect (no HTML output):

  • formulaire.php - Processes thesis submission from add.php
  • publish.php - Handles publish/unpublish actions

Shared Templates (inc/)

Reusable HTML components:

  • head.php - HTML head, CSS links, navigation menu
  • footer.php - HTML footer

Workflow

Adding a Thesis

  1. User visits add.php (displays form)
  2. User submits form to actions/formulaire.php (processes data)
  3. On success, redirects to recapitulatif.php?id=123
  4. On error, redirects back to add.php with error message

Publishing/Unpublishing

  1. User clicks publish/unpublish button in index.php
  2. Form submits to actions/publish.php (processes action)
  3. Redirects back to index.php with success/error message

Security

  • All pages require HTTP Basic Auth (configured in nginx) — primary layer
  • All pages require PHP session auth (AdminAuth::requireLogin()) — defence-in-depth
  • CSRF tokens protect all forms
  • File uploads validated and sanitized
  • Database queries use prepared statements
  • Upload directory outside public/ in production

See nginx/PHP_AUTH_LAYER.md for details on the dual-auth architecture.

Templates

The inc/ folder contains shared templates:

  • head.php - Included at the top of each page (DOCTYPE, CSS, nav)
  • footer.php - Included at the bottom of each page (closing tags)

Usage:

<?php include "inc/head.php" ?>
<!-- Page content here -->
<?php include "inc/footer.php" ?>

URL Structure

  • /admin/ - List theses (index.php)
  • /admin/add.php - Add new thesis
  • /admin/edit.php?id=123 - Edit thesis #123
  • /admin/import.php - Import CSV
  • /admin/recapitulatif.php?id=123 - Recap page

Backend actions (not directly accessed):

  • /admin/actions/formulaire.php - Form processor
  • /admin/actions/publish.php - Publish toggle

Development

Adding a New Page

  1. Create the template in /admin/yourpage.php:
<?php
require_once __DIR__ . "/../../config/bootstrap.php";
require_once __DIR__ . '/../../lib/AdminAuth.php';
AdminAuth::requireLogin();
$pageTitle = "Your Page Title";
?>
<?php include "inc/head.php" ?>

<!-- Your content here -->

<?php include "inc/footer.php" ?>
  1. Add navigation link in inc/head.php if needed

Adding a New Action

  1. Create the script in /admin/actions/youraction.php:
<?php
require_once __DIR__ . "/../../config/bootstrap.php";
require_once __DIR__ . '/../../lib/AdminAuth.php';
AdminAuth::requireLogin();

// Verify CSRF token
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
    $_SESSION['error'] = "Security error";
    header('Location: ../index.php');
    exit;
}

// Process action...

// Redirect
header('Location: ../yourpage.php');
exit;
  1. Create form in template that posts to actions/youraction.php

Notes

  • Bootstrap path from actions/: __DIR__ . "/../../config/bootstrap.php"
  • Redirects from actions/: use ../ prefix (e.g., ../index.php)
  • Database class: require_once __DIR__ . '/../../lib/Database.php'
  • All forms must include CSRF token from $_SESSION['csrf_token']