File Coverage

blib/lib/Search/Circa/Search.pm
Criterion Covered Total %
statement 15 152 9.8
branch 0 52 0.0
condition 0 18 0.0
subroutine 5 13 38.4
pod 8 8 100.0
total 28 243 11.5


line stmt bran cond sub pod time code
1             package Search::Circa::Search;
2              
3             # module Search::Circa::Search : provide function to perform search on Circa
4             # Copyright 2000 A.Barbet alian@alianwebserver.com. All rights reserved.
5              
6             # $Log: Search.pm,v $
7             # Revision 1.21 2002/12/29 03:18:37 alian
8             # Update POD documentation
9             #
10             # Revision 1.20 2002/12/28 12:37:47 alian
11             # - Ajout phase privilegiant le et (+nb mots*100 au score si tous les mots trouves dans le doc)
12             # - Affichage que de 20 liens suivants / precedant
13             #
14             # Revision 1.19 2002/12/27 12:54:48 alian
15             # Use template from conf
16             #
17             # Revision 1.18 2002/08/17 18:19:02 alian
18             # - Minor changes to all code suite to tests
19             #
20             # Revision 1.17 2001/11/19 11:38:23 alian
21             # - Correction d'un bug sur l'analyse des mots and (cas ou + sur le premier
22             # mot) ainsi +mot1 +mot2 = +mot2 +mot1
23             #
24             # Revision 1.16 2001/10/14 17:17:32 alian
25             # - Suppression d'une trace oubliee sur les mots avec and
26              
27 1     1   23605 use DBI;
  1         29728  
  1         81  
28 1     1   912 use Search::Circa;
  1         4  
  1         43  
29 1     1   6 use DBI::DBD;
  1         1  
  1         55  
30 1     1   5 use strict;
  1         1  
  1         29  
31 1     1   5 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  1         1  
  1         4168  
