/DuckDuckGo/API.php
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}