--- loncom/interface/lonsearchcat.pm 2014/01/14 18:54:56 1.341 +++ loncom/interface/lonsearchcat.pm 2025/03/19 15:44:44 1.364 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Search Catalog # -# $Id: lonsearchcat.pm,v 1.341 2014/01/14 18:54:56 bisitz Exp $ +# $Id: lonsearchcat.pm,v 1.364 2025/03/19 15:44:44 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -78,6 +78,7 @@ use Apache::lonnavmaps; use Apache::lonindexer(); use Apache::lonwishlist(); use LONCAPA; +use Time::HiRes qw(sleep); ###################################################################### ###################################################################### @@ -143,7 +144,7 @@ sub handler { ## this once, so the pause indicator is deleted ## if (exists($env{'form.pause'})) { - sleep(1); + sleep(0.1); delete($env{'form.pause'}); } ## @@ -169,22 +170,46 @@ sub handler { ## &Apache::lonhtmlcommon::clear_breadcrumbs(); - my @allowed_searches = ('portfolio'); - if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'})) { + my $crumb_text; + my @allowed_searches; + if ($env{'form.catalogmode'} eq 'import') { + $env{'form.area'} = 'res'; + $crumb_text = 'Content Library Search'; + } else { + push(@allowed_searches,'portfolio'); + } + if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'}) eq 'F') { push(@allowed_searches,'res'); - } - my $crumb_text = 'Portfolio Search'; + } else { + unless ($env{'form.catalogmode'} eq 'import') { + $env{'form.area'} = 'portfolio'; + $crumb_text = 'Portfolio Search'; + } + } if (@allowed_searches ==2) { - $crumb_text = 'Portfolio and Catalog Search'; + unless (($env{'form.area'} eq 'portfolio') || ($env{'form.area'} eq 'res')) { + delete($env{'form.area'}); + } + $crumb_text = 'Portfolio and Content Library Search'; + } + my $target = '_top'; + if ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) || + (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) { + if ($env{'form.phase'} =~ /^(sort|run_search)$/) { + $target = '_parent'; + } else { + $target = '_self'; + } } &Apache::lonhtmlcommon::add_breadcrumb ({href=>'/adm/searchcat?'. &Apache::loncommon::inhibit_menu_check(). '&catalogmode='.$env{'form.catalogmode'}. '&launch='.$env{'form.launch'}. - '&mode='.$env{'form.mode'}, + '&mode='.$env{'form.mode'}. + '&area='.$env{'form.area'}, text=>"$crumb_text", - target=>'_top', + target=>$target, bug=>'Searching',}); # if ($env{'form.phase'} !~ m/(basic|adv|course)_search/) { @@ -193,7 +218,7 @@ sub handler { &Apache::lonnet::logthis('lonsearchcat:'. 'Unable to recover data from '. $persistent_db_file); - my $msg = + my $msg = &mt('We were unable to retrieve data describing your search.'). ' '.&mt('This is a serious error and has been logged.'). '
'. @@ -298,7 +323,7 @@ END } # if ($env{'form.searchmode'} eq 'advanced') { - my $srchtype = 'Catalog'; + my $srchtype = 'Content Library'; if ($env{'form.area'} eq 'portfolio') { $srchtype = 'Portfolio'; } @@ -307,10 +332,23 @@ END '&phase=disp_adv'. '&catalogmode='.$env{'form.catalogmode'}. '&launch='.$env{'form.launch'}. - '&mode='.$env{'form.mode'}, + '&mode='.$env{'form.mode'}. + '&area='.$env{'form.area'}, text=>"Advanced $srchtype Search", bug=>'Searching',}); - } + } elsif (($env{'form.phase'} eq 'results') || + ($env{'form.phase'} =~ /^(sort|run_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'}. + '&area='.$env{'form.area'}. + '&searchmode='.$env{'form.searchmode'}, + text=>"Search Results", + bug=>'Searching',}); + } ## ## Switch on the phase ## @@ -327,10 +365,10 @@ END ['query','customquery','customshow', 'libraries','pretty_string','domains']); if ($env{'form.phase'} eq 'sort') { - &print_sort_form($r,$pretty_string); + &print_sort_form($r,$pretty_string,$target); } elsif ($env{'form.phase'} eq 'run_search') { &run_search($r,$query,$customquery,$customshow, - $libraries,$pretty_string,$env{'form.area'},$domainsref); + $libraries,$pretty_string,$env{'form.area'},$domainsref,$target); } } elsif(($env{'form.phase'} eq 'basic_search') || ($env{'form.phase'} eq 'adv_search')) { @@ -389,7 +427,7 @@ END } } return OK; -} +} # # The mechanism used to store values away and retrieve them does not @@ -427,6 +465,42 @@ sub hidden_field { return ''.$/; } +sub start_search_tabs { + my $area; + my %lt = &Apache::lonlocal::texthash ( + res => 'Content Library Search', + portfolio => 'Portfolio Search', + ); + my $output = ''; + } + } else { + $area = 'portfolio'; + $output .= "\n".'
  • '. + '    '.$lt{'portfolio'}. + '    
  • '; + } + $output .= '
    '. + '
    '. + '
    '; + return $output; +} + +sub end_search_tabs { + return '
    '; +} + ###################################################################### =pod @@ -443,19 +517,31 @@ Prints the form for the basic search. S ###################################################################### sub print_basic_search_form { my ($r,$closebutton,$hidden_fields) = @_; + my %lt = &Apache::lonlocal::texthash ( + res => 'Content Library Search', + portfolio => 'Portfolio Search', + ); my $result = ($env{'form.catalogmode'} ne 'import'); + my $area; my $bread_crumb = &Apache::lonhtmlcommon::breadcrumbs('Searching','Search_Basic', $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'})) { - $scrout .= &setup_basic_search($r,'res',$hidden_fields,$closebutton); - $scrout .= '

    '; - } + my $scrout = &Apache::loncommon::start_page('Content Library').$bread_crumb. + '
    '."\n". + &start_search_tabs(); + if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'}) eq 'F') { + if ($env{'form.area'} eq 'portfolio') { # Search form for accessible portfolio files - $scrout.= &setup_basic_search($r,'portfolio',$hidden_fields,$closebutton); - $scrout .= &Apache::loncommon::end_page(); + $scrout .= &setup_basic_search($r,'portfolio',$hidden_fields,$closebutton); + } else { +# Search form for resource space + $scrout .= &setup_basic_search($r,'res',$hidden_fields,$closebutton); + } + } else { +# Search form for accessible portfolio files + $scrout .= &setup_basic_search($r,'portfolio',$hidden_fields,$closebutton); + } + $scrout .= &end_search_tabs().&Apache::loncommon::end_page(); $r->print($scrout); return; } @@ -464,7 +550,7 @@ sub setup_basic_search { my ($r,$area,$hidden_fields,$closebutton) = @_; # Define interface components my %lt = &Apache::lonlocal::texthash ( - res => 'LON-CAPA Catalog Search', + res => 'Content Library Search', portfolio => 'Portfolio Search', ); my ($userelatedwords,$onlysearchdomain,$inclext,$adv_search_link,$scrout); @@ -478,14 +564,31 @@ sub setup_basic_search { .&mt('use related words') .''; + my $anydom = 1; + if ($area eq 'res') { + unless (&Apache::lonnet::allowed('bre','/res/') eq 'F') { + $anydom = 0; + } + } + my $singledom; + my ($disabled,$checked); + if ($anydom) { + $singledom = $r->dir_config('lonDefDomain'); + if ($env{'form.domains'} eq $singledom) { + $checked = 1; + } + } else { + $singledom = $env{'user.domain'}; + $disabled = ' disabled="disabled"'; + $checked = 1; + } $onlysearchdomain = ''; $adv_search_link = ''; } # - $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 .= '
    '. + '
    '. + '
    '. + ''.(' 'x3).$adv_search_link.''.'
    '. + ''.(' 'x1).$userelatedwords.''.'
    '. + ''.(' 'x1).$onlysearchdomain.''.'
    '. + ''.(' 'x1).$inclext.''.'
    '. + '

    '.$/; # - $scrout .= '

    ' + $scrout .= '

    ' .&viewoptions() .'

    ' .'

    ' @@ -538,9 +632,9 @@ sub setup_basic_search { .'value="'.&mt('Search').'" />' .' ' .$closebutton - .'

    '; + .'

    '; # - $scrout .= '
    '.''; + $scrout .= ''; return $scrout; } @@ -572,7 +666,7 @@ sub print_advanced_search_form{ $closebutton

    END - my $srchtype = 'Catalog'; + my $srchtype = 'Content Library'; my $jscript; if ($env{'form.area'} eq 'portfolio') { $srchtype = 'Portfolio'; @@ -590,7 +684,8 @@ function additional_metadata() { } my $scrout= &Apache::loncommon::start_page("Advanced $srchtype Search", $jscript); - $scrout .= $bread_crumb; + $scrout .= $bread_crumb.'
    '."\n". + &start_search_tabs(); $scrout .= '
    ' .$hidden_fields @@ -609,7 +704,7 @@ function additional_metadata() { # Standard Metadata $scrout .= &Apache::lonhtmlcommon::row_headline() - .'

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

    ' + .'

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

    ' .&searchhelp() .&Apache::lonhtmlcommon::row_closure(); my %related_word_search = @@ -629,47 +724,68 @@ function additional_metadata() { foreach my $field ('title','author','subject','owner','authorspace', 'modifyinguser','keywords','notes','abstract', 'standards','mime') { - $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield($fields{$field})) + $scrout .= &Apache::lonhtmlcommon::row_title('') .&Apache::lonmeta::prettyinput($field, - $env{'form.'.$field}, + $env{'form.'.$field},'', $field, 'advsearch', $related_word_search{$field}, - '', + '  ', $env{'form.'.$field.'_related'}, 50); if ($related_word_search{$field}) { - $scrout .= &mt('related words'); + $scrout .= ''; } else { $scrout .= ''; } $scrout .= &Apache::lonhtmlcommon::row_closure(); } foreach my $field ('lowestgradelevel','highestgradelevel') { - $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield($fields{$field})) + $scrout .= &Apache::lonhtmlcommon::row_title('') .&Apache::lonmeta::prettyinput($field, - $env{'form.'.$field}, + $env{'form.'.$field},'', $field, 'advsearch', 0) .&Apache::lonhtmlcommon::row_closure(); } - $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt('MIME Type Category'))) + $scrout .= &Apache::lonhtmlcommon::row_title('') .&Apache::loncommon::filecategoryselect('category', - $env{'form.category'}) + $env{'form.category'},'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(); + my $anydomain = 1; + if ($env{'form.area'} ne 'portfolio') { + unless (&Apache::lonnet::allowed('bre','/res/')) { + $anydomain = 0; + } + } + + $scrout .= &Apache::lonhtmlcommon::row_title(''); + if ($anydomain) { + my $defdom = &Apache::lonnet::default_login_domain(); + my ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('shared',$defdom); + $scrout .= &Apache::loncommon::domain_select('domains', + $env{'form.domains'},1,$trusted,$untrusted,'domains'); + } else { + $scrout .= &Apache::loncommon::select_dom_form($env{'user.domain'}, + 'domains','','','', + [$env{'user.domain'}],'',1,'domains'); + } + $scrout .= &Apache::lonhtmlcommon::row_closure(); # Misc metadata if ($env{'form.area'} ne 'portfolio') { - $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt('Copyright/Distribution'))) + $scrout .= &Apache::lonhtmlcommon::row_title('') .&Apache::lonmeta::selectbox('copyright', - $env{'form.copyright'}, + $env{'form.copyright'},'', + 'copyright', \&Apache::loncommon::copyrightdescription, ( undef, &Apache::loncommon::copyrightids) @@ -677,9 +793,10 @@ function additional_metadata() { .&Apache::lonhtmlcommon::row_closure(); } - $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt('Language'))) + $scrout .= &Apache::lonhtmlcommon::row_title('') .&Apache::lonmeta::selectbox('language', - $env{'form.language'}, + $env{'form.language'},'','language', \&Apache::loncommon::languagedescription, ('any',&Apache::loncommon::languageids) ) @@ -692,26 +809,32 @@ function additional_metadata() { if ($curnumadd eq '') { $curnumadd = 1; } + my $customlabel = &mt('Text box description'); $scrout .= &Apache::lonhtmlcommon::row_headline() .'

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

    ' .&Apache::lonhtmlcommon::row_closure() - .&Apache::lonhtmlcommon::row_title('') + .&Apache::lonhtmlcommon::row_title(''.$customlabel.'', + '','','',1) .&mt('Field Name').' | '.&mt('Field Value(s)') .&Apache::lonhtmlcommon::row_closure(); for (my $j=0; $j<$curnumadd; $j++) { my $num = $j+1; + my $namelabel = &mt('name of custom metadata field [_1]',$num); + my $valuelabel = &mt('value of custom metadata field [_1]',$num); $scrout .= &Apache::lonhtmlcommon::row_title(&mt('Custom metadata [_1]',$num)) - .'' + .' value="'.$env{'form.addedfield_'.$j}.'" aria-label="'.$namelabel.'" />' .' ' .'' + .' value="'.$env{'form.addedvalues_'.$j}.'" aria-label="'.$valuelabel.'" />' .&Apache::lonhtmlcommon::row_closure(); } - $scrout .= &Apache::lonhtmlcommon::row_title('') + my $addcustomlabel = &mt('Add metadata field option'); + $scrout .= &Apache::lonhtmlcommon::row_title(''.$addcustomlabel.'', + '','','',1) .'
    '.&Apache::loncommon::end_page(); $r->print($scrout); return; } @@ -912,20 +1060,20 @@ sub viewoptions { if (! defined($env{'form.viewselect'})) { $env{'form.viewselect'}='detailed'; } - $scrout .= '' + $scrout .= ''; + .''; my $countselect = &Apache::lonmeta::selectbox('show', - $env{'form.show'}, + $env{'form.show'},'','', undef, (10,20,50,100,1000,10000)); - $scrout .= ' ' + $scrout .= ' '.$/; + .''.$/; return $scrout; } @@ -1221,8 +1369,10 @@ sub parse_advanced_search { } if (! $fillflag) { &output_blank_field_error($r,$closebutton, - 'phase=disp_adv',$hidden_fields); - return ; + 'phase=disp_adv&area='.$env{'form.area'}. + '&catalogmode='.$env{'form.catalogmode'}, + $hidden_fields); + return; } # Turn the form input into a SQL-based query my $query=''; @@ -1235,7 +1385,9 @@ sub parse_advanced_search { &process_phrase_input($env{'form.'.$field}, $env{'form.'.$field.'_related'},$field); if (defined($error)) { - &output_unparsed_phrase_error($r,$closebutton,'phase=disp_adv', + &output_unparsed_phrase_error($r,$closebutton, + 'phase=disp_adv&area='.$env{'form.area'}. + '&catalogmode='.$env{'form.catalogmode'}. $hidden_fields,$field); return; } else { @@ -1519,7 +1671,9 @@ sub parse_basic_search { # Check to see if enough of a query is filled in my $search_string = $env{'form.basicexp'}; if (! &filled($search_string)) { - &output_blank_field_error($r,$closebutton,'phase=disp_basic'); + &output_blank_field_error($r,$closebutton,'phase=disp_basic'. + '&area='.$env{'form.area'}. + '&catalogmode='.$env{'form.catalogmode'}); return OK; } my $pretty_search_string=$search_string; @@ -1535,7 +1689,9 @@ sub parse_basic_search { $env{'form.related'}, $searchfield); if ($error) { - &output_unparsed_phrase_error($r,$closebutton,'phase=disp_basic', + &output_unparsed_phrase_error($r,$closebutton,'phase=disp_basic'. + '&area='.$env{'form.area'}. + '&catalogmode='.$env{'form.catalogmode'}, '','basicexp'); return; } @@ -1851,6 +2007,8 @@ sub build_date_queries { my (undef,undef,undef,$cbday,$cbmon,$cbyear) = localtime($cbefore); # Correct for year being relative to 1900 $cayear+=1900; $cbyear+=1900; + # Correct month; localtime gives month 0..11 but MySQL expects 1..12 + $camon++; $cbmon++; my $cquery= '(creationdate BETWEEN '. "'".$cayear.'-'.$camon.'-'.$caday."'". @@ -1869,6 +2027,8 @@ sub build_date_queries { my (undef,undef,undef,$mbday,$mbmon,$mbyear) = localtime($mbefore); # Correct for year being relative to 1900 $mayear+=1900; $mbyear+=1900; + # Correct month; localtime gives month 0..11 but MySQL expects 1..12 + $mamon++; $mbmon++; my $mquery= '(lastrevisiondate BETWEEN '. "'".$mayear.'-'.$mamon.'-'.$maday."'". @@ -1911,10 +2071,11 @@ sub copyright_check { my (undef,undef,$resdom,$resname) = split('/', $Metadata->{'url'}); # Check for priv - if (($Metadata->{'copyright'} eq 'priv') && - (($env{'user.name'} ne $resname) && - ($env{'user.domain'} ne $resdom))) { - return 0; + if ($Metadata->{'copyright'} eq 'priv') { + unless (($env{'user.name'} eq $resname) && + ($env{'user.domain'} eq $resdom)) { + return 0; + } } # Check for domain if (($Metadata->{'copyright'} eq 'domain') && @@ -2017,7 +2178,7 @@ a link to change the search query. ###################################################################### ###################################################################### sub print_sort_form { - my ($r,$pretty_query_string) = @_; + my ($r,$pretty_query_string,$target) = @_; ## my %SortableFields=&Apache::lonlocal::texthash( @@ -2050,29 +2211,20 @@ sub print_sort_form { &Apache::lonnet::logthis(&Apache::lonmysql::get_error()); return; } - my $js =< -// $target}; } -// ]]> - -END - - my $start_page = &Apache::loncommon::start_page('Results',$js); + my $start_page = &Apache::loncommon::start_page('Results',undef,$args); my $breadcrumbs= &Apache::lonhtmlcommon::breadcrumbs('Searching','Searching', - $env{'form.catalogmode'} ne 'import'); - + $env{'form.catalogmode'} ne 'import', + '','','','','','',$target); my $result = < +
    +
    END @@ -2094,7 +2246,7 @@ END .' '.$revise.'

    ' .'

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

    '; - $r->print($result.&Apache::loncommon::end_page()); + $r->print($result.'
    '.&Apache::loncommon::end_page()); return; } @@ -2228,8 +2380,22 @@ SCRIPT $r->rflush(); } +sub reload_result_frame { + my ($r) = @_; + my $newloc = '/adm/searchcat?phase=results&persistent_db_id='. + $env{'form.persistent_db_id'}.'&area='.$env{'form.area'}. + '&catalogmode='.$env{'form.catalogmode'}; + $r->print(< + parent.update_results("$newloc"); + +SCRIPT + + $r->rflush(); +} + { - my $max_time = 300; # seconds for the search to complete + my $max_time = 60; # seconds for the search to complete my $start_time = 0; my $last_time = 0; @@ -2288,7 +2454,9 @@ sub revise_button { my $newloc = '/adm/searchcat'. '?persistent_db_id='.$env{'form.persistent_db_id'}. '&cleargroupsort=1'. - '&phase='.$revise_phase; + '&phase='.$revise_phase. + '&area='.$env{'form.area'}. + '&catalogmode='.$env{'form.catalogmode'}; my $result = qq{ }; return $result; @@ -2310,7 +2478,7 @@ results into MySQL. ###################################################################### sub run_search { my ($r,$query,$customquery,$customshow,$serverlist, - $pretty_string,$area,$domainsref) = @_; + $pretty_string,$area,$domainsref,$target) = @_; my $tabletype = 'metadata'; if ($area eq 'portfolio') { $tabletype = 'portfolio_search'; @@ -2319,13 +2487,19 @@ sub run_search { # # Print run_search header # - my $start_page = &Apache::loncommon::start_page('Search Status',undef); + my $args; + if ($target eq '_parent') { + $args = {'links_target' => $target}; + } + my $start_page = &Apache::loncommon::start_page('Search Status',undef,$args); my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Searching','Searching', - $env{'form.catalogmode'} ne 'import'); + $env{'form.catalogmode'} ne 'import', + '','','','','','',$target); $r->print(< END # Remove leading and trailing
    $pretty_string =~ s:^\s*
    ::i; @@ -2370,8 +2544,6 @@ END %all_library_servers = (%library_servers,%older_library_servers); @Servers_to_contact = sort(keys(%all_library_servers)); foreach my $server (@Servers_to_contact) { - my %possdoms; - map { $possdoms{$_}=1; } &Apache::lonnet::machine_domains($all_library_servers{$server}); $domains_by_server{$server} = join(',',sort(&Apache::lonnet::machine_domains($all_library_servers{$server}))); } @@ -2410,6 +2582,8 @@ END ## ## Prepare for the big loop. my $hitcountsum; + my $oldhitcountsum; + my $displaycount; my %matches; my $server; my $status; @@ -2456,7 +2630,7 @@ END &update_status($r, &mt('waiting on [_1]',join(' ',keys(%Server_status)))); } - sleep(1); + sleep(0.1); } # # Loop through the servers we have contacted but do not @@ -2509,8 +2683,8 @@ END if ($area eq 'portfolio') { next if (defined($matches{$Fields{'url'}})); - # Skip if inaccessible - next if (!&Apache::lonnet::portfolio_access($Fields{'url'})); + # Skip unless access control set to public or passphrase-protected + next unless (($Fields{'scope'} eq 'public') || ($Fields{'scope'} eq 'guest')); $matches{$Fields{'url'}} = 1; } # @@ -2532,7 +2706,15 @@ END delete($Server_status{$server}); } last if ($connection->aborted()); - &update_count_status($r,$hitcountsum); + if ($oldhitcountsum < $hitcountsum) { + &update_count_status($r,$hitcountsum); + if (($hitcountsum <= $env{'form.show'}) || + (!$displaycount && $hitcountsum)) { + reload_result_frame($r); + $displaycount = $hitcountsum; + } + $oldhitcountsum = $hitcountsum; + } } last if ($connection->aborted()); &update_seconds($r); @@ -2545,11 +2727,11 @@ END # We have run out of time or run out of servers to talk to and # results to get, so let the client know the top frame needs to be # loaded from /adm/searchcat - $r->print(&Apache::loncommon::end_page()); + $r->print('
    '.&Apache::loncommon::end_page()); # if ($env{'form.catalogmode'} ne 'import') { $r->print(< -window.location='/adm/searchcat?phase=sort&persistent_db_id=$env{'form.persistent_db_id'}'; +window.location='/adm/searchcat?phase=sort&area=$env{"form.area"}&catalogmode=$env{"form.catalogmode"}&persistent_db_id=$env{"form.persistent_db_id"}'; SCRIPT # } @@ -2609,7 +2791,8 @@ sub display_results { if (!defined($viewfunction)) { $r->print('

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

    '."\n"); + .'

    '."\n" + .''.&Apache::loncommon::end_page()); $r->rflush(); return; } @@ -2620,20 +2803,27 @@ sub display_results { ## ## Get the catalog controls setup ## - my $action = "/adm/searchcat?phase=results"; + my $action = '/adm/searchcat?phase=results&area='.$env{'form.area'}. + '&catalogmode='.$env{'form.catalogmode'}; ## ## 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)) { + # NOTE: this can happen when a previous request to searchcat?phase=results gets interrupted + # (%groupsearch_db is not untied) $r->print('

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

    '. - ''. + ''. &Apache::loncommon::end_page()); $r->rflush(); return; } + # untie %groupsearch_db if the connection gets aborted before the end + $r->register_cleanup(sub { + untie %groupsearch_db if (tied(%groupsearch_db)); + }); } ## ## Prepare the table for querying @@ -2646,7 +2836,7 @@ sub display_results { $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); @@ -2751,17 +2941,18 @@ sub display_results { $env{'form.sortorder'}='asc'; } } - my $sortform = '' - .&mt('Sort by:').' ' + my $sortform = '' + .&mt('Sort by:').' ' .&Apache::loncommon::select_form($env{'form.sortfield'}, - 'sortfield', - \%sort_fields) + 'sortfield', + \%sort_fields,'','','', + 'LC_sortby') .' ' .&Apache::loncommon::select_form($env{'form.sortorder'}, - 'sortorder', - {asc =>&mt('Ascending'), - desc=>&mt('Descending') - }) + 'sortorder', + {asc =>&mt('Ascending'), + desc=>&mt('Descending') + },'','','','LC_sortby') .''; ## ## Display links for 'prev' and 'next' pages (if necessary) and Display Options @@ -2775,16 +2966,15 @@ sub display_results { ); if ($total_results == 0) { - $r->print(''. - '

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

    '. - "". + $r->print('

    '.&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 @@ -2814,7 +3004,14 @@ sub display_results { if ($area eq 'portfolio') { $tabletype = 'portfolio_search'; } - $r->print(&Apache::loncommon::start_data_table()); + $r->print(&Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + ''.&mt('Data').''); + if (($env{'form.viewselect'} eq 'detailedpreview') || + ($env{'form.viewselect'} eq 'summarypreview')) { + $r->print(''.&mt('Preview').''); + } + $r->print(&Apache::loncommon::end_data_table_header_row()); foreach my $row (@Results) { if ($connection->aborted()) { &cleanup(); @@ -2852,7 +3049,7 @@ sub display_results { $env{'form.persistent_db_id'}) ); } - $r->print("".&Apache::loncommon::end_page()); + $r->print(''.&Apache::loncommon::end_page()); $r->rflush(); untie %groupsearch_db if (tied(%groupsearch_db)); return; @@ -3149,12 +3346,21 @@ SCRIPT SCRIPT + $js.=< + \$(document).ready(function() { + parent.done_loading_results(); + }); + +SCRIPT + my $start_page = &Apache::loncommon::start_page(undef,$js, {'only_body' =>1, 'add_wishlist' =>1, 'add_modal' =>1}); my $result=<
    $importbutton END @@ -3163,6 +3369,8 @@ END sub results_link { my $basic_link = "/adm/searchcat?"."&table=".$env{'form.table'}. + "&area=".$env{'form.area'}. + "&catalogmode=".$env{'form.catalogmode'}. "&persistent_db_id=".$env{'form.persistent_db_id'}; my $results_link = $basic_link."&phase=results". "&pause=1"."&start=1"; @@ -3173,7 +3381,9 @@ sub results_link { ###################################################################### sub print_frames_interface { my $r = shift; - my $basic_link = "/adm/searchcat?"."&table=".$env{'form.table'}. + my $basic_link = "/adm/searchcat?table=".$env{'form.table'}. + "&area=".$env{'form.area'}. + "&catalogmode=".$env{'form.catalogmode'}. "&persistent_db_id=".$env{'form.persistent_db_id'}; my $run_search_link = $basic_link."&phase=run_search"; my $results_link = &results_link(); @@ -3182,6 +3392,26 @@ sub print_frames_interface { // JS @@ -3294,7 +3524,7 @@ sub detailed_citation_view { ''.$prefix. ''.' '. ''.$values{'title'}."\n". + 'target="preview" onclick="openMyModal(this.href, 500, 500, \'yes\');return false;">'.$values{'title'}."\n". &display_tools($values{'title'}, $jumpurl). "

    \n". ''.$values{'author'}.','. @@ -3427,7 +3657,7 @@ sub summary_view { my $link = '
    '.&display_url($jumpurl,1).'
    '; $result .= ''.$values{'title'}.''. + ' target="preview" onclick="openMyModal(this.href, 500, 500, \'yes\');return false;">'.$values{'title'}.''. &display_tools($values{'title'}, $jumpurl).< $link
    @@ -3473,7 +3703,7 @@ sub compact_view { } $jumpurl = &HTML::Entities::encode($jumpurl,'<>&"'); $result.=' '. - ''. + ''. &HTML::Entities::encode($values{'title'},'<>&"').' '. &display_tools($values{'title'}, $jumpurl). $link.' '.$values{'author'}.' ('.$values{'domain'}.')'; @@ -3489,12 +3719,17 @@ sub display_url { } elsif ($url=~m{^(http://|/uploaded/)}) { $link=''.$url.''; } else { + # replace the links to open in a new window + # (because the search opens in a new window, it gets + # confusing when the links open a tab in the + # parent window; ideally we should not force windows) + my $onclick = " onclick=\"window.open(this.href, '_blank', 'toolbar=1,location=1,menubar=0');return false;\""; $link=&Apache::lonhtmlcommon::crumbs( $url, 'preview', '', - (($env{'form.catalogmode'} eq 'import')?'parent.statusframe.document.forms.statusform':''), - $skiplast).' '; + '', + $skiplast,$onclick).' '; } return $link; } @@ -3800,7 +4035,7 @@ Cleans the global %groupsearch_db by rem ###################################################################### sub start_fresh_session { delete $groupsearch_db{'mode_catalog'}; - foreach (keys %groupsearch_db) { + foreach (keys(%groupsearch_db)) { if ($_ =~ /^pre_/) { delete $groupsearch_db{$_}; }