mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
fix: author name casing not updating — use ID lookup priority
Root cause: SQLite uses BINARY collation, so WHERE name = ? is case-sensitive. When changing 'john doe' to 'John Doe', the name lookup failed and fell through to the email path which didn't update the name. The previous fix only added UPDATE in the name-match branch. Fixes in findOrCreateAuthor: 1. Accept optional $idHint parameter — when known (edit flow), update directly by ID (fastest, zero ambiguity) 2. Add COLLATE NOCASE to the name lookup (fallback path) 3. Add UPDATE in the email fallback path too setThesisAuthors now fetches existing author_ids before deletion and passes them as position-based hints, so identity is always preserved.
This commit is contained in:
@@ -1014,7 +1014,7 @@ class Database
|
||||
/**
|
||||
* Find or create an author
|
||||
*/
|
||||
public function findOrCreateAuthor($name, $email = null, bool $showContact = false)
|
||||
public function findOrCreateAuthor($name, $email = null, bool $showContact = false, ?int $idHint = null)
|
||||
{
|
||||
// Normalise CSV artefacts: OUI/NON strings in email column → null
|
||||
if ($email !== null && in_array(strtoupper(trim($email)), ['NON', 'OUI'], true)) {
|
||||
@@ -1023,8 +1023,19 @@ class Database
|
||||
|
||||
$cleanEmail = ($email !== null && $email !== '') ? $email : null;
|
||||
|
||||
// Try to find by name first
|
||||
$stmt = $this->pdo->prepare('SELECT id, email FROM authors WHERE name = ?');
|
||||
// 1. If we have a known ID (edit flow), update directly by ID
|
||||
if ($idHint !== null) {
|
||||
$stmt = $this->pdo->prepare('SELECT id FROM authors WHERE id = ?');
|
||||
$stmt->execute([$idHint]);
|
||||
if ($stmt->fetch()) {
|
||||
$updateStmt = $this->pdo->prepare('UPDATE authors SET name = ?, email = ?, show_contact = ? WHERE id = ?');
|
||||
$updateStmt->execute([$name, $cleanEmail, $showContact ? 1 : 0, $idHint]);
|
||||
return $idHint;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Try to find by name (case-insensitive — SQLite BINARY collation otherwise)
|
||||
$stmt = $this->pdo->prepare('SELECT id, email FROM authors WHERE name = ? COLLATE NOCASE');
|
||||
$stmt->execute([$name]);
|
||||
$author = $stmt->fetch();
|
||||
|
||||
@@ -1042,16 +1053,19 @@ class Database
|
||||
return $author['id'];
|
||||
}
|
||||
|
||||
// If an author with this email already exists (different name), reuse that record.
|
||||
// 3. If an author with this email already exists (different name), reuse that record.
|
||||
if ($cleanEmail !== null) {
|
||||
$byEmail = $this->pdo->prepare('SELECT id FROM authors WHERE email = ?');
|
||||
$byEmail = $this->pdo->prepare('SELECT id, name FROM authors WHERE email = ?');
|
||||
$byEmail->execute([$cleanEmail]);
|
||||
$existing = $byEmail->fetch();
|
||||
if ($existing) {
|
||||
$updateStmt = $this->pdo->prepare('UPDATE authors SET name = ?, show_contact = ? WHERE id = ?');
|
||||
$updateStmt->execute([$name, $showContact ? 1 : 0, $existing['id']]);
|
||||
return $existing['id'];
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Create new author
|
||||
$stmt = $this->pdo->prepare('INSERT INTO authors (name, email, show_contact) VALUES (?, ?, ?)');
|
||||
$stmt->execute([$name, $cleanEmail, $showContact ? 1 : 0]);
|
||||
return $this->pdo->lastInsertId();
|
||||
@@ -2194,6 +2208,11 @@ class Database
|
||||
*/
|
||||
public function setThesisAuthors(int $thesisId, array $authors): void
|
||||
{
|
||||
// Fetch existing author IDs before deletion (preserves identity for edit)
|
||||
$existingStmt = $this->pdo->prepare('SELECT author_id FROM thesis_authors WHERE thesis_id = ? ORDER BY author_order');
|
||||
$existingStmt->execute([$thesisId]);
|
||||
$existingIds = $existingStmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
$this->pdo->prepare('DELETE FROM thesis_authors WHERE thesis_id = ?')->execute([$thesisId]);
|
||||
$stmt = $this->pdo->prepare(
|
||||
'INSERT INTO thesis_authors (thesis_id, author_id, author_order) VALUES (?, ?, ?)'
|
||||
@@ -2204,7 +2223,9 @@ class Database
|
||||
continue;
|
||||
}
|
||||
$showContact = !empty($author['show_contact']);
|
||||
$authorId = $this->findOrCreateAuthor($name, $author['email'] ?? null, $showContact);
|
||||
// Pass existing ID by position so findOrCreateAuthor can update directly
|
||||
$hintId = isset($existingIds[$index]) ? (int)$existingIds[$index] : null;
|
||||
$authorId = $this->findOrCreateAuthor($name, $author['email'] ?? null, $showContact, $hintId);
|
||||
$stmt->execute([$thesisId, $authorId, (int)$index + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user