diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php index c8a2318d74..917fb2ff10 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/ElasticSearchEngine.php @@ -326,28 +326,19 @@ class ElasticSearchEngine implements SearchEngineInterface */ private function getAllowedPrivateFields(SearchEngineOptions $options) { - $fields = array_keys($this->structure->getPrivateFields()); - - $allowed = array_fill_keys($fields, []); - foreach ($options->getDataboxes() as $databox) { - $databoxFields = $databox->get_meta_structure(); - foreach ($fields as $field) { - if ($databoxFields->get_element_by_name($field)) { - $allowed[$field] += $databox->get_collection_unique_ids(); - } - } + // Get structure data and cross it with user rights (from options object) + $allowed_collections = []; + foreach ($options->getBusinessFieldsOn() as $collection) { + $allowed_collections[] = $collection->get_base_id(); } - $businessCollections = array_map(function (\collection $collection) { - return $collection->get_base_id(); - }, $options->getBusinessFieldsOn()); - + $map = $this->structure->getCollectionsUsedByPrivateFields(); // Remove collections base_id which access is restricted. - foreach ($allowed as $name => &$collections) { - $collections = array_diff($collections, $businessCollections); + foreach ($map as $_ => &$collections) { + $collections = array_intersect($collections, $allowed_collections); } - return $allowed; + return $map; } /** diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/Field.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/Field.php index cb11a42307..3d0ddb47b5 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/Field.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/Field.php @@ -98,9 +98,9 @@ class Field return $this->type; } - public function getCollections() + public function getDependantCollections() { - return $this->collections; + return $this->used_by_collections; } public function isSearchable() @@ -169,10 +169,15 @@ class Field ); } - $used_by_collections = array_unique(array_merge( - $this->used_by_collections, - $other->used_by_collections - ), SORT_REGULAR); + $used_by_collections = array_values( + array_unique( + array_merge( + $this->used_by_collections, + $other->used_by_collections + ), + SORT_REGULAR + ) + ); return new self($this->name, $this->type, [ 'searchable' => $this->is_searchable, diff --git a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/Structure.php b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/Structure.php index fd997bdd16..a7e1c0ced7 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/Structure.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Elastic/Structure/Structure.php @@ -103,4 +103,22 @@ class Structure throw new DomainException(sprintf('Unknown field "%s".', $name)); } + + /** + * Returns an array of collections indexed by field name. + * + * [ + * "FieldName" => [1, 4, 5], + * "OtherFieldName" => [4], + * ] + */ + public function getCollectionsUsedByPrivateFields() + { + $map = []; + foreach ($this->private as $name => $field) { + $map[$name] = $field->getDependantCollections(); + } + + return $map; + } } diff --git a/tests/Alchemy/Tests/Phrasea/SearchEngine/Structure/FieldTest.php b/tests/Alchemy/Tests/Phrasea/SearchEngine/Structure/FieldTest.php index 3a5e49dd77..32c758194f 100644 --- a/tests/Alchemy/Tests/Phrasea/SearchEngine/Structure/FieldTest.php +++ b/tests/Alchemy/Tests/Phrasea/SearchEngine/Structure/FieldTest.php @@ -26,7 +26,7 @@ class FieldTest extends \PHPUnit_Framework_TestCase $this->assertFalse($merged->isPrivate()); $this->assertFalse($merged->isFacet()); $this->assertNull($merged->getThesaurusRoots()); - $this->assertEquals(['1', '2', '3', '4'], $merged->getCollections()); + $this->assertEquals(['1', '2', '3', '4'], $merged->getDependantCollections()); } /** @@ -106,4 +106,16 @@ class FieldTest extends \PHPUnit_Framework_TestCase $merged = $field->mergeWith($other); $this->assertEquals([$foo, $bar], $merged->getThesaurusRoots()); } + + public function testMergeWithDependantCollections() + { + $field = new Field('foo', Mapping::TYPE_STRING, [ + 'used_by_collections' => [1, 2] + ]); + $other = new Field('foo', Mapping::TYPE_STRING, [ + 'used_by_collections' => [2, 3] + ]); + $merged = $field->mergeWith($other); + $this->assertEquals([1, 2, 3], $merged->getDependantCollections()); + } } diff --git a/tests/Alchemy/Tests/Phrasea/SearchEngine/Structure/StructureTest.php b/tests/Alchemy/Tests/Phrasea/SearchEngine/Structure/StructureTest.php index 93bd0fb042..1aab40e031 100644 --- a/tests/Alchemy/Tests/Phrasea/SearchEngine/Structure/StructureTest.php +++ b/tests/Alchemy/Tests/Phrasea/SearchEngine/Structure/StructureTest.php @@ -34,7 +34,7 @@ class StructureTest extends \PHPUnit_Framework_TestCase $field->isPrivate()->willReturn(false); $field->isFacet()->willReturn(false); $field->hasConceptInference()->willReturn(false); - $field->getCollections()->willReturn(['1']); + $field->getDependantCollections()->willReturn(['1']); $structure->add($field->reveal()); $this->assertCount(1, $structure->getAllFields()); @@ -173,4 +173,28 @@ class StructureTest extends \PHPUnit_Framework_TestCase $structure = new Structure(); $structure->isPrivate('foo'); } + + public function testCollectionsUsedByPrivateFields() + { + $structure = new Structure(); + $structure->add($foo = (new Field('foo', Mapping::TYPE_STRING, [ + 'private' => true, + 'used_by_collections' => [1, 2] + ]))); + $structure->add(new Field('foo', Mapping::TYPE_STRING, [ + 'private' => true, + 'used_by_collections' => [2, 3] + ])); + $structure->add(new Field('bar', Mapping::TYPE_STRING, [ + 'private' => true, + 'used_by_collections' => [2, 3] + ])); + $structure->add(new Field('baz', Mapping::TYPE_STRING, ['private' => false])); + $this->assertEquals([1, 2], $foo->getDependantCollections()); + static $expected = [ + 'foo' => [1, 2, 3], + 'bar' => [2, 3] + ]; + $this->assertEquals($expected, $structure->getCollectionsUsedByPrivateFields()); + } }