FieldResolver   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 50
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 19
dl 0
loc 50
rs 10
c 2
b 0
f 0
wmc 5

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __invoke() 0 36 4
A __construct() 0 2 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApiSkeletons\Doctrine\GraphQL\Resolve;
6
7
use ApiSkeletons\Doctrine\GraphQL\Config;
8
use ApiSkeletons\Doctrine\GraphQL\Type\Entity;
9
use ApiSkeletons\Doctrine\GraphQL\Type\TypeManager;
10
use Doctrine\Common\Util\ClassUtils;
11
use GraphQL\Error\Error;
12
use GraphQL\Type\Definition\ResolveInfo;
13
14
use function assert;
15
use function is_object;
16
use function spl_object_hash;
17
18
/**
19
 * A field resolver that uses the Doctrine Laminas hydrator.
20
 */
21
class FieldResolver
22
{
23
    /**
24
     * Cache all hydrator extract operations based on spl object hash
25
     *
26
     * @var mixed[]
27
     */
28
    private array $extractValues = [];
29
30
    public function __construct(protected Config $config, protected TypeManager $typeManager)
31
    {
32
    }
33
34
    /** @throws Error */
35
    public function __invoke(mixed $source, mixed $args, mixed $context, ResolveInfo $info): mixed
36
    {
37
        assert(is_object($source), 'A non-object was passed to the FieldResolver.  '
38
            . 'Verify you\'re wrapping your Doctrine GraohQL type() call in a connection.');
39
40
        $entityClass   = ClassUtils::getRealClass($source::class);
41
        $splObjectHash = spl_object_hash($source);
42
43
        /**
44
         * For disabled hydrator cache, store only last hydrator result and reuse for consecutive calls
45
         * then drop the cache if it doesn't hit.
46
         */
47
        if (! $this->config->getUseHydratorCache()) {
48
            if (isset($this->extractValues[$splObjectHash])) {
49
                return $this->extractValues[$splObjectHash][$info->fieldName] ?? null;
50
            }
51
52
            $this->extractValues = [];
53
54
            $this->extractValues[$splObjectHash] = $this->typeManager
55
                ->build(Entity::class, $entityClass)
56
                    ->getHydrator()->extract($source);
57
58
            return $this->extractValues[$splObjectHash][$info->fieldName] ?? null;
59
        }
60
61
        // Use full hydrator cache
62
        if (isset($this->extractValues[$splObjectHash][$info->fieldName])) {
63
            return $this->extractValues[$splObjectHash][$info->fieldName] ?? null;
64
        }
65
66
        $this->extractValues[$splObjectHash] = $this->typeManager
67
            ->build(Entity::class, $entityClass)
68
            ->getHydrator()->extract($source);
69
70
        return $this->extractValues[$splObjectHash][$info->fieldName] ?? null;
71
    }
72
}
73