Commit 7d35e58a authored by Markus Kalkbrenner's avatar Markus Kalkbrenner Committed by GitHub

Improve re-usability of components for any any query type (#544)

parent c620d93b
<?php
namespace Solarium\Component;
/**
* Trait query types supporting components.
*/
interface ComponentAwareQueryInterface
{
/**
* Query component morelikethis.
*/
const COMPONENT_MORELIKETHIS = 'morelikethis';
/**
* Query component spellcheck.
*/
const COMPONENT_SPELLCHECK = 'spellcheck';
/**
* Query component spellcheck.
*/
const COMPONENT_SUGGESTER = 'suggest';
/**
* Query component debug.
*/
const COMPONENT_DEBUG = 'debug';
/**
* Query component spatial.
*/
const COMPONENT_SPATIAL = 'spatial';
/**
* Get all registered component types.
*
* @return array
*/
public function getComponentTypes();
/**
* Register a component type.
*
* @param string $key
* @param string $component
*
* @return self Provides fluent interface
*/
public function registerComponentType($key, $component);
/**
* Get all registered components.
*
* @return AbstractComponent[]
*/
public function getComponents();
/**
* Get a component instance by key.
*
* You can optionally supply an autoload class to create a new component
* instance if there is no registered component for the given key yet.
*
* @throws \Solarium\Exception\OutOfBoundsException
*
* @param string $key Use one of the constants
* @param string|boolean $autoload Class to autoload if component needs to be created
* @param array|null $config Configuration to use for autoload
*
* @return object|null
*/
public function getComponent($key, $autoload = false, $config = null);
/**
* Set a component instance.
*
* This overwrites any existing component registered with the same key.
*
* @param string $key
* @param AbstractComponent $component
*
* @return self Provides fluent interface
*/
public function setComponent($key, $component);
/**
* Remove a component instance.
*
* You can remove a component by passing its key or the component instance.
*
* @param string|AbstractComponent $component
*
* @return self Provides fluent interface
*/
public function removeComponent($component);
/**
* Get a MoreLikeThis component instance.
*
* This is a convenience method that maps presets to getComponent
*
* @return \Solarium\Component\MoreLikeThis
*/
public function getMoreLikeThis();
/**
* Get a spellcheck component instance.
*
* This is a convenience method that maps presets to getComponent
*
* @return \Solarium\Component\Spellcheck
*/
public function getSpellcheck();
/**
* Get a suggest component instance.
*
* This is a convenience method that maps presets to getComponent
*
* @return \Solarium\Component\Spellcheck
*/
public function getSuggester();
/**
* Get a Debug component instance.
*
* This is a convenience method that maps presets to getComponent
*
* @return \Solarium\Component\Debug
*/
public function getDebug();
/**
* Get a Spatial component instance.
*
* This is a convenience method that maps presets to getComponent
*
* @return \Solarium\Component\Spatial
*/
public function getSpatial();
}
<?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
*
* @link http://www.solarium-project.org/
*/
/**
* @namespace
*/
namespace Solarium\Component;
use Solarium\Core\Query\AbstractQuery;
use Solarium\Exception\OutOfBoundsException;
/**
* Base class for all query types supporting components, not intended for direct usage.
* Trait query types supporting components.
*/
abstract class AbstractComponentAwareQuery extends AbstractQuery
trait ComponentAwareQueryTrait
{
/**
* Query component morelikethis.
*/
const COMPONENT_MORELIKETHIS = 'morelikethis';
/**
* Query component spellcheck.
*/
const COMPONENT_SPELLCHECK = 'spellcheck';
/**
* Query component spellcheck.
*/
const COMPONENT_SUGGESTER = 'suggest';
/**
* Query component debug.
*/
const COMPONENT_DEBUG = 'debug';
/**
* Query component spatial.
*/
const COMPONENT_SPATIAL = 'spatial';
/**
* Search components.
*
* @var AbstractComponent[]
*/
protected $components = array();
protected $components = [];
/**
* Default select query component types.
*
* @var array
*/
protected $componentTypes = array(
self::COMPONENT_MORELIKETHIS => 'Solarium\Component\MoreLikeThis',
self::COMPONENT_SPELLCHECK => 'Solarium\Component\Spellcheck',
self::COMPONENT_SUGGESTER => 'Solarium\Component\Suggester',
self::COMPONENT_DEBUG => 'Solarium\Component\Debug',
self::COMPONENT_SPATIAL => 'Solarium\Component\Spatial',
);
protected $componentTypes = [];
/**
* Get all registered component types.
......@@ -146,8 +76,7 @@ abstract class AbstractComponentAwareQuery extends AbstractQuery
{
if (isset($this->components[$key])) {
return $this->components[$key];
} else {
if ($autoload === true) {
} elseif ($autoload === true) {
if (!isset($this->componentTypes[$key])) {
throw new OutOfBoundsException('Cannot autoload unknown component: '.$key);
}
......@@ -160,8 +89,7 @@ abstract class AbstractComponentAwareQuery extends AbstractQuery
return $component;
}
return;
}
return null;
}
/**
......@@ -230,7 +158,7 @@ abstract class AbstractComponentAwareQuery extends AbstractQuery
*/
public function getMoreLikeThis()
{
return $this->getComponent(self::COMPONENT_MORELIKETHIS, true);
return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_MORELIKETHIS, true);
}
/**
......@@ -242,7 +170,7 @@ abstract class AbstractComponentAwareQuery extends AbstractQuery
*/
public function getSpellcheck()
{
return $this->getComponent(self::COMPONENT_SPELLCHECK, true);
return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_SPELLCHECK, true);
}
/**
......@@ -254,7 +182,7 @@ abstract class AbstractComponentAwareQuery extends AbstractQuery
*/
public function getSuggester()
{
return $this->getComponent(self::COMPONENT_SUGGESTER, true);
return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_SUGGESTER, true);
}
/**
......@@ -266,7 +194,7 @@ abstract class AbstractComponentAwareQuery extends AbstractQuery
*/
public function getDebug()
{
return $this->getComponent(self::COMPONENT_DEBUG, true);
return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_DEBUG, true);
}
/**
......@@ -278,7 +206,7 @@ abstract class AbstractComponentAwareQuery extends AbstractQuery
*/
public function getSpatial()
{
return $this->getComponent(self::COMPONENT_SPATIAL, true);
return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_SPATIAL, true);
}
}
......@@ -57,7 +57,7 @@ class Debug extends AbstractComponent
*/
public function getType()
{
return AbstractComponentAwareQuery::COMPONENT_DEBUG;
return ComponentAwareQueryInterface::COMPONENT_DEBUG;
}
/**
......
......@@ -57,7 +57,7 @@ class MoreLikeThis extends AbstractComponent
*/
public function getType()
{
return AbstractComponentAwareQuery::COMPONENT_MORELIKETHIS;
return ComponentAwareQueryInterface::COMPONENT_MORELIKETHIS;
}
/**
......
......@@ -18,7 +18,7 @@ class Spatial extends AbstractComponent
*/
public function getType()
{
return AbstractComponentAwareQuery::COMPONENT_SPATIAL;
return ComponentAwareQueryInterface::COMPONENT_SPATIAL;
}
/**
......
......@@ -61,7 +61,7 @@ class Spellcheck extends AbstractComponent
*/
public function getType()
{
return AbstractComponentAwareQuery::COMPONENT_SPELLCHECK;
return ComponentAwareQueryInterface::COMPONENT_SPELLCHECK;
}
/**
......
......@@ -60,7 +60,7 @@ class Suggester extends AbstractComponent
*/
public function getType()
{
return AbstractComponentAwareQuery::COMPONENT_SUGGESTER;
return ComponentAwareQueryInterface::COMPONENT_SUGGESTER;
}
/**
......
......@@ -40,8 +40,10 @@
namespace Solarium\QueryType\Select\Query;
use Solarium\Component\AbstractComponentAwareQuery;
use Solarium\Component\ComponentAwareQueryInterface;
use Solarium\Component\ComponentAwareQueryTrait;
use Solarium\Core\Client\Client;
use Solarium\Core\Query\AbstractQuery;
use Solarium\QueryType\Select\RequestBuilder\RequestBuilder;
use Solarium\QueryType\Select\ResponseParser\ResponseParser;
use Solarium\Exception\InvalidArgumentException;
......@@ -53,8 +55,10 @@ use Solarium\Exception\InvalidArgumentException;
* lots of options and there are many Solarium subclasses for it.
* See the Solr documentation and the relevant Solarium classes for more info.
*/
class Query extends AbstractComponentAwareQuery
class Query extends AbstractQuery implements ComponentAwareQueryInterface
{
use ComponentAwareQueryTrait;
/**
* Solr sort mode descending.
*/
......@@ -133,26 +137,6 @@ class Query extends AbstractComponentAwareQuery
*/
protected $tags = array();
/**
* Default select query component types.
*
* @var array
*/
protected $componentTypes = array(
self::COMPONENT_FACETSET => 'Solarium\QueryType\Select\Query\Component\FacetSet',
self::COMPONENT_DISMAX => 'Solarium\QueryType\Select\Query\Component\DisMax',
self::COMPONENT_EDISMAX => 'Solarium\QueryType\Select\Query\Component\EdisMax',
parent::COMPONENT_MORELIKETHIS => 'Solarium\Component\MoreLikeThis',
self::COMPONENT_HIGHLIGHTING => 'Solarium\QueryType\Select\Query\Component\Highlighting\Highlighting',
self::COMPONENT_GROUPING => 'Solarium\QueryType\Select\Query\Component\Grouping',
parent::COMPONENT_SPELLCHECK => 'Solarium\Component\Spellcheck',
parent::COMPONENT_SUGGESTER => 'Solarium\Component\Suggester',
self::COMPONENT_DISTRIBUTEDSEARCH => 'Solarium\QueryType\Select\Query\Component\DistributedSearch',
self::COMPONENT_STATS => 'Solarium\QueryType\Select\Query\Component\Stats\Stats',
parent::COMPONENT_DEBUG => 'Solarium\Component\Debug',
parent::COMPONENT_SPATIAL => 'Solarium\Component\Spatial',
);
/**
* Fields to fetch.
*
......@@ -174,6 +158,26 @@ class Query extends AbstractComponentAwareQuery
*/
protected $filterQueries = array();
public function __construct($options = null)
{
$this->componentTypes = [
ComponentAwareQueryInterface::COMPONENT_MORELIKETHIS => 'Solarium\Component\MoreLikeThis',
ComponentAwareQueryInterface::COMPONENT_SPELLCHECK => 'Solarium\Component\Spellcheck',
ComponentAwareQueryInterface::COMPONENT_SUGGESTER => 'Solarium\Component\Suggester',
ComponentAwareQueryInterface::COMPONENT_DEBUG => 'Solarium\Component\Debug',
ComponentAwareQueryInterface::COMPONENT_SPATIAL => 'Solarium\Component\Spatial',
self::COMPONENT_FACETSET => 'Solarium\QueryType\Select\Query\Component\FacetSet',
self::COMPONENT_DISMAX => 'Solarium\QueryType\Select\Query\Component\DisMax',
self::COMPONENT_EDISMAX => 'Solarium\QueryType\Select\Query\Component\EdisMax',
self::COMPONENT_HIGHLIGHTING => 'Solarium\QueryType\Select\Query\Component\Highlighting\Highlighting',
self::COMPONENT_GROUPING => 'Solarium\QueryType\Select\Query\Component\Grouping',
self::COMPONENT_DISTRIBUTEDSEARCH => 'Solarium\QueryType\Select\Query\Component\DistributedSearch',
self::COMPONENT_STATS => 'Solarium\QueryType\Select\Query\Component\Stats\Stats',
];
parent::__construct($options);
}
/**
* Get type for this query.
*
......
......@@ -31,9 +31,8 @@
namespace Solarium\Tests\Component;
use Solarium\Component\AbstractComponentAwareQuery;
use Solarium\Component\ComponentAwareQueryInterface;
use Solarium\Component\Debug;
use Solarium\QueryType\Select\Query\Query;
class DebugTest extends \PHPUnit_Framework_TestCase
{
......@@ -61,7 +60,7 @@ class DebugTest extends \PHPUnit_Framework_TestCase
public function testGetType()
{
$this->assertEquals(
AbstractComponentAwareQuery::COMPONENT_DEBUG,
ComponentAwareQueryInterface::COMPONENT_DEBUG,
$this->debug->getType()
);
}
......
......@@ -31,9 +31,8 @@
namespace Solarium\Tests\Component;
use Solarium\Component\AbstractComponentAwareQuery;
use Solarium\Component\ComponentAwareQueryInterface;
use Solarium\Component\MoreLikeThis;
use Solarium\QueryType\Select\Query\Query;
class MoreLikeThisTest extends \PHPUnit_Framework_TestCase
{
......@@ -77,7 +76,7 @@ class MoreLikeThisTest extends \PHPUnit_Framework_TestCase
public function testGetType()
{
$this->assertEquals(AbstractComponentAwareQuery::COMPONENT_MORELIKETHIS, $this->mlt->getType());
$this->assertEquals(ComponentAwareQueryInterface::COMPONENT_MORELIKETHIS, $this->mlt->getType());
}
public function testGetResponseParser()
......
......@@ -31,7 +31,7 @@
namespace Solarium\Tests\Component;
use Solarium\Component\AbstractComponentAwareQuery;
use Solarium\Component\ComponentAwareQueryInterface;
use Solarium\Component\Spellcheck;
use Solarium\QueryType\Select\Query\Query;
......@@ -50,7 +50,7 @@ class SpellcheckTest extends \PHPUnit_Framework_TestCase
public function testGetType()
{
$this->assertEquals(AbstractComponentAwareQuery::COMPONENT_SPELLCHECK, $this->spellCheck->getType());
$this->assertEquals(ComponentAwareQueryInterface::COMPONENT_SPELLCHECK, $this->spellCheck->getType());
}
public function testGetResponseParser()
......
......@@ -31,7 +31,7 @@
namespace Solarium\Tests\Component;
use Solarium\Component\AbstractComponentAwareQuery;
use Solarium\Component\ComponentAwareQueryInterface;
use Solarium\Component\Suggester;
use Solarium\QueryType\Select\Query\Query;
......@@ -50,7 +50,7 @@ class SuggesterTest extends \PHPUnit_Framework_TestCase
public function testGetType()
{
$this->assertEquals(AbstractComponentAwareQuery::COMPONENT_SUGGESTER, $this->suggester->getType());
$this->assertEquals(ComponentAwareQueryInterface::COMPONENT_SUGGESTER, $this->suggester->getType());
}
public function testGetResponseParser()
......
......@@ -122,4 +122,19 @@ abstract class AbstractTechproductsTest extends \PHPUnit_Framework_TestCase
'electronics and stuff2'
], $phrases);
}
public function testTerms()
{
$terms = $this->client->createTerms();
$terms->setFields('name');
$result = $this->client->terms($terms);
$phrases = [];
foreach ($result->getTerms('name') as $term => $count) {
$phrases[] = $term;
}
$this->assertEquals([
'one', 184, '1gb', 3200, 400, 'ddr', 'gb', 'ipod', 'memory', 'pc',
], $phrases);
}
}
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