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 @@
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
*
......@@ -218,4 +232,59 @@ class Solarium_Query_Helper
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
* escaping of user input.
*
* @param string $query
* @param array $bind Bind values for placeholders in the query string
* @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));
}
......
......@@ -72,10 +72,16 @@ class Solarium_Query_Select_Component_Facet_Query extends Solarium_Query_Select_
* This overwrites the current value
*
* @param string $query
* @param array $bind Bind values for placeholders in the query string
* @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);
}
......
......@@ -111,10 +111,16 @@ class Solarium_Query_Select_FilterQuery extends Solarium_Configurable
* This overwrites the current value
*
* @param string $query
* @param array $bind Bind values for placeholders in the query string
* @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);
return $this;
}
......
......@@ -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_
$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
$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()
{
$this->_filterQuery->addTag('testtag');
......
......@@ -56,6 +56,12 @@ class Solarium_Query_SelectTest extends PHPUnit_Framework_TestCase
$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()
{
$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