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

ApiDataFetcher::fetchComplementaryData()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.2
c 0
b 0
f 0
ccs 0
cts 0
cp 0
cc 4
eloc 10
nc 5
nop 0
crap 20
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