diff --git a/VERSIONS_HOTLINE/96508 b/VERSIONS_HOTLINE/96508 new file mode 100644 index 0000000000000000000000000000000000000000..fd5ab085a0e787ac35162b549ac576ca6f1cc7ce --- /dev/null +++ b/VERSIONS_HOTLINE/96508 @@ -0,0 +1 @@ + - ticket #96508 : Facettes dynamiques : Seul le premier des sous champs unimarc répétés dans les notices était pris en compte dans la recherche \ No newline at end of file diff --git a/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php b/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php index 9af40c220138a19314f03e2d9e181c5c82f9a1f8..8c6999588e2106eb43d5ddba63e2cc7669dd788a 100644 --- a/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php +++ b/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php @@ -27,7 +27,9 @@ abstract class KohaRecordIntegrationTestCase extends NoticeIntegrationTestCase { public function getProfilDonnees() { - return Class_IntProfilDonnees::forKoha()->getRawAttributes(); + return Class_IntProfilDonnees::forKoha() + ->setIdProfil(45) + ->getRawAttributes(); } } @@ -73,11 +75,6 @@ class KohaRecordIntegrationRecordWithoutMainTitleTest extends KohaRecordIntegrat class KohaRecordIntegrationBdMilleniumTest extends KohaRecordIntegrationTestCase { - public function getProfilDonnees() { - return Class_IntProfilDonnees::forKoha()->getRawAttributes(); - } - - public function setUp() { parent::setUp(); $this->loadNotice('unimarc_bd_millenium'); @@ -99,6 +96,18 @@ class KohaRecordIntegrationBdMilleniumTest extends KohaRecordIntegrationTestCase public function collectionMilleniumShouldBeIndexed() { $this->assertEquals('MILLENIUM MILENIUM', $this->millenium->getRawAttributes()['collection']); } + + + /** @test */ + public function firstItemIdDataProfileShouldBe45() { + $this->assertEquals(45, Class_Exemplaire::find(1)->getIdDataProfile()); + } + + + /** @test */ + public function itemDataProfileLabelShouldBeUnimarcKoha() { + $this->assertEquals('Unimarc Koha', Class_Exemplaire::find(1)->getDataProfile()->getLibelle()); + } } @@ -569,18 +578,18 @@ class KohaRecordIntegrationDeduplicateTest extends KohaRecordIntegrationTestCase $this->loadRecordsFromFile('unimarc_mementos'); $this->fixture('Class_IntBib', - ['id' => 2, - 'nom' => 'My other library', - 'nom_court' => 'MOL', - 'mail' => '', - 'qualite' => 10, - 'dernier_ajout' => '2015-01-01', - 'ecart_ajouts' => '0', - 'date_mail' => '', - 'sigb' => $this->_sigb, - 'planif_mode' => 'r', - 'comm_sigb' => 0, - 'comm_params' => 'N']); + ['id' => 2, + 'nom' => 'My other library', + 'nom_court' => 'MOL', + 'mail' => '', + 'qualite' => 10, + 'dernier_ajout' => '2015-01-01', + 'ecart_ajouts' => '0', + 'date_mail' => '', + 'sigb' => $this->_sigb, + 'planif_mode' => 'r', + 'comm_sigb' => 0, + 'comm_params' => 'N']); $this->loadRecordsFromFile('unimarc_mementos', 2); $this->loadRecordsFromFile('unimarc_mementos'); @@ -610,4 +619,77 @@ class KohaRecordIntegrationDeduplicateTest extends KohaRecordIntegrationTestCase $this->assertEquals(2, Class_Exemplaire::countBy(['id_int_bib' => 2, 'id_origine' => 397126])); } -} \ No newline at end of file +} + +/** @see http://forge.afi-sa.fr/issues/96508 */ +class KohaRecordIntegrationMultipleSECTIntegrationTest extends KohaRecordIntegrationTestCase { + protected $_storm_default_to_volatile = true; + + + public function setUp() { + parent::setUp(); + + + + $this->fixture('Class_CodifThesaurus', + ['id' => 74, + 'libelle' => 'Secteur', + 'libelle_facette' => '', + 'id_thesaurus' => 'SECT', + 'id_origine' => null, + 'code' => 'SECT', + 'rule_zone' => '099', + 'rule_label_field' => 'y', + 'rule_id_field' => '', + 'rule_filter_field' => '', + 'rule_filter_value' => '' + ]); + + + + $this->fixture('Class_CodifThesaurus', + ['id' => 76, + 'libelle' => 'SANTESOCIAL', + 'libelle_facette' => 'SANTESOCIAL', + 'id_thesaurus' => 'SECT0001', + 'id_origine' => 'SANTESOCIAL', + 'code' => 'SECT', + ]); + + $this->fixture('Class_CodifThesaurus', + ['id' => 77, + 'libelle' => 'ADMINISTRATION', + 'libelle_facette' => '', + 'id_thesaurus' => 'SECT0002', + 'id_origine' => 'ADMINISTRATION', + 'code' => 'SECT'] + ); + + $this->fixture('Class_CodifThesaurus', + ['id' => 78, + 'libelle' => 'TRAVAILEMPLOI', + 'libelle_facette' => 'TRAVAILEMPLOI', + 'id_thesaurus' => 'SECT0003', + 'id_origine' => 'TRAVAILEMPLOI', + 'code' => 'SECT', + ]); + + + $writer = new Class_NoticeUnimarc_Writer(); + $writer->setNotice(file_get_contents(dirname(__FILE__)."/unimarc_minsoc_ia.txt")); + + $writer->add_field('995', ' ', [ + ['f', '12345'], + ['v', '1']]); + + $writer->update(); + $this->loadNoticeFromString($writer->getFullRecord()); + + } + + /** @test */ + public function RecordFacetsShouldContainsHSECT0001AndHSECT0002AndHSECT0003() { + $this->assertContains('HSECT0002 HSECT0001 HSECT0003', Class_Notice::find(1)->getFacettes()); + } + +} diff --git a/cosmogramme/tests/php/classes/unimarc_minsoc_ia.txt b/cosmogramme/tests/php/classes/unimarc_minsoc_ia.txt new file mode 100644 index 0000000000000000000000000000000000000000..ad68dbe65ebc5d246ceaf1795676174237c45381 --- /dev/null +++ b/cosmogramme/tests/php/classes/unimarc_minsoc_ia.txt @@ -0,0 +1 @@ +03378cam a2200397 4500001000700000010002300007090001100030099011600041100004100157101000800198102000700206200040200213210002800615215004200643225005600685300003800741330083500779410005901614609003801673609003201711609002301743712003701766801004801803856020601851856022902057003004702286020001702333105001802350106000602368606012502374606013602499676001902635686006602654930011702720930014302837440414 a9782111526341bbr. a440414 tOUVRAGEyADMINISTRATIONySANTESOCIALyTRAVAILEMPLOIaBeÌatrice LEROYbBeÌatrice LEROYc2019-08-13d2019-08-13 a20190228d2019 m h0frey50 ba0 afre aFR1 aIntelligence artificiellebOUVRAGEbDocument eÌlectroniquebRapporteeÌtat de l'art et perspectives pour la Franceerapport finalfPIPAME, PoÌ‚le interministeÌriel de prospective et d'anticipation des mutations eÌconomiques ; DGE, Direction geÌneÌrale des entreprises ; CGET, Commissariat geÌneÌral aÌ€ l'eÌgaliteÌ des territoires... [et al.]g[rapport reÌaliseÌ par ATAWAO Consulting] e53-MayennegImpr. Jouve a1 vol. (311 p.)cill. en coul.d30 cm aProspectiveeeÌtudes eÌconomiquesfDGEx2491-0058 aBibliogr. et webliogr. p. 306-309 aApreÌ€s un eÌtat de l’art des diffeÌrentes technologies du domaine, l’eÌtude propose une meÌthode de classification des secteurs potentiellement les plus transformeÌs par l’essor de l’intelligence artificielle et eÌtablit une analyse macroscopique de son adoption par ceux-ci. Elle approfondit ensuite cette analyse pour quatre secteurs : EÌnergie et environnement, Transport et logistique, SanteÌ et Industrie. Pour chacun de ces quatre secteurs, un bilan des opportuniteÌs geÌneÌreÌes par l’IA est eÌtabli et une strateÌgie cible aÌ€ adopter est proposeÌe. Dans sa dernieÌ€re partie, l’eÌtude dessine une feuille de route ainsi que des recommandations sectorielles et transverses qui permettront aÌ€ la France et aÌ€ ses entreprises de relever les deÌfis en matieÌ€re d’intelligence artificielle. 044481451tEtudes eÌconomiquesx2491-0058d2019947552 9209229aIntelligence artificielle 939035aSecteur eÌconomique 937657aProspective 317815993aAtawao consulting4710 0aFRbFR-751131015c20190228gAFNOR2intermrc 2Rapportuhttps://www.entreprises.gouv.fr/files/files/directions_services/etudes-et-statistiques/prospective/Intelligence_artificielle/2019-02-intelligence-artificielle-etat-de-l-art-et-perspectives.pdf 2SyntheÌ€se du rapportuhttps://www.entreprises.gouv.fr/files/files/directions_services/etudes-et-statistiques/prospective/Intelligence_artificielle/2019-02-intelligence-artificielle-etat-de-l-art-et-perspectives-synthese.pdfhttp://catalogue.bnf.fr/ark:/12148/cb45679700r aFRb01927606 a||||z 00|y| ar 311932084aIntelligence artificielle311975935xApplications industrielles311931476yFrance312432924z1990-....2rameau 311932084aIntelligence artificielle311939593xInnovations technologiques311931476yFrance311950184xEÌtudes de marcheÌ2rameau a006.309 44v23 2Cadre de classement de la Bibliographie nationale française 5FR-751131009:45679700001001a2019-44342b759999999cTolbiac - Rez de Jardin - Sciences et technique - MagasindO 5FR-751131008:45679700002001a084.05 DGE ib759999999cTolbiac - Haut de Jardin - Droit, eÌconomie, politique - Salle D - Libre acceÌ€sdN \ No newline at end of file diff --git a/library/Class/CodifThesaurus/Rules.php b/library/Class/CodifThesaurus/Rules.php index f9b054539d6759c8e292636dda420a663ce13d21..98ae173f5694a3b40e36cfacc80c5541229d05b9 100644 --- a/library/Class/CodifThesaurus/Rules.php +++ b/library/Class/CodifThesaurus/Rules.php @@ -87,7 +87,6 @@ class Class_CodifThesaurus_Rules extends Class_Entity { } - /** * @param $reader cosmogramme notice_unimarc */ @@ -118,27 +117,46 @@ class Class_CodifThesaurus_Rules extends Class_Entity { * @param $reader cosmogramme notice_unimarc */ public function extractIdAndFields($reader) { + $label_field = trim($this->getLabelField()); $id_field = trim($this->getIdField()); - $id_labels = array_map(function($fields) use ($label_field, $id_field) - { - if (!isset($fields[$label_field])) - return null; - - $label = $this->truncateLabel($fields[$label_field]); - if (!$this->isValidLabel($label)) - return null; - - $id = (isset($fields[$id_field]) ? $fields[$id_field] : null); - return ['id' => strtoupper($this->isValidLabel($id) ? $id : $label), - 'label' => $label]; - }, - $this->_getZonesToParse($reader)); - return array_filter($id_labels); - } + if (!$label_field) + return []; + + $filter_field = $this->getFilterField(); + + $filter_subfield_in = function($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); + + }; + + $fields = $reader->cutBlockBySubfields($this->getZonePadded(), + [$label_field =>'label', + $id_field =>'id', + $filter_field => 'filter'], $filter_subfield_in); + + return array_filter(array_map([$this,'buildAuthorityStructure'],$fields)); + } + + public function buildAuthorityStructure($block){ + $label = $this->truncateLabel($block->get('label')); + return ['id' => $block->get('id') + ? strtoupper($block->get('id')) + : strtoupper($label), + 'label' => $label]; + } public function truncateLabels($labels) { return array_filter( diff --git a/library/Class/NoticeUnimarc.php b/library/Class/NoticeUnimarc.php index a1e25d6a7da4a5bd2e2df48f7335c1f1f047ec12..6fdbb3b724ebb39f1b271bec1c702b4ccdb5c2af 100644 --- a/library/Class/NoticeUnimarc.php +++ b/library/Class/NoticeUnimarc.php @@ -40,6 +40,7 @@ class Class_NoticeUnimarc { protected $rgx_field_end; protected $subfield_begin; protected $rgx_subfield_begin; + protected $blocks = []; public function __construct() { $this->tracer_accents = isset(self::$_tracer_accents_iso) @@ -177,6 +178,70 @@ class Class_NoticeUnimarc { } + /** + @data $subfields_mapping = [ 'y' => 'label', '4'=> 'id' ] + + @return [ Class_Entity ('id' => 'valeur', + 'label' => 'label' + ),... + ] + */ + public function cutBlockBySubfields($zone, $subfields_mapping, $closure_valid) { + + $this->blocks=[]; + + foreach ($this->get_subfield($zone) as $line) { + $this->_cutLineBySubfields($line, $subfields_mapping,$closure_valid); + } + return $this->blocks; + } + + + 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 (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 decoupe_bloc_champ($bloc,$num=false) { $sc = []; $bloc = substr($bloc, 3); @@ -185,44 +250,10 @@ class Class_NoticeUnimarc { $sc[] = $num == true ? [substr($field, 0, 1), trim(substr($field, 1))] : ['code' => substr($field, 0, 1), 'valeur' => trim(substr($field, 1))]; - return (0 == count($sc)) ? null : $sc; } - - /** - * ex: $unimarc->parseZone(686) - * - * answers: - * [ - * [ 'a' => 'A12+' - * 't' => 'A12+' - * '2' => 'Ludo - Age'], - * - * [ 'a' => '3-5J' - * 't' => '3-5 JOUEURS' - * '2' => 'Ludo - Nb joueurs'] - * ] - */ - public function parseZone($zone) { - return array_map(function($bloc) - { - return $this->parseZoneFields($bloc); - }, - $this->get_subfield($this->getZonePadded())); - } - - - /** @see parseZone */ - public function parseZoneFields($marc) { - $fields = []; - foreach(explode($this->subfield_begin, substr($marc,3)) as $field) - $fields[substr($field, 0, 1)] = trim(substr($field, 1)); - return $fields; - } - - public function reset_notice() { $this->full_record = ''; $this->guide = '';