standardise multi-author support across all forms

- ThesisCreateController: comma-split auteurice, sort alphabetically,
  use setThesisAuthors() instead of hardcoded createThesis() author_id
- Database::createThesis(): removed author_id param and hardcoded insert
- Database::findDuplicateThesis(): accepts array of author names, matches
  any shared author via IN + DISTINCT
- ThesisEditController::save(): sort authors alphabetically on save
- File folder naming: slug from all authors alphabetically sorted
- v_theses_full GROUP_CONCAT: ORDER BY a.name ASC for deterministic display
- Migration 012_author_view_order.sql: rebuilds view with alphabetical order
This commit is contained in:
Pontoporeia
2026-05-05 10:31:06 +02:00
parent 125c501f40
commit 95066de7b4
6 changed files with 143 additions and 48 deletions

View File

@@ -838,7 +838,7 @@ class Database
t.id, t.identifier, t.title, t.subtitle, t.year,
o.name as orientation,
ap.name as ap_program,
GROUP_CONCAT(DISTINCT a.name) as authors,
GROUP_CONCAT(DISTINCT a.name ORDER BY a.name ASC) as authors,
t.submitted_at,
t.is_published,
at.name as access_type
@@ -983,18 +983,35 @@ class Database
* @param int $year Proposed year.
* @return array{id:int,identifier:string,title:string,author:string,year:int}|null
*/
public function findDuplicateThesis(string $title, string $authorName, int $year): ?array
/**
* @param string $title Proposed title.
* @param string[] $authorNames Proposed author names (already trimmed, non-empty).
* @param int $year Proposed year.
* @return array{id:int,identifier:string,title:string,author:string,year:int}|null
*/
public function findDuplicateThesis(string $title, array $authorNames, int $year): ?array
{
// Fetch all theses for the same year and author (case-insensitive).
if (empty($authorNames)) {
return null;
}
// Fetch all theses for the same year that share any author with the submission.
$numAuthors = count($authorNames);
$ph = implode(',', array_fill(0, $numAuthors, 'LOWER(TRIM(?))'));
$params = array_merge([$year], $authorNames);
$stmt = $this->pdo->prepare(
'SELECT t.id, t.identifier, t.title, a.name AS author, t.year
"SELECT DISTINCT t.id, t.identifier, t.title, t.year,
GROUP_CONCAT(a2.name ORDER BY ta2.author_order ASC) AS authors
FROM theses t
JOIN thesis_authors ta ON ta.thesis_id = t.id AND ta.author_order = 1
JOIN thesis_authors ta ON ta.thesis_id = t.id
JOIN authors a ON a.id = ta.author_id
JOIN thesis_authors ta2 ON ta2.thesis_id = t.id
JOIN authors a2 ON a2.id = ta2.author_id
WHERE t.year = ?
AND LOWER(TRIM(a.name)) = LOWER(TRIM(?))'
AND LOWER(TRIM(a.name)) IN ({$ph})
GROUP BY t.id"
);
$stmt->execute([$year, $authorName]);
$stmt->execute($params);
$candidates = $stmt->fetchAll();
if (empty($candidates)) {
@@ -1016,7 +1033,7 @@ class Database
'id' => (int)$row['id'],
'identifier' => $row['identifier'],
'title' => $row['title'],
'author' => $row['author'],
'author' => $row['authors'],
'year' => (int)$row['year'],
];
}
@@ -1033,7 +1050,7 @@ class Database
'id' => (int)$row['id'],
'identifier' => $row['identifier'],
'title' => $row['title'],
'author' => $row['author'],
'author' => $row['authors'],
'year' => (int)$row['year'],
];
}
@@ -1050,7 +1067,7 @@ class Database
'id' => (int)$row['id'],
'identifier' => $row['identifier'],
'title' => $row['title'],
'author' => $row['author'],
'author' => $row['authors'],
'year' => (int)$row['year'],
];
}
@@ -1849,15 +1866,7 @@ class Database
$objet,
]);
$thesisId = (int)$this->pdo->lastInsertId();
// Link author — always author_order = 1 for single-author submissions.
$stmt = $this->pdo->prepare(
'INSERT INTO thesis_authors (thesis_id, author_id, author_order) VALUES (?, ?, 1)'
);
$stmt->execute([$thesisId, (int)$data['author_id']]);
return $thesisId;
return (int)$this->pdo->lastInsertId();
}
/**