Compare commits
No commits in common. "216d30329fd42f18bc629cd27eebff70e2faa631" and "7f8c1eb291505b754b5f6bdaafbdf9f5b0ad3f51" have entirely different histories.
216d30329f
...
7f8c1eb291
@ -1,12 +0,0 @@
|
|||||||
CREATE TABLE `user_played_place` (
|
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
|
||||||
`user_id` int(10) unsigned NOT NULL,
|
|
||||||
`place_id` int(10) unsigned NOT NULL,
|
|
||||||
`last_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`occurrences` int(10) NOT NULL DEFAULT 1,
|
|
||||||
PRIMARY KEY(`id`),
|
|
||||||
KEY `user_id` (`user_id`),
|
|
||||||
KEY `place_id` (`place_id`),
|
|
||||||
CONSTRAINT `user_played_place_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
|
|
||||||
CONSTRAINT `user_played_place_place_id` FOREIGN KEY (`place_id`) REFERENCES `places` (`id`)
|
|
||||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
|
@ -8,7 +8,6 @@ use MapGuesser\PersistentData\PersistentDataManager;
|
|||||||
use MapGuesser\Repository\MultiRoomRepository;
|
use MapGuesser\Repository\MultiRoomRepository;
|
||||||
use MapGuesser\Repository\UserConfirmationRepository;
|
use MapGuesser\Repository\UserConfirmationRepository;
|
||||||
use MapGuesser\Repository\UserPasswordResetterRepository;
|
use MapGuesser\Repository\UserPasswordResetterRepository;
|
||||||
use MapGuesser\Repository\UserPlayedPlaceRepository;
|
|
||||||
use MapGuesser\Repository\UserRepository;
|
use MapGuesser\Repository\UserRepository;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
@ -26,8 +25,6 @@ class MaintainDatabaseCommand extends Command
|
|||||||
|
|
||||||
private MultiRoomRepository $multiRoomRepository;
|
private MultiRoomRepository $multiRoomRepository;
|
||||||
|
|
||||||
private UserPlayedPlaceRepository $userPlayedPlaceRepository;
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
@ -37,7 +34,6 @@ class MaintainDatabaseCommand extends Command
|
|||||||
$this->userConfirmationRepository = new UserConfirmationRepository();
|
$this->userConfirmationRepository = new UserConfirmationRepository();
|
||||||
$this->userPasswordResetterRepository = new UserPasswordResetterRepository();
|
$this->userPasswordResetterRepository = new UserPasswordResetterRepository();
|
||||||
$this->multiRoomRepository = new MultiRoomRepository();
|
$this->multiRoomRepository = new MultiRoomRepository();
|
||||||
$this->userPlayedPlaceRepository = new UserPlayedPlaceRepository();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function configure(): void
|
public function configure(): void
|
||||||
@ -85,10 +81,6 @@ class MaintainDatabaseCommand extends Command
|
|||||||
$this->pdm->deleteFromDb($userPasswordResetter);
|
$this->pdm->deleteFromDb($userPasswordResetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->userPlayedPlaceRepository->getAllByUser($user) as $userPlayedPlace) {
|
|
||||||
$this->pdm->deleteFromDb($userPlayedPlace);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->pdm->deleteFromDb($user);
|
$this->pdm->deleteFromDb($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,10 +7,8 @@ use MapGuesser\Response\JsonContent;
|
|||||||
use MapGuesser\Interfaces\Response\IContent;
|
use MapGuesser\Interfaces\Response\IContent;
|
||||||
use MapGuesser\Multi\MultiConnector;
|
use MapGuesser\Multi\MultiConnector;
|
||||||
use MapGuesser\PersistentData\PersistentDataManager;
|
use MapGuesser\PersistentData\PersistentDataManager;
|
||||||
use MapGuesser\PersistentData\Model\UserPlayedPlace;
|
|
||||||
use MapGuesser\Repository\MultiRoomRepository;
|
use MapGuesser\Repository\MultiRoomRepository;
|
||||||
use MapGuesser\Repository\PlaceRepository;
|
use MapGuesser\Repository\PlaceRepository;
|
||||||
use MapGuesser\Repository\UserPlayedPlaceRepository;
|
|
||||||
|
|
||||||
class GameFlowController
|
class GameFlowController
|
||||||
{
|
{
|
||||||
@ -27,8 +25,6 @@ class GameFlowController
|
|||||||
|
|
||||||
private PlaceRepository $placeRepository;
|
private PlaceRepository $placeRepository;
|
||||||
|
|
||||||
private UserPlayedPlaceRepository $userPlayedPlaceRepository;
|
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct(IRequest $request)
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
@ -36,7 +32,6 @@ class GameFlowController
|
|||||||
$this->multiConnector = new MultiConnector();
|
$this->multiConnector = new MultiConnector();
|
||||||
$this->multiRoomRepository = new MultiRoomRepository();
|
$this->multiRoomRepository = new MultiRoomRepository();
|
||||||
$this->placeRepository = new PlaceRepository();
|
$this->placeRepository = new PlaceRepository();
|
||||||
$this->userPlayedPlaceRepository = new UserPlayedPlaceRepository();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function initialData(): IContent
|
public function initialData(): IContent
|
||||||
@ -150,32 +145,9 @@ class GameFlowController
|
|||||||
|
|
||||||
$session->set('state', $state);
|
$session->set('state', $state);
|
||||||
|
|
||||||
$this->saveVisit($last);
|
|
||||||
|
|
||||||
return new JsonContent($response);
|
return new JsonContent($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the selected place for the round in UserPlayedPlace
|
|
||||||
private function saveVisit($last): void
|
|
||||||
{
|
|
||||||
$session = $this->request->session();
|
|
||||||
$userId = $session->get('userId');
|
|
||||||
|
|
||||||
if(isset($userId)) {
|
|
||||||
$placeId = $last['placeId'];
|
|
||||||
$userPlayedPlace = $this->userPlayedPlaceRepository->getByUserIdAndPlaceId($userId, $placeId);
|
|
||||||
if(!$userPlayedPlace) {
|
|
||||||
$userPlayedPlace = new UserPlayedPlace();
|
|
||||||
$userPlayedPlace->setUserId($userId);
|
|
||||||
$userPlayedPlace->setPlaceId($placeId);
|
|
||||||
} else {
|
|
||||||
$userPlayedPlace->incrementOccurrences();
|
|
||||||
}
|
|
||||||
$userPlayedPlace->setLastTimeDate(new DateTime());
|
|
||||||
$this->pdm->saveToDb($userPlayedPlace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function multiGuess(): IContent
|
public function multiGuess(): IContent
|
||||||
{
|
{
|
||||||
$roomId = $this->request->query('roomId');
|
$roomId = $this->request->query('roomId');
|
||||||
@ -252,10 +224,7 @@ class GameFlowController
|
|||||||
|
|
||||||
private function startNewGame(array &$state, int $mapId): void
|
private function startNewGame(array &$state, int $mapId): void
|
||||||
{
|
{
|
||||||
$session = $this->request->session();
|
$places = $this->placeRepository->getRandomNForMapWithValidPano($mapId, static::NUMBER_OF_ROUNDS);
|
||||||
$userId = $session->get('userId');
|
|
||||||
|
|
||||||
$places = $this->placeRepository->getRandomNPlaces($mapId, static::NUMBER_OF_ROUNDS, $userId);
|
|
||||||
|
|
||||||
$state['rounds'] = [];
|
$state['rounds'] = [];
|
||||||
$state['currentRound'] = 0;
|
$state['currentRound'] = 0;
|
||||||
|
@ -14,7 +14,6 @@ use MapGuesser\PersistentData\Model\UserPasswordResetter;
|
|||||||
use MapGuesser\PersistentData\PersistentDataManager;
|
use MapGuesser\PersistentData\PersistentDataManager;
|
||||||
use MapGuesser\Repository\UserConfirmationRepository;
|
use MapGuesser\Repository\UserConfirmationRepository;
|
||||||
use MapGuesser\Repository\UserPasswordResetterRepository;
|
use MapGuesser\Repository\UserPasswordResetterRepository;
|
||||||
use MapGuesser\Repository\UserPlayedPlaceRepository;
|
|
||||||
use MapGuesser\Repository\UserRepository;
|
use MapGuesser\Repository\UserRepository;
|
||||||
use MapGuesser\Response\HtmlContent;
|
use MapGuesser\Response\HtmlContent;
|
||||||
use MapGuesser\Response\JsonContent;
|
use MapGuesser\Response\JsonContent;
|
||||||
@ -33,8 +32,6 @@ class LoginController
|
|||||||
|
|
||||||
private UserPasswordResetterRepository $userPasswordResetterRepository;
|
private UserPasswordResetterRepository $userPasswordResetterRepository;
|
||||||
|
|
||||||
private UserPlayedPlaceRepository $userPlayedPlaceRepository;
|
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct(IRequest $request)
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
@ -42,7 +39,6 @@ class LoginController
|
|||||||
$this->userRepository = new UserRepository();
|
$this->userRepository = new UserRepository();
|
||||||
$this->userConfirmationRepository = new UserConfirmationRepository();
|
$this->userConfirmationRepository = new UserConfirmationRepository();
|
||||||
$this->userPasswordResetterRepository = new UserPasswordResetterRepository();
|
$this->userPasswordResetterRepository = new UserPasswordResetterRepository();
|
||||||
$this->userPlayedPlaceRepository = new UserPlayedPlaceRepository();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLoginForm()
|
public function getLoginForm()
|
||||||
@ -434,10 +430,6 @@ class LoginController
|
|||||||
|
|
||||||
$user = $this->userRepository->getById($confirmation->getUserId());
|
$user = $this->userRepository->getById($confirmation->getUserId());
|
||||||
|
|
||||||
foreach ($this->userPlayedPlaceRepository->getAllByUser($user) as $userPlayedPlace) {
|
|
||||||
$this->pdm->deleteFromDb($userPlayedPlace);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->pdm->deleteFromDb($user);
|
$this->pdm->deleteFromDb($user);
|
||||||
|
|
||||||
\Container::$dbConnection->commit();
|
\Container::$dbConnection->commit();
|
||||||
|
@ -10,7 +10,6 @@ use MapGuesser\PersistentData\Model\Place;
|
|||||||
use MapGuesser\PersistentData\PersistentDataManager;
|
use MapGuesser\PersistentData\PersistentDataManager;
|
||||||
use MapGuesser\Repository\MapRepository;
|
use MapGuesser\Repository\MapRepository;
|
||||||
use MapGuesser\Repository\PlaceRepository;
|
use MapGuesser\Repository\PlaceRepository;
|
||||||
use MapGuesser\Repository\UserPlayedPlaceRepository;
|
|
||||||
use MapGuesser\Response\HtmlContent;
|
use MapGuesser\Response\HtmlContent;
|
||||||
use MapGuesser\Response\JsonContent;
|
use MapGuesser\Response\JsonContent;
|
||||||
use MapGuesser\Util\Geo\Bounds;
|
use MapGuesser\Util\Geo\Bounds;
|
||||||
@ -28,15 +27,12 @@ class MapAdminController implements ISecured
|
|||||||
|
|
||||||
private PlaceRepository $placeRepository;
|
private PlaceRepository $placeRepository;
|
||||||
|
|
||||||
private UserPlayedPlaceRepository $userPlayedPlaceRepository;
|
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct(IRequest $request)
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
$this->pdm = new PersistentDataManager();
|
$this->pdm = new PersistentDataManager();
|
||||||
$this->mapRepository = new MapRepository();
|
$this->mapRepository = new MapRepository();
|
||||||
$this->placeRepository = new PlaceRepository();
|
$this->placeRepository = new PlaceRepository();
|
||||||
$this->userPlayedPlaceRepository = new UserPlayedPlaceRepository();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
@ -142,7 +138,7 @@ class MapAdminController implements ISecured
|
|||||||
|
|
||||||
$place = $this->placeRepository->getById((int) $placeRaw['id']);
|
$place = $this->placeRepository->getById((int) $placeRaw['id']);
|
||||||
|
|
||||||
$this->deletePlace($place);
|
$this->pdm->deleteFromDb($place);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,19 +178,10 @@ class MapAdminController implements ISecured
|
|||||||
return new JsonContent(['success' => true]);
|
return new JsonContent(['success' => true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function deletePlace(Place $place): void
|
|
||||||
{
|
|
||||||
foreach ($this->userPlayedPlaceRepository->getAllByPlace($place) as $userPlayedPlace) {
|
|
||||||
$this->pdm->deleteFromDb($userPlayedPlace);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->pdm->deleteFromDb($place);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function deletePlaces(Map $map): void
|
private function deletePlaces(Map $map): void
|
||||||
{
|
{
|
||||||
foreach ($this->placeRepository->getAllForMap($map) as $place) {
|
foreach ($this->placeRepository->getAllForMap($map) as $place) {
|
||||||
$this->deletePlace($place);
|
$this->pdm->deleteFromDb($place);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ use MapGuesser\PersistentData\PersistentDataManager;
|
|||||||
use MapGuesser\PersistentData\Model\User;
|
use MapGuesser\PersistentData\Model\User;
|
||||||
use MapGuesser\Repository\UserConfirmationRepository;
|
use MapGuesser\Repository\UserConfirmationRepository;
|
||||||
use MapGuesser\Repository\UserPasswordResetterRepository;
|
use MapGuesser\Repository\UserPasswordResetterRepository;
|
||||||
use MapGuesser\Repository\UserPlayedPlaceRepository;
|
|
||||||
use MapGuesser\Response\HtmlContent;
|
use MapGuesser\Response\HtmlContent;
|
||||||
use MapGuesser\Response\JsonContent;
|
use MapGuesser\Response\JsonContent;
|
||||||
use MapGuesser\Response\Redirect;
|
use MapGuesser\Response\Redirect;
|
||||||
@ -27,15 +26,12 @@ class UserController implements ISecured
|
|||||||
|
|
||||||
private UserPasswordResetterRepository $userPasswordResetterRepository;
|
private UserPasswordResetterRepository $userPasswordResetterRepository;
|
||||||
|
|
||||||
private UserPlayedPlaceRepository $userPlayedPlaceRepository;
|
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct(IRequest $request)
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
$this->pdm = new PersistentDataManager();
|
$this->pdm = new PersistentDataManager();
|
||||||
$this->userConfirmationRepository = new UserConfirmationRepository();
|
$this->userConfirmationRepository = new UserConfirmationRepository();
|
||||||
$this->userPasswordResetterRepository = new UserPasswordResetterRepository();
|
$this->userPasswordResetterRepository = new UserPasswordResetterRepository();
|
||||||
$this->userPlayedPlaceRepository = new UserPlayedPlaceRepository();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
@ -205,10 +201,6 @@ class UserController implements ISecured
|
|||||||
$this->pdm->deleteFromDb($userPasswordResetter);
|
$this->pdm->deleteFromDb($userPasswordResetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->userPlayedPlaceRepository->getAllByUser($user) as $userPlayedPlace) {
|
|
||||||
$this->pdm->deleteFromDb($userPlayedPlace);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->pdm->deleteFromDb($user);
|
$this->pdm->deleteFromDb($user);
|
||||||
|
|
||||||
\Container::$dbConnection->commit();
|
\Container::$dbConnection->commit();
|
||||||
|
@ -12,8 +12,6 @@ class Select
|
|||||||
|
|
||||||
const CONDITION_HAVING = 1;
|
const CONDITION_HAVING = 1;
|
||||||
|
|
||||||
const DERIVED_TABLE_KEY = 'DERIVED';
|
|
||||||
|
|
||||||
private IConnection $connection;
|
private IConnection $connection;
|
||||||
|
|
||||||
private string $table;
|
private string $table;
|
||||||
@ -57,11 +55,6 @@ class Select
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setDerivedTableAlias(string $tableAlias): Select
|
|
||||||
{
|
|
||||||
return $this->setTableAliases([Select::DERIVED_TABLE_KEY => $tableAlias]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function from(string $table): Select
|
public function from(string $table): Select
|
||||||
{
|
{
|
||||||
$this->table = $table;
|
$this->table = $table;
|
||||||
@ -201,11 +194,6 @@ class Select
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isDerivedTable(): bool
|
|
||||||
{
|
|
||||||
return array_key_exists(Select::DERIVED_TABLE_KEY, $this->tableAliases);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function addJoin(string $type, $table, $column1, string $relation, $column2): void
|
private function addJoin(string $type, $table, $column1, string $relation, $column2): void
|
||||||
{
|
{
|
||||||
$this->joins[] = [$type, $table, $column1, $relation, $column2];
|
$this->joins[] = [$type, $table, $column1, $relation, $column2];
|
||||||
@ -223,14 +211,10 @@ class Select
|
|||||||
|
|
||||||
private function generateQuery(): array
|
private function generateQuery(): array
|
||||||
{
|
{
|
||||||
list($tableQuery, $tableParams) = $this->generateTable($this->table, true);
|
$queryString = 'SELECT ' . $this->generateColumns() . ' FROM ' . $this->generateTable($this->table, true);
|
||||||
$queryString = 'SELECT ' . $this->generateColumns() . ' FROM ' . $tableQuery;
|
|
||||||
|
|
||||||
if (count($this->joins) > 0) {
|
if (count($this->joins) > 0) {
|
||||||
list($joinQuery, $joinParams) = $this->generateJoins();
|
$queryString .= ' ' . $this->generateJoins();
|
||||||
$queryString .= ' ' . $joinQuery;
|
|
||||||
} else {
|
|
||||||
$joinParams = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($this->conditions[self::CONDITION_WHERE]) > 0) {
|
if (count($this->conditions[self::CONDITION_WHERE]) > 0) {
|
||||||
@ -261,32 +245,20 @@ class Select
|
|||||||
$queryString .= ' LIMIT ' . $this->limit[1] . ', ' . $this->limit[0];
|
$queryString .= ' LIMIT ' . $this->limit[1] . ', ' . $this->limit[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->isDerivedTable()) {
|
return [$queryString, array_merge($whereParams, $havingParams)];
|
||||||
$queryString = '(' . $queryString . ') AS ' . $this->tableAliases[Select::DERIVED_TABLE_KEY];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [$queryString, array_merge($tableParams, $joinParams, $whereParams, $havingParams)];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateTable($table, bool $defineAlias = false): array
|
private function generateTable($table, bool $defineAlias = false): string
|
||||||
{
|
{
|
||||||
$params = [];
|
|
||||||
|
|
||||||
if ($table instanceof RawExpression) {
|
if ($table instanceof RawExpression) {
|
||||||
return [(string) $table, $params];
|
return (string) $table;
|
||||||
}
|
|
||||||
|
|
||||||
if($table instanceof Select)
|
|
||||||
{
|
|
||||||
return $table->generateQuery();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->tableAliases[$table])) {
|
if (isset($this->tableAliases[$table])) {
|
||||||
$queryString = ($defineAlias ? Utils::backtick($this->tableAliases[$table]) . ' ' . Utils::backtick($table) : Utils::backtick($table));
|
return ($defineAlias ? Utils::backtick($this->tableAliases[$table]) . ' ' . Utils::backtick($table) : Utils::backtick($table));
|
||||||
return [$queryString, $params];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [Utils::backtick($table), $params];
|
return Utils::backtick($table);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateColumn($column): string
|
private function generateColumn($column): string
|
||||||
@ -299,8 +271,7 @@ class Select
|
|||||||
$out = '';
|
$out = '';
|
||||||
|
|
||||||
if ($column[0]) {
|
if ($column[0]) {
|
||||||
list($tableName, $params) = $this->generateTable($column[0]);
|
$out .= $this->generateTable($column[0]) . '.';
|
||||||
$out .= $tableName . '.';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$out .= Utils::backtick($column[1]);
|
$out .= Utils::backtick($column[1]);
|
||||||
@ -326,19 +297,15 @@ class Select
|
|||||||
return implode(',', $columns);
|
return implode(',', $columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateJoins(): array
|
private function generateJoins(): string
|
||||||
{
|
{
|
||||||
|
$joins = $this->joins;
|
||||||
|
|
||||||
$joinQueries = [];
|
array_walk($joins, function (&$value, $key) {
|
||||||
$params = [];
|
$value = $value[0] . ' JOIN ' . $this->generateTable($value[1], true) . ' ON ' . $this->generateColumn($value[2]) . ' ' . $value[3] . ' ' . $this->generateColumn($value[4]);
|
||||||
|
});
|
||||||
|
|
||||||
foreach($this->joins as $join) {
|
return implode(' ', $joins);
|
||||||
list($joinQueryFragment, $paramsFragment) = $this->generateTable($join[1], true);
|
|
||||||
$joinQueries[] = $join[0] . ' JOIN ' . $joinQueryFragment . ' ON ' . $this->generateColumn($join[2]) . ' ' . $join[3] . ' ' . $this->generateColumn($join[4]);
|
|
||||||
$params = array_merge($params, $paramsFragment);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [implode(' ', $joinQueries), $params];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateConditions(int $type): array
|
private function generateConditions(int $type): array
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
<?php namespace MapGuesser\PersistentData\Model;
|
|
||||||
|
|
||||||
use DateTime;
|
|
||||||
|
|
||||||
class UserPlayedPlace extends Model
|
|
||||||
{
|
|
||||||
protected static string $table = 'user_played_place';
|
|
||||||
|
|
||||||
protected static array $fields = ['user_id', 'place_id', 'last_time', 'occurrences'];
|
|
||||||
|
|
||||||
protected static array $relations = ['user' => User::class, 'place' => Place::class];
|
|
||||||
|
|
||||||
private ?User $user = null;
|
|
||||||
|
|
||||||
private ?int $userId = null;
|
|
||||||
|
|
||||||
private ?Place $place = null;
|
|
||||||
|
|
||||||
private ?int $placeId = null;
|
|
||||||
|
|
||||||
private DateTime $lastTime;
|
|
||||||
|
|
||||||
private int $occurrences = 1;
|
|
||||||
|
|
||||||
public function setUser(User $user): void
|
|
||||||
{
|
|
||||||
$this->user = $user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setUserId(int $userId): void
|
|
||||||
{
|
|
||||||
$this->userId = $userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setPlace(Place $place): void
|
|
||||||
{
|
|
||||||
$this->place = $place;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setPlaceId(int $placeId): void
|
|
||||||
{
|
|
||||||
$this->placeId = $placeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setLastTimeDate(DateTime $lastTime): void
|
|
||||||
{
|
|
||||||
$this->lastTime = $lastTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setLastTime(string $lastTime): void
|
|
||||||
{
|
|
||||||
$this->lastTime = new DateTime($lastTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setOccurrences(int $occurrences): void
|
|
||||||
{
|
|
||||||
$this->occurrences = $occurrences;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function incrementOccurrences(): void
|
|
||||||
{
|
|
||||||
$this->occurrences++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUser(): ?User
|
|
||||||
{
|
|
||||||
return $this->user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUserId(): ?int
|
|
||||||
{
|
|
||||||
return $this->userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPlace(): ?Place
|
|
||||||
{
|
|
||||||
return $this->place;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPlaceId(): ?int
|
|
||||||
{
|
|
||||||
return $this->placeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLastTimeDate(): DateTime
|
|
||||||
{
|
|
||||||
return $this->lastTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLastTime(): string
|
|
||||||
{
|
|
||||||
return $this->lastTime->format('Y-m-d H:i:s');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getOccurrences(): int
|
|
||||||
{
|
|
||||||
return $this->occurrences;
|
|
||||||
}
|
|
||||||
}
|
|
@ -28,35 +28,13 @@ class PlaceRepository
|
|||||||
yield from $this->pdm->selectMultipleFromDb($select, Place::class);
|
yield from $this->pdm->selectMultipleFromDb($select, Place::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: use Map and User instead of id
|
|
||||||
public function getRandomNPlaces(int $mapId, int $n, ?int $userId): array
|
|
||||||
{
|
|
||||||
if (!isset($userId)) { // anonymous single player
|
|
||||||
return $this->getRandomNForMapWithValidPano($mapId, $n);
|
|
||||||
} else { // authorized user or multiplayer game with selection based on what the host played before
|
|
||||||
$unvisitedPlaces = $this->getRandomUnvisitedNForMapWithValidPano($mapId, $n, $userId);
|
|
||||||
if (count($unvisitedPlaces) == $n) {
|
|
||||||
return $unvisitedPlaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
$oldPlaces = $this->getRandomOldNForMapWithValidPano($mapId, $n - count($unvisitedPlaces), $userId);
|
|
||||||
|
|
||||||
return array_merge($unvisitedPlaces, $oldPlaces);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: use Map instead of id
|
//TODO: use Map instead of id
|
||||||
private function getRandomNForMapWithValidPano(int $mapId, int $n): array
|
public function getRandomNForMapWithValidPano(int $mapId, int $n, array $exclude = []): array
|
||||||
{
|
{
|
||||||
$places = [];
|
$places = [];
|
||||||
|
|
||||||
$select = new Select(\Container::$dbConnection, 'places');
|
|
||||||
$select->where('map_id', '=', $mapId);
|
|
||||||
$numberOfPlaces = $select->count();
|
|
||||||
|
|
||||||
$exclude = [];
|
|
||||||
for ($i = 1; $i <= $n; ++$i) {
|
for ($i = 1; $i <= $n; ++$i) {
|
||||||
$place = $this->getRandomForMapWithValidPano($numberOfPlaces, $select, $exclude);
|
$place = $this->getRandomForMapWithValidPano($mapId, $exclude);
|
||||||
|
|
||||||
$places[] = $place;
|
$places[] = $place;
|
||||||
$exclude[] = $place->getId();
|
$exclude[] = $place->getId();
|
||||||
@ -65,15 +43,11 @@ class PlaceRepository
|
|||||||
return $places;
|
return $places;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getRandomForMapWithValidPano(int $numberOfPlaces, Select $select, array &$exclude, ?callable $pickRandomInt = null): ?Place
|
//TODO: use Map instead of id
|
||||||
|
public function getRandomForMapWithValidPano(int $mapId, array $exclude = []): Place
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
$numberOfPlacesLeft = $numberOfPlaces - count($exclude);
|
$place = $this->selectRandomFromDbForMap($mapId, $exclude);
|
||||||
$place = $this->selectRandomFromDbForMap($numberOfPlacesLeft, $select, $exclude, $pickRandomInt);
|
|
||||||
if ($place === null) {
|
|
||||||
// there is no more never visited place left
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$panoId = $place->getFreshPanoId();
|
$panoId = $place->getFreshPanoId();
|
||||||
if ($panoId === null) {
|
if ($panoId === null) {
|
||||||
@ -84,97 +58,25 @@ class PlaceRepository
|
|||||||
return $place;
|
return $place;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function selectRandomFromDbForMap(int $numberOfPlacesLeft, Select $select, array $exclude, ?callable $pickRandomInt): ?Place
|
private function selectRandomFromDbForMap(int $mapId, array $exclude): Place
|
||||||
{
|
{
|
||||||
if ($numberOfPlacesLeft <= 0)
|
//TODO: omit table name here
|
||||||
return null;
|
$select = new Select(\Container::$dbConnection, 'places');
|
||||||
|
$select->where('id', 'NOT IN', $exclude);
|
||||||
|
$select->where('map_id', '=', $mapId);
|
||||||
|
|
||||||
if (!isset($pickRandomInt)) {
|
$numberOfPlaces = $select->count();
|
||||||
$randomOffset = random_int(0, $numberOfPlacesLeft - 1);
|
|
||||||
} else {
|
//TODO: prevent this
|
||||||
$randomOffset = $pickRandomInt($numberOfPlacesLeft);
|
if ($numberOfPlaces === 0) {
|
||||||
|
throw new \Exception('There is no selectable place (count was 0).');
|
||||||
}
|
}
|
||||||
|
|
||||||
$select->where('id', 'NOT IN', $exclude);
|
$randomOffset = random_int(0, $numberOfPlaces - 1);
|
||||||
|
|
||||||
|
$select->orderBy('id');
|
||||||
$select->limit(1, $randomOffset);
|
$select->limit(1, $randomOffset);
|
||||||
|
|
||||||
return $this->pdm->selectFromDb($select, Place::class);
|
return $this->pdm->selectFromDb($select, Place::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Never visited places
|
|
||||||
private function getRandomUnvisitedNForMapWithValidPano(int $mapId, int $n, int $userId): array
|
|
||||||
{
|
|
||||||
$places = [];
|
|
||||||
$exclude = [];
|
|
||||||
|
|
||||||
// list of places visited by user
|
|
||||||
$selectPlacesByCurrentUser = new Select(\Container::$dbConnection, 'user_played_place');
|
|
||||||
$selectPlacesByCurrentUser->columns(['place_id', 'last_time']);
|
|
||||||
$selectPlacesByCurrentUser->where('user_id', '=', $userId);
|
|
||||||
$selectPlacesByCurrentUser->setDerivedTableAlias('places_by_current_user');
|
|
||||||
|
|
||||||
// count the places never visited
|
|
||||||
$selectUnvisited = new Select(\Container::$dbConnection, 'places');
|
|
||||||
$selectUnvisited->leftJoin($selectPlacesByCurrentUser, ['places', 'id'], '=', ['places_by_current_user', 'place_id']);
|
|
||||||
$selectUnvisited->where('map_id', '=', $mapId);
|
|
||||||
$selectUnvisited->where('last_time', '=', null);
|
|
||||||
$numberOfUnvisitedPlaces = $selectUnvisited->count();
|
|
||||||
|
|
||||||
// look for as many new places as possible but maximum $n
|
|
||||||
do {
|
|
||||||
$place = $this->getRandomForMapWithValidPano($numberOfUnvisitedPlaces, $selectUnvisited, $exclude);
|
|
||||||
if (isset($place)) {
|
|
||||||
$places[] = $place;
|
|
||||||
$exclude[] = $place->getId();
|
|
||||||
}
|
|
||||||
} while (count($places) < $n && isset($place));
|
|
||||||
|
|
||||||
return $places;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Places visited in the longest time
|
|
||||||
private function getRandomOldNForMapWithValidPano(int $mapId, int $n, int $userId): array
|
|
||||||
{
|
|
||||||
$places = [];
|
|
||||||
$exclude = [];
|
|
||||||
|
|
||||||
// list of places visited by user
|
|
||||||
$selectPlacesByCurrentUser = new Select(\Container::$dbConnection, 'user_played_place');
|
|
||||||
$selectPlacesByCurrentUser->columns(['place_id', 'last_time']);
|
|
||||||
$selectPlacesByCurrentUser->where('user_id', '=', $userId);
|
|
||||||
$selectPlacesByCurrentUser->setDerivedTableAlias('places_by_current_user');
|
|
||||||
|
|
||||||
// count places that were visited at least once
|
|
||||||
$selectOldPlaces = new Select(\Container::$dbConnection, 'places');
|
|
||||||
$selectOldPlaces->innerJoin($selectPlacesByCurrentUser, ['places', 'id'], '=', ['places_by_current_user', 'place_id']);
|
|
||||||
$selectOldPlaces->where('map_id', '=', $mapId);
|
|
||||||
$numberOfOldPlaces = $selectOldPlaces->count();
|
|
||||||
|
|
||||||
// set order by datetime, oldest first
|
|
||||||
$selectOldPlaces->orderBy('last_time');
|
|
||||||
|
|
||||||
// selection algorithm with preference (weighting) for older places using Box-Muller transform
|
|
||||||
$pickGaussianRandomInt = function($numberOfPlaces) {
|
|
||||||
$stdev = 0.2;
|
|
||||||
$avg = 0.0;
|
|
||||||
$x = mt_rand() / mt_getrandmax();
|
|
||||||
$y = mt_rand() / mt_getrandmax();
|
|
||||||
$randomNum = abs(sqrt(-2 * log($x)) * cos(2 * pi() * $y) * $stdev + $avg);
|
|
||||||
return (int) min($randomNum * $numberOfPlaces, $numberOfPlaces - 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
// look for n - numberOfUnvisitedPlaces places
|
|
||||||
while (count($places) < $n)
|
|
||||||
{
|
|
||||||
$place = $this->getRandomForMapWithValidPano($numberOfOldPlaces, $selectOldPlaces, $exclude, $pickGaussianRandomInt);
|
|
||||||
if (isset($place))
|
|
||||||
{
|
|
||||||
$places[] = $place;
|
|
||||||
$exclude[] = $place->getId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $places;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
<?php namespace MapGuesser\Repository;
|
|
||||||
|
|
||||||
use DateTime;
|
|
||||||
use Generator;
|
|
||||||
use MapGuesser\Database\Query\Select;
|
|
||||||
use MapGuesser\PersistentData\Model\User;
|
|
||||||
use MapGuesser\PersistentData\Model\Place;
|
|
||||||
use MapGuesser\PersistentData\Model\UserPlayedPlace;
|
|
||||||
use MapGuesser\PersistentData\PersistentDataManager;
|
|
||||||
|
|
||||||
class UserPlayedPlaceRepository
|
|
||||||
{
|
|
||||||
private PersistentDataManager $pdm;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->pdm = new PersistentDataManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getByUser(User $user): Generator
|
|
||||||
{
|
|
||||||
$select = new Select(\Container::$dbConnection);
|
|
||||||
$select->where('user_id', '=', $user->getId());
|
|
||||||
|
|
||||||
yield from $this->pdm->selectMultipleFromDb($select, UserPlayedPlace::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllByPlace(Place $place): Generator
|
|
||||||
{
|
|
||||||
$select = new Select(\Container::$dbConnection);
|
|
||||||
$select->where('place_id', '=', $place->getId());
|
|
||||||
|
|
||||||
yield from $this->pdm->selectMultipleFromDb($select, UserPlayedPlace::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllByUser(User $user) : Generator
|
|
||||||
{
|
|
||||||
$select = new Select(\Container::$dbConnection);
|
|
||||||
$select->where('user_id', '=', $user->getId());
|
|
||||||
|
|
||||||
yield from $this->pdm->selectMultipleFromDb($select, UserPlayedPlace::class, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getByUserIdAndPlaceId(int $userId, int $placeId) : ?UserPlayedPlace
|
|
||||||
{
|
|
||||||
$select = new Select(\Container::$dbConnection);
|
|
||||||
$select->where('user_id', '=', $userId);
|
|
||||||
$select->where('place_id', '=', $placeId);
|
|
||||||
|
|
||||||
return $this->pdm->selectFromDb($select, UserPlayedPlace::class);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user