Completed
Push — master ( 56d6f2...6d3dfb )
by Maik
02:24
created

JsonProvider   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 103
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 74.29%

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 6
dl 0
loc 103
ccs 26
cts 35
cp 0.7429
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setTimeout() 0 4 1
B query() 0 24 3
A createHttpClient() 0 8 1
A provideUrl() 0 6 1
A setLogger() 0 4 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
    /**
21
     * Logger instance
22
     *
23
     * @var LoggerInterface
24
     */
25
    private $logger;
26
27
    /**
28
     * Timeout in seconds
29
     *
30
     * @var int
31
     */
32
    private $timeout = 5;
33
34
    /**
35
     *
36
     * @var HttpClient
37
     */
38
    private $httpClient;
39
40 4
    public function __construct()
41
    {
42 4
        $this->logger = new NullLogger();
43 4
    }
44
45
    /**
46
     * Set timeout in seconds
47
     *
48
     * @param int $timeout
49
     */
50
    public function setTimeout(int $timeout)
51
    {
52
        $this->timeout = $timeout;
53
    }
54
55
    /**
56
     * Query the duck duck go api
57
     *
58
     * @param string $query
59
     *            Keywords to start a query for
60
     * @throws ApiException
61
     * @return string The payload
62
     */
63 3
    public function query(string $query): string
64
    {
65
        try {
66 3
            $this->createHttpClient($query);
67
            
68 3
            $response = "";
69 3
            $this->httpClient->request('GET');
70
            
71 3
            while ($this->httpClient->getPayload()->ready()) {
72 3
                $response .= $this->httpClient->getPayload()->read($this->httpClient->getPayload()
73 3
                    ->count());
74
            }
75
            
76 3
            $response = strstr($response, "{");
77 3
            $response = substr($response, 0, strrpos($response, "}") + 1);
78 3
            return $response;
79
        } catch (Exception $ex) {
80
            $this->logger->error($ex->getMessage());
81
            $this->logger->debug($ex->getTraceAsString());
82
            throw new ApiException("Could not retrieve query response: {cause}", array(
83
                'cause' => $ex->getMessage()
84
            ), $ex->getCode(), $ex);
85
        }
86
    }
87
88 3
    private function createHttpClient(string $query)
89
    {
90 3
        $this->httpClient = new HttpClient($this->provideUrl($query));
91 3
        $this->httpClient->setTimeout($this->timeout);
92 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');
93 3
        $this->httpClient->setHeader('Accept-Encoding', 'identity'); // Currently there is a bug in HttpClient for passing buf to gzdecode()
94 3
        $this->httpClient->setHeader('Connection', 'close');
95 3
    }
96
97
    /**
98
     * Provide an URL object out of given duckduckgo query
99
     *
100
     * @param string $query
101
     * @return Url
102
     */
103 3
    private function provideUrl(string $query): Url
104
    {
105 3
        $url = new Url(sprintf("http://api.duckduckgo.com/?q=%s&format=json", urlencode($query)));
106
        
107 3
        return $url;
108
    }
109
110
    /**
111
     * Set the logger
112
     * 
113
     * @param LoggerInterface $logger
114
     */
115 4
    public function setLogger(LoggerInterface $logger)
116
    {
117 4
        $this->logger = $logger;
118 4
    }
119
}
120