From 44df94eb9832b0f40e7d3ab8ddf5869222631f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Vigh?= Date: Sat, 15 May 2021 11:32:41 +0200 Subject: [PATCH] MAPG-235 queries with relations on any recursion level implemented --- src/Controller/GameController.php | 3 +- src/Controller/GameFlowController.php | 16 ++-- src/PersistentData/PersistentDataManager.php | 85 ++++++++++++++++---- src/Repository/GuessRepository.php | 4 +- src/Repository/PlaceRepository.php | 9 +++ src/Repository/UserInChallengeRepository.php | 11 +++ 6 files changed, 102 insertions(+), 26 deletions(-) diff --git a/src/Controller/GameController.php b/src/Controller/GameController.php index b17aec2..788bfe0 100644 --- a/src/Controller/GameController.php +++ b/src/Controller/GameController.php @@ -143,7 +143,7 @@ class GameController // select places $mapId = (int) $this->request->post('mapId'); - $map = $this->mapRepository->getById($mapId); + // $map = $this->mapRepository->getById($mapId); $places = $this->placeRepository->getRandomNPlaces($mapId, static::NUMBER_OF_ROUNDS, $userId); @@ -242,6 +242,7 @@ class GameController $challenge = $this->challengeRepository->getByTokenStr($challengeToken_str); if(!$this->userInChallengeRepository->isUserParticipatingInChallenge($userId, $challenge)) { + // new player is joining $userInChallenge = new UserInChallenge(); $userInChallenge->setUserId($userId); $userInChallenge->setChallenge($challenge); diff --git a/src/Controller/GameFlowController.php b/src/Controller/GameFlowController.php index aa0de1b..7043afd 100644 --- a/src/Controller/GameFlowController.php +++ b/src/Controller/GameFlowController.php @@ -146,13 +146,13 @@ class GameFlowController $session = $this->request->session(); $userId = $session->get('userId'); $challengeToken_str = $this->request->query('challengeToken'); - $challenge = $this->challengeRepository->getByTokenStr($challengeToken_str); + $userInChallenge = $this->userInChallengeRepository->getByUserIdAndToken($userId, $challengeToken_str); - if (!isset($challenge)) { + if (!isset($userInChallenge)) { return new JsonContent(['error' => 'game_not_found']); } - $userInChallenge = $this->userInChallengeRepository->getByUserIdAndChallenge($userId, $challenge); + $challenge = $userInChallenge->getChallenge(); $currentRound = $userInChallenge->getRound(); $currentPlace = $this->placeRepository->getByRoundInChallenge($challenge, $currentRound); @@ -160,6 +160,7 @@ class GameFlowController $response['history'] = []; + $allGuessesInChallenge = iterator_to_array($this->guessRepository->getAllInChallenge($challenge)); $guessesByUser = iterator_to_array($this->guessRepository->getAllInChallengeByUser($userId, $challenge)); $places = iterator_to_array($this->placeRepository->getAllInChallenge($challenge)); @@ -205,6 +206,9 @@ class GameFlowController public function guess(): IContent { + // testing + $testPlace = $this->placeRepository->getByIdWithMap(5); + $mapId = (int) $this->request->query('mapId'); $session = $this->request->session(); @@ -305,13 +309,13 @@ class GameFlowController $session = $this->request->session(); $userId = $session->get('userId'); $challengeToken_str = $this->request->query('challengeToken'); - $challenge = $this->challengeRepository->getByTokenStr($challengeToken_str); + $userInChallenge = $this->userInChallengeRepository->getByUserIdAndToken($userId, $challengeToken_str); - if (!isset($challenge)) { + if (!isset($userInChallenge)) { return new JsonContent(['error' => 'game_not_found']); } - $userInChallenge = $this->userInChallengeRepository->getByUserIdAndChallenge($userId, $challenge); + $challenge = $userInChallenge->getChallenge(); $currentRound = $userInChallenge->getRound(); $currentPlace = $this->placeRepository->getByRoundInChallenge($challenge, $currentRound); $map = $this->mapRepository->getByPlace($currentPlace); diff --git a/src/PersistentData/PersistentDataManager.php b/src/PersistentData/PersistentDataManager.php index 8aa8bc1..d89ce54 100644 --- a/src/PersistentData/PersistentDataManager.php +++ b/src/PersistentData/PersistentDataManager.php @@ -45,24 +45,62 @@ class PersistentDataManager return $this->selectFromDb($select, $type, $withRelations); } - public function fillWithData(array $data, Model $model): void + public function fillWithData(array &$data, Model $model, ?string $modelKey = null): void { $relations = $model::getRelations(); $relationData = []; - foreach ($data as $key => $value) { - if ($this->extractRelationData($key, $value, $relationData, $relations)) { - continue; - } + while (key($data)) { + $key = key($data); + $value = current($data); + $relation = key($relations); - $method = 'set' . str_replace('_', '', ucwords($key, '_')); + if (strpos($key, '__') == false) { + $method = 'set' . str_replace('_', '', ucwords($key, '_')); - if (method_exists($model, $method)) { - $model->$method($value); + if (method_exists($model, $method)) { + $model->$method($value); + } + + next($data); + } else if (isset($modelKey) && substr($key, 0, strlen($modelKey . '__')) === $modelKey . '__') { + $key = substr($key, strlen($modelKey) + 2); + + $method = 'set' . str_replace('_', '', ucwords($key, '_')); + + if (method_exists($model, $method)) { + $model->$method($value); + } + + next($data); + } else if (substr($key, 0, strlen($relation . '__')) === $relation . '__') { + // $relation = current($relations); + $relationType = current($relations); + $relationModel = new $relationType(); + $this->fillWithData($data, $relationModel, $relation); + + $method = 'set' . str_replace('_', '', ucwords($relation, '_')); + $model->$method($relationModel); + + next($relations); + } else { + return; } } - $this->setRelations($model, $relationData); + // foreach ($data as $key => $value) { + // if ($this->extractRelationData($key, $value, $relationData, $relations)) { + // continue; + // } + + // $method = 'set' . str_replace('_', '', ucwords($key, '_')); + + // if (method_exists($model, $method)) { + // $model->$method($value); + // } + // } + + // $this->setRelations($model, $relationData); $model->saveSnapshot(); } @@ -133,9 +171,15 @@ class PersistentDataManager $table = call_user_func([$type, 'getTable']); $fields = call_user_func([$type, 'getFields']); - array_walk($fields, function (&$value, $key, $table) { - $value = [$table, $value]; - }, $table); + // array_walk($fields, function (&$value, $key, $table) { + // $value = [$table, $value]; + // }, $table); + + $columns = []; + + foreach ($fields as $field) { + $columns[] = [$table, $field]; + } $select->from($table); @@ -143,18 +187,19 @@ class PersistentDataManager if ($withRelations) { $relations = call_user_func([$type, 'getRelations']); - $columns = []; + // $columns = []; - foreach ($fields as $field) { - $columns[] = [$table, $field]; - } + // foreach ($fields as $field) { + // $columns[] = [$table, $field]; + // } $columns = array_merge($columns, $this->getRelationColumns($relations)); $this->leftJoinRelations($select, $table, $relations); $select->columns($columns); } else { - $select->columns($fields); + // $select->columns($fields); + $select->columns($columns); } return $select; @@ -169,6 +214,9 @@ class PersistentDataManager foreach (call_user_func([$relationType, 'getFields']) as $relationField) { $columns[] = [$relationTable, $relationField, $relation . '__' . $relationField]; } + + $nextOrderRelations = call_user_func([$relationType, 'getRelations']); + $columns = array_merge($columns, $this->getRelationColumns($nextOrderRelations)); } return $columns; @@ -179,6 +227,9 @@ class PersistentDataManager foreach ($relations as $relation => $relationType) { $relationTable = call_user_func([$relationType, 'getTable']); $select->leftJoin($relationTable, [$relationTable, 'id'], '=', [$table, $relation . '_id']); + + $nextOrderRelations = call_user_func([$relationType, 'getRelations']); + $this->leftJoinRelations($select, $relationTable, $nextOrderRelations); } } diff --git a/src/Repository/GuessRepository.php b/src/Repository/GuessRepository.php index 71c467b..b99fa90 100644 --- a/src/Repository/GuessRepository.php +++ b/src/Repository/GuessRepository.php @@ -53,11 +53,11 @@ class GuessRepository public function getAllInChallenge(Challenge $challenge): Generator { $select = new Select(\Container::$dbConnection); - $select->innerJoin('place_in_challenge', ['guesses', 'place_in_challenge_id'], '=', ['place_in_challenge', 'id']); + // $select->innerJoin('place_in_challenge', ['guesses', 'place_in_challenge_id'], '=', ['place_in_challenge', 'id']); $select->where('challenge_id', '=', $challenge->getId()); $select->orderBy('order'); - yield from $this->pdm->selectMultipleFromDb($select, Guess::class); + yield from $this->pdm->selectMultipleFromDb($select, Guess::class, true); } public function getAllInChallengeByRound(int $round, Challenge $challenge): Generator diff --git a/src/Repository/PlaceRepository.php b/src/Repository/PlaceRepository.php index 7c7c548..9d072be 100644 --- a/src/Repository/PlaceRepository.php +++ b/src/Repository/PlaceRepository.php @@ -198,5 +198,14 @@ class PlaceRepository yield from $this->pdm->selectMultipleFromDb($select, Place::class); } + + public function getByIdWithMap(int $placeId): ?Place + { + $select = new Select(\Container::$dbConnection); + // $select->innerJoin('maps', ['maps', 'id'], '=', ['places', 'map_id']); + $select->where(['places', 'id'], '=', $placeId); + + return $this->pdm->selectFromDb($select, Place::class, true); + } } diff --git a/src/Repository/UserInChallengeRepository.php b/src/Repository/UserInChallengeRepository.php index 20ae0d5..3ebdd23 100644 --- a/src/Repository/UserInChallengeRepository.php +++ b/src/Repository/UserInChallengeRepository.php @@ -41,6 +41,17 @@ class UserInChallengeRepository return $this->pdm->selectFromDb($select, UserInChallenge::class); } + public function getByUserIdAndToken(int $userId, string $token_str): ?UserInChallenge + { + $token = hexdec($token_str); + + $select = new Select(\Container::$dbConnection); + $select->where('user_id', '=', $userId); + $select->where('token', '=', $token); + + return $this->pdm->selectFromDb($select, UserInChallenge::class, true); + } + public function isUserParticipatingInChallenge(int $userId, Challenge $challenge): bool { $select = new Select(\Container::$dbConnection, 'user_in_challenge');