--- loncom/interface/lonsearchcat.pm 2006/05/30 12:46:09 1.265 +++ loncom/interface/lonsearchcat.pm 2010/08/13 13:32:36 1.325 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Search Catalog # -# $Id: lonsearchcat.pm,v 1.265 2006/05/30 12:46:09 www Exp $ +# $Id: lonsearchcat.pm,v 1.325 2010/08/13 13:32:36 wenzelju Exp $ # # Copyright Michigan State University Board of Trustees # @@ -78,7 +78,6 @@ use HTML::Entities(); use Parse::RecDescent; use Apache::lonnavmaps; use Apache::lonindexer(); -use lib '/home/httpd/lib/perl/'; use LONCAPA; ###################################################################### @@ -119,8 +118,6 @@ sub handler { # This is set and used in &handler() and is also used in # &output_results(). - my $loaderror=&Apache::lonnet::overloaderror($r); - if ($loaderror) { return $loaderror; } # my $closebutton; # button that closes the search window # This button is different for the RAT compared to @@ -139,7 +136,7 @@ sub handler { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['catalogmode','launch','acts','mode','form','element','pause', 'phase','persistent_db_id','table','start','show', - 'cleargroupsort','titleelement']); + 'cleargroupsort','titleelement','area','inhibitmenu']); ## ## The following is a trick - we wait a few seconds if asked to so ## the daemon running the search can get ahead of the daemon @@ -155,7 +152,7 @@ sub handler { ## my $domain = $r->dir_config('lonDefDomain'); $diropendb= "/home/httpd/perl/tmp/". - "$env{'user.domain'}_$env{'user.name'}_searchcat.db"; + "$env{'user.domain'}_$env{'user.name'}_sel_res.db"; # # set the name of the persistent database # $env{'form.persistent_db_id'} can only have digits in it. @@ -171,25 +168,33 @@ sub handler { '_'.$env{'form.persistent_db_id'}.'_persistent_search.db'; ## &Apache::lonhtmlcommon::clear_breadcrumbs(); + + my @allowed_searches = ('portfolio'); + if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'})) { + push(@allowed_searches,'res'); + } if (exists($env{'request.course.id'}) && $env{'request.course.id'} ne '') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/searchcat?'. - 'catalogmode='.$env{'form.catalogmode'}. - '&launch='.$env{'form.launch'}. - '&mode='.$env{'form.mode'}, - text=>"Course and Catalog Search", - target=>'_top', - bug=>'Searching',}); - } else { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/searchcat?'. - 'catalogmode='.$env{'form.catalogmode'}. - '&launch='.$env{'form.launch'}. - '&mode='.$env{'form.mode'}, - text=>"Catalog Search", + push(@allowed_searches,'course'); + } + my $crumb_text = 'Portfolio Search'; + if (@allowed_searches == 3) { + $crumb_text = 'Course, Portfolio and Catalog Search'; + } elsif (@allowed_searches ==2) { + if (grep(/^res$/,@allowed_searches)) { + $crumb_text = 'Portfolio and Catalog Search'; + } elsif (grep(/^course$/,@allowed_searches)) { + $crumb_text = 'Portfolio and Course Search'; + } + } + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/searchcat?'. + &Apache::loncommon::inhibit_menu_check(). + '&catalogmode='.$env{'form.catalogmode'}. + '&launch='.$env{'form.launch'}. + '&mode='.$env{'form.mode'}, + text=>"$crumb_text", target=>'_top', bug=>'Searching',}); - } # if ($env{'form.phase'} !~ m/(basic|adv|course)_search/) { if (! &get_persistent_form_data($persistent_db_file)) { @@ -215,7 +220,7 @@ sub handler { untie %groupsearch_db if (tied(%groupsearch_db)); if (($env{'form.cleargroupsort'} eq '1') || (($env{'form.launch'} eq '1') && - ($env{'form.catalogmode'} eq 'groupsearch'))) { + ($env{'form.catalogmode'} eq 'import'))) { if (tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT(),0640)) { &start_fresh_session(); untie %groupsearch_db; @@ -249,28 +254,35 @@ sub handler { if (exists($env{'form.mode'})) { $hidden_fields .= &hidden_field('mode'); } + if (exists($env{'form.area'})) { + $hidden_fields .= &hidden_field('area'); + } + if (exists($env{'form.inhibitmenu'})) { + $hidden_fields .= &hidden_field('inhibitmenu'); + } ## ## Configure dynamic components of interface ## if ($env{'form.catalogmode'} eq 'interactive') { - $closebutton=" + END } else { $closebutton = ''; @@ -294,19 +306,25 @@ END } # if ($env{'form.searchmode'} eq 'advanced') { + my $srchtype = 'Catalog'; + if ($env{'form.area'} eq 'portfolio') { + $srchtype = 'Portfolio'; + } &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/searchcat?phase=disp_adv&'. - 'catalogmode='.$env{'form.catalogmode'}. - '&launch='.$env{'form.launch'}. - '&mode='.$env{'form.mode'}, - text=>"Advanced Search", + ({href=>'/adm/searchcat?'.&Apache::loncommon::inhibit_menu_check(). + '&phase=disp_adv'. + '&catalogmode='.$env{'form.catalogmode'}. + '&launch='.$env{'form.launch'}. + '&mode='.$env{'form.mode'}, + text=>"Advanced $srchtype Search", bug=>'Searching',}); } elsif ($env{'form.searchmode'} eq 'course search') { &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/searchcat?phase=disp_adv&'. - 'catalogmode='.$env{'form.catalogmode'}. - '&launch='.$env{'form.launch'}. - '&mode='.$env{'form.mode'}, + ({href=>'/adm/searchcat?'.&Apache::loncommon::inhibit_menu_check(). + '&phase=disp_adv'. + '&catalogmode='.$env{'form.catalogmode'}. + '&launch='.$env{'form.launch'}. + '&mode='.$env{'form.mode'}, text=>"Course Search", bug=>'Searching',}); } @@ -318,7 +336,8 @@ END } elsif ($env{'form.phase'} eq 'disp_adv') { &print_advanced_search_form($r,$closebutton,$hidden_fields); } elsif ($env{'form.phase'} eq 'results') { - &display_results($r,$importbutton,$closebutton,$diropendb); + &display_results($r,$importbutton,$closebutton,$diropendb, + $env{'form.area'}); } elsif ($env{'form.phase'} =~ /^(sort|run_search)$/) { my ($query,$customquery,$customshow,$libraries,$pretty_string) = &get_persistent_data($persistent_db_file, @@ -328,7 +347,7 @@ END &print_sort_form($r,$pretty_string); } elsif ($env{'form.phase'} eq 'run_search') { &run_search($r,$query,$customquery,$customshow, - $libraries,$pretty_string); + $libraries,$pretty_string,$env{'form.area'}); } } elsif ($env{'form.phase'} eq 'course_search') { &course_search($r); @@ -358,14 +377,14 @@ END $persistent_db_file); # # Set up table - if (! defined(&create_results_table())) { + if (! defined(&create_results_table($env{'form.area'}))) { my $errorstring=&Apache::lonmysql::get_error(); &Apache::lonnet::logthis('lonsearchcat.pm: Unable to create '. 'needed table. lonmysql error:'. $errorstring); my $msg = - 'Unable to create table in which to store search results. '. + 'Unable to create table in which to save search results. '. 'The search has been aborted.'; &Apache::loncommon::simple_error_page($r,'Search Error', $msg); @@ -374,7 +393,7 @@ END delete($env{'form.launch'}); if (! &make_form_data_persistent($r,$persistent_db_file)) { my $msg= - 'Unable to properly store search information. '. + 'Unable to properly save search information. '. 'The search has been aborted.'; &Apache::loncommon::simple_error_page($r,'Search Error', $msg); @@ -467,7 +486,20 @@ sub course_search { my $discuss=$env{'form.crsdiscuss'}; my @allwords=($search_string,@New_Words); $totalfound=0; - $r->print(&Apache::loncommon::start_page('Course Search'). + + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/searchcat?'.&Apache::loncommon::inhibit_menu_check(). + '&phase=disp_adv'. + '&catalogmode='.$env{'form.catalogmode'}. + '&launch='.$env{'form.launch'}. + '&mode='.$env{'form.mode'}, + text=>"Course Search", + bug=>'Searching',}); + $r->print(&Apache::loncommon::start_page('Course Search')); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Searching','Searching', + $env{'form.catalogmode'} ne 'import')); + + $r->print( '
'. $pretty_search_string.'
'. '
'.&mt('Course content').':
'); @@ -490,7 +522,7 @@ sub course_search { untie(%hash); } unless ($totalfound) { - $r->print('

'.&mt('No matches found in resources').'.

'); + $r->print('

'.&mt('No matches found in resources.').'

'); } # Check discussions if requested @@ -498,72 +530,77 @@ sub course_search { my $totaldiscussions = 0; $r->print('

