Overview

Namespaces

  • PHP
  • vierbergenlars
    • Forage
      • ODM
        • HydrationSettings
      • QueryParser
      • SearchIndex
      • SearchQuery
      • SearchResult
      • Transport

Classes

  • Http

Interfaces

  • TransportInterface

Exceptions

  • TransportException
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: namespace vierbergenlars\Forage\Transport;
  4: 
  5: /**
  6:  * HTTP as transport layer for Forage queries
  7:  *
  8:  * {@inheritDoc}
  9:  */
 10: class Http implements TransportInterface
 11: {
 12:     /**
 13:      * The path to the place where Forage is listening
 14:      * @var string
 15:      */
 16:     private $base_path;
 17: 
 18:     /**
 19:      * Creates a new HTTP transport layer
 20:      * @param string $base_path The base path of the Forage server
 21:      */
 22:     public function __construct($base_path = 'http://localhost:3000/')
 23:     {
 24:         $this->base_path = $base_path;
 25:     }
 26: 
 27:     private static function addPostBody($ch, $fields = array(), $files = array())
 28:     {
 29:         $boundary = '--------------'.uniqid();
 30: 
 31:         $data = '';
 32: 
 33:         foreach($fields as $name=>$value) {
 34:             $data.='--'.$boundary."\r\n";
 35:             $data.='Content-Disposition: form-data; name="'.$name.'"';
 36:             $data.="\r\n\r\n";
 37:             $data.=$value;
 38:             $data.="\r\n";
 39:         }
 40: 
 41:         foreach($files as $name=>$file) {
 42:             $data.='--'.$boundary."\r\n";
 43:             $data.='Content-Disposition: form-data; name="'.$name.'"; filename="'.$file['filename'].'"'."\r\n";
 44:             $data.="Content-Type: application/octet-stream\r\n\r\n";
 45:             $data.=$file['data'];
 46:             $data.="\r\n";
 47:         }
 48: 
 49:         $data.='--'.$boundary.'--'."\r\n";
 50: 
 51:         curl_setopt($ch, CURLOPT_POST, true);
 52:         curl_setopt($ch, CURLOPT_HTTPHEADER, array(
 53:             'Content-Type: multipart/form-data; boundary='.$boundary,
 54:             'Content-Length: '.strlen($data)
 55:         ));
 56:         curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
 57:     }
 58: 
 59:     /**
 60:      * Adds a set of documents to the index
 61:      * @param array $documents An array of documents to submit. Each document is an array. The document may not have a key named 'id'.
 62:      * @param array $filter Array of fields that can be used for faceted search. Can only contain fields that are arrays in the document.
 63:      * @return boolean
 64:      * @throws TransportException
 65:      */
 66:     public function indexBatch(array $documents, array $filter)
 67:     {
 68:         $json_docs = json_encode($documents);
 69:         $docid = uniqid();
 70:         $ch = curl_init($this->base_path.'indexer');
 71:         if(!$ch)
 72:             throw new TransportException('Cannot open a cURL session');
 73:         self::addPostBody($ch, array(
 74:             'filterOn'=>implode(',', $filter)
 75:             ), array(
 76:                 'document'=> array(
 77:                     'filename'=>$docid.'.json',
 78:                     'data'=> $json_docs
 79:                 )
 80:         ));
 81:         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 82:         $reply = curl_exec($ch);
 83:         if(curl_errno($ch))
 84:             throw new TransportException('cURL error: '.curl_error($ch), curl_errno($ch));
 85:         curl_close($ch);
 86:         if(trim($reply) === 'indexed batch: '.$docid.'.json')
 87:             return true;
 88:         return false;
 89:     }
 90: 
 91:     /**
 92:      * Perform a search query
 93:      *
 94:      * @param string $query The search query
 95:      * @param array $searchFields An array of fields to search in
 96:      * @param array $facets An array of fields to facet on
 97:      * @param array $filters Limit search to fields with a particular value(s). Each field contains an array of acceptable values.
 98:      * @param int $offset The offset to start in the result set
 99:      * @param int $pagesize The size of each page
100:      * @param array $weight The weights to give each field.
101:      * @return array Raw json decoded data from the search server
102:      * @throws TransportException
103:      */
104:     public function search(
105:               $query,
106:         array $searchFields = null,
107:         array $facets       = null,
108:         array $filters      = null,
109:               $offset       = 0,
110:               $pagesize     = 10,
111:         array $weight       = null
112:     )
113:     {
114:         $querystring = '?q=' . urlencode($query);
115:         if($searchFields) {
116:             foreach($searchFields as $field)
117:                 $querystring.='&searchFields[]=' . urlencode($field);
118:         }
119:         if($facets) {
120:             $querystring.='&facets=' . urlencode(implode(',', $facets));
121:         }
122:         if($filters) {
123:             foreach($filters as $name=>$values)
124:                 foreach($values as $value)
125:                     $querystring.='&filter[' . urlencode($name) . '][]=' . urlencode($value);
126:         }
127:         if($offset) {
128:             $querystring .= '&offset=' . urlencode($offset);
129:         }
130:         if($pagesize != 10) {
131:             $querystring .= '&pagesize=' . urlencode($pagesize);
132:         }
133:         if($weight) {
134:             foreach($weight as $name=>$values)
135:                 foreach($values as $value)
136:                     $querystring.='&weight[' . urlencode($name) . '][]=' . urlencode($value);
137:         }
138: 
139: 
140:         $ch = curl_init($this->base_path.'search'.$querystring);
141:         if(!$ch)
142:             throw new TransportException('Cannot open a cURL session');
143:         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
144:         $resp = curl_exec($ch);
145:         if(curl_errno($ch))
146:             throw new TransportException('cURL error: '.curl_error($ch), curl_errno($ch));
147:         curl_close($ch);
148:         if($resp === 'no results') {
149:             return array(
150:                 'totalHits'=>0,
151:                 'facets'=>array(),
152:                 'hits'=> array(),
153:             );
154:         }
155:         return json_decode($resp, true);
156:     }
157: 
158:     /**
159:      * Removes a document with a specific ID
160:      *
161:      * @param int $docId
162:      * @return boolean
163:      * @throws TransportException
164:      */
165:     public function deleteDoc($docId)
166:     {
167:         $ch = curl_init($this->base_path.'delete');
168:         if(!$ch)
169:             throw new TransportException('Cannot open a cURL session');
170:         curl_setopt($ch, CURLOPT_POST, true);
171:         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
172:         curl_setopt($ch, CURLOPT_POSTFIELDS, array(
173:             'docID'=>$docId
174:         ));
175:         $resp = curl_exec($ch);
176:         if(curl_errno($ch))
177:             throw new TransportException('cURL error: '.curl_error($ch), curl_errno($ch));
178:         curl_close($ch);
179:         if(trim($resp) === 'deleted '.$docId)
180:             return true;
181:         return false;
182:     }
183: 
184:     /**
185:      * Retrieve meta-data about the index
186:      *
187:      * @return array The raw JSON decoded data from the search server
188:      * @throws TransportException
189:      */
190:     public function getIndexMetadata()
191:     {
192:         $ch = curl_init($this->base_path.'indexData');
193:         if(!$ch)
194:             throw new TransportException('Cannot open a cURL session');
195:         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
196:         $resp = curl_exec($ch);
197:         if(curl_errno($ch))
198:             throw new TransportException('cURL error: '.curl_error($ch), curl_errno($ch));
199:         curl_close($ch);
200: 
201:         return json_decode($resp, true);
202:     }
203: 
204: }
205: 
Forage-PHP-Client API documentation generated by ApiGen 2.8.0