32              
33             require Exporter;
34              
35             @ISA = qw(Exporter Search::Circa);
36             @EXPORT = qw();
37             $VERSION = ('$Revision: 1.21 $ ' =~ /(\d+\.\d+)/)[0];
38              
39             #------------------------------------------------------------------------------
40             # new
41             #------------------------------------------------------------------------------
42             sub new
43             {
44 0     0 1   my $class = shift;
45 0           my $self = $class->SUPER::new;
46 0           bless $self, $class;
47 0   0       $self->{SCRIPT_NAME} = $ENV{'SCRIPT_NAME'} || 'search.cgi';
48 0           $self->{SIZE_MAX} = 1000000; # Size max of file read
49 0           $self->{nbResultPerPage}=10;
50 0           return $self;
51             }
52              
53             #------------------------------------------------------------------------------
54             # search
55             #------------------------------------------------------------------------------
56             sub search
57             {
58 0     0 1   my ($this,$template,$mots,$first,$idc,$langue,$Url,
59             $create,$update,$categorie,$cgi)=@_;
60 0           $this->trace(5);
61 0           $this->dbh->do("insert into ".$this->pre_tbl.$idc."stats ".
62             "(requete,quand) values('$mots',now())");
63 0 0         if (!$template) {$template=$CircaConf::templateS;}
  0            
64 0           my ($indice,$i,$tab,$nbPage,$links,$resultat,@ind_and,@ind_not,@mots_tmp)
65             = (0,0);
66 0           my %rrr; $tab=\%rrr;
  0            
67 0           $mots=~s/\'/ /g;
68 0           $mots=~s/(\w)-(\w)/$1 + $2/;
69 0           my @mots = split(/\s/,$mots);
70 0 0         if (@mots==0) {$mots[0]=$mots;}
  0            
71 0           foreach (@mots)
72             {
73 0 0         if ($_ eq '+') {push(@ind_and,$i);} # Reperage mots 'and'
  0 0          
  0            
74 0           elsif ($_ eq '-') {push(@ind_not,$i);} # Reperage mots 'not'
75 0           else {push(@mots_tmp,$_); $i++;}
76             }
77             # Recherche SQL
78 0   0       $tab=$this->search_word($tab,join("','",@mots_tmp),$idc,
79             $langue,$Url,$create,$update,$categorie) ||
80             return undef;
81              
82             # On ajoute 100 au urls qui contiennent tous les mots demandes si nb mots > 1
83 0 0         if ($#mots>0) {
84 0           foreach my $url (keys %$tab) {
85 0 0         $$tab{$url}[2]+=(100*($#mots+1)) if ($#mots+1 == scalar @{$$tab{$url}[5]});
  0            
86             }
87             }
88              
89             # On supprime tout ceux qui ne repondent pas aux criteres and si present
90 0           foreach my $ind (@ind_and) {
91 0           foreach my $url (keys %$tab) {
92 0           delete $$tab{$url} if
93 0 0         (!$this->appartient($mots_tmp[$ind],@{$$tab{$url}[5]}));} }
94              
95             # On supprime tout ceux qui ne repondent pas aux criteres not si present
96 0           foreach my $ind (@ind_not) {
97 0           foreach my $url (keys %$tab) {
98 0           delete $$tab{$url} if
99 0 0         ($this->appartient($mots_tmp[$ind],@{$$tab{$url}[5]}));}}
100              
101             # Tri par facteur
102 0           my @key = reverse sort { $$tab{$a}[2] <=> $$tab{$b}[2] } keys %$tab;
  0            
103              
104             # Selection des url correspondant à la page demandée
105 0           my $nbResultPerPage;
106 0 0 0       if ($cgi) {$nbResultPerPage= $cgi->param('nbResultPerPage')
  0            
  0            
107             || $this->{nbResultPerPage};}
108             else {$nbResultPerPage= $this->{nbResultPerPage};}
109 0           my $lasto = $first + $nbResultPerPage;
110 0           foreach my $url (@key) {
111 0           my ($titre,$description,$facteur,$langue,$last_update)=@{$$tab{$url}};
  0            
112 0           my $indiceG=$indice+1;
113 0 0 0       if (($indice>=$first)&&($indice<$lasto)) {
114 0 0         if ($template) {$resultat.= eval $template;}
  0            
  0            
115             else {$resultat.=$url."\t".$titre."\n";}
116             }
117             # Constitution des liens suivants / precedents
118 0 0         if (!($indice%$nbResultPerPage)) {
119 0           $nbPage++;
120 0 0 0       if ($indice < ($first+($nbResultPerPage*10))
121             and $indice > ($first-($nbResultPerPage*10))) {
122 0 0         if ($indice==$first) {$links.="$nbPage- ";}
  0 0          
  0            
123             elsif ($ENV{"SCRIPT_NAME"})
124             {$links.=' 125             $this->get_link($indice,$cgi).'">'.$nbPage.'- '."\n";}
126             }
127             }
128 0           $indice++;
129             }
130 0 0         if (@key==0) {$resultat="

Aucun document trouvé.

";}
  0            
131 0           return ($resultat,$links,$indice);
132             }
133              
134             #------------------------------------------------------------------------------
135             # search_word
136             #------------------------------------------------------------------------------
137             sub search_word {
138 0     0 1   my ($self,$tab,$word,$idc,$langue,$Url,$create,$update,$categorie)=@_;
139 0           $self->trace(5);
140             # Restriction diverses
141             # Lang
142 0 0         if ($langue) {$langue=" and langue='$langue' ";} else {$langue= ' ';}
  0            
  0            
143             # url
144 0 0 0       if (($Url)&&($Url ne 'http://')) {$Url=" and url like '$Url%' ";}
  0            
  0            
145             else {$Url=' ';}
146             # date created
147 0 0         if ($create)
  0            
148 0           {$create="and unix_timestamp('$create')< unix_timestamp(last_check) ";}
149             else {$create=' ';}
150             # date last update
151 0 0         if ($update)
  0            
152 0           {$update="and unix_timestamp('$update')< unix_timestamp(last_update) ";}
153             else {$update=' ';}
154             # Categorie
155 0 0         if ($categorie)
156 0           {
157 0           my @l=$self->categorie->get_liste_categorie_fils($categorie,$idc);
158 0 0         if (@l) {$categorie="and l.categorie in (".join(',',@l).')';}
  0            
  0            
159             else {$categorie="and l.categorie=$categorie";}
160             }
161             else {$categorie=' ';}
162              
163 0           my $requete = "
164             select facteur,url,titre,description,langue,last_update,mot
165             from ".$self->pre_tbl.$idc."links l,".
166             $self->pre_tbl.$idc."relation r
167             where r.id_site=l.id
168             and l.valide=1
169             and r.mot in ('$word')
170             $langue $Url $create $update $categorie
171             order by facteur desc";
172 0           $self->trace(3,"Search::Circa::Search::search_word $requete");
173 0           my $sth = $self->dbh->prepare($requete);
174             #print "requete:$requete\n";
175 0 0         if ($sth->execute()) {
176 0           my $nb=0;
177 0           while (my ($facteur,$url,$titre,$description,$langue,$last_update,$mot)
178             =$sth->fetchrow_array) {
179 0           $$tab{$url}[0]=$titre;
180 0           $$tab{$url}[1]=$description;
181 0           $$tab{$url}[2]+=$facteur;
182 0           $$tab{$url}[3]=$langue;
183 0           $$tab{$url}[4]=$last_update;
184 0           push(@{$$tab{$url}[5]},$mot);
  0            
185 0           $nb++;
186             }
187 0           $self->trace(3,"Search::Circa::Search::search_word $nb results");
188 0           return $tab;
189             } else {
190 0           $self->trace(1,
191             "Circa::Search->search word Erreur $requete:$DBI::errstr\n");
192 0           return undef;
193             }
194             }
195              
196             #------------------------------------------------------------------------------
197             # get_link
198             #------------------------------------------------------------------------------
199             sub get_link
200             {
201 0     0 1   my ($self,$first,$cgi) = @_;
202 0           my $buf = $self->{SCRIPT_NAME}."?word=".$cgi->escape($cgi->param('word')).
203             "&id=".$cgi->param('id')."&first=".$first;
204 0 0         if ($cgi->param('nbResultPerPage'))
  0            
205             {$buf.="&nbResultPerPage=".$cgi->param('nbResultPerPage');}
206 0           return $buf;
207             }
208              
209             #------------------------------------------------------------------------------
210             # advanced_form
211             #------------------------------------------------------------------------------
212             sub advanced_form
213             {
214 0     0 1   my $self=shift;
215 0   0       my ($id)=$_[0] || 1;
216 0           my $cgi = $_[1];
217 0           my @l;
218 0           my $sth = $self->{DBH}->prepare("select distinct langue from ".$self->{PREFIX_TABLE}.$id."links");
219 0 0         $sth->execute() || print "Erreur: $DBI::errstr\n";
220 0           while (my ($l)=$sth->fetchrow_array) {push(@l,$l);}
  0            
221 0           $sth->finish;
222 0           my %langue=(
223             'da'=>'Dansk',
224             'de'=>'Deutsch',
225             'en'=>'English',
226             'eo'=>'Esperanto',
227             'es'=>'Espanõl',
228             'fi'=>'Suomi',
229             'fr'=>'Francais',
230             'hr'=>'Hrvatski',
231             'hu'=>'Magyar',
232             'it'=>'Italiano',
233             'nl'=>'Nederlands',
234             'no'=>'Norsk',
235             'pl'=>'Polski',
236             'pt'=>'Portuguese',
237             'ro'=>'Românã',
238             'sv'=>'Svenska',
239             'tr'=>'TurkCe',
240             '0'=>'All'
241             );
242 0           my $scrollLangue =
243             "Langue :".
244             $cgi->scrolling_list( -'name'=>'langue',
245             -'values'=>\@l,
246             -'size'=>1,
247             -'default'=>'All',
248             -'labels'=>\%langue);
249 0           my @lno = (5,10,20,50);
250 0           my $scrollNbPage = "Nombre de resultats par page:".
251             $cgi->scrolling_list( -'name'=>'nbResultPerPage',
252             -'values'=>\@lno,
253             -'size'=>1,
254             -'default'=>'5');
255 0           my $buf=$cgi->start_form.
256             ''.
257             Tr(td({'colspan'=>2}, [h1("Recherche")])).
258             Tr(td( textfield(-name=>'word')."
\n".
259             hidden(-name=>'id',-value=>1)."\n".
260             $scrollNbPage."
\n".
261             $scrollLangue."
\n".
262             "Sur le site: ".textfield({-name=>'url',
263             -size=>12,
264             -default=>'http://'})."
\n".
265             "Modifié depuis le: ".
266             textfield({-name=>'update',
267             -size=>10,
268             -default=>''})."(YYYY:MM:DD)
\n".
269             "Ajouté depuis le: ".textfield({-name=>'create',
270             -size=>10,
271             -default=>''})."(YYYY:MM:DD)
\n"
272             ),
273             td($cgi->submit))."\n".
274             '
'.
275             $cgi->end_form."
";
276 0           my ($cate,$titre)=$self->categories_in_categorie(undef,$id);
277 0           $buf.= h1("Navigation par catégorie (repertoire)").
278             h2("Catégories").$cate.
279             h2("Pages").$self->sites_in_categorie(undef,$id);
280 0           return $buf;
281             }
282              
283              
284             #------------------------------------------------------------------------------
285             # default_form
286             #------------------------------------------------------------------------------
287             sub default_form
288             {
289 0     0 1   my ($self,$cgi)=@_;
290 0           my $buf=$cgi->start_form.
291             ''.
292             Tr(td({'colspan'=>2}, [h1("Recherche")])).
293             Tr(td( textfield(-name=>'word')."
\n".
294             hidden(-name=>'id',-value=>1)."\n"),
295             td($cgi->submit))."\n".
296             '
'.
297             $cgi->end_form;
298 0           return $buf;
299             }
300              
301             #------------------------------------------------------------------------------
302             # get_liste_langue
303             #------------------------------------------------------------------------------
304             sub get_liste_langue
305             {
306 0     0 1   my ($self,$cgi)=@_;
307 0           my %langue=(
308             'da'=>'Dansk',
309             'de'=>'Deutsch',
310             'en'=>'English',
311             'eo'=>'Esperanto',
312             'es'=>'Espanõl',
313             'fi'=>'Suomi',
314             'fr'=>'Francais',
315             'hr'=>'Hrvatski',
316             'hu'=>'Magyar',
317             'it'=>'Italiano',
318             'nl'=>'Nederlands',
319             'no'=>'Norsk',
320             'pl'=>'Polski',
321             'pt'=>'Portuguese',
322             'ro'=>'Românã',
323             'sv'=>'Svenska',
324             'tr'=>'TurkCe',
325             '0'=>'All'
326             );
327 0           my @l =keys %langue;
328 0           return $cgi->scrolling_list( -'name'=>'langue',
329             -'values'=>\@l,
330             -'size'=>1,
331             -'default'=>$cgi->param('langue'),
332             -'labels'=>\%langue);
333             }
334              
335              
336             #------------------------------------------------------------------------------
337             # get_name_site
338             #------------------------------------------------------------------------------
339             sub get_name_site
340             {
341 0     0 1   my($this,$id)=@_;
342 0           my $sth = $this->{DBH}->prepare("select titre from ".$this->{PREFIX_TABLE}."responsable where id=$id");
343 0 0         $sth->execute() || print "Erreur: $DBI::errstr\n";
344 0           my ($titre)=$sth->fetchrow_array;
345 0           $sth->finish;
346 0           return $titre;
347             }
348              
349              
350              
351             #------------------------------------------------------------------------------
352             # POD DOCUMENTATION
353             #------------------------------------------------------------------------------
354              
355             =head1 NAME
356              
357             Search::Circa::Search - Search interface on Circa, a www search engine running with Mysql
358              
359             =head1 SYNOPSIS
360              
361             use Search::Circa::Search;
362             my $search = new Search::Circa::Search;
363            
364             # Connection à MySQL
365             die "Erreur à la connection MySQL:$DBI::errstr\n"
366             if (!$search->connect);
367            
368             # Affichage d'un formulaire minimum
369             print header,
370             $search->start_classic_html,
371             $search->default_form;
372            
373             # Interrogation du moteur
374             # Sites trouves, liens pages suivantes, nb pages trouvees
375             my ($resultat,$links,$indice) = $search->search('informatique internet',0,1);
376              
377              
378             =head1 DESCRIPTION
379              
380             This is Search::Circa::Search, a module who provide functions to
381             perform search on Circa database
382              
383             Notes:
384              
385             =over
386              
387             =item *
388              
389             Accents are removed on search and when indexed
390              
391             =item *
392              
393             Search are case unsensitive (mmmh what my english ? ;-)
394              
395             =back
396              
397             Circa::Search work with Circa::Indexer result. Circa::Search is a Perl
398             interface, but it's exist on this package a PHP client too.
399              
400             =head1 Class Interface
401              
402             =head2 Constructors and Instance Methods
403              
404             =over
405              
406             =item new
407              
408             Create new instance of Circa::Search
409              
410             =back
411              
412             =head2 Search method
413              
414             =over
415              
416             =item search($tab,$mot,$idc,$langue,$url,$create,$update,$categorie)
417              
418             Main method of this module. This function anlayse request of user,
419             build and make the SQL request on Circa, and return HTML result.
420             Circa support "not", "and", and "or" by default.
421              
422             =over
423              
424             =item *
425              
426             To make request with "not" : circa - alian (not idem :circa-alian who search circa and alian)
427              
428             =item *
429              
430             To make request with "and" : circa + alian
431              
432             =item *
433              
434             To make request with "or" : circa alian (default).
435              
436             =back
437              
438             Parameters:
439              
440             =over 4
441              
442             =item $template
443              
444             HTML template used for each link found. If undef, default template will be used
445             (defined at top of this file). Variables names used are : $indiceG,$titre,$description,
446             $url,$facteur,$last_update,$langue
447              
448             Example :
449              
450             '"

$indiceG - $titre $description

451             Url: $url Facteur: $facteur
452             Last update: $last_update

\n"'
453              
454             =item $mot
455              
456             Search word sequence hit by user
457              
458             Séquence des mots recherchés tel que tapé par l'utilisateur
459              
460             =item first
461              
462             Number of first site print.
463              
464             Indice du premier site affiché dans le résultat
465              
466             =item $id
467              
468             Id of account
469              
470             Id du site dans lequel effectué la recherche
471              
472             =item $langue
473              
474             Restrict by langue
475              
476             Restriction par langue (facultatif)
477              
478             =item $Url
479              
480             Restriction par url : les url trouvées commenceront par $Url (facultatif)
481              
482             =item $create
483              
484             Restriction par date inscription. Format YYYY-MM-JJ HH:MM:SS (facultatif)
485              
486             =item $update
487              
488             Restriction par date de mise à jour des pages. Format YYYY-MM-JJ HH:MM:SS (facultatif)
489              
490             =item $catego
491              
492             Restriction par categorie (facultatif)
493              
494             =back
495              
496             Retourne ($resultat,$links,$indice)
497              
498             =over
499              
500             =item $resultat
501              
502             Buffer HTML contenant la liste des sites trouves formaté en fonction de $template et des
503             mots present dans $mots
504              
505             =item $links
506              
507             Liens vers les pages suivantes / precedentes
508              
509             =item $indice
510              
511             Nombre de sites trouves
512              
513             =back
514              
515             =item search_word($tab,$word,$idc,$langue,$Url,$create,$update,$categorie)
516              
517             Make request on Circa. Call by search
518              
519             =over
520              
521             =item *
522              
523             $tab : Reference du hash où mettre le resultat
524              
525             =item *
526              
527             $word : Mot recherché
528              
529             =item *
530              
531             $id : Id du site dans lequel effectué la recherche
532              
533             =item *
534              
535             $langue : Restriction par langue (facultatif)
536              
537             =item *
538              
539             $Url : Restriction par url
540              
541             =item *
542              
543             $create : Restriction par date inscription
544              
545             =item *
546              
547             $update : Restriction par date de mise à jour des pages
548              
549             =item *
550              
551             $catego : Restriction par categorie
552              
553             =back
554              
555             Retourne la reference du hash avec le resultat de la recherche sur le mot $word
556             Le hash est constitué comme tel:
557              
558             $tab{$url}[0] : titre
559             $tab{$url}[1] : description
560             $tab{$url}[2] : facteur
561             $tab{$url}[3] : langue
562             $tab{$url}[4] : date de dernière modification
563             @{$$tab{$url}[5]}: liste des mots trouves pour cet url
564              
565             =item categories_in_categorie($id,$idr,[$template])
566              
567             Fonction retournant la liste des categories de la categorie $id dans le site $idr
568              
569             =over
570              
571             =item *
572              
573             $id Id de la categorie de depart. Si undef, 0 est utilisé (Considéré
574             comme le "Home")
575              
576              
577             =item *
578              
579             $idr Id du responsable
580              
581             =item *
582              
583             $template : Masque HTML pour le resultat de chaque lien. Si undef, le
584             masque par defaut (defini en haut de ce module) sera utlise
585              
586             =back
587              
588             Retourne ($resultat,$nom_categorie) :
589              
590             =over
591              
592             =item *
593              
594             $resultat : Buffer contenant la liste des sites formatées en ft de $template
595              
596             =item *
597              
598             $nom_categorie : Nom court de la categorie
599              
600             =back
601              
602             =item sites_in_categorie($id, $idr, [$template], [$first])
603              
604             Fonction retournant la liste des pages de la categorie $id dans le site $idr
605              
606             =over
607              
608             =item *
609              
610             $id : Id de la categorie de depart. Si undef, 0 est utilisé (Considéré comme le "Home")
611              
612             =item *
613              
614             $idr : Id du responsable
615              
616             =item *
617              
618             $template : Masque HTML pour le resultat de chaque lien. Si undef, le
619             masque par defaut (defini en haut de ce module) sera utlise
620              
621             =item *
622              
623             $first : If present return only site from $first to
624             $first + $self->{nbResultPerPage} and a buffer with link to other pages
625              
626             =back
627              
628             Retourne le buffer contenant la liste des sites formatées en ft de $template
629              
630             =back
631              
632             =head2 HTML methods
633              
634             =over
635              
636             =item get_link($no_page,$id)
637              
638             Retourne l'URL correspondant à la page no $no_page dans la recherche en cours
639              
640             =item advanced_form([$id],$cgi)
641              
642             Affiche un formulaire minimum pour effectuer une recherche sur Circa
643              
644             =item default_form
645              
646             Affiche un formulaire minimum pour effectuer une recherche sur Circa
647              
648             =item get_liste_langue($cgi)
649              
650             Retourne le buffer HTML correspondant à la liste des langues disponibles
651              
652             =item get_name_site($id)
653              
654             Retourne le nom du site dans la table responsable correspondant à l'id $id
655              
656             =back
657              
658             =head1 VERSION
659              
660             $Revision: 1.21 $
661              
662             =head1 SEE ALSO
663              
664             L, Root class for circa
665              
666             L, command line script to perform search
667              
668             =head1 AUTHOR
669              
670             Alain BARBET alian@alianwebserver.com
671              
672             =cut
673              
674             1;