[LON-CAPA-cvs] cvs: loncom /interface lonsearchcat.pm

raeburn lon-capa-cvs@mail.lon-capa.org
Tue, 26 Sep 2006 15:24:18 -0000


This is a MIME encoded message

--raeburn1159284258
Content-Type: text/plain

raeburn		Tue Sep 26 11:24:18 2006 EDT

  Modified files:              
    /loncom/interface	lonsearchcat.pm 
  Log:
  Portfolio searching - work in progress.  Basic search functional; advanced search is not.  Results display needs customization.    
  
  
--raeburn1159284258
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20060926112418.txt"

Index: loncom/interface/lonsearchcat.pm
diff -u loncom/interface/lonsearchcat.pm:1.275 loncom/interface/lonsearchcat.pm:1.276
--- loncom/interface/lonsearchcat.pm:1.275	Mon Jul 31 15:45:58 2006
+++ loncom/interface/lonsearchcat.pm	Tue Sep 26 11:24:18 2006
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Search Catalog
 #
-# $Id: lonsearchcat.pm,v 1.275 2006/07/31 19:45:58 albertel Exp $
+# $Id: lonsearchcat.pm,v 1.276 2006/09/26 15:24:18 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -139,7 +139,7 @@
     &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']);
     ##
     ## 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
@@ -249,6 +249,9 @@
     if (exists($env{'form.mode'})) {
         $hidden_fields .= &hidden_field('mode');
     }
+    if (exists($env{'form.area'})) {
+        $hidden_fields .= &hidden_field('area');
+    }
     ##
     ## Configure dynamic components of interface
     ##
@@ -318,7 +321,8 @@
     } 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 +332,7 @@
             &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,7 +362,7 @@
                          $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:'.
@@ -665,68 +669,13 @@
         &Apache::lonhtmlcommon::breadcrumbs('Searching','Search_Basic',
 					    $env{'form.catalogmode'} ne 'import');
     my $scrout = &Apache::loncommon::start_page('Search').$bread_crumb;
+# Search form for resource space 
     if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'})) {
-        # Define interface components
-        my $userelatedwords= '<label>'.
-            &mt('[_1] use related words',
-                &Apache::lonhtmlcommon::checkbox
-                ('related',$env{'form.related'},'related')).'</label>';
-        my $onlysearchdomain='<label>'.
-            &mt('[_1] only search domain [_2]',
-                &Apache::lonhtmlcommon::checkbox('domains',
-                                                 $env{'form.domains'},
-                                                 $r->dir_config('lonDefDomain')
-                                                 ),
-                $r->dir_config('lonDefDomain')
-                ).'</label>';
-        my $inclext= '<label>'.
-            &mt('[_1] include external resources',
-                &Apache::lonhtmlcommon::checkbox
-                ('inclext',$env{'form.inclext'})).'</label>';
-        my $adv_search_link = 
-            '<a href="/adm/searchcat?'.
-            'phase=disp_adv&'.
-            'catalogmode='.$env{'form.catalogmode'}.
-            '&launch='.$env{'form.launch'}.
-            '&mode='.$env{'form.mode'}.
-            '">'.&mt('Advanced Search').'</a>';
-        #
-        $scrout.='<form name="loncapa_search" method="post" '.
-            'action="/adm/searchcat">'.
-            '<input type="hidden" name="phase" value="basic_search" />'.
-            $hidden_fields;
-        #
-        $scrout .= '<center>'.$/;
-        if ($env{'request.course.id'}) {
-            $scrout .= '<h1>'.&mt('LON-CAPA Catalog Search').'</h1>';
-        } else {
-            # No need to tell them they are searching
-            $scrout.= ('<br />'x2);
-        }
-        $scrout.='<table>'.
-            '<tr><td align="center" valign="top">'.
-            &Apache::lonhtmlcommon::textbox('basicexp',
-					    $env{'form.basicexp'},50).
-             '<br />'.
-            '<font size="-1">'.&searchhelp().'</font>'.'</td>'.
-            '<td><font size="-1">'.
-            '<nobr>'.('&nbsp;'x3).$adv_search_link.'</nobr>'.'<br />'.
-            '<nobr>'.('&nbsp;'x1).$userelatedwords.'</nobr>'.'<br />'.
-            '<nobr>'.('&nbsp;'x1).$onlysearchdomain.'</nobr>'.'<br />'.
-            '<nobr>'.('&nbsp;'x1).$inclext.'</nobr>'.'<br />'.
-             '</font></td>'.
-            '</tr>'.$/;
-        #
-        $scrout .= '<tr><td align="center" colspan="2">'.
-            '<font size="-1">'.
-            '<input type="submit" name="basicsubmit" '.
-            'value="'.&mt('Search').'" />'.
-            ('&nbsp;'x2).$closebutton.('&nbsp;'x2).
-            &viewoptions().
-            '</font>'.
-            '</td></tr>'.$/;
-        $scrout .= '</table>'.$/.'</center>'.'</form>';
+        $scrout .= &setup_basic_search($r,'res',$hidden_fields,$closebutton);
+        $scrout .= '<hr /><br />';
     }
+# 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',
@@ -777,6 +726,75 @@
     $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 = '<label>'.&mt('[_1] use related words',
+      &Apache::lonhtmlcommon::checkbox('related',$env{'form.related'},'related')).
+                       '</label>';
+    $onlysearchdomain = '<label>'.&mt('[_1] only search domain [_2]',
+      &Apache::lonhtmlcommon::checkbox('domains',$env{'form.domains'},
+                                       $r->dir_config('lonDefDomain'))).
+                        '</label>';
+    if ($area eq 'res') {
+        $inclext= '<label>'.&mt('[_1] include external resources',
+             &Apache::lonhtmlcommon::checkbox('inclext',$env{'form.inclext'})).
+                  '</label>';
+    }
+    $adv_search_link = '<a href="/adm/searchcat?'.
+                       'phase=disp_adv&'.
+                       'catalogmode='.$env{'form.catalogmode'}.
+                       '&launch='.$env{'form.launch'}.
+                       '&mode='.$env{'form.mode'}.
+                       '&area='.$area.
+                       '">'.&mt('Advanced Search').'</a>';
+    #
+    $scrout.='<form name="loncapa_search" method="post" '.
+             'action="/adm/searchcat">'.
+             '<input type="hidden" name="phase" value="basic_search" />'.
+             $hidden_fields;
+             if (!exists($env{'form.area'})) {
+                 $scrout .= '<input type="hidden" name="area" value="'.$area.'" />';
+             }
+    #
+    $scrout .= '<center>'.$/;
+#    if ($env{'request.course.id'}) {
+        $scrout .= '<h1>'.$lt{$area}.'</h1>';
+#    } else {
+        # No need to tell them they are searching
+#        $scrout.= ('<br />'x2);
+#    }
+    $scrout.='<table>'.
+             '<tr><td align="center" valign="top">'.
+             &Apache::lonhtmlcommon::textbox('basicexp',
+                                             $env{'form.basicexp'},50).
+             '<br />'.
+            '<font size="-1">'.&searchhelp().'</font>'.'</td>'.
+            '<td><font size="-1">'.
+            '<nobr>'.('&nbsp;'x3).$adv_search_link.'</nobr>'.'<br />'.
+            '<nobr>'.('&nbsp;'x1).$userelatedwords.'</nobr>'.'<br />'.
+            '<nobr>'.('&nbsp;'x1).$onlysearchdomain.'</nobr>'.'<br />'.
+            '<nobr>'.('&nbsp;'x1).$inclext.'</nobr>'.'<br />'.
+             '</font></td>'.
+            '</tr>'.$/;
+    #
+    $scrout .= '<tr><td align="center" colspan="2">'.
+               '<font size="-1">'.
+               '<input type="submit" name="basicsubmit" '.
+               'value="'.&mt('Search').'" />'.
+               ('&nbsp;'x2).$closebutton.('&nbsp;'x2). &viewoptions().
+               '</font>'.
+               '</td></tr>'.$/;
+    $scrout .= '</table>'.$/.'</center>'.'</form>';
+    return $scrout;
+} 
+
 ######################################################################
 ######################################################################
 
@@ -871,20 +889,26 @@
 	&titlefield(&mt('Domains')).'</td><td colspan="2">'. 
 	    &Apache::loncommon::domain_select('domains',
 						   $env{'form.domains'},1).
-						   '<br /><label>'.
-            &mt('[_1] include external resources',
-                &Apache::lonhtmlcommon::checkbox
-                ('inclext',$env{'form.inclext'})).'</label></td></tr>'.$/;
+						   '<br /><label>';
+            if ($env{'form.area'} ne 'portfolio') {
+                $scrout .= &mt('[_1] include external resources',
+                           &Apache::lonhtmlcommon::checkbox
+                           ('inclext',$env{'form.inclext'})).'</label>'
+            }
+     $scrout .= '</td></tr>'.$/;
     #
     # Misc metadata
