implemented user lists
This commit is contained in:
parent
3218253076
commit
c3e81ce6ea
16 changed files with 365 additions and 74 deletions
|
@ -7,7 +7,7 @@ use Doctrine\ORM\Mapping as ORM;
|
|||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'games')]
|
||||
final class Game
|
||||
class Game
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
|
|
|
@ -5,10 +5,12 @@ namespace GamesShop\Entities\Games;
|
|||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use GamesShop\Entities\Account\User;
|
||||
use GamesShop\Entities\GamesList;
|
||||
use JsonSerializable;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'keys')]
|
||||
final class Key
|
||||
final class Key implements JsonSerializable
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
|
@ -17,7 +19,7 @@ final class Key
|
|||
#[ORM\ManyToOne]
|
||||
private Game $game;
|
||||
#[ORM\ManyToOne]
|
||||
private User $contributedUser;
|
||||
private GamesList $list;
|
||||
#[ORM\Column]
|
||||
private string $key;
|
||||
#[ORM\Column(type: 'string', enumType: Store::class)]
|
||||
|
@ -29,10 +31,10 @@ final class Key
|
|||
#[ORM\Column(type: 'integer', enumType: KeyState::class)]
|
||||
private KeyState $state;
|
||||
|
||||
public function __construct(Game $game, User $contributedUser, string $key, Store $store, ?string $storeLink, ?string $fromWhere)
|
||||
public function __construct(Game $game, GamesList $list, string $key, Store $store, ?string $storeLink, ?string $fromWhere)
|
||||
{
|
||||
$this->game = $game;
|
||||
$this->contributedUser = $contributedUser;
|
||||
$this->list = $list;
|
||||
$this->key = $key;
|
||||
$this->store = $store;
|
||||
$this->storeLink = $storeLink;
|
||||
|
@ -79,4 +81,16 @@ final class Key
|
|||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'key' => $this->key,
|
||||
'store' => $this->store->value,
|
||||
'store_link' => $this->storeLink,
|
||||
'from_where' => $this->fromWhere,
|
||||
'state' => $this->state->value,
|
||||
];
|
||||
}
|
||||
}
|
62
src/php/Entities/GamesList.php
Normal file
62
src/php/Entities/GamesList.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use GamesShop\Entities\Account\User;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'games_lists')]
|
||||
final class GamesList
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
#[ORM\GeneratedValue]
|
||||
private int|null $id;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
private User $owner;
|
||||
|
||||
#[ORM\Column(nullable: true)]
|
||||
private string|null $name;
|
||||
|
||||
#[ORM\JoinTable(name: 'games_list_claimer')]
|
||||
#[ORM\JoinColumn(name: 'id', referencedColumnName: 'id')]
|
||||
#[ORM\ManyToMany(targetEntity: User::class)]
|
||||
private Collection $claimer;
|
||||
|
||||
/**
|
||||
* @param User $owner
|
||||
* @param string|null $name
|
||||
*/
|
||||
public function __construct(User $owner, ?string $name)
|
||||
{
|
||||
$this->owner = $owner;
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getOwner(): User
|
||||
{
|
||||
return $this->owner;
|
||||
}
|
||||
|
||||
public function getName(): ?string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getClaimer(): array
|
||||
{
|
||||
return $this->claimer;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@ use GamesShop\Entities\Games\Game;
|
|||
use GamesShop\Entities\Games\Key;
|
||||
use GamesShop\Entities\Games\KeyAttribute;
|
||||
use GamesShop\Entities\Games\Store;
|
||||
use GamesShop\Entities\GamesList;
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
|
||||
final class GameImporter
|
||||
|
@ -75,7 +76,7 @@ final class GameImporter
|
|||
/**
|
||||
* @param string[] $columnDefinitions
|
||||
*/
|
||||
public function import(string $path, array $columnDefinitions, User $contributedUser): array {
|
||||
public function import(string $path, array $columnDefinitions, GamesList $list): array {
|
||||
$spreadsheet = IOFactory::load($path);
|
||||
|
||||
$worksheet = $spreadsheet->getSheet(0);
|
||||
|
@ -129,7 +130,7 @@ final class GameImporter
|
|||
|
||||
$key = new Key(
|
||||
$game,
|
||||
$contributedUser,
|
||||
$list,
|
||||
$values['key'],
|
||||
$values['store'],
|
||||
$values['store_link'],
|
||||
|
|
|
@ -9,9 +9,11 @@ use Doctrine\ORM\EntityManager;
|
|||
use GamesShop\Entities\Account\User;
|
||||
use GamesShop\Entities\Games\Game;
|
||||
use GamesShop\Entities\Games\Key;
|
||||
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;
|
||||
|
@ -37,62 +39,40 @@ final class ProviderKeysEndpoint
|
|||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
$body = $request->getQueryParams();
|
||||
if (!array_key_exists('listid', $body)) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
$params = $request->getQueryParams();
|
||||
$draw = $params['draw'];
|
||||
$start = $params['start'];
|
||||
$length = $params['length'];
|
||||
$list = $this->entityManager->getRepository(GamesList::class)->findOneBy([ 'owner' => $user, 'id' => $body['listid'] ]);
|
||||
if (!$list instanceof GamesList) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
$searchValue = $params['search']['value'];
|
||||
$keys = $this->entityManager->getRepository(Key::class)->findBy(['list' => $list]);
|
||||
$gameToKeyArray = [];
|
||||
foreach ($keys as $key) {
|
||||
$game = $key->getGame();
|
||||
$id = $game->getId();
|
||||
|
||||
$repo = $this->entityManager->getRepository(Game::class);
|
||||
$total = $repo->count();
|
||||
if (!array_key_exists($id, $gameToKeyArray)) {
|
||||
$gameToKeyArray[$id] = [ $game, [] ];
|
||||
}
|
||||
|
||||
$criteria = Criteria::create();
|
||||
$criteria->where(Criteria::expr()->contains('name', $searchValue));
|
||||
$criteria->setFirstResult((int)$start);
|
||||
$criteria->setMaxResults((int)$length);
|
||||
$criteria->orderBy([ 'name' => Order::Ascending ]);
|
||||
$gameToKeyArray[$id][1][] = $key;
|
||||
}
|
||||
|
||||
$values = $repo->matching($criteria);
|
||||
$filteredCount = $values->count();
|
||||
$result = [];
|
||||
foreach ($gameToKeyArray as [$game, $keys]) {
|
||||
$result[] = [
|
||||
'gamePicture' => '',
|
||||
'name' => $game->getName(),
|
||||
'keysAmount' => count($keys),
|
||||
'igdbState' => 'not implermented',
|
||||
'keys' => $keys,
|
||||
];
|
||||
}
|
||||
|
||||
$entityManager = $this->entityManager;
|
||||
|
||||
return new JsonResponse([
|
||||
'draw' => $draw,
|
||||
'recordsTotal' => $total,
|
||||
'recordsFiltered' => $filteredCount,
|
||||
'data' =>
|
||||
array_filter($values->map(function (Game $game) use ($entityManager, $user) {
|
||||
$criteria = Criteria::create();
|
||||
$criteria->where(Criteria::expr()->eq('game', $game));
|
||||
$criteria->andWhere(Criteria::expr()->eq('contributedUser', $user));
|
||||
$criteria->orderBy(['state' => Order::Ascending]);
|
||||
|
||||
$keys = $entityManager->getRepository(Key::class)->matching($criteria);
|
||||
|
||||
$keysAmount = $keys->count();
|
||||
if ($keysAmount < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'gamePicture' => '',
|
||||
'name' => $game->getName(),
|
||||
'keysAmount' => $keysAmount,
|
||||
'igdbState' => 'yet to be implermented',
|
||||
'keys' => $keys->map(function (Key $key) use ($entityManager) {
|
||||
return [
|
||||
'keyState' => $key->getState()->value,
|
||||
'key' => $key->getKey(),
|
||||
'store' => $key->getStore()->value,
|
||||
'store_link' => $key->getStoreLink(),
|
||||
'from' => $key->getFromWhere(),
|
||||
];
|
||||
})->toArray()
|
||||
];
|
||||
})->toArray())
|
||||
]);
|
||||
return new JsonResponse([ 'data' => $result ]);
|
||||
}
|
||||
}
|
49
src/php/Routing/Api/Web/CreateKeyListRoute.php
Normal file
49
src/php/Routing/Api/Web/CreateKeyListRoute.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
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 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;
|
||||
|
||||
final class CreateKeyListRoute
|
||||
{
|
||||
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('name', $body)) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
$name = $body['name'];
|
||||
$list = new GamesList($user, $name);
|
||||
$this->entityManager->persist($list);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new Response();
|
||||
}
|
||||
}
|
|
@ -3,6 +3,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace GamesShop\Routing\Api\Web;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\Entities\GamesList;
|
||||
use GamesShop\Importer\GameImporter;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
|
@ -19,6 +21,7 @@ final class ImportKeysRoute
|
|||
public function __construct(
|
||||
private readonly LoginHandler $loginHandler,
|
||||
private readonly GameImporter $importer,
|
||||
private readonly EntityManager $entityManager,
|
||||
) { }
|
||||
|
||||
public function __invoke(ServerRequestInterface $request): ResponseInterface
|
||||
|
@ -32,6 +35,16 @@ final class ImportKeysRoute
|
|||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @var UploadedFile $file
|
||||
*/
|
||||
|
@ -45,7 +58,7 @@ final class ImportKeysRoute
|
|||
|
||||
$columnDefs = $request->getParsedBody()['columns'];
|
||||
|
||||
[$total, $imported] = $this->importer->import($fileName, $columnDefs, $user);
|
||||
[$total, $imported] = $this->importer->import($fileName, $columnDefs, $list);
|
||||
unlink($fileName);
|
||||
|
||||
return new JsonResponse([ 'success' => true, 'total' => $total, 'imported' => $imported ]);
|
||||
|
|
|
@ -12,5 +12,7 @@ final class WebAPIRoutes
|
|||
|
||||
$group->post('/keys/import/prepare', ImportKeysPrepareRoute::class);
|
||||
$group->post('/keys/import/perform', ImportKeysRoute::class);
|
||||
|
||||
$group->post('/keys/list/create', CreateKeyListRoute::class);
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ final class ErrorRoute
|
|||
public function renderErrorPage(int $errorCode): ResponseInterface {
|
||||
$pageContent = ContainerHandler::get(TemplateEngine::class)->renderErrorPage($errorCode);
|
||||
|
||||
$response = new Response;
|
||||
$response = new Response(status: $errorCode);
|
||||
$response->getBody()->write($pageContent);
|
||||
return $response;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\Entities\GamesList;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use GamesShop\Routing\Responses\TemplateResponse;
|
||||
|
@ -14,7 +16,8 @@ use Psr\Http\Message\ServerRequestInterface;
|
|||
final class KeysRoute
|
||||
{
|
||||
public function __construct(
|
||||
private readonly LoginHandler $loginHandler
|
||||
private readonly LoginHandler $loginHandler,
|
||||
private readonly EntityManager $entityManager
|
||||
)
|
||||
{
|
||||
}
|
||||
|
@ -30,8 +33,9 @@ final class KeysRoute
|
|||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
|
||||
return new TemplateResponse('key-manager');
|
||||
$entityManager = $this->entityManager->getRepository(GamesList::class);
|
||||
$lists = $entityManager->findBy([ 'owner' => $user ]);
|
||||
return new TemplateResponse('key-manager', [ 'usersLists' => $lists ]);
|
||||
}
|
||||
|
||||
public static function applyRoutes(\League\Route\Router $router): void
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue