Skip to content

Commit

Permalink
Merge pull request #11 from inetis-ch/fc_oc3-compatibility
Browse files Browse the repository at this point in the history
OctoberCMS 3 compatibility
  • Loading branch information
Fl0Cri authored Sep 26, 2022
2 parents fdb2779 + 97523cd commit 52ab95b
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 35 deletions.
85 changes: 85 additions & 0 deletions classes/HttpClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php namespace Inetis\GoogleCustomSearch\Classes;

use October\Rain\Network\Http;

/**
* This plugin was originally using October's Http facade to make http requests to the Google API.
* Using it was a bad idea as it was undocumented and it has some caveats (such as no SSL certificates verification).
* With Laravel 9, a Http facade, which is a Guzzle wrapper, with a different interface has now taken the name
* of October's client.
* To maintain backward compatibility with OC 1 (which doesn't feature Guzzle) and not introduce a requirement on some
* http library, here's a very minimalistic http helper based on cURL that allows to make a GET request.
*
* @see Http
*/
class HttpClient
{
public $url;
public $code;
public $requestHeaders = [];
public $requestData = [];
public $responseBody = '';
public $responseRawBody = '';

public static function make($url)
{
$client = new self();
$client->url = $url;

return $client;
}

public function header($name, $value)
{
$this->requestHeaders[$name] = $value;

return $this;
}

public function setData($data)
{
$this->requestData = $data;

return $this;
}

public function send()
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

curl_setopt($curl, CURLOPT_URL, $this->getEncodedUrl());
curl_setopt($curl, CURLOPT_HTTPHEADER, $this->getEncodedRequestHeaders());

$response = $this->responseRawBody = curl_exec($curl);
$this->code = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
$headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$this->responseBody = substr($response, $headerSize);

curl_close($curl);

return $this;
}

public function __toString()
{
return (string) $this->responseBody;
}

private function getEncodedUrl()
{
return $this->url . '?' . http_build_query($this->requestData);
}

private function getEncodedRequestHeaders()
{
$requestHeaders = [];

foreach ($this->requestHeaders as $name => $value) {
$requestHeaders[] = "{$name}: {$value}";
}

return $requestHeaders;
}
}
46 changes: 15 additions & 31 deletions components/SearchResults.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
<?php namespace Inetis\GoogleCustomSearch\Components;

use Cms\Classes\ComponentBase;
use Http;
use Flash;
use Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Inetis\GoogleCustomSearch\Models\Settings;
use Inetis\GoogleCustomSearch\Classes\HttpClient;
use Request;

class SearchResults extends ComponentBase
{

const APIURL = 'https://customsearch.googleapis.com/customsearch/v1';

var $search;
Expand Down Expand Up @@ -81,46 +79,32 @@ public function onRun()
{
Flash::error($response->error->message);
}
elseif ($response->searchInformation->totalResults)
elseif ($totalResults = data_get($response, 'searchInformation.totalResults'))
{
// set the hard limit to all results and pagination
$totalResponseResults = min($this->maxResults, $response->searchInformation->totalResults);
$totalResponseResults = min($this->maxResults, $totalResults);

$this->page['totalResults'] = $totalResponseResults;
$result = new LengthAwarePaginator($response->items, $totalResponseResults, $this->resultPerPage, $this->currentPage);
$result = new LengthAwarePaginator($response->items, $totalResponseResults, $this->resultPerPage, $this->currentPage);
$result->setPath($this->page['baseFileName']);
$result->appends('q', $this->search);
$this->page['results'] = $result;
}
}

/**
* Calculate the API url call
*
* @return string
*/
private function buildAPIUrl()
{

$apiKey = $this->property('apikey');
$cx = $this->property('cx');

$start = min($this->maxResults, ($this->currentPage - 1) * $this->resultPerPage + 1);
$params = array('key' => $apiKey,
'cx' => $cx,
'start' => $start,
'q' => $this->search,
'num' => $this->resultPerPage);

return self::APIURL . '?' . http_build_query($params);
}

private function buildRequest()
{
$http = Http::make($this->buildAPIUrl(), 'GET');
$http = HttpClient::make(self::APIURL);

if ($this->property('sendReferer'))
{
$http->setData([
'key' => $this->property('apikey'),
'cx' => $this->property('cx'),
'start' => min($this->maxResults, ($this->currentPage - 1) * $this->resultPerPage + 1),
'q' => $this->search,
'num' => $this->resultPerPage,
]);

if ($this->property('sendReferer')) {
$http->header('Referer', Request::url());
}

Expand Down
8 changes: 4 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ OctoberCMS plugin to add Google's Custom Search Engine (CSE) Search using the Go

### Search engine ID

When calling the API, the user issues requests against an existing instance of a CSE. Therefore, before using this API you will need to create a CSE in the [CSE Google Control Panel](http://cse.google.com/manage/all). Follow the [tutorial](https://developers.google.com/custom-search/docs/tutorial/creatingcse) to learn more about the different configuration options. Once you have setup a CSE, you can find the CSE's ID in the **Setup > Basics > Details** section of the Control Panel for the CSE.
When calling the API, the user issues requests against an existing instance of a CSE. Therefore, before using this API you will need to create a CSE in the [CSE Google Control Panel](https://programmablesearchengine.google.com/controlpanel/all). Follow the [tutorial](https://developers.google.com/custom-search/docs/tutorial/creatingcse) to learn more about the different configuration options. Once you have setup a CSE, you can find the CSE's ID in the **Setup > Basics > Details** section of the Control Panel for the CSE.

### API key

Expand All @@ -21,9 +21,9 @@ url="/results"
layout="default"
[searchResults]
apiKey=XXXXXXXXXXXXXXXXXXX
apikey=XXXXXXXXXXXXXXXXXXX
cx=1232342342344:xxxxxx
resultsPerPage=20
resultsPerPage=10
sendReferer=true
==
{% component 'searchResults' %}
Expand All @@ -34,7 +34,7 @@ The default template for rendering the results is
{% if results %}
<ul>
{% for result in results %}
<li>
<li>
<h3><a href="{{ result.link }}">{{ result.htmlTitle|raw }}</a></h3>
{{ result.htmlSnippet|raw }}
</li>
Expand Down
2 changes: 2 additions & 0 deletions updates/version.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@
- Add composer.json for October store
1.0.6:
- Remove composer.lock to avoid dependency problems in the future
1.0.7:
- Fix for OctoberCMS 3.0

0 comments on commit 52ab95b

Please sign in to comment.