Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ node_modules/
/fe/build/
/fe/yarn-error.log
/fe/.vs/
/fe/.graphql_ppx_cache/
/be/vendor/
/be/config.php
/be/config_cba.php
Expand Down
4 changes: 4 additions & 0 deletions be/Api/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@
use Controller\AuthCtrl;
use Controller\RatingsHistoryCtrl;
use Controller\RemoveGameCtrl;
use Controller\GraphqlCtrl;
use Middleware\Privileges\PrivilegesIsLogged;
use Middleware\Validation;

require 'autoload.php';

$app = new EloApp;

$app->post('/graphql', [GraphqlCtrl::class, 'api'])
->add(PrivilegesIsLogged::class);

$app->get('/auth/isLogged', [AuthCtrl::class, 'isLogged']);

$app->post('/auth/login', [AuthCtrl::class, 'login']);
Expand Down
64 changes: 64 additions & 0 deletions be/Controller/GraphqlCtrl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace Controller;

use Slim\Http\Response;
use \Psr\Http\Message\ServerRequestInterface as Request;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\GraphQL;
use GraphQL\Type\Schema;
use GraphQL\Type\Definition\Type;
use GraphQLElo\Resolvers\UsersResolver;
use GraphQLElo\Types\UserType;

class GraphqlCtrl {
/** @var UsersResolver */
private $usersResolver;

/** @var UserType */
private $userType;

public function __construct(UsersResolver $usersResolver, UserType $userType) {
$this->usersResolver = $usersResolver;
$this->userType = $userType;
}

public function api(Request $request, Response $response): Response {
$schema = new Schema([
'query' => new ObjectType([
'name' => 'Query',
'fields' => $this->getQueryFields(),
]),
]);

$rawInput = $request->getBody();
$input = json_decode($rawInput, true);
$query = $input['query'];
$variableValues = $input['variables'] ?? null;

try {
$result = GraphQL::executeQuery($schema, $query, null, null, $variableValues);
$output = $result->toArray();
} catch (\Exception $e) {
$output = [
'errors' => [
[
'message' => $e->getMessage()
]
]
];
}

return $response->withJson($output);
}

private function getQueryFields(): array {
return [
'users' => [
'type' => Type::nonNull(Type::listOf(Type::nonNull($this->userType))),
'resolve' => $this->usersResolver,
],
];
}
}

28 changes: 28 additions & 0 deletions be/GraphQLElo/Resolvers/UsersResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace GraphQLElo\Resolvers;

use Model\Entity\User;
use Model\Repository\UserRepository;

class UsersResolver {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zakładam, że resolvery służą do przetworzenia parametrów Requesta i na ich podstawie zwrócenia odpowiednich danych? Czy tutaj w jakiś sposób czasem te parametry nie powinny być przekazywane? Chodzi mi o to, że np. czy kod ['rating' => 'DESC', 'code' => 'ASC'] nie powinien czasem być jakoś przekazywany jako parametr mówiący o tym według czego ma być sortowanie?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tak, możnaby zrobić jakiś input typ który by tym sterował i wtedy możnaby tym sterować z FE, ale narazie to jest wprowadzenie graphqlea - narazie bym zostawł w przyszłości jak będzie potrzeba będzie można to oczywiście zmienić

/** @var UserRepository */
private $userRepository;

public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}

/**
* @return User[];
*/
public function __invoke(): array
{
return $this->userRepository->findBy(
['deleted' => 0],
['rating' => 'DESC', 'code' => 'ASC']
);
}
}

55 changes: 55 additions & 0 deletions be/GraphQLElo/Types/UserType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace GraphQLElo\Types;

use Model\Entity\User;
use Service\UsersSvc;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;

class UserType extends ObjectType {
public function __construct(UsersSvc $usersSvc) {
$config = [
'fields' => [
'userNid' => [
'type' => Type::nonNull(Type::int()),
'resolve' => static function (User $user) {
return $user->getUserNid();
},
],
'code' => [
'type' => Type::nonNull(Type::string()),
'resolve' => static function (User $user) {
return $user->getCode();
},
],
'name' => [
'type' => Type::nonNull(Type::string()),
'resolve' => static function (User $user) {
return $user->getName();
},
],
'rating' => [
'type' => Type::nonNull(Type::int()),
'resolve' => static function (User $user) {
return $user->getRating();
},
],
'team' => [
'type' => Type::nonNull(Type::string()),
'resolve' => static function (User $user) {
return $user->getTeam();
},
],
'trendRatingDiff' => [
'type' => Type::nonNull(Type::int()),
'resolve' => static function (User $user) use ($usersSvc) {
return $usersSvc->calculateTrendRatingDiffForGql($user);
},
],
],
];
parent::__construct($config);
}

}
9 changes: 8 additions & 1 deletion be/Service/UsersSvc.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function __construct(
$this->userRepository = $userRepository;
$this->gameFactory = $gameFactory;
}

public function getUsers(): array
{
$userEntityList = $this->userRepository->findBy(
Expand Down Expand Up @@ -68,6 +68,13 @@ private function calculateTrendRatingDiff(array $userArray): array
return $userArray;
}

public function calculateTrendRatingDiffForGql(User $user): int {
$winGamesSumRating = $this->sumRatingDiffs($user->getLastWonGameList());
$looseGamesSumRating = $this->sumRatingDiffs($user->getLastLostGameList());

return $winGamesSumRating - $looseGamesSumRating;
}

private function sumRatingDiffs(Collection $gameList): int
{
return array_reduce($gameList->toArray(), function (int $acc, Game $game) {
Expand Down
3 changes: 2 additions & 1 deletion be/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"php": "7.2.*",
"ext-json": "*",
"doctrine/orm": "2.6.3",
"php-di/slim-bridge": "^2.0"
"php-di/slim-bridge": "^2.0",
"webonyx/graphql-php": "^0.13.1"
},
"require-dev": {
"roave/security-advisories": "dev-master",
Expand Down
52 changes: 52 additions & 0 deletions be/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion fe/bsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
"@glennsl/bs-json",
"@ahrefs/bs-reactstrap",
"@ahrefs/bs-recharts",
"reason-react-document-title"
"reason-react-document-title",
"reason-apollo"
],
"ppx-flags": [
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[pytanie] Cóż to?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sam tego dobrze nie obczajam ale ppx pozwala na wprowadzenie swojej składni która się kompiluje do czegoś (jakiegoś modułu czy coś takiego). Żeby można było używać jakieś zewnętrzene ppxy to trzeba to tutaj zadeklarować. To co tutaj używam to graphql_ppx - czyli daje on możliwość używania składni graphqla - wymaga go reason-apollo aby działał.
Ogólnie o ppx'ach: https://blog.hackages.io/reasonml-ppx-8ecd663d5640

"graphql_ppx/ppx"
],
"refmt": 3
}
Loading