├── composer.json ├── LICENSE ├── README.md └── src └── GoogleCustomSearch.php /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "imarc/google-site-search", 3 | "type": "library", 4 | "description": "A PHP Interface to the Google Custom Search API", 5 | "keywords": ["google", "search"], 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Jeff Turcotte", 10 | "email": "jeff@imarc.net" 11 | }, 12 | { 13 | "name": "Dan Collins", 14 | "email": "dan@imarc.net" 15 | } 16 | ], 17 | "require": { 18 | "php": ">=5.4.0" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "iMarc\\": "src/" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 iMarc LLC 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Google Custom Search 2 | ================== 3 | 4 | A PHP interface to the Google Custom Search JSON API. The JSON API allows for [free](https://cse.google.com/cse) and [paid](https://www.google.com/work/search/products/gss.html) users to take advantage of adding Google search results to your website. 5 | 6 | Google's documentation for the Custom Search JSON API can be found here: 7 | https://developers.google.com/custom-search/json-api/v1/overview 8 | 9 | Credentials 10 | ----- 11 | 12 | **Search Engine ID** - On the [Custom Search Engine Control Panel](http://www.google.com/cse/manage/all), create a new search engine for the site you would like to integrate. Once created, you can retrieve your Search Engine ID from the *Setup* tab. 13 | 14 | **API Key** - If you're using the free option, visit the [Google Developers Console](https://console.developers.google.com) and create a project for your search engine. Within your project, you’ll need to enable the *Custom Search API* from the *APIs* tab. Finally, on the *Credentials* tab, you will need to create a Public API access key by selecting the *Create new Key* option and choosing *Server key*. The API Key will now be available. 15 | 16 | If you're using a paid option, you can find your API key in the [Control Panel](http://www.google.com/cse/manage/all) in the *Business > XML & JSON* tab. 17 | 18 | Usage 19 | ----- 20 | 21 | ```(php) 22 | $search = new iMarc\GoogleCustomSearch(SEARCH_ENGINE_ID, API_KEY); 23 | $results = $search->search('Apples'); 24 | ``` -------------------------------------------------------------------------------- /src/GoogleCustomSearch.php: -------------------------------------------------------------------------------- 1 | search('Apples'); 16 | * 17 | * @copyright iMarc LLC 2015 18 | * @author Jeff Turcotte 19 | * @author Dan Collins 20 | * @version 2.0.0 21 | * 22 | * @license MIT 23 | **/ 24 | class GoogleCustomSearch 25 | { 26 | /** 27 | * Google Search Engine ID 28 | * 29 | * @var string 30 | **/ 31 | protected $search_engine_id; 32 | 33 | /** 34 | * Google API Key 35 | * 36 | * @var string 37 | **/ 38 | protected $api_key; 39 | 40 | /** 41 | * Constructor 42 | * 43 | * @param string search_engine_id Search Engine ID 44 | * @param string api_key API Key 45 | * @return void 46 | **/ 47 | public function __construct($search_engine_id, $api_key) 48 | { 49 | $this->search_engine_id = $search_engine_id; 50 | $this->api_key = $api_key; 51 | } 52 | 53 | /** 54 | * Sends search request to Google 55 | * 56 | * @param array params The parameters of the search request 57 | * @return object The raw results of the search request 58 | **/ 59 | private function request($params) 60 | { 61 | $params = array_merge( 62 | $params, 63 | [ 64 | 'key' => $this->api_key, 65 | 'cx' => $this->search_engine_id 66 | ] 67 | ); 68 | 69 | // disable peer verification 70 | $context = stream_context_create([ 71 | 'http' => [ 72 | 'ignore_errors' => true 73 | ], 74 | 'ssl' => [ 75 | 'verify_peer' => false, 76 | 'verify_peer_name' => false, 77 | ] 78 | ]); 79 | 80 | // use cURL if avaible, otherwise fallback to file_get_contents 81 | if (function_exists('curl_version')) { 82 | $response = $this->getSslPage('https://www.googleapis.com/customsearch/v1?' . http_build_query($params)); 83 | } else { 84 | $response = file_get_contents('https://www.googleapis.com/customsearch/v1?' . http_build_query($params), false, $context); 85 | } 86 | 87 | return json_decode($response); 88 | } 89 | 90 | /** 91 | * Perform search 92 | * 93 | * Returns an object with the following properties: 94 | * 95 | * page 96 | * perPage 97 | * start 98 | * end 99 | * totalResults 100 | * results 101 | * title 102 | * snippet 103 | * htmlSnippet 104 | * link 105 | * image 106 | * thumbnail 107 | * 108 | * @param string terms The search terms 109 | * @param integer page The page to return 110 | * @param integer per_page How many results to dispaly per page 111 | * @param array extra Extra parameters to pass to Google 112 | * @return object The results of the search 113 | * @throws Exception If error is returned from Google 114 | **/ 115 | public function search($terms, $page=1, $per_page=10, $extra=[]) 116 | { 117 | // Google only allows 10 results at a time 118 | $per_page = ($per_page > 10) ? 10 : $per_page; 119 | 120 | $params = [ 121 | 'q' => $terms, 122 | 'start' => (($page - 1) * $per_page) + 1, 123 | 'num' => $per_page 124 | ]; 125 | if (sizeof($extra)) { 126 | $params = array_merge($params, $extra); 127 | } 128 | 129 | $response = $this->request($params); 130 | 131 | if (isset($response->error)) { 132 | throw new \Exception($response->error->message); 133 | } 134 | 135 | $request_info = $response->queries->request[0]; 136 | 137 | $results = new \stdClass(); 138 | $results->page = $page; 139 | $results->perPage = $per_page; 140 | $results->start = $request_info->startIndex; 141 | $results->end = ($request_info->startIndex + $request_info->count) - 1; 142 | $results->totalResults = $request_info->totalResults; 143 | $results->results = []; 144 | 145 | if (isset($response->items)) { 146 | foreach ($response->items as $result) { 147 | $results->results[] = (object) [ 148 | 'title' => $result->title, 149 | 'snippet' => $result->snippet, 150 | 'htmlSnippet' => $result->htmlSnippet, 151 | 'link' => $result->link, 152 | 'image' => isset($result->pagemap->cse_image) ? $result->pagemap->cse_image[0]->src : '', 153 | 'thumbnail' => isset($result->pagemap->cse_thumbnail) ? $result->pagemap->cse_thumbnail[0]->src : '', 154 | ]; 155 | } 156 | } 157 | 158 | return $results; 159 | } 160 | 161 | /** 162 | * Allow call to api under https using cURL - replacement function for file_get_contents 163 | * By setting CURLOPT_RETURNTRANSFER to true we're able to fetch the results via cURL 164 | * @param string $url 165 | * @return Object $results 166 | */ 167 | public function getSslPage($url) { 168 | $ch = curl_init(); 169 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 170 | curl_setopt($ch, CURLOPT_HEADER, false); 171 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 172 | curl_setopt($ch, CURLOPT_URL, $url); 173 | curl_setopt($ch, CURLOPT_REFERER, $url); 174 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 175 | $result = curl_exec($ch); 176 | curl_close($ch); 177 | return $result; 178 | } 179 | } 180 | --------------------------------------------------------------------------------