diff --git a/VERSIONS_HOTLINE/138829 b/VERSIONS_HOTLINE/138829 new file mode 100644 index 0000000000000000000000000000000000000000..ab6f966d6612827bcf6e1b2633ab2758efd299d0 --- /dev/null +++ b/VERSIONS_HOTLINE/138829 @@ -0,0 +1 @@ + - correctif #138829 : Magasin de thème : dédoublonnage des facettes avec le même libellé. Par exemple: les facettes Hugo Victor et Victor Hugo sont regroupés et leurs occurences additionnées \ No newline at end of file diff --git a/library/templates/Intonation/View/Search/Facets.php b/library/templates/Intonation/View/Search/Facets.php index 04748618715e29729dd149d88e40fd7a8950baa6..b690a2e42324372b45dd9aef529876c3eb8f375c 100644 --- a/library/templates/Intonation/View/Search/Facets.php +++ b/library/templates/Intonation/View/Search/Facets.php @@ -158,9 +158,7 @@ class Intonation_View_Search_Facets extends ZendAfi_View_Helper_Facettes { protected function _orderFacets($facets) { - $labels = []; - foreach ($facets as $code => $count) - $labels [Class_Codification::getInstance()->getLibelleFacette($code)] = [$code => $count]; + $labels = $this->_getFacets($facets); if ($this->_preferences['facets_order']) ksort($labels, SORT_NATURAL | SORT_FLAG_CASE); @@ -187,4 +185,74 @@ class Intonation_View_Search_Facets extends ZendAfi_View_Helper_Facettes { protected function isMultiActive($code) { return $this->isActive($code); } + + + protected function _getFacets(array $facets) : array { + $facet_fields = new Storm_Collection; + foreach ($facets as $code => $count) + $this->_addFacet($facet_fields, $code, $count); + + return $facet_fields + ->injectInto([], + function($result, $facet) { + $result [$facet->getLabel()] = [$facet->getCode() => $facet->getCount()]; + + return $result; + }); + } + + + protected function _addFacet(Storm_Collection $facet_fields, + string $code, + int $count) : self { + $label = Class_Codification::getInstance()->getLibelleFacette($code); + $field = $facet_fields->detect(fn($facet) => $label === $facet->getLabel()); + if (!$field) { + $field = new Search_Facets_Field($label); + $facet_fields->add($field); + } + + $field->addCodeAndCount($code, $count); + + return $this; + } +} + + + + +class Search_Facets_Field { + + protected string $_label; + protected string $_code; + protected int $_count; + + public function __construct(string $label) { + $this->_label = $label; + $this->_code = ''; + $this->_count = 0; + } + + + public function getLabel() : string { + return $this->_label; + } + + + public function getCode() : string { + return $this->_code; + } + + + public function getCount() : string { + return $this->_count; + } + + + public function addCodeAndCount(string $code, int $count) : self { + $this->_code .= ($this->_code ? '+' : '') . $code; + $this->_count += $count; + + return $this; + } } diff --git a/tests/scenarios/Templates/TemplatesSearchFacetsTest.php b/tests/scenarios/Templates/TemplatesSearchFacetsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..41893cb42f2b7080899adfbad29a36842cb50d6d --- /dev/null +++ b/tests/scenarios/Templates/TemplatesSearchFacetsTest.php @@ -0,0 +1,107 @@ +<?php +/** + * Copyright (c) 2012-2022, 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 + */ + +require_once 'TemplatesTest.php'; + +/* hotline: https://forge.afi-sa.net/issues/138829 */ +class TemplatesSearchFacetsTest extends AbstractControllerTestCase { + + public function setUp() { + parent::setUp(); + + $this->_buildTemplateProfil(['id' => 1, + 'libelle' => 'Search Facets']) + ->assertSave(); + + $sql = $this->mock() + ->whenCalled('fetchAll') + ->with("select id_notice, facettes from notices Where (MATCH(titres, auteurs, editeur, collection, matieres, dewey, other_terms) AGAINST('+(GUILLAUME GUILLAUMES GIOM) +(MUSSO MUSSOS MUSO)' IN BOOLEAN MODE)) and type=1 order by date_creation asc, alpha_titre asc", + true, + false) + ->answers([[10, 'A1'], + [11, 'A1'], + [12, 'A2'], + [13, 'A3'], + ]); + + Zend_Registry::set('sql', $sql); + + $this->fixture(Class_CodifAuteur::class, + ['id' => 1, + 'libelle' => 'Guillaume Musso' + ]); + $this->fixture(Class_CodifAuteur::class, + ['id' => 2, + 'libelle' => 'Guillaume Musso' + ]); + $this->fixture(Class_CodifAuteur::class, + ['id' => 3, + 'libelle' => 'Arnaud Romain' + ]); + + $this->fixture(Class_Notice::class, + ['id' => 10, + 'auteurs' => 'GUILLAUME MUSSO', + 'facettes' => 'A1', + 'exemplaires' => [$this->fixture(Class_Exemplaire::class, + ['id' => 100, + 'code_barres' => '1234'])] + ]); + $this->fixture(Class_Notice::class, + ['id' => 11, + 'auteurs' => 'GUILLAUME MUSSO', + 'facettes' => 'A1', + 'exemplaires' => [$this->fixture(Class_Exemplaire::class, + ['id' => 101, + 'code_barres' => '5678'])] + ]); + $this->fixture(Class_Notice::class, + ['id' => 12, + 'auteurs' => 'GUILLAUME MUSSO', + 'facettes' => 'A2', + 'exemplaires' => [$this->fixture(Class_Exemplaire::class, + ['id' => 102, + 'code_barres' => '9012'])] + ]); + $this->fixture(Class_Notice::class, + ['id' => 13, + 'auteurs' => 'GUILLAUME MUSSO ARNAUD ROMAIN', + 'facettes' => 'A3', + 'exemplaires' => [$this->fixture(Class_Exemplaire::class, + ['id' => 103, + 'code_barres' => '3456'])] + ]); + + $this->dispatch('recherche/simple/tri/date_creation+asc%2C+alpha_titre+asc/expressionRecherche/guillaume+musso'); + } + + + /** @test */ + public function authorsFacetShouldContainsThreeGuillaumeMussoWithCodesA1_A2() { + $this->assertXPath('//li[@class="facet_item facette list-group-item py-1 pr-1 d-flex justify-content-between align-items-center"]//a[@href="/recherche/simple/tri/date_creation+asc%2C+alpha_titre+asc/expressionRecherche/guillaume+musso/facette/A1%2BA2"][@class="facette text-secondary"][text()="Guillaume Musso"]/following-sibling::span[@class="badge badge-primary badge-pill"][text()=3]'); + } + + + /** @test */ + public function authorsFacetShouldContainsOneArnaudRomainWithCodeA3() { + $this->assertXPath('//li[@class="facet_item facette list-group-item py-1 pr-1 d-flex justify-content-between align-items-center"]//a[@href="/recherche/simple/tri/date_creation+asc%2C+alpha_titre+asc/expressionRecherche/guillaume+musso/facette/A3"][@class="facette text-secondary"][text()="Arnaud Romain"]/following-sibling::span[@class="badge badge-primary badge-pill"][text()=1]'); + } +}