This repository has been archived by the owner on Jan 10, 2018. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4e81184
commit 96f04a0
Showing
5 changed files
with
283 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
vendor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"name": "vierbergenlars/norch-php-client", | ||
"description": "PHP client for the norch search server", | ||
"require": { | ||
"ext-curl": "*" | ||
}, | ||
"require-dev": { | ||
"vierbergenlars/simpletest": "1.1.2" | ||
}, | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "Lars Vierbergen", | ||
"email": "vierbergenlars@gmail.com" | ||
} | ||
], | ||
"autoload": { | ||
"psr-0": { | ||
"vierbergenlars\\Norch": "lib/" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
<?php | ||
|
||
namespace vierbergenlars\Norch\Transport; | ||
|
||
/** | ||
* HTTP as transport layer for Norch queries | ||
* | ||
* {@inheritDoc} | ||
*/ | ||
class Http implements TransportInterface | ||
{ | ||
/** | ||
* The path to the place where Norch is listening | ||
* @var string | ||
*/ | ||
private $base_path; | ||
|
||
/** | ||
* Creates a new HTTP transport layer | ||
* @param string $base_path The base path of the Norch server | ||
*/ | ||
public function __construct($base_path = 'http://localhost:3000/') | ||
{ | ||
$this->base_path = $base_path; | ||
} | ||
|
||
private static function addPostBody($ch, $fields = array(), $files = array()) | ||
{ | ||
$boundary = '--------------'.uniqid(); | ||
|
||
$data = ''; | ||
|
||
foreach($fields as $name=>$value) { | ||
$data.='--'.$boundary."\r\n"; | ||
$data.='Content-Disposition: form-data; name="'.$name.'"'; | ||
$data.="\r\n\r\n"; | ||
$data.=$value; | ||
$data.="\r\n"; | ||
} | ||
|
||
foreach($files as $name=>$file) { | ||
$data.='--'.$boundary."\r\n"; | ||
$data.='Content-Disposition: form-data; name="'.$name.'"; filename="'.$file['filename'].'"'."\r\n"; | ||
$data.="Content-Type: application/octet-stream\r\n\r\n"; | ||
$data.=$file['data']; | ||
$data.="\r\n"; | ||
} | ||
|
||
$data.='--'.$boundary.'--'."\r\n"; | ||
|
||
curl_setopt($ch, CURLOPT_POST, true); | ||
curl_setopt($ch, CURLOPT_HTTPHEADER, array( | ||
'Content-Type: multipart/form-data; boundary='.$boundary, | ||
'Content-Length: '.strlen($data) | ||
)); | ||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); | ||
} | ||
|
||
/** | ||
* Adds a set of documents to the index | ||
* @param array $documents An array of documents to submit. Each document is an array. The document may not have a key named 'id'. | ||
* @param array $filter Array of fields that can be used for faceted search. Can only contain fields that are arrays in the document. | ||
* @return boolean | ||
* @throws TransportException | ||
*/ | ||
public function indexBatch(array $documents, array $filter) | ||
{ | ||
$json_docs = json_encode($documents); | ||
$docid = uniqid(); | ||
$ch = curl_init($this->base_path.'indexer'); | ||
if(!$ch) | ||
throw new TransportException('Cannot open a cURL session'); | ||
self::addPostBody($ch, array( | ||
'filterOn'=>implode(',', $filter) | ||
), array( | ||
'document'=> array( | ||
'filename'=>$docid.'.json', | ||
'data'=> $json_docs | ||
) | ||
)); | ||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
$reply = curl_exec($ch); | ||
curl_close($ch); | ||
if($reply === 'indexed batch: '.$docid.'.json'."\r\n") | ||
return true; | ||
return false; | ||
} | ||
|
||
/** | ||
* Perform a search query | ||
* | ||
* @param string $query The search query | ||
* @param array $searchFields An array of fields to search in | ||
* @param array $facets An array of fields to facet on | ||
* @param array $filters Limit search to fields with a particular value(s). Each field contains an array of acceptable values. | ||
* @param int $offset The offset to start in the result set | ||
* @param int $pagesize The size of each page | ||
* @param array $weight The weights to give each field. | ||
* @return array Raw json decoded data from the search server | ||
* @throws TransportException | ||
*/ | ||
public function search( | ||
$query, | ||
array $searchFields = null, | ||
array $facets = null, | ||
array $filters = null, | ||
$offset = 0, | ||
$pagesize = 10, | ||
array $weight = null | ||
) | ||
{ | ||
$querystring = '?q='.$query; | ||
if($searchFields) { | ||
$querystring.='&searchFields='.implode(',', $searchFields); | ||
} | ||
if($facets) { | ||
$querystring.='&facets='.implode(',', $facets); | ||
} | ||
if($filters) { | ||
foreach($filters as $name=>$values) | ||
foreach($values as $value) | ||
$querystring.='&filter['.$name.'][]='.$value; | ||
} | ||
if($offset) { | ||
$querystring .= '&offset='.$offset; | ||
} | ||
if($pagesize != 10) { | ||
$querystring .= '&pagesize='.$pagesize; | ||
} | ||
if($weight) { | ||
foreach($weight as $name=>$values) | ||
foreach($values as $value) | ||
$querystring.='&weight['.$name.'][]='.$value; | ||
} | ||
|
||
|
||
$ch = curl_init($this->base_path.'search'.$querystring); | ||
if(!$ch) | ||
throw new TransportException('Cannot open a cURL session'); | ||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
$resp = curl_exec($ch); | ||
curl_close($ch); | ||
|
||
return json_decode($resp, true); | ||
} | ||
|
||
/** | ||
* Removes a document with a specific ID | ||
* | ||
* @param int $docId | ||
* @return boolean | ||
* @throws TransportException | ||
*/ | ||
public function deleteDoc($docId) | ||
{ | ||
$ch = curl_init($this->base_path.'delete'); | ||
if(!$ch) | ||
throw new TransportException('Cannot open a cURL session'); | ||
curl_setopt($ch, CURLOPT_POST, true); | ||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
curl_setopt($ch, CURLOPT_POSTFIELDS, array( | ||
'docID'=>$docId | ||
)); | ||
$resp = curl_exec($ch); | ||
curl_close($ch); | ||
if($resp === "deleted ".$docId."\r\n") | ||
return true; | ||
return false; | ||
} | ||
|
||
/** | ||
* Retrieve meta-data about the index | ||
* | ||
* @return array The raw JSON decoded data from the search server | ||
* @throws TransportException | ||
*/ | ||
public function getIndexMetadata() | ||
{ | ||
$ch = curl_init($this->base_path.'indexData'); | ||
if(!$ch) | ||
throw new TransportException('Cannot open a cURL session'); | ||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
$resp = curl_exec($ch); | ||
curl_close($ch); | ||
|
||
return json_decode($resp, true); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
namespace vierbergenlars\Norch\Transport; | ||
|
||
class TransportException extends \RuntimeException | ||
{ | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<?php | ||
|
||
namespace vierbergenlars\Norch\Transport; | ||
|
||
/** | ||
* Interface all transport objects should implement | ||
* | ||
* The Transport layer provides a low-level interface to the Norch search server. | ||
* The transport layer is responsible for serializing of the passed data, | ||
* and unserialisation of the received data. It should not modify requests or responses. | ||
*/ | ||
interface TransportInterface | ||
{ | ||
/** | ||
* Adds a set of documents to the index | ||
* | ||
* @param array $documents An array of documents to submit. Each document is an array. The document may not have a key named 'id'. | ||
* @param array $filter Array of fields that can be used for faceted search. Can only contain fields that are arrays in the document. | ||
* @return boolean | ||
* @throws TransportException | ||
*/ | ||
public function indexBatch(array $documents, array $filter); | ||
|
||
/** | ||
* Perform a search query | ||
* | ||
* @param string $query The search query | ||
* @param array $searchFields An array of fields to search in | ||
* @param array $facets An array of fields to facet on | ||
* @param array $filters Limit search to fields with a particular value(s). Each field contains an array of acceptable values. | ||
* @param int $offset The offset to start in the result set | ||
* @param int $pagesize The size of each page | ||
* @param array $weight The weights to give each field. | ||
* @return array Raw json decoded data from the search server | ||
* @throws TransportException | ||
*/ | ||
public function search( | ||
$query, | ||
array $searchFields = null, | ||
array $facets = null, | ||
array $filters = null, | ||
$offset = 0, | ||
$pagesize = 10, | ||
array $weight = null | ||
); | ||
|
||
/** | ||
* Removes a document with a specific ID | ||
* | ||
* @param int|string $docId | ||
* @return boolean | ||
* @throws TransportException | ||
*/ | ||
public function deleteDoc($docId); | ||
|
||
/** | ||
* Retrieve meta-data about the index | ||
* | ||
* @return array The raw JSON decoded data from the search server | ||
* @throws TransportException | ||
*/ | ||
public function getIndexMetadata(); | ||
} |