Public:
- /escape-rooms: Leaflet + OpenStreetMap map with marker clustering and a
searchable list, both built from a cached slim JSON feed
- /escape-rooms/{id}-{slug}: room detail with a mini-map and user reviews
(rating + title + body, login required)
- /escape-rooms/suggest: visitor submission form with click-to-drop-pin map
and reCAPTCHA v3; new rooms land as pending
Data:
- EscapeRoom / EscapeRoomReview entities (soft-delete), migration
- app:escaperooms:import-osm console command pulls leisure=escape_game from
the Overpass API, upserts by (osmType, osmId), skips locked rows;
--tiled / --area / --bbox options
Admin (new "Website Admin" area, separate from Game Admin):
- src/Website/Controller/AdminEscapeRoomController.php at /admin/escape-rooms:
status-filtered list, new/edit, publish/hide/reject, delete, review removal
- game admin sidebar extracted into a block and cross-linked
Assets: leaflet + leaflet.markercluster; escaperoom-map and escaperoom-detail
Encore entries.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
80 lines
3.7 KiB
PHP
80 lines
3.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace DoctrineMigrations;
|
|
|
|
use Doctrine\DBAL\Schema\Schema;
|
|
use Doctrine\Migrations\AbstractMigration;
|
|
|
|
final class Version20260829150000 extends AbstractMigration
|
|
{
|
|
public function getDescription(): string
|
|
{
|
|
return 'Add escape_room and escape_room_review tables for the physical escape room map and reviews';
|
|
}
|
|
|
|
public function up(Schema $schema): void
|
|
{
|
|
$this->addSql(<<<'SQL'
|
|
CREATE TABLE escape_room (
|
|
id INT AUTO_INCREMENT NOT NULL,
|
|
submitted_by_id INT DEFAULT NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
venue VARCHAR(255) DEFAULT NULL,
|
|
street VARCHAR(255) DEFAULT NULL,
|
|
house_number VARCHAR(32) DEFAULT NULL,
|
|
postcode VARCHAR(32) DEFAULT NULL,
|
|
city VARCHAR(128) DEFAULT NULL,
|
|
country VARCHAR(2) DEFAULT NULL,
|
|
latitude NUMERIC(10, 7) NOT NULL,
|
|
longitude NUMERIC(10, 7) NOT NULL,
|
|
website VARCHAR(511) DEFAULT NULL,
|
|
phone VARCHAR(64) DEFAULT NULL,
|
|
source VARCHAR(16) NOT NULL,
|
|
osm_type VARCHAR(8) DEFAULT NULL,
|
|
osm_id BIGINT DEFAULT NULL,
|
|
status VARCHAR(16) NOT NULL,
|
|
locked TINYINT(1) DEFAULT 0 NOT NULL,
|
|
created_at DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)',
|
|
updated_at DATETIME DEFAULT NULL COMMENT '(DC2Type:datetime_immutable)',
|
|
deleted_at DATETIME DEFAULT NULL COMMENT '(DC2Type:datetime_immutable)',
|
|
INDEX idx_escape_room_submitted_by (submitted_by_id),
|
|
UNIQUE INDEX uniq_escape_room_osm (osm_type, osm_id),
|
|
INDEX idx_escape_room_status (status),
|
|
INDEX idx_escape_room_bbox (latitude, longitude),
|
|
PRIMARY KEY(id)
|
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB
|
|
SQL);
|
|
|
|
$this->addSql(<<<'SQL'
|
|
CREATE TABLE escape_room_review (
|
|
id INT AUTO_INCREMENT NOT NULL,
|
|
escape_room_id INT NOT NULL,
|
|
author_id INT DEFAULT NULL,
|
|
rating SMALLINT NOT NULL,
|
|
title VARCHAR(150) NOT NULL,
|
|
body LONGTEXT NOT NULL,
|
|
created_at DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)',
|
|
deleted_at DATETIME DEFAULT NULL COMMENT '(DC2Type:datetime_immutable)',
|
|
INDEX idx_escape_room_review_room (escape_room_id),
|
|
INDEX idx_escape_room_review_author (author_id),
|
|
PRIMARY KEY(id)
|
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB
|
|
SQL);
|
|
|
|
$this->addSql('ALTER TABLE escape_room ADD CONSTRAINT fk_escape_room_submitted_by FOREIGN KEY (submitted_by_id) REFERENCES `user` (id) ON DELETE SET NULL');
|
|
$this->addSql('ALTER TABLE escape_room_review ADD CONSTRAINT fk_escape_room_review_room FOREIGN KEY (escape_room_id) REFERENCES escape_room (id) ON DELETE CASCADE');
|
|
$this->addSql('ALTER TABLE escape_room_review ADD CONSTRAINT fk_escape_room_review_author FOREIGN KEY (author_id) REFERENCES `user` (id) ON DELETE SET NULL');
|
|
}
|
|
|
|
public function down(Schema $schema): void
|
|
{
|
|
$this->addSql('ALTER TABLE escape_room_review DROP FOREIGN KEY fk_escape_room_review_room');
|
|
$this->addSql('ALTER TABLE escape_room_review DROP FOREIGN KEY fk_escape_room_review_author');
|
|
$this->addSql('ALTER TABLE escape_room DROP FOREIGN KEY fk_escape_room_submitted_by');
|
|
$this->addSql('DROP TABLE escape_room_review');
|
|
$this->addSql('DROP TABLE escape_room');
|
|
}
|
|
}
|