Passed
Push — claude/understand-crawl-pLOr9 ( dfbc4e...041f51 )
by Akihito
03:39 queued 01:48
created

DataLoaderProcessor   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 21
c 1
b 0
f 0
dl 0
loc 69
rs 10
wmc 11

3 Methods

Rating   Name   Duplication   Size   Complexity  
B process() 0 33 8
A __construct() 0 3 1
A getDataLoader() 0 7 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource\DataLoader;
6
7
use BEAR\Resource\Annotation\Link;
8
use BEAR\Resource\LinkType;
9
use BEAR\Resource\Types;
10
11
use function array_values;
12
use function uri_template;
13
14
/**
15
 * Processes DataLoader-enabled links in batch
16
 *
17
 * @psalm-import-type Query from Types
18
 * @psalm-import-type QueryList from Types
19
 * @psalm-import-type ObjectList from Types
20
 */
21
final class DataLoaderProcessor
22
{
23
    /** @var array<class-string<DataLoaderInterface>, DataLoaderInterface> */
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<class-string<DataL...>, DataLoaderInterface> at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in array<class-string<DataLoaderInterface>, DataLoaderInterface>.
Loading history...
24
    private array $cache = [];
25
26
    public function __construct(
27
        private readonly DataLoaderFactoryInterface $factory,
28
    ) {
29
    }
30
31
    /**
32
     * Process DataLoader-enabled links
33
     *
34
     * @param ObjectList $annotations
0 ignored issues
show
Bug introduced by
The type BEAR\Resource\DataLoader\ObjectList was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
35
     * @param QueryList  $bodyList
0 ignored issues
show
Bug introduced by
The type BEAR\Resource\DataLoader\QueryList was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
36
     *
37
     * @param-out QueryList $bodyList
38
     *
39
     * @psalm-suppress ReferenceConstraintViolation
40
     */
41
    public function process(array $annotations, LinkType $link, array &$bodyList): void
42
    {
43
        // Group URIs by DataLoader class
44
        /** @var array<class-string<DataLoaderInterface>, array{annotation: Link, uris: array<int, string>}> $loaderGroups */
45
        $loaderGroups = [];
46
47
        foreach ($annotations as $annotation) {
48
            if (! $annotation instanceof Link || $annotation->crawl !== $link->key) {
49
                continue;
50
            }
51
52
            if ($annotation->dataLoader === null) {
53
                continue;
54
            }
55
56
            $loaderClass = $annotation->dataLoader;
57
            $loaderGroups[$loaderClass] = ['annotation' => $annotation, 'uris' => []];
58
59
            foreach ($bodyList as $index => $body) {
60
                $uri = uri_template($annotation->href, $body);
61
                $loaderGroups[$loaderClass]['uris'][$index] = $uri;
62
            }
63
        }
64
65
        // Execute DataLoaders and distribute results
66
        foreach ($loaderGroups as $loaderClass => $group) {
67
            $loader = $this->getDataLoader($loaderClass);
68
            $requests = new Requests(array_values($group['uris']));
69
            $results = $loader($requests);
70
71
            foreach ($group['uris'] as $index => $uri) {
72
                /** @psalm-suppress MixedAssignment -- Results::get() returns mixed by design */
73
                $bodyList[$index][$group['annotation']->rel] = $results->get($uri);
74
            }
75
        }
76
    }
77
78
    /**
79
     * Get or create a DataLoader instance
80
     *
81
     * @param class-string<DataLoaderInterface> $class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<DataLoaderInterface> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<DataLoaderInterface>.
Loading history...
82
     */
83
    private function getDataLoader(string $class): DataLoaderInterface
84
    {
85
        if (! isset($this->cache[$class])) {
86
            $this->cache[$class] = $this->factory->create($class);
87
        }
88
89
        return $this->cache[$class];
90
    }
91
}
92