Skip to content

Instantly share code, notes, and snippets.

@wizhippo
Created April 15, 2015 17:33
Show Gist options
  • Save wizhippo/5b0909c83b827bfe8eb1 to your computer and use it in GitHub Desktop.
Save wizhippo/5b0909c83b827bfe8eb1 to your computer and use it in GitHub Desktop.
<?php
namespace ExampleBundle\Core\Persistence\Legacy\Content\Search\Common\Gateway\CriterionHandler;
use eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler;
use eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\CriteriaConverter;
use eZ\Publish\Core\Persistence\Database\DatabaseHandler;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
use eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry as Registry;
use eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\Converter;
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException;
use eZ\Publish\Core\Persistence\TransformationProcessor;
use eZ\Publish\Core\Persistence\Database\SelectQuery;
use RuntimeException;
use Tocom\Bundle\CoreBundle\API\Repository\Values\Content\Query\Criterion\Attribute as AttributeValue;
/**
* Field criterion handler
*/
class Attribute extends CriterionHandler
{
/**
* DB handler to fetch additional field information
*
* @var \eZ\Publish\Core\Persistence\Database\DatabaseHandler
*/
protected $dbHandler;
/**
* Field converter registry
*
* @var \eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry
*/
protected $fieldConverterRegistry;
/**
* Transformation processor
*
* @var \eZ\Publish\Core\Persistence\TransformationProcessor
*/
protected $transformationProcessor;
/**
* Construct from handler handler
*
* @param \eZ\Publish\Core\Persistence\Database\DatabaseHandler $dbHandler
* @param \eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry $fieldConverterRegistry
* @param \eZ\Publish\Core\Persistence\TransformationProcessor $transformationProcessor
*/
public function __construct(
DatabaseHandler $dbHandler,
Registry $fieldConverterRegistry,
TransformationProcessor $transformationProcessor
)
{
$this->dbHandler = $dbHandler;
$this->fieldConverterRegistry = $fieldConverterRegistry;
$this->transformationProcessor = $transformationProcessor;
}
/**
* Check if this criterion handler accepts to handle the given criterion.
*
* @param \eZ\Publish\API\Repository\Values\Content\Query\Criterion $criterion
*
* @return boolean
*/
public function accept( Criterion $criterion )
{
return $criterion instanceof AttributeValue;
}
/**
* Returns relevant field information for the specified field
*
* The returned information is returned as an array of the attribute
* identifier and the sort column, which should be used.
*
* @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException If no searchable fields are found for the given $fieldIdentifier.
* @throws \RuntimeException if no converter is found
*
* @caching
*
* @param string $fieldIdentifier
*
* @return array
*/
protected function getFieldsInformation( $fieldIdentifier )
{
$query = $this->dbHandler->createSelectQuery();
$query
->select(
$this->dbHandler->quoteColumn( 'id', 'ezcontentclass_attribute' ),
$this->dbHandler->quoteColumn( 'data_type_string', 'ezcontentclass_attribute' )
)
->from(
$this->dbHandler->quoteTable( 'ezcontentclass_attribute' )
)
->where(
$query->expr->lAnd(
$query->expr->eq(
$this->dbHandler->quoteColumn( 'identifier', 'ezcontentclass_attribute' ),
$query->bindValue( $fieldIdentifier )
),
$query->expr->eq(
$this->dbHandler->quoteColumn(
'is_searchable',
'ezcontentclass_attribute'
),
$query->bindValue( 1, null, \PDO::PARAM_INT )
)
)
);
$statement = $query->prepare();
$statement->execute();
if ( !( $rows = $statement->fetchAll( \PDO::FETCH_ASSOC ) ) )
{
throw new InvalidArgumentException(
"\$criterion->target",
"No searchable fields found for the given criterion target '{$fieldIdentifier}'."
);
}
$fieldMapArray = array();
foreach ( $rows as $row )
{
if ( !isset( $fieldMapArray[$row['data_type_string']] ) )
{
$converter = $this->fieldConverterRegistry->getConverter(
$row['data_type_string']
);
if ( !$converter instanceof Converter )
{
throw new RuntimeException(
"getConverter({$row['data_type_string']}) did not return a converter, got: " .
gettype( $converter )
);
}
$fieldMapArray[$row['data_type_string']] = array(
'ids' => array(),
'column' => $converter->getIndexColumn(),
);
}
$fieldMapArray[$row['data_type_string']]['ids'][] = $row['id'];
}
return $fieldMapArray;
}
/**
* Generate query expression for a Criterion this handler accepts
*
* accept() must be called before calling this method.
*
* @throws \eZ\Publish\API\Repository\Exceptions\NotImplementedException If no searchable fields are found for the given criterion target.
*
* @param \eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\CriteriaConverter $converter
* @param \eZ\Publish\Core\Persistence\Database\SelectQuery $query
* @param \eZ\Publish\API\Repository\Values\Content\Query\Criterion $criterion
*
* @return \eZ\Publish\Core\Persistence\Database\Expression
*/
public function handle( CriteriaConverter $converter, SelectQuery $query, Criterion $criterion )
{
list( $contentClassId, $target ) = explode( '/', $criterion->target );
$fieldsInformation = $this->getFieldsInformation( $target );
$query->innerJoin(
$this->dbHandler->quoteTable( 'ezcontentclass' ),
$query->expr->lAnd(
$query->expr->in(
$this->dbHandler->quoteColumn( 'identifier', 'ezcontentclass' ),
array( $contentClassId )
),
$query->expr->eq(
$this->dbHandler->quoteColumn( 'id', 'ezcontentclass' ),
$this->dbHandler->quoteColumn( 'contentclass_id', 'ezcontentobject' )
)
)
);
$query->innerJoin(
$this->dbHandler->quoteTable( 'ezcontentobject_attribute' ),
$query->expr->lAnd(
$query->expr->eq(
$this->dbHandler->quoteColumn(
'contentobject_id',
'ezcontentobject_attribute'
),
$this->dbHandler->quoteColumn( 'id', 'ezcontentobject' )
),
$query->expr->eq(
$this->dbHandler->quoteColumn( 'version', 'ezcontentobject_attribute' ),
$this->dbHandler->quoteColumn( 'current_version', 'ezcontentobject' )
)
)
);
$whereExpressions = array(
$query->expr->eq(
$this->dbHandler->quoteColumn(
'sort_key_string',
'ezcontentobject_attribute'
),
"'" . (string)$criterion->value[0] . "'"
)
);
foreach ( $fieldsInformation as $fieldTypeIdentifier => $fieldsInfo )
{
$whereExpressions[] = $query->expr->in(
$this->dbHandler->quoteColumn(
'contentclassattribute_id',
'ezcontentobject_attribute'
),
$fieldsInfo['ids']
);
}
return count( $whereExpressions ) > 1 ? $query->expr->lAnd(
$whereExpressions
) : $whereExpressions[0];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment