yxcyc
All checks were successful
Deploy / deploy (push) Successful in 57s

This commit is contained in:
2026-08-19 20:58:48 +02:00
parent b0d80e209c
commit ca8544b31b
4 changed files with 79 additions and 2 deletions

View File

@@ -24,6 +24,13 @@ final class ListingCatalog
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci',
'CREATE TABLE IF NOT EXISTS listing_category_redirects (
old_slug VARCHAR(120) NOT NULL PRIMARY KEY,
old_title VARCHAR(160) NOT NULL,
target_slug VARCHAR(120) NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_listing_category_redirects_target (target_slug)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci',
'CREATE TABLE IF NOT EXISTS listing_places (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
created_by BIGINT UNSIGNED NULL,
@@ -186,7 +193,15 @@ final class ListingCatalog
VALUES (:slug, :title, :groupName, :sortOrder)
ON DUPLICATE KEY UPDATE title = VALUES(title), category_group = VALUES(category_group), sort_order = VALUES(sort_order), updated_at = CURRENT_TIMESTAMP'
);
$redirectedSlugs = [];
$redirectStmt = $this->pdo->query('SELECT old_slug FROM listing_category_redirects');
foreach (($redirectStmt ? $redirectStmt->fetchAll(\PDO::FETCH_COLUMN) : []) as $redirectedSlug) {
$redirectedSlugs[(string)$redirectedSlug] = true;
}
foreach ($this->defaultCategories() as $index => $category) {
if (isset($redirectedSlugs[(string)$category['slug']])) {
continue;
}
$seed->execute([
'slug' => $category['slug'],
'title' => $category['title'],
@@ -247,6 +262,15 @@ final class ListingCatalog
}
$slug = $this->slugify($input);
$redirect = $this->findCategoryRedirect($slug, $input);
if ($redirect !== null) {
$resolved = $this->findCategoryBySlug($redirect['target_slug']);
if ($resolved !== null) {
$resolved['is_new'] = false;
return $resolved;
}
}
$stmt = $this->pdo->prepare(
'SELECT id, slug, title, category_group, sort_order
FROM listing_categories
@@ -292,6 +316,8 @@ final class ListingCatalog
(SELECT COUNT(*) FROM listing_category_map m WHERE m.category_id = c.id) AS listing_count,
(SELECT COUNT(*) FROM listing_places p WHERE p.place_kind = c.slug) AS place_count
FROM listing_categories c
LEFT JOIN listing_category_redirects r ON r.old_slug = c.slug
WHERE r.old_slug IS NULL
ORDER BY
CASE WHEN c.sort_order >= 900 THEN 0 ELSE 1 END,
c.sort_order ASC,
@@ -343,7 +369,9 @@ final class ListingCatalog
(SELECT COUNT(*) FROM listing_category_map m WHERE m.category_id = c.id) AS listing_count,
(SELECT COUNT(*) FROM listing_places p WHERE p.place_kind = c.slug) AS place_count
FROM listing_categories c
WHERE ' . implode(' AND ', $conditions) . '
LEFT JOIN listing_category_redirects r ON r.old_slug = c.slug
WHERE r.old_slug IS NULL
AND ' . implode(' AND ', $conditions) . '
ORDER BY
CASE
WHEN LOWER(c.title) = :exactTitle THEN 0
@@ -400,6 +428,17 @@ final class ListingCatalog
$this->pdo->beginTransaction();
try {
$redirectUpsert = $this->pdo->prepare(
'INSERT INTO listing_category_redirects (old_slug, old_title, target_slug)
VALUES (:oldSlug, :oldTitle, :targetSlug)
ON DUPLICATE KEY UPDATE old_title = VALUES(old_title), target_slug = VALUES(target_slug)'
);
$redirectUpsert->execute([
'oldSlug' => $sourceSlug,
'oldTitle' => $sourceTitle,
'targetSlug' => $targetSlug,
]);
$mapRows = $this->pdo->prepare('SELECT listing_id FROM listing_category_map WHERE category_id = :categoryId');
$mapRows->execute(['categoryId' => $sourceId]);
$listingIds = $mapRows->fetchAll(\PDO::FETCH_COLUMN) ?: [];
@@ -484,6 +523,12 @@ final class ListingCatalog
return null;
}
$slug = $this->slugify($input);
$redirect = $this->findCategoryRedirect($slug, $input);
if ($redirect !== null) {
return $redirect['target_slug'];
}
$stmt = $this->pdo->prepare(
'SELECT slug
FROM listing_categories
@@ -492,13 +537,42 @@ final class ListingCatalog
LIMIT 1'
);
$stmt->execute([
'slug' => $input,
'slug' => $slug,
'title' => $input,
]);
$slug = $stmt->fetchColumn();
return $slug !== false ? (string)$slug : null;
}
private function findCategoryRedirect(string $slug, string $title): ?array
{
$stmt = $this->pdo->prepare(
'SELECT old_slug, old_title, target_slug
FROM listing_category_redirects
WHERE old_slug = :slug OR LOWER(old_title) = LOWER(:title)
LIMIT 1'
);
$stmt->execute([
'slug' => $slug,
'title' => $title,
]);
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
return $row ?: null;
}
private function findCategoryBySlug(string $slug): ?array
{
$stmt = $this->pdo->prepare(
'SELECT id, slug, title, category_group, sort_order
FROM listing_categories
WHERE slug = :slug
LIMIT 1'
);
$stmt->execute(['slug' => $slug]);
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
return $row ?: null;
}
public function listPublishedDirectoryEntries(): array
{
$this->ensureSchema();