source: spip-zone/_plugins_/critere_mots/trunk/critere_mots_fonctions.php @ 115944

Last change on this file since 115944 was 115944, checked in by real3t@…, 14 months ago

[Critère {mots}] Retour sur r114363 suite à remarque de b_b sur la liste (https://www.mail-archive.com/spip-zone@rezo.net/msg47970.html)
Pour chercher dans l'arbo, rajouter à mes_options.php :

if (!defined('_CRITERE_MOTS_ARBO_BRANCHE'))

define('_CRITERE_MOTS_ARBO_BRANCHE', true);


File size: 6.5 KB
Line 
1<?php
2
3if (!defined('_ECRIRE_INC_VERSION')) {
4        return;
5}
6
7define ('_CRITERE_MOTS_OPTIMISE',1);// pour pouvoir revenir aux anciennes requetes si besoin
8
9// Critere {mots} : "l'article est lie a tous les mots demandes"
10// {mots?} ne s'applique que si au moins un mot est demande
11// on passe dans l'url &mots[]=titre1&mots[]=titre2
12// et/ou &mots[]=11 etc
13// parametre optionnel : {mots score} ou score est un nombre entre 0 et 1
14// qui indique le pourcentage de mots a valider
15// ex: {mots? 0.66} selectionne tous les articles qui ont au moins 2/3
16// ou encore {mots score} qui indique le nombre de mots communs (par exemple 2) si score >= 1
17// ex: {mots 2} indique qu'il doit y avoir 2 mots communs
18// ou encore {mots 66%} indique qu'on doit avoir 66% de mot en commun (identique à {mots 0.66}
19// de mots en commun avec ceux demandes par le contexte (ou l'URL)
20// par defaut score=100% (tous les mots demandes doivent figurer)
21function critere_mots_dist($idb, &$boucles, $crit,$id_ou_titre=false) {
22
23        $boucle = &$boucles[$idb];
24        $_table = table_objet($boucle->id_table);
25        $objet_delatable=objet_type($_table);
26        $id_objet = id_table_objet($boucle->id_table);
27        $tri = false;
28
29        // pouvoir utiliser plusieurs fois le critère dans une même boucle.
30        $hash = substr(uniqid(), -4);
31
32        if (isset($crit->param[0][2]) and ($crit->param[0][2]->texte == "tri" or $crit->param[0][2]->texte=="!tri")){
33                        $tri = true;
34        }
35       
36        if (isset($crit->param[0][0])) {
37                $score = calculer_liste(array($crit->param[0][0]), array(), $boucles, $boucles[$idb]->id_parent);
38        } else {
39                $score = "'100%'";
40        }
41
42        if (isset($crit->param[0][1])) {
43                $quoi = calculer_liste(array($crit->param[0][1]), array(), $boucles, $boucles[$idb]->id_parent);
44        } else {
45                $quoi = '@$Pile[0]["mots"]';
46        }
47        $boucle->hash .= '
48        // {MOTS}
49        $prepare_mots = charger_fonction(\'prepare_mots\', \'inc\');
50        $mots_where_' . $hash . ' = $prepare_mots('.$quoi.', "'.$boucle->id_table.'", "'.$crit->cond.'", '.$score.', "' . $boucle->sql_serveur . '","'.$id_ou_titre.'");
51        ';
52
53        $t = $boucle->id_table . '.' . $boucle->primary;
54        if (!in_array($t, $boucles[$idb]->select)) {
55                $boucle->select[]= $t; # pour postgres, neuneu ici
56        }
57
58        $boucle->where[] = "\n\t\t".'$mots_where_' . $hash;
59        if ($tri == true) {
60
61                $boucle->jointures[]="mots_liens" ;
62                $boucle->from['mots_liens'] = "spip_mots_liens";
63                $boucle->join["mots_liens"] = array(
64                    "'$boucle->id_table'",
65                    "'id_objet'",
66                    "'$id_objet'",
67                    "'mots_liens.objet='.sql_quote('$objet_delatable')");
68                $boucle->where[] = "\n\t\t".'sql_in(\'mots_liens.id_mot\',sql_quote('.$quoi.'))';
69                $boucle->group[] = "mots_liens.id_objet";
70                if ($crit->param[0][2]->texte == "tri") // si dans le sens ascendant
71                    $boucle->order[] = "'COUNT(mots_liens.id_objet) ASC'";
72                else
73                    $boucle->order[] = "'COUNT(mots_liens.id_objet) DESC'";
74               
75                // Pseudo critère "Si"
76                $boucle->hash .= "\n\tif (!isset(\$si_init)) { \$command['si'] = array(); \$si_init = true; }\n";
77                $boucle->hash .= "\t\$command['si'][] = (count($quoi) > '0');";
78        }
79
80
81}
82
83
84
85function critere_mots_selon_id_dist($idb, &$boucles, $crit){
86    critere_mots_dist($idb, $boucles, $crit,'id');
87}
88function critere_mots_selon_titre_dist($idb, &$boucles, $crit){
89    critere_mots_dist($idb, $boucles, $crit,'titre');
90}
91
92
93function inc_prepare_mots_dist($mots, $table='articles', $cond=false, $score, $serveur='',$id_ou_titre=false) {
94  $score = trim($score);
95        if (!is_array($mots)
96        OR !$mots = array_filter($mots)) {
97                // traiter le cas {mots?}
98                if ($cond)
99                        return '';
100                else
101                // {mots} mais pas de mot dans l'url
102                        return '0=1';
103        }
104
105  if (!defined('_CRITERE_MOTS_ARBO_BRANCHE'))
106          define('_CRITERE_MOTS_ARBO_BRANCHE', false);
107
108  $_table = table_objet($table);
109  $objet_delatable=objet_type($_table);
110
111        $_id_table = id_table_objet($table);
112        $where = array();
113   
114  //selon le cas, on sélectionne sur les titres ou sur les id
115  if (!$id_ou_titre){
116      foreach($mots as $mot) {
117          if (preg_match(',^[1-9][0-9]*$,', $mot))
118              $id_mot = $mot;
119          else
120              $id_mot = sql_getfetsel('id_mot', 'spip_mots', 'titre='.sql_quote($mot));
121          if (function_exists('calcul_branche_mot_in') AND _CRITERE_MOTS_ARBO_BRANCHE) {
122                          $where[] = sql_in('id_mot',calcul_branche_mot_in($id_mot)).' and objet='.sql_quote($objet_delatable);
123                  } else {
124                        $where[] = 'id_mot='.sql_quote($id_mot).' and objet='.sql_quote($objet_delatable);
125                  }               
126      }
127  }
128        elseif($id_ou_titre == 'id'){
129           foreach($mots as $id_mot) {
130          if (function_exists('calcul_branche_mot_in') AND _CRITERE_MOTS_ARBO_BRANCHE) {
131                        $where[] = sql_in('id_mot',calcul_branche_mot_in($id_mot)).' and objet='.sql_quote($objet_delatable);
132                  } else {
133                        $where[] = 'id_mot='.sql_quote($id_mot).' and objet='.sql_quote($objet_delatable);
134                  }
135           }
136        }
137        elseif($id_ou_titre == 'titre'){
138           foreach($mots as $mot) {
139                $id_mot = sql_getfetsel('id_mot', 'spip_mots', 'titre='.sql_quote($mot));
140                    if (function_exists('calcul_branche_mot_in') AND _CRITERE_MOTS_ARBO_BRANCHE) {
141                          $where[] = sql_in('id_mot',calcul_branche_mot_in($id_mot)).' and objet='.sql_quote($objet_delatable);
142                    } else {
143                          $where[] = 'id_mot='.sql_quote($id_mot).' and objet='.sql_quote($objet_delatable);
144                    }
145           }
146        }
147       
148        // on analyse la jointure spip_mots_$_table
149        // sans regarder spip_mots ni les groupes
150        // (=> faire attention si on utilise les mots techniques)
151   
152        // si on a un % dans le score, c'est que c'est un %age
153        if (substr($score,-1)=='%'){
154       
155           $score = str_replace('%','',$score);
156           $having = ' HAVING SUM(1) >= '.ceil($score/100 * count($where)) ;
157        }
158        elseif ((0 < $score) and ($score < 1)){
159           $having = ' HAVING SUM(1) >= '.ceil($score * count($where)) ;
160        }
161        else{
162           $having = ' HAVING SUM(1) >= '. $score;
163           }
164       
165        $in = array();
166        // Normalement on devrait faire un sous-select, mais mysql 5* a un bug (ttp://bugs.mysql.com/bug.php?id=32665)
167        // du coup on calcule d'abord le résultat de la sous-select, et on intègre cela inc_prepare_mots_dist
168  $s = sql_query("SELECT id_objet as i FROM spip_mots_liens WHERE "
169    . join(' OR ', $where)
170    . ' GROUP BY id_objet,objet'
171    . $having);
172  while($t = sql_fetch($s)){
173                        $in[] = $t['i'];
174        }
175        if ($in){
176          $wh = sql_in("$_table.$_id_table", $in);
177  }
178        else{
179                $wh = '22=0';//1=0 est automatiquement filtré par le compilateur
180        }
181        return $wh;
182}
183
184function critere_mots_enleve_mot_de_liste($listemots, $id_mot) {
185        if (!is_array($listemots) OR !$listemots)
186                return $listemots;
187        $listemots = array_unique($listemots);
188        $listemots = array_diff($listemots,array($id_mot));
189        return $listemots;
190}
Note: See TracBrowser for help on using the repository browser.