Passed
Branch master (f320c5)
by Xavier
01:33
created

ApiDataFetcher   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 13
dl 0
loc 116
rs 10
c 0
b 0
f 0
ccs 27
cts 27
cp 1

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getErrors() 0 3 1
A fetchComplementaryData() 0 15 4
A getData() 0 10 2
A instantiateResource() 0 3 1
A __construct() 0 5 1
A getPromises() 0 12 2
A getResourceAtIndex() 0 3 1
A fetch() 0 13 1
1
<?php
2
3
namespace PubPeerFoundation\PublicationDataExtractor;
4
5
use Generator;
6
use Tightenco\Collect\Support\Arr;
7
use GuzzleHttp\Promise\EachPromise;
8
use Psr\Http\Message\ResponseInterface;
9
use GuzzleHttp\Exception\RequestException;
10
use GrahamCampbell\GuzzleFactory\GuzzleFactory;
11
use PubPeerFoundation\PublicationDataExtractor\Resources\Resource;
12
use PubPeerFoundation\PublicationDataExtractor\Identifiers\Identifier;
13
14
class ApiDataFetcher
15
{
16
    protected $identifier;
17
18
    protected $client;
19
20
    protected $apiData;
21
22
    protected $resources = [];
23 3
24
    protected $resourcesToFetch = [];
25 3
26 3
    protected $errors = [];
27 3
28
    public function __construct(Identifier $identifier)
29
    {
30
        $this->identifier = $identifier;
31
        $this->resourcesToFetch = $identifier->getRelatedResources();
32 3
        $this->client = GuzzleFactory::make(compact('headers'), 100);
33
    }
34 3
35 3
    /**
36 3
     * Fetch data from API calls promises.
37 3
     */
38 3
    public function fetch(): void
39 3
    {
40 3
        (new EachPromise($this->getPromises(), [
41 3
            'concurrency' => 5,
42 3
            'fulfilled' => function (ResponseInterface $response, $index) {
43
                $this->apiData[] = $this->getResourceAtIndex($index)
44
                    ->getDataFrom((string) $response->getBody());
45
            },
46
            'rejected' => function (RequestException $exception, $index) {
47
                $resourceName = get_class_name($this->getResourceAtIndex($index));
48
                $this->errors[$resourceName] = $exception->getCode();
49 3
            },
50
        ]))->promise()->wait();
51 3
    }
52 3
53
    /**
54 3
     * Get list of API calls promises.
55 3
     *
56 3
     * @return Generator
57 3
     */
58
    protected function getPromises(): Generator
59
    {
60 3
        foreach ($this->resourcesToFetch as $resourceClass) {
61
            $resource = $this->instantiateResource($resourceClass);
62 3
63
            $promise = $this->client->requestAsync(
64
                'GET',
65
                $resource->getApiUrl(),
66
                $resource->getRequestOptions()
67
            );
68
69
            yield $promise;
70
        }
71 3
    }
72
73 3
    public function getData(): array
74
    {
75
        if (0 === count(array_filter(Arr::pluck($this->apiData, 'publication')))) {
76
            return [];
77
        }
78
79
        $this->fetchComplementaryData();
80
81
        return array_values(
82
            array_filter($this->apiData)
83 3
        );
84
    }
85 3
86
    public function getErrors(): array
87
    {
88
        return $this->errors;
89
    }
90
91
    /**
92
     * Get resource instance from resources array.
93
     *
94
     * @param int $index
95
     *
96
     * @return resource
97
     */
98
    protected function getResourceAtIndex(int $index): Resource
99
    {
100
        return $this->resources[$index];
101
    }
102
103
    /**
104
     * Create and store an instance of the Resource class.
105
     *
106
     * @param string $resourceClass
107
     *
108
     * @return resource
109
     */
110
    protected function instantiateResource($resourceClass): Resource
111
    {
112
        return $this->resources[] = new $resourceClass($this->identifier);
113
    }
114
115
    protected function fetchComplementaryData()
116
    {
117
        $flatIdentifiers = Arr::flatten(Arr::pluck($this->apiData, 'identifiers'));
118
119
        foreach ($this->identifier->getComplementaryResources() as $key => $value) {
120
            if (false !== $valueKey = array_search($key, $flatIdentifiers)) {
121
                try {
122
                    $this->identifier = (new IdentifierResolver($flatIdentifiers[$valueKey - 1]))->handle();
123
124
                    $this->resourcesToFetch = [$value];
125
                    $this->resources = [];
126
127
                    $this->fetch();
128
                } catch (Exceptions\UnknownIdentifierException $e) {
129
                    var_dump('an error occured');
0 ignored issues
show
Security Debugging Code introduced by
var_dump('an error occured') looks like debug code. Are you sure you do not want to remove it?
Loading history...
130
                }
131
            }
132
        }
133
    }
134
}
135