Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ jobs:
run: vendor/bin/psalm

- name: PHPStan
run: vendor/bin/phpstan analyze src --level=5
run: vendor/bin/phpstan analyze src --level=8
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ GraphQL Type Driver for Doctrine ORM

[![Build Status](https://github.com/API-Skeletons/doctrine-orm-graphql/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/API-Skeletons/doctrine-orm-graphql/actions/workflows/continuous-integration.yml?query=branch%3Amain)
[![Code Coverage](https://codecov.io/gh/API-Skeletons/doctrine-orm-graphql/branch/main/graphs/badge.svg)](https://codecov.io/gh/API-Skeletons/doctrine-orm-graphql/branch/main)
[![PHPStan](https://img.shields.io/badge/PHPStan-level%205-brightgreen.svg)](https://img.shields.io/badge/PHPStan-level%205-brightgreen.svg)
[![psalm](https://img.shields.io/badge/psalm-level%204-brightgreen.svg)](https://img.shields.io/badge/psalm-level%204-brightgreen.svg)
[![PHPStan](https://img.shields.io/badge/PHPStan-level%208-brightgreen.svg)](https://img.shields.io/badge/PHPStan-level%208-brightgreen.svg)
[![psalm](https://img.shields.io/badge/psalm-level%201-brightgreen.svg)](https://img.shields.io/badge/psalm-level%201-brightgreen.svg)
[![License](https://poser.pugx.org/api-skeletons/doctrine-orm-graphql/license)](//packagist.org/packages/api-skeletons/doctrine-orm-graphql)

GraphQL, with types so neat,
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"vendor/bin/parallel-lint ./src/ ./test",
"vendor/bin/phpcs",
"vendor/bin/psalm",
"vendor/bin/phpstan analyze src --level=5",
"vendor/bin/phpstan analyze src --level=8",
"vendor/bin/phpunit"
],
"coverage": "XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html=coverage-report"
Expand Down
2 changes: 1 addition & 1 deletion psalm.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<psalm
errorLevel="4"
errorLevel="1"
resolveFromConfigFile="true"
findUnusedBaselineEntry="true"
findUnusedCode="false"
Expand Down
6 changes: 5 additions & 1 deletion src/Attribute/ExcludeFilters.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ trait ExcludeFilters
/** @var Filters[] */
private readonly array $excludeFilters;

/** @return Filters[] */
/**
* @return Filters[]
*
* @psalm-suppress MixedReturnTypeCoercion
*/
public function getExcludeFilters(): array
{
$filters = [];
Expand Down
6 changes: 5 additions & 1 deletion src/Cache/QueryResultCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Doctrine\ORM\Query;

use function count;
use function implode;
use function is_array;
use function md5;
use function serialize;

Expand All @@ -23,7 +25,7 @@
* The cache is stored in memory and is automatically cleared after
* the request completes.
*/
class QueryResultCache
final class QueryResultCache
{
/** @var array<string, mixed[]> */
private array $cache = [];
Expand Down Expand Up @@ -118,11 +120,13 @@ public function getStats(): array
private function getCacheKey(Query $query): string
{
$sql = $query->getSQL();
$sql = is_array($sql) ? implode(';', $sql) : $sql;
$parameters = $query->getParameters()->toArray();

// Normalize parameters for consistent cache keys
$normalizedParams = [];
foreach ($parameters as $param) {
/** @psalm-suppress MixedAssignment */
$normalizedParams[$param->getName()] = $param->getValue();
}

Expand Down
3 changes: 2 additions & 1 deletion src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* This class is used for setting parameters when
* creating the driver
*/
class Config
final class Config
{
/**
* @var string The GraphQL group. This allows multiple GraphQL
Expand Down Expand Up @@ -105,6 +105,7 @@ public function __construct(array $config = [])
'excludeFilters' => [],
];

/** @var array{group: string, groupSuffix: string|null, useHydratorCache: bool, useQueryResultCache: bool, limit: int, globalEnable: bool, ignoreFields: string[], globalByValue: bool|null, entityPrefix: string|null, sortFields: bool|null, excludeFilters: Filters[]} $mergedConfig */
$mergedConfig = array_merge($default, $config);

foreach ($mergedConfig as $field => $value) {
Expand Down
2 changes: 1 addition & 1 deletion src/ConfigBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* ->build();
* </code>
*/
class ConfigBuilder
final class ConfigBuilder
{
private string $group = 'default';
private string|null $groupSuffix = null;
Expand Down
6 changes: 4 additions & 2 deletions src/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use ReflectionException;

use function array_keys;
use function array_map;
use function assert;
use function strtolower;

Expand Down Expand Up @@ -41,7 +42,7 @@ public function get(string $id): mixed
$id = strtolower($id);

if (! $this->has($id)) {
$availableTypes = array_keys($this->register);
$availableTypes = array_map('strval', array_keys($this->register));
$suggestion = $this->findSimilarString($originalId, $availableTypes);

throw new TypeNotFoundException(
Expand Down Expand Up @@ -79,7 +80,7 @@ public function set(string $id, mixed $value): self
*/
public function getRegisteredTypes(): array
{
return array_keys($this->register);
return array_map('strval', array_keys($this->register));
}

/**
Expand All @@ -101,6 +102,7 @@ public function build(string $className, string $typeName, mixed ...$params): mi
$reflectionClass = new ReflectionClass($className);
assert($reflectionClass->implementsInterface(Buildable::class));

/** @psalm-suppress MixedMethodCall */
return $this
->set($typeName, new $className($this, $typeName, $params))
->get($typeName);
Expand Down
51 changes: 38 additions & 13 deletions src/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
use GraphQL\Type\Definition\ObjectType;

use function array_merge;
use function assert;

class Driver extends Container
final class Driver extends Container
{
use Services;

Expand All @@ -25,9 +26,13 @@ class Driver extends Container
public function connection(string $id, string|null $eventName = null): ObjectType
{
$objectType = $this->type($id, $eventName);
assert($objectType instanceof ObjectType);

return $this->get(Type\TypeContainer::class)
->build(Type\Connection::class, $objectType->name, $objectType);
$typeContainer = $this->get(Type\TypeContainer::class);
assert($typeContainer instanceof Type\TypeContainer);

/** @psalm-suppress MixedReturnStatement */
return $typeContainer->build(Type\Connection::class, $objectType->name, $objectType);
}

/**
Expand All @@ -38,11 +43,16 @@ public function connection(string $id, string|null $eventName = null): ObjectTyp
public function type(string $id, string|null $eventName = null): mixed
{
$entityTypeContainer = $this->get(Type\Entity\EntityTypeContainer::class);
assert($entityTypeContainer instanceof Type\Entity\EntityTypeContainer);
if ($entityTypeContainer->has($id)) {
return $entityTypeContainer->get($id, $eventName)->getObjectType();
$entity = $entityTypeContainer->get($id, $eventName);
assert($entity instanceof Type\Entity\Entity);

return $entity->getObjectType();
}

$typeContainer = $this->get(Type\TypeContainer::class);
assert($typeContainer instanceof Type\TypeContainer);
if ($typeContainer->has($id)) {
return $typeContainer->get($id);
}
Expand Down Expand Up @@ -70,9 +80,14 @@ public function type(string $id, string|null $eventName = null): mixed
*/
public function filter(string $id): object
{
return $this->get(Filter\FilterFactory::class)->get(
$this->get(Type\Entity\EntityTypeContainer::class)->get($id),
);
$filterFactory = $this->get(Filter\FilterFactory::class);
assert($filterFactory instanceof Filter\FilterFactory);
$entityTypeContainer = $this->get(Type\Entity\EntityTypeContainer::class);
assert($entityTypeContainer instanceof Type\Entity\EntityTypeContainer);
$entity = $entityTypeContainer->get($id);
assert($entity instanceof Type\Entity\Entity);

return $filterFactory->get($entity);
}

/**
Expand All @@ -82,7 +97,10 @@ public function filter(string $id): object
*/
public function pagination(): object
{
return $this->type('pagination');
$result = $this->type('pagination');
assert($result instanceof InputObjectType);

return $result;
}

/**
Expand All @@ -92,10 +110,14 @@ public function pagination(): object
*/
public function resolve(string $id, string|null $eventName = null): Closure
{
return $this->get(Resolve\ResolveEntityFactory::class)->get(
$this->get(Type\Entity\EntityTypeContainer::class)->get($id),
$eventName,
);
$resolveEntityFactory = $this->get(Resolve\ResolveEntityFactory::class);
assert($resolveEntityFactory instanceof Resolve\ResolveEntityFactory);
$entityTypeContainer = $this->get(Type\Entity\EntityTypeContainer::class);
assert($entityTypeContainer instanceof Type\Entity\EntityTypeContainer);
$entity = $entityTypeContainer->get($id);
assert($entity instanceof Type\Entity\Entity);

return $resolveEntityFactory->get($entity, $eventName);
}

/**
Expand All @@ -104,7 +126,10 @@ public function resolve(string $id, string|null $eventName = null): Closure
*/
public function input(string $entityClass, array $requiredFields = [], array $optionalFields = []): InputObjectType
{
return $this->get(Input\InputFactory::class)->get($entityClass, $requiredFields, $optionalFields);
$inputFactory = $this->get(Input\InputFactory::class);
assert($inputFactory instanceof Input\InputFactory);

return $inputFactory->get($entityClass, $requiredFields, $optionalFields);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Event/EntityDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/**
* This event is fired each time an entity GraphQL type is created
*/
class EntityDefinition implements
final class EntityDefinition implements
HasEventName
{
public function __construct(
Expand Down
2 changes: 1 addition & 1 deletion src/Event/Metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/**
* This event is fired when the metadta is created
*/
class Metadata implements
final class Metadata implements
HasEventName
{
public function __construct(
Expand Down
2 changes: 1 addition & 1 deletion src/Event/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/**
* This event is fired when the QueryBuilder is created for an entity
*/
class QueryBuilder implements
final class QueryBuilder implements
HasEventName
{
/** @param mixed[] $args */
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
/**
* Thrown when configuration is invalid
*/
class Configuration extends GraphQL
final class Configuration extends GraphQL
{
/** @param string[] $validOptions */
public function __construct(
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
* Thrown when filter operations fail or are invalid
*/
class Filter extends GraphQL
final class Filter extends GraphQL
{
public function __construct(
string $message,
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/Hydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
* Thrown when hydrator operations fail
*/
class Hydrator extends GraphQL
final class Hydrator extends GraphQL
{
public function __construct(
string $message,
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/Input.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
* Thrown when input validation fails
*/
class Input extends GraphQL
final class Input extends GraphQL
{
public function __construct(
string $message,
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/Metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
* Thrown when entity metadata is invalid or missing
*/
class Metadata extends GraphQL
final class Metadata extends GraphQL
{
public function __construct(
string $message,
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/TypeNotFound.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
/**
* Thrown when a requested GraphQL type or entity type is not registered
*/
class TypeNotFound extends GraphQL
final class TypeNotFound extends GraphQL
{
/** @param string[] $availableTypes */
public function __construct(
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/TypeSerialization.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
* Thrown when a GraphQL scalar type fails to parse or serialize a value
*/
class TypeSerialization extends GraphQL
final class TypeSerialization extends GraphQL
{
public function __construct(
string $message,
Expand Down
Loading
Loading