Skip to content

Commit

Permalink
Merge pull request #507 from ezsystems/fix-EZP-21516-search-field-ezs…
Browse files Browse the repository at this point in the history
…election-multiple

Fix EZP-21516: Field criterion: unable to query ezselection using Multiple Choice
  • Loading branch information
pspanja committed Oct 1, 2013
2 parents 9a70edc + c47c852 commit aac3a23
Show file tree
Hide file tree
Showing 17 changed files with 805 additions and 49 deletions.
116 changes: 116 additions & 0 deletions eZ/Publish/API/Repository/Tests/SearchServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,121 @@ public function testFindSingle()
);
}

/**
* Create test Content with ezcountry field having multiple countries selected.
*
* @return \eZ\Publish\API\Repository\Values\Content\Content
*/
protected function createMultipleCountriesContent()
{
$repository = $this->getRepository();
$contentTypeService = $repository->getContentTypeService();
$contentService = $repository->getContentService();

$createStruct = $contentTypeService->newContentTypeCreateStruct( "countries-multiple" );
$createStruct->mainLanguageCode = "eng-GB";
$createStruct->remoteId = "countries-multiple-123";
$createStruct->names = array( "eng-GB" => "Multiple countries" );
$createStruct->creatorId = 14;
$createStruct->creationDate = new \DateTime();

$fieldCreate = $contentTypeService->newFieldDefinitionCreateStruct( "countries", "ezcountry" );
$fieldCreate->names = array( "eng-GB" => "Countries" );
$fieldCreate->fieldGroup = "main";
$fieldCreate->position = 1;
$fieldCreate->isTranslatable = false;
$fieldCreate->isSearchable = true;
$fieldCreate->fieldSettings = array( "isMultiple" => true );

$createStruct->addFieldDefinition( $fieldCreate );

$contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier( "Content" );
$contentTypeDraft = $contentTypeService->createContentType( $createStruct, array( $contentGroup ) );
$contentTypeService->publishContentTypeDraft( $contentTypeDraft );
$contentType = $contentTypeService->loadContentType( $contentTypeDraft->id );

$createStruct = $contentService->newContentCreateStruct( $contentType, "eng-GB" );
$createStruct->remoteId = "countries-multiple-456";
$createStruct->alwaysAvailable = false;
$createStruct->setField(
"countries",
array( "BE", "DE", "FR", "HR", "NO", "PT", "RU" )
);

$draft = $contentService->createContent( $createStruct );
$content = $contentService->publishVersion( $draft->getVersionInfo() );

return $content;
}

/**
* Test for the findContent() method.
*
* @see \eZ\Publish\API\Repository\SearchService::findContent()
* @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetSearchService
*/
public function testFieldCollectionContains()
{
$testContent = $this->createMultipleCountriesContent();

$setupFactory = $this->getSetupFactory();
if ( $setupFactory instanceof \eZ\Publish\API\Repository\Tests\SetupFactory\LegacySolr )
{
$country = "BE";
}
else
{
$country = "Belgium";
}

$query = new Query(
array(
'criterion' => new Criterion\Field(
"countries",
Criterion\Operator::CONTAINS,
$country
)
)
);

$repository = $this->getRepository();
$searchService = $repository->getSearchService();
$result = $searchService->findContent( $query );

$this->assertEquals( 1, $result->totalCount );
$this->assertEquals(
$testContent->id,
$result->searchHits[0]->valueObject->id
);
}

/**
* Test for the findContent() method.
*
* @see \eZ\Publish\API\Repository\SearchService::findContent()
* @depends eZ\Publish\API\Repository\Tests\RepositoryTest::testGetSearchService
* @depends eZ\Publish\API\Repository\Tests\SearchServiceTest::testFieldCollectionContains
*/
public function testFieldCollectionContainsNoMatch()
{
$this->createMultipleCountriesContent();
$query = new Query(
array(
'criterion' => new Criterion\Field(
"countries",
Criterion\Operator::CONTAINS,
"Netherlands Antilles"
)
)
);

$repository = $this->getRepository();
$searchService = $repository->getSearchService();
$result = $searchService->findContent( $query );

$this->assertEquals( 0, $result->totalCount );
}

/**
* @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
*/
Expand Down Expand Up @@ -1022,6 +1137,7 @@ public function testFindFacettedContent( Query $query, $fixture )
*
* @param Query $query
* @param string $fixture
* @param null|callable $closure
*
* @return void
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ protected function getSearchHandler( $persistenceHandler )
'eztext' => new FieldType\TextLine\SearchField(),
'ezxmltext' => new FieldType\TextLine\SearchField(),
// @todo: Define proper types for these:
'ezcountry' => new FieldType\Unindexed(),
'ezcountry' => new FieldType\Country\SearchField(),
'ezfloat' => new FieldType\Unindexed(),
'ezinteger' => new FieldType\Unindexed(),
'ezuser' => new FieldType\Unindexed(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public function getSpecifications()
new Specifications( Operator::LTE, Specifications::FORMAT_SINGLE ),
new Specifications( Operator::LIKE, Specifications::FORMAT_SINGLE ),
new Specifications( Operator::BETWEEN, Specifications::FORMAT_ARRAY, null, 2 ),
new Specifications( Operator::CONTAINS, Specifications::FORMAT_SINGLE ),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ abstract class Operator
const IN = "in";
const BETWEEN = "between";
const LIKE = "like";
const CONTAINS = "contains";
}
50 changes: 50 additions & 0 deletions eZ/Publish/Core/FieldType/Country/SearchField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
/**
* File containing the Country SearchField class
*
* @copyright Copyright (C) 1999-2013 eZ Systems AS. All rights reserved.
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
* @version //autogentag//
*/

namespace eZ\Publish\Core\FieldType\Country;