'.&mt('Discussion postings').':
'); my $navmap = Apache::lonnavmaps::navmap->new(); - my @allres=$navmap->retrieveResources(); - my %discussiontime = &Apache::lonnet::dump('discussiontimes', - $env{'course.'.$env{'request.course.id'}.'.domain'}, - $env{'course.'.$env{'request.course.id'}.'.num'}); - foreach my $resource (@allres) { - my $result = ''; - my $applies = 0; - my $symb = $resource->symb(); - my $ressymb = $symb; - if ($symb =~ m#(___adm/\w+/\w+)/(\d+)/bulletinboard$#) { - $ressymb = 'bulletin___'.$2.$1.'/'.$2.'/bulletinboard'; - unless ($ressymb =~ m#bulletin___\d+___adm/wrapper#) { - $ressymb=~s#(bulletin___\d+___)#$1adm/wrapper/#; + if (defined($navmap)) { + my @allres=$navmap->retrieveResources(); + my %discussiontime = &Apache::lonnet::dump('discussiontimes', + $env{'course.'.$env{'request.course.id'}.'.domain'}, + $env{'course.'.$env{'request.course.id'}.'.num'}); + foreach my $resource (@allres) { + my $result = ''; + my $applies = 0; + my $symb = $resource->symb(); + my $ressymb = $symb; + if ($symb =~ m#(___adm/$LONCAPA::domain_re/$LONCAPA::username_re)/(\d+)/bulletinboard$#) { + $ressymb = 'bulletin___'.$2.$1.'/'.$2.'/bulletinboard'; + unless ($ressymb =~ m#bulletin___\d+___adm/wrapper#) { + $ressymb=~s#(bulletin___\d+___)#$1adm/wrapper/#; + } } - } - if (defined($discussiontime{$ressymb})) { - my %contrib = &Apache::lonnet::restore($ressymb,$env{'request.course.id'}, - $env{'course.'.$env{'request.course.id'}.'.domain'}, - $env{'course.'.$env{'request.course.id'}.'.num'}); - if ($contrib{'version'}) { - for (my $id=1;$id<=$contrib{'version'};$id++) { - unless (($contrib{'hidden'}=~/\.$id\./) || ($contrib{'deleted'}=~/\.$id\./)) { - if ($contrib{$id.':subject'}) { - $result .= $contrib{$id.':subject'}; - } - if ($contrib{$id.':message'}) { - $result .= $contrib{$id.':message'}; - } - if ($contrib{$id,':attachmenturl'}) { - if ($contrib{$id,':attachmenturl'} =~ m-/([^/]+)$-) { - $result .= $1; + if (defined($discussiontime{$ressymb})) { + my %contrib = &Apache::lonnet::restore($ressymb,$env{'request.course.id'}, + $env{'course.'.$env{'request.course.id'}.'.domain'}, + $env{'course.'.$env{'request.course.id'}.'.num'}); + if ($contrib{'version'}) { + for (my $id=1;$id<=$contrib{'version'};$id++) { + unless (($contrib{'hidden'}=~/\.$id\./) || ($contrib{'deleted'}=~/\.$id\./)) { + if ($contrib{$id.':subject'}) { + $result .= $contrib{$id.':subject'}; + } + if ($contrib{$id.':message'}) { + $result .= $contrib{$id.':message'}; } + if ($contrib{$id,':attachmenturl'}) { + if ($contrib{$id,':attachmenturl'} =~ m-/([^/]+)$-) { + $result .= $1; + } + } + $applies = &checkwords($result,$applies,@allwords); } - $applies = &checkwords($result,$applies,@allwords); } } } - } # Does this discussion apply? - if ($applies) { - my ($map,$ind,$url)=&Apache::lonnet::decode_symb($ressymb); - my $disctype = &mt('resource'); - if ($url =~ m#/bulletinboard$#) { - if ($url =~m#^adm/wrapper/adm/.*/bulletinboard$#) { - $url =~s#^adm/wrapper##; + if ($applies) { + my ($map,$ind,$url)=&Apache::lonnet::decode_symb($ressymb); + my $disctype = &mt('resource'); + if ($url =~ m#/bulletinboard$#) { + if ($url =~m#^adm/wrapper/adm/.*/bulletinboard$#) { + $url =~s#^adm/wrapper##; + } + $disctype = &mt('discussion board'); + } else { + $url = '/res/'.$url; } - $disctype = &mt('bulletin board'); - } else { - $url = '/res/'.$url; - } - if ($url =~ /\?/) { - $url .= '&symb='; + if ($url =~ /\?/) { + $url .= '&symb='; + } else { + $url .= '?symb='; + } + $url .= &escape($resource->symb()); + my $title = $resource->compTitle(); + $r->print('
'. + ($title?$title:$url).'  - '. + $disctype.'
'); + $totaldiscussions++; } else { - $url .= '?symb='; + $r->print(' .'); } - $url .= &escape($resource->symb()); - my $title = $resource->compTitle(); - $r->print('
'. - ($title?$title:$url).'  - '.$disctype.'
'); - $totaldiscussions++; - } else { - $r->print(' .'); } - } - unless ($totaldiscussions) { - $r->print('

'.&mt('No matches found in postings').'.

'); + unless ($totaldiscussions) { + $r->print('

'.&mt('No matches found in postings.').'

