Completed
Push — master ( 58e1a3...56d6f2 )
by Maik
01:20
created

JsonProvider::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
namespace Nkey\DDG\API;
3
4
use Generics\Client\HttpClient;
5
use Generics\Socket\Url;
6
use Exception;
7
use Psr\Log\LoggerAwareInterface;
8
use Psr\Log\LoggerInterface;
9
use Psr\Log\NullLogger;
10
11
/**
12
 * This class provides means of fetching data from duckduckgo api
13
 *
14
 * @author Maik Greubel <[email protected]>
15
 * @license Apache 2.0
16
 */
17
class JsonProvider implements LoggerAwareInterface
18
{
19
    /**
20
     * Logger instance
21
     * 
22
     * @var LoggerInterface
23
     */
24
    private $logger;
25
    
26
    /**
27
     * Timeout in seconds
28
     *
29
     * @var int
30
     */
31
    private $timeout = 5;
32
33
    /**
34
     *
35
     * @var HttpClient
36
     */
37
    private $httpClient;
38
    
39 4
    public function __construct()
40
    {
41 4
        $this->logger = new NullLogger();
42 4
    }
43
44
    /**
45
     * Set timeout in seconds
46
     *
47
     * @param int $timeout
48
     */
49
    public function setTimeout(int $timeout)
50
    {
51
        $this->timeout = $timeout;
52
    }
53
54
    /**
55
     * Query the duck duck go api
56
     *
57
     * @param string $query
58
     *            Keywords to start a query for
59
     * @throws ApiException
60
     * @return string The payload
61
     */
62 3
    public function query(string $query): string
63
    {
64
        try {
65
            
66 3
            $this->httpClient = new HttpClient($this->provideUrl($query));
67 3
            $this->httpClient->setTimeout($this->timeout);
68 3
            $this->httpClient->setHeader('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36');
69 3
            $this->httpClient->setHeader('Accept-Encoding', 'identity'); // Currently there is a bug in HttpClient for passing buf to gzdecode()
70 3
            $this->httpClient->setHeader('Connection', 'close');
71 3
            $this->httpClient->request('GET');
72 3
            $response = "";
73
            
74 3
            while ($this->httpClient->getPayload()->ready()) {
75 3
                $response .= $this->httpClient->getPayload()->read($this->httpClient->getPayload()
76 3
                    ->count());
77
            }
78
            
79 3
            $response = strstr($response, "{");
80 3
            $response = substr($response, 0, strrpos($response, "}") + 1);
81 3
            return $response;
82
        } catch (Exception $ex) {
83
            $this->logger->error($ex->getMessage());
84
            $this->logger->debug($ex->getTraceAsString());
85
            throw new ApiException("Could not retrieve query response: {cause}", array(
86
                'cause' => $ex->getMessage()
87
            ), $ex->getCode(), $ex);
88
        }
89
    }
90
91
    /**
92
     * Provide an URL object out of given duckduckgo query
93
     *
94
     * @param string $query
95
     * @return Url
96
     */
97 3
    private function provideUrl(string $query): Url
98
    {
99 3
        $url = new Url(sprintf("http://api.duckduckgo.com/?q=%s&format=json", urlencode($query)));
100
        
101 3
        return $url;
102
    }
103
    
104
    /**
105
     * Set the logger
106
     * @param LoggerInterface $logger
107
     */
108 4
    public function setLogger(LoggerInterface $logger)
109
    {
110 4
        $this->logger = $logger;
111 4
    }
112
113
}
114