-    $scrout.='<tr><td align="right" valign="top">'.
-	&titlefield(&mt('Copyright/Distribution')).'</td><td colspan="2">'.
-        &Apache::lonmeta::selectbox('copyright',
-                                    $env{'form.copyright'},
-                                    \&Apache::loncommon::copyrightdescription,
-                                    ( undef,
-                                      &Apache::loncommon::copyrightids)
-                                    ).'</td></tr>'.$/;
+    if ($env{'form.area'} ne 'portfolio') {
+        $scrout.='<tr><td align="right" valign="top">'.
+	         &titlefield(&mt('Copyright/Distribution')).
+                 '</td><td colspan="2">'.
+                 &Apache::lonmeta::selectbox('copyright',
+                                             $env{'form.copyright'},
+                                \&Apache::loncommon::copyrightdescription,
+                                       ( undef,
+                                        &Apache::loncommon::copyrightids)
+                                ).'</td></tr>'.$/;
+    }
     $scrout.='<tr><td align="right" valign="top">'.
 	&titlefield(&mt('Language')).'</td><td colspan="2">'.
         &Apache::lonmeta::selectbox('language',
@@ -892,62 +916,94 @@
                                     \&Apache::loncommon::languagedescription,
                                     ('any',&Apache::loncommon::languageids)
                                     ).'</td></tr>';
-    $scrout .= "</table>\n";    
-    #
-    # Dynamic metadata
-    $scrout .= '<h3>'.&mt('Problem Statistics').'</h3>';
-    $scrout .= "<table>\n";
-    $scrout .= '<tr><td>&nbsp;</td><td align="center">'.&mt('Minimum').'</td>'.
-        '<td align="center">'.&mt('Maximum').'</td></tr>'."\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 .= '<tr><td align="right">'.
-            &titlefield(&mt($statistic->{'description'})).
-            '</td><td align="center">'.
-            '<input type="text" name="'.$statistic->{'name'}.'_min" '.
-            'value="" size="6" />'.
-            '</td><td align="center">'.
-            '<input type="text" name="'.$statistic->{'name'}.'_max" '.
-            'value="" size="6" />'.
-            '</td></tr>'.$/;
-    }
     $scrout .= "</table>\n";
-    $scrout .= '<h3>'.&mt('Evaluation Data').'</h3>';
-    $scrout .= "<table>\n";
-    $scrout .= '<tr><td>&nbsp;</td><td align="center">'.&mt('Minimum').'</td>'.
-        '<td align="center">'.&mt('Maximum').'</td></tr>'."\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 .= '<tr><td align="right">'.
-            &titlefield(&mt($evaluation->{'description'})).
-            '</td><td align="center">'.
-            '<input type="text" name="'.$evaluation->{'name'}.'_min" '.
-            'value="" size="6" />'.
-            '</td><td align="center">'.
-            '<input type="text" name="'.$evaluation->{'name'}.'_max" '.
-            'value="" size="6" />'.
-            '</td></tr>'.$/;
+
+    
+    if ($env{'form.area'} eq 'portfolio') {
+        # Added fields
+        $scrout .= '<h3>'.&mt('Custom Metadata fields').'</h3>';
+        $scrout .= "<table>\n";
+        $scrout .= '<tr><td>&nbsp;</td><td align="center">'.
+                   &mt('Field Name').'</td>'.'<td align="center">'.
+                   &mt('Field Value(s)').'</td></tr>'.
+                   '<tr><td>'.&mt('1: ').
+                   '</td><td align="center">'.
+                   '<input type="text" name="addedfield_0" size="10" /></td>'.
+                   '<td align="center"><input type="text" '.
+                   'name="addedvalues_0" size="15" /></td></tr>';
+        for (my $j=1; $j<=$env{'form.numaddedfields'}; $j++) {
+            my $num = $j+1;
+            $scrout .= '<tr><td>'.&mt('Custom metadata [_1]: ',$num).
+                       '</td><td align="center">'.
+                       '<input type="text" name="addedfield_'.$j.
+                       '" size="10" /></td>'.
+                       '<td align="center"><input type="text" '.
+                       'name="addedvalues_'.$j.'" size="15" /></td></tr>';
+        }
+        my $numadded = 1 + $env{'form.numaddedfields'};
+        $scrout .= '<tr><td colspan="3">&nbsp;</td></tr>'.
+                   '<tr><td align="left" colspan="3">'.
+                   '<input type="button" name="newfield" '.
+                   'value="Additional custom field/value" '.
+                   'onclick="javascript:additional_metadata()" />'.
+                   '<input type="hidden" name="numaddedfelds" value="'.
+                   $numadded.'" /></td></tr></table>';
+    } else {
+        #
+        # Dynamic metadata
+        $scrout .= '<h3>'.&mt('Problem Statistics').'</h3>';
+        $scrout .= "<table>\n";
+        $scrout .= '<tr><td>&nbsp;</td><td align="center">'.
+                   &mt('Minimum').'</td>'.'<td align="center">'.
+                   &mt('Maximum').'</td></tr>'."\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 .= '<tr><td align="right">'.
+                         &titlefield(&mt($statistic->{'description'})).
+                         '</td><td align="center">'.
+                         '<input type="text" name="'.$statistic->{'name'}.
+                         '_min" value="" size="6" /></td><td align="center">'.
+                         '<input type="text" name="'.$statistic->{'name'}.
+                         '_max" value="" size="6" /></td></tr>'.$/;
+        }
+        $scrout .= "</table>\n";
+        $scrout .= '<h3>'.&mt('Evaluation Data').'</h3>';
+        $scrout .= "<table>\n";
+        $scrout .= '<tr><td>&nbsp;</td><td align="center">'.
+                   &mt('Minimum').'</td>'.'<td align="center">'.
+                   &mt('Maximum').'</td></tr>'."\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 .= '<tr><td align="right">'.
+                       &titlefield(&mt($evaluation->{'description'})).
+                       '</td><td align="center">'.
+                       '<input type="text" name="'.
+                       $evaluation->{'name'}.'_min" value="" size="6" />'.
+                       '</td><td align="center"><input type="text" name="'.
+                       $evaluation->{'name'}.'_max" value="" size="6" />'.
+                       '</td></tr>'.$/;
+        }
+        $scrout .= "</table>\n";
     }