'); + } + } else { + $r->print('
'.&mt('An error occurred retrieving information about resources in the course.').'
'.&mt('It is recommended that you [_1]re-initialize the course[_2] and then try your search again.','','').'
'); } } @@ -660,80 +697,25 @@ Prints the form for the basic search. S ###################################################################### sub print_basic_search_form { my ($r,$closebutton,$hidden_fields) = @_; - my $result = ($env{'form.catalogmode'} ne 'groupsearch'); + my $result = ($env{'form.catalogmode'} ne 'import'); my $bread_crumb = &Apache::lonhtmlcommon::breadcrumbs('Searching','Search_Basic', - $env{'form.catalogmode'} ne 'groupsearch'); - my $scrout = &Apache::loncommon::start_page('Search').$bread_crumb; + $env{'form.catalogmode'} ne 'import'); + my $scrout = &Apache::loncommon::start_page('Content Library').$bread_crumb; +# Search form for resource space if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'})) { - # Define interface components - my $userelatedwords= ''; - my $onlysearchdomain=''; - my $inclext= ''; - my $adv_search_link = - ''.&mt('Advanced Search').''; - # - $scrout.='
'. - ''. - $hidden_fields; - # - $scrout .= '
'.$/; - if ($env{'request.course.id'}) { - $scrout .= '

'.&mt('LON-CAPA Catalog Search').'

'; - } else { - # No need to tell them they are searching - $scrout.= ('
'x2); - } - $scrout.=''. - ''. - ''. - ''.$/; - # - $scrout .= ''.$/; - $scrout .= '
'. - &Apache::lonhtmlcommon::textbox('basicexp', - $env{'form.basicexp'},50). - '
'. - ''.&searchhelp().''.'
'. - ''.(' 'x3).$adv_search_link.''.'
'. - ''.(' 'x1).$userelatedwords.''.'
'. - ''.(' 'x1).$onlysearchdomain.''.'
'. - ''.(' 'x1).$inclext.''.'
'. - '
'. - ''. - ''. - (' 'x2).$closebutton.(' 'x2). - &viewoptions(). - ''. - '
'.$/.'
'.'
'; + $scrout .= &setup_basic_search($r,'res',$hidden_fields,$closebutton); + $scrout .= '

'; } +# Search form for accessible portfolio files + $scrout.= &setup_basic_search($r,'portfolio',$hidden_fields,$closebutton); if ($env{'request.course.id'}) { my %lt=&Apache::lonlocal::texthash('srch' => 'Search', 'header' => 'Course Search', 'note' => 'Enter terms or phrases, then press "Search" below', 'use' => 'use related words', 'full' =>'fulltext search (time consuming)', - 'disc' => 'search discussion postings (resources and bulletin boards)', + 'disc' => 'search discussion postings (resources and discussion boards)', ); $scrout.=(< @@ -745,7 +727,6 @@ $hidden_fields

$lt{'note'}.

-

-
ENDCOURSESEARCH @@ -766,8 +747,9 @@ ENDCOURSESEARCH

+ +

+

@@ -777,6 +759,91 @@ ENDENDCOURSE $r->print($scrout); return; } + +sub setup_basic_search { + my ($r,$area,$hidden_fields,$closebutton) = @_; + # Define interface components + my %lt = &Apache::lonlocal::texthash ( + res => 'LON-CAPA Catalog Search', + portfolio => 'Portfolio Search', + ); + my ($userelatedwords,$onlysearchdomain,$inclext,$adv_search_link,$scrout); + + $userelatedwords = ''; + + $onlysearchdomain = ''; + + $adv_search_link = ''.&mt('Advanced Search').''; + # + $scrout.='
'. + ''. + $hidden_fields; + if (!exists($env{'form.area'})) { + $scrout .= ''; + } + # + $scrout .= '
'.$/; +# if ($env{'request.course.id'}) { + $scrout .= '

'.$lt{$area}.'

'; +# } else { + # No need to tell them they are searching +# $scrout.= ('
'x2); +# } + $scrout.=''. + ''. + ''. + ''. + '
'. + &Apache::lonhtmlcommon::textbox('basicexp', + $env{'form.basicexp'},50). + '
'. + ''.&searchhelp().''.'
'. + ''.(' 'x3).$adv_search_link.''.'
'. + ''.(' 'x1).$userelatedwords.''.'
'. + ''.(' 'x1).$onlysearchdomain.''.'
'. + ''.(' 'x1).$inclext.''.'
'. + '
'.$/; + # + $scrout .= '

' + .&viewoptions() + .'

' + .'

' + .'' + .' ' + .$closebutton + .'

'; + # + $scrout .= '
'.'
'; + return $scrout; +} + ###################################################################### ###################################################################### @@ -794,30 +861,57 @@ sub print_advanced_search_form{ my ($r,$closebutton,$hidden_fields) = @_; my $bread_crumb = &Apache::lonhtmlcommon::breadcrumbs('Searching','Search_Advanced', - $env{'form.catalogmode'} ne 'groupsearch'); + $env{'form.catalogmode'} ne 'import'); my %lt=&Apache::lonlocal::texthash('srch' => 'Search', 'reset' => 'Reset', 'help' => 'Help'); my $advanced_buttons=<<"END"; +

$closebutton +

END - my $scrout= &Apache::loncommon::start_page('Advanced Catalog Search'); - $scrout .= <<"ENDHEADER"; -$bread_crumb -
-

-$advanced_buttons -ENDHEADER - $scrout.=(' 'x2).&viewoptions().'

'.$hidden_fields. - ''; + my $srchtype = 'Catalog'; + my $jscript; + if ($env{'form.area'} eq 'portfolio') { + $srchtype = 'Portfolio'; + $jscript = ''; + } + my $scrout= &Apache::loncommon::start_page("Advanced $srchtype Search", + $jscript); + $scrout .= $bread_crumb; + + $scrout .= '' + .$hidden_fields + .''; + + $scrout .= '
'."\n" + .''.&mt('Display Options').''."\n" + .&viewoptions() + .'
'; + + $scrout .= $advanced_buttons; + + $scrout .= &Apache::lonhtmlcommon::start_pick_box(); + my %fields=&Apache::lonmeta::fieldnames(); - # - $scrout .= '

'.&mt('Standard Metadata').'

'; - $scrout .= "\n"; - $scrout .= '\n"; + + # Standard Metadata + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

'.&mt("Standard $srchtype Metadata").'

' + .&searchhelp() + .&Apache::lonhtmlcommon::row_closure(); my %related_word_search = ('title' => 1, 'author' => 0, @@ -829,129 +923,167 @@ ENDHEADER 'abstract' => 1, 'standards'=> 1, 'mime' => 1, - 'subject' => 1, + 'subject' => 1, ); # foreach my $field ('title','author','subject','owner','authorspace', - 'modifyinguser','keywords','notes','abstract', - 'standards','mime') { - $scrout.=''.$/; + $scrout .= &Apache::lonhtmlcommon::row_closure(); } foreach my $field ('lowestgradelevel','highestgradelevel') { - $scrout.=''. - ''. - ''.$/; + 0) + .&Apache::lonhtmlcommon::row_closure(); } - $scrout.=''.$/; - $scrout.=''.$/; - # + + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt('MIME Type Category'))) + .&Apache::loncommon::filecategoryselect('category', + $env{'form.category'}) + .&Apache::lonhtmlcommon::row_closure(); + + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt('Domains'))) + .&Apache::loncommon::domain_select('domains', + $env{'form.domains'},1) + .&Apache::lonhtmlcommon::row_closure(); + # Misc metadata - $scrout.=''.$/; - $scrout.=''; - $scrout .= "
 '. - (' 'x2).&searchhelp()."
'.&titlefield($fields{$field}).''. - &Apache::lonmeta::prettyinput($field, + 'modifyinguser','keywords','notes','abstract', + 'standards','mime') { + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield($fields{$field})) + .&Apache::lonmeta::prettyinput($field, $env{'form.'.$field}, $field, 'advsearch', - $related_word_search{$field}, - '', + $related_word_search{$field}, + '', $env{'form.'.$field.'_related'}, 50); if ($related_word_search{$field}) { - $scrout .= 'related words'; + $scrout .= &mt('related words'); } else { - $scrout .= ' '; + $scrout .= ''; } - $scrout .= '
'.&titlefield($fields{$field}).''. - &Apache::lonmeta::prettyinput($field, + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield($fields{$field})) + .&Apache::lonmeta::prettyinput($field, $env{'form.'.$field}, $field, 'advsearch', - 0). - '
'. - &titlefield(&mt('MIME Type Category')).''. - &Apache::loncommon::filecategoryselect('category', - $env{'form.category'}). - '
'. - &titlefield(&mt('Domains')).''. - &Apache::loncommon::domain_select('domains', - $env{'form.domains'},1). - '
'. - &titlefield(&mt('Copyright/Distribution')).''. - &Apache::lonmeta::selectbox('copyright', - $env{'form.copyright'}, - \&Apache::loncommon::copyrightdescription, - ( undef, - &Apache::loncommon::copyrightids) - ).'
'. - &titlefield(&mt('Language')).''. - &Apache::lonmeta::selectbox('language', + if ($env{'form.area'} ne 'portfolio') { + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt('Copyright/Distribution'))) + .&Apache::lonmeta::selectbox('copyright', + $env{'form.copyright'}, + \&Apache::loncommon::copyrightdescription, + ( undef, + &Apache::loncommon::copyrightids) + ) + .&Apache::lonhtmlcommon::row_closure(); + } + + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt('Language'))) + .&Apache::lonmeta::selectbox('language', $env{'form.language'}, \&Apache::loncommon::languagedescription, ('any',&Apache::loncommon::languageids) - ).'
\n"; - # - # Dynamic metadata - $scrout .= '

'.&mt('Problem Statistics').'

'; - $scrout .= "\n"; - $scrout .= ''. - ''."\n"; - foreach my $statistic - ({ name=>'count', - description=>'Network-wide number of accesses (hits)',}, - { name=>'stdno', - description=> - 'Total number of students who have worked on this problem',}, - { name => 'avetries', - description=>'Average number of tries till solved',}, - { name => 'difficulty', - description=>'Degree of difficulty',}, - { name => 'disc', - description=>'Degree of discrimination'}) { - $scrout .= ''.$/; - } - $scrout .= "
 '.&mt('Minimum').''.&mt('Maximum').'
'. - &titlefield(&mt($statistic->{'description'})). - ''. - ''. - ''. - ''. - '
\n"; - $scrout .= '

'.&mt('Evaluation Data').'

'; - $scrout .= "\n"; - $scrout .= ''. - ''."\n"; - foreach my $evaluation - ( { name => 'clear', - description => 'Material presented in clear way'}, - { name =>'depth', - description => 'Material covered with sufficient depth'}, - { name => 'helpful', - description => 'Material is helpful'}, - { name => 'correct', - description => 'Material appears to be correct'}, - { name => 'technical', - description => 'Resource is technically correct'}){ - $scrout .= ''.$/; + ) + .&Apache::lonhtmlcommon::row_closure(); + + # Portfolio Metadata + if ($env{'form.area'} eq 'portfolio') { + # Added fields + my $curnumadd = $env{'form.numaddedfields'}; + if ($curnumadd eq '') { + $curnumadd = 1; + } + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

'.&mt('Custom Metadata fields').'

' + .&Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title('') + .&mt('Field Name').' | '.&mt('Field Value(s)') + .&Apache::lonhtmlcommon::row_closure(); + + for (my $j=0; $j<$curnumadd; $j++) { + my $num = $j+1; + $scrout .= &Apache::lonhtmlcommon::row_title(&mt('Custom metadata [_1]',$num)) + .'' + .' ' + .'' + .&Apache::lonhtmlcommon::row_closure(); + } + $scrout .= &Apache::lonhtmlcommon::row_title('') + .'' + .'' + .&Apache::lonhtmlcommon::row_closure(); +} else { + # + # Dynamic metadata + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

'.&mt('Problem Statistics').'

' + .&Apache::lonhtmlcommon::row_closure(); + $scrout .= &Apache::lonhtmlcommon::row_title('') + .&mt('Minimum').' | '.&mt('Maximum') + .&Apache::lonhtmlcommon::row_closure(); + foreach my $statistic + ({ name=>'count', + description=>'Network-wide number of accesses (hits)',}, + { name=>'stdno', + description=> + 'Statistics calculated for number of students',}, + { name => 'avetries', + description=>'Average number of tries till solved',}, + { name => 'difficulty', + description=>'Degree of difficulty',}, + { name => 'disc', + description=>'Degree of discrimination'}) { + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt($statistic->{'description'}))) + .'' + .' ' + .'' + .&Apache::lonhtmlcommon::row_closure(); + } + + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

'.&mt('Evaluation Data').'

' + .&Apache::lonhtmlcommon::row_closure(); + $scrout .= &Apache::lonhtmlcommon::row_title('') + .&mt('Minimum').' | '.&mt('Maximum') + .&Apache::lonhtmlcommon::row_closure(); + foreach my $evaluation + ( { name => 'clear', + description => 'Material presented in clear way'}, + { name =>'depth', + description => 'Material covered with sufficient depth'}, + { name => 'helpful', + description => 'Material is helpful'}, + { name => 'correct', + description => 'Material appears to be correct'}, + { name => 'technical', + description => 'Resource is technically correct'}){ + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt($evaluation->{'description'}))) + .'' + .' ' + .'' + .&Apache::lonhtmlcommon::row_closure(); + } } - $scrout .= "
 '.&mt('Minimum').''.&mt('Maximum').'
'. - &titlefield(&mt($evaluation->{'description'})). - ''. - ''. - ''. - ''. - '
\n"; # # Creation/Modification date limits - $scrout .= '

'.&mt('Creation and Modification dates').'

'; - $scrout .= "\n\n"; + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

'.&mt('Creation and Modification dates').'

' + .&Apache::lonhtmlcommon::row_closure(); + $scrout .= &Apache::lonhtmlcommon::row_title('') + .&mt('Month[_1]Day[_2]Year',' 'x14,' 'x6) + .&Apache::lonhtmlcommon::row_closure(); + my $cafter = &Apache::lonhtmlcommon::date_setter('advsearch', # formname 'creationdate1', # fieldname @@ -970,10 +1102,13 @@ ENDHEADER '', # state 1, # no_hh_mm_ss ); - $scrout .= &mt(''. - ''. - ''. - '',$cafter,$cbefore); + $scrout .= &Apache::lonhtmlcommon::row_title(&mt('Created between')) + .$cafter + .&Apache::lonhtmlcommon::row_closure(1) + .&Apache::lonhtmlcommon::row_title(&mt('and')) + .$cbefore + .&Apache::lonhtmlcommon::row_closure(); + my $lafter = &Apache::lonhtmlcommon::date_setter('advsearch', 'revisiondate1', @@ -992,15 +1127,18 @@ ENDHEADER '', # state 1, # no_hh_mm_ss ); - $scrout .= &mt(''. - ''. - ''. - '',$lafter,$lbefore); - $scrout.="
Created between[_1]
and [_2]
Last modified between [_1]
and[_2]
\n"; - $scrout.=< -ENDDOCUMENT + $scrout .= &Apache::lonhtmlcommon::row_title(&mt('Last modified between')) + .$lafter + .&Apache::lonhtmlcommon::row_closure(1) + .&Apache::lonhtmlcommon::row_title(&mt('and')) + .$lbefore + .&Apache::lonhtmlcommon::row_closure(1); # Last row of total pick_box + + $scrout .= &Apache::lonhtmlcommon::end_pick_box(); + + $scrout .= $advanced_buttons + .''; + $scrout .= &Apache::loncommon::end_page(); $r->print($scrout); return; @@ -1074,17 +1212,20 @@ sub viewoptions { if (! defined($env{'form.viewselect'})) { $env{'form.viewselect'}='detailed'; } - $scrout.=&Apache::lonmeta::selectbox('viewselect', - $env{'form.viewselect'}, - \&viewoptiontext, - sort(keys(%Views))); - $scrout.= '  '; + $scrout .= '' + .&mt('Type:').' ' + .&Apache::lonmeta::selectbox('viewselect', + $env{'form.viewselect'}, + \&viewoptiontext, + sort(keys(%Views))) + .''; my $countselect = &Apache::lonmeta::selectbox('show', $env{'form.show'}, undef, (10,20,50,100,1000,10000)); - $scrout .= (' 'x2).&mt('[_1] Records per Page',$countselect). - ''.$/; + $scrout .= ' ' + .&mt('Records per Page:').' '.$countselect + .''.$/; return $scrout; } @@ -1310,7 +1451,7 @@ sub parse_advanced_search { 'lastrevisiondatestart_month','lastrevisiondatestart_day', 'lastrevisiondatestart_year','lastrevisiondateend_month', 'lastrevisiondateend_day','lastrevisiondateend_year') { - $env{'form.'.$field}=~s/[^\w\/\s\(\)\=\-\"\']//g; + $env{'form.'.$field}=~s/[^\w\/\s\(\)\=\-\"\'.\*]//g; } foreach ('mode','form','element') { # is this required? Hmmm. @@ -1343,6 +1484,17 @@ sub parse_advanced_search { $fillflag++; } } + if ($env{'form.area'} eq 'portfolio') { + # Added metadata fields + for (my $i=0; $i<$env{'form.numaddedfields'} ; $i++) { + my $field = $env{'form.addedfield_'.$i}; + $field =~ s/^\s*(\S*)\s*$/$1/; + $field =~ s/\W/_/g; + if ($field ne '') { + $fillflag++; + } + } + } if (! $fillflag) { &output_blank_field_error($r,$closebutton, 'phase=disp_adv',$hidden_fields); @@ -1429,29 +1581,56 @@ sub parse_advanced_search { &Apache::loncommon::copyrightdescription($env{'form.copyright'}). "
\n"; } - # - # Statistics - foreach my $field (@StatsFields,@EvalFields) { - my ($min,$max); - if (exists($env{'form.'.$field.'_min'}) && - $env{'form.'.$field.'_min'} ne '') { - $min = $env{'form.'.$field.'_min'}; - } - if (exists($env{'form.'.$field.'_max'}) && - $env{'form.'.$field.'_max'} ne '') { - $max = $env{'form.'.$field.'_max'}; - } - next if (! defined($max) && ! defined($min)); - if (defined($min) && defined($max)) { - ($min,$max) = sort {$a <=>$b} ($min,$max); - } - if (defined($min) && $min =~ /^(\d+\.\d+|\d+|\.\d+)$/) { - push(@queries,'('.$field.'>'.$min.')'); - $pretty_search_string.=$font.$field.'>'.$min.'
'; - } - if (defined($max) && $max =~ /^(\d+\.\d+|\d+|\.\d+)$/) { - push(@queries,'('.$field.'<'.$max.')'); - $pretty_search_string.=$font.$field.'<'.$max.'
'; + if ($env{'form.area'} eq 'portfolio') { + # + # Added metadata fields + for (my $i=0; $i<$env{'form.numaddedfields'} ; $i++) { + my $field = $env{'form.addedfield_'.$i}; + $field =~ s/^\s*(\S*)\s*$/$1/; + $field =~ s/\W/_/g; + $field =~ tr/A-Z/a-z/; + if ($field ne '') { + my $value = $env{'form.addedvalues_'.$i}; + if ($value ne '') { + $value =~ s/'/''/g; #' stupid emacs + my ($error,$query) = + &process_phrase_input($value,0,'pf.value'); + if (!defined($error)) { + push(@queries,"pf.field = '$field' AND $query"); + $pretty_search_string .= + $font.$field.': '. + $env{'form.addedvalues_'.$i}.'
'; + } + } else { + push(@queries,"pf.field = '$field' AND pf.value IS NULL"); + } + } + } + } else { + # + # Statistics + foreach my $field (@StatsFields,@EvalFields) { + my ($min,$max); + if (exists($env{'form.'.$field.'_min'}) && + $env{'form.'.$field.'_min'} ne '') { + $min = $env{'form.'.$field.'_min'}; + } + if (exists($env{'form.'.$field.'_max'}) && + $env{'form.'.$field.'_max'} ne '') { + $max = $env{'form.'.$field.'_max'}; + } + next if (! defined($max) && ! defined($min)); + if (defined($min) && defined($max)) { + ($min,$max) = sort {$a <=>$b} ($min,$max); + } + if (defined($min) && $min =~ /^(\d+\.\d+|\d+|\.\d+)$/) { + push(@queries,'('.$field.'>'.$min.')'); + $pretty_search_string.=$font.$field.'>'.$min.'
'; + } + if (defined($max) && $max =~ /^(\d+\.\d+|\d+|\.\d+)$/) { + push(@queries,'('.$field.'<'.$max.')'); + $pretty_search_string.=$font.$field.'<'.$max.'
'; + } } } # @@ -1516,7 +1695,11 @@ sub parse_advanced_search { } # if (@queries) { - $query="SELECT * FROM metadata WHERE (".join(") AND (",@queries).')'; + if ($env{'form.area'} eq 'portfolio') { + $query ="SELECT pm.*,pa.keynum,pa.scope FROM portfolio_metadata pm, portfolio_access pa, portfolio_addedfields pf WHERE (pm.url = pa.url AND pf.url = pm.url AND (pa.start < UTC_TIMESTAMP() AND (pa.end IS NULL OR pa.end > UTC_TIMESTAMP())) AND (".join(') AND (',@queries).'))'; + } else { + $query="SELECT * FROM metadata WHERE (".join(") AND (",@queries).')'; + } } elsif ($customquery) { $query = ''; } @@ -1540,21 +1723,19 @@ sub parse_domain_restrictions { $domain_hash{$_}++; } if ($domain_hash{'any'}) { - $pretty_domains_string = "In all LON-CAPA domains."; + $pretty_domains_string = &mt("in all LON-CAPA domains."); } else { if (@allowed_domains > 1) { - $pretty_domains_string = "In LON-CAPA domains:"; + $pretty_domains_string = &mt("in LON-CAPA domains:"); } else { - $pretty_domains_string = "In LON-CAPA domain "; + $pretty_domains_string = &mt("in LON-CAPA domain "); } foreach (sort @allowed_domains) { $pretty_domains_string .= "".$_." "; } - foreach (keys(%Apache::lonnet::libserv)) { - if (exists($domain_hash{$Apache::lonnet::hostdom{$_}})) { - push @$libraries_to_query,$_; - } - } + my %servers = &Apache::lonnet::get_unique_servers(\@allowed_domains, + 'library'); + $libraries_to_query = [keys(%servers)]; } return ($libraries_to_query, $pretty_domains_string); @@ -1578,7 +1759,7 @@ sub parse_basic_search { # # Clean up fields for safety for my $field ('basicexp') { - $env{"form.$field"}=~s/[^\w\s\'\"\!\(\)\-]//g; + $env{"form.$field"}=~s/[^\w\s\'\"\!\(\)\-\*]//g; } foreach ('mode','form','element') { # is this required? Hmmm. @@ -1596,10 +1777,13 @@ sub parse_basic_search { } my $pretty_search_string=$search_string; my @Queries; - my $searchfield = 'concat_ws(" ",'.join(',', - ('title','author','subject', - 'notes','abstract','keywords') - ).')'; + my @fields = ('title','author','subject','notes','abstract','keywords'); + my $searchfield; + if ($env{'form.area'} eq 'portfolio') { + $searchfield = 'concat_ws(" ",pm.'.join(',pm.',@fields).')'; + } else { + $searchfield = 'concat_ws(" ",'.join(',',@fields).')'; + } my ($error,$SQLQuery) = &process_phrase_input($search_string, $env{'form.related'}, $searchfield); @@ -1612,14 +1796,22 @@ sub parse_basic_search { #foreach my $q (@Queries) { # &Apache::lonnet::logthis(' '.$q); #} - my $final_query = 'SELECT * FROM metadata WHERE '.join(" AND ",@Queries); + my $final_query; + if ($env{'form.area'} eq 'portfolio') { + $final_query = 'SELECT pm.*,pa.keynum,pa.scope FROM portfolio_metadata pm, portfolio_access pa WHERE (pm.url = pa.url AND (pa.start < UTC_TIMESTAMP() AND (pa.end IS NULL OR pa.end > UTC_TIMESTAMP())) AND '.join(" AND ",@Queries).')'; + } else { + $final_query = 'SELECT * FROM metadata WHERE '.join(" AND ",@Queries); + } # + if ($env{'form.related'}) { + $pretty_search_string.=' '.&mt('(including related words)'); + } if (defined($pretty_domains_string) && $pretty_domains_string ne '') { $pretty_search_string .= ' '.$pretty_domains_string; } $pretty_search_string .= "
\n"; $pretty_search_string =~ s:^
and ::; - #&Apache::lonnet::logthis('simple search final query = '.$/.$final_query); + &Apache::lonnet::logthis('simple search final query = '.$/.$final_query); return ($final_query,$pretty_search_string, $libraries_to_query); } @@ -1722,7 +1914,7 @@ sub process_phrase_input { $item[1]; } term: - /[\w\Q:!@#$%^&*()+_=|{}<>,.;\\\/?\E]+/ { + /[\w\Q:!@#$%^&*()+_=|{}<>,.;\\\/?\E\-]+/ { $item[1]; } ENDGRAMMAR @@ -1982,6 +2174,10 @@ sub copyright_check { ($env{'user.domain'} ne $resdom)) { return 0; } + # Check for custom rights + if ($Metadata->{'copyright'} eq 'custom') { + return &Apache::lonnet::customaccess('bre',$Metadata->{'url'}); + } return 1; } @@ -2009,9 +2205,13 @@ sub ensure_db_and_table { ## Sanity check the table id. ## if (! defined($table) || $table eq '' || $table =~ /\D/ ) { - $r->print("Unable to retrieve search results. ". - "Unable to determine the table results were stored in. ". - &Apache::loncommon::end_page()); + $r->print(&Apache::loncommon::start_page(&mt('Error')) +. '

table: |'.$table.'|

' # SB + .'

' + .&mt('Unable to retrieve search results. ' + .'Unable to determine the table results were saved in.') + .&Apache::loncommon::end_page() + ); return undef; } ## @@ -2020,7 +2220,7 @@ sub ensure_db_and_table { my $connection_result = &Apache::lonmysql::connect_to_db(); if (!defined($connection_result)) { $r->print("Unable to connect to the MySQL database where your results". - " are stored.". + " are saved.". &Apache::loncommon::end_page()); &Apache::lonnet::logthis("lonsearchcat: unable to get lonmysql to". " connect to database."); @@ -2093,6 +2293,7 @@ sub print_sort_form { } my $js =< +// END - my $start_page = &Apache::loncommon::start_page('Results',$js, - {'only_body' => 1}); + my $start_page = &Apache::loncommon::start_page('Results',$js); my $breadcrumbs= &Apache::lonhtmlcommon::breadcrumbs('Searching','Searching', - $env{'form.catalogmode'} ne 'groupsearch'); + $env{'form.catalogmode'} ne 'import'); my $result = < - +

+ + END #

Sort Results

@@ -2128,14 +2330,11 @@ END # } # $result.="\n"; my $revise = &revise_button(); - $result.=< -There are $total_results matches to your query. $revise -

