mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-08-10 15:21:22 +02:00
refactor: combined duration (pages + minutes), has_annexes checkbox, remove Mo
- Remove Mo option from duration, keep only pages and minutes - Redesign duration fieldset: separate Pages input + Durée h:m inputs, both can be set together - Fix minutes input visibility: wider inputs (6ch), proper CSS layout - Add has_annexes checkbox to fichiers fragment + DB column + controllers - Display duration on admin backoffice recap page - Display duration on public partage recap page - Update public TFE page for new combined duration format - Migration 041: add duration_pages, duration_minutes, has_annexes columns; migrate data; recreate views
This commit is contained in:
@@ -162,8 +162,9 @@ class ThesisCreateController
|
||||
'exemplaire_baiu' => $data['exemplaireBaiu'],
|
||||
'exemplaire_erg' => $data['exemplaireErg'],
|
||||
'cc2r' => $data['cc2r'],
|
||||
'duration_value' => $data['durationValue'],
|
||||
'duration_unit' => $data['durationUnit'],
|
||||
'duration_pages' => $data['durationPages'],
|
||||
'duration_minutes' => $data['durationMins'],
|
||||
'has_annexes' => $data['hasAnnexes'] ? 1 : 0,
|
||||
]);
|
||||
|
||||
$identifier = $this->db->getThesisIdentifier($thesisId);
|
||||
@@ -555,20 +556,22 @@ class ThesisCreateController
|
||||
$exemplaireErg = !empty($post['exemplaire_erg']);
|
||||
$cc2r = !empty($post['cc2r']);
|
||||
|
||||
// Duration: numeric value + unit (optional, admin-validated)
|
||||
$validDurationUnits = ['pages', 'mo', 'durée'];
|
||||
$durationValue = $post['duration_value'] ?? null;
|
||||
$durationUnit = $post['duration_unit'] ?? 'pages';
|
||||
if ($durationValue !== null && $durationValue !== '') {
|
||||
$durationValue = filter_var($durationValue, FILTER_VALIDATE_FLOAT);
|
||||
if ($durationValue === false || $durationValue <= 0) {
|
||||
$durationValue = null; // ignore invalid
|
||||
// Duration: separate pages (int) and time (h/m → total minutes)
|
||||
$durationPages = null;
|
||||
$durationPagesRaw = $post['duration_pages'] ?? null;
|
||||
if ($durationPagesRaw !== null && $durationPagesRaw !== '') {
|
||||
$durationPages = filter_var($durationPagesRaw, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0]]);
|
||||
if ($durationPages === false || $durationPages <= 0) {
|
||||
$durationPages = null;
|
||||
}
|
||||
} else {
|
||||
$durationValue = null;
|
||||
}
|
||||
if (!in_array($durationUnit, $validDurationUnits, true)) {
|
||||
$durationUnit = 'pages';
|
||||
$durationMins = null;
|
||||
$durationMinsRaw = $post['duration_minutes'] ?? null;
|
||||
if ($durationMinsRaw !== null && $durationMinsRaw !== '') {
|
||||
$durationMins = filter_var($durationMinsRaw, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0]]);
|
||||
if ($durationMins === false || $durationMins <= 0) {
|
||||
$durationMins = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Annexes are optional — no validation required
|
||||
@@ -601,8 +604,9 @@ class ThesisCreateController
|
||||
'exemplaireBaiu',
|
||||
'exemplaireErg',
|
||||
'cc2r',
|
||||
'durationValue',
|
||||
'durationUnit'
|
||||
'durationPages',
|
||||
'durationMins',
|
||||
'hasAnnexes'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,8 +109,8 @@ class ThesisEditController
|
||||
$currentAccessTypeId = $rawRow['access_type_id'] ?? null;
|
||||
$currentContextNote = $rawRow['context_note'] ?? '';
|
||||
$currentContactVisible = $rawRow['contact_visible'] ?? '';
|
||||
$currentDurationValue = $rawRow['duration_value'] ?? null;
|
||||
$currentDurationUnit = $rawRow['duration_unit'] ?? 'pages';
|
||||
$currentDurationPages = $rawRow['duration_pages'] ?? null;
|
||||
$currentDurationMins = $rawRow['duration_minutes'] ?? null;
|
||||
|
||||
// Author contact info (from view)
|
||||
$contactInterne = $thesis['contact_interne'] ?? '';
|
||||
@@ -134,8 +134,8 @@ class ThesisEditController
|
||||
'currentAccessTypeId' => $currentAccessTypeId,
|
||||
'currentContextNote' => $currentContextNote,
|
||||
'currentContactVisible' => $currentContactVisible,
|
||||
'currentDurationValue' => $currentDurationValue,
|
||||
'currentDurationUnit' => $currentDurationUnit,
|
||||
'currentDurationPages' => $currentDurationPages,
|
||||
'currentDurationMins' => $currentDurationMins,
|
||||
'contactInterne' => $contactInterne,
|
||||
'contactPublic' => $contactPublic,
|
||||
'currentRaw' => $rawRow,
|
||||
@@ -223,8 +223,9 @@ class ThesisEditController
|
||||
'exemplaire_erg' => !empty($post['exemplaire_erg']),
|
||||
'cc2r' => !empty($post['cc2r']),
|
||||
'license_custom' => trim($post['license_custom'] ?? ''),
|
||||
'duration_value' => isset($post['duration_value']) && $post['duration_value'] !== '' ? (float)$post['duration_value'] : null,
|
||||
'duration_unit' => !empty($post['duration_unit']) ? $post['duration_unit'] : 'pages',
|
||||
'duration_pages' => (isset($post['duration_pages']) && $post['duration_pages'] !== '') ? (int)$post['duration_pages'] : null,
|
||||
'duration_minutes' => (isset($post['duration_minutes']) && $post['duration_minutes'] !== '') ? (int)$post['duration_minutes'] : null,
|
||||
'has_annexes' => !empty($post['has_annexes']) ? 1 : 0,
|
||||
];
|
||||
// Regenerate identifier if year changed or if identifier prefix doesn't match year
|
||||
$oldThesis = $this->db->getThesis($thesisId);
|
||||
|
||||
+13
-9
@@ -2032,7 +2032,7 @@ class Database
|
||||
public function getThesisRawFields(int $thesisId): ?array
|
||||
{
|
||||
$stmt = $this->pdo->prepare(
|
||||
'SELECT license_id, license_custom, access_type_id, context_note, contact_visible, remarks, jury_points, exemplaire_baiu, exemplaire_erg, cc2r, duration_value, duration_unit, is_published FROM theses WHERE id = ? LIMIT 1'
|
||||
'SELECT license_id, license_custom, access_type_id, context_note, contact_visible, remarks, jury_points, exemplaire_baiu, exemplaire_erg, cc2r, duration_pages, duration_minutes, has_annexes, is_published FROM theses WHERE id = ? LIMIT 1'
|
||||
);
|
||||
$stmt->execute([$thesisId]);
|
||||
$row = $stmt->fetch();
|
||||
@@ -2176,8 +2176,9 @@ class Database
|
||||
exemplaire_baiu = ?,
|
||||
exemplaire_erg = ?,
|
||||
cc2r = ?,
|
||||
duration_value = ?,
|
||||
duration_unit = ?,
|
||||
duration_pages = ?,
|
||||
duration_minutes = ?,
|
||||
has_annexes = ?,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
");
|
||||
@@ -2209,8 +2210,9 @@ class Database
|
||||
!empty($data['exemplaire_baiu']) ? 1 : 0,
|
||||
!empty($data['exemplaire_erg']) ? 1 : 0,
|
||||
!empty($data['cc2r']) ? 1 : 0,
|
||||
isset($data['duration_value']) && $data['duration_value'] !== '' ? (float)$data['duration_value'] : null,
|
||||
!empty($data['duration_unit']) ? $data['duration_unit'] : 'pages',
|
||||
isset($data['duration_pages']) && $data['duration_pages'] !== '' ? (int)$data['duration_pages'] : null,
|
||||
isset($data['duration_minutes']) && $data['duration_minutes'] !== '' ? (int)$data['duration_minutes'] : null,
|
||||
!empty($data['has_annexes']) ? 1 : 0,
|
||||
$thesisId,
|
||||
]);
|
||||
$stmt->execute($params);
|
||||
@@ -2261,9 +2263,10 @@ class Database
|
||||
remarks, jury_points,
|
||||
exemplaire_baiu, exemplaire_erg,
|
||||
cc2r,
|
||||
duration_value, duration_unit,
|
||||
duration_pages, duration_minutes,
|
||||
has_annexes,
|
||||
submitted_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, "draft", ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, "draft", ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
|
||||
');
|
||||
|
||||
$validObjet = ['tfe', 'thèse', 'frart'];
|
||||
@@ -2296,8 +2299,9 @@ class Database
|
||||
!empty($data['exemplaire_baiu']) ? 1 : 0,
|
||||
!empty($data['exemplaire_erg']) ? 1 : 0,
|
||||
!empty($data['cc2r']) ? 1 : 0,
|
||||
isset($data['duration_value']) && $data['duration_value'] !== '' ? (float)$data['duration_value'] : null,
|
||||
!empty($data['duration_unit']) ? $data['duration_unit'] : 'pages',
|
||||
isset($data['duration_pages']) && $data['duration_pages'] !== '' ? (int)$data['duration_pages'] : null,
|
||||
isset($data['duration_minutes']) && $data['duration_minutes'] !== '' ? (int)$data['duration_minutes'] : null,
|
||||
!empty($data['has_annexes']) ? 1 : 0,
|
||||
]);
|
||||
|
||||
$newId = (int)$this->pdo->lastInsertId();
|
||||
|
||||
@@ -203,8 +203,7 @@ class FormBootstrap
|
||||
'contactPublic' => null,
|
||||
'currentContextNote' => null,
|
||||
'currentContactVisible' => null,
|
||||
'currentDurationValue' => null,
|
||||
'currentDurationUnit' => 'pages',
|
||||
|
||||
|
||||
// Files (edit mode)
|
||||
'currentCover' => null,
|
||||
|
||||
@@ -31,5 +31,8 @@ function icon(string $name, int $size = 0, string $class = ''): string {
|
||||
$svg = str_replace('<svg', '<svg class="' . $class . '"', $svg);
|
||||
}
|
||||
}
|
||||
// Collapse newlines: otherwise raw SVG markup breaks JS string literals
|
||||
// when icon() is used inside <script> tags (e.g., contenus.php inline rename)
|
||||
$svg = str_replace(["\n", "\r"], '', $svg);
|
||||
return $svg;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user