Completed
Push — master ( 13652a...28f145 )
by Sven
08:03
created

Http::applyResult()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 15
ccs 0
cts 11
cp 0
rs 9.4285
cc 3
eloc 8
nc 3
nop 2
crap 12
1
<?php
2
3
namespace LegalThings\DataEnricher\Processor;
4
5
use LegalThings\DataEnricher\Node;
6
use LegalThings\DataEnricher\Processor;
7
use GuzzleHttp\Client;
8
use GuzzleHttp\Psr7\Response;
9
10
/**
11
 * Load an external source
12
 */
13
class Http implements Processor
14
{
15
    use Processor\Implementation;
16
    
17
    /**
18
     * Get the URL from a node
19
     * 
20
     * @param Node $node
21
     * @return string
22
     */
23
    protected function getUrl($node)
24
    {
25
        $url = $node->getInstruction($this);
26
        
27
        $type = (is_object($url) ? get_class($url) . ' ' : '') . gettype($url);
28
        if (!assert(is_string($url), "Expected '{$this->property}' to be a string, but got a $type")) {
29
            return null;
30
        }
31
        
32
        return $url;
33
    }
34
    
35
    /**
36
     * Do async request for node
37
     * 
38
     * @param Node $node
39
     */
40
    public function applyToNode(Node $node)
41
    {
42
        $url = $this->getUrl($node);
43
        if (!isset($url)) {
44
            return;
45
        }
46
47
        $client = new Client(['http_errors' => false]);
48
        $promise = $client->getAsync($url)->then(function (Response $response) use ($node) {
49
            $this->applyResult($node, $response);
50
        });
51
        
52
        $node->setResult($promise);
53
    }
54
    
55
    /**
56
     * Apply results to a node
57
     * 
58
     * @param Node     $node
59
     * @param Response $response
60
     */
61
    protected function applyResult(Node $node, Response $response)
62
    {
63
        $result = null;
64
        
65
        if ($this->hasExpectedResponse($node, $response)) {
66
            $result = json_decode($response->getBody());
67
68
            if (!$result) {
69
                $url = $this->getUrl($node);
70
                trigger_error("Failed to fetch '$url': Corrupt JSON response", E_USER_WARNING);
71
            }
72
        }
73
74
        $node->setResult($result);
75
    }
76
    
77
    /**
78
     * Check if we got an expected response
79
     * 
80
     * @param Node     $node
81
     * @param Response $response
82
     * @return boolean
83
     */
84
    protected function hasExpectedResponse(Node $node, Response $response)
85
    {
86
        $status = $response->getStatusCode();
87
        $contentType = preg_replace('/\s*;.*$/', '', $response->getHeaderLine('Content-Type'));
88
89
        if ($status == 404) {
90
            return false;
91
        } elseif ($status >= 300 || !in_array($contentType, ['application/json', 'text/plain'])) {
92
            $url = $this->getUrl($node);
93
            
94
            if ($contentType === 'text/plain') {
95
                $message = $response->getBody();
96
            } else {
97
                $message = "Server responded with a $status status and $contentType";
98
            }
99
            
100
            trigger_error("Failed to fetch '$url': $message", E_USER_WARNING);
101
            return false;
102
        }
103
        
104
        return true;
105
    }
106
}
107