Skip to content
Snippets Groups Projects
Commit db74d95d authored by Patrick Barroca's avatar Patrick Barroca :grin:
Browse files

Merge branch 'dev_#13854_phonetix_collision' into 'master'

Dev #13854 phonetix collision

See merge request !482
parents ba6cf074 997ecc30
Branches
Tags
4 merge requests!529Hotline 6.56,!512Master,!500Hotline 6.55,!484Master
- ticket #13854 : désactivation de la recherche phonétique lorsque 2 termes saisis en recherche simples ont la même représentation phonétique
\ No newline at end of file
......@@ -78,44 +78,33 @@ class Class_MoteurRecherche {
}
public function visitExpression($expression,$pertinence,$tri) {
public function visitExpression($expression, $pertinence, $tri) {
// Analyse de l'expression
$expression = trim($expression);
if ($expression == '*')
return;
// Recherche par isbn (1 seul mot et isbn ou ean valide)
$recherche = '';
$against_titre = '';
if (!$mode_isbn = $this->createReqForIsbn($expression)) {
$mots = $this->ix->getMots($expression);
foreach ($mots as $mot) {
$against_titre .= ' ' . $mot;
if (!$mot = $this->ix->getExpressionRecherche($mot))
continue;
$this->nb_mots++;
if ($recherche !='')
$recherche .= ' ';
$recherche .= ($pertinence ? ' ' : '+') . $mot;
}
$recherche = trim($recherche);
if (!$recherche) {
$this->setErreur(("Il n'y aucun mot assez significatif pour la recherche"));
return ;
}
if ($this->createReqForIsbn($expression))
return;
$against = " AGAINST('".$recherche."'" . ($pertinence ? '' : ' IN BOOLEAN MODE') . ')';
$terms = (new Class_MoteurRecherche_Terms($this->ix))
->analyse($expression);
$this->setCondition('MATCH(titres, auteurs, editeur, collection, matieres, dewey)' . $against);
$this->nb_mots = $terms->termsCount();
if (!$against = $terms->asWhereAgainst($pertinence)) {
$this->setErreur("Il n'y aucun mot assez significatif pour la recherche");
return;
}
if (!($tri and $tri != '*' and !$pertinence or $mode_isbn)) {
$this->setCondition('MATCH(titres, auteurs, editeur, collection, matieres, dewey)'
. $against);
if (!($tri and $tri != '*' and !$pertinence)) {
$against_titre = $terms->asSelectAgainst();
$this->select_notices = 'id_notice, '
. "MATCH(alpha_titre) AGAINST('" . $against_titre . "') as rel1, "
. "MATCH(alpha_auteur) AGAINST('" . $against_titre . "') as rel2 "
. 'MATCH(alpha_titre) ' . $against_titre . ' as rel1, '
. 'MATCH(alpha_auteur) ' . $against_titre . ' as rel2 '
. 'from notices ';
$this->order_by = ' order by (rel1 * 1.5) + (rel2) desc';
}
......
<?php
/**
* Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
*
* AFI-OPAC 2.0 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).
*
* AFI-OPAC 2.0 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 AFI-OPAC 2.0; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Class_MoteurRecherche_Terms {
protected $_expression, $_indexation;
protected $_raws = [];
protected $_terms = [];
public function __construct($indexation) {
$this->_indexation = $indexation;
}
public function analyse($expression) {
$ix = $this->getIndexation();
$this->_expression = $expression;
foreach ($ix->getMots($this->_expression) as $token) {
$this->_raws[] = $token;
$term = new Class_MoteurRecherche_Term($ix, $token);
if ($term->isValid())
$this->_terms[] = $term;
}
(new Class_MoteurRecherche_PhonetixCollector())->clean($this->_terms);
return $this;
}
public function termsCount() {
return count($this->_terms);
}
public function asWhereAgainst($is_extended) {
if (empty($this->_terms))
return '';
$against = array_map(
function($term) use ($is_extended) {
return $term->asAgainstClause($is_extended);
},
$this->_terms);
return " AGAINST('". implode(' ', $against) ."'"
. ($is_extended ? '' : ' IN BOOLEAN MODE') . ')';
}
public function asSelectAgainst() {
return 'AGAINST(\' ' . implode(' ', $this->_raws) . '\')';
}
protected function getIndexation() {
return (null !== $this->_indexation) ?
$this->_indexation : new Class_Indexation();
}
}
class Class_MoteurRecherche_Term {
protected $_raw, $_singular, $_plural, $_phonetix;
public function __construct($indexation, $term) {
$this->_raw = $term;
$star = '*' == substr($term, -1);
$term = $star ? substr($term, 0, strlen($term) - 1) : $term;
if (false === $plural = $indexation->getPluriel($term))
return;
$this->_singular = $plural[0] . ($star ? '*': '');
$this->_plural = $plural[1];
$this->_phonetix = $indexation->phonetix($plural[0]);
}
public function collectPhonetix($collector) {
if ($this->_phonetix)
$collector->add($this->_phonetix);
}
public function disablePhonetix($value) {
if ($this->_phonetix == $value)
$this->_phonetix = false;
return $this;
}
public function asAgainstClause($is_extended) {
return ($is_extended ? ' ' : '+')
. '(' . $this->_singular . ' ' . $this->_plural
. ($this->_phonetix ? ' ' . $this->_phonetix : '') .')';
}
public function isValid() {
return null !== $this->_singular;
}
}
class Class_MoteurRecherche_PhonetixCollector {
protected $_values = [];
public function clean($terms) {
array_walk($terms, function($term) { $term->collectPhonetix($this); });
foreach ($this->_values as $value => $count)
if (1 < $count)
array_walk(
$terms,
function($term) use ($value) {
$term->disablePhonetix($value);
});
}
protected function withTermsDo($terms, $closure) {
array_walk($terms, $closure);
return $this;
}
public function add($value) {
array_key_exists($value, $this->_values) ?
$this->_values[$value]++ :
$this->_values[$value] = 1;
}
}
?>
\ No newline at end of file
......@@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
abstract class MoteurRechercheAbstractTest extends Storm_Test_ModelTestCase {
abstract class MoteurRechercheTestCase extends Storm_Test_ModelTestCase {
protected
$mock_sql,
$_original_sql,
......@@ -30,7 +30,7 @@ abstract class MoteurRechercheAbstractTest extends Storm_Test_ModelTestCase {
parent::setUp();
$this->_original_sql = Zend_Registry::get('sql');
$this->mock_sql = Storm_Test_ObjectWrapper::mock();
$this->mock_sql = $this->mock();
Zend_Registry::set('sql', $this->mock_sql);
......@@ -96,7 +96,7 @@ abstract class MoteurRechercheAbstractTest extends Storm_Test_ModelTestCase {
class MoteurRechercheAvanceeTest extends MoteurRechercheAbstractTest {
class MoteurRechercheAvanceeTest extends MoteurRechercheTestCase {
public function expectedSql() {
$list_sql = 'Select id_notice from notices Where %s order by %s';
$count_sql = 'Select count(*) from notices Where %s';
......@@ -231,7 +231,7 @@ class MoteurRechercheAvanceeTest extends MoteurRechercheAbstractTest {
class MoteurRechercheSimpleTest extends MoteurRechercheAbstractTest {
class MoteurRechercheSimpleTest extends MoteurRechercheTestCase {
public function expectedSql() {
$match_axes = 'MATCH(titres, auteurs, editeur, collection, matieres, dewey)';
$count_sql = 'Select count(*) from notices Where ' . $match_axes . ' AGAINST(%s IN BOOLEAN MODE)';
......@@ -320,7 +320,7 @@ class MoteurRechercheSimpleTest extends MoteurRechercheAbstractTest {
class MoteurRechercheSerieTest extends MoteurRechercheAbstractTest {
class MoteurRechercheSerieTest extends MoteurRechercheTestCase {
public function expectedSql() {
return [
[['expressionRecherche' => 'Geo',
......@@ -351,7 +351,7 @@ class MoteurRechercheSerieTest extends MoteurRechercheAbstractTest {
class MoteurRechercheRebondTest extends MoteurRechercheAbstractTest {
class MoteurRechercheRebondTest extends MoteurRechercheTestCase {
public function expectedSql() {
return [
[['expressionRecherche' => 'pomme',
......@@ -464,7 +464,7 @@ class MoteurRechercheRebondTest extends MoteurRechercheAbstractTest {
class MoteurRechercheGuideeWithOneSubCategorieTest extends MoteurRechercheAbstractTest {
class MoteurRechercheGuideeWithOneSubCategorieTest extends MoteurRechercheTestCase {
public function expectedSql() {
return [
[['rubrique' =>'D6',
......@@ -564,7 +564,7 @@ class MoteurRechercheGuideeWithOneSubCategorieTest extends MoteurRechercheAbstra
class MoteurRechercheGuideeWithTwoSubCategorieTest extends MoteurRechercheAbstractTest {
class MoteurRechercheGuideeWithTwoSubCategorieTest extends MoteurRechercheTestCase {
public function expectedSql() {
return [
[['facettes' => 'M123-A989',
......@@ -642,7 +642,7 @@ class MoteurRechercheGuideeWithTwoSubCategorieTest extends MoteurRechercheAbstra
class MoteurRechercheCatalogueTest extends MoteurRechercheAbstractTest {
class MoteurRechercheCatalogueTest extends MoteurRechercheTestCase {
public function setUp() {
parent::setUp();
$this->createCatalogueWithNouveauteAndTypeDoc();
......@@ -742,4 +742,17 @@ class MoteurRechercheCatalogueTest extends MoteurRechercheAbstractTest {
}
}
?>
\ No newline at end of file
class MoteurRecherchePhonetixCollisionTest extends MoteurRechercheTestCase {
/** @test */
public function shouldNotUsePhonetix() {
$this->mock_sql
->whenCalled('fetchOne')
->with("Select count(*) from notices Where MATCH(titres, auteurs, editeur, collection, matieres, dewey) AGAINST('+(JEAN JEANS) +(GENET GENETS) +(PARCOUR PARCOURS PARKOUR)' IN BOOLEAN MODE)")
->answers(5000)
->beStrict();
$this->criteres_recherche->setParams(['expressionRecherche' => 'jean genet parcours']);
$retour = $this->moteur_recherche->lancerRecherche($this->criteres_recherche);
}
}
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment