Pontoporeia
a83dc1c74e
feat: multi-type file upload with sort order, labels, and expanded MIME support
...
- DB migration 007: add sort_order + display_label to thesis_files
- Database: getThesisFiles ordered by sort_order; insertThesisFile accepts label/order;
new reorderThesisFiles() and updateThesisFileLabel() methods
- ThesisCreateController + ThesisEditController: expand allowed MIME/exts to include
audio (mp3/ogg/wav/flac/aac/m4a), video (webm/mov/ogv), image (gif/webp),
archives (tar/gz), any-ext via octet-stream; max size raised to 500 MB;
accept file_labels[] and file_orders[] POST fields; detectFileType() helper
- MediaController: expanded MIME allowlist; HTTP Range support for audio/video;
force-download for unknown types; inline for known displayable types
- fieldset-files.php: sortable queue UI with SortableJS, per-file labels, 500 MB hint
- templates/admin/edit.php: existing files as sortable list with drag handles,
type icons, label inputs, delete checkboxes, hidden sort-order fields
- file-upload-queue.js: new JS replacing file-preview.js — sortable new-file queue,
per-file labels, hidden order fields on submit, backward-compat legacy preview
- tfe.php: renders audio (<audio>), all video formats, images, PDF, and
download-only 'other' files; reads display_label; sorted by sort_order
- tfe.css + form.css: styles for audio player, download files, sortable queue,
drag handles, file type badges, label inputs
- .htaccess + .user.ini: upload_max_filesize=512M / post_max_size=520M
2026-05-05 11:04:52 +02:00
Pontoporeia
89b7ab476e
Handle SMTP 550 recipient-rejected errors with structured SmtpSendException
...
- Add SmtpSendException with smtpCode/smtpResponse/isRecipientRejected()
- smtpSend() $expect closure throws SmtpSendException (with code) instead of RuntimeException
- SmtpRelay::send() re-throws SmtpSendException so callers can inspect it
- request-access.php (new): catch 550 → roll back token+approval, return HTTP 422 with FR user message
- request-access.php (resend): catch 550 → HTTP 422 instead of silently claiming success
- StudentEmail::sendConfirmation(): catch SmtpSendException → log+false (submission not aborted)
- admin/actions/access-request.php: catch SmtpSendException post-approval → flash warning (recipient-rejected vs transient)
2026-05-05 11:04:52 +02:00
Pontoporeia
8d115dc965
smtp: enable TLS peer verification, fix envelope injection, fix dot-stuffing
2026-05-05 11:04:52 +02:00
Pontoporeia
33987c9b15
smtp: add notify_email field; fix admin notification sent to no-reply sender
2026-05-05 11:04:52 +02:00
Pontoporeia
bdb68479d5
smtp: typed probe errors with per-field UI highlighting on save
2026-05-05 11:04:52 +02:00
Pontoporeia
b750aca2f5
smtp: probe credentials on save (connect+auth+quit, no message sent)
2026-05-05 11:04:52 +02:00
Pontoporeia
56c8d54435
repertoire: align all column headings to shared baseline row
2026-05-05 11:04:52 +02:00
Pontoporeia
a9e03c4b1c
repertoire: fixed-header columns, remove main/index padding, minimal column padding
2026-05-05 11:04:52 +02:00
Pontoporeia
0960afb731
fix: add missing favicon tags to partage/recapitulatif.php
2026-05-05 11:04:52 +02:00
Pontoporeia
9ba60084bf
fix: require SmtpRelay.php before StudentEmail.php in partage/index.php
2026-05-05 11:04:52 +02:00
Pontoporeia
ab51bf3a66
fix: deploy-server.sh cleans up legacy posterg configs and prunes old xamxam backups
2026-05-05 11:04:52 +02:00
Pontoporeia
68e30abb56
fix: remove Post-ERG branding → XAMXAM; drop legacy posterg nginx symlink in deploy script; rename posterg.db → xamxam.db
2026-05-05 11:04:52 +02:00
Pontoporeia
c949cf9481
rename posterg → xamxam throughout: nginx conf, scripts, PHP source, docs
2026-05-05 11:04:52 +02:00
Pontoporeia
3e35bbc40f
style: align mobile nav dropdown links left
2026-05-05 11:04:52 +02:00
Pontoporeia
471c892638
style: larger mobile nav dropdown links
2026-05-05 11:04:52 +02:00
Pontoporeia
42286b1b71
Header link modification
2026-05-05 11:04:44 +02:00
Pontoporeia
671cfb6d83
fix: hamburger dropdown not showing — reset display:none at mobile breakpoint
2026-04-30 00:02:44 +02:00
Pontoporeia
11f429eb72
feat: pure-CSS hamburger menu for public nav (≤640px)
2026-04-29 22:13:19 +02:00
Pontoporeia
c27ffafa7e
fix: add missing favicon tags to partage/index.php (error, password gate, form)
2026-04-29 21:58:49 +02:00
Pontoporeia
80b7fddea4
fix: partials must not unset caller-owned $formData
...
fieldset-academic.php, fieldset-metadata.php and fieldset-licence-explanation.php
were each calling unset($formData) (or wrong variable) in their cleanup block,
destroying the variable in the parent renderShareLinkForm() scope. This caused
an Undefined variable / TypeError on old($formData, ...) for any field rendered
after those partials (e.g. confirmation_email at line 328).
Fix: remove $formData from the unset() calls; fieldset-licence-explanation.php
was also unsetting the wrong name — corrected to unset($n) which is the variable
it actually declares.
2026-04-29 21:56:42 +02:00
Pontoporeia
992f74b31c
fix: prevent jury-fieldset partial from calling old() with wrong arity in partage context
...
Drop '?: null' coercions on juryPresident/juryPromoteur seeding in partage/index.php
so they are '' (not null), making the partial's $addMode guard false and skipping the
single-arg old() call that clashes with partage's 3-arg old() signature.
2026-04-29 21:56:42 +02:00
Pontoporeia
43702542eb
feat(admin): sortable form-help blocks with two-panel UI
...
- Migration 005: add sort_order column to form_help_blocks
- Database: getAllFormHelpBlocks orders by sort_order; new reorderFormHelpBlocks()
- actions/form-help-reorder.php: HTMX POST handler, CSRF-validated, 204 response
- templates/admin/contenus.php: replace flat table with two-panel layout
- Left: SortableJS 1.15.2 + htmx drag-and-drop ordered block cards
- Right: static form structure reference showing fieldsets and their inputs
- admin.css: .fhb-* styles for layout, cards, ghost/chosen/drag states, anchors
- schema.sql: updated form_help_blocks DDL with sort_order column
2026-04-29 21:45:55 +02:00
Pontoporeia
5c39e856a3
fix: pass enabledAccessTypes from ThesisEditController to edit view
2026-04-29 21:34:47 +02:00
Pontoporeia
885150ea45
css: centralise semantic element baseline styles in common.css
2026-04-29 21:33:55 +02:00
Pontoporeia
b5189c0d08
admin: merge acces-etudiante+file-access into acces.php, absorb system.php into parametres.php
2026-04-29 21:18:25 +02:00
Pontoporeia
670a38f30d
add form help blocks: DB table, admin editor, live rendering in partage form
2026-04-29 21:08:09 +02:00
Pontoporeia
0437ec8d15
fix: escape apostrophe in FORM_HELP_LABELS string (Database.php:2005)
2026-04-29 21:05:53 +02:00
Pontoporeia
d665cb502d
centralise form fieldsets into shared partials; add TODO stubs in partage form
2026-04-29 20:59:35 +02:00
Pontoporeia
89de6dd748
Removed the test csv
2026-04-28 22:21:35 +02:00
Pontoporeia
18a02a0018
deploy: rename deploy path from /var/www/posterg to /var/www/xamxam
2026-04-28 22:21:09 +02:00
Pontoporeia
59c4cf055f
smtp-test: bypass DB, use POST fields directly for credentials
2026-04-27 21:44:10 +02:00
Pontoporeia
9ff8b1b464
fix: call RateLimit::checkKey() as instance method in request-access.php
2026-04-27 21:16:26 +02:00
Pontoporeia
e09b056115
fix: iframe for PDF display, exclude cover files from public loop, no session on media requests
2026-04-27 21:11:58 +02:00
Pontoporeia
46a3c360ec
fix: use local storage/ in dev, create upload dirs, gitignore uploads
2026-04-27 21:08:48 +02:00
Pontoporeia
48059c2317
fix: serve logs, formulaire.php error_log path, CSRF debug, undefined $redirect
2026-04-27 21:04:21 +02:00
Pontoporeia
32a7509598
feat: add file display to forms and recap pages
...
- Live file preview on all file inputs (file-field partial, edit template):
thumbnails for images, emoji icons for PDF/video/zip/vtt, filename + size
- New file-preview.js wired via $extraJs in add.php / edit.php and direct
<script> in partage/index.php; $extraJs support added to head.php
- admin/recapitulatif.php: replace plain table with rich file list — image
thumbnails linked to media.php, type badges, human-readable size, date
- partage/recapitulatif.php: full rewrite — shows thesis metadata + files
list with same rich display (no media links for student privacy)
- form.css: new sections for .file-preview-list (live preview) and
.recap-file-list / .recap-dl / .partage-recap (recap pages)
2026-04-27 20:52:27 +02:00
Pontoporeia
aca7e7eef8
rename thanks.php to recapitulatif.php in admin and partage
2026-04-27 20:41:43 +02:00
Pontoporeia
4d88bd8cc5
edit.php: rework Fichiers fieldset layout
...
- Drop file-field.php partial for cover/banner (it added a second label)
- Inline all three file inputs with admin-file-input wrapper
- Move banner inside the Fichiers fieldset
- Each entry: one label, one input, one small hint — no duplicate labels
- Context-aware hints: 'Laisser vide pour conserver...' when file already exists
2026-04-27 20:38:45 +02:00
Pontoporeia
8e864fc624
admin edit.php: add cover image + thesis file management fields
...
- Database: add deleteThesisFile() and handleCoverUpload() methods
- ThesisEditController::load(): expose currentFiles + currentCover to view
- ThesisEditController::save(): handle couverture upload/removal,
per-file deletion (delete_files[]), and new thesis file uploads
- edit.php template: new Fichiers fieldset with cover preview+remove,
existing files list with delete checkboxes, new file upload input
(mirrors add.php / partage.php)
2026-04-27 20:33:21 +02:00
Pontoporeia
27e1b6828d
Implement TFE file access restriction feature (complete)
...
Requirements:
- parametres.php toggle: 'restricted_files_enabled' enables/disables the feature
- Public TFE page: when enabled + access_type=Interne, hides files, shows French
restriction message + access request form (metadata/synopsis still visible)
- ERG emails (@erg.school / @erg.be): auto-approve, send 24h access link immediately
- External emails: show justification textarea, create pending request, notify admin
- Admin panel /admin/file-access.php: approve/reject requests with optional notes,
sends access email on approval (linked from admin nav with pending count badge)
Security:
- One-time 24h email tokens (used_at + is_valid=0 on first click)
- Token redeemed via POST /validate-access (GET shows confirmation page only)
- Long-lived 30-day browser session in file_access_sessions table
- Cookie: HttpOnly + Secure + SameSite=Strict
- CSRF on all mutations, rate limiting on request submission
- Audit trail: IP, UA, event, timestamp in file_access_audit
Bug fixes:
- admin/file-access.php: $vars never extract()ed → page was blank
- Template had self-contained head/footer includes (double-include)
- Admin approval URL used $requestId instead of $request['thesis_id']
- App::boot() now starts session so CSRF token works on public pages
- Dispatcher routes /validate-access and /request-access through front controller
2026-04-27 20:20:52 +02:00
Théophile Gervreau-Mercier
5c776dd39e
Updated gitignore to keep cache folder but exclude rate_limit logs
2026-04-27 19:33:23 +02:00
Théophile Gervreau-Mercier
88b9f341cd
Replace Posterg branding with XAMXAM in all user-facing content
2026-04-27 19:30:54 +02:00
Théophile Gervreau-Mercier
7e26351f4b
refactor: remove test.db, use only posterg.db for all environments
...
- Simplified Database.php determineDatabasePath to always use posterg.db
- Removed test.db auto-detection based on php_sapi_name
- Removed test.db targets from justfile (migrate-test removed)
- Removed CreateTestDatabase.php fixture script
- Updated migrate.sh to only init posterg.db
- Updated setup-dev.sh to init posterg.db
- Updated run-tests.php (removed DB_ENV=test env var)
- Updated deploy-db to use posterg.db
- Removed test.db file
refactor: remove empty fixtures directory
2026-04-27 18:07:20 +02:00
Pontoporeia
54ef24d21f
ignore *.db files, fix thesis identifier to use max seq instead of count, untrack .db files
2026-04-24 23:03:49 +02:00
Pontoporeia
4986fa74f4
add structured logging for admin/partage form submissions + migration system
...
- AppLogger: JSON-line logger in storage/logs/form-submissions.log
- Logs submissions (admin + partage) with IP, UA, thesis ID, author
- Logs errors with context (post keys, share slug)
- Migration runner (app/migrations/run.php) handles schema drift
- 001_add_objet_column.sql fixes production DB missing 'objet' column
- ThesisCreateController::getIdentifier() helper for logging
2026-04-24 23:03:49 +02:00
Pontoporeia
decb9e2907
fix: replace mb_strlen/mb_substr in student-preview.php (mbstring unavailable)
2026-04-24 23:03:49 +02:00
Pontoporeia
9b4cb52617
fix: replace mb_strtolower with strtolower in admin import (mbstring unavailable in php8.4-fpm)
2026-04-24 23:03:49 +02:00
Pontoporeia
769beae4ee
fix: drop hx-trigger once — rely on browser cache for dedup
2026-04-24 23:03:49 +02:00
Pontoporeia
743268cf1b
fix: drop hx-trigger once — rely on browser cache for dedup
2026-04-24 23:03:49 +02:00
Pontoporeia
6eb111a6ab
perf: htmx lazy popover with Cache-Control — no pre-render, images load on hover only
2026-04-24 23:03:49 +02:00