-Search:$pretty_query_string -

- -END + $result.='

' + .&mt('There are [_1] matches to your query.',$total_results) + .' '.$revise.'

' + .'

'.&mt('Search: ').$pretty_query_string + .'

'; $r->print($result.&Apache::loncommon::end_page()); return; } @@ -2172,7 +2371,7 @@ my @Fullindicies; Creates the table of search results by calling lonmysql. Stores the table id in $env{'form.table'} -Inputs: none. +Inputs: search area - either res or portfolio Returns: the identifier of the table on success, undef on error. @@ -2181,8 +2380,9 @@ Returns: the identifier of the table on ###################################################################### ###################################################################### sub set_up_table_structure { + my ($tabletype) = @_; my ($datatypes,$fullindicies) = - &LONCAPA::lonmetadata::describe_metadata_storage(); + &LONCAPA::lonmetadata::describe_metadata_storage($tabletype); # Copy the table description before modifying it... @Datatypes = @{$datatypes}; unshift(@Datatypes,{name => 'id', @@ -2195,7 +2395,12 @@ sub set_up_table_structure { } sub create_results_table { - &set_up_table_structure(); + my ($area) = @_; + if ($area eq 'portfolio') { + &set_up_table_structure('portfolio_search'); + } else { + &set_up_table_structure('metadata'); + } my $table = &Apache::lonmysql::create_table ( { columns => \@Datatypes, FULLTEXT => [{'columns' => \@Fullindicies},], @@ -2239,16 +2444,28 @@ Returns: Nothing. sub update_count_status { my ($r,$text) = @_; $text =~ s/\'/\\\'/g; - $r->print - ("\n"); + $r->print(< +// + +SCRIPT + $r->rflush(); } sub update_status { my ($r,$text) = @_; $text =~ s/\'/\\\'/g; - $r->print - ("\n"); + $r->print(< +// + +SCRIPT + $r->rflush(); } @@ -2275,9 +2492,14 @@ sub update_seconds { my ($r) = @_; my $time = &time_left(); if (($last_time-$time) > 0) { - $r->print("\n"); + $r->print(< +// + +SCRIPT + $r->rflush(); } $last_time = $time; @@ -2301,14 +2523,15 @@ Returns: html string for a 'revise searc ###################################################################### ###################################################################### sub revise_button { + my $revisetext = &mt('Revise search'); my $revise_phase = 'disp_basic'; $revise_phase = 'disp_adv' if ($env{'form.searchmode'} eq 'advanced'); my $newloc = '/adm/searchcat'. '?persistent_db_id='.$env{'form.persistent_db_id'}. - '&cleargroupsort=1'. - '&phase='.$revise_phase; - my $result = qq{ }; + '&cleargroupsort=1'. + '&phase='.$revise_phase; + my $result = qq{ }; return $result; } @@ -2327,22 +2550,23 @@ results into MySQL. ###################################################################### ###################################################################### sub run_search { - my ($r,$query,$customquery,$customshow,$serverlist,$pretty_string) = @_; - + my ($r,$query,$customquery,$customshow,$serverlist, + $pretty_string,$area) = @_; + my $tabletype = 'metadata'; + if ($area eq 'portfolio') { + $tabletype = 'portfolio_search'; + } my $connection = $r->connection; # # Print run_search header # - my $start_page = &Apache::loncommon::start_page('Search Status',undef, - {'only_body' => 1}); + my $start_page = &Apache::loncommon::start_page('Search Status',undef); my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Searching','Searching', - $env{'form.catalogmode'} ne 'groupsearch'); + $env{'form.catalogmode'} ne 'import'); $r->print(< - END # Remove leading and trailing
$pretty_string =~ s:^\s*
::i; @@ -2353,7 +2577,7 @@ END pop(@Lines); } if (@Lines > 2) { - $pretty_string = join '
',(@Lines[0..2],'....
'); + $pretty_string = join '
',(@Lines[0..2],'...
'); } $r->print(&mt("Search: [_1]",$pretty_string)); $r->rflush(); @@ -2367,14 +2591,15 @@ END @Servers_to_contact = ($serverlist); } } else { - @Servers_to_contact = sort(keys(%Apache::lonnet::libserv)); + my %all_library_servers = &Apache::lonnet::unique_library(); + @Servers_to_contact = sort(keys(%all_library_servers)); } my %Server_status; # # Check on the mysql table we will use to store results. my $table =$env{'form.table'}; if (! defined($table) || $table eq '' || $table =~ /\D/ ) { - $r->print("Unable to determine table id to store search results in.". + $r->print("Unable to determine table id to save search results in.". "The search has been aborted.". &Apache::loncommon::end_page()); return; @@ -2403,21 +2628,26 @@ END ## ## Prepare for the big loop. my $hitcountsum; + my %matches; my $server; my $status; my $revise = &revise_button(); - $r->print(< -StatusTotal MatchesTime Remaining - - - - -$revise - - - -END + $r->print('
'."\n". + ''."\n". + '' + .'' + .'' + .&Apache::loncommon::end_data_table_header_row() + .&Apache::loncommon::start_data_table_row() + .'' + .'' + .'' + .&Apache::loncommon::end_data_table_row() + .&Apache::loncommon::end_data_table() + .'
'."\n". + &Apache::loncommon::start_data_table()); + $r->print(&Apache::loncommon::start_data_table_header_row() + .''.&mt('Status').''.&mt('Total Matches').''.&mt('Time Remaining').' '.$revise.'
'); $r->rflush(); &reset_timing(); &update_seconds($r); @@ -2457,7 +2687,7 @@ END delete ($Server_status{$server}); next; } - $status=~s|/||g; + $status=~s|/||g; my $datafile=$r->dir_config('lonDaemons').'/tmp/'.$status; if (-e $datafile && ! -e "$datafile.end") { &update_status($r,&mt('Receiving results from [_1]',$server)); @@ -2486,14 +2716,18 @@ END next if (! $result); # # Parse the result. - my %Fields = &parse_raw_result($result,$server); + my %Fields = &parse_raw_result($result,$server,$tabletype); $Fields{'hostname'} = $server; # - # Skip if external and we did not want that - next if ((! $env{'form.inclext'}) && ($Fields{'url'}=~/^\/ext\//)); # Skip based on copyright next if (! ©right_check(\%Fields)); + if ($area eq 'portfolio') { + next if (defined($matches{$Fields{'url'}})); + # Skip if inaccessible + next if (!&Apache::lonnet::portfolio_access($Fields{'url'})); + $matches{$Fields{'url'}} = 1; + } # # Store the result in the mysql database my $result = &Apache::lonmysql::store_row($table,\%Fields); @@ -2518,7 +2752,7 @@ END last if ($connection->aborted()); &update_seconds($r); } - &update_status($r,&mt('Search Complete [_1]',$server)); + &update_status($r,&mt('Search Complete on Server [_1]',$server)); &update_seconds($r); # &Apache::lonmysql::disconnect_from_db(); # This is unneccessary @@ -2527,12 +2761,12 @@ END # results to get, so let the client know the top frame needs to be # loaded from /adm/searchcat $r->print(&Apache::loncommon::end_page()); -# if ($env{'form.catalogmode'} ne 'groupsearch') { - $r->print(""); +# if ($env{'form.catalogmode'} ne 'import') { + $r->print(< +window.location='/adm/searchcat?phase=sort&persistent_db_id=$env{'form.persistent_db_id'}'; + +SCRIPT # } return; } @@ -2555,15 +2789,15 @@ sub prev_next_buttons { return '' if ($show eq 'all'); # No links if you get them all at once. # # Create buttons - my $buttons = ''; - $buttons .= ' 'x3; - $buttons .= '' + .'' + .' ' + .'' + .' ' + .'' + .'

'; } ###################################################################### @@ -2580,7 +2814,7 @@ Prints the results out for selection and ###################################################################### ###################################################################### sub display_results { - my ($r,$importbutton,$closebutton,$diropendb) = @_; + my ($r,$importbutton,$closebutton,$diropendb,$area) = @_; my $connection = $r->connection; $r->print(&search_results_header($importbutton,$closebutton)); ## @@ -2588,24 +2822,29 @@ sub display_results { ## my $viewfunction = $Views{$env{'form.viewselect'}}; if (!defined($viewfunction)) { - $r->print("Internal Error - Bad view selected.\n"); + $r->print('

' + .&mt('Internal Error - Bad view selected.') + .'

'."\n"); $r->rflush(); return; } ## ## $checkbox_num is a count of the number of checkboxes output on the - ## page this is used only during catalogmode=groupsearch. + ## page this is used only during catalogmode=import. my $checkbox_num = 0; ## ## Get the catalog controls setup ## my $action = "/adm/searchcat?phase=results"; ## - ## Deal with groupsearch by opening the groupsearch db file. - if ($env{'form.catalogmode'} eq 'groupsearch') { + ## Deal with import by opening the import db file. + if ($env{'form.catalogmode'} eq 'import') { if (! tie(%groupsearch_db,'GDBM_File',$diropendb, &GDBM_WRCREAT(),0640)) { - $r->print('Unable to store import results.'. + $r->print('

'. + &mt('Unable to save import results.'). + '

'. + ''. &Apache::loncommon::end_page()); $r->rflush(); return; @@ -2619,7 +2858,10 @@ sub display_results { ## Get the number of results my $total_results = &Apache::lonmysql::number_of_rows($table); if (! defined($total_results)) { - $r->print("A MySQL error has occurred.". + $r->print('

'. + &mt('A MySQL error has occurred.'). + '

'. + ''. &Apache::loncommon::end_page()); &Apache::lonnet::logthis("lonmysql was unable to determine the number". " of rows in table ".$table); @@ -2650,7 +2892,8 @@ sub display_results { $r->print(&hidden_field('table'). &hidden_field('phase'). &hidden_field('persistent_db_id'). - &hidden_field('start') + &hidden_field('start'). + &hidden_field('area') ); # # Build sorting selector @@ -2671,6 +2914,16 @@ sub display_results { {key =>'lowestgradelevel'}, {key =>'highestgradelevel'}, {key =>'standards',desc=>'Standards'}, + ); + if ($area eq 'portfolio') { + push(@fields, + ( + {key => 'scope'}, + {key => 'keynum'}, + )); + } else { + push(@fields, + ( {key =>'count',desc=>'Number of accesses'}, {key =>'stdno',desc=>'Students Attempting'}, {key =>'avetries',desc=>'Average Number of Tries'}, @@ -2681,7 +2934,8 @@ sub display_results { {key =>'correct',desc=>'Evaluation: Material is Correct'}, {key =>'helpful',desc=>'Evaluation: Material is Helpful'}, {key =>'depth',desc=>'Evaluation: Material has Depth'}, - ); + )); + } my %fieldnames = &Apache::lonmeta::fieldnames(); my @field_order; foreach my $field_data (@fields) { @@ -2698,7 +2952,13 @@ sub display_results { my %sort_fields = map {$_->{'key'},$_->{'desc'}} @fields; $sort_fields{'select_form_order'} = \@field_order; $env{'form.sortorder'} = 'desc' if (! exists($env{'form.sortorder'})); - $env{'form.sortfield'} = 'count' if (! exists($env{'form.sortfield'})); + if (! exists($env{'form.sortfield'})) { + if ($area eq 'portfolio') { + $env{'form.sortfield'} = 'owner'; + } else { + $env{'form.sortfield'} = 'count'; + } + } if (! exists($env{'form.sortorder'})) { if ($env{'form.sortfield'}=~/^(count|stdno|disc|clear|technical|correct|helpful)$/) { $env{'form.sortorder'}='desc'; @@ -2706,37 +2966,40 @@ sub display_results { $env{'form.sortorder'}='asc'; } } - my $sortform = &mt('Sort by [_1] [_2]', - &Apache::loncommon::select_form($env{'form.sortfield'}, + my $sortform = '' + .&mt('Sort by:').' ' + .&Apache::loncommon::select_form($env{'form.sortfield'}, 'sortfield', - %sort_fields), - &Apache::loncommon::select_form($env{'form.sortorder'}, + \%sort_fields) + .' ' + .&Apache::loncommon::select_form($env{'form.sortorder'}, 'sortorder', - (asc =>&mt('Ascending'), + {asc =>&mt('Ascending'), desc=>&mt('Descending') - )) - ); + }) + .''; ## - ## Output links (if necessary) for 'prev' and 'next' pages. - $r->print - ('
'. - ''.$sortform.''. - ''. - &prev_next_buttons($min,$env{'form.show'},$total_results). - ''. - &viewoptions().'
' - ); + ## Display links for 'prev' and 'next' pages (if necessary) and Display Options + $r->print('
'."\n" + .''.&mt('Display Options').''."\n" + .$sortform + .' ' + .&viewoptions() + .'
' + .&prev_next_buttons($min,$env{'form.show'},$total_results) + ); + if ($total_results == 0) { $r->print(''. - '

'.&mt('There are currently no results').'.

'. + '

'.&mt('There are currently no results.').'

'. "". &Apache::loncommon::end_page()); return; } else { - $r->print('
'. + $r->print('
'. mt('Results [_1] to [_2] out of [_3]', $min,$max,$total_results). - "
\n"); + "\n"); } ## ## Get results from MySQL table @@ -2762,13 +3025,18 @@ sub display_results { my @Results = &Apache::lonmysql::get_rows($table,$sort_command); ## ## Loop through the results and output them. + my $tabletype = 'metadata'; + if ($area eq 'portfolio') { + $tabletype = 'portfolio_search'; + } + $r->print(&Apache::loncommon::start_data_table()); foreach my $row (@Results) { if ($connection->aborted()) { &cleanup(); return; } - my %Fields = %{&parse_row(@$row)}; - my $output="

\n"; + my %Fields = %{&parse_row($tabletype,@$row)}; + my $output; if (! defined($Fields{'title'}) || $Fields{'title'} eq '') { $Fields{'title'} = 'Untitled'; } @@ -2777,21 +3045,27 @@ sub display_results { # Render the result into html $output.= &$viewfunction($prefix,%Fields); # Print them out as they come in. - $r->print($output); + $r->print(&Apache::loncommon::start_data_table_row() + .'' + .$output + .'' + .&Apache::loncommon::end_data_table_row() + ); $r->rflush(); } + $r->print(&Apache::loncommon::end_data_table()); if (@Results < 1) { - $r->print(&mt("There were no results matching your query")); + $r->print('

' + .&mt('There were no results matching your query.') + .'

'); } else { - $r->print - ('
'. - &prev_next_buttons($min,$env{'form.show'},$total_results, + $r->print( + &prev_next_buttons($min,$env{'form.show'},$total_results, "table=".$env{'form.table'}. - "&phase=results". - "&persistent_db_id=". + "&phase=results". + "&persistent_db_id=". $env{'form.persistent_db_id'}) - ."
\n" - ); + ); } $r->print("".&Apache::loncommon::end_page()); $r->rflush(); @@ -2820,18 +3094,18 @@ sub catalogmode_output { $title=~ s/\'/\\\'/g; if ($env{'form.catalogmode'} eq 'interactive') { $output.=< + END } - } elsif ($env{'form.catalogmode'} eq 'groupsearch') { + } elsif ($env{'form.catalogmode'} eq 'import') { $groupsearch_db{"pre_${fnum}_link"}=$url; $groupsearch_db{"pre_${fnum}_title"}=$title; $output.=< - + END } @@ -2851,10 +3125,10 @@ Parse a row returned from the database. ###################################################################### ###################################################################### sub parse_row { - my @Row = @_; + my ($tabletype,@Row) = @_; my %Fields; if (! scalar(@Datatypes)) { - &set_up_table_structure(); + &set_up_table_structure($tabletype); } for (my $i=0;$i<=$#Row;$i++) { $Fields{$Datatypes[$i]->{'name'}}=&unescape($Row[$i]); @@ -2890,12 +3164,13 @@ The 'title' field is set to "Untitled" i ########################################################### ########################################################### sub parse_raw_result { - my ($result,$hostname) = @_; + my ($result,$hostname,$tabletype) = @_; # conclude from self to others regarding fields my %Fields=&LONCAPA::lonmetadata::metadata_col_to_hash - (map { + ($tabletype, + map { &unescape($_); - } (split(/\,/,$result)) ); + } (split(/\,/,$result)) ); return %Fields; } @@ -2964,7 +3239,7 @@ The following environment variables are =item 'form.catalogmode' -Checked for 'interactive' and 'groupsearch'. +Checked for 'interactive' and 'import'. =item 'form.mode' @@ -2999,6 +3274,7 @@ sub search_results_header { if (! exists($env{'form.mode'}) || $env{'form.mode'} ne 'edit') { $js.=< +// SCRIPT } elsif ($env{'form.mode'} eq 'edit') { @@ -3038,6 +3315,7 @@ END $js.=< +// SCRIPT } } - $js.=< +SCRIPT + + # HTML-Markup for 'Set a link for this resource to wishlist' + # this is written via JavaScript document.write (function set_wishlistlink) + # it is split into 3 parts and the inputfields for title and path are left out + # these fields are inserted later to set the values for title and path + # automatically via JavaScript (document.title and location.pathname) + my $start_page_wishlistlink = + &Apache::loncommon::start_page('Set link to wishlist',undef, + {'only_body' => 1, + 'js_ready' => 1, + 'bgcolor' => '#FFFFFF',}); + + my $warningLink = &mt('You must insert a title!'); + + my $in_page_wishlistlink1 = '

'.&mt('Set a link to wishlist').'

'. + '
'. + &Apache::lonhtmlcommon::start_pick_box(). + &Apache::lonhtmlcommon::row_title(&mt('Link Title')); + + my $in_page_wishlistlink2 = &Apache::lonhtmlcommon::row_closure(). + &Apache::lonhtmlcommon::row_title(&mt('Path')); + + my $in_page_wishlistlink3 = &Apache::lonhtmlcommon::row_closure(). + &Apache::lonhtmlcommon::row_title(&mt('Note')). + ''. + &Apache::lonhtmlcommon::row_closure(1). + &Apache::lonhtmlcommon::end_pick_box(). + '

'. + ''. + ''. + ''. + '
'; + + # remove all \n for inserting on javascript document.write + $in_page_wishlistlink1 =~ s/\n//g; + $in_page_wishlistlink2 =~ s/\n//g; + $in_page_wishlistlink3 =~ s/\n//g; + + my $end_page_wishlistlink = + &Apache::loncommon::end_page({'js_ready' => 1}); + + # Add JavaScript-function to set link for a ressource to wishlist + $js.=< +// ' + +'function newlinksubmit(){' + +'var title = document.getElementsByName("title")[0].value;' + +'if (!title) {' + +'alert("$warningLink");' + +'return false;}' + +'return true;}' + +'<\/scr'+'ipt>' + +'$in_page_wishlistlink1' + +'' + +'$in_page_wishlistlink2' + +'' + +'$in_page_wishlistlink3' + +'$end_page_wishlistlink' ); + wishlistlink.document.close(); +} + +// ]]> SCRIPT @@ -3086,30 +3447,17 @@ SCRIPT {'only_body' =>1}); my $result=< - +
$importbutton END return $result; } -###################################################################### -###################################################################### -sub search_status_header { - my $start_page = &Apache::loncommon::start_page('Search Status',undef, - {'only_body' => 1}); - return <Search Status -Sending search request to LON-CAPA servers.
-ENDSTATUS -} - sub results_link { - my $basic_link = "/adm/searchcat?"."&table=".$env{'form.table'}. - "&persistent_db_id=".$env{'form.persistent_db_id'}; - my $results_link = $basic_link."&phase=results". - "&pause=1"."&start=1"; + my $basic_link = "/adm/searchcat?"."&table=".$env{'form.table'}. + "&persistent_db_id=".$env{'form.persistent_db_id'}; + my $results_link = $basic_link."&phase=results". + "&pause=1"."&start=1"; return $results_link; } @@ -3117,14 +3465,16 @@ sub results_link { ###################################################################### sub print_frames_interface { my $r = shift; - my $basic_link = "/adm/searchcat?"."&table=".$env{'form.table'}. - "&persistent_db_id=".$env{'form.persistent_db_id'}; - my $run_search_link = $basic_link."&phase=run_search"; + my $basic_link = "/adm/searchcat?"."&table=".$env{'form.table'}. + "&persistent_db_id=".$env{'form.persistent_db_id'}; + my $run_search_link = $basic_link."&phase=run_search"; my $results_link = &results_link(); my $js = < +// JS @@ -3209,11 +3559,15 @@ sub detailed_citation_view { my ($prefix,%values) = @_; my $result; my $jumpurl=$values{'url'}; - $jumpurl=~s/^\/ext\//http\:\/\//; + $jumpurl=~s|^/ext/|http://|; $result .= ''.$prefix. - ''.' '. - ''.$values{'title'}."\n"; + ''.' '. + ''.$values{'title'}."\n". + ''. + ''; $result .= "

\n"; $result .= ''.$values{'author'}.','. ' '.$values{'owner'}.'
'; @@ -3277,25 +3631,18 @@ sub detailed_citation_view { next if (! exists($values{$field->{'name'}}) || $values{$field->{'name'}} eq ''); if (exists($field->{'type'}) && $field->{'type'} eq 'list') { - $result .= ''.&mt($field->{'translate'}).'

    '; + $result .= ''.&mt($field->{'translate'}).''; foreach my $item (split(',',$values{$field->{'name'}})){ - $result .= '
  • '. - ''.$item.'
  • '; + $item = &Apache::lonnet::clutter($item); + $result .= '
    '.&display_url($item,1).'
    '; } - $result .= '
'; } elsif (exists($field->{'format'}) && $field->{'format'} ne ''){ $result.= &mt($field->{'translate'}, sprintf($field->{'format'}, $values{$field->{'name'}}))."
\n"; } else { if ($field->{'special'} eq 'url link') { - $result.= - &mt($field->{'translate'}, - ''. - $values{$field->{'name'}}. - ''); + $result .= '
'.&display_url($jumpurl,1).'
'; } else { $result.= &mt($field->{'translate'}, $values{$field->{'name'}}); @@ -3310,17 +3657,14 @@ sub detailed_citation_view { if (exists($values{'shortabstract'}) && $values{'shortabstract'} ne '') { $result .= '

'.$values{'shortabstract'}.'

'; } - $result .= '
'."\n"; return $result; } sub detailed_citation_preview { my ($prefix,%values)=@_; - return '
'. - &detailed_citation_view($prefix,%values). + return &detailed_citation_view($prefix,%values). ''. - &Apache::lonindexer::showpreview($values{'url'}). - '

'; + &Apache::lonindexer::showpreview($values{'url'}); } @@ -3337,7 +3681,7 @@ sub detailed_citation_preview { sub summary_view { my ($prefix,%values) = @_; my $icon=&Apache::loncommon::icon($values{'url'}); - my $result=qq{$prefix}; + my $result=qq{$prefix}; if (exists($env{'form.sortfield'}) && $env{'form.sortfield'} !~ /^(default| author| @@ -3351,27 +3695,32 @@ sub summary_view { $result .= ' '.$tmp.' '; } my $jumpurl=$values{'url'}; - $jumpurl=~s/^\/ext\//http\:\/\//; + $jumpurl=~s|^/ext/|http://|; + my $link = '
'.&display_url($jumpurl,1).'
'; + my $titleWL = &mt('Set link to wishlist'); $result.=<$values{'title'}
+$values{'title'} + + set wishlistlink + +
+$link
$values{'author'}, $values{'owner'} -- $values{'lastrevisiondate'}
$values{'copyrighttag'}
$values{'extrashow'} -

-
END return $result; } sub summary_preview { my ($prefix,%values)=@_; - return '
'. - &summary_view($prefix,%values). + return &summary_view($prefix,%values). ''. - &Apache::lonindexer::showpreview($values{'url'}). - '

'; + &Apache::lonindexer::showpreview($values{'url'}); } ###################################################################### @@ -3388,22 +3737,49 @@ sub summary_preview { sub compact_view { my ($prefix,%values) = @_; my $jumpurl=$values{'url'}; - $jumpurl=~s/^\/ext\//http\:\/\//; + $jumpurl=~s|^/ext/|http://|; + my $link = &display_url($jumpurl,1); + my $result = - $prefix.''; + $prefix.''; if (exists($env{'form.sortfield'}) && $env{'form.sortfield'} !~ /^(default|author|url|title)$/) { my $tmp = $values{$env{'form.sortfield'}}; if (! defined($tmp)) { $tmp = 'undefined'; } $result .= ' '.$tmp.' '; } - $result.=' '. - $values{'title'}.''.(' 'x2). - ''.$values{'author'}.' ('.$values{'domain'}.')
'; + $jumpurl = &HTML::Entities::encode($jumpurl,'<>&"'); + $result.=' '. + ''. + &HTML::Entities::encode($values{'title'},'<>&"').' '. + ''. + ''. + ''. + $link.' '.$values{'author'}.' ('.$values{'domain'}.')'; return $result; } +sub display_url { + my ($url,$skiplast) = @_; + my $link; + if ($url=~m|^/ext/|) { + $url=~s|^/ext/|http://|; + $link=''.$url.''; + } elsif ($url=~m{^(http://|/uploaded/)}) { + $link=''.$url.''; + } else { + $link=&Apache::lonhtmlcommon::crumbs( + $url, + 'preview', + '', + (($env{'form.catalogmode'} eq 'import')?'parent.statusframe.document.forms.statusform':''), + $skiplast).' '; + } + return $link; +} ###################################################################### ###################################################################### @@ -3421,14 +3797,21 @@ sub fielded_format_view { my $icon=&Apache::loncommon::icon($values{'url'}); my %Translated = &Apache::lonmeta::fieldnames(); my $jumpurl=$values{'url'}; - $jumpurl=~s/^\/ext\//http\:\/\//; + $jumpurl=~s|^/ext/|http://|; + my $titleWL = ('Set link to wishlist'); my $result=< +$prefix
URL:
-
$values{'url'}
+
$values{'url'} + + set wishlistlink + +
END foreach my $field ('title','author','domain','subject','keywords','notes', 'mimetag','language','creationdate','lastrevisiondate', @@ -3450,7 +3833,6 @@ END } $result .= "
\n"; $result .= $values{'extrashow'}; - $result .= '
'."\n"; return $result; } @@ -3524,7 +3906,6 @@ $prefix $xml $values{'extrashow'} -
END return $result; } @@ -3564,9 +3945,12 @@ sub output_unparsed_phrase_error { my ($r,$closebutton,$parms,$hidden_fields,$field)=@_; my $errorstring; if ($field eq 'basicexp') { - $errorstring = &mt('Unable to understand the search phrase [_1]. Please modify your search.',$env{'form.basicexp'}); + $errorstring = &mt('Unable to understand the search phrase [_1]. Please modify your search.' + ,''.$env{'form.basicexp'}.''); } else { - $errorstring = &mt('Unable to understand the search phrase [_1]:[_2].',$field,$env{'form.'.$field}); + $errorstring = &mt('Unable to understand the search phrase [_1]: [_2]' + ,''.$field.'' + ,$env{'form.'.$field}); } my $heading = &mt('Unparsed Field'); my $revise = &mt('Revise search request'); @@ -3580,11 +3964,11 @@ $hidden_fields $closebutton

$heading

-

+

$errorstring

-$revise +$revise

$end_page ENDPAGE @@ -3612,23 +3996,32 @@ $parms is extra information to include i ###################################################################### sub output_blank_field_error { my ($r,$closebutton,$parms,$hidden_fields)=@_; - my $errormsg = &mt('You did not fill in enough information for the search to be started. You need to fill in relevant fields on the search page in order for a query to be processed.'); + my $errormsg = &mt('You did not fill in enough information for the search to be started. You need to fill in relevant fields on the search page in order for a query to be processed.'); my $revise = &mt('Revise Search Request'); - my $heading = &mt('Unactionable Search Queary'); + my $heading = &mt('Unactionable Search Query'); my $start_page = &Apache::loncommon::start_page('Search'); my $end_page = &Apache::loncommon::end_page(); + if ($closebutton) { + $closebutton = '

'.$closebutton.'


'; + } else { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'', + text=>$heading,}); + $start_page .= &Apache::lonhtmlcommon::breadcrumbs(); + } + $r->print(< $hidden_fields $closebutton -
+

$heading

-

+

$errormsg

-$revise  +$revise

$end_page ENDPAGE @@ -3659,16 +4052,18 @@ sub output_date_error { # make query information persistent to allow for subsequent revision my $start_page = &Apache::loncommon::start_page('Search'); my $end_page = &Apache::loncommon::end_page(); + my $heading = &mt('Error'); $r->print(< $hidden_fields +onclick='this.form.submit();' /> $closebutton +
-

Error

-

+

$heading

+

$message

$end_page 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.