16 KiB
TODO
Pending tasks have been split into topic files under todo/:
| File | Topic |
|---|---|
| todo/01-css-semantic-refactor.md | CSS class audit, semantic HTML (public + admin), inline style extraction, favicon |
| todo/02-php-components.md | Form field partials, shared UI partials, controller extraction, backend maintenance |
| todo/03-system-cache.md | system_cache table, SystemCache class, system.php refactor |
| todo/04-accessibility.md | WCAG 2.1 AA - remaining failures grouped by success criterion |
Recently completed (this session)
-
pages-edit.php— replaced EasyMDE (333 KB: 320 KB JS + 13 KB CSS) with OverType (118 KB, single JS file, no CSS); removedeasymde.min.jsandeasymde.min.cssfrompublic/assets/; vendoredovertype.min.js; replaced<textarea name="content">+ 60-line EasyMDE toolbar/SVG init block with<input type="hidden" name="content">+<div id="editor">mount target + 6-line OverType init;onChangecallback keeps the hidden input in sync for form submission; net saving: ~215 KB, ~54 lines of JS -
templates/header.php+admin.css— extracted last remaining inlinestyle=from any shared template:style="vertical-align:middle;margin-right:0.4em"on the admin-nav public-site SVG icon moved to.admin-body header nav > a svgrule inadmin.css;templates/header.phpnow contains zerostyle=attributes; only the dynamic gradient (hsl(<?= $hue ?>)) inpublic/index.phpand the PHP-runtime--disk-pct/--disk-colorcustom properties insystem.phpremain (both legitimately dynamic) -
admin/thanks.php+admin/pages.php+admin.css— extracted last 3 inlinestyle=attributes from admin PHP templates:<div style="margin-top:1.5rem;display:flex;gap:.75rem;flex-wrap:wrap;">inthanks.php→class="admin-action-bar"(.admin-action-barrule added to CSS);<p style="color:var(--text-secondary);">inthanks.php→class="admin-muted"(.admin-mutedrule added);style="font-size:.8rem;padding:.3rem .75rem;"on Éditer button inpages.php→class="admin-btn admin-btn--sm"(uses existing modifier). Only the dynamic--disk-pct/--disk-colorCSS custom properties on the disk bar insystem.phpremain (carry PHP runtime values — legitimate). -
variables.css+search.css— public dark-mode support via@media (prefers-color-scheme: dark)scoped tobody:not(.admin-body): all semantic tokens (--bg-*,--text-*,--border-*,--accent-*, status colours) overridden with dark equivalents;--accent-primarylightened to#b87fd4for WCAG contrast on dark backgrounds;--search-error-*variables added to replace hardcoded#fff0f0/#c00in.search-error; admin pages unaffected -
src/ThesisCreateController.php— extracted all validation, DB writes, and file-upload handling fromadmin/actions/formulaire.phpinto a dedicated controller;make()factory instantiatesDatabase;loadFormData()returns all lookup tables for the add-form view;submit(post, files)runs the full creation flow: validates/sanitises all POST fields, callsfindOrCreateAuthor, inserts thesis row viacreateThesis, links jury/languages/formats/tags inside a transaction, then processes cover image, banner, and multi-file uploads outside the transaction;autofocusFieldForError()maps exception messages to WCAG 3.3.1 autofocus field hints;actions/formulaire.phpreduced 346→45 lines (CSRF guard + onesubmit()call);admin/add.phplookup-table block replaced withThesisCreateController::make()->loadFormData();Database::setPublished()andDatabase::bulkSetPublished()added, eliminating raw SQL fromactions/publish.php(100→65 lines); no raw PDO calls remain in any action handler file -
src/HomeController.php— extracted all data-fetching logic frompublic/index.phpinto a dedicated controller class;create()returns a ready instance withDatabasesingleton injected;handle()parsespage/yearGET params, determines display mode (default-random-latest / year-filtered / paginated-all), runs the appropriate DB queries (getLatestPublishedYear,getLatestYearTheses,searchTheses+countSearchResults,getPublishedTheses+countPublishedTheses), batch-loads cover images viagetCoverPathsForTheses, assembles OG/meta tags, and returns a flat view-variable array;public/index.phpreduced 100→71 lines (6-line dispatcher + pure view template);todo/02-php-components.md“Extract remaining controllers” task marked done -
src/TfeController.php— extracted all data-fetching, OG-tag assembly, and view-variable construction frompublic/tfe.phpinto a dedicated controller class;create()returns a ready instance withDatabasesingleton injected;handle()validates theidparam (redirects on missing/invalid), loads the thesis row viagetThesisById(), callsgetThesisAccessTypeId()for visibility gating, builds the meta description (strip_tags + 160-char truncation), resolves the OG image (banner_path → first image file → empty), assembles the full$ogTagsarray (type/title/description/url/image/image_alt/site_name/article_author/article_published_time), collects WebVTT caption paths for N-th-video pairing, and returns a flat view-variable array;captionFilesreplaces inline$_captionFilesarray in the view;$dbreference removed fromtfe.phpentirely;tfe.phpreduced 271→206 lines (9-line dispatcher + pure view template);todo/02-php-components.md“Extract remaining controllers” and “Move OG tag construction into controller logic” tasks updated -
src/ThesisEditController.php— extracted all data-fetching and mutation logic fromadmin/edit.phpandadmin/actions/edit.phpinto a dedicated controller class;load(int $thesisId): arrayfetches the thesis row, current language/format/jury selections, and all lookup tables for the view;save(int $thesisId, array $post, array $files): voidvalidates and persists thesis metadata, authors, jury, languages, formats, tags, and banner in a transaction with proper rollback on error; staticautofocusFieldForError(string $msg): ?stringcentralises WCAG 3.3.1 field-name mapping;admin/edit.phpreduced 191→162 lines (pure dispatcher + view template);actions/edit.phpreduced 153→53 lines (CSRF guard + one controller call) -
src/SystemController.php— extracted all data-fetching logic fromadmin/system.phpandadmin/system-fragment.phpinto a dedicated controller class; centralises: system status checks (nginx, php-fpm, HTTP ping, SQLite DB, storage dir, maintenance flag) with 2-min TTL caching, PHP environment info (1-hour TTL), disk usage (5-min TTL), log file reading (readLogTail), nginx config reading, and the shared CSS-class classifier methods (logLineClass,nginxLineClass,statusLabel,statusClass,humanBytes,diskColor);system.phpreduced 582→282 lines;system-fragment.phpreduced 213→137 lines with allfrag_*-prefixed duplicated helpers removed; both files now purely dispatch to the controller and render view templates -
src/SearchController.php— extracted all data-fetching logic frompublic/search.phpinto a dedicated controller class;SearchController::create()handles rate-limit enforcement (429 response + exit) and returns a ready instance;handle()sanitises GET params, runs all DB queries (searchTheses,countSearchResults,getAvailableYears,getAllOrientations,getAllAPPrograms,getUsedTags,getPublishedAuthors), builds the alphabetical author map, assembles OG/meta tags, and returns a flat view-variable array;public/search.phpreduced from 285 lines to 162 lines (pure dispatcher + view template) -
admin/system.php+assets/js/system.js+assets/css/system.css— extracted the large$extraJsInlineheredoc (≈130 lines) into a staticpublic/assets/js/system.jsloaded via$extraJs; replaced 4 inlinestyle=attributes with named CSS modifier classes (srv-section-title--compact,srv-section-title--sub,php-grid--flush,log-toolbar labelrule); only the dynamic--disk-pct/--disk-colorCSS custom properties remain inline because they carry PHP runtime values -
src/App.php— removed dead legacy flash key fallback chains fromconsumeFlash(): theerror,admin_error,edit_error,form_error,success,admin_success,edit_successsession keys were never written by any code; all callers already useApp::flash()→_flash_error/_flash_success. Method is now 4 lines instead of 18. -
admin/import.php+admin.css— extracted all 4 remaining inlinestyle=attributes fromimport.phpinto named CSS classes (admin-error-list,admin-file-hint,admin-import-results,admin-import-results__title) in the Import page section ofadmin.css. No more inline styles inimport.php. -
WCAG 3.3.1
autofocuson first invalid field —App::flashAutofocus()/consumeAutofocus()added;actions/formulaire.phpmaps exception messages → field names and stores the autofocus hint in$_SESSION['_flash_autofocus'];actions/edit.phpdoes the same;add.phpconsumes it via awithAutofocus()helper and injectsautofocus => trueinto$attrsfortext-field.php/select-field.phpincludes;edit.phpuses inline ternary for the same;text-field.phpandselect-field.phppartials now support booleantruevalues in$attrs(emit bare attribute names forautofocus,required, etc.) -
config/apropos.php— fixed PHP parse error: straight apostrophe in'Responsable des mémoires de l'ERG :'broke string literal; replaced with curly apostrophe (U+2019); also removed stray blank line introduced by earlier edit -
config/apropos.php— extracted hardcoded contacts (Laurent Leprince, Xavier Gorgol, Brigitte Ledune) and credits into a config array (contacts[],credits[],erg_url);public/apropos.phpnow loops over the config withhtmlspecialcharsinstead of embedding names/emails in HTML -
todo/02-php-components.md— audited and marked 8 stale items as already done: all 5 form field partials (text-field,select-field,checkbox-list,file-field,jury-fieldset),admin-alert.php/flash-messages.phpconsolidation,RateLimitcache dir placement, andapropos.phpcontacts extraction -
WCAG 4.1.2
<video>captions —tfe.phpnow emits<track kind="captions">for each MP4 when a.vttsidecar exists (N-th VTT paired with N-th video).formulaire.phpaccepts.vttuploads (file_type='caption', MIME normalised).media.phpservestext/vttwith correct headers and visibility gating. Adminadd.phpfile-field hint documents the.vttupload convention. -
admin/edit.php— WCAG 4.1.2: removedmb_strimwidthtruncation from$accessOptionsmapping; access type<select>options now include full description text (name — description) so the accessible name is unambiguous for screen readers -
public/assets/favicon.svg— created public favicon: brand-purple (#9557b5) rounded square with white "P" lettermark; distinct fromadmin_favicon.svg(archive-restore icon in#c104fc) -
templates/head.php— favicon<link>now selectsfavicon.svg(public) vsadmin_favicon.svg(admin) based on$isAdmin; closestodo/01-css-semantic-refactor.mdfavicon task -
todo/04-accessibility.md— marked WCAG 3.1.1 lang audit and WCAG 4.1.2 select truncation items as done -
todo/01-css-semantic-refactor.md— marked favicon task as done -
admin.css- added[aria-current="page"]rule for admin nav links (border-bottom: 2px solid currentColor; padding-bottom: 1px) fixing WCAG 1.4.1 (active nav link had no non-colour indicator) -
admin.css- fixed undefined--admin-purplevariable in pagination hover; replaced with--accent-primary(same#9557b5value) -
todo/01-css-semantic-refactor.md- audited all CSS/HTML refactor tasks; marked ~15 items as already-done (.admin-main,.admin-page-title,.admin-form-row,.admin-label,.admin-input/select/textarea,.admin-table,.admin-fieldset,tfe.cssclass replacements,search.cssselector,login.php/edit.phpinline styles,admin-alertreplacement, form partial hints) -
todo/04-accessibility.md- marked WCAG 1.4.1 admin nav and--admin-purpleaudit items as completed -
admin/index.php- server-side pagination (25/page);Database::getThesesListCount()added;getThesesList()extended with$limit/$offset;access_typeJOIN added to query (was missing); result-count meta line added;.pagination-wrap+.pagination-btn+.pagination-infostyles added toadmin.css -
checkbox-list.php- replaced<div class="admin-checkbox-list">with<fieldset class="admin-checkbox-group"><legend class="sr-only">...</legend><ul>(WCAG 1.3.1 fix) -
admin.css- replaced.admin-checkbox-listwith.admin-body fieldset.admin-checkbox-group > ulsemantic selectors; addedspan.admin-row-labelas visible label column counterpart -
login.php- wrapped content in<main id="main-content">landmark -
account.php-<div class="admin-account-status">→<dl>;__rowdivs kept;__labelspans →<dt>;admin-danger-zone__descriptiondiv →<p> -
index.php- maintenance bar<div>→<aside role="status" aria-label="Statut du site"> -
add.php/edit.php-autocomplete="name"on author field,autocomplete="email"on contact field -
tags.php- all inlinestyle=attributes removed; sizing/spacing moved to CSS (.admin-input--inline,.admin-select--inline,.admin-inline-form + .admin-inline-form,.admin-tags-count) -
Marked already-done items in todo files: stats
<dl>,thanks.php<section>,scope="col"on both tables,tfe.phpinline styles,role="alert"on flash messages -
admin-submit-wrap→admin-form-footerrename: updated all 6 admin templates (add.php,edit.php,login.php,account.php,import.php,pages-edit.php) and all 8 CSS selectors inadmin.css(.admin-form > div:not(...)exclusion guards,.admin-login-boxoverrides). Closestodo/01-css-semantic-refactor.mdsubmit-wrap task. -
Marked
status-badge.phppartial and WCAG 1.3.1 status-badge items as already-done intodo/02-php-components.mdandtodo/04-accessibility.md(partial + CSS were fully implemented; TODO had not been updated) -
public/index.php— WCAG 2.4.4: home page cards now append<span class="sr-only">, YEAR</span>to each card’s<p>link text so screen readers get unique link names when two theses share the same title -
todo/04-accessibility.md— WCAG 2.4.3: marked back-link focus-order item as already done (tfe-back-linkis already the first DOM element in.tfe-left, before<h1>) -
jury-fieldset.php— WCAG 3.3.2: replaced bare<label>Lecteur·ices :</label>with<fieldset class="admin-jury-lecteurs"><legend>Lecteur·ices</legend>so the lecteur group has a proper programmatic label -
jury-fieldset.php— WCAG 4.1.2: all "Externe" checkboxes (promoteur + each lecteur row, static + dynamically added via JS) now carryaria-label="[Role] — externe"providing group context without visible redundancy -
jury-fieldset.php— WCAG 2.1.1: jury remove buttons verified to have descriptivearia-label="Supprimer le lecteur·ice N"on all rows (static + dynamic) -
admin.css— added.admin-body fieldset fieldset.admin-jury-lecteursrule: strips border/background on the nested lecteur fieldset so it renders as a visual sub-group, not a double-bordered card -
todo/04-accessibility.md— WCAG 1.4.4 + 1.4.12 audited and marked done: all font-sizes arerem; nooverflow:hiddenon essential text content