use eZ\Publish\SPI\Persistence\Content\Field;
use eZ\Publish\SPI\FieldType\Indexable;
use eZ\Publish\SPI\Persistence\Content\Search;

/**
* Indexable definition for Country field type
*/
class SearchField implements Indexable
{
/**
* Get index data for field for search backend
*
* @param Field $field
*
* @return \eZ\Publish\SPI\Persistence\Content\Search\Field[]
*/
public function getIndexData( Field $field )
{
return array(
new Search\Field(
'value',
$field->value->data,
new Search\FieldType\MultipleStringField()
),
);
}

/**
* Get index field types for search backend
*
* @return \eZ\Publish\SPI\Persistence\Content\Search\FieldType[]
*/
public function getIndexDefinition()
{
return array(
'value' => new Search\FieldType\MultipleStringField(),
);
}
}
5 changes: 2 additions & 3 deletions eZ/Publish/Core/FieldType/TextLine/SearchField.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/**
* File containing the UserStorage class
* File containing the TextLine SearchField class
*
* @copyright Copyright (C) 1999-2013 eZ Systems AS. All rights reserved.
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
Expand All @@ -14,7 +14,7 @@
use eZ\Publish\SPI\Persistence\Content\Search;

/**
* Indexable definition for string field type
* Indexable definition for TextLine field type
*/
class SearchField implements Indexable
{
Expand Down Expand Up @@ -48,4 +48,3 @@ public function getIndexDefinition()
);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,3 @@ public function convertCriteria( ezcQuerySelect $query, Criterion $criterion )
throw new RuntimeException( 'No conversion for criterion found.' );
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use eZ\Publish\API\Repository\Exceptions\NotImplementedException;
use eZ\Publish\Core\Persistence\Legacy\Content\Search\Gateway\CriterionHandler;
use eZ\Publish\Core\Persistence\Legacy\Content\Search\Gateway\CriterionHandler\FieldValue\Converter as FieldValueConverter;
use eZ\Publish\Core\Persistence\Legacy\Content\Search\Gateway\CriteriaConverter;
use eZ\Publish\Core\Persistence\Legacy\EzcDbHandler;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
Expand All @@ -29,7 +30,7 @@ class Field extends CriterionHandler
/**
* DB handler to fetch additional field information
*
* @var \eZ\Publish\Core\Persistence\Legacy\EzcDbHandler
* @var \eZ\Publish\Core\Persistence\Legacy\EzcDbHandler|\ezcDbHandler
*/
protected $dbHandler;

Expand All @@ -40,6 +41,13 @@ class Field extends CriterionHandler
*/
protected $fieldConverterRegistry;

/**
* Field value converter
*
* @var \eZ\Publish\Core\Persistence\Legacy\Content\Search\Gateway\CriterionHandler\Field\ValueConverter
*/
protected $fieldValueConverter;

/**
* Transformation processor
*
Expand All @@ -52,12 +60,19 @@ class Field extends CriterionHandler
*
* @param \eZ\Publish\Core\Persistence\Legacy\EzcDbHandler $dbHandler
* @param \eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry $fieldConverterRegistry
* @param \eZ\Publish\Core\Persistence\Legacy\Content\Search\Gateway\CriterionHandler\FieldValue\Converter $fieldValueConverter
* @param \eZ\Publish\Core\Persistence\TransformationProcessor $transformationProcessor
*/
public function __construct( EzcDbHandler $dbHandler, Registry $fieldConverterRegistry, TransformationProcessor $transformationProcessor )
public function __construct(
EzcDbHandler $dbHandler,
Registry $fieldConverterRegistry,
FieldValueConverter $fieldValueConverter,
TransformationProcessor $transformationProcessor
)
{
$this->dbHandler = $dbHandler;
$this->fieldConverterRegistry = $fieldConverterRegistry;
$this->fieldValueConverter = $fieldValueConverter;
$this->transformationProcessor = $transformationProcessor;
}

Expand Down Expand Up @@ -181,40 +196,12 @@ public function handle( CriteriaConverter $converter, ezcQuerySelect $query, Cri
);
}

$column = $this->dbHandler->quoteColumn( $fieldsInfo['column'] );
switch ( $criterion->operator )
{
case Criterion\Operator::IN:
$filter = $subSelect->expr->in(
$column,
array_map( array( $this, 'lowercase' ), $criterion->value )
);
break;

case Criterion\Operator::BETWEEN:
$filter = $subSelect->expr->between(
$column,
$subSelect->bindValue( $this->lowercase( $criterion->value[0] ) ),
$subSelect->bindValue( $this->lowercase( $criterion->value[1] ) )
);
break;

case Criterion\Operator::EQ:
case Criterion\Operator::GT:
case Criterion\Operator::GTE:
case Criterion\Operator::LT:
case Criterion\Operator::LTE:
case Criterion\Operator::LIKE:
$operatorFunction = $this->comparatorMap[$criterion->operator];
$filter = $subSelect->expr->$operatorFunction(
$column,
$subSelect->bindValue( $this->lowercase( $criterion->value ) )
);
break;

default:
throw new RuntimeException( 'Unknown operator.' );
}
$filter = $this->fieldValueConverter->convertCriteria(
$fieldTypeIdentifier,
$subSelect,
$criterion,
$fieldsInfo['column']
);

$whereExpressions[] = $subSelect->expr->lAnd(
$subSelect->expr->in(
Expand All @@ -241,10 +228,4 @@ public function handle( CriteriaConverter $converter, ezcQuerySelect $query, Cri
$subSelect
);
}

protected function lowerCase( $string )
{
return $this->transformationProcessor->transformByGroup( $string, "lowercase" );
}
}

Loading

0 comments on commit aac3a23

Please sign in to comment.