diff --git a/VERSIONS_HOTLINE/128944 b/VERSIONS_HOTLINE/128944 new file mode 100644 index 0000000000000000000000000000000000000000..98839f09083a56dca99030df48a77911a2d5c1fa --- /dev/null +++ b/VERSIONS_HOTLINE/128944 @@ -0,0 +1 @@ + - ticket #128944 : Autorités : Correction d'une erreur dans un résultat de recherche contenant un critère d'autorité \ No newline at end of file diff --git a/library/Class/CodifThesaurusFixed.php b/library/Class/CodifThesaurusFixed.php index a8e25790274c75022b56f11740e7dcc5d3971852..426e2ef7f33326060c4eb11721be35467064b44a 100644 --- a/library/Class/CodifThesaurusFixed.php +++ b/library/Class/CodifThesaurusFixed.php @@ -44,6 +44,22 @@ class Class_CodifThesaurusFixed extends Class_Entity { } + public static function isFixedValue($value) { + if (!$value + || Class_CodifThesaurus::CODE_FACETTE !== substr($value, 0, 1) + || 1 !== (strlen($value) % Class_CodifThesaurus::ID_KEY_LENGTH)) + return false; + + $root = substr($value, 1, Class_CodifThesaurus::ID_KEY_LENGTH); + + return in_array($root, array_map(function($definition) + { + return $definition[0]; + }, + static::$_known)); + } + + public static function __callStatic($name, $args) { $action = substr($name, 0, 3); $target = substr($name, 3); diff --git a/library/Class/CriteresRecherche/AuthoritiesParam.php b/library/Class/CriteresRecherche/AuthoritiesParam.php index bde7be0f070f422fe2d7c00107efde962a6b1f3a..65fb8108a12c8e658ced9f53f96d84d76b0b17cd 100644 --- a/library/Class/CriteresRecherche/AuthoritiesParam.php +++ b/library/Class/CriteresRecherche/AuthoritiesParam.php @@ -215,6 +215,18 @@ abstract class Class_CriteresRecherche_AuthorityParam { } + protected function _dynamicFacetsOf($record) { + if (!$record) + return []; + + return array_filter($record->getDynamicFacetValues(), + function($facet) + { + return !Class_CodifThesaurusFixed::isFixedValue($facet); + }); + } + + public function asString() { return implode(static::PART_SEPARATOR, [$this->_facet, $this->_id, $this->_mode]); @@ -243,7 +255,7 @@ class Class_CriteresRecherche_AuthorityParam_Flat if (!$record = $this->_record()) return; - ($facets = $record->getDynamicFacetValues()) + ($facets = $this->_dynamicFacetsOf($record)) ? $this->_applyFacetsTo($facets, $engine) : $this->_applyDummyFacetTo($engine); } @@ -271,7 +283,7 @@ class Class_CriteresRecherche_AuthorityParam_Hierarchical if (!$record = $this->_record()) return; - $facets = $record->getDynamicFacetValues(); + $facets = $this->_dynamicFacetsOf($record); $this->_collectRecursiveFacetsFrom($record, $facets); $facets @@ -288,7 +300,7 @@ class Class_CriteresRecherche_AuthorityParam_Hierarchical if (!$record = $relation->getRecord()) return; - foreach($record->getDynamicFacetValues() as $facet) + foreach($this->_dynamicFacetsOf($record) as $facet) $facets[] = $facet; $this->_collectRecursiveFacetsFrom($record, $facets); diff --git a/tests/application/modules/opac/controllers/RechercheControllerAuthoritiesTest.php b/tests/application/modules/opac/controllers/RechercheControllerAuthoritiesTest.php new file mode 100644 index 0000000000000000000000000000000000000000..502655571821b347b23b43007f42a13b370ea4e7 --- /dev/null +++ b/tests/application/modules/opac/controllers/RechercheControllerAuthoritiesTest.php @@ -0,0 +1,136 @@ +<?php +/** + * Copyright (c) 2012-2021, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +abstract class RechercheControllerAuthoritiesTestCase extends AbstractControllerTestCase { + protected + $_default_storm_to_volatile = true, + $_current_id = 8898; + + protected function _fixtureRecord($id_origine, $child_id='', $with_thesaurus=true) { + $autority = (new Class_Notice_AuthorityPartial) + ->newWith(Class_Notice_AuthorityType::SUBJECT, + $id_origine, + 'Authority ' . $this->_current_id, + ['b' => 'CUSTOM']); + + if ($child_id) + $autority->zoneWithChildren('550', ['3' => $child_id, '5' => 'h']); + + $thesaurus = $with_thesaurus + ? ('HDOCU' . $this->_current_id) + : ''; + + $this->fixture('Class_Notice', + ['id' => $this->_current_id, + 'type_doc' => Class_Notice_AuthorityType::SUBJECT, + 'facettes' => 'HDOCU ' . $thesaurus . ' HNRNR0001', + 'type' => Class_Notice::TYPE_AUTHORITY, + 'unimarc' => $autority->render()]); + + $this->fixture('Class_Exemplaire', + ['id' => $this->_current_id, + 'type' => Class_Notice::TYPE_AUTHORITY, + 'id_int_bib' => 1, + 'id_origine' => $id_origine, + 'id_notice' => $this->_current_id]); + + $this->_current_id++; + } +} + + + + +class RechercheControllerAuthoritiesRecordHeirarchyWithHolesTest + extends RechercheControllerAuthoritiesTestCase { + + public function setUp() { + parent::setUp(); + + $this->fixture('Class_CodifThesaurus', + ['id' => 78, + 'id_thesaurus' => 'DOCU', + 'libelle' => 'Documentary']); + + $this->_fixtureRecord('189260', '111111', false); + $this->_fixtureRecord('111111', '222222'); + $this->_fixtureRecord('222222', '333333', false); + $this->_fixtureRecord('333333', ''); + + $this->mock_sql = $this->mock()->beStrict(); + Zend_Registry::set('sql', $this->mock_sql); + } + + + /** @test */ + public function withoutHierarchyAndNoFacetShouldQueryOnDummyFacet() { + $this->mock_sql->whenCalled('fetchAll') + ->with("select id_notice, facettes from notices Where (MATCH(facettes) AGAINST('+(H0000)' IN BOOLEAN MODE)) and type=1", true, false) + ->answers([]); + + $this->dispatch('/opac/recherche/simple/authorities/HDOCU_8898_0'); + $this->assertTrue($this->mock_sql->methodHasBeenCalled('fetchAll')); + } + + + /** @test */ + public function withoutHierarchyAndNoFacetShouldDisplayDocumentaryAuthority8898() { + $this->mock_sql->whenCalled('fetchAll') + ->with("select id_notice, facettes from notices Where (MATCH(facettes) AGAINST('+(H0000)' IN BOOLEAN MODE)) and type=1", true, false) + ->answers([]); + + $this->dispatch('/opac/recherche/simple/authorities/HDOCU_8898_0'); + $this->assertXPathContentContains('//a', 'Documentary: Authority 8898'); + } + + + /** @test */ + public function withoutHierarchyAndLocalFacetShouldQueryOnLocalFacet() { + $this->mock_sql->whenCalled('fetchAll') + ->with("select id_notice, facettes from notices Where (MATCH(facettes) AGAINST('+(HDOCU8899)' IN BOOLEAN MODE)) and type=1", true, false) + ->answers([]); + + $this->dispatch('/opac/recherche/simple/authorities/HDOCU_8899_0'); + $this->assertTrue($this->mock_sql->methodHasBeenCalled('fetchAll')); + } + + /** @test */ + public function withHierarchyAndNoFacetShouldQueryOnChildrenFacets() { + $this->mock_sql->whenCalled('fetchAll') + ->with("select id_notice, facettes from notices Where (MATCH(facettes) AGAINST('+(HDOCU8899 HDOCU8901)' IN BOOLEAN MODE)) and type=1", true, false) + ->answers([]); + + $this->dispatch('/opac/recherche/simple/authorities/HDOCU_8898_1'); + $this->assertTrue($this->mock_sql->methodHasBeenCalled('fetchAll')); + } + + + /** @test */ + public function withHierarchyAndLocalFacetShouldQueryOnLocalAndChildrenFacet() { + $this->mock_sql->whenCalled('fetchAll') + ->with("select id_notice, facettes from notices Where (MATCH(facettes) AGAINST('+(HDOCU8899 HDOCU8901)' IN BOOLEAN MODE)) and type=1", true, false) + ->answers([]); + + $this->dispatch('/opac/recherche/simple/authorities/HDOCU_8899_1'); + $this->assertTrue($this->mock_sql->methodHasBeenCalled('fetchAll')); + } +} diff --git a/tests/application/modules/opac/controllers/RechercheControllerTest.php b/tests/application/modules/opac/controllers/RechercheControllerTest.php index 83748d2c5f1cabbdb87da6182faf32355691fb23..f0740e80a9295a721ab8fa4e8043351fdcad4005 100644 --- a/tests/application/modules/opac/controllers/RechercheControllerTest.php +++ b/tests/application/modules/opac/controllers/RechercheControllerTest.php @@ -3890,122 +3890,3 @@ class RechercheControllerNoExtensionTest extends AbstractControllerTestCase { $this->assertXPathContentContains('//div[@class="liste_notices"]/h2', 'Aucun résultat trouvé'); } } - - - - -abstract class RechercheControllerAuthoritiesTestCase extends RechercheControllerNoticeTestCase { - protected - $_default_storm_to_volatile = true, - $_current_id = 8898; - - protected function _fixtureRecord($id_origine, $child_id='', $with_thesaurus=true) { - $autority = (new Class_Notice_AuthorityPartial) - ->newWith(Class_Notice_AuthorityType::SUBJECT, - $id_origine, - 'Authority ' . $this->_current_id, - ['b' => 'CUSTOM']); - - if ($child_id) - $autority->zoneWithChildren('550', ['3' => $child_id, '5' => 'h']); - - $thesaurus = $with_thesaurus - ? ('HDOCU' . $this->_current_id) - : ''; - - $this->fixture('Class_Notice', - ['id' => $this->_current_id, - 'type_doc' => Class_Notice_AuthorityType::SUBJECT, - 'facettes' => 'HDOCU ' . $thesaurus, - 'type' => Class_Notice::TYPE_AUTHORITY, - 'unimarc' => $autority->render()]); - - $this->fixture('Class_Exemplaire', - ['id' => $this->_current_id, - 'type' => Class_Notice::TYPE_AUTHORITY, - 'id_int_bib' => 1, - 'id_origine' => $id_origine, - 'id_notice' => $this->_current_id]); - - $this->_current_id++; - } -} - - - - -class RechercheControllerAuthoritiesRecordHeirarchyWithHolesTest - extends RechercheControllerAuthoritiesTestCase { - - public function setUp() { - parent::setUp(); - - $this->fixture('Class_CodifThesaurus', - ['id' => 78, - 'id_thesaurus' => 'DOCU', - 'libelle' => 'Documentary']); - - $this->_fixtureRecord('189260', '111111', false); - $this->_fixtureRecord('111111', '222222'); - $this->_fixtureRecord('222222', '333333', false); - $this->_fixtureRecord('333333', ''); - - $this->mock_sql = $this->mock()->beStrict(); - Zend_Registry::set('sql', $this->mock_sql); - } - - - /** @test */ - public function withoutHierarchyAndNoFacetShouldQueryOnDummyFacet() { - $this->mock_sql->whenCalled('fetchAll') - ->with("select id_notice, facettes from notices Where (MATCH(facettes) AGAINST('+(H0000)' IN BOOLEAN MODE)) and type=1", true, false) - ->answers([]); - - $this->dispatch('/opac/recherche/simple/authorities/HDOCU_8898_0'); - $this->assertTrue($this->mock_sql->methodHasBeenCalled('fetchAll')); - } - - - /** @test */ - public function withoutHierarchyAndNoFacetShouldDisplayDocumentaryAuthority8898() { - $this->mock_sql->whenCalled('fetchAll') - ->with("select id_notice, facettes from notices Where (MATCH(facettes) AGAINST('+(H0000)' IN BOOLEAN MODE)) and type=1", true, false) - ->answers([]); - - $this->dispatch('/opac/recherche/simple/authorities/HDOCU_8898_0'); - $this->assertXPathContentContains('//a', 'Documentary: Authority 8898'); - } - - - /** @test */ - public function withoutHierarchyAndLocalFacetShouldQueryOnLocalFacet() { - $this->mock_sql->whenCalled('fetchAll') - ->with("select id_notice, facettes from notices Where (MATCH(facettes) AGAINST('+(HDOCU8899)' IN BOOLEAN MODE)) and type=1", true, false) - ->answers([]); - - $this->dispatch('/opac/recherche/simple/authorities/HDOCU_8899_0'); - $this->assertTrue($this->mock_sql->methodHasBeenCalled('fetchAll')); - } - - - /** @test */ - public function withHierarchyAndNoFacetShouldQueryOnChildrenFacets() { - $this->mock_sql->whenCalled('fetchAll') - ->with("select id_notice, facettes from notices Where (MATCH(facettes) AGAINST('+(HDOCU8899 HDOCU8901)' IN BOOLEAN MODE)) and type=1", true, false) - ->answers([]); - - $this->dispatch('/opac/recherche/simple/authorities/HDOCU_8898_1'); - $this->assertTrue($this->mock_sql->methodHasBeenCalled('fetchAll')); - } - - - /** @test */ - public function withHierarchyAndLocalFacetShouldQueryOnLocalAndChildrenFacet() { - $this->mock_sql->whenCalled('fetchAll') - ->with("select id_notice, facettes from notices Where (MATCH(facettes) AGAINST('+(HDOCU8899 HDOCU8901)' IN BOOLEAN MODE)) and type=1", true, false) - ->answers([]); - - $this->dispatch('/opac/recherche/simple/authorities/HDOCU_8899_1'); - $this->assertTrue($this->mock_sql->methodHasBeenCalled('fetchAll')); - } -}