diff --git a/CHANGELOG.md b/CHANGELOG.md index 46461d7be..15b913f14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # CHANGELOG +## 3.7.0 - 2016-10-28 + +- added: support for nested documents in update query +- added: spatial component for select query +- added: support for keys and excludes in interval facet +- added: support for grouping using a function (group.func) +- bugfix: spellcheck collation parsing for Solr 5+ +- improvement: lots of fixes in documentation markup +- added: included suggestion in composer file for a query builder library ## 3.6.0 - 2016-05-03 diff --git a/composer.json b/composer.json index 538895cec..1bcf8b7d7 100644 --- a/composer.json +++ b/composer.json @@ -21,6 +21,9 @@ "zendframework/zendframework1": "~1.12", "satooshi/php-coveralls": "~1.0" }, + "suggest": { + "minimalcode/search": "Query builder compatible with Solarium, allows simplified solr-query handling" + }, "extra": { "branch-alias": { "dev-develop": "3.3.x-dev" diff --git a/docs/customizing-solarium.md b/docs/customizing-solarium.md index 8491ca9a6..665c6f89c 100644 --- a/docs/customizing-solarium.md +++ b/docs/customizing-solarium.md @@ -97,7 +97,8 @@ By combining these options you can achieve almost any type of customization with Solarium uses a separate library (included using Composer) for events. For more info on the Event Dispatcher take a look at [http://symfony.com/doc/2.0/components/event\_dispatcher/introduction.html the docs](http://symfony.com/doc/2.0/components/event_dispatcher/introduction.html_the_docs) -This example shows all available events and how to use the events to create a very basic debugger: ```php +This example shows all available events and how to use the events to create a very basic debugger: +```php ](https://packagist.org) for other packages. ```json { "require": { - "solarium/solarium": "2.4.0" + "solarium/solarium": "3.6.0" } } ``` diff --git a/docs/queries/select-query/building-a-select-query/components/grouping-component.md b/docs/queries/select-query/building-a-select-query/components/grouping-component.md index 53c09b347..e8bed30cd 100644 --- a/docs/queries/select-query/building-a-select-query/components/grouping-component.md +++ b/docs/queries/select-query/building-a-select-query/components/grouping-component.md @@ -24,7 +24,9 @@ Options Examples -------- -Grouping by field: ```php +Grouping by field: + +```php setExcludes($value); unset($this->options['exclude']); diff --git a/library/Solarium/QueryType/Select/Query/Component/Spatial.php b/library/Solarium/QueryType/Select/Query/Component/Spatial.php new file mode 100644 index 000000000..71ee4281b --- /dev/null +++ b/library/Solarium/QueryType/Select/Query/Component/Spatial.php @@ -0,0 +1,96 @@ +setOption('sfield', $sfield); + } + + /** + * @param int $distance + */ + public function setDistance($distance) + { + $this->setOption('d', $distance); + } + + /** + * @param string $point + */ + public function setPoint($point) + { + $this->setOption('pt', $point); + } + + /** + * Get sfield option. + * + * @return string|null + */ + public function getField() + { + return $this->getOption('sfield'); + } + + /** + * Get d option. + * + * @return int|null + */ + public function getDistance() + { + return $this->getOption('d'); + } + + /** + * Get pt option. + * + * @return int|null + */ + public function getPoint() + { + return $this->getOption('pt'); + } +} diff --git a/library/Solarium/QueryType/Select/Query/Query.php b/library/Solarium/QueryType/Select/Query/Query.php index f77e8d351..bc2a11b63 100644 --- a/library/Solarium/QueryType/Select/Query/Query.php +++ b/library/Solarium/QueryType/Select/Query/Query.php @@ -127,6 +127,11 @@ class Query extends BaseQuery */ const COMPONENT_DEBUG = 'debug'; + /** + * Query component spatial. + */ + const COMPONENT_SPATIAL = 'spatial'; + /** * Default options. * @@ -166,6 +171,7 @@ class Query extends BaseQuery self::COMPONENT_DISTRIBUTEDSEARCH => 'Solarium\QueryType\Select\Query\Component\DistributedSearch', self::COMPONENT_STATS => 'Solarium\QueryType\Select\Query\Component\Stats\Stats', self::COMPONENT_DEBUG => 'Solarium\QueryType\Select\Query\Component\Debug', + self::COMPONENT_SPATIAL => 'Solarium\QueryType\Select\Query\Component\Spatial', ); /** @@ -1057,6 +1063,18 @@ public function setTags($tags) return $this->addTags($tags); } + /** + * Get a Spatial component instance. + * + * This is a convenience method that maps presets to getComponent + * + * @return \Solarium\QueryType\Select\Query\Component\Spatial + */ + public function getSpatial() + { + return $this->getComponent(self::COMPONENT_SPATIAL, true); + } + /** * Initialize options. * @@ -1090,7 +1108,7 @@ protected function init() break; case 'tag': if (!is_array($value)) { - $value = array($value); + $value = explode(',', $value); } $this->addTags($value); break; diff --git a/library/Solarium/QueryType/Select/RequestBuilder/Component/FacetSet.php b/library/Solarium/QueryType/Select/RequestBuilder/Component/FacetSet.php index eaf9590ce..58e32ed33 100644 --- a/library/Solarium/QueryType/Select/RequestBuilder/Component/FacetSet.php +++ b/library/Solarium/QueryType/Select/RequestBuilder/Component/FacetSet.php @@ -246,9 +246,8 @@ public function addFacetInterval($request, $facet) $request->addParam( 'facet.interval', $this->renderLocalParams( - $field - // key & ex not supported for interval - //,array('key' => $facet->getKey(), 'ex' => $facet->getExcludes()) + $field, + array('key' => $facet->getKey(), 'ex' => $facet->getExcludes()) ) ); diff --git a/library/Solarium/QueryType/Select/RequestBuilder/Component/Spatial.php b/library/Solarium/QueryType/Select/RequestBuilder/Component/Spatial.php new file mode 100644 index 000000000..da70ce4e9 --- /dev/null +++ b/library/Solarium/QueryType/Select/RequestBuilder/Component/Spatial.php @@ -0,0 +1,29 @@ +addParam('sfield', $component->getField()); + $request->addParam('pt', $component->getPoint()); + $request->addParam('d', $component->getDistance()); + + return $request; + } +} diff --git a/library/Solarium/QueryType/Select/ResponseParser/Component/Grouping.php b/library/Solarium/QueryType/Select/ResponseParser/Component/Grouping.php index f3eac5ffb..a3bb718bc 100644 --- a/library/Solarium/QueryType/Select/ResponseParser/Component/Grouping.php +++ b/library/Solarium/QueryType/Select/ResponseParser/Component/Grouping.php @@ -67,7 +67,9 @@ public function parse($query, $grouping, $data) // parse field groups $valueResultClass = $grouping->getOption('resultvaluegroupclass'); $documentClass = $query->getOption('documentclass'); - foreach ($grouping->getFields() as $field) { + + // check grouping fields as well as the grouping function (either can be used in the query) + foreach (array_merge($grouping->getFields(), array($grouping->getFunction())) as $field) { if (isset($data['grouped'][$field])) { $result = $data['grouped'][$field]; diff --git a/library/Solarium/QueryType/Select/ResponseParser/Component/Spellcheck.php b/library/Solarium/QueryType/Select/ResponseParser/Component/Spellcheck.php index bc48aa3d7..379345691 100644 --- a/library/Solarium/QueryType/Select/ResponseParser/Component/Spellcheck.php +++ b/library/Solarium/QueryType/Select/ResponseParser/Component/Spellcheck.php @@ -141,10 +141,18 @@ protected function parseCollation($queryObject, $values) if ($queryObject->getResponseWriter() == $queryObject::WT_JSON) { if (is_array(current($values))) { foreach ($values as $key => $value) { - $values[$key] = $this->convertToKeyValueArray($value); + if (array_key_exists('collationQuery', $value)) { + $values[$key] = $value; + } else { + $values[$key] = $this->convertToKeyValueArray($value); + } } } else { - $values = array($this->convertToKeyValueArray($values)); + if (array_key_exists('collationQuery', $values)) { + $values = array($values); + } else { + $values = array($this->convertToKeyValueArray($values)); + } } } diff --git a/library/Solarium/QueryType/Update/RequestBuilder.php b/library/Solarium/QueryType/Update/RequestBuilder.php index eed559aa0..bc61bea3c 100644 --- a/library/Solarium/QueryType/Update/RequestBuilder.php +++ b/library/Solarium/QueryType/Update/RequestBuilder.php @@ -112,7 +112,7 @@ public function getRawData($query) * Build XML for an add command. * * @param \Solarium\QueryType\Update\Query\Command\Add $command - * @param UpdateQuery $query + * @param UpdateQuery $query * * @return string */ @@ -131,13 +131,7 @@ public function buildAddXml($command, $query = null) foreach ($doc->getFields() as $name => $value) { $boost = $doc->getFieldBoost($name); $modifier = $doc->getFieldModifier($name); - if (is_array($value)) { - foreach ($value as $multival) { - $xml .= $this->buildFieldXml($name, $boost, $multival, $modifier, $query); - } - } else { - $xml .= $this->buildFieldXml($name, $boost, $value, $modifier, $query); - } + $xml .= $this->buildFieldsXml($name, $boost, $value, $modifier, $query); } $version = $doc->getVersion(); @@ -164,10 +158,10 @@ public function buildDeleteXml($command) { $xml = ''; foreach ($command->getIds() as $id) { - $xml .= ''.htmlspecialchars($id, ENT_NOQUOTES, 'UTF-8').''; + $xml .= '' . htmlspecialchars($id, ENT_NOQUOTES, 'UTF-8') . ''; } foreach ($command->getQueries() as $query) { - $xml .= ''.htmlspecialchars($query, ENT_NOQUOTES, 'UTF-8').''; + $xml .= '' . htmlspecialchars($query, ENT_NOQUOTES, 'UTF-8') . ''; } $xml .= ''; @@ -225,10 +219,10 @@ public function buildRollbackXml() * * Used in the add command * - * @param string $name - * @param float $boost - * @param mixed $value - * @param string $modifier + * @param string $name + * @param float $boost + * @param mixed $value + * @param string $modifier * @param UpdateQuery $query * * @return string @@ -239,7 +233,7 @@ protected function buildFieldXml($name, $boost, $value, $modifier = null, $query $value = $query->getHelper()->formatDate($value); } - $xml = 'attrib('boost', $boost); $xml .= $this->attrib('update', $modifier); if ($value === null) { @@ -250,9 +244,42 @@ protected function buildFieldXml($name, $boost, $value, $modifier = null, $query $value = 'true'; } - $xml .= '>'.htmlspecialchars($value, ENT_NOQUOTES, 'UTF-8'); + $xml .= '>' . htmlspecialchars($value, ENT_NOQUOTES, 'UTF-8'); $xml .= ''; return $xml; } + + /** + * @param string $key + * + * @param float $boost + * @param mixed $value + * @param string $modifier + * @param UpdateQuery $query + * @return string + */ + private function buildFieldsXml($key, $boost, $value, $modifier, $query) + { + $xml = ''; + if (is_array($value)) { + foreach ($value as $multival) { + if (is_array($multival)) { + $xml .= ''; + foreach ($multival as $k => $v) { + $xml .= $this->buildFieldsXml($k, $boost, $v, $modifier, $query); + } + $xml .= ''; + + } else { + $xml .= $this->buildFieldXml($key, $boost, $multival, $modifier, $query); + } + } + + } else { + $xml .= $this->buildFieldXml($key, $boost, $value, $modifier, $query); + } + + return $xml; + } } diff --git a/tests/Solarium/Tests/QueryType/Select/Query/AbstractQueryTest.php b/tests/Solarium/Tests/QueryType/Select/Query/AbstractQueryTest.php index e31485db5..3bb2e4c76 100644 --- a/tests/Solarium/Tests/QueryType/Select/Query/AbstractQueryTest.php +++ b/tests/Solarium/Tests/QueryType/Select/Query/AbstractQueryTest.php @@ -708,4 +708,14 @@ public function testSetTags() $this->query->setTags(array('t3', 't4')); $this->assertEquals(array('t3', 't4'), $this->query->getTags()); } + + public function testGetSpatial() + { + $spatial = $this->query->getSpatial(); + + $this->assertEquals( + 'Solarium\QueryType\Select\Query\Component\Spatial', + get_class($spatial) + ); + } } diff --git a/tests/Solarium/Tests/QueryType/Select/Query/Component/SpatialTest.php b/tests/Solarium/Tests/QueryType/Select/Query/Component/SpatialTest.php new file mode 100644 index 000000000..4b4e17add --- /dev/null +++ b/tests/Solarium/Tests/QueryType/Select/Query/Component/SpatialTest.php @@ -0,0 +1,88 @@ +spatial = new Spatial; + } + + public function testConfigMode() + { + $options = array( + 'sfield' => 'geo', + 'd' => 50, + 'pt' => '48.2233,16.3161', + ); + + $this->spatial->setOptions($options); + + $this->assertEquals($options['sfield'], $this->spatial->getField()); + $this->assertEquals($options['d'], $this->spatial->getDistance()); + $this->assertEquals($options['pt'], $this->spatial->getPoint()); + } + + public function testGetType() + { + $this->assertEquals( + Query::COMPONENT_SPATIAL, + $this->spatial->getType() + ); + } + + public function testGetResponseParser() + { + $this->assertEquals(null, $this->spatial->getResponseParser()); + } + + public function testGetRequestBuilder() + { + $this->assertInstanceOf( + 'Solarium\QueryType\Select\RequestBuilder\Component\Spatial', + $this->spatial->getRequestBuilder() + ); + } + + public function testSetAndGetField() + { + $value = 'geo'; + $this->spatial->setField($value); + + $this->assertEquals( + $value, + $this->spatial->getField() + ); + } + + public function testSetAndGetDistance() + { + $value = 'distance'; + $this->spatial->setDistance($value); + + $this->assertEquals( + $value, + $this->spatial->getDistance() + ); + } + + public function testSetAndGetPoint() + { + $value = '52,13'; + $this->spatial->setPoint($value); + + $this->assertEquals( + $value, + $this->spatial->getPoint() + ); + } +} diff --git a/tests/Solarium/Tests/QueryType/Select/RequestBuilder/Component/FacetSetTest.php b/tests/Solarium/Tests/QueryType/Select/RequestBuilder/Component/FacetSetTest.php index f1b99117b..51501caab 100644 --- a/tests/Solarium/Tests/QueryType/Select/RequestBuilder/Component/FacetSetTest.php +++ b/tests/Solarium/Tests/QueryType/Select/RequestBuilder/Component/FacetSetTest.php @@ -9,7 +9,7 @@ * 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 + * this list of 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" @@ -69,7 +69,7 @@ public function testBuildEmptyFacetSet() { $request = $this->builder->buildComponent($this->component, $this->request); - $this->assertEquals( + static::assertEquals( array(), $request->getParams() ); @@ -86,12 +86,12 @@ public function testBuildWithFacets() $request = $this->builder->buildComponent($this->component, $this->request); - $this->assertEquals( + static::assertEquals( null, $request->getRawData() ); - $this->assertEquals( + static::assertEquals( '?facet=true&facet.field={!key=f1}owner&facet.query={!key=f2}category:23&facet.query={!key=f4}category:40', urldecode($request->getUri()) ); @@ -114,12 +114,12 @@ public function testBuildWithRangeFacet() $request = $this->builder->buildComponent($this->component, $this->request); - $this->assertEquals( + static::assertEquals( null, $request->getRawData() ); - $this->assertEquals( + static::assertEquals( '?facet=true&facet.range={!key=f1}price&f.price.facet.range.start=1&f.price.facet.range.end=100&f.price.facet.range.gap=10&f.price.facet.mincount=123&f.price.facet.range.other=all&f.price.facet.range.include=outer', urldecode($request->getUri()) ); @@ -141,12 +141,12 @@ public function testBuildWithRangeFacetExcludingOptionalParams() $request = $this->builder->buildComponent($this->component, $this->request); - $this->assertEquals( + static::assertEquals( null, $request->getRawData() ); - $this->assertEquals( + static::assertEquals( '?facet=true&facet.range={!key=f1}price&f.price.facet.range.start=1&f.price.facet.range.end=100'. '&f.price.facet.range.gap=10', urldecode($request->getUri()) @@ -165,12 +165,12 @@ public function testBuildWithFacetsAndGlobalFacetSettings() $request = $this->builder->buildComponent($this->component, $this->request); - $this->assertEquals( + static::assertEquals( null, $request->getRawData() ); - $this->assertEquals( + static::assertEquals( '?facet=true&facet.missing=true&facet.limit=10&facet.field={!key=f1}owner&facet.query={!key=f2}category:23'. '&facet.query={!key=f4}category:40', urldecode($request->getUri()) @@ -199,12 +199,12 @@ public function testBuildWithPivotFacet() $request = $this->builder->buildComponent($this->component, $this->request); - $this->assertEquals( + static::assertEquals( null, $request->getRawData() ); - $this->assertEquals( + static::assertEquals( '?facet=true&facet.pivot={!key=f1 ex=owner}cat,inStock&facet.pivot.mincount=123', urldecode($request->getUri()) ); @@ -223,12 +223,12 @@ public function testBuildWithPivotStatFacet() $request = $this->builder->buildComponent($this->component, $this->request); - $this->assertEquals( + static::assertEquals( null, $request->getRawData() ); - $this->assertEquals( + static::assertEquals( '?facet=true&facet.pivot={!stats=piv1}cat,inStock', urldecode($request->getUri()) ); @@ -250,18 +250,18 @@ public function testBuildWithContainsSettings() $request = $this->builder->buildComponent($this->component, $this->request); - $this->assertEquals( + static::assertEquals( null, $request->getRawData() ); - $this->assertEquals( + static::assertEquals( '?facet=true&facet.contains=bar&facet.contains.ignoreCase=false&facet.field={!key=f1}owner&f.owner.facet.contains=foo&f.owner.facet.contains.ignoreCase=true', urldecode($request->getUri()) ); } - public function testBuildeWithIntervalFacet() + public function testBuildWithIntervalFacet() { $facet = new FacetInterval( array( @@ -275,13 +275,13 @@ public function testBuildeWithIntervalFacet() $request = $this->builder->buildComponent($this->component, $this->request); - $this->assertEquals( + static::assertEquals( null, $request->getRawData() ); - $this->assertEquals( - '?facet=true&f..facet.interval.set=int1&f..facet.interval.set={!key="one"}int2', + static::assertEquals( + '?facet=true&facet.interval={!key=f1}&f..facet.interval.set=int1&f..facet.interval.set={!key="one"}int2', urldecode($request->getUri()) ); } diff --git a/tests/Solarium/Tests/QueryType/Select/RequestBuilder/Component/SpatialTest.php b/tests/Solarium/Tests/QueryType/Select/RequestBuilder/Component/SpatialTest.php new file mode 100644 index 000000000..003e8758b --- /dev/null +++ b/tests/Solarium/Tests/QueryType/Select/RequestBuilder/Component/SpatialTest.php @@ -0,0 +1,33 @@ +setField('geo'); + $component->setDistance(50); + $component->setPoint('48.2233,16.3161'); + + $request = $builder->buildComponent($component, $request); + + $this->assertEquals( + array( + 'pt' => '48.2233,16.3161', + 'sfield' => 'geo', + 'd' => 50, + ), + $request->getParams() + ); + + } +} diff --git a/tests/Solarium/Tests/QueryType/Select/ResponseParser/Component/GroupingTest.php b/tests/Solarium/Tests/QueryType/Select/ResponseParser/Component/GroupingTest.php index f82e1c89f..600f23fa0 100644 --- a/tests/Solarium/Tests/QueryType/Select/ResponseParser/Component/GroupingTest.php +++ b/tests/Solarium/Tests/QueryType/Select/ResponseParser/Component/GroupingTest.php @@ -64,6 +64,7 @@ public function setUp() $this->query = new Query(); $this->grouping = $this->query->getGrouping(); $this->grouping->addField('fieldA'); + $this->grouping->setFunction('functionF'); $this->grouping->addQuery('cat:1'); $data = array( @@ -83,6 +84,21 @@ public function setUp() ) ) ), + 'functionF' => array( + 'matches' => 8, + 'ngroups' => 3, + 'groups' => array( + array( + 'groupValue' => true, + 'doclist' => array( + 'numFound' => 5, + 'docs' => array( + array('id' => 3, 'name' => 'fun') + ) + ) + ) + ) + ), 'cat:1' => array( 'matches' => 40, 'doclist' => array( @@ -101,13 +117,15 @@ public function setUp() public function testGroupParsing() { - $this->assertEquals(2, count($this->result->getGroups())); + $this->assertEquals(3, count($this->result->getGroups())); $fieldGroup = $this->result->getGroup('fieldA'); $queryGroup = $this->result->getGroup('cat:1'); + $functionGroup = $this->result->getGroup('functionF'); $this->assertEquals('Solarium\QueryType\Select\Result\Grouping\FieldGroup', get_class($fieldGroup)); $this->assertEquals('Solarium\QueryType\Select\Result\Grouping\QueryGroup', get_class($queryGroup)); + $this->assertEquals('Solarium\QueryType\Select\Result\Grouping\FieldGroup', get_class($functionGroup)); } public function testFieldGroupParsing() @@ -142,4 +160,20 @@ public function testParseNoData() $result = $this->parser->parse($this->query, $this->grouping, array()); $this->assertEquals(array(), $result->getGroups()); } + + public function testFunctionGroupParsing() + { + $fieldGroup = $this->result->getGroup('functionF'); + $valueGroups = $fieldGroup->getValueGroups(); + + $this->assertEquals(8, $fieldGroup->getMatches()); + $this->assertEquals(3, $fieldGroup->getNumberOfGroups()); + $this->assertEquals(1, count($valueGroups)); + + $valueGroup = $valueGroups[0]; + $this->assertEquals(5, $valueGroup->getNumFound()); + + $docs = $valueGroup->getDocuments(); + $this->assertEquals('fun', $docs[0]->name); + } } diff --git a/tests/Solarium/Tests/QueryType/Select/ResponseParser/Component/SpellcheckTest.php b/tests/Solarium/Tests/QueryType/Select/ResponseParser/Component/SpellcheckTest.php index 0d5818d0a..cd8a9cded 100644 --- a/tests/Solarium/Tests/QueryType/Select/ResponseParser/Component/SpellcheckTest.php +++ b/tests/Solarium/Tests/QueryType/Select/ResponseParser/Component/SpellcheckTest.php @@ -194,12 +194,9 @@ public function providerParseExtended() 'collations' => array( 'collation', array( - 0 => 'collationQuery', - 1 => 'dell ultrasharp', - 2 => 'hits', - 3 => 0, - 4 => 'misspellingsAndCorrections', - 5 => array( + 'collationQuery' => 'dell ultrasharp', + 'hits' => 0, + 'misspellingsAndCorrections' => array( 0 => 'delll', 1 => 'dell', 2 => 'ultrashar', @@ -208,12 +205,9 @@ public function providerParseExtended() ), 'collation', array( - 0 => 'collationQuery', - 1 => 'dell ultrasharp new', - 2 => 'hits', - 3 => 0, - 4 => 'misspellingsAndCorrections', - 5 => array( + 'collationQuery' => 'dell ultrasharp new', + 'hits' => 0, + 'misspellingsAndCorrections' => array( 0 => 'delll', 1 => 'dell', 2 => 'ultrashar', diff --git a/tests/Solarium/Tests/QueryType/Update/RequestBuilderTest.php b/tests/Solarium/Tests/QueryType/Update/RequestBuilderTest.php index 4dc496f0c..df8865dcb 100644 --- a/tests/Solarium/Tests/QueryType/Update/RequestBuilderTest.php +++ b/tests/Solarium/Tests/QueryType/Update/RequestBuilderTest.php @@ -31,15 +31,15 @@ namespace Solarium\Tests\QueryType\Update; -use Solarium\QueryType\Update\Query\Query; -use Solarium\QueryType\Update\RequestBuilder; use Solarium\Core\Client\Request; use Solarium\QueryType\Update\Query\Command\Add as AddCommand; +use Solarium\QueryType\Update\Query\Command\Commit as CommitCommand; use Solarium\QueryType\Update\Query\Command\Delete as DeleteCommand; use Solarium\QueryType\Update\Query\Command\Optimize as OptimizeCommand; -use Solarium\QueryType\Update\Query\Command\Commit as CommitCommand; use Solarium\QueryType\Update\Query\Command\Rollback as RollbackCommand; use Solarium\QueryType\Update\Query\Document\Document; +use Solarium\QueryType\Update\Query\Query; +use Solarium\QueryType\Update\RequestBuilder; class RequestBuilderTest extends \PHPUnit_Framework_TestCase { @@ -127,13 +127,52 @@ public function testBuildAddXmlMultivalueField() $command->addDocument(new Document(array('id' => array(1, 2, 3), 'text' => 'test < 123 > test'))); $this->assertEquals( - ''. - ''. - '1'. - '2'. - '3'. - 'test < 123 > test'. - ''. + '' . + '' . + '1' . + '2' . + '3' . + 'test < 123 > test' . + '' . + '', + $this->builder->buildAddXml($command) + ); + } + + public function testBuildAddXmlWithNestedDocuments() + { + $command = new AddCommand; + $command->addDocument( + new Document( + array( + 'id' => array( + array( + 'nested_id' => 42, + 'customer_ids' => array( + 15, + 16 + ) + ), + 2, + 'foo' + ), + 'text' => 'test < 123 > test' + ) + ) + ); + + $this->assertEquals( + '' . + '' . + '' . + '42' . + '15' . + '16' . + '' . + '2' . + 'foo' . + 'test < 123 > test' . + '' . '', $this->builder->buildAddXml($command) ); @@ -189,13 +228,13 @@ public function testBuildAddXmlWithFieldModifiers() $command->addDocument($doc); $this->assertEquals( - ''. - ''. - '1'. - '123'. - 'test'. - '2'. - ''. + '' . + '' . + '1' . + '123' . + 'test' . + '2' . + '' . '', $this->builder->buildAddXml($command) ); @@ -214,14 +253,14 @@ public function testBuildAddXmlWithFieldModifiersAndMultivalueFields() $command->addDocument($doc); $this->assertEquals( - ''. - ''. - '1'. - '123'. - '234'. - 'test'. - '2'. - ''. + '' . + '' . + '1' . + '123' . + '234' . + 'test' . + '2' . + '' . '', $this->builder->buildAddXml($command) ); @@ -244,7 +283,9 @@ public function testBuildAddXmlWithVersionedDocument() public function testBuildAddXmlWithDateTime() { $command = new AddCommand; - $command->addDocument(new Document(array('id' => 1, 'datetime' => new \DateTime('2013-01-15 14:41:58')))); + $command->addDocument( + new Document(array('id' => 1, 'datetime' => new \DateTime('2013-01-15 14:41:58', new \DateTimeZone('Europe/London')))) + ); $this->assertEquals( '12013-01-15T14:41:58Z', @@ -262,11 +303,11 @@ public function testBuildAddXmlWithFieldModifierAndNullValue() $command->addDocument($doc); $this->assertEquals( - ''. - ''. - '05991'. - ''. - ''. + '' . + '' . + '05991' . + '' . + '' . '', $this->builder->buildAddXml($command) ); @@ -366,7 +407,7 @@ public function testBuildOptimizeXml() public function testBuildOptimizeXmlWithParams() { - $command = new OptimizeCommand(array('softcommit'=>true, 'waitsearcher'=>false, 'maxsegments'=>10)); + $command = new OptimizeCommand(array('softcommit' => true, 'waitsearcher' => false, 'maxsegments' => 10)); $this->assertEquals( '', @@ -386,7 +427,7 @@ public function testBuildCommitXml() public function testBuildCommitXmlWithParams() { - $command = new CommitCommand(array('softcommit'=>true, 'waitsearcher'=>false, 'expungedeletes'=>true)); + $command = new CommitCommand(array('softcommit' => true, 'waitsearcher' => false, 'expungedeletes' => true)); $this->assertEquals( '',