Commit dfd88b94 authored by Patrick Barroca's avatar Patrick Barroca 😁
Browse files

Merge branch 'hotline#133782_aide_pour_les_facettes_dynamiques' into 'hotline'

hotline #133782 : fix filter on dynamic facets

See merge request afi/opacce!4127
parents 96b4624c b0aec4ab
- ticket #133782 : Cosmogramme : Les facettes dynamiques ne se créaient pas lorsqu'elles avaient le même champs de libellé et de filtre
\ No newline at end of file
......@@ -689,11 +689,6 @@ class Class_CodifThesaurus extends Storm_Model_Abstract {
}
public function rulesTruncateLabels($labels) {
return $this->_getListRules()->truncateLabels($labels);
}
public function getRulesAsArray() {
return ['rule_list_zone' => $this->getRuleListZone(),
'rule_list_label_field' => $this->getRuleListLabelField(),
......
......@@ -116,68 +116,7 @@ class Class_CodifThesaurus_Rules extends Class_Entity {
* @param $reader cosmogramme notice_unimarc
*/
public function extractIdAndFields($reader) {
if (!$label_field = trim($this->getLabelField()))
return [];
$id_field = trim($this->getIdField());
$filter_field = $this->getFilterField();
$fields = $reader->cutBlockBySubfields($this->getZonePadded(),
[$label_field => 'label',
$id_field => 'id',
$filter_field => 'filter'],
[$this, 'filterSubfieldIn']);
return array_filter(array_map([$this, 'buildAuthorityStructure'],
$fields));
}
public function filterSubfieldIn($block) {
$label = $this->truncateLabel($block->get('label'));
if (!$this->isValidLabel($label))
return false;
$filter_zone = $this->getZone();
$filter_field = $this->getFilterField();
$filter_value = $this->getFilterValue();
if (!$filter_zone || (null === $filter_field) | !$filter_value)
return true;
return $block->get('filter') == $filter_value;
}
public function buildAuthorityStructure($block){
$label = $this->truncateLabel($block->get('label'));
return ['id' => ($block->get('id')
? strtoupper($block->get('id'))
: ''),
'label' => $label];
}
public function truncateLabels($labels) {
return array_filter(
array_map([$this, 'truncateLabel'], $labels),
[$this, 'isValidLabel']);
}
public function truncateLabel($label) {
if (!$this->getLabelLength())
return $label;
return $this->isValidLabel($label)
? substr($label,
max(0, $this->getLabelStartPos()-1),
$this->getLabelLength())
: '';
}
public function isValidLabel($label) {
return is_string($label) && $label > '';
return (new Class_NoticeUnimarc_ExtractFields($reader, $this))->getListFields();
}
......@@ -190,4 +129,4 @@ class Class_CodifThesaurus_Rules extends Class_Entity {
public function getZonePadded() {
return sprintf('%03d', trim($this->getZone()));
}
}
\ No newline at end of file
}
......@@ -231,59 +231,15 @@ class Class_NoticeUnimarc {
),...
]
*/
public function cutBlockBySubfields($zone, $subfields_mapping, $closure_valid = null) {
$this->blocks=[];
foreach ($this->get_subfield($zone) as $line) {
$this->_cutLineBySubfields($line, $subfields_mapping,$closure_valid);
}
return $this->blocks;
public function cutBlockBySubfields($zone, $subfields_mapping) {
return (new Class_NoticeUnimarc_ExtractFields($this, $subfields_mapping, $zone))
->getListFields();
}
protected function _cutLineBySubfields($line, $subfields_mapping, $closure_valid) {
$block = $this->_newBlock();
$fields = $this->_bloc_to_array($line);
$bloc_values = array_values($subfields_mapping);
foreach($fields as $field) {
$code = substr($field, 0, 1);
$value = trim(substr($field, 1));
if (!in_array($code,array_keys($subfields_mapping)))
continue;
if ($block->get($subfields_mapping[$code])) {
$block = $this->_addBlock($block,$closure_valid);
}
$block->set($subfields_mapping[$code], $value);
}
$this->_addBlock($block,$closure_valid);
return $this;
}
protected function _newBlock() {
return new Class_Entity();
}
protected function _addBlock($block, $closure_valid) {
if (!$closure_valid || call_user_func($closure_valid,$block))
$this->blocks[] = $block;
return $this->_newBlock();
}
protected function _bloc_to_array($bloc) {
$bloc = substr($bloc, 3);
return explode($this->subfield_begin, $bloc);
public function lineToArray($line) {
$line = substr($line, 3);
return explode($this->subfield_begin, $line);
}
......@@ -383,7 +339,7 @@ class Class_NoticeUnimarc {
public function get_field($zone) {
$instance = new Class_NoticeUnimarc_Field;
$instance = new Class_Entity();
$bloc = substr($zone, 3);
$fields = explode($this->subfield_begin, $bloc);
......
<?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
*/
class Class_NoticeUnimarc_ExtractFields {
protected
$_reader,
$_list_fields;
public function __construct($reader, $rules_or_array, $zone = null) {
$this->_reader = $reader;
$this->_list_fields = Class_NoticeUnimarc_ListFields::newFor($rules_or_array,
$zone);
}
public function getListFields() {
if (!$this->_list_fields->isValid())
return [];
foreach ($this->_reader->get_subfield($this->_list_fields->getZone()) as $line)
$this->_cutLineBySubfields($line);
return $this->_list_fields->getListResult();
}
protected function _cutLineBySubfields($line) {
$fields = $this->_reader->lineToArray($line);
foreach ($fields as $field) {
$code = substr($field, 0, 1);
$value = trim(substr($field, 1));
$this->_list_fields->addCodeValue($code, $value);
}
$this->_list_fields->addInResultAndReset();
return $this;
}
}
<?php
/**
* Copyright (c) 2012-2019, Agence Française Informatique (AFI). All rights reserved.
* 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
......@@ -20,4 +20,41 @@
*/
class Class_NoticeUnimarc_Field extends Class_Entity {}
class Class_NoticeUnimarc_Field {
protected
$_code,
$_value,
$_label;
public function __construct($code, $label) {
$this->_code = $code;
$this->_label = $label;
}
public function getCode() {
return $this->_code;
}
public function isSameCode($code) {
return $code && $code == $this->getCode();
}
public function getLabel() {
return $this->_label;
}
public function getValue() {
return $this->_value;
}
public function setValue($value) {
$this->_value = $value;
return $this;
}
}
<?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
*/
class Class_NoticeUnimarc_ListFields {
protected
$_list_fields,
$_list_result,
$_zone,
$_valid = false;
public function __construct($rules_or_array, $zone = null) {
$this->_list_fields = new Storm_Collection();
$this->_list_result = [];
$this->_zone = $zone;
$this->_init($rules_or_array);
}
public static function newFor($rules_or_array, $zone = null) {
if (is_a($rules_or_array, Class_CodifThesaurus_Rules::class))
return new Class_NoticeUnimarc_ListFieldsRules($rules_or_array, $zone);
return new static($rules_or_array, $zone);
}
public function isValid() {
return $this->_valid;
}
public function getListResult() {
return $this->_list_result;
}
public function getZone() {
return $this->_zone;
}
public function addCodeValue($code, $value) {
if (!($working_list = $this->_getWorkingList($code)))
return $this;
$with_value = $working_list->detect(function ($field) {
return $field->getValue();
});
if ($with_value)
return $this->addInResultAndReset($code, $value);
$working_list->eachDo(function ($field) use ($value) {
$field->setValue($value);
});
return $this;
}
public function addInResultAndReset($code = null, $value = null) {
if ($this->_canAddResult())
$this->_list_result [] = $this->_buildOneResult();
$this->_reset();
$this->_addAfterReset($code, $value);
return $this;
}
protected function _init($array) {
if (!($this->_valid = is_array($array)))
return $this;
foreach ($array as $code => $label)
$this->_list_fields->add(new Class_NoticeUnimarc_Field($code, $label));
return $this;
}
protected function _getWorkingList($code) {
if (!$this->isValid() || !$code)
return null;
$working_list = $this->_list_fields->select(function ($field) use ($code) {
return $field->isSameCode($code);
});
return $working_list->isEmpty()
? null
: $working_list;
}
protected function _reset() {
$this->_list_fields->eachDo(function ($field) {
$field->setValue(null);
});
return $this;
}
protected function _addAfterReset($code, $value) {
if (!($working_list = $this->_getWorkingList($code)))
return $this;
$working_list->eachDo(function ($field) use ($value) {
$field->setValue($value);
});
return $this;
}
protected function _canAddResult() {
return true;
}
protected function _buildOneResult() {
$array = [];
$this->_list_fields->eachDo(function ($field) use (&$array) {
$array [$field->getLabel()] = $field->getValue();
});
return $array;
}
}
class Class_NoticeUnimarc_ListFieldsRules extends Class_NoticeUnimarc_ListFields {
const
ID = 'id',
LABEL = 'label',
FILTER = 'filter';
protected $_rules;
protected function _init($rules) {
$label_field = new Class_NoticeUnimarc_Field(trim($rules->getLabelField()),
static::LABEL);
if (!$label_field->getCode())
return $this;
$this->_zone = $rules->getZonePadded();
$this->_valid = true;
$this->_rules = $rules;
$this->_list_fields->add($label_field);
$this->_list_fields->add(new Class_NoticeUnimarc_Field(trim($rules->getIdField()),
static::ID));
$this->_list_fields
->add(new Class_NoticeUnimarc_Field($rules->getFilterField(),
static::FILTER));
return $this;
}
protected function _getFieldLabel() {
return $this->_detectByLabel(static::LABEL);
}
protected function _getFieldId() {
return $this->_detectByLabel(static::ID);
}
protected function _getFieldFilter() {
return $this->_detectByLabel(static::FILTER);
}
protected function _detectByLabel($label) {
return $this->_list_fields->detect(function ($field) use ($label) {
return $label === $field->getLabel();
});
}
protected function _canAddResult() {
$field_label = $this->_getFieldLabel();
$label = $this->_truncateLabel($field_label->getValue());
$field_label->setValue($label);
if (!$label)
return false;
$filter_zone = $this->_rules->getZone();
$filter_field = $this->_rules->getFilterField();
$filter_value = $this->_rules->getFilterValue();
if (!$filter_zone || (null === $filter_field) | !$filter_value)
return true;
return $this->_getFieldFilter()->getValue() == $filter_value;
}
protected function _buildOneResult() {
return [static::ID => (($id = $this->_getFieldId()->getValue())
? strtoupper($id)
: ''),
static::LABEL => $this->_getFieldLabel()->getValue()];
}
protected function _truncateLabel($label) {
$valid = is_string($label) && $label > '';
if (!$this->_rules->getLabelLength())
return $valid ? $label : '';
return $valid
? substr($label,
max(0, $this->_rules->getLabelStartPos() - 1),
$this->_rules->getLabelLength())
: '';
}
}
......@@ -50,18 +50,30 @@ abstract class RechercheControllerThumbnailTestCase extends AbstractControllerTe
class RechercheControllerThumbnailCmsTest extends RechercheControllerThumbnailTestCase {
class RechercheControllerThumbnailCmsTest
extends RechercheControllerThumbnailTestCase {
public function setUp() {
parent::setUp();
$article = $this->fixture('Class_Article',
Class_Article::setFileWriter($this->mock()
->whenCalled('fileExists')
->answers(true));
$article = $this->fixture(Class_Article::class,
['id' => 123,
'titre' => 'An article with img',
'contenu' => 'This article should contains an image like this <img src="/images/articles/img.png" />']);
$article->index();
$this->dispatch('recherche/vignette/id_notice/1');
}
$this->dispatch('recherche/vignette/id_notice/1', true);
public function tearDown() {
Class_Article::setFileWriter(null);
parent::tearDown();
}
......@@ -75,7 +87,6 @@ class RechercheControllerThumbnailCmsTest extends RechercheControllerThumbnailTe
class RechercheControllerThumbnailAlbumCmsWithImageTest
extends RechercheControllerThumbnailTestCase {
......
......@@ -215,7 +215,7 @@ class PhaseNoticeLomTest extends PhaseNoticeTestCase {
$this->assertEquals(['Name' => 'Anne Teyssèdre',
'Responsibility' => 'author',
'Affiliation' => 'Museum National d\'Histoire Naturelle'],
$author->toArray());
$author);
}
......
......@@ -886,3 +886,152 @@ class AuthoritiesFacetsWithIndexSystemThesaurusNotExistingTest
$this->assertFalse($this->_thesaurus_loader->methodHasBeenCalled('save'));
}
}
/* hotline: #133782 */
abstract class AuthoritiesThesaurusWithFilterFieldTestCase extends ModelTestCase {
protected $_thesaurus;
public function setUp() {
parent::setUp();
Class_CodifThesaurus::clearCache();
$this->_createThesaurus();
$attributs = [[Class_IntProfilDonnees::PROFILE_INDEX_SYSTEMS_FIELDS
=> [['rule' => '',
'system' => 'TESS',
'default_type' => 'j',
'thesaurus' => '6']]]];
$this->fixture(Class_IntProfilDonnees::class,
['id' => 1004,
'libelle' => 'Authorities',
'type_fichier' => Class_IntProfilDonnees::FT_AUTHORITY,
'format' => Class_IntProfilDonnees::FORMAT_UNIMARC,
'accents' => Class_IntProfilDonnees::ENCODING_UTF8,
'attributs' => serialize($attributs),