Implermented front page and set public
This commit is contained in:
parent
15a9dcf09b
commit
d6ebf8f4ff
18 changed files with 658 additions and 23 deletions
|
@ -11,7 +11,7 @@ use Symfony\Component\Uid\UuidV4;
|
|||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: "users")]
|
||||
final class User
|
||||
class User
|
||||
{
|
||||
|
||||
#[ORM\Id()]
|
||||
|
|
|
@ -31,6 +31,9 @@ final class Key implements JsonSerializable
|
|||
#[ORM\Column(type: 'integer', enumType: KeyState::class)]
|
||||
private KeyState $state;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
private User $claimedUser;
|
||||
|
||||
public function __construct(Game $game, GamesList $list, string $key, Store $store, ?string $storeLink, ?string $fromWhere)
|
||||
{
|
||||
$this->game = $game;
|
||||
|
@ -52,11 +55,6 @@ final class Key implements JsonSerializable
|
|||
return $this->game;
|
||||
}
|
||||
|
||||
public function getContributedUser(): User
|
||||
{
|
||||
return $this->contributedUser;
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return $this->key;
|
||||
|
@ -81,6 +79,19 @@ final class Key implements JsonSerializable
|
|||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
public function getList(): GamesList
|
||||
{
|
||||
return $this->list;
|
||||
}
|
||||
|
||||
public function setState(KeyState $state): void {
|
||||
$this->state = $state;
|
||||
}
|
||||
|
||||
public function setClaimedUser(User $claimedUser): void {
|
||||
$this->claimedUser = $claimedUser;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
|
|
|
@ -12,4 +12,33 @@ enum Store: string
|
|||
case UPLAY = 'uplay';
|
||||
case BATTLENET = 'battlenet';
|
||||
case EXTERNAL = 'external';
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::STEAM => 'Steam',
|
||||
self::GOG => "GOG",
|
||||
self::EPICGAMES => "Epic Games Store",
|
||||
self::ORIGIN => "EA Play / Origin",
|
||||
self::UPLAY => "UPlay",
|
||||
self::BATTLENET => "Battlenet",
|
||||
self::EXTERNAL => "Other",
|
||||
};
|
||||
}
|
||||
|
||||
public function getIcon(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::STEAM => 'fa-solid fa-steam',
|
||||
default => '',
|
||||
};
|
||||
}
|
||||
|
||||
public function getClaimURL(Key $key): ?string {
|
||||
return match ($this) {
|
||||
self::STEAM => 'https://store.steampowered.com/account/registerkey?key=' . $key->getKey(),
|
||||
self::EXTERNAL => $key->getStoreLink(),
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use GamesShop\Entities\Account\User;
|
|||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'games_lists')]
|
||||
final class GamesList
|
||||
class GamesList
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
|
@ -27,6 +27,9 @@ final class GamesList
|
|||
#[ORM\JoinColumn(name: 'id', referencedColumnName: 'id')]
|
||||
#[ORM\ManyToMany(targetEntity: User::class)]
|
||||
private Collection $claimer;
|
||||
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true, 'default' => 0])]
|
||||
private bool $isPublic = false;
|
||||
|
||||
/**
|
||||
* @param User $owner
|
||||
|
@ -60,6 +63,14 @@ final class GamesList
|
|||
return $this->claimer;
|
||||
}
|
||||
|
||||
public function isPublic(): bool {
|
||||
return $this->isPublic;
|
||||
}
|
||||
|
||||
public function setIsPublic(bool $isPublic): void {
|
||||
$this->isPublic = $isPublic;
|
||||
}
|
||||
|
||||
public function addClaimer(User $claimer): void
|
||||
{
|
||||
$this->claimer[] = $claimer;
|
||||
|
|
74
src/php/Routing/Api/DataTables/AvailableKeysEndpoint.php
Normal file
74
src/php/Routing/Api/DataTables/AvailableKeysEndpoint.php
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace GamesShop\Routing\Api\DataTables;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Entities\Games\Key;
|
||||
use GamesShop\Entities\Games\KeyState;
|
||||
use GamesShop\Entities\GamesList;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use GamesShop\UserManager;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class AvailableKeysEndpoint
|
||||
{
|
||||
public function __construct(
|
||||
private readonly LoginHandler $loginHandler,
|
||||
private readonly EntityManager $entityManager,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
if (!$this->loginHandler->isLoggedIn()) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
|
||||
$user = $this->loginHandler->getCurrentUser();
|
||||
if (!$user->getPermission()->hasLevel(UserPermission::VIEWER)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
$applicableLists = ContainerHandler::get(UserManager::class)
|
||||
->getApplicableGameLists($user);
|
||||
|
||||
$keyRepo = $this->entityManager->getRepository(Key::class);
|
||||
$keys = $keyRepo->matching(Criteria::create()
|
||||
->where(Criteria::expr()->in('list', $applicableLists->toArray()))
|
||||
->andWhere(Criteria::expr()->eq('state', KeyState::AVAILABLE))
|
||||
);
|
||||
|
||||
$games = new ArrayCollection();
|
||||
foreach ($keys as $key) {
|
||||
$game = $key->getGame();
|
||||
|
||||
if ($games->contains($game)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$games->add($game);
|
||||
}
|
||||
|
||||
return new JsonResponse(
|
||||
[
|
||||
'data' =>
|
||||
$games
|
||||
->map(fn ($game) => [
|
||||
'name' => $game->getName(),
|
||||
'id' => $game->getId(),
|
||||
])
|
||||
->toArray()
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ final class DataTablesAPIRoutes
|
|||
AccountsEndpoint::applyRoutes($group);
|
||||
|
||||
$group->get('/keys/provider', ProviderKeysEndpoint::class);
|
||||
$group->get('/keys/available', AvailableKeysEndpoint::class);
|
||||
$group->get('/list/users', SharedUsersEndpoint::class);
|
||||
}
|
||||
}
|
71
src/php/Routing/Api/Web/ClaimKey.php
Normal file
71
src/php/Routing/Api/Web/ClaimKey.php
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace GamesShop\Routing\Api\Web;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\Entities\Games\Key;
|
||||
use GamesShop\Entities\Games\KeyState;
|
||||
use GamesShop\Entities\GamesList;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use League\Route\Http\Exception\BadRequestException;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class ClaimKey
|
||||
{
|
||||
public function __construct(
|
||||
private readonly LoginHandler $loginHandler,
|
||||
private readonly EntityManager $entityManager,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
if (!$this->loginHandler->isLoggedIn()) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
|
||||
$user = $this->loginHandler->getCurrentUser();
|
||||
if (!$user->getPermission()->hasLevel(UserPermission::VIEWER)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
$body = $request->getParsedBody();
|
||||
if (!array_key_exists('keyid', $body)) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
$key = $this->entityManager->getRepository(Key::class)->find($body['keyid']);
|
||||
if (!$key instanceof Key) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
if (!$key->getList()->isPublic() && !$key->getList()->getClaimer()->contains($user)) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
if ($key->getState() !== KeyState::AVAILABLE) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
$key->setState(KeyState::CLAIMED);
|
||||
$key->setClaimedUser($user);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new JsonResponse([
|
||||
'key' => $key->getKey(),
|
||||
'providedBy' => $key->getList()->getOwner()->getName(),
|
||||
'from' => $key->getFromWhere() ?? 'unknown',
|
||||
'store' => [
|
||||
'name' => $key->getStore()->getName(),
|
||||
'icon' => $key->getStore()->getIcon(),
|
||||
'claimLink' => $key->getStore()->getClaimURL($key),
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
75
src/php/Routing/Api/Web/GetGameData.php
Normal file
75
src/php/Routing/Api/Web/GetGameData.php
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace GamesShop\Routing\Api\Web;
|
||||
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Entities\Games\Game;
|
||||
use GamesShop\Entities\Games\Key;
|
||||
use GamesShop\Entities\Games\KeyState;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use GamesShop\UserManager;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\NotFoundException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class GetGameData
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private readonly LoginHandler $loginHandler,
|
||||
private readonly EntityManager $entityManager,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request): ResponseInterface {
|
||||
|
||||
if (!$this->loginHandler->isLoggedIn()) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
|
||||
$user = $this->loginHandler->getCurrentUser();
|
||||
if (!$user->getPermission()->hasLevel(UserPermission::VIEWER)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
$game = $this->entityManager->getRepository(Game::class)
|
||||
->find($request->getQueryParams()['gameid']);
|
||||
if (!$game) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
$applicableLists = ContainerHandler::get(UserManager::class)
|
||||
->getApplicableGameLists($user);
|
||||
|
||||
$keyRepo = $this->entityManager->getRepository(Key::class);
|
||||
$keys = $keyRepo->matching(Criteria::create()
|
||||
->where(Criteria::expr()->in('list', $applicableLists->toArray()))
|
||||
->andWhere(Criteria::expr()->eq('game', $game))
|
||||
->andWhere(Criteria::expr()->eq('state', KeyState::AVAILABLE))
|
||||
);
|
||||
|
||||
return new JsonResponse([
|
||||
'name' => $game->getName(),
|
||||
'id' => $game->getId(),
|
||||
'keys' => $keys->map(fn (Key $key) => [
|
||||
'id' => $key->getId(),
|
||||
'store' => [
|
||||
'name' => $key->getStore()->getName(),
|
||||
'icon' => $key->getStore()->getIcon()
|
||||
],
|
||||
'fromWhere' => $key->getFromWhere(),
|
||||
'list' => [
|
||||
'owner' => $key->getList()->getOwner()->getName(),
|
||||
'name' => $key->getList()->getName(),
|
||||
],
|
||||
])->toArray(),
|
||||
]);
|
||||
}
|
||||
}
|
53
src/php/Routing/Api/Web/SetListPublic.php
Normal file
53
src/php/Routing/Api/Web/SetListPublic.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace GamesShop\Routing\Api\Web;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\Entities\GamesList;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use League\Route\Http\Exception\BadRequestException;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class SetListPublic
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private readonly LoginHandler $loginHandler,
|
||||
private readonly EntityManager $entityManager,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
if (!$this->loginHandler->isLoggedIn()) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
|
||||
$user = $this->loginHandler->getCurrentUser();
|
||||
if (!$user->getPermission()->hasLevel(UserPermission::PROVIDER)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
$body = $request->getParsedBody();
|
||||
if (!array_key_exists('listid', $body)) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
$list = $this->entityManager->getRepository(GamesList::class)->findOneBy(['owner' => $user, 'id' => $body['listid']]);
|
||||
if (!$list instanceof GamesList) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
$list->setIsPublic($body['publicState'] === '1');
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new Response();
|
||||
}
|
||||
}
|
|
@ -18,5 +18,9 @@ final class WebAPIRoutes
|
|||
$group->get('/share/search', SearchForUsers::class);
|
||||
$group->post('/share/add', AddUserToList::class);
|
||||
$group->post('/share/remove', RemoveUserFromList::class);
|
||||
$group->post('/share/setPublic', SetListPublic::class);
|
||||
|
||||
$group->get('/game', GetGameData::class);
|
||||
$group->post('/key/claim', ClaimKey::class);
|
||||
}
|
||||
}
|
41
src/php/UserManager.php
Normal file
41
src/php/UserManager.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace GamesShop;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\Entities\Account\User;
|
||||
use GamesShop\Entities\GamesList;
|
||||
|
||||
class UserManager
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private readonly EntityManager $entityManager
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function getApplicableGameLists(User $user): Collection {
|
||||
|
||||
$listRepo = $this->entityManager->getRepository(GamesList::class);
|
||||
|
||||
$allLists = $listRepo->findAll();
|
||||
$applicableLists = new ArrayCollection();
|
||||
foreach ($allLists as $list) {
|
||||
if ($list->isPublic()) {
|
||||
$applicableLists->add($list);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$list->getClaimer()->contains($user)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$applicableLists->add($list);
|
||||
}
|
||||
|
||||
return $applicableLists;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue