Files
xamxam/TODO.md
Pontoporeia 03c5fd217e feat: dual upload system — direct file storage + PeerTube API integration
Adds a parallel PeerTube upload system behind a feature flag (disabled by default
until upload quota is granted). When disabled, the existing direct file upload
path works unchanged.

Files:
- src/PeerTubeService.php — credential storage (encrypted), OAuth2 token
  retrieval, multipart upload to /api/v1/videos/upload
- migrations/021_peertube_settings.sql — peertube_settings singleton table
  + peertube_upload_enabled site_setting (default 0)
- admin/actions/settings.php — peertube section handler
- admin/parametres.php / templates/admin/parametres.php — PeerTube UI section
- partage/fichiers-fragment.php — shows file inputs when enabled, TODO notice otherwise
- ThesisCreateController / ThesisEditController — handlePeerTubeUpload()
- tfe.php — PeerTube iframe embed detection
- AdminLogger — logPeerTubeUpdate()
2026-05-13 17:59:13 +02:00

8.0 KiB
Raw Blame History

XAMXAM TODO

Completed

  • PeerTube integration — two parallel systems (backup direct upload + PeerTube API)

    • PeerTubeService.php — credentials CRUD + OAuth2 password grant + multipart upload to /api/v1/videos/upload
    • Migration 021_peertube_settings.sqlpeertube_settings table (singleton) + peertube_upload_enabled feature flag (default 0 = disabled)
    • actions/settings.phppeertube section handler (toggle + credential save)
    • admin/parametres.php — PeerTube section UI (instance URL, username, password, channel ID, privacy)
    • templates/admin/parametres.php — PeerTube settings form between SMTP and admin account sections
    • admin/partage/fichiers-fragment.php — shows <input type="file"> for video/audio when enabled, keeps TODO notice when disabled
    • ThesisCreateControllerhandlePeerTubeUpload() uploads video/audio to PeerTube, stores watch URL as thesis_files row
    • ThesisEditController — same handlePeerTubeUpload() method for edit workflow
    • templates/public/tfe.php — renders PeerTube iframe embed for files whose path contains /videos/watch/
    • AdminLoggerlogPeerTubeUpdate() audit method
    • Direct file upload fallback: when peertube_upload_enabled = 0, standard <input type="file"> + local storage works unchanged
  • Fix just serve — justfile shebang recipes (deploy-env, reencrypt-password) used space indentation instead of tabs, causing "extra leading whitespace" parse error

  • PDF 100 MB limit + bentopdf mention

    • ThesisCreateController: MAX_PDF_SIZE = 100 MB; PDFs checked against it, other files still 500 MB
    • ThesisEditController: same per-PDF limit applied
    • fichiers-fragment.php: note d'intention and TFE hints mention 100 MB PDF limit + bentopdf.com link
    • form.php edit-mode new-files hint updated
    • file-field.php: added $hintRaw flag to allow HTML in hints
  • Format types: reorder, rename, add Image/Écriture

    • Migration 019: add Écriture
    • Migration 020: add sort_order column, rename Autre → Etc. / Autre, add Image, set display order (Écriture · Image · Audio · Vidéo · Site web · Performance · Objet éditorial · Installation · Etc. / Autre)
    • Database.php format_types query uses ORDER BY sort_order, id
    • fichiers-fragment.php uses ORDER BY sort_order, id; Image/Vidéo/Audio IDs resolved via name map
    • TODO: Vidéo + Audio — PeerTube API upload (notice shown in form for now)
  • Combined Format + Fichiers into HTMX-swappable block

    • partage/fichiers-fragment.php — new combined fragment: format checkboxes + fichiers fieldset that adapts based on selected formats (upload inputs / URL fields / both)
    • Route /partage/fichiers-fragment added to partage/index.php
    • admin/fichiers-fragment.php — admin-gated wrapper for the same fragment (sets admin_mode=1)
    • admin/format-website-fragment.php — admin-gated fragment for edit-mode website URL fieldset toggle
    • form.php — add/partage mode: replaced separate Format + Fichiers + website-url-fieldset with single #format-fichiers-block server-rendered via shared fragment
    • form.php — edit mode: Format checkboxes wire to admin/format-website-fragment.php#edit-website-url-fieldset (existing-file management untouched)
    • checkbox-list.php — added $hxInclude variable (defaults to 'this, #website-url-fieldset') so callers can customise included fields
  • TDD analysis + new test suites

    • Bug fixed: SearchController::handleSearch()$coverMap undefined variable + never populated for search results
    • ShareLinkTest (13 tests) — generateSlug, all validateLink branches, verifyPassword, incrementUsage, objet_restriction
    • PureLogicTest (31 tests) — TfeController helpers (meta, OG image, jury split, captions), ThesisCreateController helpers (autofocus, detectFileType, authorSlug), ThesisEditController::buildFileSizeInfo, ExportController CSV column consistency, SearchController coverMap regression
    • Private helpers promoted to protected in TfeController, ThesisCreateController, ThesisEditController to enable subclass-based testing without reflection
  • Form save audit + TDD

    • createThesis() missing duration_pages/duration_minutes columns — fixed
    • ThesisCreateController not passing raw page/minute values to createThesis() — fixed (durationPages, durationMinutes extracted and passed)
    • FormSaveTest.php — 14 red-green tests covering create+edit round-trips for all fields
  • Language form improvements

    • Add Néerlandais as default language option (schema + migration 017)
    • language_autre conditionally required via HTMX fragment (replaced custom JS)
    • language_autre saved via getOrCreateLanguage() in both create and edit controllers
    • formData['languages'] wired in edit.php so checkboxes are pre-checked
    • duration_pages/duration_minutes saved in updateThesis() and read back in getThesisRawFields()
    • beforeunload-guard applied to add and partage forms too
  • Audit + fix direct PHP URL references blocked by nginx catch-all deny all

    • /request-access.php fetch in tfe.php/request-access
    • /media.php?path= in form.php (×2) and admin/recapitulatif.php/media?path=
  • Fix 403 on /language-autre-fragment.php from edit.php

    • Root cause: standalone root-level PHP file blocked by nginx catch-all deny all
    • Moved logic to partage/language-autre-fragment.php (shared include)
    • Added route /partage/language-autre-fragment in partage/index.php
    • Added admin/language-autre-fragment.php (AdminAuth gated, includes shared logic)
    • form.php picks URL based on $mode (partage vs admin)
    • Deleted public/language-autre-fragment.php; nginx unchanged
  • Merge banner images into cover images

    • Migration 016: copy storage/banners/*storage/covers/, insert thesis_files cover records, clear banner_path, remove banners dir
    • Remove banner fieldset from edit form (form.php)
    • Remove banner fieldset from student submission form (fieldset-files.php: rename to couverture)
    • Update ThesisEditController::save() — remove banner upload/removal logic
    • Update ThesisCreateController::submit() — remove handleBannerUpload call
    • Update Database::handleCoverUpload() — add webp support, raise limit to 20 MB
    • Remove Database::setBannerPath(), handleBannerUpload(), getThesisBannerPath()
    • Update Database::deleteThesis() / bulkDeleteTheses() — remove banner file cleanup
    • HomeController: batch-load covers for all items, remove banner_path fallback
    • SearchController::handleSearch(): batch-load covers, pass $coverMap to view
    • SearchController::handleStudentPreview(): load covers, pass $coverMap to partial
    • TfeController::resolveOgImage(): use cover file_type instead of banner_path
    • home.php: use only $coverMap (no banner_path fallback)
    • search.php: show cover thumbnail on result cards
    • student-preview.php: use $coverMap instead of banner_path
    • Migration applied and file moved to applied/
  • Remove required from all form inputs in admin add/edit

    • Introduced $adminMode flag in form.php (true when $mode is 'add' or 'edit')
    • Hidden "champs obligatoires" note in admin mode
    • All $required = true callers in form.php, fieldset-tfe-info.php, fieldset-academic.php, fieldset-licence-explanation.php, fieldset-files.php changed to !$adminMode
    • Hardcoded required HTML attributes in fieldset-tfe-info.php (synopsis, objet radios), fieldset-licence-explanation.php (access type radios), jury-fieldset.php (promoteur, lecteurs interne/externe) gated on !$adminMode
    • Dynamic JS ulbInput.required in jury fieldset also gated