PageRenderTime 2ms CodeModel.GetById 20ms app.highlight 6ms RepoModel.GetById 19ms app.codeStats 0ms

/DuckDuckGo/API.php

http://github.com/duckduckgo/php5-duckduckgo
PHP | 163 lines | 81 code | 31 blank | 51 comment | 8 complexity | b13b6f6e51df4c900e5d5134b89da281 MD5 | raw file
  1<?php
  2
  3/**
  4 * @file DuckDuckGo/API.php
  5 * This file provides the base class to interface with the DuckDuckGo API.
  6 * It will also include any necessary classes.
  7 * With this interface, you can currently only perform ZeroClickInfo queries.
  8 * Simple example:
  9 *     $api = new DuckDuckGo\API();
 10 *     $info = $api->zeroClickQuery('Internet Relay Chat');
 11 *     echo $info->definition;
 12 */
 13
 14namespace DuckDuckGo;
 15
 16/* Include the necessary classes. */
 17require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'APIResult.php';
 18require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ZeroClickInfo.php';
 19
 20class API
 21{
 22
 23    /* General API options and flags. */
 24
 25    /**
 26     * The API base URL. This defaults to api.duckduckgo.com.
 27     */
 28    public $baseURL;
 29    /**
 30     * Whether to use HTTPS or not. This defaults to FALSE (no HTTPS).
 31     */
 32    public $secure;
 33    /**
 34     * Whether to disallow HTML in the result. This defaults to FALSE (don't disallow HTML).
 35     */
 36    public $noHTML;
 37
 38    /**
 39     * Query-specific flags
 40     */
 41
 42    /**
 43     * Whether or not to return Disambiguation (D) results (ZeroClickInfo).
 44     * Defaults to FALSE (allow disambiguation results).
 45     */
 46    public $noDisambiguations;
 47
 48
 49    /* Constructors and internal functions. */
 50
 51    /**
 52     * Constructor.
 53     */
 54    public function __construct()
 55    {
 56        $this->secure = FALSE;
 57        $this->noHTML = FALSE;
 58        $this->noDisambiguations = FALSE;
 59        $this->baseURL = 'api.duckduckgo.com';
 60    }
 61
 62    /**
 63     * Construct an API URL, given a section and an associative options array.
 64     * @param section   Which part of the API to call.
 65     * @param options   An associative array containing options to pass in key => value form.
 66     * @return          The API URL that corresponds with this query, which then can be retrieved in order to get the query results.
 67     */
 68    protected function constructURL($section, $options)
 69    {
 70        $url = '';
 71        if($this->secure) {
 72            $url .= 'https://' . $this->baseURL;
 73        } else {
 74            $url .= 'http://' . $this->baseURL;
 75        }
 76        $url .= $section;
 77
 78        if(count($options) > 0) {
 79            $url .= '?' . \urlencode(\current(\array_keys($options))) . '=' . \urlencode(\array_shift($options));
 80
 81            foreach($options as $name => $value) {
 82                $url .= '&' . \urlencode($name) . '=' . \urlencode($value);
 83            }
 84        }
 85
 86        return $url;
 87    }
 88
 89    /**
 90     * Given an API section and query options, queries the API and returns the raw results.
 91     * @param section   Which part of the API to call.
 92     * @param options   An associative array containing options to pass in key => value form.
 93     * @return          The raw results of the API call.
 94     */
 95    protected function getAPIResult($section, $options)
 96    {
 97        $url = $this->constructURL($section, $options);
 98
 99        if(\extension_loaded('curl')) {
100            $curl = \curl_init($url);
101            \curl_setopt($curl, CURLOPT_HEADER, FALSE);
102            \curl_setopt($curl, CURLOPT_FOLLOWLOCATION, FALSE);
103            \curl_setopt($curl, CURLOPT_FRESH_CONNECT, TRUE);
104            \curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
105
106            $result = \curl_exec($curl);
107            \curl_close($curl);
108
109            return $result;
110        }
111
112        if(\function_exists('http_get') && \function_exists('http_parse_message')) {
113            $options = array(
114                'redirect' => 0,
115            );
116
117            return \http_parse_message(\http_get($url), $options)->body;
118        }
119
120        if(\ini_get('allow_url_fopen')) {
121            $context = \stream_context_create(array(
122                'http' => array(
123                    'follow_location' => 0,
124                )
125            ));
126
127            $handle = \fopen($url, 'r', FALSE, $context);
128            $result = \stream_get_contents($handle);
129            \fclose($handle);
130
131            return $result;
132        }
133
134        throw new Exception('Could not find suitable method to retrieve API result. Either install the cURL or pear_http extension, or set allow_url_fopen to 1.');
135    }
136
137
138    /* API functions. */
139
140    /**
141     * Perform a ZeroClickInfo query against the DuckDuckGo API.
142     * @param query     The term to query for.
143     * @return          A ZeroClickInfo object containing the results of the query.
144     * @see ZeroClickInfo
145     */
146    public function zeroClickQuery($query)
147    {
148        $result = $this->getAPIResult('/', array(
149            'q' => $query,
150            'format' => 'json',
151            'no_html' => ($this->noHTML ? 1 : 0),
152            'no_redirect' => 1,
153            'skip_disambig' => ($this->noDisambiguations ? 1 : 0),
154        ));
155
156        if(!$result) {
157            throw new Exception('Could not retrieve API result.');
158        }
159
160        return new ZeroClickInfo(\json_decode($result, TRUE));
161    }
162
163}