mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 19:19:19 +02:00
refactor: rename keywords→tags M2M (migration 001)
- migration 001_rename_keywords_to_tags.sql: CREATE tags/thesis_tags from keywords/thesis_keywords, copy data, drop old tables, rebuild indexes and views - schema.sql: tags table, thesis_tags junction, updated indexes and v_theses_full/v_theses_public - Database.php: findOrCreateTag(), getUsedTags() with proper JOIN; backwards-compat aliases; buildSearchConditions uses EXISTS subquery on thesis_tags+tags with vp. alias throughout - admin/actions/formulaire.php: INSERT OR IGNORE INTO thesis_tags - admin/edit.php: DELETE FROM thesis_tags + findOrCreateTag - search.php: $kw['name'] (was $kw['keyword']) - fixtures/CreateTestDatabase.php: tags/thesis_tags table names
This commit is contained in:
@@ -288,58 +288,66 @@ class Database {
|
||||
* @return array{0: string[], 1: array<string,mixed>} [$conditions, $bindings]
|
||||
*/
|
||||
private function buildSearchConditions(array $params): array {
|
||||
$conditions = ["is_published = 1"];
|
||||
$conditions = ["vp.is_published = 1"];
|
||||
$bindings = [];
|
||||
|
||||
if (!empty($params['query'])) {
|
||||
$conditions[] = "(
|
||||
title LIKE :query ESCAPE '\\' OR
|
||||
subtitle LIKE :query ESCAPE '\\' OR
|
||||
synopsis LIKE :query ESCAPE '\\' OR
|
||||
authors LIKE :query ESCAPE '\\' OR
|
||||
supervisors LIKE :query ESCAPE '\\' OR
|
||||
keywords LIKE :query ESCAPE '\\'
|
||||
vp.title LIKE :query ESCAPE '\\' OR
|
||||
vp.subtitle LIKE :query ESCAPE '\\' OR
|
||||
vp.synopsis LIKE :query ESCAPE '\\' OR
|
||||
vp.authors LIKE :query ESCAPE '\\' OR
|
||||
vp.supervisors LIKE :query ESCAPE '\\' OR
|
||||
EXISTS (
|
||||
SELECT 1 FROM thesis_tags tt2
|
||||
JOIN tags tg2 ON tg2.id = tt2.tag_id
|
||||
WHERE tt2.thesis_id = vp.id AND tg2.name LIKE :query ESCAPE '\\'
|
||||
)
|
||||
)";
|
||||
$bindings[':query'] = '%' . $params['query'] . '%';
|
||||
}
|
||||
|
||||
if (!empty($params['year'])) {
|
||||
$conditions[] = "year = :year";
|
||||
$conditions[] = "vp.year = :year";
|
||||
$bindings[':year'] = $params['year'];
|
||||
}
|
||||
|
||||
if (!empty($params['orientation'])) {
|
||||
$conditions[] = "orientation LIKE :orientation ESCAPE '\\'";
|
||||
$conditions[] = "vp.orientation LIKE :orientation ESCAPE '\\'";
|
||||
$bindings[':orientation'] = '%' . $params['orientation'] . '%';
|
||||
}
|
||||
|
||||
if (!empty($params['ap_program'])) {
|
||||
$conditions[] = "ap_program LIKE :ap_program ESCAPE '\\'";
|
||||
$conditions[] = "vp.ap_program LIKE :ap_program ESCAPE '\\'";
|
||||
$bindings[':ap_program'] = '%' . $params['ap_program'] . '%';
|
||||
}
|
||||
|
||||
if (!empty($params['finality'])) {
|
||||
$conditions[] = "finality_type LIKE :finality ESCAPE '\\'";
|
||||
$conditions[] = "vp.finality_type LIKE :finality ESCAPE '\\'";
|
||||
$bindings[':finality'] = '%' . $params['finality'] . '%';
|
||||
}
|
||||
|
||||
if (!empty($params['keyword'])) {
|
||||
$conditions[] = "keywords LIKE :keyword ESCAPE '\\'";
|
||||
$conditions[] = "EXISTS (
|
||||
SELECT 1 FROM thesis_tags tt_kw
|
||||
JOIN tags tg_kw ON tg_kw.id = tt_kw.tag_id
|
||||
WHERE tt_kw.thesis_id = vp.id AND tg_kw.name LIKE :keyword ESCAPE '\\'
|
||||
)";
|
||||
$bindings[':keyword'] = '%' . $params['keyword'] . '%';
|
||||
}
|
||||
|
||||
if (!empty($params['format'])) {
|
||||
$conditions[] = "formats LIKE :format ESCAPE '\\'";
|
||||
$conditions[] = "vp.formats LIKE :format ESCAPE '\\'";
|
||||
$bindings[':format'] = '%' . $params['format'] . '%';
|
||||
}
|
||||
|
||||
if (!empty($params['language'])) {
|
||||
$conditions[] = "languages LIKE :language ESCAPE '\\'";
|
||||
$conditions[] = "vp.languages LIKE :language ESCAPE '\\'";
|
||||
$bindings[':language'] = '%' . $params['language'] . '%';
|
||||
}
|
||||
|
||||
if (isset($params['is_doctoral'])) {
|
||||
$conditions[] = "is_doctoral = :is_doctoral";
|
||||
$conditions[] = "vp.is_doctoral = :is_doctoral";
|
||||
$bindings[':is_doctoral'] = $params['is_doctoral'] ? 1 : 0;
|
||||
}
|
||||
|
||||
@@ -357,7 +365,7 @@ class Database {
|
||||
[$conditions, $bindings] = $this->buildSearchConditions($params);
|
||||
|
||||
$whereClause = implode(' AND ', $conditions);
|
||||
$sql = "SELECT * FROM v_theses_public WHERE $whereClause ORDER BY year DESC, title ASC LIMIT :limit OFFSET :offset";
|
||||
$sql = "SELECT vp.* FROM v_theses_public vp WHERE $whereClause ORDER BY vp.year DESC, vp.title ASC LIMIT :limit OFFSET :offset";
|
||||
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
foreach ($bindings as $key => $value) {
|
||||
@@ -379,7 +387,7 @@ class Database {
|
||||
[$conditions, $bindings] = $this->buildSearchConditions($params);
|
||||
|
||||
$whereClause = implode(' AND ', $conditions);
|
||||
$sql = "SELECT COUNT(*) as count FROM v_theses_public WHERE $whereClause";
|
||||
$sql = "SELECT COUNT(*) as count FROM v_theses_public vp WHERE $whereClause";
|
||||
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
foreach ($bindings as $key => $value) {
|
||||
@@ -451,16 +459,21 @@ class Database {
|
||||
/**
|
||||
* Get all keywords used in published theses
|
||||
*/
|
||||
public function getUsedKeywords() {
|
||||
$sql = "SELECT DISTINCT k.* FROM keywords k
|
||||
INNER JOIN thesis_keywords tk ON k.id = tk.keyword_id
|
||||
INNER JOIN theses t ON tk.thesis_id = t.id
|
||||
WHERE t.is_published = 1
|
||||
ORDER BY k.keyword";
|
||||
public function getUsedTags(): array {
|
||||
$sql = "SELECT DISTINCT tg.id, tg.name FROM tags tg
|
||||
JOIN thesis_tags tt ON tg.id = tt.tag_id
|
||||
JOIN theses th ON tt.thesis_id = th.id
|
||||
WHERE th.is_published = 1
|
||||
ORDER BY tg.name";
|
||||
$stmt = $this->pdo->query($sql);
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
/** Backwards-compat alias */
|
||||
public function getUsedKeywords(): array {
|
||||
return $this->getUsedTags();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all format types
|
||||
*/
|
||||
@@ -601,25 +614,30 @@ class Database {
|
||||
}
|
||||
|
||||
/**
|
||||
* Find or create a keyword
|
||||
* Find or create a tag (formerly keyword)
|
||||
*/
|
||||
public function findOrCreateKeyword($keyword) {
|
||||
$keyword = trim($keyword);
|
||||
if (empty($keyword)) {
|
||||
public function findOrCreateTag(string $name): ?int {
|
||||
$name = trim($name);
|
||||
if ($name === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$stmt = $this->pdo->prepare("SELECT id FROM keywords WHERE keyword = ?");
|
||||
$stmt->execute([$keyword]);
|
||||
$kw = $stmt->fetch();
|
||||
$stmt = $this->pdo->prepare("SELECT id FROM tags WHERE name = ?");
|
||||
$stmt->execute([$name]);
|
||||
$row = $stmt->fetch();
|
||||
|
||||
if ($kw) {
|
||||
return $kw['id'];
|
||||
if ($row) {
|
||||
return (int)$row['id'];
|
||||
}
|
||||
|
||||
$stmt = $this->pdo->prepare("INSERT INTO keywords (keyword) VALUES (?)");
|
||||
$stmt->execute([$keyword]);
|
||||
return $this->pdo->lastInsertId();
|
||||
$stmt = $this->pdo->prepare("INSERT INTO tags (name) VALUES (?)");
|
||||
$stmt->execute([$name]);
|
||||
return (int)$this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
/** Backwards-compat alias */
|
||||
public function findOrCreateKeyword($keyword): ?int {
|
||||
return $this->findOrCreateTag((string)$keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user