diff --git a/database/migrations/structure/20220526_1315_unlisted_maps.sql b/database/migrations/structure/20220526_1315_unlisted_maps.sql
new file mode 100644
index 0000000..bd91f6b
--- /dev/null
+++ b/database/migrations/structure/20220526_1315_unlisted_maps.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `maps`
+ ADD `unlisted` TINYINT(1) NOT NULL DEFAULT 0;
diff --git a/public/static/css/mapguesser.css b/public/static/css/mapguesser.css
index a5eb801..65a4637 100644
--- a/public/static/css/mapguesser.css
+++ b/public/static/css/mapguesser.css
@@ -241,7 +241,7 @@ button.green:enabled:hover, button.green:enabled:focus, a.button.green:hover, a.
background-color: #1b7d31;
}
-input, select, textarea {
+input[type=text], select, textarea {
background-color: #f9fafb;
border: solid #c8d2e1 1px;
border-radius: 2px;
@@ -250,22 +250,26 @@ input, select, textarea {
font-weight: 300;
}
-input, select {
+input[type=text], select {
height: 30px;
line-height: 30px;
padding: 0 5px;
}
+input[type=checkbox], input[type=radio] {
+ margin-right: 0.5em;
+}
+
textarea {
padding: 5px;
resize: none;
}
-input.big, select.big, textarea.big, div.inputWithButton>input {
+input[type=text].big, select.big, textarea.big, div.inputWithButton>input[type=text] {
font-size: 18px;
}
-input.big, select.big, div.inputWithButton>input {
+input[type=text].big, select.big, div.inputWithButton>input[type=text] {
height: 35px;
line-height: 35px;
padding: 0 6px;
@@ -280,19 +284,19 @@ input.fullWidth, select.fullWidth, textarea.fullWidth {
width: 100%;
}
-input:disabled, select:disabled, textarea:disabled {
+input[type=text]:disabled, select:disabled, textarea:disabled {
background-color: #dfdfdf;
border: solid #dfdfdf 1px;
color: #000000;
}
-input:focus, select:focus, textarea:focus {
+input[type=text]:focus, select:focus, textarea:focus {
background-color: #ffffff;
border: solid #29457f 2px;
outline: none;
}
-input:focus, select:focus {
+input[type=text]:focus, select:focus {
padding: 0 4px;
}
@@ -300,16 +304,16 @@ textarea:focus {
padding: 4px;
}
-input.big:focus, select.big:focus {
+input[type=text].big:focus, select.big:focus {
padding: 0 5px;
}
-div.inputWithButton>input {
+div.inputWithButton>input[type=text] {
width: 100%;
padding: 0 83px 0 6px;
}
-div.inputWithButton>input:focus {
+div.inputWithButton>input[type=text]:focus {
padding: 0 82px 0 5px;
}
diff --git a/public/static/css/maps.css b/public/static/css/maps.css
index 70e7821..c40da96 100644
--- a/public/static/css/maps.css
+++ b/public/static/css/maps.css
@@ -13,6 +13,10 @@ div.mapItem.new {
align-items: center;
}
+div.mapItem.unlisted {
+ opacity: 0.6;
+}
+
div.mapItem>div.title {
background-color: #28a745;
color: white;
@@ -75,19 +79,8 @@ div.mapItem>div.buttonContainer {
grid-auto-flow: column;
}
-#restrictions input {
- height: auto;
- margin: 0.5em;
-}
-
-#restrictions input[type=range] {
- height: 1.5em;
- margin-left: 2em;
- width: 70%;
-}
-
#timeLimitType {
- margin-left: 2em;
+ margin-left: 1.5em;
}
@media screen and (min-width: 1504px) {
diff --git a/public/static/js/map_editor.js b/public/static/js/map_editor.js
index 433bc05..6533941 100644
--- a/public/static/js/map_editor.js
+++ b/public/static/js/map_editor.js
@@ -18,6 +18,7 @@
MapEditor.metadata.name = form.elements.name.value;
MapEditor.metadata.description = form.elements.description.value;
+ MapEditor.metadata.unlisted = form.elements.unlisted.checked;
document.getElementById('mapName').innerHTML = form.elements.name.value ? form.elements.name.value : '[unnamed map]';
@@ -254,6 +255,9 @@
if (MapEditor.metadata.description !== null) {
data.append('description', MapEditor.metadata.description);
}
+ if (MapEditor.metadata.unlisted !== null) {
+ data.append('unlisted', MapEditor.metadata.unlisted);
+ }
for (var placeId in MapEditor.added) {
if (!MapEditor.added.hasOwnProperty(placeId)) {
diff --git a/src/Controller/MapAdminController.php b/src/Controller/MapAdminController.php
index aff6a7e..dd00f88 100644
--- a/src/Controller/MapAdminController.php
+++ b/src/Controller/MapAdminController.php
@@ -81,6 +81,7 @@ class MapAdminController implements ISecured
'mapId' => $mapId,
'mapName' => $map->getName(),
'mapDescription' => str_replace('
', "\n", $map->getDescription()),
+ 'mapUnlisted' => $map->getUnlisted(),
'bounds' => $map->getBounds()->toArray(),
'places' => &$places
]);
@@ -175,6 +176,9 @@ class MapAdminController implements ISecured
if (isset($_POST['description'])) {
$map->setDescription(str_replace(["\n", "\r\n"], '
', $_POST['description']));
}
+ if (isset($_POST['unlisted'])) {
+ $map->setUnlisted((bool)$_POST['unlisted']);
+ }
$this->pdm->saveToDb($map);
diff --git a/src/Controller/MapsController.php b/src/Controller/MapsController.php
index 87bca4c..d4f68af 100644
--- a/src/Controller/MapsController.php
+++ b/src/Controller/MapsController.php
@@ -30,12 +30,19 @@ class MapsController
['maps', 'bound_north_lat'],
['maps', 'bound_east_lng'],
['maps', 'area'],
+ ['maps', 'unlisted'],
new RawExpression('COUNT(places.id) AS num_places')
]);
$select->leftJoin('places', ['places', 'map_id'], '=', ['maps', 'id']);
$select->groupBy(['maps', 'id']);
$select->orderBy('name');
+ $user = $this->request->user();
+ $isAdmin = $user !== null && $user->hasPermission(IUser::PERMISSION_ADMIN);
+ if (!$isAdmin) {
+ $select->where(['maps', 'unlisted'], '=', false);
+ }
+
$result = $select->execute();
$maps = [];
@@ -45,11 +52,10 @@ class MapsController
$maps[] = $map;
}
- $user = $this->request->user();
return new HtmlContent('maps', [
'maps' => $maps,
'isLoggedIn' => $user !== null,
- 'isAdmin' => $user !== null && $user->hasPermission(IUser::PERMISSION_ADMIN)
+ 'isAdmin' => $isAdmin
]);
}
diff --git a/src/PersistentData/Model/Map.php b/src/PersistentData/Model/Map.php
index 919c156..cabcb66 100644
--- a/src/PersistentData/Model/Map.php
+++ b/src/PersistentData/Model/Map.php
@@ -6,7 +6,7 @@ class Map extends Model
{
protected static string $table = 'maps';
- protected static array $fields = ['name', 'description', 'bound_south_lat', 'bound_west_lng', 'bound_north_lat', 'bound_east_lng', 'area'];
+ protected static array $fields = ['name', 'description', 'bound_south_lat', 'bound_west_lng', 'bound_north_lat', 'bound_east_lng', 'area', 'unlisted'];
private string $name = '';
@@ -16,6 +16,8 @@ class Map extends Model
private float $area = 0.0;
+ private bool $unlisted = false;
+
public function __construct()
{
$this->bounds = Bounds::createDirectly(-90.0, -180.0, 90.0, 180.0);
@@ -61,6 +63,11 @@ class Map extends Model
$this->area = $area;
}
+ public function setUnlisted(bool $unlisted): void
+ {
+ $this->unlisted = $unlisted;
+ }
+
public function getName(): string
{
return $this->name;
@@ -100,4 +107,9 @@ class Map extends Model
{
return $this->area;
}
+
+ public function getUnlisted(): bool
+ {
+ return $this->unlisted;
+ }
}
diff --git a/views/admin/map_editor.php b/views/admin/map_editor.php
index cd69871..2908278 100644
--- a/views/admin/map_editor.php
+++ b/views/admin/map_editor.php
@@ -54,6 +54,9 @@