Commit f5ddbee9 authored by Bas de Nooijer's avatar Bas de Nooijer

Merge branch 'feature/query-placeholders' into develop

parents e8ee11b1 850bcf4c
...@@ -47,6 +47,20 @@ ...@@ -47,6 +47,20 @@
class Solarium_Query_Helper class Solarium_Query_Helper
{ {
/**
* Placeholder pattern for use in the assemble method
*
* @var string
*/
protected $_placeHolderPattern = '/%(L|P|T|)([0-9]+)%/i';
/**
* Array of parts to use for assembling a query string
*
* @var array
*/
protected $_assembleParts;
/** /**
* Escape a term * Escape a term
* *
...@@ -218,4 +232,59 @@ class Solarium_Query_Helper ...@@ -218,4 +232,59 @@ class Solarium_Query_Helper
return $name . '(' . implode($params, ',') . ')'; return $name . '(' . implode($params, ',') . ')';
} }
/**
* Assemble a querystring with placeholders
*
* These placeholder modes are supported:
* %1% = no mode, will default to literal
* %L2% = literal
* %P3% = phrase-escaped
* %T4% = term-escaped
*
* Numbering starts at 1, so number 1 refers to the first entry
* of $parts (which has array key 0)
* You can use the same part multiple times, even in multiple modes.
* The mode letters are not case sensitive.
*
* The mode matching pattern can be customized by overriding the
* value of $this->_placeHolderPattern
*
* @param string $query
* @param array $parts Array of strings
* @return string
*/
public function assemble($query, $parts)
{
$this->_assembleParts = $parts;
return preg_replace_callback(
$this->_placeHolderPattern,
array($this, '_renderPlaceHolder'),
$query);
}
protected function _renderPlaceHolder($matches)
{
$partNumber = $matches[2];
$partMode = strtoupper($matches[1]);
if (isset($this->_assembleParts[$partNumber-1])) {
$value = $this->_assembleParts[$partNumber-1];
} else {
throw new Solarium_Exception('No value supplied for part #' . $partNumber . ' in query assembler');
}
switch($partMode)
{
case 'P':
$value = $this->escapePhrase($value);
break;
case 'T':
$value = $this->escapeTerm($value);
break;
}
return $value;
}
} }
\ No newline at end of file
...@@ -188,10 +188,15 @@ class Solarium_Query_Select extends Solarium_Query ...@@ -188,10 +188,15 @@ class Solarium_Query_Select extends Solarium_Query
* escaping of user input. * escaping of user input.
* *
* @param string $query * @param string $query
* @param array $bind Bind values for placeholders in the query string
* @return Solarium_Query_Select Provides fluent interface * @return Solarium_Query_Select Provides fluent interface
*/ */
public function setQuery($query) public function setQuery($query, $bind = null)
{ {
if (!is_null($bind)) {
$query = $this->getHelper()->assemble($query, $bind);
}
return $this->_setOption('query', trim($query)); return $this->_setOption('query', trim($query));
} }
......
...@@ -72,10 +72,16 @@ class Solarium_Query_Select_Component_Facet_Query extends Solarium_Query_Select_ ...@@ -72,10 +72,16 @@ class Solarium_Query_Select_Component_Facet_Query extends Solarium_Query_Select_
* This overwrites the current value * This overwrites the current value
* *
* @param string $query * @param string $query
* @param array $bind Bind values for placeholders in the query string
* @return Solarium_Query_Select_Facet_Query Provides fluent interface * @return Solarium_Query_Select_Facet_Query Provides fluent interface
*/ */
public function setQuery($query) public function setQuery($query, $bind = null)
{ {
if (!is_null($bind)) {
$helper = new Solarium_Query_Helper;
$query = $helper->assemble($query, $bind);
}
return $this->_setOption('query', $query); return $this->_setOption('query', $query);
} }
......
...@@ -111,10 +111,16 @@ class Solarium_Query_Select_FilterQuery extends Solarium_Configurable ...@@ -111,10 +111,16 @@ class Solarium_Query_Select_FilterQuery extends Solarium_Configurable
* This overwrites the current value * This overwrites the current value
* *
* @param string $query * @param string $query
* @param array $bind Bind values for placeholders in the query string
* @return Solarium_Query Provides fluent interface * @return Solarium_Query Provides fluent interface
*/ */
public function setQuery($query) public function setQuery($query, $bind = null)
{ {
if (!is_null($bind)) {
$helper = new Solarium_Query_Helper;
$query = $helper->assemble($query, $bind);
}
$this->_query = trim($query); $this->_query = trim($query);
return $this; return $this;
} }
......
...@@ -152,4 +152,43 @@ class Solarium_Query_HelperTest extends PHPUnit_Framework_TestCase ...@@ -152,4 +152,43 @@ class Solarium_Query_HelperTest extends PHPUnit_Framework_TestCase
); );
} }
public function testAssemble()
{
// test single basic placeholder
$this->assertEquals(
'id:456 AND cat:2',
$this->_helper->assemble('id:%1% AND cat:2',array(456))
);
// test multiple basic placeholders and placeholder repeat
$this->assertEquals(
'(id:456 AND cat:2) OR (id:456 AND cat:1)',
$this->_helper->assemble('(id:%1% AND cat:%2%) OR (id:%1% AND cat:%3%)',array(456, 2, 1))
);
// test literal placeholder (same as basic)
$this->assertEquals(
'id:456 AND cat:2',
$this->_helper->assemble('id:%L1% AND cat:2',array(456))
);
// test term placeholder
$this->assertEquals(
'cat:2 AND content:a\\+b',
$this->_helper->assemble('cat:2 AND content:%T1%',array('a+b'))
);
// test term placeholder case-insensitive
$this->assertEquals(
'cat:2 AND content:a\\+b',
$this->_helper->assemble('cat:2 AND content:%t1%',array('a+b'))
);
// test phrase placeholder
$this->assertEquals(
'cat:2 AND content:"a+\\"b"',
$this->_helper->assemble('cat:2 AND content:%P1%',array('a+"b'))
);
}
} }
...@@ -71,5 +71,9 @@ class Solarium_Query_Select_Component_Facet_QueryTest extends PHPUnit_Framework_ ...@@ -71,5 +71,9 @@ class Solarium_Query_Select_Component_Facet_QueryTest extends PHPUnit_Framework_
$this->assertEquals('category:1', $this->_facet->getQuery()); $this->assertEquals('category:1', $this->_facet->getQuery());
} }
public function testSetAndGetQueryWithBind()
{
$this->_facet->setQuery('id:%1%', array(678));
$this->assertEquals('id:678', $this->_facet->getQuery());
}
} }
...@@ -69,6 +69,12 @@ class Solarium_Query_Select_FilterQueryTest extends PHPUnit_Framework_TestCase ...@@ -69,6 +69,12 @@ class Solarium_Query_Select_FilterQueryTest extends PHPUnit_Framework_TestCase
$this->assertEquals('category:1', $this->_filterQuery->getQuery()); $this->assertEquals('category:1', $this->_filterQuery->getQuery());
} }
public function testSetAndGetQueryWithBind()
{
$this->_filterQuery->setQuery('id:%1%', array(678));
$this->assertEquals('id:678', $this->_filterQuery->getQuery());
}
public function testAddTag() public function testAddTag()
{ {
$this->_filterQuery->addTag('testtag'); $this->_filterQuery->addTag('testtag');
......
...@@ -56,6 +56,12 @@ class Solarium_Query_SelectTest extends PHPUnit_Framework_TestCase ...@@ -56,6 +56,12 @@ class Solarium_Query_SelectTest extends PHPUnit_Framework_TestCase
$this->assertEquals('*:*', $this->_query->getQuery()); $this->assertEquals('*:*', $this->_query->getQuery());
} }
public function testSetAndGetQueryWithBind()
{
$this->_query->setQuery('id:%1%', array(678));
$this->assertEquals('id:678', $this->_query->getQuery());
}
public function testSetAndGetResultClass() public function testSetAndGetResultClass()
{ {
$this->_query->setResultClass('MyResult'); $this->_query->setResultClass('MyResult');
......
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