-    $scrout .= "</table>\n";
     #
     # Creation/Modification date limits
     $scrout .= '<h3>'.&mt('Creation and Modification dates').'</h3>';
@@ -1429,29 +1485,40 @@
             &Apache::loncommon::copyrightdescription($env{'form.copyright'}).
                 "<br />\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.'</font>&gt;'.$min.'<br />';
-        }
-        if (defined($max) && $max =~ /^(\d+\.\d+|\d+|\.\d+)$/) {
-            push(@queries,'('.$field.'<'.$max.')');
-            $pretty_search_string.=$font.$field.'</font>&lt;'.$max.'<br />';
+    if ($env{'form.area'} eq 'portfolio') {
+        #
+        # Added metadata fields
+        for (my $i=0; $i<$env{'form.numaddedfields'} ; $i++) {
+            if (($env{'form.addedfield_'.$i} ne '') && 
+                ($env{'form.addedvalue_'.$i} ne '')) {
+                my $stuff = 1; #FIXME 
+            }
+        }
+    } 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.'</font>&gt;'.$min.'<br />';
+            }
+            if (defined($max) && $max =~ /^(\d+\.\d+|\d+|\.\d+)$/) {
+                push(@queries,'('.$field.'<'.$max.')');
+                $pretty_search_string.=$font.$field.'</font>&lt;'.$max.'<br />';
+            }
         }
     }
     #
@@ -1596,10 +1663,13 @@
     }
     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,7 +1682,12 @@
     #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 < NOW() AND (pa.end IS NULL OR pa.end > NOW())) 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)');
@@ -1622,7 +1697,7 @@
     }
     $pretty_search_string .= "<br />\n";
     $pretty_search_string =~ s:^<br /> 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);
 }
@@ -2176,7 +2251,7 @@
 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.
 
@@ -2185,8 +2260,9 @@
 ######################################################################
 ######################################################################
 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',  
@@ -2199,7 +2275,12 @@
 }
 
 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},],
@@ -2331,8 +2412,12 @@
 ######################################################################
 ######################################################################
 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
@@ -2407,6 +2492,7 @@
     ##
     ## Prepare for the big loop.
     my $hitcountsum;
+    my %matches;
     my $server; 
     my $status;
     my $revise = &revise_button();
@@ -2461,7 +2547,7 @@
                 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));
@@ -2490,7 +2576,7 @@
                     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
@@ -2498,6 +2584,12 @@
                     # Skip based on copyright
                     next if (! &copyright_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);
@@ -2584,7 +2676,7 @@
 ######################################################################
 ######################################################################
 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));
     ##
@@ -2654,7 +2746,8 @@
     $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
@@ -2675,6 +2768,16 @@
          {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'},
@@ -2685,7 +2788,8 @@
          {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) {
@@ -2702,7 +2806,13 @@
     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';
@@ -2766,12 +2876,16 @@
     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';
+    }
     foreach my $row (@Results) {
         if ($connection->aborted()) {
             &cleanup();
             return;
         }
-        my %Fields = %{&parse_row(@$row)};
+        my %Fields = %{&parse_row($tabletype,@$row)};
         my $output="<p>\n";
         if (! defined($Fields{'title'}) || $Fields{'title'} eq '') {
             $Fields{'title'} = 'Untitled';
@@ -2855,10 +2969,10 @@
 ######################################################################
 ######################################################################
 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]);
@@ -2894,12 +3008,13 @@
 ###########################################################
 ###########################################################
 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;
 }
 

--raeburn1159284258--