Commit 2e069d4e authored by Bernhard Schussek's avatar Bernhard Schussek

Merge branch 'feature/avz-event' into 'master'

ÖWM AVZ registration tweaks

See merge request !1
parents 57fd2051 871db92d
......@@ -122,29 +122,35 @@ abstract class ORMRepository extends EntityRepository implements EditableReposit
*/
public function getMultiple(array $ids, bool $ignoreMissing = false): Cursor
{
if (0 === count($ids)) {
if ([] === $ids) {
return new EmptyCursor();
}
// Index by ID for the ID check below
$results = $this->createQueryBuilder('e', sprintf('e.%s', $this->idField))
$aggregates = $this->createQueryBuilder('e', sprintf('e.%s', $this->idField))
->where(sprintf('e.%s IN (:ids)', $this->idField))
->setParameter('ids', array_map('strval', array_values($ids)))
->getQuery()
->execute();
$cursor = new ArrayCursor($aggregates);
if ($ignoreMissing) {
return $cursor;
}
$notFoundIds = array_filter(
$ids,
function (Id $id) use ($results) {
return !isset($results[$id->toString()]);
function (Id $id) use ($aggregates) {
return !isset($aggregates[$id->toString()]);
}
);
if (!$ignoreMissing && count($notFoundIds) > 0) {
if ([] !== $notFoundIds) {
throw NoResultFound::objectsWithIds($notFoundIds, $this->getClassName());
}
return new ArrayCursor(array_values($results));
return $cursor;
}
/**
......@@ -152,7 +158,7 @@ abstract class ORMRepository extends EntityRepository implements EditableReposit
*/
public function getMultipleBy(array $fieldValues): Cursor
{
if (0 === count($fieldValues)) {
if ([] === $fieldValues) {
return new EmptyCursor();
}
......@@ -213,30 +219,58 @@ abstract class ORMRepository extends EntityRepository implements EditableReposit
return [];
}
// Make sure we don't pass through any invalid field names
$fieldNames = array_intersect($fieldNames, $this->_class->getFieldNames());
$fieldNames = $this->retrieveFieldsToSelect($fieldNames);
$suggestFieldName = $this->getSuggestFieldName();
$containsEmbeddedFields = array_reduce(
$fieldNames,
function ($containsEmbeddedFields, string $field): bool {
return $containsEmbeddedFields || false !== mb_strpos($field, '.');
},
false
);
$qb = $this->createQueryBuilder('e')->select('e.'.implode(', e.', $fieldNames));
$orExpressions = array_map(
function (string $field): string {
return sprintf(
'distance(e.%s, :text) < %f',
$field,
self::SUGGEST_DISTANCE_THRESHOLD
);
},
$this->getSuggestFieldNames()
);
$qb = $this->createQueryBuilder('e')
->select('e.'.implode(', e.', $fieldNames))
->where(sprintf(
'distance(e.%s, :text) < %f',
$suggestFieldName,
self::SUGGEST_DISTANCE_THRESHOLD
));
$qb->where($qb->expr()->orX(...$orExpressions));
$qb->setParameter('text', $text);
foreach ($filters as $field => $value) {
$qb->andWhere(sprintf('e.%1$s = :filter%1$s', $field))
->setParameter(sprintf('filter%s', $field), $value);
$qb
->andWhere(sprintf('e.%1$s = :filter%1$s', $field))
->setParameter(sprintf('filter%s', $field), $value)
;
}
return $qb->orderBy(sprintf('distance(e.%s, :text)', $suggestFieldName))
->setParameter('text', $text)
foreach ($this->getSuggestFieldNames() as $field) {
$qb->addOrderBy(sprintf('distance(e.%s, :text)', $field));
}
$result = $qb
->setMaxResults(self::SUGGEST_LIMIT)
->getQuery()
->setHydrationMode(Query::HYDRATE_SCALAR)
->execute();
->execute()
;
if (!$containsEmbeddedFields) {
return $result;
}
return array_map(
[self::class, 'convertEmbeddablePath'],
$result
);
}
/**
......@@ -284,6 +318,17 @@ abstract class ORMRepository extends EntityRepository implements EditableReposit
return [$this->getEntityName()];
}
/**
* @param string[] $fieldNames
*
* @return string[]
*/
protected function retrieveFieldsToSelect(array $fieldNames): array
{
// Make sure we don't pass through any invalid field names
return array_intersect($fieldNames, $this->_class->getFieldNames());
}
/**
* Synchronizes the changes of all objects of the given class names with
* the database.
......@@ -293,7 +338,7 @@ abstract class ORMRepository extends EntityRepository implements EditableReposit
*
* @throws DuplicateValue If a unique constraint was violated
*/
protected function doFlush(array $classNames)
protected function doFlush(array $classNames): void
{
foreach ($classNames as $className) {
// Get fresh identity map after every flush() (orphan removal!)
......@@ -470,11 +515,11 @@ abstract class ORMRepository extends EntityRepository implements EditableReposit
/**
* Returns the field used for suggesting.
*
* @return string The field name used for suggesting
* @return string[] The field names used for suggesting
*/
protected function getSuggestFieldName(): string
protected function getSuggestFieldNames(): array
{
return 'name';
return ['name'];
}
/**
......@@ -564,4 +609,23 @@ abstract class ORMRepository extends EntityRepository implements EditableReposit
return QueryBuilderBuilder::create($queryBuilder, 'e', $offsetStrategy);
}
private static function convertEmbeddablePath(array $array): array
{
$converted = [];
foreach ($array as $path => $value) {
(function (&$array, string $path, $value): void {
$keys = explode('.', $path);
foreach ($keys as $key) {
$array = &$array[$key];
}
$array = $value;
})($converted, $path, $value);
}
return $converted;
}
}
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