Commit 2f1edbf2 authored by Bas de Nooijer's avatar Bas de Nooijer

- lots of refactoring for the new solarium 2.0 structure

- still very much a work in progress, largely untested!
parent a41cc287
......@@ -55,6 +55,13 @@
class Solarium_Client extends Solarium_Configurable
{
/**
* Querytype definitions
*/
const QUERYTYPE_SELECT = 'Select';
const QUERYTYPE_UPDATE = 'Update';
const QUERYTYPE_PING = 'Ping';
/**
* Default options
*
......@@ -64,12 +71,25 @@ class Solarium_Client extends Solarium_Configurable
* @var array
*/
protected $_options = array(
'host' => '127.0.0.1',
'port' => 8983,
'path' => '/solr',
'core' => null,
'adapter' => 'Solarium_Client_Adapter_Http',
'timeout' => 5,
);
/**
* Querytype mappings
*/
protected $_queryTypes = array(
self::QUERYTYPE_SELECT => array(
'requestbuilder' => 'Solarium_Client_RequestBuilder_Select',
'responseparser' => 'Solarium_Client_ResponseParser_Select'
),
self::QUERYTYPE_UPDATE => array(
'requestbuilder' => 'Solarium_Client_RequestBuilder_Update',
'responseparser' => 'Solarium_Client_ResponseParser_Update'
),
self::QUERYTYPE_PING => array(
'requestbuilder' => 'Solarium_Client_RequestBuilder_Ping',
'responseparser' => 'Solarium_Client_ResponseParser_Ping'
),
);
/**
......@@ -87,131 +107,11 @@ class Solarium_Client extends Solarium_Configurable
protected $_adapter;
/**
* Initialization hook
*
* In this case the path needs to be cleaned of trailing slashes.
* @see setPath()
*/
protected function _init()
{
foreach ($this->_options AS $name => $value) {
switch ($name) {
case 'path':
$this->setPath($value);
break;
}
}
}
/**
* Set an option
*
* If any option of this client is changed after the adapter has been
* instantiated the change is propagated to the adapter. This allows for
* switching the client to another core for a second query, for instance.
*
* @param string $name
* @param mixed $value
* @return Solarium_Configurable
*/
protected function _setOption($name, $value)
{
parent::_setOption($name, $value);
if (null !== $this->_adapter) {
$this->_adapter->setOptions($this->_options);
}
return $this;
}
/**
* Set host option
*
* @param string $host This can be a hostname or an IP address
* @return Solarium_Client Provides fluent interface
*/
public function setHost($host)
{
return $this->_setOption('host', $host);
}
/**
* Get host option
*
* @return string
*/
public function getHost()
{
return $this->getOption('host');
}
/**
* Set port option
* Request builder instances
*
* @param int $port Common values are 80, 8080 and 8983
* @return Solarium_Client Provides fluent interface
*/
public function setPort($port)
{
return $this->_setOption('port', $port);
}
/**
* Get port option
*
* @return int
*/
public function getPort()
{
return $this->getOption('port');
}
/**
* Set path option
*
* If the path has a trailing slash it will be removed.
*
* @param string $path
* @return Solarium_Client Provides fluent interface
*/
public function setPath($path)
{
if (substr($path, -1) == '/') $path = substr($path, 0, -1);
return $this->_setOption('path', $path);
}
/**
* Get path option
*
* @return void
*/
public function getPath()
{
return $this->getOption('path');
}
/**
* Set core option
*
* @param string $core
* @return Solarium_Client Provides fluent interface
* @var array
*/
public function setCore($core)
{
return $this->_setOption('core', $core);
}
/**
* Get core option
*
* @return string
*/
public function getCore()
{
return $this->getOption('core');
}
protected $_requestBuilders;
/**
* Set the adapter
......@@ -284,29 +184,92 @@ class Solarium_Client extends Solarium_Configurable
}
/**
* Set adapter options
* Register a querytype
*
* You can also use this method to override any existing querytype with a new mapping
*
* @param array|object $options
* @param string $type
* @param string $requestBuilder
* @param string $responseParser
* @return Solarium_Client Provides fluent interface
*/
public function setAdapterOptions($options)
public function registerQueryType($type, $requestBuilder, $responseParser)
{
// covert config object into an array if needed
if (is_object($options)) {
$options = $options->toArray();
$this->_queryTypes[$type] = array(
'requestbuilder' => $requestBuilder,
'responseparser' => $responseParser,
);
return $this;
}
/**
* Get all registered querytypes
*
* @return array
*/
public function getQueryTypes()
{
return $this->_queryTypes;
}
/**
* Creates a request based on a query instance
*
* @todo add caching of request builder?
*
* @param Solarium_Query $query
* @return Solarium_Client_Request
*/
public function createRequest($query)
{
$queryType = $query->getType();
if (!isset($this->_queryTypes[$queryType])) {
throw new Solarium_Exception('No requestbuilder registered for querytype: '. $queryType);
}
return $this->_setOption('adapteroptions', $options);
$requestBuilderClass = $this->_queryTypes[$queryType]['requestbuilder'];
$requestBuilder = new $requestBuilderClass;
return $requestBuilder->build($query);
}
/**
* Get adapteroptions
* Creates a result object
*
* @return array
* @param Solarium_Query $query
* @param array Solarium_Client_Response $response
* @return Solarium_Result
*/
public function createResult($query, $response)
{
$resultClass = $query->getResultClass();
return new $resultClass($this, $query, $response);
}
/**
* Execute a query
*
* @param Solarium_Query
* @return Solarium_Result
*/
public function execute($query)
{
$request = $this->createRequest($query);
$response = $this->executeRequest($request);
return $this->createResult($query, $response);
}
/**
* Execute a request and return the response
*
* @param Solarium_Client_Request
* @return Solarium_Client_Response
*/
public function getAdapterOptions()
public function executeRequest($request)
{
return $this->getOption('adapteroptions');
return $this->getAdapter()->execute($request);
}
/**
......@@ -330,7 +293,7 @@ class Solarium_Client extends Solarium_Configurable
*/
public function ping($query)
{
return $this->getAdapter()->ping($query);
return $this->execute($query);
}
/**
......@@ -356,7 +319,7 @@ class Solarium_Client extends Solarium_Configurable
*/
public function update($query)
{
return $this->getAdapter()->update($query);
return $this->execute($query);
}
/**
......@@ -381,6 +344,6 @@ class Solarium_Client extends Solarium_Configurable
*/
public function select($query)
{
return $this->getAdapter()->select($query);
return $this->execute($query);
}
}
\ No newline at end of file
......@@ -56,58 +56,175 @@
*/
abstract class Solarium_Client_Adapter extends Solarium_Configurable
{
/**
* Default options
*
* The defaults match a standard Solr example instance as distributed by
* the Apache Lucene Solr project.
*
* @var array
*/
protected $_options = array(
'host' => '127.0.0.1',
'port' => 8983,
'path' => '/solr',
'core' => null,
'timeout' => 5,
);
/**
* Initialization hook
*
* In this case the path needs to be cleaned of trailing slashes.
* @see setPath()
*/
protected function _init()
{
foreach ($this->_options AS $name => $value) {
switch ($name) {
case 'path':
$this->setPath($value);
break;
}
}
}
/**
* Set host option
*
* @param string $host This can be a hostname or an IP address
* @return Solarium_Client Provides fluent interface
*/
public function setHost($host)
{
return $this->_setOption('host', $host);
}
/**
* Get host option
*
* @return string
*/
public function getHost()
{
return $this->getOption('host');
}
/**
* Set port option
*
* @param int $port Common values are 80, 8080 and 8983
* @return Solarium_Client Provides fluent interface
*/
public function setPort($port)
{
return $this->_setOption('port', $port);
}
/**
* Get port option
*
* @return int
*/
public function getPort()
{
return $this->getOption('port');
}
/**
* Set options
* Set path option
*
* Overrides any existing values
* If the path has a trailing slash it will be removed.
*
* @param string $path
* @return Solarium_Client Provides fluent interface
*/
public function setPath($path)
{
if (substr($path, -1) == '/') $path = substr($path, 0, -1);
return $this->_setOption('path', $path);
}
/**
* Get path option
*
* @param array $options
* @return void
*/
public function setOptions($options)
public function getPath()
{
$this->_setOptions($options, true);
return $this->getOption('path');
}
/**
* Execute a select query
* Set core option
*
* Abstract method to require an implementation inside all adapters.
* If the adapter cannot support this method it should implement a method
* that throws an exception.
* @param string $core
* @return Solarium_Client Provides fluent interface
*/
public function setCore($core)
{
return $this->_setOption('core', $core);
}
/**
* Get core option
*
* @abstract
* @param Solarium_Query_Select $query
* @return Solarium_Result_Select
* @return string
*/
abstract public function select($query);
public function getCore()
{
return $this->getOption('core');
}
/**
* Execute a ping query
* Set timeout option
*
* Abstract method to require an implementation inside all adapters.
* If the adapter cannot support this method it should implement a method
* that throws an exception.
* @param int $timeout
* @return Solarium_Client Provides fluent interface
*/
public function setTimeout($timeout)
{
return $this->_setOption('timeout', $timeout);
}
/**
* Get timeout option
*
* @abstract
* @param Solarium_Query_Ping $query
* @return boolean
* @return string
*/
abstract public function ping($query);
public function getTimeout()
{
return $this->getOption('timeout');
}
/**
* Execute an update query
* Execute a request
*
* Abstract method to require an implementation inside all adapters.
* If the adapter cannot support this method it should implement a method
* that throws an exception.
*
* @abstract
* @param Solarium_Query_Update $query
* @return Solarium_Result_Update
* @param Solarium_Client_Request $request
* @return Solarium_Client_Response
*/
abstract public function execute($request);
/**
* Get the base url for all requests
*
* Based on host, path, port and core options.
*
* @return void
*/
abstract public function update($query);
public function getBaseUri()
{
$uri = 'http://' . $this->getHost() . ':' . $this->getPort() . $this->getPath() . '/';
$core = $this->getCore();
if (!empty($core)) {
$uri .= $core.'/';
}
return $uri;
}
}
\ No newline at end of file
......@@ -44,67 +44,24 @@
class Solarium_Client_Adapter_Http extends Solarium_Client_Adapter
{
/**
* Executes a select query
*
* @param Solarium_Query_Select $query
* @return Solarium_Result_Select
*/
public function select($query)
{
$request = new Solarium_Client_Request_Select($this->_options, $query);
$data = $this->_handleRequest($request);
$response = new Solarium_Client_Response_Select($query, $data);
return $response->getResult();
}
/**
* Executes a ping query
*
* @param Solarium_Query_Ping $query
* @return boolean
*/
public function ping($query)
{
$request = new Solarium_Client_Request_Ping($this->_options, $query);
return (boolean)$this->_handleRequest($request);
}
/**
* Executes an update query
*
* @param Solarium_Query_Update $query
* @return Solarium_Result_Update
*/
public function update($query)
{
$request = new Solarium_Client_Request_Update($this->_options, $query);
$data = $this->_handleRequest($request);
$response = new Solarium_Client_Response_Update($query, $data);
return $response->getResult();
}
/**
* Handle Solr communication
*
* @throws Solarium_Exception
* @param Solarium_Client_Request
* @return array
* @return Solarium_Client_Response
*/
protected function _handleRequest($request)
public function execute($request)
{
$method = $request->getMethod();
$context = stream_context_create(
array('http' => array(
'method' => $method,
'timeout' => $this->getOption('timeout')
'timeout' => $this->getTimeout()
))
);
if ($method == Solarium_Client_Request::POST) {
if ($method == Solarium_Client_Request::METHOD_POST) {
$data = $request->getRawData();
if (null !== $data) {
stream_context_set_option(
......@@ -113,6 +70,7 @@ class Solarium_Client_Adapter_Http extends Solarium_Client_Adapter
'content',
$data
);
//TODO header via request->setRawData!!
stream_context_set_option(
$context,
'http',
......@@ -122,85 +80,16 @@ class Solarium_Client_Adapter_Http extends Solarium_Client_Adapter
}
}
$data = @file_get_contents($request->getUri(), false, $context);
$uri = $this->getBaseUri() . $request->getUri();
$data = @file_get_contents($uri, false, $context);
// if there is no data and there are no headers it's a total failure,
// a connection to the host was impossible.
if (false === $data && !isset($http_response_header)) {
throw new Solarium_Client_HttpException("HTTP request failed");
}
$this->_checkHeaders($http_response_header);
if ($method == Solarium_Client_Request::HEAD) {
// HEAD request has no result data
return true;
} else {
if (false === $data) {
$error = error_get_last();
throw new Solarium_Exception($error['message']);
}
return $this->_jsonDecode($data);
}
return new Solarium_Client_Response($data, $http_response_header);
}
/**
* Check HTTP headers
*
* The status header is parsed, an exception will be thrown for an error
* code.
*
* @throws Solarium_Client_HttpException
* @param array $headers
* @return void
*/
protected function _checkHeaders($headers)
{
// get the status header
$statusHeader = null;
foreach ($headers AS $header) {
if (substr($header, 0, 4) == 'HTTP') {
$statusHeader = $header;
break;
}
}
if (null == $statusHeader) {
throw new Solarium_Client_HttpException("No HTTP status found");
}
// parse header like "$statusInfo[1]" into code and message
// $statusInfo[1] = the HTTP response code
// $statusInfo[2] = the response message
$statusInfo = explode(' ', $statusHeader, 3);
// check status for error (range of 400 and 500)
$statusNum = floor($statusInfo[1] / 100);
if ($statusNum == 4 || $statusNum == 5) {
throw new Solarium_Client_HttpException(
$statusInfo[2],
$statusInfo[1]
);
}
}
/**
* Decode json response data
*
* @throws Solarium_Exception
* @param string $data
* @return string
*/
protected function _jsonDecode($data)
{
$data = json_decode($data, true);
if (null === $data) {
throw new Solarium_Exception(
'Solr JSON response could not be decoded'
);
}
return $data;
}
}
\ No newline at end of file
......@@ -36,102 +36,117 @@
*/
/**
* Base class for building Solr HTTP requests
* Class for describing a request
*
* Most {@link Solarium_Client_Adapter} implementations will use HTTP for
* communicating with Solr. While the HTTP part is adapter-specific, generating
* the HTTP request setting (url, postdata, etc.) is not.
* This abstract class is the base for several requestbuilders that generate the
* settings for the various querytypes.
* @todo support config mode
*
* @package Solarium
* @subpackage Client
*/
abstract class Solarium_Client_Request
class Solarium_Client_Request extends Solarium_Configurable
{
/**
* Http request methods
*/
const GET = 'GET';
const POST = 'POST';
const HEAD = 'HEAD';
const METHOD_GET = 'get';
const METHOD_POST = 'post';
const METHOD_HEAD = 'head';
/**
* Query instance
*
* The query that has to be used for building the request.
*
* @var Solarium_Query
* Default options
*
* @var array
*/
protected $_query;
protected $_options = array(
'method' => self::METHOD_GET,
);
/**
* Adapter options
* Request headers
*/
protected $_headers;
/**
* Request params
*
* When the adapter class the {@link __construct()} method it forwards it's
* options. These options are needed for building the right uri.
* Multivalue params are supported using a multidimensional array:
* 'fq' => array('cat:1','published:1')
*
* @var array
*/
protected $_options;
protected $_params;
/**
* HTTP GET params
* Raw POST data
*
* Used for building the uri in {@link buildUri()}
*
* @var array
* @var string
*/
protected $_params;
protected $_rawData;
/**
* Constructor
* Set request handler
*
* @param array|object $options Passed on by the adapter
* @param Solarium_Query $query
* @param string $handler
* @return Solarium_Client_Request
*/
public function __construct($options, $query)
public function setHandler($handler)
{
$this->_options = $options;
$this->_query = $query;
$this->_setOption('handler', $handler);
return $this;
}
/**
* Get HTTP request method
* Get request handler
*
* @return string
*/
public function getMethod()
public function getHandler()
{
return self::GET;
return $this->getOption('handler');
}
/**
* Get request uri
* Set request method
*
* To be implemented by query specific request builders.
* Use one of the constants as value
*
* @abstract
* @return string
* @param string $method
* @return Solarium_Client_Request
*/
abstract public function getUri();
public function setMethod($method)
{
$this->_setOption('method', $method);
return $this;
}
/**
* Get raw POST data
* Get request method
*
* Returns null by default, disabling raw POST.
* If raw POST data is needed for a request the builder must override this
* method and return a data string. This string must be safely encoded.
* @return string
*/
public function getMethod()
{
return $this->getOption('method');
}
/**
* Get a param value
*
* @return null
* @param string $key
* @return string|array
*/
public function getRawData()
public function getParam($key)
{
return null;
if (isset($this->_params[$key])) {
return $this->_params[$key];
} else {
return null;
}
}
/**
* Get request GET params
* Get all params
*
* @return array
*/
......@@ -141,133 +156,193 @@ abstract class Solarium_Client_Request
}
/**
* Build a URL for this request
* Set request params
*
* Based on {@link $_options} and {@link $_params} as input.
* @param array $params
* @return Solarium_Client_Request
*/
public function setParams($params)
{
$this->clearParams();
$this->addParams($params);
return $this;
}
/**
* Add a request param
*
* @internal Solr expects multiple GET params of the same name instead of
* the PHP array type notation. Therefore the result of http_build_query
* has to be altered.
* If you add a request param that already exists the param will be converted into a multivalue param,
* unless you set the overwrite param to true.
*
* @return string
* Empty params are not added to the request. If you want to empty a param disable it you should use
* remove param instead.
*
* @param string $key
* @param string|array $value
* @param boolean $overwrite
* @return Solarium_Client_Request
*/
public function buildUri()
public function addParam($key, $value, $overwrite = false)
{
$queryString = '';
if (count($this->_params) > 0) {
$queryString = http_build_query($this->_params, null, '&');
$queryString = preg_replace(
'/%5B(?:[0-9]|[1-9][0-9]+)%5D=/',
'=',
$queryString
);
if (!empty($value)) {
if (!$overwrite && isset($this->_params[$key])) {
if (!is_array($this->_params[$key])) {
$this->_params[$key] = array($this->_params[$key]);
}
$this->_params[$key][] = $value;
} else {
$this->_params[$key] = $value;
}
}
if (null !== $this->_options['core']) {
$core = '/' . $this->_options['core'];
} else {
$core = '';
return $this;
}
/**
* Add multiple params to the request
*
* @param array $params
* @param boolean $overwrite
* @return Solarium_Client_Request
*/
public function addParams($params, $overwrite = false)
{
foreach ($params as $key => $value) {
$this->addParam($key, $value, $overwrite);
}
return 'http://' . $this->_options['host'] . ':'
. $this->_options['port'] . $this->_options['path']
. $core . '/' . $this->_query->getHandler() . '?'
. $queryString;
return $this;
}
/**
* Render a boolean attribute
* Remove a param by key
*
* For use in building XML messages
*
* @param string $name
* @param boolean $value
* @return string
* @param string $key
* @return Solarium_Client_Request
*/
public function boolAttrib($name, $value)
public function removeParam($key)
{
if (null !== $value) {
$value = (true == $value) ? 'true' : 'false';
return $this->attrib($name, $value);
} else {
return '';
if (isset($this->_params[$key])) {
unset($this->_params[$key]);
}
return $this;
}
/**
* Render an attribute
* Clear all request params
*
* @return Solarium_Client_Request
*/
public function clearParams()
{
$this->_params = array();
return $this;
}
/**
* Get raw POST data
*
* @return null
*/
public function getRawData()
{
return $this->_rawData;
}
/**
* Set raw POST data
*
* For use in building XML messages
* This string must be safely encoded.
*
* @param string $name
* @param striung $value
* @return string
* @param string $data
* @return Solarium_Client_Request
*/
public function attrib($name, $value)
public function setRawData($data)
{
if (null !== $value) {
return ' ' . $name . '="' . $value . '"';
} else {
return '';
}
$this->_rawData = $data;
return $this;
}
/**
* Render a param with localParams
* Get all request headers
*
* LocalParams can be use in various Solr GET params.
* @link http://wiki.apache.org/solr/LocalParams
* @return array
*/
public function getHeaders()
{
return $this->_headers;
}
/**
* Set request headers
*
* @param string $value
* @param array $localParams in key => value format
* @return string with Solr localparams syntax
* @header array $headers
* @return Solarium_Client_Request
*/
public function renderLocalParams($value, $localParams = array())
public function setHeaders($headers)
{
$params = '';
foreach ($localParams AS $paramName => $paramValue) {
if (empty($paramValue)) continue;
$this->clearHeaders();
$this->addHeaders($headers);
return $this;
}
if (is_array($paramValue)) {
$paramValue = implode($paramValue, ',');
}
/**
* Add a request header
*
* @header string $key
* @header string|array $value
* @return Solarium_Client_Request
*/
public function addHeader($key, $value)
{
$this->_headers[] = $value;
return $this;
}
$params .= $paramName . '=' . $paramValue . ' ';
/**
* Add multiple headers to the request
*
* @header array $headers
* @return Solarium_Client_Request
*/
public function addHeaders($headers)
{
foreach ($headers as $key => $value) {
$this->addHeader($key, $value);
}
if ($params !== '') {
$value = '{!' . trim($params) . '}' . $value;
}
return $this;
}
return $value;
/**
* Clear all request headers
*
* @return Solarium_Client_Request
*/
public function clearHeaders()
{
$this->_headers = array();
return $this;
}
/**
* Add a param to the request
*
* This method makes adding params easy in two ways:
* - empty params are filtered out, so you don't to manually check each
* param
* - if you add the same param twice it will be converted into a multivalue
* param automatically. This way you don't need to check for single or
* multiple values beforehand.
* Get an URI for this request
*
* @param string $name
* @param string $value
* @return void
* @return string
*/
public function addParam($name, $value)
public function getUri()
{
if (0 === strlen($value)) return;
if (!isset($this->_params[$name])) {
$this->_params[$name] = $value;
} else {
if (!is_array($this->_params[$name])) {
$this->_params[$name] = array($this->_params[$name]);
}
$this->_params[$name][] = $value;
$queryString = '';
if (count($this->_params) > 0) {
$queryString = http_build_query($this->_params, null, '&');
$queryString = preg_replace(
'/%5B(?:[0-9]|[1-9][0-9]+)%5D=/',
'=',
$queryString
);
}
return $this->getHandler() . '?' . $queryString;
}
}
\ No newline at end of file
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
*
* @package Solarium
* @subpackage Client
*/
/**
* Class for building Solarium client requests
*
* @package Solarium
* @subpackage Client
*/
abstract class Solarium_Client_RequestBuilder
{
/**
* Render a param with localParams
*
* LocalParams can be use in various Solr GET params.
* @link http://wiki.apache.org/solr/LocalParams
*
* @param string $value
* @param array $localParams in key => value format
* @return string with Solr localparams syntax
*/
public function renderLocalParams($value, $localParams = array())
{
$params = '';
foreach ($localParams AS $paramName => $paramValue) {
if (empty($paramValue)) continue;
if (is_array($paramValue)) {
$paramValue = implode($paramValue, ',');
}
$params .= $paramName . '=' . $paramValue . ' ';
}
if ($params !== '') {
$value = '{!' . trim($params) . '}' . $value;
}
return $value;
}
}
\ No newline at end of file
......@@ -41,7 +41,7 @@
* @package Solarium
* @subpackage Client
*/
class Solarium_Client_Request_Ping extends Solarium_Client_Request
class Solarium_Client_RequestBuilder_Ping extends Solarium_Client_RequestBuilder
{
/**
......
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
*
* @package Solarium
* @subpackage Client
*/
/**
* Build a select request
*
* @package Solarium
* @subpackage Client
*/
class Solarium_Client_RequestBuilder_Select extends Solarium_Client_RequestBuilder
{
/**
* Build request for a select query
*
* @param Solarium_Query_Select $query
* @return Solarium_Client_Request
*/
public function build($query)
{
$request = new Solarium_Client_Request;
$request->setHandler($query->getHandler());
// add basic params to request
$request->addParam('q', $query->getQuery());
$request->addParam('start', $query->getStart());
$request->addParam('rows', $query->getRows());
$request->addParam('fl', implode(',', $query->getFields()));
$request->addParam('wt', 'json');
// add sort fields to request
$sort = array();
foreach ($query->getSortFields() AS $field => $order) {
$sort[] = $field . ' ' . $order;
}
if (count($sort) !== 0) {
$request->addParam('sort', implode(',', $sort));
}
// add filterqueries to request
$filterQueries = $query->getFilterQueries();
if (count($filterQueries) !== 0) {
foreach ($filterQueries AS $filterQuery) {
$fq = $this->renderLocalParams(
$filterQuery->getQuery(),
array('tag' => $filterQuery->getTags())
);
$request->addParam('fq', $fq);
}
}
// add components to request
$types = $query->getComponentTypes();
foreach ($query->getComponents() as $component) {
$componentBuilderClass = $types[$component->getType()]['requestbuilder'];
if (!empty($componentBuilderClass)) {
// todo add caching?
$componentBuilder = new $componentBuilderClass;
$request = $componentBuilder->build($component, $request);
}
}
return $request;
}
}
\ No newline at end of file
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
*
* @package Solarium
* @subpackage Client
*/
/**
* Add select component dismax to the request
*
* @package Solarium
* @subpackage Client
*/
class Solarium_Client_RequestBuilder_Select_Component_DisMax
{
/**
* Add request settings for Dismax
*
* @param Solarium_Query_Select_Component_Dismax $component
* @param Solarium_Client_Request $request
* @return Solarium_Client_Request
*/
public function build($component, $request)
{
// enable dismax
$request->addParam('defType', 'dismax');
$request->addParam('q.alt', $component->getQueryAlternative());
$request->addParam('qf', $component->getQueryFields());
$request->addParam('mm', $component->getMinimumMatch());
$request->addParam('pf', $component->getPhraseFields());
$request->addParam('ps', $component->getPhraseSlop());
$request->addParam('qs', $component->getQueryPhraseSlop());
$request->addParam('tie', $component->getTie());
$request->addParam('bq', $component->getBoostQuery());
$request->addParam('bf', $component->getBoostFunctions());
return $request;
}
}
\ No newline at end of file
......@@ -36,127 +36,72 @@
*/
/**
* Build a select request
* Add select component FacetSet to the request
*
* @package Solarium
* @subpackage Client
*/
class Solarium_Client_Request_Select extends Solarium_Client_Request
class Solarium_Client_RequestBuilder_Select_Component_FacetSet extends Solarium_Client_RequestBuilder
{
/**
* Get uri
*
* Builds a complex uri based on the query settings
* Add request settings for FacetSet
*
* @throws Solarium_Exception
* @return string
* @param Solarium_Query_Select_Component_FacetSet $component
* @param Solarium_Client_Request $request
* @return Solarium_Client_Request
*/
public function getUri()
public function build($component, $request)
{
$this->_params = array(
'q' => $this->_query->getQuery(),
'start' => $this->_query->getStart(),
'rows' => $this->_query->getRows(),
'fl' => implode(',', $this->_query->getFields()),
'wt' => 'json',
);
$sort = array();
foreach ($this->_query->getSortFields() AS $field => $order) {
$sort[] = $field . ' ' . $order;
}
if (count($sort) !== 0) {
$this->addParam('sort', implode(',', $sort));
}
$filterQueries = $this->_query->getFilterQueries();
if (count($filterQueries) !== 0) {
foreach ($filterQueries AS $filterQuery) {
$fq = $this->renderLocalParams(
$filterQuery->getQuery(),
array('tag' => $filterQuery->getTags())
);
$this->addParam('fq', $fq);
}
}
foreach ($this->_query->getComponents() as $component) {
switch ($component->getType())
{
case Solarium_Query_Select_Component::MORELIKETHIS:
$this->addMoreLikeThis($component);
break;
case Solarium_Query_Select_Component::FACETSET:
$this->addFacetSet($component);
break;
case Solarium_Query_Select_Component::DISMAX:
$this->addDisMax($component);
break;
case Solarium_Query_Select_Component::HIGHLIGHTING:
$this->addHighlighting($component);
break;
default:
throw new Solarium_Exception('Unknown component type');
}
}
return $this->buildUri();
}
/**
* @throws Solarium_Exception
* @param Solarium_Query_Select_Component_FacetSet $facetSet
* @return void
*/
public function addFacetSet($facetSet)
{
$facets = $facetSet->getFacets();
$facets = $component->getFacets();
if (count($facets) !== 0) {
// enable faceting
$this->_params['facet'] = 'true';
$request->addParam('facet', 'true');
// global facet params
$this->addParam('facet.sort', $facetSet->getSort());
$this->addParam('facet.prefix', $facetSet->getPrefix());
$this->addParam('facet.missing', $facetSet->getMissing());
$this->addParam('facet.mincount', $facetSet->getMinCount());
$this->addParam('facet.limit', $facetSet->getLimit());
$request->addParam('facet.sort', $component->getSort());
$request->addParam('facet.prefix', $component->getPrefix());
$request->addParam('facet.missing', $component->getMissing());
$request->addParam('facet.mincount', $component->getMinCount());
$request->addParam('facet.limit', $component->getLimit());
foreach ($facets AS $facet) {
switch ($facet->getType())
{
case Solarium_Query_Select_Component_Facet::FIELD:
$this->addFacetField($facet);
$this->addFacetField($request, $facet);
break;
case Solarium_Query_Select_Component_Facet::QUERY:
$this->addFacetQuery($facet);
$this->addFacetQuery($request, $facet);
break;
case Solarium_Query_Select_Component_Facet::MULTIQUERY:
$this->addFacetMultiQuery($facet);
$this->addFacetMultiQuery($request, $facet);
break;
case Solarium_Query_Select_Component_Facet::RANGE:
$this->addFacetRange($facet);
$this->addFacetRange($request, $facet);
break;
default:
throw new Solarium_Exception('Unknown facet type');
}
}
}
return $request;
}
/**
* Add params for a field facet to request
*
* @param Solarium_Client_Request $request
* @param Solarium_Query_Select_Component_Facet_Field $facet
* @return void
*/
public function addFacetField($facet)
public function addFacetField($request, $facet)
{
$field = $facet->getField();
$this->addParam(
$request->addParam(
'facet.field',
$this->renderLocalParams(
$field,
......@@ -164,24 +109,25 @@ class Solarium_Client_Request_Select extends Solarium_Client_Request
)
);
$this->addParam("f.$field.facet.limit", $facet->getLimit());
$this->addParam("f.$field.facet.sort", $facet->getSort());
$this->addParam("f.$field.facet.prefix", $facet->getPrefix());
$this->addParam("f.$field.facet.offset", $facet->getOffset());
$this->addParam("f.$field.facet.mincount", $facet->getMinCount());
$this->addParam("f.$field.facet.missing", $facet->getMissing());
$this->addParam("f.$field.facet.method", $facet->getMethod());
$request->addParam("f.$field.facet.limit", $facet->getLimit());
$request->addParam("f.$field.facet.sort", $facet->getSort());
$request->addParam("f.$field.facet.prefix", $facet->getPrefix());
$request->addParam("f.$field.facet.offset", $facet->getOffset());
$request->addParam("f.$field.facet.mincount", $facet->getMinCount());
$request->addParam("f.$field.facet.missing", $facet->getMissing());
$request->addParam("f.$field.facet.method", $facet->getMethod());
}
/**
* Add params for a facet query to request
*
* @param Solarium_Client_Request $request
* @param Solarium_Query_Select_Component_Facet_Query $facet
* @return void
*/
public function addFacetQuery($facet)
public function addFacetQuery($request, $facet)
{
$this->addParam(
$request->addParam(
'facet.query',
$this->renderLocalParams(
$facet->getQuery(),
......@@ -193,27 +139,29 @@ class Solarium_Client_Request_Select extends Solarium_Client_Request
/**
* Add params for a multiquery facet to request
*
* @param Solarium_Client_Request $request
* @param Solarium_Query_Select_Component_Facet_MultiQuery $facet
* @return void
*/
public function addFacetMultiQuery($facet)
public function addFacetMultiQuery($request, $facet)
{
foreach ($facet->getQueries() AS $facetQuery) {
$this->addFacetQuery($facetQuery);
$this->addFacetQuery($request, $facetQuery);
}
}
/**
* Add params for a range facet to request
*
* @param Solarium_Client_Request $request
* @param Solarium_Query_Select_Component_Facet_Range $facet
* @return void
*/
public function addFacetRange($facet)
public function addFacetRange($request, $facet)
{
$field = $facet->getField();
$this->addParam(
$request->addParam(
'facet.range',
$this->renderLocalParams(
$field,
......@@ -221,98 +169,19 @@ class Solarium_Client_Request_Select extends Solarium_Client_Request
)
);
$this->addParam("f.$field.facet.range.start", $facet->getStart());
$this->addParam("f.$field.facet.range.end", $facet->getEnd());
$this->addParam("f.$field.facet.range.gap", $facet->getGap());
$this->addParam("f.$field.facet.range.hardend", $facet->getHardend());
$request->addParam("f.$field.facet.range.start", $facet->getStart());
$request->addParam("f.$field.facet.range.end", $facet->getEnd());
$request->addParam("f.$field.facet.range.gap", $facet->getGap());
$request->addParam("f.$field.facet.range.hardend", $facet->getHardend());
$other = explode(',', $facet->getOther());
foreach ($other AS $otherValue) {
$this->addParam("f.$field.facet.range.other", trim($otherValue));
$request->addParam("f.$field.facet.range.other", trim($otherValue));
}
$include = explode(',', $facet->getInclude());
foreach ($include AS $includeValue) {
$this->addParam("f.$field.facet.range.include", trim($includeValue));
$request->addParam("f.$field.facet.range.include", trim($includeValue));
}
}
/**
* Add params for morelikethis
*
* @param Solarium_Query_Select_Component_MoreLikeThis $component
* @return void
*/
public function addMoreLikeThis($component)
{
// enable morelikethis
$this->_params['mlt'] = 'true';
$this->addParam('mlt.fl', $component->getFields());
$this->addParam('mlt.mintf', $component->getMinimumTermFrequency());
$this->addParam('mlt.mindf', $component->getMinimumDocumentFrequency());
$this->addParam('mlt.minwl', $component->getMinimumWordLength());
$this->addParam('mlt.maxwl', $component->getMaximumWordLength());
$this->addParam('mlt.maxqt', $component->getMaximumQueryTerms());
$this->addParam('mlt.maxntp', $component->getMaximumNumberOfTokens());
$this->addParam('mlt.boost', $component->getBoost());
$this->addParam('mlt.qf', $component->getQueryFields());
$this->addParam('mlt.count', $component->getCount());
}
/**
* Add params for DisMax
*
* @param Solarium_Query_Select_Component_DisMax $component
* @return void
*/
public function addDisMax($component)
{
// enable dismax
$this->_params['defType'] = 'dismax';
$this->addParam('q.alt', $component->getQueryAlternative());
$this->addParam('qf', $component->getQueryFields());
$this->addParam('mm', $component->getMinimumMatch());
$this->addParam('pf', $component->getPhraseFields());
$this->addParam('ps', $component->getPhraseSlop());
$this->addParam('qs', $component->getQueryPhraseSlop());
$this->addParam('tie', $component->getTie());
$this->addParam('bq', $component->getBoostQuery());
$this->addParam('bf', $component->getBoostFunctions());
}
/**
* Add params for highlighting
*
* @param Solarium_Query_Select_Component_Highlighting $component
* @return void
*/
public function addHighlighting($component)
{
// enable highlighting
$this->_params['hl'] = 'true';
$this->addParam('hl.fl', $component->getFields());
$this->addParam('hl.snippets', $component->getSnippets());
$this->addParam('hl.fragsize', $component->getFragSize());
$this->addParam('hl.mergeContiguous', $component->getMergeContiguous());
$this->addParam('hl.requireFieldMatch', $component->getRequireFieldMatch());
$this->addParam('hl.maxAnalyzedChars', $component->getMaxAnalyzedChars());
$this->addParam('hl.alternateField', $component->getAlternateField());
$this->addParam('hl.maxAlternateFieldLength', $component->getMaxAlternateFieldLength());
$this->addParam('hl.formatter', $component->getFormatter());
$this->addParam('hl.simple.pre', $component->getSimplePrefix());
$this->addParam('hl.simple.post', $component->getSimplePostfix());
$this->addParam('hl.fragmenter', $component->getFragmenter());
$this->addParam('hl.fragListBuilder', $component->getFragListBuilder());
$this->addParam('hl.fragmentsBuilder', $component->getFragmentsBuilder());
$this->addParam('hl.useFastVectorHighlighter', $component->getUseFastVectorHighlighter());
$this->addParam('hl.usePhraseHighlighter', $component->getUsePhraseHighlighter());
$this->addParam('hl.highlightMultiTerm', $component->getHighlightMultiTerm());
$this->addParam('hl.regex.slop', $component->getRegexSlop());
$this->addParam('hl.regex.pattern', $component->getRegexPattern());
$this->addParam('hl.regex.maxAnalyzedChars', $component->getRegexMaxAnalyzedChars());
}
}
\ No newline at end of file
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
*
* @package Solarium
* @subpackage Client
*/
/**
* Add select component Highlighting to the request
*
* @package Solarium
* @subpackage Client
*/
class Solarium_Client_RequestBuilder_Select_Component_Highlighting
{
/**
* Add request settings for Highlighting
*
* @param Solarium_Query_Select_Component_Highlighting $component
* @param Solarium_Client_Request $request
* @return Solarium_Client_Request
*/
public function build($component, $request)
{
// enable highlighting
$request->addParam('hl', 'true');
$request->addParam('hl.fl', $component->getFields());
$request->addParam('hl.snippets', $component->getSnippets());
$request->addParam('hl.fragsize', $component->getFragSize());
$request->addParam('hl.mergeContiguous', $component->getMergeContiguous());
$request->addParam('hl.requireFieldMatch', $component->getRequireFieldMatch());
$request->addParam('hl.maxAnalyzedChars', $component->getMaxAnalyzedChars());
$request->addParam('hl.alternateField', $component->getAlternateField());
$request->addParam('hl.maxAlternateFieldLength', $component->getMaxAlternateFieldLength());
$request->addParam('hl.formatter', $component->getFormatter());
$request->addParam('hl.simple.pre', $component->getSimplePrefix());
$request->addParam('hl.simple.post', $component->getSimplePostfix());
$request->addParam('hl.fragmenter', $component->getFragmenter());
$request->addParam('hl.fragListBuilder', $component->getFragListBuilder());
$request->addParam('hl.fragmentsBuilder', $component->getFragmentsBuilder());
$request->addParam('hl.useFastVectorHighlighter', $component->getUseFastVectorHighlighter());
$request->addParam('hl.usePhraseHighlighter', $component->getUsePhraseHighlighter());
$request->addParam('hl.highlightMultiTerm', $component->getHighlightMultiTerm());
$request->addParam('hl.regex.slop', $component->getRegexSlop());
$request->addParam('hl.regex.pattern', $component->getRegexPattern());
$request->addParam('hl.regex.maxAnalyzedChars', $component->getRegexMaxAnalyzedChars());
return $request;
}
}
\ No newline at end of file
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
*
* @package Solarium
* @subpackage Client
*/
/**
* Add select component morelikethis to the request
*
* @package Solarium
* @subpackage Client
*/
class Solarium_Client_RequestBuilder_Select_Component_MoreLikeThis
{
/**
* Add request settings for morelikethis
*
* @param Solarium_Query_Select_Component_MoreLikeThis $component
* @param Solarium_Client_Request $request
* @return Solarium_Client_Request
*/
public function build($component, $request)
{
// enable morelikethis
$request->addParam('mlt','true');
$request->addParam('mlt.fl', $component->getFields());
$request->addParam('mlt.mintf', $component->getMinimumTermFrequency());
$request->addParam('mlt.mindf', $component->getMinimumDocumentFrequency());
$request->addParam('mlt.minwl', $component->getMinimumWordLength());
$request->addParam('mlt.maxwl', $component->getMaximumWordLength());
$request->addParam('mlt.maxqt', $component->getMaximumQueryTerms());
$request->addParam('mlt.maxntp', $component->getMaximumNumberOfTokens());
$request->addParam('mlt.boost', $component->getBoost());
$request->addParam('mlt.qf', $component->getQueryFields());
$request->addParam('mlt.count', $component->getCount());
return $request;
}
}
\ No newline at end of file
......@@ -41,7 +41,7 @@
* @package Solarium
* @subpackage Client
*/
class Solarium_Client_Request_Update extends Solarium_Client_Request
class Solarium_Client_RequestBuilder_Update extends Solarium_Client_RequestBuilder
{
/**
......
......@@ -36,63 +36,124 @@
*/
/**
* Base class for handling Solr HTTP responses
*
* Most {@link Solarium_Client_Adapter} implementations will use HTTP for
* communicating with Solr. While the HTTP part is adapter-specific, the parsing
* of the response into Solarium_Result classes is not. This abstract class is
* the base for several response handlers that do just that for the various
* querytypes.
* Class for describing a response
*
* @package Solarium
* @subpackage Client
*/
abstract class Solarium_Client_Response
class Solarium_Client_Response
{
/**
* Query instance
* Headers
*
* The query that was used for executing a request that led to this
* response. The query holds important settings for generating the right
* result, like the resultclass and documentclass settings.
* @var array
*/
protected $_headers;
/**
* Body
*
* @var Solarium_Query
* @var string
*/
protected $_query;
protected $_body;
/**
* Response data
* HTTP response code
*
* A (json)decoded HTTP response body data array.
* @var int
*/
protected $_statusCode;
/**
* HTTP response message
*
* @var array
* @var string
*/
protected $_data;
protected $_statusMessage;
/**
* Constructor
*
* @param Solarium_Query $query Query instance that was used for the request
* @param array $data Decoded data array of the HTTP response
* @param string $body
* @param array $headers
*/
public function __construct($query, $data = null)
public function __construct($body, $headers = array())
{
$this->_query = $query;
$this->_data = $data;
$this->_body = $body;
$this->_headers = $headers;
$this->_setHeaders($headers);
}
/**
* Get a Solarium_Result instance for the response
* Get body data
*
* When this method is called the actual response parsing is started.
* @return string
*/
public function getBody()
{
return $this->_body;
}
/**
* Get response headers
*
* @internal Must be implemented in descendents because this parsing is
* query specific.
* @return array
*/
public function getHeaders()
{
return $this->_headers;
}
/**
* Get status code
*
* @abstract
* @return mixed
* @return int
*/
abstract function getResult();
public function getStatusCode()
{
return $this->_statusCode;
}
/**
* Get status message
*
* @return string
*/
public function getStatusMessage()
{
return $this->_statusMessage;
}
/**
* Set headers
*
* @param array $headers
* @return void
*/
public function _setHeaders($headers)
{
$this->_headers = $headers;
// get the status header
$statusHeader = null;
foreach ($headers AS $header) {
if (substr($header, 0, 4) == 'HTTP') {
$statusHeader = $header;
break;
}
}
if (null == $statusHeader) {
throw new Solarium_Client_HttpException("No HTTP status found");
}
// parse header like "$statusInfo[1]" into code and message
// $statusInfo[1] = the HTTP response code
// $statusInfo[2] = the response message
$statusInfo = explode(' ', $statusHeader, 3);
$this->_statusCode = $statusInfo[1];
$this->_statusMessage = $statusInfo[2];
}
}
\ No newline at end of file
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
*
* @package Solarium
* @subpackage Client
*/
/**
* Base class for handling Solr response data
*
* Most {@link Solarium_Client_Adapter} implementations will use HTTP for
* communicating with Solr. While the HTTP part is adapter-specific, the parsing
* of the response into Solarium_Result classes is not. This abstract class is
* the base for several response handlers that do just that for the various
* querytypes.
*
* @package Solarium
* @subpackage Client
*/
abstract class Solarium_Client_ResponseParser
{
/**
* Get a Solarium_Result instance for the given data
*
* When this method is called the actual response parsing is started.
*
* @internal Must be implemented in descendents because this parsing is
* query specific.
*
* @abstract
*
* @param Solarium_Result $result
* @return mixed
*/
abstract function parse($result);
}
\ No newline at end of file
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
*
* @package Solarium
* @subpackage Client
*/
/**
* Parse select response data
*
* @package Solarium
* @subpackage Client
*/
class Solarium_Client_ResponseParser_Select extends Solarium_Client_ResponseParser
{
/**
* Get result data for the response
*
* @param Solarium_Result_Select $result
* @return array
*/
public function parse($result)
{
$data = $result->getData();
$query = $result->getQuery();
// reset arrays
$this->_components = array();
// create document instances
$documentClass = $query->getOption('documentclass');
$documents = array();
if (isset($data['response']['docs'])) {
foreach ($data['response']['docs'] AS $doc) {
$fields = (array)$doc;
$documents[] = new $documentClass($fields);
}
}
// component results
$components = array();
$types = $query->getComponentTypes();
foreach ($query->getComponents() as $component) {
$componentParserClass = $types[$component->getType()]['responseparser'];
if (!empty($componentParserClass)) {
// todo add caching?
$componentParser = new $componentParserClass;
$components[$component->getType()] = $componentParser->parse($query, $component, $data);
}
}
return array(
'status' => $data['responseHeader']['status'],
'querytime' => $data['responseHeader']['QTime'],
'numfound' => $data['response']['numFound'],
'documents' => $documents,
'components' => $components,
);
}
}
\ No newline at end of file
......@@ -36,121 +36,63 @@
*/
/**
* Parse select response data
*
* Will create a result object based on response data of the type
* {@Solarium_Result_Select} (or your own resultclass setting)
* Parse select component FacetSet result from the data
*
* @package Solarium
* @subpackage Client
*/
class Solarium_Client_Response_Select extends Solarium_Client_Response
class Solarium_Client_ResponseParser_Select_Component_FacetSet
{
/**
* Facet results
*
* Filled by the _addFacet* methods (for instance {@_addFacetField()})
* Parse result data into result objects
*
* @var array
* @param Solarium_Query_Select $query
* @param Solarium_Query_Select_Component_FacetSet $facetSet
* @param array $data
* @return Solarium_Result_Select_FacetSet
*/
protected $_facets = array();
/**
* Component results
*
* @var array
*/
protected $_components = array();
/**
* Get a result instance for the response
*
* When this method is called the actual response parsing is done.
*
* @return mixed
*/
public function getResult()
{
// create document instances
$documentClass = $this->_query->getOption('documentclass');
$documents = array();
if (isset($this->_data['response']['docs'])) {
foreach ($this->_data['response']['docs'] AS $doc) {
$fields = (array)$doc;
$documents[] = new $documentClass($fields);
}
}
// component results
foreach ($this->_query->getComponents() as $component) {
switch ($component->getType())
{
case Solarium_Query_Select_Component::MORELIKETHIS:
$this->_addMoreLikeThis($component);
break;
case Solarium_Query_Select_Component::FACETSET:
$this->_addFacetSet($component);
break;
case Solarium_Query_Select_Component::DISMAX:
// no result action needed
break;
case Solarium_Query_Select_Component::HIGHLIGHTING:
$this->_addHighlighting($component);
break;
default:
throw new Solarium_Exception('Unknown component type');
}
}
// add general data
$status = $this->_data['responseHeader']['status'];
$queryTime = $this->_data['responseHeader']['QTime'];
$numFound = $this->_data['response']['numFound'];
// create the result instance that combines all data
$resultClass = $this->_query->getOption('resultclass');
return new $resultClass(
$status, $queryTime, $numFound, $documents, $this->_facets, $this->_components
);
}
protected function _addFacetSet($facetSet)
public function parse($query, $facetSet, $data)
{
// create facet results
foreach ($facetSet->getFacets() AS $facet) {
$facets = array();
foreach ($facetSet->getFacets() AS $key => $facet) {
switch ($facet->getType()) {
case Solarium_Query_Select_Component_Facet::FIELD:
$this->_addFacetField($facet);
$result = $this->_facetField($facet, $data);
break;
case Solarium_Query_Select_Component_Facet::QUERY:
$this->_addFacetQuery($facet);
$result = $this->_facetQuery($facet, $data);
break;
case Solarium_Query_Select_Component_Facet::MULTIQUERY:
$this->_addFacetMultiQuery($facet);
$result = $this->_facetMultiQuery($facet, $data);
break;
case Solarium_Query_Select_Component_Facet::RANGE:
$this->_addFacetRange($facet);
$result = $this->_facetRange($facet, $data);
break;
default:
throw new Solarium_Exception('Unknown facet type');
}
if($result !== null) $facets[$key] = $result;
}
return new Solarium_Result_Select_FacetSet($facets);
}
/**
* Add a facet result for a field facet
*
* @param Solarium_Query_Select_Component_Facet_Field $facet
* @param array $data
* @return void
*/
protected function _addFacetField($facet)
protected function _facetField($facet, $data)
{
$key = $facet->getKey();
if (isset($this->_data['facet_counts']['facet_fields'][$key])) {
if (isset($data['facet_counts']['facet_fields'][$key])) {
$values = array_chunk(
$this->_data['facet_counts']['facet_fields'][$key],
$data['facet_counts']['facet_fields'][$key],
2
);
......@@ -159,8 +101,7 @@ class Solarium_Client_Response_Select extends Solarium_Client_Response
$facetValues[$value[0]] = $value[1];
}
$this->_facets[$key] =
new Solarium_Result_Select_Facet_Field($facetValues);
return new Solarium_Result_Select_Facet_Field($facetValues);
}
}
......@@ -168,16 +109,16 @@ class Solarium_Client_Response_Select extends Solarium_Client_Response
* Add a facet result for a facet query
*
* @param Solarium_Query_Select_Component_Facet_Query $facet
* @param array $data
* @return void
*/
protected function _addFacetQuery($facet)
protected function _facetQuery($facet, $data)
{
$key = $facet->getKey();
if (isset($this->_data['facet_counts']['facet_queries'][$key])) {
if (isset($data['facet_counts']['facet_queries'][$key])) {
$value = $this->_data['facet_counts']['facet_queries'][$key];
$this->_facets[$key] =
new Solarium_Result_Select_Facet_Query($value);
$value = $data['facet_counts']['facet_queries'][$key];
return new Solarium_Result_Select_Facet_Query($value);
}
}
......@@ -185,21 +126,21 @@ class Solarium_Client_Response_Select extends Solarium_Client_Response
* Add a facet result for a multiquery facet
*
* @param Solarium_Query_Select_Component_Facet_MultiQuery $facet
* @param array $data
* @return void
*/
protected function _addFacetMultiQuery($facet)
protected function _facetMultiQuery($facet, $data)
{
$values = array();
foreach ($facet->getQueries() AS $query) {
$key = $query->getKey();
if (isset($this->_data['facet_counts']['facet_queries'][$key])) {
$count = $this->_data['facet_counts']['facet_queries'][$key];
if (isset($data['facet_counts']['facet_queries'][$key])) {
$count = $data['facet_counts']['facet_queries'][$key];
$values[$key] = $count;
}
}
$this->_facets[$facet->getKey()] =
new Solarium_Result_Select_Facet_MultiQuery($values);
return new Solarium_Result_Select_Facet_MultiQuery($values);
}
......@@ -207,80 +148,22 @@ class Solarium_Client_Response_Select extends Solarium_Client_Response
* Add a facet result for a range facet
*
* @param Solarium_Query_Select_Component_Facet_Range $facet
* @param array $data
* @return void
*/
protected function _addFacetRange($facet)
protected function _facetRange($facet, $data)
{
$key = $facet->getKey();
if (isset($this->_data['facet_counts']['facet_ranges'][$key])) {
if (isset($data['facet_counts']['facet_ranges'][$key])) {
$data = $this->_data['facet_counts']['facet_ranges'][$key];
$data = $data['facet_counts']['facet_ranges'][$key];
$before = (isset($data['before'])) ? $data['before'] : null;
$after = (isset($data['after'])) ? $data['after'] : null;
$between = (isset($data['after'])) ? $data['after'] : null;
$this->_facets[$key] =
new Solarium_Result_Select_Facet_Range($data['counts'], $before, $after, $between);
}
}
/**
* Add morelikethis result
*
* @param Solarium_Query_Select_Component_MoreLikeThis $component
* @return void
*/
protected function _addMoreLikeThis($component)
{
$results = array();
if (isset($this->_data['moreLikeThis'])) {
$documentClass = $this->_query->getOption('documentclass');
$searchResults = $this->_data['moreLikeThis'];
foreach ($searchResults AS $key => $result) {
// create document instances
$docs = array();
foreach ($result['docs'] AS $fields) {
$docs[] = new $documentClass($fields);
}
$results[$key] = new Solarium_Result_Select_MoreLikeThis_Result(
$result['numFound'],
$result['maxScore'],
$docs
);
}
return new Solarium_Result_Select_Facet_Range($data['counts'], $before, $after, $between);
}
$moreLikeThis = new Solarium_Result_Select_MoreLikeThis($results);
$this->_components[$component->getType()] = $moreLikeThis;
}
/**
* Add highlighting result
*
* @param Solarium_Query_Select_Component_Highlighting $component
* @return void
*/
protected function _addHighlighting($component)
{
$results = array();
if (isset($this->_data['highlighting'])) {
$highlightResults = $this->_data['highlighting'];
foreach ($highlightResults AS $key => $result) {
$results[$key] = new Solarium_Result_Select_Highlighting_Result(
$result
);
}
}
$highlighting = new Solarium_Result_Select_Highlighting($results);
$this->_components[$component->getType()] = $highlighting;
}
}
\ No newline at end of file
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
*
* @package Solarium
* @subpackage Client
*/
/**
* Parse select component Highlighting result from the data
*
* @package Solarium
* @subpackage Client
*/
class Solarium_Client_ResponseParser_Select_Component_Highlighting
{
/**
* Parse result data into result objects
*
* @param Solarium_Query_Select $query
* @param Solarium_Query_Select_Component_Highlighting $highlighting
* @param array $data
* @return Solarium_Result_Select_Highlighting
*/
public function parse($query, $highlighting, $data)
{
$results = array();
if (isset($data['highlighting'])) {
$highlightResults = $data['highlighting'];
foreach ($highlightResults AS $key => $result) {
$results[$key] = new Solarium_Result_Select_Highlighting_Result(
$result
);
}
}
return new Solarium_Result_Select_Highlighting($results);
}
}
\ No newline at end of file
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
*
* @package Solarium
* @subpackage Client
*/
/**
* Parse select component MoreLikeThis result from the data
*
* @package Solarium
* @subpackage Client
*/
class Solarium_Client_ResponseParser_Select_Component_MoreLikeThis
{
/**
* Parse result data into result objects
*
* @param Solarium_Query_Select $query
* @param Solarium_Query_Select_Component_MoreLikeThis $moreLikeThis
* @param array $data
* @return Solarium_Result_Select_MoreLikeThis
*/
public function parse($query, $moreLikeThis, $data)
{
$results = array();
if (isset($data['moreLikeThis'])) {
$documentClass = $query->getOption('documentclass');
$searchResults = $data['moreLikeThis'];
foreach ($searchResults AS $key => $result) {
// create document instances
$docs = array();
foreach ($result['docs'] AS $fields) {
$docs[] = new $documentClass($fields);
}
$results[$key] = new Solarium_Result_Select_MoreLikeThis_Result(
$result['numFound'],
$result['maxScore'],
$docs
);
}
}
return new Solarium_Result_Select_MoreLikeThis($results);
}
}
\ No newline at end of file
......@@ -38,29 +38,27 @@
/**
* Parse update response data
*
* Will create a result object based on response data of the type
* {@Solarium_Result_Update} (or your own resultclass setting)
*
* @package Solarium
* @subpackage Client
*/
class Solarium_Client_Response_Update extends Solarium_Client_Response
class Solarium_Client_ResponseParser_Update extends Solarium_Client_ResponseParser
{
/**
* Get a result instance for the response
*
* When this method is called the actual response parsing is done.
* Parse response data
*
* @return mixed
* @param Solarium_Result_Select $result
* @return array
*/
public function getResult()
public function parse($result)
{
$resultClass = $this->_query->getOption('resultclass');
$data = $result->getData();
$query = $result->getQuery();
$resultClass = $query->getResultClass();
return new $resultClass(
$this->_data['responseHeader']['status'],
$this->_data['responseHeader']['QTime']
return array(
'status' => $data['responseHeader']['status'],
'querytime' => $data['responseHeader']['QTime'],
);
}
......
......@@ -58,7 +58,7 @@ class Solarium_Configurable
* Constructor
*
* If options are passed they will be merged with {@link $_options} using
* the {@link _setOptions()} method.
* the {@link setOptions()} method.
*
* After handling the options the {@link _init()} method is called.
*
......@@ -68,7 +68,7 @@ class Solarium_Configurable
*/
public function __construct($options = null)
{
$this->_setOptions($options);
$this->setOptions($options);
$this->_init();
}
......@@ -87,7 +87,7 @@ class Solarium_Configurable
*
* @return void
*/
protected function _setOptions($options, $overwrite = false)
public function setOptions($options, $overwrite = false)
{
if (null !== $options) {
// first convert to array if needed
......@@ -105,6 +105,9 @@ class Solarium_Configurable
} else {
$this->_options = array_merge($this->_options, $options);
}
// re-init for new options
$this->_init();
}
}
......
......@@ -41,8 +41,15 @@
* @package Solarium
* @subpackage Query
*/
class Solarium_Query extends Solarium_Configurable
abstract class Solarium_Query extends Solarium_Configurable
{
/**
* Get type for this query
*
* @return string
*/
abstract public function getType();
/**
* Set handler option
......
......@@ -48,6 +48,16 @@
class Solarium_Query_Ping extends Solarium_Query
{
/**
* Get type for this query
*
* @return string
*/
public function getType()
{
return Solarium_Client::QUERYTYPE_PING;
}
/**
* Default options
*
......
......@@ -54,6 +54,24 @@ class Solarium_Query_Select extends Solarium_Query
const SORT_DESC = 'desc';
const SORT_ASC = 'asc';
/**
* Query components
*/
const COMPONENT_FACETSET = 'facetset';
const COMPONENT_DISMAX = 'dismax';
const COMPONENT_MORELIKETHIS = 'morelikethis';
const COMPONENT_HIGHLIGHTING = 'highlighting';
/**
* Get type for this query
*
* @return string
*/
public function getType()
{
return Solarium_Client::QUERYTYPE_SELECT;
}
/**
* Default options
*
......@@ -69,6 +87,34 @@ class Solarium_Query_Select extends Solarium_Query
'fields' => '*,score',
);
/**
* Default select query component types
*
* @var array
*/
protected $_componentTypes = array(
self::COMPONENT_FACETSET => array(
'component' => 'Solarium_Query_Select_Component_FacetSet',
'requestbuilder' => 'Solarium_Client_RequestBuilder_Select_Component_FacetSet',
'responseparser' => 'Solarium_Client_ResponseParser_Select_Component_FacetSet',
),
self::COMPONENT_DISMAX => array(
'component' => 'Solarium_Query_Select_Component_DisMax',
'requestbuilder' => 'Solarium_Client_RequestBuilder_Select_Component_DisMax',
'responseparser' => null,
),
self::COMPONENT_MORELIKETHIS => array(
'component' => 'Solarium_Query_Select_Component_MoreLikeThis',
'requestbuilder' => 'Solarium_Client_RequestBuilder_Select_Component_MoreLikeThis',
'responseparser' => 'Solarium_Client_ResponseParser_Select_Component_MoreLikeThis',
),
self::COMPONENT_HIGHLIGHTING => array(
'component' => 'Solarium_Query_Select_Component_Highlighting',
'requestbuilder' => 'Solarium_Client_RequestBuilder_Select_Component_Highlighting',
'responseparser' => 'Solarium_Client_ResponseParser_Select_Component_Highlighting',
),
);
/**
* Fields to fetch
*
......@@ -537,6 +583,36 @@ class Solarium_Query_Select extends Solarium_Query
$this->addFilterQueries($filterQueries);
}
/**
* Get all registered component types
*
* @return array
*/
public function getComponentTypes()
{
return $this->_componentTypes;
}
/**
* Register a component type
*
* @param string $key
* @param string $component
* @param string $requestBuilder
* @param string $responseParser
* @return Solarium_Query Provides fluent interface
*/
public function registerComponentType($key, $component, $requestBuilder=null, $responseParser=null)
{
$this->_componentTypes[$key] = array(
'component' => $component,
'requestbuilder' => $requestBuilder,
'responseparser' => $responseParser,
);
return $this;
}
/**
* Get all registered components
*
......@@ -566,16 +642,16 @@ class Solarium_Query_Select extends Solarium_Query
if ($autoload == true) {
switch ($key) {
case Solarium_Query_Select_Component::MORELIKETHIS:
case Solarium_Query_Select::COMPONENT_MORELIKETHIS:
$className = 'Solarium_Query_Select_Component_MoreLikeThis';
break;
case Solarium_Query_Select_Component::FACETSET:
case Solarium_Query_Select::COMPONENT_FACETSET:
$className = 'Solarium_Query_Select_Component_FacetSet';
break;
case Solarium_Query_Select_Component::DISMAX:
case Solarium_Query_Select::COMPONENT_DISMAX:
$className = 'Solarium_Query_Select_Component_DisMax';
break;
case Solarium_Query_Select_Component::HIGHLIGHTING:
case Solarium_Query_Select::COMPONENT_HIGHLIGHTING:
$className = 'Solarium_Query_Select_Component_Highlighting';
break;
default:
......@@ -642,7 +718,7 @@ class Solarium_Query_Select extends Solarium_Query
*/
public function getMoreLikeThis()
{
return $this->getComponent(Solarium_Query_Select_Component::MORELIKETHIS, true);
return $this->getComponent(Solarium_Query_Select::COMPONENT_MORELIKETHIS, true);
}
/**
......@@ -654,7 +730,7 @@ class Solarium_Query_Select extends Solarium_Query
*/
public function getFacetSet()
{
return $this->getComponent(Solarium_Query_Select_Component::FACETSET, true);
return $this->getComponent(Solarium_Query_Select::COMPONENT_FACETSET, true);
}
/**
......@@ -666,7 +742,7 @@ class Solarium_Query_Select extends Solarium_Query
*/
public function getDisMax()
{
return $this->getComponent(Solarium_Query_Select_Component::DISMAX, true);
return $this->getComponent(Solarium_Query_Select::COMPONENT_DISMAX, true);
}
/**
......@@ -678,7 +754,7 @@ class Solarium_Query_Select extends Solarium_Query
*/
public function getHighlighting()
{
return $this->getComponent(Solarium_Query_Select_Component::HIGHLIGHTING, true);
return $this->getComponent(Solarium_Query_Select::COMPONENT_HIGHLIGHTING, true);
}
/**
......
......@@ -44,14 +44,6 @@
class Solarium_Query_Select_Component extends Solarium_Configurable
{
/**
* Component types
*/
const MORELIKETHIS = 'morelikethis';
const FACETSET = 'facetset';
const DISMAX = 'dismax';
const HIGHLIGHTING = 'highlighting';
/**
* Component type
*
......
......@@ -51,7 +51,7 @@ class Solarium_Query_Select_Component_DisMax extends Solarium_Query_Select_Compo
*
* @var string
*/
protected $_type = self::DISMAX;
protected $_type = Solarium_Query_Select::COMPONENT_DISMAX;
/**
* Set QueryAlternative option
......
......@@ -51,7 +51,7 @@ class Solarium_Query_Select_Component_FacetSet extends Solarium_Query_Select_Com
*
* @var string
*/
protected $_type = self::FACETSET;
protected $_type = Solarium_Query_Select::COMPONENT_FACETSET;
/**
* Default options
......
......@@ -56,7 +56,7 @@ class Solarium_Query_Select_Component_Highlighting extends Solarium_Query_Select
*
* @var string
*/
protected $_type = self::HIGHLIGHTING;
protected $_type = Solarium_Query_Select::COMPONENT_HIGHLIGHTING;
/**
* Set fields option
......
......@@ -51,7 +51,7 @@ class Solarium_Query_Select_Component_MoreLikeThis extends Solarium_Query_Select
*
* @var string
*/
protected $_type = self::MORELIKETHIS;
protected $_type = Solarium_Query_Select::COMPONENT_MORELIKETHIS;
/**
* Set fields option
......
......@@ -48,6 +48,16 @@
class Solarium_Query_Update extends Solarium_Query
{
/**
* Get type for this query
*
* @return string
*/
public function getType()
{
return Solarium_Client::QUERYTYPE_UPDATE;
}
/**
* Default options
*
......
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
*
* @package Solarium
* @subpackage Result
*/
/**
* Query result
*
* This base class provides access to the response and decoded data. If you need more functionality
* like resultset parsing use one of the subclasses
*
* @package Solarium
* @subpackage Result
*/
class Solarium_Result
{
/**
* Response object
*
* @var Solarium_Client_Response
*/
protected $_response;
/**
* Decode response data
*
* This is lazy loaded, see getData()
*
* @var array
*/
protected $_data;
/**
* Query used for this request
*
* @var Solarium_Query
*/
protected $_query;
/**
* @var Solarium_Client
*/
protected $_client;
/**
* Constructor
*
* @param Solarium_Client $client
* @param Solarium_Query $query
* @param Solarium_Client_Response $response
* @return void
*/
public function __construct($client, $query, $response)
{
$this->_client = $client;
$this->_query = $query;
$this->_response = $response;
// check status for error (range of 400 and 500)
$statusNum = floor($response->getStatusCode() / 100);
if ($statusNum == 4 || $statusNum == 5) {
throw new Solarium_Client_HttpException(
$response->getStatusMessage(),
$response->getStatusCode()
);
}
}
/**
* Get response object
*
* This is the raw HTTP response object, not the parsed data!
*
* @return Solarium_Client_Response
*/
public function getResponse()
{
return $this->_response;
}
/**
* Get query instance
*
* @return Solarium_Query
*/
public function getQuery()
{
return $this->_query;
}
/**
* Get Solr response data
*
* Included a lazy loading mechanism: JSON body data is decoded on first use and then saved for reuse.
*
* @return array
*/
public function getData()
{
if (null == $this->_data) {
$this->_data = json_decode($this->_response->getBody(), true);
if (null === $this->_data) {
throw new Solarium_Exception(
'Solr JSON response could not be decoded'
);
}
}
return $this->_data;
}
}
\ No newline at end of file
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
*
* @package Solarium
* @subpackage Result
*/
/**
* QueryType result
*
* TODO intro
*
* @package Solarium
* @subpackage Result
*/
class Solarium_Result_QueryType extends Solarium_Result
{
/**
* Lazy load parsing indicator
*
* @var bool
*/
protected $_parsed = false;
/**
* Parse response into result objects
*
* Only runs once
*
* @return void
*/
protected function _parseResponse()
{
if (!$this->_parsed) {
$queryType = $this->_query->getType();
$queryTypes = $this->_client->getQueryTypes();
if (!isset($queryTypes[$queryType])) {
throw new Solarium_Exception('No responseparser registered for querytype: '. $queryType);
}
$responseParserClass = $queryTypes[$queryType]['responseparser'];
$responseParser = new $responseParserClass;
$this->_mapData($responseParser->parse($this));
}
}
/**
* Map parser data into properties
*
* @param array $mapData
* @return void
*/
protected function _mapData($mapData)
{
foreach($mapData AS $key => $data) {
$this->{'_'.$key} = $data;
}
}
}
\ No newline at end of file
......@@ -58,7 +58,7 @@
* @package Solarium
* @subpackage Result
*/
class Solarium_Result_Select extends Solarium_Result_Query
class Solarium_Result_Select extends Solarium_Result_QueryType
implements IteratorAggregate, Countable
{
......@@ -69,7 +69,7 @@ class Solarium_Result_Select extends Solarium_Result_Query
*
* @var int
*/
protected $_numFound;
protected $_numfound;
/**
* Document instances array
......@@ -78,43 +78,11 @@ class Solarium_Result_Select extends Solarium_Result_Query
*/
protected $_documents;
/**
* Facet result instances
*
* @var array
*/
protected $_facets;
/**
* Component results
*/
protected $_components;
/**
* Constructor
*
* This is the only point where data can be set in this immutable value
* object.
*
* @param int $status
* @param int $queryTime
* @param int $numFound
* @param array $documents
* @param array $facets
* @param array $components
* @return void
*/
public function __construct($status, $queryTime, $numFound, $documents,
$facets, $components)
{
$this->_status = $status;
$this->_queryTime = $queryTime;
$this->_numFound = $numFound;
$this->_documents = $documents;
$this->_facets = $facets;
$this->_components = $components;
}
/**
* get Solr numFound
*
......@@ -125,7 +93,9 @@ class Solarium_Result_Select extends Solarium_Result_Query
*/
public function getNumFound()
{
return $this->_numFound;
$this->_parseResponse();
return $this->_numfound;
}
/**
......@@ -135,32 +105,9 @@ class Solarium_Result_Select extends Solarium_Result_Query
*/
public function getDocuments()
{
return $this->_documents;
}
/**
* Get all facet results
*
* @return array
*/
public function getFacets()
{
return $this->_facets;
}
$this->_parseResponse();
/**
* Get a facet result by key
*
* @param string $key
* @return Solarium_Result_Select_Facet
*/
public function getFacet($key)
{
if (isset($this->_facets[$key])) {
return $this->_facets[$key];
} else {
return null;
}
return $this->_documents;
}
/**
......@@ -170,6 +117,8 @@ class Solarium_Result_Select extends Solarium_Result_Query
*/
public function getIterator()
{
$this->_parseResponse();
return new ArrayIterator($this->_documents);
}
......@@ -180,6 +129,8 @@ class Solarium_Result_Select extends Solarium_Result_Query
*/
public function count()
{
$this->_parseResponse();
return count($this->_documents);
}
......@@ -190,6 +141,8 @@ class Solarium_Result_Select extends Solarium_Result_Query
*/
public function getComponents()
{
$this->_parseResponse();
return $this->_components;
}
......@@ -201,6 +154,8 @@ class Solarium_Result_Select extends Solarium_Result_Query
*/
public function getComponent($key)
{
$this->_parseResponse();
if (isset($this->_components[$key])) {
return $this->_components[$key];
} else {
......@@ -217,7 +172,7 @@ class Solarium_Result_Select extends Solarium_Result_Query
*/
public function getMoreLikeThis()
{
return $this->getComponent(Solarium_Query_Select_Component::MORELIKETHIS);
return $this->getComponent(Solarium_Query_Select::COMPONENT_MORELIKETHIS);
}
/**
......@@ -229,6 +184,18 @@ class Solarium_Result_Select extends Solarium_Result_Query
*/
public function getHighlighting()
{
return $this->getComponent(Solarium_Query_Select_Component::HIGHLIGHTING);
return $this->getComponent(Solarium_Query_Select::COMPONENT_HIGHLIGHTING);
}
/**
* Get facetset component result
*
* This is a convenience method that maps presets to getComponent
*
* @return Solarium_Result_Select_Component_FacetSet
*/
public function getFacetSet()
{
return $this->getComponent(Solarium_Query_Select::COMPONENT_HIGHLIGHTING);
}
}
\ No newline at end of file
......@@ -36,69 +36,74 @@
*/
/**
* Query result
*
* This base class provides methods for two common result values: status and
* querytime.
* Select component facetset result
*
* @package Solarium
* @subpackage Result
*/
class Solarium_Result_Query
class Solarium_Result_Select_FacetSet implements IteratorAggregate, Countable
{
/**
* Status code returned by Solr
* Facet array
*
* @var int
* @var array
*/
protected $_status;
protected $_facets;
/**
* Solr index queryTime
*
* This doesn't include things like the HTTP responsetime. Purely the Solr
* query execution time.
* Constructor
*
* @var int
* @param array $facets
* @return void
*/
protected $_queryTime;
public function __construct($facets)
{
$this->_facets = $facets;
}
/**
* Constructor
* Get a facet by key
*
* @param int $status
* @param int $queryTime
* @return void
* @param mixed $key
* @return mixed
*/
public function __construct($status, $queryTime)
public function getFacet($key)
{
$this->_status = $status;
$this->_queryTime = $queryTime;
if (isset($this->_facets[$key])) {
return $this->_facets[$key];
} else {
return null;
}
}
/**
* Get Solr status code
* Get all results
*
* This is not the HTTP status code! The normal value for success is 0.
* @return array
*/
public function getFacets()
{
return $this->_facets;
}
/**
* IteratorAggregate implementation
*
* @return int
* @return ArrayIterator
*/
public function getStatus()
public function getIterator()
{
return $this->_status;
return new ArrayIterator($this->_facets);
}
/**
* Get Solr query time
* Countable implementation
*
* This doesn't include things like the HTTP responsetime. Purely the Solr
* query execution time.
*
* @return int
*/
public function getQueryTime()
public function count()
{
return $this->_queryTime;
return count($this->_facets);
}
}
\ No newline at end of file
......@@ -47,7 +47,7 @@
* @package Solarium
* @subpackage Result
*/
class Solarium_Result_Update extends Solarium_Result_Query
class Solarium_Result_Update extends Solarium_Result
{
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment