I rightly do not know what this all is
This commit is contained in:
parent
af6b2b752e
commit
287c1f67c5
78 changed files with 3484 additions and 3365 deletions
|
@ -1,79 +1,79 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Api;
|
||||
|
||||
use Curl\Curl;
|
||||
use Exception;
|
||||
use GamesShop\Environment\EnvironmentHandler;
|
||||
use GamesShop\Errors\ExtendedException;
|
||||
|
||||
final class DiscordAPI
|
||||
{
|
||||
const string OAUTH_TOKEN_URL = "https://discord.com/api/oauth2/token";
|
||||
const string USER_ME_URL = 'https://discord.com/api/users/@me';
|
||||
|
||||
public function __construct(
|
||||
private readonly EnvironmentHandler $env
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{id: string, global_name: string, avatar: string, discriminator: int}
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getUserFromCode(string $code, string $redirectUri): array {
|
||||
$discordEnv = $this->env->getDiscordEnvironment();
|
||||
|
||||
$curl = new Curl();
|
||||
$curl->setHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
$curl->setBasicAuthentication($discordEnv->clientId, $discordEnv->clientSecret);
|
||||
|
||||
$data =[
|
||||
'grant_type' => 'authorization_code',
|
||||
'code' => $code,
|
||||
'redirect_uri' => $redirectUri
|
||||
];
|
||||
$curl->post(self::OAUTH_TOKEN_URL, $data);
|
||||
|
||||
if ($curl->error) {
|
||||
$curl->diagnose();
|
||||
|
||||
throw new ExtendedException($curl->errorMessage, [ 'response' => $curl->response, 'data' => $data ]);
|
||||
}
|
||||
|
||||
$accessToken = $curl->response->access_token;
|
||||
$tokenType = $curl->response->token_type;
|
||||
|
||||
$curl = new Curl();
|
||||
$curl->setHeader("authorization", "$tokenType $accessToken");
|
||||
$curl->get(self::USER_ME_URL);
|
||||
|
||||
if ($curl->error) {
|
||||
$curl->diagnose();
|
||||
|
||||
throw new ExtendedException($curl->errorMessage, [ 'response' => $curl->response, ]);
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $curl->response->id,
|
||||
'global_name' => $curl->response->global_name,
|
||||
'avatar' => $curl->response->avatar,
|
||||
'discriminator' => (int) $curl->response->discriminator
|
||||
];
|
||||
}
|
||||
|
||||
public function getAvatarURL(string $userId, string|int $avatarHash) {
|
||||
if (is_int($avatarHash)) {
|
||||
return "https://cdn.discordapp.com/embed/avatars/{$avatarHash}.png";
|
||||
}
|
||||
|
||||
$extension = 'png';
|
||||
if (str_starts_with($avatarHash, 'a_')) {
|
||||
$extension = 'gif';
|
||||
}
|
||||
|
||||
return "https://cdn.discordapp.com/avatars/{$userId}/{$avatarHash}.{$extension}";
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Api;
|
||||
|
||||
use Curl\Curl;
|
||||
use Exception;
|
||||
use GamesShop\Environment\EnvironmentHandler;
|
||||
use GamesShop\Errors\ExtendedException;
|
||||
|
||||
final class DiscordAPI
|
||||
{
|
||||
const string OAUTH_TOKEN_URL = "https://discord.com/api/oauth2/token";
|
||||
const string USER_ME_URL = 'https://discord.com/api/users/@me';
|
||||
|
||||
public function __construct(
|
||||
private readonly EnvironmentHandler $env
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{id: string, global_name: string, avatar: string, discriminator: int}
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getUserFromCode(string $code, string $redirectUri): array {
|
||||
$discordEnv = $this->env->getDiscordEnvironment();
|
||||
|
||||
$curl = new Curl();
|
||||
$curl->setHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
$curl->setBasicAuthentication($discordEnv->clientId, $discordEnv->clientSecret);
|
||||
|
||||
$data =[
|
||||
'grant_type' => 'authorization_code',
|
||||
'code' => $code,
|
||||
'redirect_uri' => $redirectUri
|
||||
];
|
||||
$curl->post(self::OAUTH_TOKEN_URL, $data);
|
||||
|
||||
if ($curl->error) {
|
||||
$curl->diagnose();
|
||||
|
||||
throw new ExtendedException($curl->errorMessage, [ 'response' => $curl->response, 'data' => $data ]);
|
||||
}
|
||||
|
||||
$accessToken = $curl->response->access_token;
|
||||
$tokenType = $curl->response->token_type;
|
||||
|
||||
$curl = new Curl();
|
||||
$curl->setHeader("authorization", "$tokenType $accessToken");
|
||||
$curl->get(self::USER_ME_URL);
|
||||
|
||||
if ($curl->error) {
|
||||
$curl->diagnose();
|
||||
|
||||
throw new ExtendedException($curl->errorMessage, [ 'response' => $curl->response, ]);
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $curl->response->id,
|
||||
'global_name' => $curl->response->global_name,
|
||||
'avatar' => $curl->response->avatar,
|
||||
'discriminator' => (int) $curl->response->discriminator
|
||||
];
|
||||
}
|
||||
|
||||
public function getAvatarURL(string $userId, string|int $avatarHash) {
|
||||
if (is_int($avatarHash)) {
|
||||
return "https://cdn.discordapp.com/embed/avatars/{$avatarHash}.png";
|
||||
}
|
||||
|
||||
$extension = 'png';
|
||||
if (str_starts_with($avatarHash, 'a_')) {
|
||||
$extension = 'gif';
|
||||
}
|
||||
|
||||
return "https://cdn.discordapp.com/avatars/{$userId}/{$avatarHash}.{$extension}";
|
||||
}
|
||||
}
|
|
@ -1,39 +1,39 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop;
|
||||
|
||||
use League\Container\Container;
|
||||
use League\Container\ReflectionContainer;
|
||||
|
||||
final class ContainerHandler
|
||||
{
|
||||
private static Container|null $instance = null;
|
||||
|
||||
public static function getInstance(): Container
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::createInstance();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template RequestedType
|
||||
*
|
||||
* @param class-string<RequestedType>|string $id
|
||||
*
|
||||
* @return RequestedType|mixed
|
||||
*/
|
||||
public static function get(string $id) {
|
||||
return self::getInstance()->get($id);
|
||||
}
|
||||
|
||||
private static function createInstance()
|
||||
{
|
||||
self::$instance = new Container();
|
||||
$reflectionContainer = new ReflectionContainer(true);
|
||||
self::$instance->delegate($reflectionContainer);
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop;
|
||||
|
||||
use League\Container\Container;
|
||||
use League\Container\ReflectionContainer;
|
||||
|
||||
final class ContainerHandler
|
||||
{
|
||||
private static Container|null $instance = null;
|
||||
|
||||
public static function getInstance(): Container
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::createInstance();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template RequestedType
|
||||
*
|
||||
* @param class-string<RequestedType>|string $id
|
||||
*
|
||||
* @return RequestedType|mixed
|
||||
*/
|
||||
public static function get(string $id) {
|
||||
return self::getInstance()->get($id);
|
||||
}
|
||||
|
||||
private static function createInstance()
|
||||
{
|
||||
self::$instance = new Container();
|
||||
$reflectionContainer = new ReflectionContainer(true);
|
||||
self::$instance->delegate($reflectionContainer);
|
||||
}
|
||||
}
|
|
@ -1,35 +1,35 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\ORMSetup;
|
||||
use GamesShop\Environment\EnvironmentHandler;
|
||||
|
||||
final class DoctrineManager
|
||||
{
|
||||
public function setup() {
|
||||
$container = ContainerHandler::getInstance();
|
||||
|
||||
$environmentHandler = $container->get(EnvironmentHandler::class);
|
||||
|
||||
$config = ORMSetup::createAttributeMetadataConfiguration(
|
||||
paths: [ Paths::PHP_SOURCE_PATH . '/Entities' ],
|
||||
isDevMode: !$environmentHandler->isProduction()
|
||||
);
|
||||
|
||||
$dbEnvironment = $environmentHandler->getDatabaseEnvironment();
|
||||
$connection = DriverManager::getConnection($dbEnvironment->getDoctrineConfig());
|
||||
|
||||
$entityManager = new EntityManager($connection, $config);
|
||||
|
||||
$container->addShared(EntityManager::class, $entityManager);
|
||||
$container->addShared(EntityManagerInterface::class, $entityManager);
|
||||
$container->addShared(Connection::class, $connection);
|
||||
}
|
||||
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\ORMSetup;
|
||||
use GamesShop\Environment\EnvironmentHandler;
|
||||
|
||||
final class DoctrineManager
|
||||
{
|
||||
public function setup() {
|
||||
$container = ContainerHandler::getInstance();
|
||||
|
||||
$environmentHandler = $container->get(EnvironmentHandler::class);
|
||||
|
||||
$config = ORMSetup::createAttributeMetadataConfiguration(
|
||||
paths: [ Paths::PHP_SOURCE_PATH . '/Entities' ],
|
||||
isDevMode: !$environmentHandler->isProduction()
|
||||
);
|
||||
|
||||
$dbEnvironment = $environmentHandler->getDatabaseEnvironment();
|
||||
$connection = DriverManager::getConnection($dbEnvironment->getDoctrineConfig());
|
||||
|
||||
$entityManager = new EntityManager($connection, $config);
|
||||
|
||||
$container->addShared(EntityManager::class, $entityManager);
|
||||
$container->addShared(EntityManagerInterface::class, $entityManager);
|
||||
$container->addShared(Connection::class, $connection);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,85 +1,85 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities\Account;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use GamesShop\Login\LoginMethod;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
use Symfony\Component\Uid\UuidV4;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: "users")]
|
||||
final class User
|
||||
{
|
||||
|
||||
#[ORM\Id()]
|
||||
#[ORM\Column]
|
||||
#[ORM\GeneratedValue]
|
||||
private int|null $id = null;
|
||||
#[ORM\Column(type: 'integer', enumType: LoginMethod::class)]
|
||||
private LoginMethod $loginMethod;
|
||||
#[ORM\Column]
|
||||
private string|null $foreignLoginId = null;
|
||||
#[ORM\Column]
|
||||
private string $name;
|
||||
#[ORM\Column]
|
||||
private string $profilePictureUrl;
|
||||
#[ORM\Column]
|
||||
private UserPermission $permission;
|
||||
|
||||
public function __construct(LoginMethod $loginMethod, ?string $foreignLoginId, string $name, string $profilePictureUrl, UserPermission $permission)
|
||||
{
|
||||
$this->loginMethod = $loginMethod;
|
||||
$this->foreignLoginId = $foreignLoginId;
|
||||
$this->name = $name;
|
||||
$this->profilePictureUrl = $profilePictureUrl;
|
||||
$this->permission = $permission;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getLoginMethod(): LoginMethod
|
||||
{
|
||||
return $this->loginMethod;
|
||||
}
|
||||
|
||||
public function getForeignLoginId(): ?string
|
||||
{
|
||||
return $this->foreignLoginId;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getProfilePictureUrl(): string
|
||||
{
|
||||
return $this->profilePictureUrl;
|
||||
}
|
||||
|
||||
public function getPermission(): UserPermission
|
||||
{
|
||||
return $this->permission;
|
||||
}
|
||||
|
||||
public function setName(string $name): void
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function setProfilePictureUrl(string $profilePictureUrl): void
|
||||
{
|
||||
$this->profilePictureUrl = $profilePictureUrl;
|
||||
}
|
||||
|
||||
public function setPermission(UserPermission $permission): void
|
||||
{
|
||||
$this->permission = $permission;
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities\Account;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use GamesShop\Login\LoginMethod;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
use Symfony\Component\Uid\UuidV4;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: "users")]
|
||||
final class User
|
||||
{
|
||||
|
||||
#[ORM\Id()]
|
||||
#[ORM\Column]
|
||||
#[ORM\GeneratedValue]
|
||||
private int|null $id = null;
|
||||
#[ORM\Column(type: 'integer', enumType: LoginMethod::class)]
|
||||
private LoginMethod $loginMethod;
|
||||
#[ORM\Column]
|
||||
private string|null $foreignLoginId = null;
|
||||
#[ORM\Column]
|
||||
private string $name;
|
||||
#[ORM\Column]
|
||||
private string $profilePictureUrl;
|
||||
#[ORM\Column]
|
||||
private UserPermission $permission;
|
||||
|
||||
public function __construct(LoginMethod $loginMethod, ?string $foreignLoginId, string $name, string $profilePictureUrl, UserPermission $permission)
|
||||
{
|
||||
$this->loginMethod = $loginMethod;
|
||||
$this->foreignLoginId = $foreignLoginId;
|
||||
$this->name = $name;
|
||||
$this->profilePictureUrl = $profilePictureUrl;
|
||||
$this->permission = $permission;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getLoginMethod(): LoginMethod
|
||||
{
|
||||
return $this->loginMethod;
|
||||
}
|
||||
|
||||
public function getForeignLoginId(): ?string
|
||||
{
|
||||
return $this->foreignLoginId;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getProfilePictureUrl(): string
|
||||
{
|
||||
return $this->profilePictureUrl;
|
||||
}
|
||||
|
||||
public function getPermission(): UserPermission
|
||||
{
|
||||
return $this->permission;
|
||||
}
|
||||
|
||||
public function setName(string $name): void
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function setProfilePictureUrl(string $profilePictureUrl): void
|
||||
{
|
||||
$this->profilePictureUrl = $profilePictureUrl;
|
||||
}
|
||||
|
||||
public function setPermission(UserPermission $permission): void
|
||||
{
|
||||
$this->permission = $permission;
|
||||
}
|
||||
}
|
|
@ -1,36 +1,36 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities\Games;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'games')]
|
||||
class Game
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
#[ORM\GeneratedValue]
|
||||
private int|null $id;
|
||||
#[ORM\Column]
|
||||
private string $name;
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities\Games;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'games')]
|
||||
class Game
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
#[ORM\GeneratedValue]
|
||||
private int|null $id;
|
||||
#[ORM\Column]
|
||||
private string $name;
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
|
@ -1,96 +1,96 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
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 implements JsonSerializable
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
#[ORM\GeneratedValue]
|
||||
private int|null $id;
|
||||
#[ORM\ManyToOne]
|
||||
private Game $game;
|
||||
#[ORM\ManyToOne]
|
||||
private GamesList $list;
|
||||
#[ORM\Column]
|
||||
private string $key;
|
||||
#[ORM\Column(type: 'string', enumType: Store::class)]
|
||||
private Store $store;
|
||||
#[ORM\Column(nullable: true)]
|
||||
private string|null $storeLink;
|
||||
#[ORM\Column]
|
||||
private string|null $fromWhere;
|
||||
#[ORM\Column(type: 'integer', enumType: KeyState::class)]
|
||||
private KeyState $state;
|
||||
|
||||
public function __construct(Game $game, GamesList $list, string $key, Store $store, ?string $storeLink, ?string $fromWhere)
|
||||
{
|
||||
$this->game = $game;
|
||||
$this->list = $list;
|
||||
$this->key = $key;
|
||||
$this->store = $store;
|
||||
$this->storeLink = $storeLink;
|
||||
$this->fromWhere = $fromWhere;
|
||||
$this->state = KeyState::AVAILABLE;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getGame(): Game
|
||||
{
|
||||
return $this->game;
|
||||
}
|
||||
|
||||
public function getContributedUser(): User
|
||||
{
|
||||
return $this->contributedUser;
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function getStore(): Store
|
||||
{
|
||||
return $this->store;
|
||||
}
|
||||
|
||||
public function getStoreLink(): ?string
|
||||
{
|
||||
return $this->storeLink;
|
||||
}
|
||||
|
||||
public function getFromWhere(): ?string
|
||||
{
|
||||
return $this->fromWhere;
|
||||
}
|
||||
|
||||
public function getState(): KeyState
|
||||
{
|
||||
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,
|
||||
];
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
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 implements JsonSerializable
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
#[ORM\GeneratedValue]
|
||||
private int|null $id;
|
||||
#[ORM\ManyToOne]
|
||||
private Game $game;
|
||||
#[ORM\ManyToOne]
|
||||
private GamesList $list;
|
||||
#[ORM\Column]
|
||||
private string $key;
|
||||
#[ORM\Column(type: 'string', enumType: Store::class)]
|
||||
private Store $store;
|
||||
#[ORM\Column(nullable: true)]
|
||||
private string|null $storeLink;
|
||||
#[ORM\Column]
|
||||
private string|null $fromWhere;
|
||||
#[ORM\Column(type: 'integer', enumType: KeyState::class)]
|
||||
private KeyState $state;
|
||||
|
||||
public function __construct(Game $game, GamesList $list, string $key, Store $store, ?string $storeLink, ?string $fromWhere)
|
||||
{
|
||||
$this->game = $game;
|
||||
$this->list = $list;
|
||||
$this->key = $key;
|
||||
$this->store = $store;
|
||||
$this->storeLink = $storeLink;
|
||||
$this->fromWhere = $fromWhere;
|
||||
$this->state = KeyState::AVAILABLE;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getGame(): Game
|
||||
{
|
||||
return $this->game;
|
||||
}
|
||||
|
||||
public function getContributedUser(): User
|
||||
{
|
||||
return $this->contributedUser;
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function getStore(): Store
|
||||
{
|
||||
return $this->store;
|
||||
}
|
||||
|
||||
public function getStoreLink(): ?string
|
||||
{
|
||||
return $this->storeLink;
|
||||
}
|
||||
|
||||
public function getFromWhere(): ?string
|
||||
{
|
||||
return $this->fromWhere;
|
||||
}
|
||||
|
||||
public function getState(): KeyState
|
||||
{
|
||||
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,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,22 +1,22 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities\Games;
|
||||
|
||||
enum KeyAttribute: string
|
||||
{
|
||||
case NONE = 'none';
|
||||
case GAME_NAME = "game_name";
|
||||
case KEY = "key";
|
||||
case STORE = 'store';
|
||||
case FROM = 'from';
|
||||
|
||||
public static function casesAsAssociative(): array {
|
||||
$result = [];
|
||||
foreach (self::cases() as $case) {
|
||||
$result[$case->name] = $case->value;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities\Games;
|
||||
|
||||
enum KeyAttribute: string
|
||||
{
|
||||
case NONE = 'none';
|
||||
case GAME_NAME = "game_name";
|
||||
case KEY = "key";
|
||||
case STORE = 'store';
|
||||
case FROM = 'from';
|
||||
|
||||
public static function casesAsAssociative(): array {
|
||||
$result = [];
|
||||
foreach (self::cases() as $case) {
|
||||
$result[$case->name] = $case->value;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities\Games;
|
||||
|
||||
enum KeyState: int
|
||||
{
|
||||
case AVAILABLE = 1;
|
||||
case UNKNOWN = 0;
|
||||
case RESERVED_FOR_GIFT = -1;
|
||||
case CLAIMED = -10;
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities\Games;
|
||||
|
||||
enum KeyState: int
|
||||
{
|
||||
case AVAILABLE = 1;
|
||||
case UNKNOWN = 0;
|
||||
case RESERVED_FOR_GIFT = -1;
|
||||
case CLAIMED = -10;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities\Games;
|
||||
|
||||
enum Store: string
|
||||
{
|
||||
case STEAM = 'steam';
|
||||
case GOG = 'gog';
|
||||
case EPICGAMES = 'epicgames';
|
||||
case ORIGIN = 'origin';
|
||||
case UPLAY = 'uplay';
|
||||
case BATTLENET = 'battlenet';
|
||||
case EXTERNAL = 'external';
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities\Games;
|
||||
|
||||
enum Store: string
|
||||
{
|
||||
case STEAM = 'steam';
|
||||
case GOG = 'gog';
|
||||
case EPICGAMES = 'epicgames';
|
||||
case ORIGIN = 'origin';
|
||||
case UPLAY = 'uplay';
|
||||
case BATTLENET = 'battlenet';
|
||||
case EXTERNAL = 'external';
|
||||
}
|
||||
|
|
|
@ -1,62 +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;
|
||||
}
|
||||
|
||||
|
||||
<?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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,34 +1,34 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'attributes')]
|
||||
final class SystemAttribute
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column]
|
||||
private string $name;
|
||||
|
||||
#[ORM\Column]
|
||||
private string $value;
|
||||
|
||||
public function __construct(string $name, string $value)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getValue(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Entities;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'attributes')]
|
||||
final class SystemAttribute
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column]
|
||||
private string $name;
|
||||
|
||||
#[ORM\Column]
|
||||
private string $value;
|
||||
|
||||
public function __construct(string $name, string $value)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getValue(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
|
@ -1,21 +1,21 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Environment;
|
||||
|
||||
final readonly class DatabaseEnvironment
|
||||
{
|
||||
public function __construct(
|
||||
public string $driver,
|
||||
public string $path
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function getDoctrineConfig() {
|
||||
return [
|
||||
'driver' => $this->driver,
|
||||
'path' => $this->path
|
||||
];
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Environment;
|
||||
|
||||
final readonly class DatabaseEnvironment
|
||||
{
|
||||
public function __construct(
|
||||
public string $driver,
|
||||
public string $path
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function getDoctrineConfig() {
|
||||
return [
|
||||
'driver' => $this->driver,
|
||||
'path' => $this->path
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Environment;
|
||||
|
||||
final readonly class DiscordEnvironment
|
||||
{
|
||||
public function __construct(
|
||||
public string $clientId,
|
||||
public string $clientSecret,
|
||||
public string $loginUrl,
|
||||
) {}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Environment;
|
||||
|
||||
final readonly class DiscordEnvironment
|
||||
{
|
||||
public function __construct(
|
||||
public string $clientId,
|
||||
public string $clientSecret,
|
||||
public string $loginUrl,
|
||||
) {}
|
||||
}
|
|
@ -1,40 +1,40 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Environment;
|
||||
|
||||
use DotenvVault\DotenvVault;
|
||||
use GamesShop\Paths;
|
||||
|
||||
final class EnvironmentHandler
|
||||
{
|
||||
private const string ENVIRONMENT_PATH = Paths::ROOT_PATH . '/config';
|
||||
|
||||
public function load() {
|
||||
$dotEnv = DotenvVault::createImmutable(
|
||||
self::ENVIRONMENT_PATH
|
||||
);
|
||||
|
||||
$dotEnv->safeLoad();
|
||||
}
|
||||
|
||||
public function getDiscordEnvironment(): DiscordEnvironment {
|
||||
return new DiscordEnvironment(
|
||||
$_SERVER['DISCORD_CLIENT_ID'],
|
||||
$_SERVER['DISCORD_CLIENT_SECRET'],
|
||||
$_SERVER['DISCORD_CLIENT_LOGIN_URI'],
|
||||
);
|
||||
}
|
||||
|
||||
public function getDatabaseEnvironment(): DatabaseEnvironment
|
||||
{
|
||||
return new DatabaseEnvironment(
|
||||
$_SERVER['DB_DRIVER'],
|
||||
$_SERVER['DB_PATH']
|
||||
);
|
||||
}
|
||||
|
||||
public function isProduction(): bool {
|
||||
return $_SERVER['PRODUCTION'] === 'true';
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Environment;
|
||||
|
||||
use DotenvVault\DotenvVault;
|
||||
use GamesShop\Paths;
|
||||
|
||||
final class EnvironmentHandler
|
||||
{
|
||||
private const string ENVIRONMENT_PATH = Paths::ROOT_PATH . '/config';
|
||||
|
||||
public function load() {
|
||||
$dotEnv = DotenvVault::createImmutable(
|
||||
self::ENVIRONMENT_PATH
|
||||
);
|
||||
|
||||
$dotEnv->safeLoad();
|
||||
}
|
||||
|
||||
public function getDiscordEnvironment(): DiscordEnvironment {
|
||||
return new DiscordEnvironment(
|
||||
$_SERVER['DISCORD_CLIENT_ID'],
|
||||
$_SERVER['DISCORD_CLIENT_SECRET'],
|
||||
$_SERVER['DISCORD_CLIENT_LOGIN_URI'],
|
||||
);
|
||||
}
|
||||
|
||||
public function getDatabaseEnvironment(): DatabaseEnvironment
|
||||
{
|
||||
return new DatabaseEnvironment(
|
||||
$_SERVER['DB_DRIVER'],
|
||||
$_SERVER['DB_PATH']
|
||||
);
|
||||
}
|
||||
|
||||
public function isProduction(): bool {
|
||||
return $_SERVER['PRODUCTION'] === 'true';
|
||||
}
|
||||
}
|
|
@ -1,26 +1,26 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace GamesShop\Errors;
|
||||
|
||||
use Exception;
|
||||
use GamesShop\ContainerHandler;
|
||||
use Whoops\Handler\HandlerInterface;
|
||||
use Whoops\Handler\PrettyPageHandler;
|
||||
|
||||
|
||||
|
||||
final class ExtendedException extends Exception
|
||||
{
|
||||
public function __construct(string $message = "", array $additionals = [], int $code = 0, ?Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
|
||||
$handler = ContainerHandler::get(HandlerInterface::class);
|
||||
|
||||
if (!($handler instanceof PrettyPageHandler)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$handler->addDataTable("Additional Info", $additionals);
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace GamesShop\Errors;
|
||||
|
||||
use Exception;
|
||||
use GamesShop\ContainerHandler;
|
||||
use Whoops\Handler\HandlerInterface;
|
||||
use Whoops\Handler\PrettyPageHandler;
|
||||
|
||||
|
||||
|
||||
final class ExtendedException extends Exception
|
||||
{
|
||||
public function __construct(string $message = "", array $additionals = [], int $code = 0, ?Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
|
||||
$handler = ContainerHandler::get(HandlerInterface::class);
|
||||
|
||||
if (!($handler instanceof PrettyPageHandler)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$handler->addDataTable("Additional Info", $additionals);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use Whoops\Run;
|
||||
|
||||
final class WhoopsHandler
|
||||
{
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use Whoops\Run;
|
||||
|
||||
final class WhoopsHandler
|
||||
{
|
||||
}
|
|
@ -1,166 +1,166 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Importer;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Exception;
|
||||
use GamesShop\Entities\Account\User;
|
||||
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
|
||||
{
|
||||
private const HEADER_ROW_INDEX = 1;
|
||||
|
||||
private const STORE_ADDITIONAL_CASES = [
|
||||
'epic' => Store::EPICGAMES,
|
||||
'ea' => Store::ORIGIN,
|
||||
'eaplay' => Store::ORIGIN,
|
||||
'ubisoft' => Store::UPLAY,
|
||||
'activision' => Store::BATTLENET
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
) { }
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return ImportColumnInterpretation[]
|
||||
*/
|
||||
public function interpret(string $path): array {
|
||||
$spreadsheet = IOFactory::load($path);
|
||||
|
||||
$worksheet = $spreadsheet->getSheet(0);
|
||||
$result = [];
|
||||
foreach ($worksheet->getColumnIterator() as $column) {
|
||||
$columnIndex = $column->getColumnIndex();
|
||||
|
||||
$value = $worksheet->getCell(sprintf('%s%d', $columnIndex, self::HEADER_ROW_INDEX))->getValueString();
|
||||
|
||||
if (empty(trim($value))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$guessedAttribute = $this->guessAttribute($value);
|
||||
$result[] = new ImportColumnInterpretation(
|
||||
$columnIndex,
|
||||
$value,
|
||||
$guessedAttribute
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function guessAttribute(string $value): KeyAttribute|null {
|
||||
$value = trim($value);
|
||||
$value = strtolower($value);
|
||||
$value = str_replace(' ', '_', $value);
|
||||
|
||||
$attribute = match($value) {
|
||||
'key' => KeyAttribute::KEY,
|
||||
'name', 'game_name', 'game' => KeyAttribute::GAME_NAME,
|
||||
'from' => KeyAttribute::FROM,
|
||||
'store', 'for' => KeyAttribute::STORE,
|
||||
default => null
|
||||
};
|
||||
|
||||
return $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $columnDefinitions
|
||||
*/
|
||||
public function import(string $path, array $columnDefinitions, GamesList $list): array {
|
||||
$spreadsheet = IOFactory::load($path);
|
||||
|
||||
$worksheet = $spreadsheet->getSheet(0);
|
||||
|
||||
$totalRows = 0;
|
||||
$addedAmount = 0;
|
||||
|
||||
foreach ($worksheet->getRowIterator(self::HEADER_ROW_INDEX + 1) as $row) {
|
||||
$totalRows++;
|
||||
$values = [
|
||||
'name' => null,
|
||||
'key' => null,
|
||||
'from' => null,
|
||||
'store' => null,
|
||||
'store_link' => null
|
||||
];
|
||||
|
||||
foreach ($columnDefinitions as $columnIndex => $attribute) {
|
||||
$value = $worksheet->getCell(sprintf('%s%d', $columnIndex, $row->getRowIndex()))->getValueString();
|
||||
|
||||
switch(KeyAttribute::from($attribute)) {
|
||||
case KeyAttribute::NONE:
|
||||
break;
|
||||
case KeyAttribute::GAME_NAME:
|
||||
$values['name'] = $value;
|
||||
break;
|
||||
case KeyAttribute::KEY:
|
||||
$values['key'] = $value;
|
||||
break;
|
||||
case KeyAttribute::FROM:
|
||||
$values['from'] = $value;
|
||||
break;
|
||||
case KeyAttribute::STORE:
|
||||
$store = $this->interpretStore($value);
|
||||
$values['store'] = $store;
|
||||
if ($store === Store::EXTERNAL) {
|
||||
$values['store_link'] = $value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($values['key'] === null || $values['name'] === null || $values['store'] === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$game = $this->entityManager->getRepository(Game::class)->findOneBy([ 'name' => $values['name'] ]);
|
||||
if ($game === null) {
|
||||
$game = new Game($values['name']);
|
||||
}
|
||||
|
||||
$key = new Key(
|
||||
$game,
|
||||
$list,
|
||||
$values['key'],
|
||||
$values['store'],
|
||||
$values['store_link'],
|
||||
$values['from'],
|
||||
);
|
||||
|
||||
$this->entityManager->persist($game);
|
||||
$this->entityManager->persist($key);
|
||||
$addedAmount++;
|
||||
}
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
return [$totalRows, $addedAmount];
|
||||
}
|
||||
|
||||
private function interpretStore(string $storeString): Store {
|
||||
$storeString = trim($storeString);
|
||||
$storeString = strtolower($storeString);
|
||||
$storeString = str_replace(' ', '', $storeString);
|
||||
|
||||
$triedConversion = Store::tryFrom($storeString);
|
||||
if ($triedConversion !== null) {
|
||||
return $triedConversion;
|
||||
}
|
||||
|
||||
if (array_key_exists($storeString, self::STORE_ADDITIONAL_CASES)) {
|
||||
return self::STORE_ADDITIONAL_CASES[$storeString];
|
||||
}
|
||||
|
||||
return Store::EXTERNAL;
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Importer;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Exception;
|
||||
use GamesShop\Entities\Account\User;
|
||||
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
|
||||
{
|
||||
private const HEADER_ROW_INDEX = 1;
|
||||
|
||||
private const STORE_ADDITIONAL_CASES = [
|
||||
'epic' => Store::EPICGAMES,
|
||||
'ea' => Store::ORIGIN,
|
||||
'eaplay' => Store::ORIGIN,
|
||||
'ubisoft' => Store::UPLAY,
|
||||
'activision' => Store::BATTLENET
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
) { }
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return ImportColumnInterpretation[]
|
||||
*/
|
||||
public function interpret(string $path): array {
|
||||
$spreadsheet = IOFactory::load($path);
|
||||
|
||||
$worksheet = $spreadsheet->getSheet(0);
|
||||
$result = [];
|
||||
foreach ($worksheet->getColumnIterator() as $column) {
|
||||
$columnIndex = $column->getColumnIndex();
|
||||
|
||||
$value = $worksheet->getCell(sprintf('%s%d', $columnIndex, self::HEADER_ROW_INDEX))->getValueString();
|
||||
|
||||
if (empty(trim($value))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$guessedAttribute = $this->guessAttribute($value);
|
||||
$result[] = new ImportColumnInterpretation(
|
||||
$columnIndex,
|
||||
$value,
|
||||
$guessedAttribute
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function guessAttribute(string $value): KeyAttribute|null {
|
||||
$value = trim($value);
|
||||
$value = strtolower($value);
|
||||
$value = str_replace(' ', '_', $value);
|
||||
|
||||
$attribute = match($value) {
|
||||
'key' => KeyAttribute::KEY,
|
||||
'name', 'game_name', 'game' => KeyAttribute::GAME_NAME,
|
||||
'from' => KeyAttribute::FROM,
|
||||
'store', 'for' => KeyAttribute::STORE,
|
||||
default => null
|
||||
};
|
||||
|
||||
return $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $columnDefinitions
|
||||
*/
|
||||
public function import(string $path, array $columnDefinitions, GamesList $list): array {
|
||||
$spreadsheet = IOFactory::load($path);
|
||||
|
||||
$worksheet = $spreadsheet->getSheet(0);
|
||||
|
||||
$totalRows = 0;
|
||||
$addedAmount = 0;
|
||||
|
||||
foreach ($worksheet->getRowIterator(self::HEADER_ROW_INDEX + 1) as $row) {
|
||||
$totalRows++;
|
||||
$values = [
|
||||
'name' => null,
|
||||
'key' => null,
|
||||
'from' => null,
|
||||
'store' => null,
|
||||
'store_link' => null
|
||||
];
|
||||
|
||||
foreach ($columnDefinitions as $columnIndex => $attribute) {
|
||||
$value = $worksheet->getCell(sprintf('%s%d', $columnIndex, $row->getRowIndex()))->getValueString();
|
||||
|
||||
switch(KeyAttribute::from($attribute)) {
|
||||
case KeyAttribute::NONE:
|
||||
break;
|
||||
case KeyAttribute::GAME_NAME:
|
||||
$values['name'] = $value;
|
||||
break;
|
||||
case KeyAttribute::KEY:
|
||||
$values['key'] = $value;
|
||||
break;
|
||||
case KeyAttribute::FROM:
|
||||
$values['from'] = $value;
|
||||
break;
|
||||
case KeyAttribute::STORE:
|
||||
$store = $this->interpretStore($value);
|
||||
$values['store'] = $store;
|
||||
if ($store === Store::EXTERNAL) {
|
||||
$values['store_link'] = $value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($values['key'] === null || $values['name'] === null || $values['store'] === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$game = $this->entityManager->getRepository(Game::class)->findOneBy([ 'name' => $values['name'] ]);
|
||||
if ($game === null) {
|
||||
$game = new Game($values['name']);
|
||||
}
|
||||
|
||||
$key = new Key(
|
||||
$game,
|
||||
$list,
|
||||
$values['key'],
|
||||
$values['store'],
|
||||
$values['store_link'],
|
||||
$values['from'],
|
||||
);
|
||||
|
||||
$this->entityManager->persist($game);
|
||||
$this->entityManager->persist($key);
|
||||
$addedAmount++;
|
||||
}
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
return [$totalRows, $addedAmount];
|
||||
}
|
||||
|
||||
private function interpretStore(string $storeString): Store {
|
||||
$storeString = trim($storeString);
|
||||
$storeString = strtolower($storeString);
|
||||
$storeString = str_replace(' ', '', $storeString);
|
||||
|
||||
$triedConversion = Store::tryFrom($storeString);
|
||||
if ($triedConversion !== null) {
|
||||
return $triedConversion;
|
||||
}
|
||||
|
||||
if (array_key_exists($storeString, self::STORE_ADDITIONAL_CASES)) {
|
||||
return self::STORE_ADDITIONAL_CASES[$storeString];
|
||||
}
|
||||
|
||||
return Store::EXTERNAL;
|
||||
}
|
||||
}
|
|
@ -1,26 +1,26 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Importer;
|
||||
|
||||
use GamesShop\Entities\Games\KeyAttribute;
|
||||
use JsonSerializable;
|
||||
|
||||
final readonly class ImportColumnInterpretation implements JsonSerializable
|
||||
{
|
||||
public function __construct(
|
||||
public string $index,
|
||||
public string $displayName,
|
||||
public KeyAttribute|null $guessedAttribute
|
||||
)
|
||||
{ }
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'index' => $this->index,
|
||||
'displayName' => $this->displayName,
|
||||
'guessedAttribute' => $this->guessedAttribute ?? null
|
||||
];
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Importer;
|
||||
|
||||
use GamesShop\Entities\Games\KeyAttribute;
|
||||
use JsonSerializable;
|
||||
|
||||
final readonly class ImportColumnInterpretation implements JsonSerializable
|
||||
{
|
||||
public function __construct(
|
||||
public string $index,
|
||||
public string $displayName,
|
||||
public KeyAttribute|null $guessedAttribute
|
||||
)
|
||||
{ }
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'index' => $this->index,
|
||||
'displayName' => $this->displayName,
|
||||
'guessedAttribute' => $this->guessedAttribute ?? null
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,47 +1,47 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Login;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\Api\DiscordAPI;
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Entities\Account\User;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class DiscordLoginProvider implements LoginProvider
|
||||
{
|
||||
public function __construct(
|
||||
private readonly EntityManager $entityManager
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function getUser(ServerRequestInterface $request): User
|
||||
{
|
||||
$discordApiHandler = ContainerHandler::get(DiscordAPI::class);
|
||||
$result = $discordApiHandler->getUserFromCode($request->getQueryParams()['code'], (string)$request->getUri()->withQuery(''));
|
||||
|
||||
$repo = $this->entityManager->getRepository(User::class);
|
||||
$users = $repo->findBy(['loginMethod' => LoginMethod::DISCORD, 'foreignLoginId' => $result['id']]);
|
||||
|
||||
$profilePictureUrl = $discordApiHandler->getAvatarURL($result['id'], $result['avatar'] ?? $result['discriminator'] % 5);
|
||||
if (!empty($users)) {
|
||||
$user = $users[0];
|
||||
$user->setName($result['global_name']);
|
||||
$user->setProfilePictureUrl($profilePictureUrl);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
$newUser = new User(
|
||||
LoginMethod::DISCORD,
|
||||
$result['id'],
|
||||
$result['global_name'],
|
||||
$profilePictureUrl,
|
||||
UserPermission::VIEWER
|
||||
);
|
||||
|
||||
return $newUser;
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Login;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\Api\DiscordAPI;
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Entities\Account\User;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class DiscordLoginProvider implements LoginProvider
|
||||
{
|
||||
public function __construct(
|
||||
private readonly EntityManager $entityManager
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function getUser(ServerRequestInterface $request): User
|
||||
{
|
||||
$discordApiHandler = ContainerHandler::get(DiscordAPI::class);
|
||||
$result = $discordApiHandler->getUserFromCode($request->getQueryParams()['code'], (string)$request->getUri()->withQuery(''));
|
||||
|
||||
$repo = $this->entityManager->getRepository(User::class);
|
||||
$users = $repo->findBy(['loginMethod' => LoginMethod::DISCORD, 'foreignLoginId' => $result['id']]);
|
||||
|
||||
$profilePictureUrl = $discordApiHandler->getAvatarURL($result['id'], $result['avatar'] ?? $result['discriminator'] % 5);
|
||||
if (!empty($users)) {
|
||||
$user = $users[0];
|
||||
$user->setName($result['global_name']);
|
||||
$user->setProfilePictureUrl($profilePictureUrl);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
$newUser = new User(
|
||||
LoginMethod::DISCORD,
|
||||
$result['id'],
|
||||
$result['global_name'],
|
||||
$profilePictureUrl,
|
||||
UserPermission::VIEWER
|
||||
);
|
||||
|
||||
return $newUser;
|
||||
}
|
||||
}
|
|
@ -1,76 +1,76 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Login;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Exception;
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Entities\Account\User;
|
||||
|
||||
final class LoginHandler
|
||||
{
|
||||
/**
|
||||
* @return class-string[]
|
||||
*/
|
||||
private static array $providers;
|
||||
|
||||
public function __construct(
|
||||
private readonly EntityManager $entityManager
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function isLoggedIn(): bool {
|
||||
$this->ensureSession();
|
||||
|
||||
return isset($_SESSION['accountid']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getLoginProvider(string $method): LoginProvider {
|
||||
$providers = self::getProviders();
|
||||
if (!array_key_exists($method, $providers)) {
|
||||
throw new Exception("Couldn't find method for login '{$method}'");
|
||||
}
|
||||
|
||||
return ContainerHandler::get($providers[$method]);
|
||||
}
|
||||
|
||||
public function setCurrentUser(User $user) {
|
||||
$this->ensureSession();
|
||||
|
||||
$_SESSION['accountid'] = $user->getId();
|
||||
}
|
||||
|
||||
public function getCurrentUser(): User {
|
||||
$this->ensureSession();
|
||||
|
||||
$userid = $_SESSION['accountid'];
|
||||
return $this->entityManager->getRepository(User::class)->find($userid);
|
||||
}
|
||||
|
||||
public function deleteSession() {
|
||||
$this->ensureSession();
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
private function ensureSession()
|
||||
{
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
session_start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string[]
|
||||
*/
|
||||
private static function getProviders(): array
|
||||
{
|
||||
return self::$providers ??= [
|
||||
'discord' => DiscordLoginProvider::class
|
||||
];
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Login;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Exception;
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Entities\Account\User;
|
||||
|
||||
final class LoginHandler
|
||||
{
|
||||
/**
|
||||
* @return class-string[]
|
||||
*/
|
||||
private static array $providers;
|
||||
|
||||
public function __construct(
|
||||
private readonly EntityManager $entityManager
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function isLoggedIn(): bool {
|
||||
$this->ensureSession();
|
||||
|
||||
return isset($_SESSION['accountid']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getLoginProvider(string $method): LoginProvider {
|
||||
$providers = self::getProviders();
|
||||
if (!array_key_exists($method, $providers)) {
|
||||
throw new Exception("Couldn't find method for login '{$method}'");
|
||||
}
|
||||
|
||||
return ContainerHandler::get($providers[$method]);
|
||||
}
|
||||
|
||||
public function setCurrentUser(User $user) {
|
||||
$this->ensureSession();
|
||||
|
||||
$_SESSION['accountid'] = $user->getId();
|
||||
}
|
||||
|
||||
public function getCurrentUser(): User {
|
||||
$this->ensureSession();
|
||||
|
||||
$userid = $_SESSION['accountid'];
|
||||
return $this->entityManager->getRepository(User::class)->find($userid);
|
||||
}
|
||||
|
||||
public function deleteSession() {
|
||||
$this->ensureSession();
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
private function ensureSession()
|
||||
{
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
session_start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string[]
|
||||
*/
|
||||
private static function getProviders(): array
|
||||
{
|
||||
return self::$providers ??= [
|
||||
'discord' => DiscordLoginProvider::class
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,23 +1,23 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Login;
|
||||
|
||||
enum LoginMethod: int
|
||||
{
|
||||
case DISCORD = 1;
|
||||
|
||||
public function getIconClass(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::DISCORD => 'fa-discord',
|
||||
};
|
||||
}
|
||||
|
||||
public function getHumanReadableName(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::DISCORD => 'Discord',
|
||||
};
|
||||
}
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Login;
|
||||
|
||||
enum LoginMethod: int
|
||||
{
|
||||
case DISCORD = 1;
|
||||
|
||||
public function getIconClass(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::DISCORD => 'fa-discord',
|
||||
};
|
||||
}
|
||||
|
||||
public function getHumanReadableName(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::DISCORD => 'Discord',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Login;
|
||||
|
||||
use GamesShop\Entities\Account\User;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
interface LoginProvider
|
||||
{
|
||||
public function getUser(ServerRequestInterface $request): User;
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Login;
|
||||
|
||||
use GamesShop\Entities\Account\User;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
interface LoginProvider
|
||||
{
|
||||
public function getUser(ServerRequestInterface $request): User;
|
||||
}
|
|
@ -1,25 +1,25 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Login;
|
||||
|
||||
enum UserPermission : int
|
||||
{
|
||||
case NONE = 0;
|
||||
case VIEWER = 1;
|
||||
case PROVIDER = 10;
|
||||
case ADMIN = 100;
|
||||
|
||||
public function hasLevel(UserPermission $userPermission): bool {
|
||||
return $this->value >= $userPermission->value;
|
||||
}
|
||||
|
||||
public function getHumanReadableName() {
|
||||
return match ($this) {
|
||||
self::VIEWER => "Claimer",
|
||||
self::PROVIDER => "Provider",
|
||||
self::ADMIN => "Admin",
|
||||
default => "None",
|
||||
};
|
||||
}
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Login;
|
||||
|
||||
enum UserPermission : int
|
||||
{
|
||||
case NONE = 0;
|
||||
case VIEWER = 1;
|
||||
case PROVIDER = 10;
|
||||
case ADMIN = 100;
|
||||
|
||||
public function hasLevel(UserPermission $userPermission): bool {
|
||||
return $this->value >= $userPermission->value;
|
||||
}
|
||||
|
||||
public function getHumanReadableName() {
|
||||
return match ($this) {
|
||||
self::VIEWER => "Claimer",
|
||||
self::PROVIDER => "Provider",
|
||||
self::ADMIN => "Admin",
|
||||
default => "None",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop;
|
||||
|
||||
final class Paths
|
||||
{
|
||||
public const string ROOT_PATH = __DIR__ . '/../..';
|
||||
public const string PUBLIC_PATH = self::ROOT_PATH . '/public';
|
||||
public const string SOURCE_PATH = self::ROOT_PATH . '/src';
|
||||
|
||||
public const string PHP_SOURCE_PATH = self::SOURCE_PATH . '/php';
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop;
|
||||
|
||||
final class Paths
|
||||
{
|
||||
public const string ROOT_PATH = __DIR__ . '/../..';
|
||||
public const string PUBLIC_PATH = self::ROOT_PATH . '/public';
|
||||
public const string SOURCE_PATH = self::ROOT_PATH . '/src';
|
||||
|
||||
public const string PHP_SOURCE_PATH = self::SOURCE_PATH . '/php';
|
||||
}
|
|
@ -1,49 +1,49 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use GamesShop\Routing\Responses\TemplateResponse;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
use Laminas\Diactoros\Response\RedirectResponse;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class AdminAccountConfigRoute
|
||||
{
|
||||
public function __construct(
|
||||
private readonly LoginHandler $loginHandler
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ForbiddenException
|
||||
* @throws UnauthorizedException
|
||||
*/
|
||||
public function __invoke(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
if (!$this->loginHandler->isLoggedIn()) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
|
||||
$user = $this->loginHandler->getCurrentUser();
|
||||
if ($user->getPermission()->value < UserPermission::ADMIN->value) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
|
||||
return new TemplateResponse('admin/accounts');
|
||||
}
|
||||
|
||||
public static function applyRoutes(\League\Route\Router $router) {
|
||||
$router->get('/accounts', self::class);
|
||||
}
|
||||
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use GamesShop\Routing\Responses\TemplateResponse;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
use Laminas\Diactoros\Response\RedirectResponse;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class AdminAccountConfigRoute
|
||||
{
|
||||
public function __construct(
|
||||
private readonly LoginHandler $loginHandler
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ForbiddenException
|
||||
* @throws UnauthorizedException
|
||||
*/
|
||||
public function __invoke(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
if (!$this->loginHandler->isLoggedIn()) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
|
||||
$user = $this->loginHandler->getCurrentUser();
|
||||
if ($user->getPermission()->value < UserPermission::ADMIN->value) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
|
||||
return new TemplateResponse('admin/accounts');
|
||||
}
|
||||
|
||||
public static function applyRoutes(\League\Route\Router $router) {
|
||||
$router->get('/accounts', self::class);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api;
|
||||
|
||||
use GamesShop\Routing\Api\DataTables\DataTablesAPIRoutes;
|
||||
use GamesShop\Routing\Api\Web\WebAPIRoutes;
|
||||
use League\Route\Router;
|
||||
|
||||
final class APIRoutes
|
||||
{
|
||||
public static function applyRoutes(Router $router) {
|
||||
$router->group('/api/dt', DataTablesAPIRoutes::setupRoutes(...));
|
||||
$router->group('/api/web', WebAPIRoutes::applyRoutes(...));
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api;
|
||||
|
||||
use GamesShop\Routing\Api\DataTables\DataTablesAPIRoutes;
|
||||
use GamesShop\Routing\Api\Web\WebAPIRoutes;
|
||||
use League\Route\Router;
|
||||
|
||||
final class APIRoutes
|
||||
{
|
||||
public static function applyRoutes(Router $router) {
|
||||
$router->group('/api/dt', DataTablesAPIRoutes::setupRoutes(...));
|
||||
$router->group('/api/web', WebAPIRoutes::applyRoutes(...));
|
||||
}
|
||||
}
|
|
@ -1,80 +1,80 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api\DataTables;
|
||||
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Common\Collections\Expr\Comparison;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\Entities\Account\User;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use League\Route\RouteGroup;
|
||||
use League\Route\Router;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class AccountsEndpoint
|
||||
{
|
||||
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::ADMIN)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
|
||||
$params = $request->getQueryParams();
|
||||
$draw = $params['draw'];
|
||||
$start = $params['start'];
|
||||
$length = $params['length'];
|
||||
|
||||
$searchValue = $params['search']['value'];
|
||||
|
||||
$repo = $this->entityManager->getRepository(User::class);
|
||||
$total = $repo->count();
|
||||
|
||||
$criteria = Criteria::create();
|
||||
$criteria->where(Criteria::expr()->contains('name', $searchValue));
|
||||
$criteria->setFirstResult((int)$start);
|
||||
$criteria->setMaxResults((int)$length);
|
||||
|
||||
$values = $repo->matching($criteria);
|
||||
$filteredCount = $values->count();
|
||||
|
||||
return new JsonResponse([
|
||||
'draw' => $draw,
|
||||
'recordsTotal' => $total,
|
||||
'recordsFiltered' => $filteredCount,
|
||||
'data' =>
|
||||
$values->map(function (User $user) {
|
||||
return [
|
||||
'userid' => $user->getId(),
|
||||
'name' => $user->getName(),
|
||||
'profilePictureUrl' => $user->getProfilePictureUrl(),
|
||||
'permission' => $user->getPermission()->getHumanReadableName(),
|
||||
'permissionIndex' => $user->getPermission()->value,
|
||||
'loginMethod' => $user->getLoginMethod()->getHumanReadableName(),
|
||||
];
|
||||
})->toArray()
|
||||
]);
|
||||
}
|
||||
|
||||
public static function applyRoutes(RouteGroup $router) {
|
||||
$router->get('/accounts', AccountsEndpoint::class);
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api\DataTables;
|
||||
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Common\Collections\Expr\Comparison;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\Entities\Account\User;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use League\Route\RouteGroup;
|
||||
use League\Route\Router;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class AccountsEndpoint
|
||||
{
|
||||
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::ADMIN)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
|
||||
$params = $request->getQueryParams();
|
||||
$draw = $params['draw'];
|
||||
$start = $params['start'];
|
||||
$length = $params['length'];
|
||||
|
||||
$searchValue = $params['search']['value'];
|
||||
|
||||
$repo = $this->entityManager->getRepository(User::class);
|
||||
$total = $repo->count();
|
||||
|
||||
$criteria = Criteria::create();
|
||||
$criteria->where(Criteria::expr()->contains('name', $searchValue));
|
||||
$criteria->setFirstResult((int)$start);
|
||||
$criteria->setMaxResults((int)$length);
|
||||
|
||||
$values = $repo->matching($criteria);
|
||||
$filteredCount = $values->count();
|
||||
|
||||
return new JsonResponse([
|
||||
'draw' => $draw,
|
||||
'recordsTotal' => $total,
|
||||
'recordsFiltered' => $filteredCount,
|
||||
'data' =>
|
||||
$values->map(function (User $user) {
|
||||
return [
|
||||
'userid' => $user->getId(),
|
||||
'name' => $user->getName(),
|
||||
'profilePictureUrl' => $user->getProfilePictureUrl(),
|
||||
'permission' => $user->getPermission()->getHumanReadableName(),
|
||||
'permissionIndex' => $user->getPermission()->value,
|
||||
'loginMethod' => $user->getLoginMethod()->getHumanReadableName(),
|
||||
];
|
||||
})->toArray()
|
||||
]);
|
||||
}
|
||||
|
||||
public static function applyRoutes(RouteGroup $router) {
|
||||
$router->get('/accounts', AccountsEndpoint::class);
|
||||
}
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api\DataTables;
|
||||
|
||||
use League\Route\RouteGroup;
|
||||
use League\Route\Router;
|
||||
|
||||
final class DataTablesAPIRoutes
|
||||
{
|
||||
public static function setupRoutes(RouteGroup $group): void {
|
||||
AccountsEndpoint::applyRoutes($group);
|
||||
|
||||
$group->get('/keys/provider', ProviderKeysEndpoint::class);
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api\DataTables;
|
||||
|
||||
use League\Route\RouteGroup;
|
||||
use League\Route\Router;
|
||||
|
||||
final class DataTablesAPIRoutes
|
||||
{
|
||||
public static function setupRoutes(RouteGroup $group): void {
|
||||
AccountsEndpoint::applyRoutes($group);
|
||||
|
||||
$group->get('/keys/provider', ProviderKeysEndpoint::class);
|
||||
}
|
||||
}
|
|
@ -1,78 +1,78 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api\DataTables;
|
||||
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Common\Collections\Order;
|
||||
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;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class ProviderKeysEndpoint
|
||||
{
|
||||
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->getQueryParams();
|
||||
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();
|
||||
}
|
||||
|
||||
$keys = $this->entityManager->getRepository(Key::class)->findBy(['list' => $list]);
|
||||
$gameToKeyArray = [];
|
||||
foreach ($keys as $key) {
|
||||
$game = $key->getGame();
|
||||
$id = $game->getId();
|
||||
|
||||
if (!array_key_exists($id, $gameToKeyArray)) {
|
||||
$gameToKeyArray[$id] = [ $game, [] ];
|
||||
}
|
||||
|
||||
$gameToKeyArray[$id][1][] = $key;
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach ($gameToKeyArray as [$game, $keys]) {
|
||||
$result[] = [
|
||||
'gamePicture' => '',
|
||||
'name' => $game->getName(),
|
||||
'keysAmount' => count($keys),
|
||||
'igdbState' => 'not implermented',
|
||||
'keys' => $keys,
|
||||
];
|
||||
}
|
||||
|
||||
return new JsonResponse([ 'data' => $result ]);
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api\DataTables;
|
||||
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Common\Collections\Order;
|
||||
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;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class ProviderKeysEndpoint
|
||||
{
|
||||
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->getQueryParams();
|
||||
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();
|
||||
}
|
||||
|
||||
$keys = $this->entityManager->getRepository(Key::class)->findBy(['list' => $list]);
|
||||
$gameToKeyArray = [];
|
||||
foreach ($keys as $key) {
|
||||
$game = $key->getGame();
|
||||
$id = $game->getId();
|
||||
|
||||
if (!array_key_exists($id, $gameToKeyArray)) {
|
||||
$gameToKeyArray[$id] = [ $game, [] ];
|
||||
}
|
||||
|
||||
$gameToKeyArray[$id][1][] = $key;
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach ($gameToKeyArray as [$game, $keys]) {
|
||||
$result[] = [
|
||||
'gamePicture' => '',
|
||||
'name' => $game->getName(),
|
||||
'keysAmount' => count($keys),
|
||||
'igdbState' => 'not implermented',
|
||||
'keys' => $keys,
|
||||
];
|
||||
}
|
||||
|
||||
return new JsonResponse([ 'data' => $result ]);
|
||||
}
|
||||
}
|
|
@ -1,49 +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();
|
||||
}
|
||||
<?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();
|
||||
}
|
||||
}
|
|
@ -1,50 +1,50 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api\Web;
|
||||
|
||||
use GamesShop\Importer\GameImporter;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Laminas\Diactoros\UploadedFile;
|
||||
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 ImportKeysPrepareRoute
|
||||
{
|
||||
public function __construct(
|
||||
private readonly LoginHandler $loginHandler,
|
||||
private readonly GameImporter $importer,
|
||||
) { }
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @var UploadedFile $file
|
||||
*/
|
||||
$file = $request->getUploadedFiles()['file'] ?? null;
|
||||
if (!$file === null) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
$fileName = tempnam(sys_get_temp_dir(), 'ImportKeys');
|
||||
$file->moveTo($fileName);
|
||||
$results = $this->importer->interpret($fileName);
|
||||
unlink($fileName);
|
||||
|
||||
return new JsonResponse($results);
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api\Web;
|
||||
|
||||
use GamesShop\Importer\GameImporter;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Laminas\Diactoros\UploadedFile;
|
||||
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 ImportKeysPrepareRoute
|
||||
{
|
||||
public function __construct(
|
||||
private readonly LoginHandler $loginHandler,
|
||||
private readonly GameImporter $importer,
|
||||
) { }
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @var UploadedFile $file
|
||||
*/
|
||||
$file = $request->getUploadedFiles()['file'] ?? null;
|
||||
if (!$file === null) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
$fileName = tempnam(sys_get_temp_dir(), 'ImportKeys');
|
||||
$file->moveTo($fileName);
|
||||
$results = $this->importer->interpret($fileName);
|
||||
unlink($fileName);
|
||||
|
||||
return new JsonResponse($results);
|
||||
}
|
||||
}
|
|
@ -1,66 +1,66 @@
|
|||
<?php
|
||||
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;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Laminas\Diactoros\UploadedFile;
|
||||
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 ImportKeysRoute
|
||||
{
|
||||
public function __construct(
|
||||
private readonly LoginHandler $loginHandler,
|
||||
private readonly GameImporter $importer,
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @var UploadedFile $file
|
||||
*/
|
||||
$file = $request->getUploadedFiles()['file'] ?? null;
|
||||
if (!$file === null) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
$fileName = tempnam(sys_get_temp_dir(), 'ImportKeys');
|
||||
$file->moveTo($fileName);
|
||||
|
||||
$columnDefs = $request->getParsedBody()['columns'];
|
||||
|
||||
[$total, $imported] = $this->importer->import($fileName, $columnDefs, $list);
|
||||
unlink($fileName);
|
||||
|
||||
return new JsonResponse([ 'success' => true, 'total' => $total, 'imported' => $imported ]);
|
||||
}
|
||||
<?php
|
||||
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;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Laminas\Diactoros\UploadedFile;
|
||||
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 ImportKeysRoute
|
||||
{
|
||||
public function __construct(
|
||||
private readonly LoginHandler $loginHandler,
|
||||
private readonly GameImporter $importer,
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @var UploadedFile $file
|
||||
*/
|
||||
$file = $request->getUploadedFiles()['file'] ?? null;
|
||||
if (!$file === null) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
$fileName = tempnam(sys_get_temp_dir(), 'ImportKeys');
|
||||
$file->moveTo($fileName);
|
||||
|
||||
$columnDefs = $request->getParsedBody()['columns'];
|
||||
|
||||
[$total, $imported] = $this->importer->import($fileName, $columnDefs, $list);
|
||||
unlink($fileName);
|
||||
|
||||
return new JsonResponse([ 'success' => true, 'total' => $total, 'imported' => $imported ]);
|
||||
}
|
||||
}
|
|
@ -1,46 +1,46 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api\Web;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use GamesShop\Entities\Account\User;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final readonly class UserModifyRoute
|
||||
{
|
||||
public function __construct(
|
||||
private LoginHandler $loginHandler,
|
||||
private EntityManager $entityManager,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request, array $args): ResponseInterface
|
||||
{
|
||||
if (!$this->loginHandler->isLoggedIn()) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
|
||||
$user = $this->loginHandler->getCurrentUser();
|
||||
if (!$user->getPermission()->hasLevel(UserPermission::ADMIN)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
$permissions = $request->getParsedBody()['permission'];
|
||||
|
||||
$toChangeUser = $this->entityManager->getRepository(User::class)->find((int)$args['id']);
|
||||
$toChangeUser->setPermission(UserPermission::from((int)$permissions));
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new EmptyResponse(200);
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api\Web;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use GamesShop\Entities\Account\User;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final readonly class UserModifyRoute
|
||||
{
|
||||
public function __construct(
|
||||
private LoginHandler $loginHandler,
|
||||
private EntityManager $entityManager,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request, array $args): ResponseInterface
|
||||
{
|
||||
if (!$this->loginHandler->isLoggedIn()) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
|
||||
$user = $this->loginHandler->getCurrentUser();
|
||||
if (!$user->getPermission()->hasLevel(UserPermission::ADMIN)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
$permissions = $request->getParsedBody()['permission'];
|
||||
|
||||
$toChangeUser = $this->entityManager->getRepository(User::class)->find((int)$args['id']);
|
||||
$toChangeUser->setPermission(UserPermission::from((int)$permissions));
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new EmptyResponse(200);
|
||||
}
|
||||
}
|
|
@ -1,18 +1,18 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api\Web;
|
||||
|
||||
use League\Route\RouteGroup;
|
||||
|
||||
final class WebAPIRoutes
|
||||
{
|
||||
public static function applyRoutes(RouteGroup $group): void {
|
||||
$group->post('/users/{id:number}', UserModifyRoute::class);
|
||||
|
||||
$group->post('/keys/import/prepare', ImportKeysPrepareRoute::class);
|
||||
$group->post('/keys/import/perform', ImportKeysRoute::class);
|
||||
|
||||
$group->post('/keys/list/create', CreateKeyListRoute::class);
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Api\Web;
|
||||
|
||||
use League\Route\RouteGroup;
|
||||
|
||||
final class WebAPIRoutes
|
||||
{
|
||||
public static function applyRoutes(RouteGroup $group): void {
|
||||
$group->post('/users/{id:number}', UserModifyRoute::class);
|
||||
|
||||
$group->post('/keys/import/prepare', ImportKeysPrepareRoute::class);
|
||||
$group->post('/keys/import/perform', ImportKeysRoute::class);
|
||||
|
||||
$group->post('/keys/list/create', CreateKeyListRoute::class);
|
||||
}
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Templates\TemplateEngine;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
final class ErrorRoute
|
||||
{
|
||||
public function renderErrorPage(int $errorCode): ResponseInterface {
|
||||
$pageContent = ContainerHandler::get(TemplateEngine::class)->renderErrorPage($errorCode);
|
||||
|
||||
$response = new Response(status: $errorCode);
|
||||
$response->getBody()->write($pageContent);
|
||||
return $response;
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Templates\TemplateEngine;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
final class ErrorRoute
|
||||
{
|
||||
public function renderErrorPage(int $errorCode): ResponseInterface {
|
||||
$pageContent = ContainerHandler::get(TemplateEngine::class)->renderErrorPage($errorCode);
|
||||
|
||||
$response = new Response(status: $errorCode);
|
||||
$response->getBody()->write($pageContent);
|
||||
return $response;
|
||||
}
|
||||
}
|
|
@ -1,33 +1,33 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Templates\TemplateEngine;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\Diactoros\Response\RedirectResponse;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class IndexRoute
|
||||
{
|
||||
public function __invoke(ServerRequestInterface $request): ResponseInterface {
|
||||
$loginHandler = ContainerHandler::get(LoginHandler::class);
|
||||
|
||||
if (!$loginHandler->isLoggedIn()) {
|
||||
return new RedirectResponse('/login');
|
||||
}
|
||||
|
||||
$pageContent = ContainerHandler::get(TemplateEngine::class)->renderPage('index');
|
||||
|
||||
$response = new Response;
|
||||
$response->getBody()->write($pageContent);
|
||||
return $response;
|
||||
}
|
||||
|
||||
public static function applyRoutes(\League\Route\Router $router): void {
|
||||
$router->get('/', self::class);
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Templates\TemplateEngine;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\Diactoros\Response\RedirectResponse;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class IndexRoute
|
||||
{
|
||||
public function __invoke(ServerRequestInterface $request): ResponseInterface {
|
||||
$loginHandler = ContainerHandler::get(LoginHandler::class);
|
||||
|
||||
if (!$loginHandler->isLoggedIn()) {
|
||||
return new RedirectResponse('/login');
|
||||
}
|
||||
|
||||
$pageContent = ContainerHandler::get(TemplateEngine::class)->renderPage('index');
|
||||
|
||||
$response = new Response;
|
||||
$response->getBody()->write($pageContent);
|
||||
return $response;
|
||||
}
|
||||
|
||||
public static function applyRoutes(\League\Route\Router $router): void {
|
||||
$router->get('/', self::class);
|
||||
}
|
||||
}
|
|
@ -1,45 +1,45 @@
|
|||
<?php
|
||||
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;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class KeysRoute
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
$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
|
||||
{
|
||||
$router->get('/keys', KeysRoute::class);
|
||||
}
|
||||
<?php
|
||||
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;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class KeysRoute
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
$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
|
||||
{
|
||||
$router->get('/keys', KeysRoute::class);
|
||||
}
|
||||
}
|
|
@ -1,72 +1,72 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Exception\ORMException;
|
||||
use Doctrine\ORM\OptimisticLockException;
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Environment\EnvironmentHandler;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Routing\Responses\TemplateResponse;
|
||||
use GamesShop\Templates\TemplateEngine;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class LoginRoutes
|
||||
{
|
||||
public function __construct(
|
||||
private readonly EntityManager $entityManager
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function login(ServerRequestInterface $request) {
|
||||
$discordEnv = ContainerHandler::get(EnvironmentHandler::class)->getDiscordEnvironment();
|
||||
|
||||
return new TemplateResponse('login', [
|
||||
'discordUrl' => $discordEnv->loginUrl
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws OptimisticLockException
|
||||
* @throws ORMException
|
||||
*/
|
||||
public function loginCallback(ServerRequestInterface $request, array $args): ResponseInterface {
|
||||
if (array_key_exists('error', $request->getQueryParams())) {
|
||||
return new Response\RedirectResponse('/login');
|
||||
}
|
||||
|
||||
$method = $args['method'];
|
||||
$loginHandler = ContainerHandler::get(LoginHandler::class);
|
||||
$loginProvider = $loginHandler->getLoginProvider($method);
|
||||
|
||||
$user = $loginProvider->getUser($request);
|
||||
if ($user->getId() === null) {
|
||||
$this->entityManager->persist($user);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
$loginHandler->setCurrentUser($user);
|
||||
return new Response\RedirectResponse('/');
|
||||
}
|
||||
|
||||
public function logout(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$loginHandler = ContainerHandler::get(LoginHandler::class);
|
||||
$loginHandler->deleteSession();
|
||||
|
||||
return new Response\RedirectResponse('/login');
|
||||
}
|
||||
|
||||
public static function addRoutes(\League\Route\Router $router): void {
|
||||
$routes = ContainerHandler::get(LoginRoutes::class);
|
||||
|
||||
$router->get('/login', $routes->login(...));
|
||||
$router->get('/login-callback/{method:word}', $routes->loginCallback(...));
|
||||
$router->get('/logout', $routes->logout(...));
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Exception\ORMException;
|
||||
use Doctrine\ORM\OptimisticLockException;
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Environment\EnvironmentHandler;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Routing\Responses\TemplateResponse;
|
||||
use GamesShop\Templates\TemplateEngine;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class LoginRoutes
|
||||
{
|
||||
public function __construct(
|
||||
private readonly EntityManager $entityManager
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function login(ServerRequestInterface $request) {
|
||||
$discordEnv = ContainerHandler::get(EnvironmentHandler::class)->getDiscordEnvironment();
|
||||
|
||||
return new TemplateResponse('login', [
|
||||
'discordUrl' => $discordEnv->loginUrl
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws OptimisticLockException
|
||||
* @throws ORMException
|
||||
*/
|
||||
public function loginCallback(ServerRequestInterface $request, array $args): ResponseInterface {
|
||||
if (array_key_exists('error', $request->getQueryParams())) {
|
||||
return new Response\RedirectResponse('/login');
|
||||
}
|
||||
|
||||
$method = $args['method'];
|
||||
$loginHandler = ContainerHandler::get(LoginHandler::class);
|
||||
$loginProvider = $loginHandler->getLoginProvider($method);
|
||||
|
||||
$user = $loginProvider->getUser($request);
|
||||
if ($user->getId() === null) {
|
||||
$this->entityManager->persist($user);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
$loginHandler->setCurrentUser($user);
|
||||
return new Response\RedirectResponse('/');
|
||||
}
|
||||
|
||||
public function logout(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$loginHandler = ContainerHandler::get(LoginHandler::class);
|
||||
$loginHandler->deleteSession();
|
||||
|
||||
return new Response\RedirectResponse('/login');
|
||||
}
|
||||
|
||||
public static function addRoutes(\League\Route\Router $router): void {
|
||||
$routes = ContainerHandler::get(LoginRoutes::class);
|
||||
|
||||
$router->get('/login', $routes->login(...));
|
||||
$router->get('/login-callback/{method:word}', $routes->loginCallback(...));
|
||||
$router->get('/logout', $routes->logout(...));
|
||||
}
|
||||
}
|
|
@ -1,55 +1,55 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Paths;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\Diactoros\Uri;
|
||||
use Mimey\MimeTypes;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
final class ResourceRoute
|
||||
{
|
||||
private const array RESOURCE_EXTENSIONS = [
|
||||
'js',
|
||||
'css',
|
||||
'ttf', 'woff', 'woff2',
|
||||
'gif', 'svg', 'png', 'jpg'
|
||||
];
|
||||
|
||||
public function isValid(Uri $uri): bool {
|
||||
$path = $uri->getPath();
|
||||
foreach (self::RESOURCE_EXTENSIONS as $extension) {
|
||||
if (!str_ends_with($path, $extension)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getResponse(Uri $uri): ResponseInterface {
|
||||
$filePath = Paths::PUBLIC_PATH . $uri->getPath();
|
||||
|
||||
if (!file_exists($filePath)) {
|
||||
$response = new Response(status: 404);
|
||||
$response->getBody()->write('File not found');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
$mimey = ContainerHandler::get(MimeTypes::class);
|
||||
$response = new Response(
|
||||
headers: [
|
||||
'Content-Type' => $mimey->getMimeType(pathinfo($filePath, PATHINFO_EXTENSION)),
|
||||
'Cache-Control' => 'public, max-age=3600, must-revalidate',
|
||||
]
|
||||
);
|
||||
$response->getBody()->write(file_get_contents($filePath));
|
||||
|
||||
return $response;
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Paths;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\Diactoros\Uri;
|
||||
use Mimey\MimeTypes;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
final class ResourceRoute
|
||||
{
|
||||
private const array RESOURCE_EXTENSIONS = [
|
||||
'js',
|
||||
'css',
|
||||
'ttf', 'woff', 'woff2',
|
||||
'gif', 'svg', 'png', 'jpg'
|
||||
];
|
||||
|
||||
public function isValid(Uri $uri): bool {
|
||||
$path = $uri->getPath();
|
||||
foreach (self::RESOURCE_EXTENSIONS as $extension) {
|
||||
if (!str_ends_with($path, $extension)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getResponse(Uri $uri): ResponseInterface {
|
||||
$filePath = Paths::PUBLIC_PATH . $uri->getPath();
|
||||
|
||||
if (!file_exists($filePath)) {
|
||||
$response = new Response(status: 404);
|
||||
$response->getBody()->write('File not found');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
$mimey = ContainerHandler::get(MimeTypes::class);
|
||||
$response = new Response(
|
||||
headers: [
|
||||
'Content-Type' => $mimey->getMimeType(pathinfo($filePath, PATHINFO_EXTENSION)),
|
||||
'Cache-Control' => 'public, max-age=3600, must-revalidate',
|
||||
]
|
||||
);
|
||||
$response->getBody()->write(file_get_contents($filePath));
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Responses;
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Templates\TemplateEngine;
|
||||
use Laminas\Diactoros\Response;
|
||||
|
||||
final class TemplateResponse extends Response
|
||||
{
|
||||
public function __construct(string $templateName, array $data = [], array $headers = [])
|
||||
{
|
||||
parent::__construct('php://memory', 200, $headers);
|
||||
|
||||
$templateEngine = ContainerHandler::get(TemplateEngine::class);
|
||||
$body = $templateEngine->renderPage($templateName, $data);
|
||||
$this->getBody()->write($body);
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing\Responses;
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Templates\TemplateEngine;
|
||||
use Laminas\Diactoros\Response;
|
||||
|
||||
final class TemplateResponse extends Response
|
||||
{
|
||||
public function __construct(string $templateName, array $data = [], array $headers = [])
|
||||
{
|
||||
parent::__construct('php://memory', 200, $headers);
|
||||
|
||||
$templateEngine = ContainerHandler::get(TemplateEngine::class);
|
||||
$body = $templateEngine->renderPage($templateName, $data);
|
||||
$this->getBody()->write($body);
|
||||
}
|
||||
}
|
|
@ -1,61 +1,61 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Routing\Api\APIRoutes;
|
||||
use GamesShop\Templates\TemplateEngine;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\Diactoros\ServerRequestFactory;
|
||||
use League\Container\Container;
|
||||
use League\Route\Http\Exception\BadRequestException;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\NotFoundException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use League\Route\Strategy\ApplicationStrategy;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class Router
|
||||
{
|
||||
public function __construct(
|
||||
private ResourceRoute $resourceRoute
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function route(): ResponseInterface
|
||||
{
|
||||
$request = ServerRequestFactory::fromGlobals(
|
||||
$_SERVER, $_GET, $_POST, $_COOKIE, $_FILES
|
||||
);
|
||||
if ($this->resourceRoute->isValid($request->getUri())) {
|
||||
return $this->resourceRoute->getResponse($request->getUri());
|
||||
}
|
||||
|
||||
$router = new \League\Route\Router;
|
||||
$strategy = (new ApplicationStrategy)->setContainer(ContainerHandler::getInstance());
|
||||
$router->setStrategy($strategy);
|
||||
|
||||
IndexRoute::applyRoutes($router);
|
||||
LoginRoutes::addRoutes($router);
|
||||
SetupRoute::applyRoutes($router);
|
||||
|
||||
KeysRoute::applyRoutes($router);
|
||||
AdminAccountConfigRoute::applyRoutes($router);
|
||||
|
||||
APIRoutes::applyRoutes($router);
|
||||
|
||||
try {
|
||||
return $router->dispatch($request);
|
||||
} catch (NotFoundException $e) {
|
||||
return (new ErrorRoute())->renderErrorPage(404);
|
||||
} catch (UnauthorizedException) {
|
||||
return (new ErrorRoute())->renderErrorPage(401);
|
||||
} catch (ForbiddenException) {
|
||||
return (new ErrorRoute())->renderErrorPage(403);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Routing\Api\APIRoutes;
|
||||
use GamesShop\Templates\TemplateEngine;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\Diactoros\ServerRequestFactory;
|
||||
use League\Container\Container;
|
||||
use League\Route\Http\Exception\BadRequestException;
|
||||
use League\Route\Http\Exception\ForbiddenException;
|
||||
use League\Route\Http\Exception\NotFoundException;
|
||||
use League\Route\Http\Exception\UnauthorizedException;
|
||||
use League\Route\Strategy\ApplicationStrategy;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class Router
|
||||
{
|
||||
public function __construct(
|
||||
private ResourceRoute $resourceRoute
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function route(): ResponseInterface
|
||||
{
|
||||
$request = ServerRequestFactory::fromGlobals(
|
||||
$_SERVER, $_GET, $_POST, $_COOKIE, $_FILES
|
||||
);
|
||||
if ($this->resourceRoute->isValid($request->getUri())) {
|
||||
return $this->resourceRoute->getResponse($request->getUri());
|
||||
}
|
||||
|
||||
$router = new \League\Route\Router;
|
||||
$strategy = (new ApplicationStrategy)->setContainer(ContainerHandler::getInstance());
|
||||
$router->setStrategy($strategy);
|
||||
|
||||
IndexRoute::applyRoutes($router);
|
||||
LoginRoutes::addRoutes($router);
|
||||
SetupRoute::applyRoutes($router);
|
||||
|
||||
KeysRoute::applyRoutes($router);
|
||||
AdminAccountConfigRoute::applyRoutes($router);
|
||||
|
||||
APIRoutes::applyRoutes($router);
|
||||
|
||||
try {
|
||||
return $router->dispatch($request);
|
||||
} catch (NotFoundException $e) {
|
||||
return (new ErrorRoute())->renderErrorPage(404);
|
||||
} catch (UnauthorizedException) {
|
||||
return (new ErrorRoute())->renderErrorPage(401);
|
||||
} catch (ForbiddenException) {
|
||||
return (new ErrorRoute())->renderErrorPage(403);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,52 +1,52 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\Entities\SystemAttribute;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use Laminas\Diactoros\Response\RedirectResponse;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class SetupRoute
|
||||
{
|
||||
public function __construct(
|
||||
private readonly EntityManager $entityManager,
|
||||
private readonly LoginHandler $loginHandler
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request): ResponseInterface {
|
||||
if (!$this->loginHandler->isLoggedIn()) {
|
||||
return new RedirectResponse('/login');
|
||||
}
|
||||
|
||||
$repo = $this->entityManager->getRepository(SystemAttribute::class);
|
||||
|
||||
$attribute = $repo->find('ADMIN_SETUP_COMPLETED');
|
||||
if ($attribute) {
|
||||
return new RedirectResponse('/');
|
||||
}
|
||||
|
||||
$user = $this->loginHandler->getCurrentUser();
|
||||
$user->setPermission(UserPermission::ADMIN);
|
||||
|
||||
$attribute = new SystemAttribute(
|
||||
'ADMIN_SETUP_COMPLETED',
|
||||
'true'
|
||||
);
|
||||
$this->entityManager->persist($attribute);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new RedirectResponse('/');
|
||||
}
|
||||
|
||||
public static function applyRoutes(\League\Route\Router $router) {
|
||||
$router->get('/setup-admin', self::class);
|
||||
}
|
||||
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Routing;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use GamesShop\Entities\SystemAttribute;
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Login\UserPermission;
|
||||
use Laminas\Diactoros\Response\RedirectResponse;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
final class SetupRoute
|
||||
{
|
||||
public function __construct(
|
||||
private readonly EntityManager $entityManager,
|
||||
private readonly LoginHandler $loginHandler
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request): ResponseInterface {
|
||||
if (!$this->loginHandler->isLoggedIn()) {
|
||||
return new RedirectResponse('/login');
|
||||
}
|
||||
|
||||
$repo = $this->entityManager->getRepository(SystemAttribute::class);
|
||||
|
||||
$attribute = $repo->find('ADMIN_SETUP_COMPLETED');
|
||||
if ($attribute) {
|
||||
return new RedirectResponse('/');
|
||||
}
|
||||
|
||||
$user = $this->loginHandler->getCurrentUser();
|
||||
$user->setPermission(UserPermission::ADMIN);
|
||||
|
||||
$attribute = new SystemAttribute(
|
||||
'ADMIN_SETUP_COMPLETED',
|
||||
'true'
|
||||
);
|
||||
$this->entityManager->persist($attribute);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new RedirectResponse('/');
|
||||
}
|
||||
|
||||
public static function applyRoutes(\League\Route\Router $router) {
|
||||
$router->get('/setup-admin', self::class);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop;
|
||||
|
||||
final class SetupHandler
|
||||
{
|
||||
public function __construct(
|
||||
|
||||
)
|
||||
{
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop;
|
||||
|
||||
final class SetupHandler
|
||||
{
|
||||
public function __construct(
|
||||
|
||||
)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,17 +1,17 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Templates;
|
||||
|
||||
use GamesShop\Login\UserPermission;
|
||||
|
||||
final class NavigationHeader
|
||||
{
|
||||
public function __construct(
|
||||
public readonly string $title,
|
||||
public readonly string $link,
|
||||
public readonly UserPermission $minimumPermission,
|
||||
)
|
||||
{
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Templates;
|
||||
|
||||
use GamesShop\Login\UserPermission;
|
||||
|
||||
final class NavigationHeader
|
||||
{
|
||||
public function __construct(
|
||||
public readonly string $title,
|
||||
public readonly string $link,
|
||||
public readonly UserPermission $minimumPermission,
|
||||
)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Templates;
|
||||
|
||||
final class ResourceEntry
|
||||
{
|
||||
/**
|
||||
* @param string[] $js
|
||||
* @param string[] $css
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly array $js,
|
||||
public readonly array $css,
|
||||
) { }
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Templates;
|
||||
|
||||
final class ResourceEntry
|
||||
{
|
||||
/**
|
||||
* @param string[] $js
|
||||
* @param string[] $css
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly array $js,
|
||||
public readonly array $css,
|
||||
) { }
|
||||
}
|
|
@ -1,51 +1,51 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Templates;
|
||||
|
||||
use Exception;
|
||||
use GamesShop\Paths;
|
||||
|
||||
final class ResourceIndex
|
||||
{
|
||||
private const string PATH = Paths::SOURCE_PATH . '/file-index.json';
|
||||
|
||||
/**
|
||||
* @var ResourceEntry[]
|
||||
*/
|
||||
private array $resources = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$fileContents = file_get_contents(self::PATH);
|
||||
$index = json_decode($fileContents, true);
|
||||
|
||||
foreach ($index as $entryKey => $resource) {
|
||||
$js = $resource['js'];
|
||||
if (is_string($js)) {
|
||||
$js = [$js];
|
||||
}
|
||||
|
||||
$css = $resource['css'];
|
||||
if (is_string($css)) {
|
||||
$css = [$css];
|
||||
}
|
||||
|
||||
$this->resources[$entryKey] = new ResourceEntry(
|
||||
$js, $css
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getResource(string $entry): ResourceEntry
|
||||
{
|
||||
if (!array_key_exists($entry, $this->resources)) {
|
||||
throw new Exception("Entry '$entry' not found");
|
||||
}
|
||||
|
||||
return $this->resources[$entry];
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Templates;
|
||||
|
||||
use Exception;
|
||||
use GamesShop\Paths;
|
||||
|
||||
final class ResourceIndex
|
||||
{
|
||||
private const string PATH = Paths::SOURCE_PATH . '/file-index.json';
|
||||
|
||||
/**
|
||||
* @var ResourceEntry[]
|
||||
*/
|
||||
private array $resources = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$fileContents = file_get_contents(self::PATH);
|
||||
$index = json_decode($fileContents, true);
|
||||
|
||||
foreach ($index as $entryKey => $resource) {
|
||||
$js = $resource['js'];
|
||||
if (is_string($js)) {
|
||||
$js = [$js];
|
||||
}
|
||||
|
||||
$css = $resource['css'];
|
||||
if (is_string($css)) {
|
||||
$css = [$css];
|
||||
}
|
||||
|
||||
$this->resources[$entryKey] = new ResourceEntry(
|
||||
$js, $css
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getResource(string $entry): ResourceEntry
|
||||
{
|
||||
if (!array_key_exists($entry, $this->resources)) {
|
||||
throw new Exception("Entry '$entry' not found");
|
||||
}
|
||||
|
||||
return $this->resources[$entry];
|
||||
}
|
||||
}
|
|
@ -1,34 +1,34 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Templates;
|
||||
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Paths;
|
||||
use League\Plates\Engine;
|
||||
|
||||
final class TemplateEngine extends Engine
|
||||
{
|
||||
private const string TEMPLATES_PATH = Paths::SOURCE_PATH . '/templates';
|
||||
|
||||
public function __construct(
|
||||
private ResourceIndex $resourceIndex,
|
||||
LoginHandler $loginHandler,
|
||||
)
|
||||
{
|
||||
parent::__construct(self::TEMPLATES_PATH, 'php');
|
||||
$this->addData([
|
||||
'resources' => $this->resourceIndex,
|
||||
'activeUser' => $loginHandler->isLoggedIn() ? $loginHandler->getCurrentUser() : null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function renderPage(string $page, array $data = array())
|
||||
{
|
||||
return parent::render("pages/$page", $data);
|
||||
}
|
||||
|
||||
public function renderErrorPage(int $error) {
|
||||
return self::renderPage('error', [ 'errorCode' => $error ]);
|
||||
}
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GamesShop\Templates;
|
||||
|
||||
use GamesShop\Login\LoginHandler;
|
||||
use GamesShop\Paths;
|
||||
use League\Plates\Engine;
|
||||
|
||||
final class TemplateEngine extends Engine
|
||||
{
|
||||
private const string TEMPLATES_PATH = Paths::SOURCE_PATH . '/templates';
|
||||
|
||||
public function __construct(
|
||||
private ResourceIndex $resourceIndex,
|
||||
LoginHandler $loginHandler,
|
||||
)
|
||||
{
|
||||
parent::__construct(self::TEMPLATES_PATH, 'php');
|
||||
$this->addData([
|
||||
'resources' => $this->resourceIndex,
|
||||
'activeUser' => $loginHandler->isLoggedIn() ? $loginHandler->getCurrentUser() : null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function renderPage(string $page, array $data = array())
|
||||
{
|
||||
return parent::render("pages/$page", $data);
|
||||
}
|
||||
|
||||
public function renderErrorPage(int $error) {
|
||||
return self::renderPage('error', [ 'errorCode' => $error ]);
|
||||
}
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
#!/usr/bin/env php
|
||||
|
||||
<?php
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Tools\Console\ConsoleRunner;
|
||||
use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider;
|
||||
use GamesShop\ContainerHandler;
|
||||
|
||||
require_once __DIR__ . '/../bootstrap.php';
|
||||
|
||||
$entityManager = ContainerHandler::get(EntityManager::class);
|
||||
ConsoleRunner::run(
|
||||
new SingleManagerProvider($entityManager)
|
||||
#!/usr/bin/env php
|
||||
|
||||
<?php
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Tools\Console\ConsoleRunner;
|
||||
use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider;
|
||||
use GamesShop\ContainerHandler;
|
||||
|
||||
require_once __DIR__ . '/../bootstrap.php';
|
||||
|
||||
$entityManager = ContainerHandler::get(EntityManager::class);
|
||||
ConsoleRunner::run(
|
||||
new SingleManagerProvider($entityManager)
|
||||
);
|
|
@ -1,11 +1,11 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\DoctrineManager;
|
||||
use GamesShop\Environment\EnvironmentHandler;
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
ContainerHandler::get(EnvironmentHandler::class)->load();
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\DoctrineManager;
|
||||
use GamesShop\Environment\EnvironmentHandler;
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
ContainerHandler::get(EnvironmentHandler::class)->load();
|
||||
ContainerHandler::get(DoctrineManager::class)->setup();
|
|
@ -1,25 +1,25 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\DoctrineManager;
|
||||
use GamesShop\Environment\EnvironmentHandler;
|
||||
use GamesShop\Routing\Router;
|
||||
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
||||
use Whoops\Handler\HandlerInterface;
|
||||
use Whoops\Handler\PrettyPageHandler;
|
||||
use Whoops\Run;
|
||||
|
||||
require_once __DIR__ . '/../src/php/bootstrap.php';
|
||||
|
||||
$whoops = new Run();
|
||||
$prettyPageHandler = new PrettyPageHandler();
|
||||
$whoops->pushHandler($prettyPageHandler);
|
||||
$whoops->register();
|
||||
|
||||
ContainerHandler::getInstance()->addShared(HandlerInterface::class, $prettyPageHandler);
|
||||
|
||||
$router = ContainerHandler::getInstance()->get(Router::class);
|
||||
$result = $router->route();
|
||||
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use GamesShop\ContainerHandler;
|
||||
use GamesShop\DoctrineManager;
|
||||
use GamesShop\Environment\EnvironmentHandler;
|
||||
use GamesShop\Routing\Router;
|
||||
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
||||
use Whoops\Handler\HandlerInterface;
|
||||
use Whoops\Handler\PrettyPageHandler;
|
||||
use Whoops\Run;
|
||||
|
||||
require_once __DIR__ . '/../src/php/bootstrap.php';
|
||||
|
||||
$whoops = new Run();
|
||||
$prettyPageHandler = new PrettyPageHandler();
|
||||
$whoops->pushHandler($prettyPageHandler);
|
||||
$whoops->register();
|
||||
|
||||
ContainerHandler::getInstance()->addShared(HandlerInterface::class, $prettyPageHandler);
|
||||
|
||||
$router = ContainerHandler::getInstance()->get(Router::class);
|
||||
$result = $router->route();
|
||||
|
||||
(new SapiEmitter)->emit($result);
|
|
@ -1,2 +1,2 @@
|
|||
<?php
|
||||
<?php
|
||||
declare(strict_types=1);
|
Loading…
Add table
Add a link
Reference in a new issue