File:  [LON-CAPA] / loncom / interface / lonmeta.pm
Revision 1.135: download - view: text, annotated - select for diffs
Thu Dec 8 02:17:56 2005 UTC (18 years, 6 months ago) by banghart
Branches: MAIN
CVS tags: HEAD
	New lables for buttons if portfolio metadata (not catalog info)
	Better message telling what course provides metadata framework
	Don't display the courserestricting metadata field in case
		of no course restricting metadata.
	Minor style stuff

    1: # The LearningOnline Network with CAPA
    2: # Metadata display handler
    3: #
    4: # $Id: lonmeta.pm,v 1.135 2005/12/08 02:17:56 banghart Exp $
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License 
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: 
   28: 
   29: package Apache::lonmeta;
   30: 
   31: use strict;
   32: use LONCAPA::lonmetadata();
   33: use Apache::Constants qw(:common);
   34: use Apache::lonnet;
   35: use Apache::loncommon();
   36: use Apache::lonhtmlcommon(); 
   37: use Apache::lonmsg;
   38: use Apache::lonpublisher;
   39: use Apache::lonlocal;
   40: use Apache::lonmysql;
   41: use Apache::lonmsg;
   42: 
   43: 
   44: ############################################################
   45: ############################################################
   46: ##
   47: ## &get_dynamic_metadata_from_sql($url)
   48: ## 
   49: ## Queries sql database for dynamic metdata
   50: ## Returns a hash of hashes, with keys of urls which match $url
   51: ## Returned fields are given below.
   52: ##
   53: ## Examples:
   54: ## 
   55: ## %DynamicMetadata = &Apache::lonmeta::get_dynmaic_metadata_from_sql
   56: ##     ('/res/msu/korte/');
   57: ##
   58: ## $DynamicMetadata{'/res/msu/korte/example.problem'}->{$field}
   59: ##
   60: ############################################################
   61: ############################################################
   62: sub get_dynamic_metadata_from_sql {
   63:     my ($url) = shift();
   64:     my ($authordom,$author)=($url=~m:^/res/(\w+)/(\w+)/:);
   65:     if (! defined($authordom)) {
   66:         $authordom = shift();
   67:     }
   68:     if  (! defined($author)) { 
   69:         $author = shift();
   70:     }
   71:     if (! defined($authordom) || ! defined($author)) {
   72:         return ();
   73:     }
   74:     my @Fields = ('url','count','course',
   75:                   'goto','goto_list',
   76:                   'comefrom','comefrom_list',
   77:                   'sequsage','sequsage_list',
   78:                   'stdno','stdno_list',
   79: 		  'dependencies',
   80:                   'avetries','avetries_list',
   81:                   'difficulty','difficulty_list',
   82:                   'disc','disc_list',
   83:                   'clear','technical','correct',
   84:                   'helpful','depth');
   85:     #
   86:     my $query = 'SELECT '.join(',',@Fields).
   87:         ' FROM metadata WHERE url LIKE "'.$url.'%"';
   88:     my $server = &Apache::lonnet::homeserver($author,$authordom);
   89:     my $reply = &Apache::lonnet::metadata_query($query,undef,undef,
   90:                                                 ,[$server]);
   91:     return () if (! defined($reply) || ref($reply) ne 'HASH');
   92:     my $filename = $reply->{$server};
   93:     if (! defined($filename) || $filename =~ /^error/) {
   94:         return ();
   95:     }
   96:     my $max_time = time + 10; # wait 10 seconds for results at most
   97:     my %ReturnHash;
   98:     #
   99:     # Look for results
  100:     my $finished = 0;
  101:     while (! $finished && time < $max_time) {
  102:         my $datafile=$Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/'.$filename;
  103:         if (! -e "$datafile.end") { next; }
  104:         my $fh;
  105:         if (!($fh=Apache::File->new($datafile))) { next; }
  106:         while (my $result = <$fh>) {
  107:             chomp($result);
  108:             next if (! $result);
  109:             my @Data = 
  110:                 map { 
  111:                     &Apache::lonnet::unescape($_); 
  112:                 } split(',',$result);
  113:             my $url = $Data[0];
  114:             for (my $i=0;$i<=$#Fields;$i++) {
  115:                 $ReturnHash{$url}->{$Fields[$i]}=$Data[$i];
  116:             }
  117:         }
  118:         $finished = 1;
  119:     }
  120:     #
  121:     return %ReturnHash;
  122: }
  123: 
  124: 
  125: # Fetch and evaluate dynamic metadata
  126: sub dynamicmeta {
  127:     my $url=&Apache::lonnet::declutter(shift);
  128:     $url=~s/\.meta$//;
  129:     my ($adomain,$aauthor)=($url=~/^(\w+)\/(\w+)\//);
  130:     my $regexp=$url;
  131:     $regexp=~s/(\W)/\\$1/g;
  132:     $regexp='___'.$regexp.'___';
  133:     my %evaldata=&Apache::lonnet::dump('nohist_resevaldata',$adomain,
  134: 				       $aauthor,$regexp);
  135:     my %DynamicData = &LONCAPA::lonmetadata::process_reseval_data(\%evaldata);
  136:     my %Data = &LONCAPA::lonmetadata::process_dynamic_metadata($url,
  137:                                                                \%DynamicData);
  138:     #
  139:     # Deal with 'count' separately
  140:     $Data{'count'} = &access_count($url,$aauthor,$adomain);
  141:     #
  142:     # Debugging code I will probably need later
  143:     if (0) {
  144:         &Apache::lonnet::logthis('Dynamic Metadata');
  145:         while(my($k,$v)=each(%Data)){
  146:             &Apache::lonnet::logthis('    "'.$k.'"=>"'.$v.'"');
  147:         }
  148:         &Apache::lonnet::logthis('-------------------');
  149:     }
  150:     return %Data;
  151: }
  152: 
  153: sub access_count {
  154:     my ($src,$author,$adomain) = @_;
  155:     my %countdata=&Apache::lonnet::dump('nohist_accesscount',$adomain,
  156:                                         $author,$src);
  157:     if (! exists($countdata{$src})) {
  158:         return &mt('Not Available');
  159:     } else {
  160:         return $countdata{$src};
  161:     }
  162: }
  163: 
  164: # Try to make an alt tag if there is none
  165: sub alttag {
  166:     my ($base,$src)=@_;
  167:     my $fullpath=&Apache::lonnet::hreflocation($base,$src);
  168:     my $alttag=&Apache::lonnet::metadata($fullpath,'title').' '.
  169:         &Apache::lonnet::metadata($fullpath,'subject').' '.
  170:         &Apache::lonnet::metadata($fullpath,'abstract');
  171:     $alttag=~s/\s+/ /gs;
  172:     $alttag=~s/\"//gs;
  173:     $alttag=~s/\'//gs;
  174:     $alttag=~s/\s+$//gs;
  175:     $alttag=~s/^\s+//gs;
  176:     if ($alttag) { 
  177:         return $alttag; 
  178:     } else { 
  179:         return &mt('No information available'); 
  180:     }
  181: }
  182: 
  183: # Author display
  184: sub authordisplay {
  185:     my ($aname,$adom)=@_;
  186:     return &Apache::loncommon::aboutmewrapper
  187:         (&Apache::loncommon::plainname($aname,$adom),
  188:          $aname,$adom,'preview').' <tt>['.$aname.'@'.$adom.']</tt>';
  189: }
  190: 
  191: # Pretty display
  192: sub evalgraph {
  193:     my $value=shift;
  194:     if (! $value) { 
  195:         return '';
  196:     }
  197:     my $val=int($value*10.+0.5)-10;
  198:     my $output='<table border="0" cellpadding="0" cellspacing="0"><tr>';
  199:     if ($val>=20) {
  200: 	$output.='<td width="20" bgcolor="#555555">&nbsp&nbsp;</td>';
  201:     } else {
  202:         $output.='<td width="'.($val).'" bgcolor="#555555">&nbsp;</td>'.
  203:                  '<td width="'.(20-$val).'" bgcolor="#FF3333">&nbsp;</td>';
  204:     }
  205:     $output.='<td bgcolor="#FFFF33">&nbsp;</td>';
  206:     if ($val>20) {
  207: 	$output.='<td width="'.($val-20).'" bgcolor="#33FF33">&nbsp;</td>'.
  208:                  '<td width="'.(40-$val).'" bgcolor="#555555">&nbsp;</td>';
  209:     } else {
  210:         $output.='<td width="20" bgcolor="#555555">&nbsp&nbsp;</td>';
  211:     }
  212:     $output.='<td> ('.sprintf("%5.2f",$value).') </td></tr></table>';
  213:     return $output;
  214: }
  215: 
  216: sub diffgraph {
  217:     my $value=shift;
  218:     if (! $value) { 
  219:         return '';
  220:     }
  221:     my $val=int(40.0*$value+0.5);
  222:     my @colors=('#FF9933','#EEAA33','#DDBB33','#CCCC33',
  223:                 '#BBDD33','#CCCC33','#DDBB33','#EEAA33');
  224:     my $output='<table border="0" cellpadding="0" cellspacing="0"><tr>';
  225:     for (my $i=0;$i<8;$i++) {
  226: 	if ($val>$i*5) {
  227:             $output.='<td width="5" bgcolor="'.$colors[$i].'">&nbsp;</td>';
  228:         } else {
  229: 	    $output.='<td width="5" bgcolor="#555555">&nbsp;</td>';
  230: 	}
  231:     }
  232:     $output.='<td> ('.sprintf("%3.2f",$value).') </td></tr></table>';
  233:     return $output;
  234: }
  235: 
  236: 
  237: # The field names
  238: sub fieldnames {
  239:     my $file_type=shift;
  240:     my %fields = 
  241:         ('title' => 'Title',
  242:          'author' =>'Author(s)',
  243:          'authorspace' => 'Author Space',
  244:          'modifyinguser' => 'Last Modifying User',
  245:          'subject' => 'Subject',
  246:          'standards' => 'Standards',
  247:          'keywords' => 'Keyword(s)',
  248:          'notes' => 'Notes',
  249:          'abstract' => 'Abstract',
  250:          'lowestgradelevel' => 'Lowest Grade Level',
  251:          'highestgradelevel' => 'Highest Grade Level',
  252:          'courserestricted' => 'Course Restricting Metadata');
  253:          
  254:     if (! defined($file_type) || $file_type ne 'portfolio') {
  255:         %fields = 
  256:         (%fields,
  257:          'domain' => 'Domain',
  258:          'mime' => 'MIME Type',
  259:          'language' => 'Language',
  260:          'creationdate' => 'Creation Date',
  261:          'lastrevisiondate' => 'Last Revision Date',
  262:          'owner' => 'Publisher/Owner',
  263:          'copyright' => 'Copyright/Distribution',
  264:          'customdistributionfile' => 'Custom Distribution File',
  265:          'sourceavail' => 'Source Available',
  266:          'sourcerights' => 'Source Custom Distribution File',
  267:          'obsolete' => 'Obsolete',
  268:          'obsoletereplacement' => 'Suggested Replacement for Obsolete File',
  269:          'count'      => 'Network-wide number of accesses (hits)',
  270:          'course'     => 'Network-wide number of courses using resource',
  271:          'course_list' => 'Network-wide courses using resource',
  272:          'sequsage'      => 'Number of resources using or importing resource',
  273:          'sequsage_list' => 'Resources using or importing resource',
  274:          'goto'       => 'Number of resources that follow this resource in maps',
  275:          'goto_list'  => 'Resources that follow this resource in maps',
  276:          'comefrom'   => 'Number of resources that lead up to this resource in maps',
  277:          'comefrom_list' => 'Resources that lead up to this resource in maps',
  278:          'clear'      => 'Material presented in clear way',
  279:          'depth'      => 'Material covered with sufficient depth',
  280:          'helpful'    => 'Material is helpful',
  281:          'correct'    => 'Material appears to be correct',
  282:          'technical'  => 'Resource is technically correct', 
  283:          'avetries'   => 'Average number of tries till solved',
  284:          'stdno'      => 'Total number of students who have worked on this problem',
  285:          'difficulty' => 'Degree of difficulty',
  286:          'disc'       => 'Degree of discrimination',
  287: 	     'dependencies' => 'Resources used by this resource',
  288:          );
  289:     }
  290:     return &Apache::lonlocal::texthash(%fields);
  291: }
  292: 
  293: sub select_course {
  294:     my ($r)=@_;
  295:     my %courses;
  296:     foreach my $key (keys (%env)) { 
  297:         if ($key =~ m/\.metadata\./) {
  298:             $key =~ m/^course\.(.+)(\.metadata.+$)/;
  299:             my $course = $1;
  300:             my $coursekey = 'course.'.$course.'.description';
  301:             my $value = $env{$coursekey};
  302:             $courses{$coursekey} = $value;
  303:         }
  304:     }
  305:     $r->print('<h3>Course Related Meta-Data</h3><br />');
  306:     $r->print('<form action="" method="post">');
  307:     $r->print('Select course restrictions<br />');
  308:     $r->print('<select name="metacourse" >');
  309:     my $meta_not_found = 1;
  310:     foreach my $key (keys (%courses)) {    
  311:         if ($meta_not_found) {
  312:             undef($meta_not_found);
  313:             $r->print('<h3>Portfolio Meta-Data</h3><br />');
  314:             $r->print('<form action="" method="post">');
  315:             $r->print('Select your course<br />');
  316:             $r->print('<select name="metacourse" >');
  317:         }
  318:         $key =~ m/(^.+)\.description$/;
  319:         $r->print('<option value="'.$1.'">');
  320:         $r->print($courses{$key});
  321:         $r->print('</option>');
  322:     }
  323:     unless ($meta_not_found) {
  324:         $r->print('</select><br />');
  325:         $r->print('<input type="submit" value="Assign Portfolio Metadata" />');
  326:         $r->print('</form>');
  327:     }
  328:     return 'ok';
  329: }
  330: # Pretty printing of metadata field
  331: 
  332: sub prettyprint {
  333:     my ($type,$value,$target,$prefix,$form,$noformat)=@_;
  334: # $target,$prefix,$form are optional and for filecrumbs only
  335:     if (! defined($value)) { 
  336:         return '&nbsp;'; 
  337:     }
  338:     # Title
  339:     if ($type eq 'title') {
  340: 	return '<font size="+1" face="arial">'.$value.'</font>';
  341:     }
  342:     # Dates
  343:     if (($type eq 'creationdate') ||
  344: 	($type eq 'lastrevisiondate')) {
  345: 	return ($value?&Apache::lonlocal::locallocaltime(
  346: 			  &Apache::lonmysql::unsqltime($value)):
  347: 		&mt('not available'));
  348:     }
  349:     # Language
  350:     if ($type eq 'language') {
  351: 	return &Apache::loncommon::languagedescription($value);
  352:     }
  353:     # Copyright
  354:     if ($type eq 'copyright') {
  355: 	return &Apache::loncommon::copyrightdescription($value);
  356:     }
  357:     # Copyright
  358:     if ($type eq 'sourceavail') {
  359: 	return &Apache::loncommon::source_copyrightdescription($value);
  360:     }
  361:     # MIME
  362:     if ($type eq 'mime') {
  363:         return '<img src="'.&Apache::loncommon::icon($value).'" />&nbsp;'.
  364:             &Apache::loncommon::filedescription($value);
  365:     }
  366:     # Person
  367:     if (($type eq 'author') || 
  368: 	($type eq 'owner') ||
  369: 	($type eq 'modifyinguser') ||
  370: 	($type eq 'authorspace')) {
  371: 	$value=~s/(\w+)(\:|\@)(\w+)/&authordisplay($1,$3)/gse;
  372: 	return $value;
  373:     }
  374:     # Gradelevel
  375:     if (($type eq 'lowestgradelevel') ||
  376: 	($type eq 'highestgradelevel')) {
  377: 	return &Apache::loncommon::gradeleveldescription($value);
  378:     }
  379:     # Only for advance users below
  380:     if (! $env{'user.adv'}) { 
  381:         return '<i>- '.&mt('not displayed').' -</i>';
  382:     }
  383:     # File
  384:     if (($type eq 'customdistributionfile') ||
  385: 	($type eq 'obsoletereplacement') ||
  386: 	($type eq 'goto_list') ||
  387: 	($type eq 'comefrom_list') ||
  388: 	($type eq 'sequsage_list') ||
  389: 	($type eq 'dependencies')) {
  390: 	return '<ul><font size="-1">'.join("\n",map {
  391:             my $url = &Apache::lonnet::clutter($_);
  392:             my $title = &Apache::lonnet::gettitle($url);
  393:             if ($title eq '') {
  394:                 $title = 'Untitled';
  395:                 if ($url =~ /\.sequence$/) {
  396:                     $title .= ' Sequence';
  397:                 } elsif ($url =~ /\.page$/) {
  398:                     $title .= ' Page';
  399:                 } elsif ($url =~ /\.problem$/) {
  400:                     $title .= ' Problem';
  401:                 } elsif ($url =~ /\.html$/) {
  402:                     $title .= ' HTML document';
  403:                 } elsif ($url =~ m:/syllabus$:) {
  404:                     $title .= ' Syllabus';
  405:                 } 
  406:             }
  407:             $_ = '<li>'.$title.' '.
  408: 		&Apache::lonhtmlcommon::crumbs($url,$target,$prefix,$form,'-1',$noformat).
  409:                 '</li>'
  410: 	    } split(/\s*\,\s*/,$value)).'</ul></font>';
  411:     }
  412:     # Evaluations
  413:     if (($type eq 'clear') ||
  414: 	($type eq 'depth') ||
  415: 	($type eq 'helpful') ||
  416: 	($type eq 'correct') ||
  417: 	($type eq 'technical')) {
  418: 	return &evalgraph($value);
  419:     }
  420:     # Difficulty
  421:     if ($type eq 'difficulty' || $type eq 'disc') {
  422: 	return &diffgraph($value);
  423:     }
  424:     # List of courses
  425:     if ($type=~/\_list/) {
  426:         my @Courses = split(/\s*\,\s*/,$value);
  427:         my $Str;
  428:         foreach my $course (@Courses) {
  429:             my %courseinfo = &Apache::lonnet::coursedescription($course);
  430:             if (! exists($courseinfo{'num'}) || $courseinfo{'num'} eq '') {
  431:                 next;
  432:             }
  433:             if ($Str ne '') { $Str .= '<br />'; }
  434:             $Str .= '<a href="/public/'.$courseinfo{'domain'}.'/'.
  435:                 $courseinfo{'num'}.'/syllabus" target="preview">'.
  436:                 $courseinfo{'description'}.'</a>';
  437:         }
  438: 	return $Str;
  439:     }
  440:     # No pretty print found
  441:     return $value;
  442: }
  443: 
  444: # Pretty input of metadata field
  445: sub direct {
  446:     return shift;
  447: }
  448: 
  449: sub selectbox {
  450:     my ($name,$value,$functionref,@idlist)=@_;
  451:     if (! defined($functionref)) {
  452:         $functionref=\&direct;
  453:     }
  454:     my $selout='<select name="'.$name.'">';
  455:     foreach (@idlist) {
  456:         $selout.='<option value=\''.$_.'\'';
  457:         if ($_ eq $value) {
  458: 	    $selout.=' selected>'.&{$functionref}($_).'</option>';
  459: 	}
  460:         else {$selout.='>'.&{$functionref}($_).'</option>';}
  461:     }
  462:     return $selout.'</select>';
  463: }
  464: 
  465: sub relatedfield {
  466:     my ($show,$relatedsearchflag,$relatedsep,$fieldname,$relatedvalue)=@_;
  467:     if (! $relatedsearchflag) { 
  468:         return '';
  469:     }
  470:     if (! defined($relatedsep)) {
  471:         $relatedsep=' ';
  472:     }
  473:     if (! $show) {
  474:         return $relatedsep.'&nbsp;';
  475:     }
  476:     return $relatedsep.'<input type="checkbox" name="'.$fieldname.'_related"'.
  477: 	($relatedvalue?' checked="1"':'').' />';
  478: }
  479: 
  480: sub prettyinput {
  481:     my ($type,$value,$fieldname,$formname,
  482: 	$relatedsearchflag,$relatedsep,$relatedvalue,$size,$course_key)=@_;
  483:     if (! defined($size)) {
  484:         $size = 80;
  485:     }
  486:     my $output;
  487:     if (defined($course_key)) {
  488:         my $stu_add;
  489:         my $only_one;
  490:         my %meta_options;
  491:         my @cur_values_inst;
  492:         my $cur_values_stu;
  493:         my $values = $env{$course_key.'.metadata.'.$type.'.values'};
  494:         if ($env{$course_key.'.metadata.'.$type.'.options'} =~ m/stuadd/) {
  495:             $stu_add = 'true';
  496:         }
  497:         if ($env{$course_key.'.metadata.'.$type.'.options'} =~ m/onlyone/) {
  498:             $only_one = 'true';
  499:         }
  500:         # need to take instructor values out of list where instructor and student
  501:         # values may be mixed.
  502:         if ($values) {
  503:             foreach my $item (split(/,/,$values)) {
  504:                 $item =~ s/^\s+//;
  505:                 $meta_options{$item} = $item;
  506:             }
  507:             foreach my $item (split(/,/,$value)) {
  508:                 $item =~ s/^\s+//;
  509:                 if ($meta_options{$item}) {
  510:                     push(@cur_values_inst,$item);
  511:                 } else {
  512:                     $cur_values_stu .= $item.',';
  513:                 }
  514:             }
  515:         } else {
  516:             $cur_values_stu = $value;
  517:         }
  518:         if ($type eq 'courserestricted') {
  519:             return ('<input type="hidden" name="new_courserestricted" value="'.$course_key.'" />');
  520:         }
  521:         if (($type eq 'keywords') || ($type eq 'subject')
  522:              || ($type eq 'author')||($type eq  'notes')
  523:              || ($type eq  'abstract')|| ($type eq  'title')|| ($type eq  'standards')) {
  524:             if ($values) {
  525:                 if ($only_one) {
  526:                     $output .= (&Apache::loncommon::select_form($cur_values_inst[0],'new_'.$type,%meta_options));
  527:                 } else {
  528:                     $output .= (&Apache::loncommon::multiple_select_form('new_'.$type,\@cur_values_inst,undef,\%meta_options));
  529:                 }
  530:             }
  531:             if ($stu_add) {
  532:                 $output .= '<input type="text" name="'.$fieldname.'" size="'.$size.'" '.
  533:                 'value="'.$cur_values_stu.'" />'.
  534:                 &relatedfield(1,$relatedsearchflag,$relatedsep,$fieldname,
  535:                       $relatedvalue); 
  536:             }
  537:             return ($output);
  538:         }
  539:         if (($type eq 'lowestgradelevel') ||
  540: 	    ($type eq 'highestgradelevel')) {
  541: 	    return &Apache::loncommon::select_level_form($value,$fieldname).
  542:             &relatedfield(0,$relatedsearchflag,$relatedsep); 
  543:         }
  544:         return(); 
  545:     }
  546:     # Language
  547:     if ($type eq 'language') {
  548: 	return &selectbox($fieldname,
  549: 			  $value,
  550: 			  \&Apache::loncommon::languagedescription,
  551: 			  (&Apache::loncommon::languageids)).
  552:                               &relatedfield(0,$relatedsearchflag,$relatedsep);
  553:     }
  554:     # Copyright
  555:     if ($type eq 'copyright') {
  556: 	return &selectbox($fieldname,
  557: 			  $value,
  558: 			  \&Apache::loncommon::copyrightdescription,
  559: 			  (&Apache::loncommon::copyrightids)).
  560:                               &relatedfield(0,$relatedsearchflag,$relatedsep);
  561:     }
  562:     # Source Copyright
  563:     if ($type eq 'sourceavail') {
  564: 	return &selectbox($fieldname,
  565: 			  $value,
  566: 			  \&Apache::loncommon::source_copyrightdescription,
  567: 			  (&Apache::loncommon::source_copyrightids)).
  568:                               &relatedfield(0,$relatedsearchflag,$relatedsep);
  569:     }
  570:     # Gradelevels
  571:     if (($type eq 'lowestgradelevel') ||
  572: 	($type eq 'highestgradelevel')) {
  573: 	return &Apache::loncommon::select_level_form($value,$fieldname).
  574:             &relatedfield(0,$relatedsearchflag,$relatedsep);
  575:     }
  576:     # Obsolete
  577:     if ($type eq 'obsolete') {
  578: 	return '<input type="checkbox" name="'.$fieldname.'"'.
  579: 	    ($value?' checked="1"':'').' />'.
  580:             &relatedfield(0,$relatedsearchflag,$relatedsep); 
  581:     }
  582:     # Obsolete replacement file
  583:     if ($type eq 'obsoletereplacement') {
  584: 	return '<input type="text" name="'.$fieldname.
  585: 	    '" size="60" value="'.$value.'" /><a href="javascript:openbrowser'.
  586: 	    "('".$formname."','".$fieldname."'".
  587: 	    ",'')\">".&mt('Select').'</a>'.
  588:             &relatedfield(0,$relatedsearchflag,$relatedsep); 
  589:     }
  590:     # Customdistribution file
  591:     if ($type eq 'customdistributionfile') {
  592: 	return '<input type="text" name="'.$fieldname.
  593: 	    '" size="60" value="'.$value.'" /><a href="javascript:openbrowser'.
  594: 	    "('".$formname."','".$fieldname."'".
  595: 	    ",'rights')\">".&mt('Select').'</a>'.
  596:             &relatedfield(0,$relatedsearchflag,$relatedsep); 
  597:     }
  598:     # Source Customdistribution file
  599:     if ($type eq 'sourcerights') {
  600: 	return '<input type="text" name="'.$fieldname.
  601: 	    '" size="60" value="'.$value.'" /><a href="javascript:openbrowser'.
  602: 	    "('".$formname."','".$fieldname."'".
  603: 	    ",'rights')\">".&mt('Select').'</a>'.
  604:             &relatedfield(0,$relatedsearchflag,$relatedsep); 
  605:     }
  606:     if ($type eq 'courserestricted') {
  607:             return ('<input type="hidden" name="new_courserestricted" value="'.$course_key.'" />');
  608:     }
  609: 
  610:     # Dates
  611:     if (($type eq 'creationdate') ||
  612: 	($type eq 'lastrevisiondate')) {
  613: 	return 
  614:             &Apache::lonhtmlcommon::date_setter($formname,$fieldname,$value).
  615:             &relatedfield(0,$relatedsearchflag,$relatedsep);
  616:     }
  617:     # No pretty input found
  618:     $value=~s/^\s+//gs;
  619:     $value=~s/\s+$//gs;
  620:     $value=~s/\s+/ /gs;
  621:     $value=~s/\"/\&quot\;/gs;
  622:     return 
  623:         '<input type="text" name="'.$fieldname.'" size="'.$size.'" '.
  624:         'value="'.$value.'" />'.
  625:         &relatedfield(1,$relatedsearchflag,$relatedsep,$fieldname,
  626:                       $relatedvalue); 
  627: }
  628: 
  629: # Main Handler
  630: sub handler {
  631:     my $r=shift;
  632:     #
  633:     my $uri=$r->uri;
  634:     #
  635:     # Set document type
  636:     &Apache::loncommon::content_type($r,'text/html');
  637:     $r->send_http_header;
  638:     return OK if $r->header_only;
  639:     #
  640:     my ($resdomain,$resuser)=
  641:         (&Apache::lonnet::declutter($uri)=~/^(\w+)\/(\w+)\//);
  642:     my $html=&Apache::lonxml::xmlbegin();
  643:     $r->print($html.'<head><title>'.
  644:               'Catalog Information'.
  645:               '</title></head>');
  646:     if ($uri=~m:/adm/bombs/(.*)$:) {
  647:         $r->print(&Apache::loncommon::bodytag('Error Messages'));
  648:         # Looking for all bombs?
  649:         &report_bombs($r,$uri);
  650:     } elsif ($uri=~/\/portfolio\//) {
  651: 	($resdomain,$resuser)=
  652: 	    (&Apache::lonnet::declutter($uri)=~m|^(\w+)/(\w+)/portfolio|);
  653:         $r->print(&Apache::loncommon::bodytag
  654:           ('Edit Portfolio File Information','','','',$resdomain));
  655:         &present_editable_metadata($r,$uri,'portfolio');
  656:         &select_course($r);
  657:     } elsif ($uri=~/^\/\~/) { 
  658:         # Construction space
  659:         $r->print(&Apache::loncommon::bodytag
  660:                   ('Edit Catalog Information','','','',$resdomain));
  661:         &present_editable_metadata($r,$uri);
  662:     } else {
  663:         $r->print(&Apache::loncommon::bodytag
  664: 		  ('Catalog Information','','','',$resdomain));
  665:         &present_uneditable_metadata($r,$uri);
  666:     }
  667:     $r->print('</body></html>');
  668:     return OK;
  669: }
  670: 
  671: #####################################################
  672: #####################################################
  673: ###                                               ###
  674: ###                Report Bombs                   ###
  675: ###                                               ###
  676: #####################################################
  677: #####################################################
  678: sub report_bombs {
  679:     my ($r,$uri) = @_;
  680:     # Set document type
  681:     $uri =~ s:/adm/bombs/::;
  682:     $uri = &Apache::lonnet::declutter($uri);
  683:     $r->print('<h1>'.&Apache::lonnet::clutter($uri).'</h1>');
  684:     my ($domain,$author)=($uri=~/^(\w+)\/(\w+)\//);
  685:     if (&Apache::loncacc::constructaccess('/~'.$author.'/',$domain)) {
  686: 	if ($env{'form.clearbombs'}) {
  687: 	    &Apache::lonmsg::clear_author_res_msg($uri);
  688: 	}
  689:         my $clear=&mt('Clear all Messages in Subdirectory');
  690: 	$r->print(<<ENDCLEAR);
  691: <form method="post">
  692: <input type="submit" name="clearbombs" value="$clear" />
  693: </form>
  694: ENDCLEAR
  695:         my %brokenurls = 
  696:             &Apache::lonmsg::all_url_author_res_msg($author,$domain);
  697:         foreach (sort(keys(%brokenurls))) {
  698:             if ($_=~/^\Q$uri\E/) {
  699:                 $r->print
  700:                     ('<a href="'.&Apache::lonnet::clutter($_).'">'.$_.'</a>'.
  701:                      &Apache::lonmsg::retrieve_author_res_msg($_).
  702:                      '<hr />');
  703:             }
  704:         }
  705:     } else {
  706:         $r->print(&mt('Not authorized'));
  707:     }
  708:     return;
  709: }
  710: 
  711: #####################################################
  712: #####################################################
  713: ###                                               ###
  714: ###        Uneditable Metadata Display            ###
  715: ###                                               ###
  716: #####################################################
  717: #####################################################
  718: sub present_uneditable_metadata {
  719:     my ($r,$uri) = @_;
  720:     #
  721:     my %content=();
  722:     # Read file
  723:     foreach (split(/\,/,&Apache::lonnet::metadata($uri,'keys'))) {
  724:         $content{$_}=&Apache::lonnet::metadata($uri,$_);
  725:     }
  726:     # Render Output
  727:     # displayed url
  728:     my ($thisversion)=($uri=~/\.(\d+)\.(\w+)\.meta$/);
  729:     $uri=~s/\.meta$//;
  730:     my $disuri=&Apache::lonnet::clutter($uri);
  731:     # version
  732:     my $currentversion=&Apache::lonnet::getversion($disuri);
  733:     my $versiondisplay='';
  734:     if ($thisversion) {
  735:         $versiondisplay=&mt('Version').': '.$thisversion.
  736:             ' ('.&mt('most recent version').': '.
  737:             ($currentversion>0 ? 
  738:              $currentversion   :
  739:              &mt('information not available')).')';
  740:     } else {
  741:         $versiondisplay='Version: '.$currentversion;
  742:     }
  743:     # crumbify displayed URL               uri     target prefix form  size
  744:     $disuri=&Apache::lonhtmlcommon::crumbs($disuri,undef, undef, undef,'+1');
  745:     $disuri =~ s:<br />::g;
  746:     # obsolete
  747:     my $obsolete=$content{'obsolete'};
  748:     my $obsoletewarning='';
  749:     if (($obsolete) && ($env{'user.adv'})) {
  750:         $obsoletewarning='<p><font color="red">'.
  751:             &mt('This resource has been marked obsolete by the author(s)').
  752:             '</font></p>';
  753:     }
  754:     #
  755:     my %lt=&fieldnames();
  756:     my $table='';
  757:     my $title = $content{'title'};
  758:     if (! defined($title)) {
  759:         $title = 'Untitled Resource';
  760:     }
  761:     foreach ('title', 
  762:              'author', 
  763:              'subject', 
  764:              'keywords', 
  765:              'notes', 
  766:              'abstract',
  767:              'lowestgradelevel',
  768:              'highestgradelevel',
  769:              'standards', 
  770:              'mime', 
  771:              'language', 
  772:              'creationdate', 
  773:              'lastrevisiondate', 
  774:              'owner', 
  775:              'copyright', 
  776:              'customdistributionfile',
  777:              'sourceavail',
  778:              'sourcerights', 
  779:              'obsolete', 
  780:              'obsoletereplacement') {
  781:         $table.='<tr><td bgcolor="#AAAAAA">'.$lt{$_}.
  782:             '</td><td bgcolor="#CCCCCC">'.
  783:             &prettyprint($_,$content{$_}).'</td></tr>';
  784:         delete $content{$_};
  785:     }
  786:     #
  787:     $r->print(<<ENDHEAD);
  788: <h2>$title</h2>
  789: <p>
  790: $disuri<br />
  791: $obsoletewarning
  792: $versiondisplay
  793: </p>
  794: <table cellspacing="2" border="0">
  795: $table
  796: </table>
  797: ENDHEAD
  798:     if ($env{'user.adv'}) {
  799:         &print_dynamic_metadata($r,$uri,\%content);
  800:     }
  801:     return;
  802: }
  803: 
  804: sub print_dynamic_metadata {
  805:     my ($r,$uri,$content) = @_;
  806:     #
  807:     my %content = %$content;
  808:     my %lt=&fieldnames();
  809:     #
  810:     my $description = 'Dynamic Metadata (updated periodically)';
  811:     $r->print('<h3>'.&mt($description).'</h3>'.
  812:               &mt('Processing'));
  813:     $r->rflush();
  814:     my %items=&fieldnames();
  815:     my %dynmeta=&dynamicmeta($uri);
  816:     #
  817:     # General Access and Usage Statistics
  818:     if (exists($dynmeta{'count'}) ||
  819:         exists($dynmeta{'sequsage'}) ||
  820:         exists($dynmeta{'comefrom'}) ||
  821:         exists($dynmeta{'goto'}) ||
  822:         exists($dynmeta{'course'})) {
  823:         $r->print('<h4>'.&mt('Access and Usage Statistics').'</h4>'.
  824:                   '<table cellspacing="2" border="0">');
  825:         foreach ('count',
  826:                  'sequsage','sequsage_list',
  827:                  'comefrom','comefrom_list',
  828:                  'goto','goto_list',
  829:                  'course','course_list') {
  830:             $r->print('<tr><td bgcolor="#AAAAAA">'.$lt{$_}.'</td>'.
  831:                       '<td bgcolor="#CCCCCC">'.
  832:                       &prettyprint($_,$dynmeta{$_})."</td></tr>\n");
  833:         }
  834:         $r->print('</table>');
  835:     } else {
  836:         $r->print('<h4>'.&mt('No Access or Usages Statistics are available for this resource.').'</h4>');
  837:     }
  838:     #
  839:     # Assessment statistics
  840:     if ($uri=~/\.(problem|exam|quiz|assess|survey|form)$/) {
  841:         if (exists($dynmeta{'stdno'}) ||
  842:             exists($dynmeta{'avetries'}) ||
  843:             exists($dynmeta{'difficulty'}) ||
  844:             exists($dynmeta{'disc'})) {
  845:             # This is an assessment, print assessment data
  846:             $r->print('<h4>'.
  847:                       &mt('Overall Assessment Statistical Data').
  848:                       '</h4>'.
  849:                       '<table cellspacing="2" border="0">');
  850:             $r->print('<tr><td bgcolor="#AAAAAA">'.$lt{'stdno'}.'</td>'.
  851:                       '<td bgcolor="#CCCCCC">'.
  852:                       &prettyprint('stdno',$dynmeta{'stdno'}).
  853:                       '</td>'."</tr>\n");
  854:             foreach ('avetries','difficulty','disc') {
  855:                 $r->print('<tr><td bgcolor="#AAAAAA">'.$lt{$_}.'</td>'.
  856:                           '<td bgcolor="#CCCCCC">'.
  857:                           &prettyprint($_,sprintf('%5.2f',$dynmeta{$_})).
  858:                           '</td>'."</tr>\n");
  859:             }
  860:             $r->print('</table>');    
  861:         }
  862:         if (exists($dynmeta{'stats'})) {
  863:             #
  864:             # New assessment statistics
  865:             $r->print('<h4>'.
  866:                       &mt('Detailed Assessment Statistical Data').
  867:                       '</h4>');
  868:             my $table = '<table cellspacing="2" border="0">'.
  869:                 '<tr>'.
  870:                 '<th>Course</th>'.
  871:                 '<th>Section(s)</th>'.
  872:                 '<th>Num Students</th>'.
  873:                 '<th>Mean Tries</th>'.
  874:                 '<th>Degree of Difficulty</th>'.
  875:                 '<th>Degree of Discrimination</th>'.
  876:                 '<th>Time of computation</th>'.
  877:                 '</tr>'.$/;
  878:             foreach my $identifier (sort(keys(%{$dynmeta{'stats'}}))) {
  879:                 my $data = $dynmeta{'stats'}->{$identifier};
  880:                 my $course = $data->{'course'};
  881:                 my %courseinfo = &Apache::lonnet::coursedescription($course);
  882:                 if (! exists($courseinfo{'num'}) || $courseinfo{'num'} eq '') {
  883:                     &Apache::lonnet::logthis('lookup for '.$course.' failed');
  884:                     next;
  885:                 }
  886:                 $table .= '<tr>';
  887:                 $table .= 
  888:                     '<td><nobr>'.$courseinfo{'description'}.'</nobr></td>';
  889:                 $table .= 
  890:                     '<td align="right">'.$data->{'sections'}.'</td>';
  891:                 $table .=
  892:                     '<td align="right">'.$data->{'stdno'}.'</td>';
  893:                 foreach ('avetries','difficulty','disc') {
  894:                     $table .= '<td align="right">';
  895:                     if (exists($data->{$_})) {
  896:                         $table .= sprintf('%.2f',$data->{$_}).'&nbsp;';
  897:                     } else {
  898:                         $table .= '';
  899:                     }
  900:                     $table .= '</td>';
  901:                 }
  902:                 $table .=
  903:                     '<td><nobr>'.
  904:                     &Apache::lonlocal::locallocaltime($data->{'timestamp'}).
  905:                     '</nobr></td>';
  906:                 $table .=
  907:                     '</tr>'.$/;
  908:             }
  909:             $table .= '</table>'.$/;
  910:             $r->print($table);
  911:         } else {
  912:             $r->print('No new dynamic data found.');
  913:         }
  914:     } else {
  915:         $r->print('<h4>'.
  916:           &mt('No Assessment Statistical Data is available for this resource').
  917:                   '</h4>');
  918:     }
  919: 
  920:     #
  921:     #
  922:     if (exists($dynmeta{'clear'})   || 
  923:         exists($dynmeta{'depth'})   || 
  924:         exists($dynmeta{'helpful'}) || 
  925:         exists($dynmeta{'correct'}) || 
  926:         exists($dynmeta{'technical'})){ 
  927:         $r->print('<h4>'.&mt('Evaluation Data').'</h4>'.
  928:                   '<table cellspacing="2" border="0">');
  929:         foreach ('clear','depth','helpful','correct','technical') {
  930:             $r->print('<tr><td bgcolor="#AAAAAA">'.$lt{$_}.'</td>'.
  931:                       '<td bgcolor="#CCCCCC">'.
  932:                       &prettyprint($_,$dynmeta{$_})."</td></tr>\n");
  933:         }
  934:         $r->print('</table>');
  935:     } else {
  936:         $r->print('<h4>'.&mt('No Evaluation Data is available for this resource.').'</h4>');
  937:     }
  938:     $uri=~/^\/res\/(\w+)\/(\w+)\//; 
  939:     if ((($env{'user.domain'} eq $1) && ($env{'user.name'} eq $2))
  940:         || ($env{'user.role.ca./'.$1.'/'.$2})) {
  941:         if (exists($dynmeta{'comments'})) {
  942:             $r->print('<h4>'.&mt('Evaluation Comments').' ('.
  943:                       &mt('visible to author and co-authors only').
  944:                       ')</h4>'.
  945:                       '<blockquote>'.$dynmeta{'comments'}.'</blockquote>');
  946:         } else {
  947:             $r->print('<h4>'.&mt('There are no Evaluation Comments on this resource.').'</h4>');
  948:         }
  949:         my $bombs = &Apache::lonmsg::retrieve_author_res_msg($uri);
  950:         if (defined($bombs) && $bombs ne '') {
  951:             $r->print('<a name="bombs" /><h4>'.&mt('Error Messages').' ('.
  952:                       &mt('visible to author and co-authors only').')'.
  953:                       '</h4>'.$bombs);
  954:         } else {
  955:             $r->print('<h4>'.&mt('There are currently no Error Messages for this resource.').'</h4>');
  956:         }
  957:     }
  958:     #
  959:     # All other stuff
  960:     $r->print('<h3>'.
  961:               &mt('Additional Metadata (non-standard, parameters, exports)').
  962:               '</h3><table border="0" cellspacing="1">');
  963:     foreach (sort(keys(%content))) {
  964:         my $name=$_;
  965:         if ($name!~/\.display$/) {
  966:             my $display=&Apache::lonnet::metadata($uri,
  967:                                                   $name.'.display');
  968:             if (! $display) { 
  969:                 $display=$name;
  970:             };
  971:             my $otherinfo='';
  972:             foreach ('name','part','type','default') {
  973:                 if (defined(&Apache::lonnet::metadata($uri,
  974:                                                       $name.'.'.$_))) {
  975:                     $otherinfo.=' '.$_.'='.
  976:                         &Apache::lonnet::metadata($uri,
  977:                                                   $name.'.'.$_).'; ';
  978:                 }
  979:             }
  980:             $r->print('<tr><td bgcolor="#bbccbb"><font size="-1" color="#556655">'.$display.'</font></td><td bgcolor="#ccddcc"><font size="-1" color="#556655">'.$content{$name});
  981:             if ($otherinfo) {
  982:                 $r->print(' ('.$otherinfo.')');
  983:             }
  984:             $r->print("</font></td></tr>\n");
  985:         }
  986:     }
  987:     $r->print("</table>");
  988:     return;
  989: }
  990: 
  991: 
  992: 
  993: #####################################################
  994: #####################################################
  995: ###                                               ###
  996: ###          Editable metadata display            ###
  997: ###                                               ###
  998: #####################################################
  999: #####################################################
 1000: sub present_editable_metadata {
 1001:     my ($r,$uri, $file_type) = @_;
 1002:     # Construction Space Call
 1003:     # Header
 1004:     my $disuri=$uri;
 1005:     my $fn=&Apache::lonnet::filelocation('',$uri);
 1006:     $disuri=~s/^\/\~/\/priv\//;
 1007:     $disuri=~s/\.meta$//;
 1008:     $disuri=~s|^/editupload||;
 1009:     my $target=$uri;
 1010:     $target=~s/^\/\~/\/res\/$env{'request.role.domain'}\//;
 1011:     $target=~s/\.meta$//;
 1012:     my $bombs=&Apache::lonmsg::retrieve_author_res_msg($target);
 1013:     if ($bombs) {
 1014:         my $showdel=1;
 1015:         if ($env{'form.delmsg'}) {
 1016:             if (&Apache::lonmsg::del_url_author_res_msg($target) eq 'ok') {
 1017:                 $bombs=&mt('Messages deleted.');
 1018: 		$showdel=0;
 1019:             } else {
 1020:                 $bombs=&mt('Error deleting messages');
 1021:             }
 1022:         }
 1023:         if ($env{'form.clearmsg'}) {
 1024: 	    my $cleardir=$target;
 1025: 	    $cleardir=~s/\/[^\/]+$/\//;
 1026:             if (&Apache::lonmsg::clear_author_res_msg($cleardir) eq 'ok') {
 1027:                 $bombs=&mt('Messages cleared.');
 1028: 		$showdel=0;
 1029:             } else {
 1030:                 $bombs=&mt('Error clearing messages');
 1031:             }
 1032:         }
 1033:         my $del=&mt('Delete Messages for this Resource');
 1034: 	my $clear=&mt('Clear all Messages in Subdirectory');
 1035: 	my $goback=&mt('Back to Source File');
 1036:         $r->print(<<ENDBOMBS);
 1037: <h1>$disuri</h1>
 1038: <form method="post" name="defaultmeta">
 1039: ENDBOMBS
 1040:         if ($showdel) {
 1041: 	    $r->print(<<ENDDEL);
 1042: <input type="submit" name="delmsg" value="$del" />
 1043: <input type="submit" name="clearmsg" value="$clear" />
 1044: ENDDEL
 1045:         } else {
 1046:             $r->print('<a href="'.$disuri.'" />'.$goback.'</a>');
 1047: 	}
 1048: 	$r->print('<br />'.$bombs);
 1049:     } else {
 1050:         my $displayfile='Catalog Information for '.$disuri;
 1051:         if ($disuri=~/\/default$/) {
 1052:             my $dir=$disuri;
 1053:             $dir=~s/default$//;
 1054:             $displayfile=
 1055:                 &mt('Default Cataloging Information for Directory').' '.
 1056:                 $dir;
 1057:         }
 1058:         %Apache::lonpublisher::metadatafields=();
 1059:         %Apache::lonpublisher::metadatakeys=();
 1060:         my $result=&Apache::lonnet::getfile($fn);
 1061:         if ($result == -1){
 1062:             $r->print('Creating new '.$disuri);
 1063:         } else {
 1064:             &Apache::lonpublisher::metaeval($result);
 1065:         }
 1066:         $r->print(<<ENDEDIT);
 1067: <h1>$displayfile</h1>
 1068: <form method="post" name="defaultmeta">
 1069: ENDEDIT
 1070:         $r->print('<script language="JavaScript">'.
 1071:                   &Apache::loncommon::browser_and_searcher_javascript().
 1072:                   '</script>');
 1073:         my %lt=&fieldnames($file_type);
 1074: 	my $output;
 1075: 	my @fields;
 1076: 	if ($file_type eq 'portfolio') {
 1077: 	    @fields =  ('author','title','subject','keywords','abstract','notes','lowestgradelevel',
 1078: 	                'highestgradelevel','standards','courserestricted');
 1079: 	} else {
 1080: 	    @fields = ('author','title','subject','keywords','abstract','notes',
 1081:                  'copyright','customdistributionfile','language',
 1082:                  'standards',
 1083:                  'lowestgradelevel','highestgradelevel','sourceavail','sourcerights',
 1084:                  'obsolete','obsoletereplacement');
 1085:         }
 1086:         my $metacourse;
 1087:         if ($env{'form.metacourse'} ) {
 1088:             $Apache::lonpublisher::metadatafields{'courserestricted'} = $env{'form.metacourse'};
 1089:             $metacourse = $env{'form.metacourse'};
 1090:          } else {
 1091:             if (! $Apache::lonpublisher::metadatafields{'courserestricted'}) {
 1092:                 $Apache::lonpublisher::metadatafields{'courserestricted'}=
 1093:                     'none';
 1094:                 $metacourse = 'none';
 1095:             } else {
 1096:                 $metacourse = $Apache::lonpublisher::metadatafields{'courserestricted'};
 1097:             }
 1098:         }
 1099:         if (! $Apache::lonpublisher::metadatafields{'copyright'}) {
 1100:                 $Apache::lonpublisher::metadatafields{'copyright'}=
 1101:                 'default';
 1102:         }
 1103:         if ($metacourse ne 'none') {
 1104:              $r->print('Using: <strong> '.$env{$metacourse.".description"}."</strong> metadata framework<br />");
 1105:         }
 1106:         foreach my $field_name(@fields) {
 1107: 
 1108:             if (defined($env{'form.new_'.$field_name})) {
 1109:                 $Apache::lonpublisher::metadatafields{$field_name}=
 1110:                     join(',',&Apache::loncommon::get_env_multiple('form.new_'.$field_name));
 1111:             }
 1112:             if ($metacourse ne 'none') {
 1113:                 # handle restrictions here
 1114:                 if ($env{$metacourse.'.metadata.'.$field_name.'.options'} =~ m/active/){
 1115:                     $output.=('<p>'.$lt{$field_name}.': '.
 1116:                               &prettyinput($field_name,
 1117: 				   $Apache::lonpublisher::metadatafields{$field_name},
 1118: 				   'new_'.$field_name,'defaultmeta',undef,undef,undef,undef,$metacourse).'</p>');
 1119:                  } elsif ($field_name eq 'courserestricted') {
 1120:                             $output.=(
 1121:                                 &prettyinput($field_name,
 1122: 				    $Apache::lonpublisher::metadatafields{$field_name},
 1123: 				    'new_'.$field_name,'defaultmeta',undef,undef,undef,undef,$metacourse));
 1124:                  }
 1125:             } else {
 1126:                 if ($field_name ne 'courserestricted') {
 1127:                     $output.=('<p>'.$lt{$field_name}.': '.
 1128:                             &prettyinput($field_name,
 1129: 				   $Apache::lonpublisher::metadatafields{$field_name},
 1130: 				   'new_'.$field_name,'defaultmeta').'</p>');
 1131: 	        } else {
 1132:                     $output.=&prettyinput($field_name,
 1133: 				   $Apache::lonpublisher::metadatafields{$field_name},
 1134: 				   'new_'.$field_name,'defaultmeta');
 1135:                 }
 1136:             }
 1137:         }
 1138:         if ($env{'form.store'}) {
 1139:             my $mfh;
 1140:             my $formname='store'; 
 1141:             my $file_content;
 1142:             foreach my $meta_field (keys %env) {
 1143:                 if (&Apache::loncommon::get_env_multiple('form.new_keywords')) {
 1144:                     $Apache::lonpublisher::metadatafields{'keywords'} = 
 1145:                         join (',', &Apache::loncommon::get_env_multiple('form.new_keywords'));
 1146:                 }
 1147:             }
 1148:             foreach (sort keys %Apache::lonpublisher::metadatafields) {
 1149:                 next if ($_ =~ /\./);
 1150:                 my $unikey=$_;
 1151:                 $unikey=~/^([A-Za-z]+)/;
 1152:                 my $tag=$1;
 1153:                 $tag=~tr/A-Z/a-z/;
 1154:                 $file_content.= "\n\<$tag";
 1155:                 foreach (split(/\,/,
 1156:                              $Apache::lonpublisher::metadatakeys{$unikey})
 1157:                          ) {
 1158:                     my $value=
 1159:                     $Apache::lonpublisher::metadatafields{$unikey.'.'.$_};
 1160:                     $value=~s/\"/\'\'/g;
 1161:                     $file_content.=' '.$_.'="'.$value.'"' ;
 1162:                     # print $mfh ' '.$_.'="'.$value.'"';
 1163:                 }
 1164:                 $file_content.= '>'.
 1165:                     &HTML::Entities::encode
 1166:                     ($Apache::lonpublisher::metadatafields{$unikey},
 1167:                      '<>&"').
 1168:                      '</'.$tag.'>';
 1169:             }
 1170:             if ($fn =~ /\/portfolio\//) {
 1171:                 $fn =~ /\/portfolio\/(.*)$/;
 1172:                 my $new_fn = '/'.$1;
 1173:                 $env{'form.'.$formname}=$file_content."\n";
 1174:                 $env{'form.'.$formname.'.filename'}=$new_fn;
 1175:                 &Apache::lonnet::userfileupload('uploaddoc','',
 1176: 	        	 'portfolio'.$env{'form.currentpath'});
 1177:                 if (&Apache::lonnet::userfileupload($formname,'','portfolio') eq 'error: no uploaded file') {
 1178:                     $r->print('<p><font color="red">'.
 1179:                       &mt('Could not write metadata').', '.
 1180:                      &mt('FAIL').'</font></p>');
 1181:                 } else {
 1182:                     $r->print('<p><font color="blue">'.&mt('Wrote Metadata').
 1183: 		  ' '.&Apache::lonlocal::locallocaltime(time).
 1184: 		  '</font></p>');
 1185:                 }
 1186:             } else {
 1187:                 if (!  ($mfh=Apache::File->new('>'.$fn))) {
 1188:                     $r->print('<p><font color="red">'.
 1189:                         &mt('Could not write metadata').', '.
 1190:                         &mt('FAIL').'</font></p>');
 1191:                 } else {
 1192:                     print $mfh $file_content;
 1193: 		    $r->print('<p><font color="blue">'.&mt('Wrote Metadata').
 1194: 			      ' '.&Apache::lonlocal::locallocaltime(time).
 1195: 			      '</font></p>');
 1196:                 }
 1197:             }
 1198:         }
 1199:         my $button_label;
 1200:         if ($fn =~ /\/portfolio\//) {
 1201:             $button_label = 'Store Metadata';
 1202:         } else {
 1203:             $button_label = 'Store Catalog Information';
 1204:         }
 1205: 	    $r->print($output.'<br /><input type="submit" name="store" value="'.
 1206:                   &mt($button_label).'">');
 1207:     }
 1208:     $r->print('</form>');
 1209:     return;
 1210: }
 1211: 
 1212: 1;
 1213: __END__
 1214: 
 1215:      

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>