FieldResolver::__invoke()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 38
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

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