diff --git a/src/Controller/GameFlowController.php b/src/Controller/GameFlowController.php index 913cfa6..b15ffa7 100644 --- a/src/Controller/GameFlowController.php +++ b/src/Controller/GameFlowController.php @@ -4,6 +4,7 @@ use MapGuesser\Interfaces\Request\IRequest; use MapGuesser\Util\Geo\Position; use MapGuesser\Response\JsonContent; use MapGuesser\Interfaces\Response\IContent; +use MapGuesser\PersistentData\Model\Place; use MapGuesser\Repository\PlaceRepository; class GameFlowController @@ -33,11 +34,14 @@ class GameFlowController } if (count($state['rounds']) === 0) { - $place = $this->placeRepository->getForMapWithValidPano($mapId); - $state['rounds'][] = $place; + $placesWithoutPano = []; + $place = $this->placeRepository->getRandomForMapWithValidPano($mapId, [], $placesWithoutPano); + + $this->addNewRoundToState($state, $place, $placesWithoutPano); + $session->set('state', $state); - $data = ['panoId' => $place['panoId']]; + $data = ['panoId' => $place->getPanoIdCached()]; } else { $rounds = count($state['rounds']); $last = $state['rounds'][$rounds - 1]; @@ -93,18 +97,20 @@ class GameFlowController $exclude = array_merge($exclude, $round['placesWithoutPano'], [$round['placeId']]); } - $place = $this->placeRepository->getForMapWithValidPano($mapId, $exclude); - $state['rounds'][] = $place; - $session->set('state', $state); + $placesWithoutPano = []; + $place = $this->placeRepository->getRandomForMapWithValidPano($mapId, $exclude, $placesWithoutPano); - $panoId = $place['panoId']; + $this->addNewRoundToState($state, $place, $placesWithoutPano); + + $panoId = $place->getPanoIdCached(); } else { $state['rounds'] = []; - $session->set('state', $state); $panoId = null; } + $session->set('state', $state); + $data = [ 'result' => [ 'position' => $position->toArray(), @@ -116,6 +122,16 @@ class GameFlowController return new JsonContent($data); } + private function addNewRoundToState(&$state, Place $place, array $placesWithoutPano): void + { + $state['rounds'][] = [ + 'placesWithoutPano' => $placesWithoutPano, + 'placeId' => $place->getId(), + 'position' => $place->getPosition(), + 'panoId' => $place->getPanoIdCached() + ]; + } + private function calculateDistance(Position $realPosition, Position $guessPosition): float { return $realPosition->calculateDistanceTo($guessPosition); diff --git a/src/Controller/MapAdminController.php b/src/Controller/MapAdminController.php index 6ddada2..d12ccbf 100644 --- a/src/Controller/MapAdminController.php +++ b/src/Controller/MapAdminController.php @@ -1,7 +1,6 @@ mapRepository->getById($mapId); - $places = $this->getPlaces($mapId); + $places = $this->getPlaces($map); } else { $map = new Map(); $map->setName(self::$unnamedMapName); @@ -65,9 +65,9 @@ class MapAdminController implements ISecured { $placeId = (int) $this->request->query('placeId'); - $placeData = $this->placeRepository->getById($placeId); + $place = $this->placeRepository->getById($placeId); - $data = ['panoId' => $placeData['panoId']]; + $data = ['panoId' => $place->getFreshPanoId()]; return new JsonContent($data); } @@ -83,7 +83,6 @@ class MapAdminController implements ISecured $map = new Map(); $map->setName(self::$unnamedMapName); $this->pdm->saveToDb($map); - $mapId = $map->getId(); } if (isset($_POST['added'])) { @@ -91,11 +90,18 @@ class MapAdminController implements ISecured foreach ($_POST['added'] as $placeRaw) { $placeRaw = json_decode($placeRaw, true); - $addedIds[] = ['tempId' => $placeRaw['id'], 'id' => $this->placeRepository->addToMap($mapId, [ - 'lat' => (float) $placeRaw['lat'], - 'lng' => (float) $placeRaw['lng'], - 'pano_id_cached_timestamp' => $placeRaw['panoId'] === -1 ? (new DateTime('-1 day'))->format('Y-m-d H:i:s') : null - ])]; + $place = new Place(); + $place->setMap($map); + $place->setLat((float) $placeRaw['lat']); + $place->setLng((float) $placeRaw['lng']); + + if ($placeRaw['panoId'] === -1) { + $place->setPanoIdCachedTimestampDate(new DateTime('-1 day')); + } + + $this->pdm->saveToDb($place); + + $addedIds[] = ['tempId' => $placeRaw['id'], 'id' => $place->getId()]; } } else { $addedIds = []; @@ -105,10 +111,12 @@ class MapAdminController implements ISecured foreach ($_POST['edited'] as $placeRaw) { $placeRaw = json_decode($placeRaw, true); - $this->placeRepository->modify((int) $placeRaw['id'], [ - 'lat' => (float) $placeRaw['lat'], - 'lng' => (float) $placeRaw['lng'] - ]); + $place = $this->placeRepository->getById((int) $placeRaw['id']); + $place->setLat((float) $placeRaw['lat']); + $place->setLng((float) $placeRaw['lng']); + $place->setPanoIdCachedTimestampDate(new DateTime('-1 day')); + + $this->pdm->saveToDb($place); } } @@ -116,11 +124,13 @@ class MapAdminController implements ISecured foreach ($_POST['deleted'] as $placeRaw) { $placeRaw = json_decode($placeRaw, true); - $this->placeRepository->delete($placeRaw['id']); + $place = $this->placeRepository->getById((int) $placeRaw['id']); + + $this->pdm->deleteFromDb($place); } } - $mapBounds = $this->calculateMapBounds($mapId); + $mapBounds = $this->calculateMapBounds($map); $map->setBounds($mapBounds); $map->setArea($mapBounds->calculateApproximateArea()); @@ -136,7 +146,7 @@ class MapAdminController implements ISecured \Container::$dbConnection->commit(); - $data = ['mapId' => $mapId, 'added' => $addedIds]; + $data = ['mapId' => $map->getId(), 'added' => $addedIds]; return new JsonContent($data); } @@ -147,7 +157,7 @@ class MapAdminController implements ISecured \Container::$dbConnection->startTransaction(); - $this->deletePlaces($mapId); + $this->deletePlaces($map); $this->pdm->deleteFromDb($map); @@ -157,26 +167,30 @@ class MapAdminController implements ISecured return new JsonContent($data); } - private function deletePlaces(int $mapId): void + private function deletePlaces(Map $map): void { + //TODO: relations? $select = new Select(\Container::$dbConnection, 'places'); - $select->columns(['id']); - $select->where('map_id', '=', $mapId); + $select->columns(Place::getFields()); + $select->where('map_id', '=', $map->getId()); $result = $select->execute(); - while ($place = $result->fetch(IResultSet::FETCH_ASSOC)) { - $modify = new Modify(\Container::$dbConnection, 'places'); - $modify->setId($place['id']); - $modify->delete(); + while ($placeData = $result->fetch(IResultSet::FETCH_ASSOC)) { + $place = new Place(); + + $this->pdm->fillWithData($placeData, $place); + + $this->pdm->deleteFromDb($place); } } - private function calculateMapBounds(int $mapId): Bounds + private function calculateMapBounds(Map $map): Bounds { + //TODO: from repository or relations $select = new Select(\Container::$dbConnection, 'places'); $select->columns(['lat', 'lng']); - $select->where('map_id', '=', $mapId); + $select->where('map_id', '=', $map->getId()); $result = $select->execute(); @@ -188,11 +202,12 @@ class MapAdminController implements ISecured return $bounds; } - private function &getPlaces(int $mapId): array + private function &getPlaces(Map $map): array { + //TODO: from repository or relations $select = new Select(\Container::$dbConnection, 'places'); $select->columns(['id', 'lat', 'lng', 'pano_id_cached', 'pano_id_cached_timestamp']); - $select->where('map_id', '=', $mapId); + $select->where('map_id', '=', $map->getId()); $result = $select->execute(); diff --git a/src/Repository/PlaceRepository.php b/src/Repository/PlaceRepository.php index 2a6b325..16f2afe 100644 --- a/src/Repository/PlaceRepository.php +++ b/src/Repository/PlaceRepository.php @@ -1,95 +1,43 @@ selectFromDbById($placeId); - - $panoId = $this->requestPanoId($place); - - $position = new Position($place['lat'], $place['lng']); - - return [ - 'position' => $position, - 'panoId' => $panoId - ]; + $this->pdm = new PersistentDataManager(); } - public function getForMapWithValidPano(int $mapId, array $exclude = []): array + public function getById(int $placeId): ?Place + { + return $this->pdm->selectFromDbById($placeId, Place::class); + } + + public function getRandomForMapWithValidPano(int $mapId, array $exclude = [], array &$placesWithoutPano): Place { $placesWithoutPano = []; do { - $place = $this->selectFromDbForMap($mapId, $exclude); + $place = $this->selectRandomFromDbForMap($mapId, $exclude); - $panoId = $this->requestPanoId($place); + $panoId = $place->getFreshPanoId(); if ($panoId === null) { - $placesWithoutPano[] = $exclude[] = $place['id']; + $placesWithoutPano[] = $exclude[] = $place->getId(); } } while ($panoId === null); - $position = new Position($place['lat'], $place['lng']); - - return [ - 'placesWithoutPano' => $placesWithoutPano, - 'placeId' => $place['id'], - 'position' => $position, - 'panoId' => $panoId - ]; - } - - public function addToMap(int $mapId, array $place): int - { - $modify = new Modify(\Container::$dbConnection, 'places'); - $modify->set('map_id', $mapId); - $modify->fill($place); - $modify->save(); - - return $modify->getId(); - } - - public function modify(int $id, array $place): void - { - $modify = new Modify(\Container::$dbConnection, 'places'); - $modify->setId($id); - $modify->set('pano_id_cached', null); - $modify->set('pano_id_cached_timestamp', null); - $modify->fill($place); - $modify->save(); - } - - public function delete(int $id): void - { - $modify = new Modify(\Container::$dbConnection, 'places'); - $modify->setId($id); - $modify->delete(); - } - - private function selectFromDbById(int $placeId): array - { - $select = new Select(\Container::$dbConnection, 'places'); - $select->columns(['id', 'lat', 'lng', 'pano_id_cached', 'pano_id_cached_timestamp']); - $select->whereId($placeId); - - $place = $select->execute()->fetch(IResultSet::FETCH_ASSOC); - return $place; } - private function selectFromDbForMap(int $mapId, array $exclude): array + private function selectRandomFromDbForMap(int $mapId, array $exclude): ?Place { $select = new Select(\Container::$dbConnection, 'places'); - $select->columns(['id', 'lat', 'lng', 'pano_id_cached', 'pano_id_cached_timestamp']); $select->where('id', 'NOT IN', $exclude); $select->where('map_id', '=', $mapId); @@ -99,49 +47,6 @@ class PlaceRepository $select->orderBy('id'); $select->limit(1, $randomOffset); - $place = $select->execute()->fetch(IResultSet::FETCH_ASSOC); - - return $place; - } - - private function requestPanoId(array $place, bool $canBeIndoor = false): ?string - { - if ( - $place['pano_id_cached_timestamp'] && - (new DateTime($place['pano_id_cached_timestamp']))->add(new DateInterval('P1D')) > new DateTime() - ) { - return $place['pano_id_cached']; - } - - $request = new Request('https://maps.googleapis.com/maps/api/streetview/metadata', Request::HTTP_GET); - $request->setQuery([ - 'key' => $_ENV['GOOGLE_MAPS_SERVER_API_KEY'], - 'location' => $place['lat'] . ',' . $place['lng'], - 'source' => $canBeIndoor ? 'default' : 'outdoor' - ]); - - $response = $request->send(); - - $panoData = json_decode($response->getBody(), true); - - $panoId = $panoData['status'] === 'OK' ? $panoData['pano_id'] : null; - - // enable indoor panos if no outdoor found - if ($panoId === null && !$canBeIndoor) { - return $this->requestPanoId($place, true); - } - - $this->saveCachedPanoId($place['id'], $panoId); - - return $panoId; - } - - private function saveCachedPanoId(int $placeId, ?string $panoId): void - { - $modify = new Modify(\Container::$dbConnection, 'places'); - $modify->setId($placeId); - $modify->set('pano_id_cached', $panoId); - $modify->set('pano_id_cached_timestamp', (new DateTime())->format('Y-m-d H:i:s')); - $modify->save(); + return $this->pdm->selectFromDb($select, Place::class); } }