--- loncom/interface/loncommon.pm 2011/01/03 14:19:38 1.993 +++ loncom/interface/loncommon.pm 2011/10/17 12:41:30 1.1021 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.993 2011/01/03 14:19:38 raeburn Exp $ +# $Id: loncommon.pm,v 1.1021 2011/10/17 12:41:30 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -409,7 +409,7 @@ sub studentbrowser_javascript { +ENDRESBRW +} + sub selectstudent_link { - my ($form,$unameele,$udomele,$courseadvonly)=@_; - my $callargs = "'".$form."','".$unameele."','".$udomele."'"; + my ($form,$unameele,$udomele,$courseadvonly,$clickerid)=@_; + my $callargs = "'".&Apache::lonhtmlcommon::entity_encode($form)."','". + &Apache::lonhtmlcommon::entity_encode($unameele)."','". + &Apache::lonhtmlcommon::entity_encode($udomele)."'"; if ($env{'request.course.id'}) { if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'}) && !&Apache::lonnet::allowed('srm',$env{'request.course.id'}. '/'.$env{'request.course.sec'})) { return ''; } + $callargs.=",'".&Apache::lonhtmlcommon::entity_encode($clickerid)."'"; if ($courseadvonly) { $callargs .= ",'',1,1"; } @@ -452,7 +475,7 @@ sub selectstudent_link { &mt('Select User').''; } if ($env{'request.role'}=~/^(au|dc|su)/) { - $callargs .= ",1"; + $callargs .= ",'',1"; return ''. ''. &mt('Select User').''; @@ -460,6 +483,19 @@ sub selectstudent_link { return ''; } +sub selectresource_link { + my ($form,$reslink,$arg)=@_; + + my $callargs = "'".&Apache::lonhtmlcommon::entity_encode($form)."','". + &Apache::lonhtmlcommon::entity_encode($reslink)."'"; + unless ($env{'request.course.id'}) { return $arg; } + return ''. + ''. + $arg.''; +} + + + sub authorbrowser_javascript { return <<"ENDAUTHORBRW"; + +ENDJS + +} + sub userbrowser_javascript { my $id_functions = &javascript_index_functions(); return <<"ENDUSERBRW"; @@ -766,6 +847,9 @@ sub selectcourse_link { } elsif ($selecttype eq 'Course/Community') { $linktext = &mt('Select Course/Community'); $type = ''; + } elsif ($selecttype eq 'Select') { + $linktext = &mt('Select'); + $type = ''; } return '' ."set_tempdir(LONCAPA::tempdir()); # my $format = &Apache::loncommon::define_excel_formats($workbook); return ($workbook,$filename,$format); @@ -3423,6 +3507,7 @@ sub get_previous_attempt { my $data=$parts[-1]; next if ($data eq 'foilorder'); pop(@parts); + $prevattempts.=''.&mt('Part ').join('.',@parts).'
'.$data.' '; if ($data eq 'type') { unless ($showsurv) { my $id = join(',',@parts); @@ -3431,10 +3516,7 @@ sub get_previous_attempt { $lasthidden{$ign.'.'.$id} = 1; } } - delete($lasthash{$key}); - } else { - $prevattempts.=''.&mt('Part ').join('.',@parts).'
'.$data.' '; - } + } } else { if ($#parts == 0) { $prevattempts.=''.$parts[0].''; @@ -3551,7 +3633,7 @@ sub get_previous_attempt { sub format_previous_attempt_value { my ($key,$value) = @_; - if ($key =~ /timestamp/) { + if (($key =~ /timestamp/) || ($key=~/duedate/)) { $value = &Apache::lonlocal::locallocaltime($value); } elsif (ref($value) eq 'ARRAY') { $value = '('.join(', ', @{ $value }).')'; @@ -3560,8 +3642,8 @@ sub format_previous_attempt_value { my @anskeys = sort(keys(%answers)); if (@anskeys == 1) { my $answer = $answers{$anskeys[0]}; - if ($answer =~ m{\Q\0\E}) { - $answer =~ s{\Q\0\E}{, }g; + if ($answer =~ m{\0}) { + $answer =~ s{\0}{,}g; } my $tag_internal_answer_name = 'INTERNAL'; if ($anskeys[0] eq $tag_internal_answer_name) { @@ -3572,8 +3654,8 @@ sub format_previous_attempt_value { } else { foreach my $ans (@anskeys) { my $answer = $answers{$ans}; - if ($answer =~ m{\Q\0\E}) { - $answer =~ s{\Q\0\E}{, }g; + if ($answer =~ m{\0}) { + $answer =~ s{\0}{,}g; } $value .= $ans.'='.$answer.'
';; } @@ -4272,8 +4354,7 @@ sub get_domainconf { if (ref($domconfig{'login'}{$key}) eq 'HASH') { if ($key eq 'loginvia') { if (ref($domconfig{'login'}{'loginvia'}) eq 'HASH') { - my @ids = &Apache::lonnet::current_machine_ids(); - foreach my $hostname (@ids) { + foreach my $hostname (keys(%{$domconfig{'login'}{'loginvia'}})) { if (ref($domconfig{'login'}{'loginvia'}{$hostname}) eq 'HASH') { if ($domconfig{'login'}{'loginvia'}{$hostname}{'server'}) { my $server = $domconfig{'login'}{'loginvia'}{$hostname}{'server'}; @@ -4282,7 +4363,7 @@ sub get_domainconf { $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'custompath'}; } else { - $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'}; + $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'}; } if ($domconfig{'login'}{'loginvia'}{$hostname}{'exempt'}) { $designhash{$udom.'.login.loginvia_exempt_'.$hostname} = $domconfig{'login'}{'loginvia'}{$hostname}{'exempt'}; @@ -4423,7 +4504,10 @@ sub designparm { return $env{'environment.color.'.$which}; } $domain=&determinedomain($domain); - my %domdesign = &get_domainconf($domain); + my %domdesign; + unless ($domain eq 'public') { + %domdesign = &get_domainconf($domain); + } my $output; if ($domdesign{$domain.'.'.$which} ne '') { $output = $domdesign{$domain.'.'.$which}; @@ -4925,6 +5009,10 @@ form, .inline { text-decoration:none; } +.LC_setting { + text-decoration:underline; +} + .LC_error { color: red; font-size: larger; @@ -5089,6 +5177,7 @@ td.LC_table_cell_checkbox { overflow: hidden; margin: 0; padding: 0; + text-align: left; } .LC_head_subbox { @@ -5097,6 +5186,7 @@ td.LC_table_cell_checkbox { border: 1px solid $sidebg; margin: 0 0 10px 0; padding: 3px; + text-align: left; } .LC_fontsize_medium { @@ -5119,6 +5209,7 @@ td.LC_table_cell_checkbox { li.LC_menubuttons_inline_text img,a { cursor:pointer; + text-decoration: none; } .LC_menubuttons_link { @@ -5166,14 +5257,6 @@ table.LC_nested { width: 100%; } -.ui-accordion, -.ui-accordion table.LC_data_table, -.ui-accordion table.LC_nested_outer{ - border: 0px; - border-spacing: 0px; - margin: 3px; -} - table.LC_data_table tr th, table.LC_calendar tr th, table.LC_prior_tries tr th, @@ -5289,22 +5372,6 @@ table.LC_nested tr td.LC_right_item { text-align: right; } -.ui-accordion table.LC_nested tr.LC_odd_row td.LC_left_item, -.ui-accordion table.LC_nested tr.LC_even_row td.LC_left_item { - text-align: right; - width: 40%; - padding-right:10px; - vertical-align: top; - padding: 5px; -} - -.ui-accordion table.LC_nested tr.LC_odd_row td.LC_right_item, -.ui-accordion table.LC_nested tr.LC_even_row td.LC_right_item { - text-align: left; - width: 60%; - padding: 2px 4px; -} - table.LC_nested tr.LC_odd_row td { background-color: #EEEEEE; } @@ -6064,6 +6131,7 @@ fieldset > legend { #LC_nav_bar { float: left; + background-color: $pgbg_or_bgcolor; margin: 0 0 2px 0; } @@ -6072,6 +6140,7 @@ fieldset > legend { padding: 0; font-weight: bold; text-align: center; + background-color: $pgbg_or_bgcolor; } #LC_nav_bar em { @@ -6082,6 +6151,7 @@ fieldset > legend { ol.LC_primary_menu { float: right; margin: 0; + background-color: $pgbg_or_bgcolor; } ol#LC_PathBreadcrumbs { @@ -6141,6 +6211,7 @@ ul#LC_secondary_menu { padding: 0; margin: 0; width: 100%; + text-align: left; } ul#LC_secondary_menu li { @@ -6157,7 +6228,7 @@ ul.LC_TabContent { background: $sidebg; border-bottom: solid 1px $lg_border_color; list-style:none; - margin: 0 -10px; + margin: -1px -10px 0 -10px; padding: 0; } @@ -6180,7 +6251,7 @@ ul.LC_TabContent li { padding: 0 16px 0 10px; background-color:$tabbg; border-bottom:solid 1px $lg_border_color; - border-right: solid 1px $font; + border-left: solid 1px $font; } ul.LC_TabContent .right { @@ -6274,17 +6345,15 @@ ul.LC_TabContentBigger li.active b { background:url('/adm/lonIcons/tabbgright.gif') right top no-repeat; color:$font; border: 0; - cursor:default; } ul.LC_CourseBreadcrumbs { background: $sidebg; - line-height: 32px; + height: 2em; padding-left: 10px; - margin: 0 0 10px 0; + margin: 0; list-style-position: inside; - } ol#LC_MenuBreadcrumbs, @@ -6326,6 +6395,11 @@ ol#LC_PathBreadcrumbs li a { padding: 0 10px 10px 10px; } +.LC_DocsBox { + border: solid 1px $lg_border_color; + padding: 0 0 10px 10px; +} + .LC_AboutMe_Image { float:left; margin-right:10px; @@ -6530,12 +6604,6 @@ ul.LC_funclist li { line-height: 150%; } -.ui-accordion .LC_advanced_toggle { - float: right; - font-size: 90%; - padding: 0px 4px -} - .LC_hidden { display: none; } @@ -6877,6 +6945,24 @@ sub validate_page { } } + +sub start_scrollbox { + my ($outerwidth,$width,$height,$id)=@_; + unless ($outerwidth) { $outerwidth='520px'; } + unless ($width) { $width='500px'; } + unless ($height) { $height='200px'; } + my ($table_id,$div_id); + if ($id ne '') { + $table_id = " id='table_$id'"; + $div_id = " id='div_$id'"; + } + return "
"; +} + +sub end_scrollbox { + return '
'; +} + sub simple_error_page { my ($r,$title,$msg) = @_; my $page = @@ -6904,10 +6990,14 @@ sub simple_error_page { } sub start_data_table { - my ($add_class) = @_; + my ($add_class,$id) = @_; my $css_class = (join(' ','LC_data_table',$add_class)); + my $table_id; + if (defined($id)) { + $table_id = ' id="'.$id.'"'; + } &start_data_table_count(); - return ''."\n"; + return '
'."\n"; } sub end_data_table { @@ -7676,7 +7766,7 @@ sub get_secgrprole_info { } sub user_picker { - my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype) = @_; + my ($dom,$srch,$forcenewuser,$caller,$cancreate,$usertype,$context) = @_; my $currdom = $dom; my %curr_selected = ( srchin => 'dom', @@ -7767,10 +7857,15 @@ sub user_picker { $srchtypesel .= "\n \n"; my ($newuserscript,$new_user_create); - + my $context_dom = $env{'request.role.domain'}; + if ($context eq 'requestcrs') { + if ($env{'form.coursedom'} ne '') { + $context_dom = $env{'form.coursedom'}; + } + } if ($forcenewuser) { if (ref($srch) eq 'HASH') { - if ($srch->{'srchby'} eq 'uname' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchin'} eq 'dom' && $srch->{'srchdomain'} eq $env{'request.role.domain'}) { + if ($srch->{'srchby'} eq 'uname' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchin'} eq 'dom' && $srch->{'srchdomain'} eq $context_dom) { if ($cancreate) { $new_user_create = '

&"').'" onclick="javascript:setSearch(\'1\','.$caller.');" />

'; } else { @@ -7809,7 +7904,7 @@ function setSearch(createnew,callingForm } } for (var i=0; i'.$fname.'', $filesize).'
'. - &mt('Either the file you attempted to upload was empty, or your web browser was unable to read its contents.').'
'; + &mt('Either the file you attempted to upload was empty, or your web browser was unable to read its contents.').'
'. ''; return ('zero_bytes',$msg); } $filesize = $filesize/1000; #express in k (1024?) my $getpropath = 1; - my @dir_list = &Apache::lonnet::dirlist($portfolio_root.$path,$udom,$uname, - $getpropath); + my ($dirlistref,$listerror) = + &Apache::lonnet::dirlist($portfolio_root.$path,$udom,$uname,$getpropath); my $found_file = 0; my $locked_file = 0; my @lockers; @@ -8962,48 +9063,50 @@ sub check_for_upload { if ($env{'request.course.id'}) { $navmap = Apache::lonnavmaps::navmap->new(); } - foreach my $line (@dir_list) { - my ($file_name,$rest)=split(/\&/,$line,2); - if ($file_name eq $fname){ - $file_name = $path.$file_name; - if ($group ne '') { - $file_name = $group.$file_name; - } - $found_file = 1; - if (&Apache::lonnet::is_locked($file_name,$udom,$uname,\@lockers) eq 'true') { - foreach my $lock (@lockers) { - if (ref($lock) eq 'ARRAY') { - my ($symb,$crsid) = @{$lock}; - if ($crsid eq $env{'request.course.id'}) { - if (ref($navmap)) { - my $res = $navmap->getBySymb($symb); - foreach my $part (@{$res->parts()}) { - my ($slot_status,$slot_time,$slot_name)=$res->check_for_slot($part); - unless (($slot_status == $res->RESERVED) || - ($slot_status == $res->RESERVED_LOCATION)) { - $locked_file = 1; + if (ref($dirlistref) eq 'ARRAY') { + foreach my $line (@{$dirlistref}) { + my ($file_name,$rest)=split(/\&/,$line,2); + if ($file_name eq $fname){ + $file_name = $path.$file_name; + if ($group ne '') { + $file_name = $group.$file_name; + } + $found_file = 1; + if (&Apache::lonnet::is_locked($file_name,$udom,$uname,\@lockers) eq 'true') { + foreach my $lock (@lockers) { + if (ref($lock) eq 'ARRAY') { + my ($symb,$crsid) = @{$lock}; + if ($crsid eq $env{'request.course.id'}) { + if (ref($navmap)) { + my $res = $navmap->getBySymb($symb); + foreach my $part (@{$res->parts()}) { + my ($slot_status,$slot_time,$slot_name)=$res->check_for_slot($part); + unless (($slot_status == $res->RESERVED) || + ($slot_status == $res->RESERVED_LOCATION)) { + $locked_file = 1; + } } + } else { + $locked_file = 1; } } else { $locked_file = 1; } - } else { - $locked_file = 1; } - } - } - } else { - my @info = split(/\&/,$rest); - my $currsize = $info[6]/1000; - if ($currsize < $filesize) { - my $extra = $filesize - $currsize; - if (($current_disk_usage + $extra) > $disk_quota) { - my $msg = ''. - &mt('Unable to upload [_1]. (size = [_2] kilobytes). Disk quota will be exceeded if existing (smaller) file with same name (size = [_3] kilobytes) is replaced.', - ''.$fname.'',$filesize,$currsize).''. - '
'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.', - $disk_quota,$current_disk_usage); - return ('will_exceed_quota',$msg); + } + } else { + my @info = split(/\&/,$rest); + my $currsize = $info[6]/1000; + if ($currsize < $filesize) { + my $extra = $filesize - $currsize; + if (($current_disk_usage + $extra) > $disk_quota) { + my $msg = ''. + &mt('Unable to upload [_1]. (size = [_2] kilobytes). Disk quota will be exceeded if existing (smaller) file with same name (size = [_3] kilobytes) is replaced.', + ''.$fname.'',$filesize,$currsize).''. + '
'.&mt('Disk quota is [_1] kilobytes. Your current disk usage is [_2] kilobytes.', + $disk_quota,$current_disk_usage); + return ('will_exceed_quota',$msg); + } } } } @@ -9075,6 +9178,113 @@ sub check_for_traversal { =pod +=item * &get_turnedin_filepath() + +Determines path in a user's portfolio file for storage of files uploaded +to a specific essayresponse or dropbox item. + +Inputs: 3 required + 1 optional. +$symb is symb for resource, $uname and $udom are for current user (required). +$caller is optional (can be "submission", if routine is called when storing +an upoaded file when "Submit Answer" button was pressed). + +Returns array containing $path and $multiresp. +$path is path in portfolio. $multiresp is 1 if this resource contains more +than one file upload item. Callers of routine should append partid as a +subdirectory to $path in cases where $multiresp is 1. + +Called by: homework/essayresponse.pm and homework/structuretags.pm + +=cut + +sub get_turnedin_filepath { + my ($symb,$uname,$udom,$caller) = @_; + my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb); + my $turnindir; + my %userhash = &Apache::lonnet::userenvironment($udom,$uname,'turnindir'); + $turnindir = $userhash{'turnindir'}; + my ($path,$multiresp); + if ($turnindir eq '') { + if ($caller eq 'submission') { + $turnindir = &mt('turned in'); + $turnindir =~ s/\W+/_/g; + my %newhash = ( + 'turnindir' => $turnindir, + ); + &Apache::lonnet::put('environment',\%newhash,$udom,$uname); + } + } + if ($turnindir ne '') { + $path = '/'.$turnindir.'/'; + my ($multipart,$turnin,@pathitems); + my $navmap = Apache::lonnavmaps::navmap->new(); + if (defined($navmap)) { + my $mapres = $navmap->getResourceByUrl($map); + if (ref($mapres)) { + my $pcslist = $mapres->map_hierarchy(); + if ($pcslist ne '') { + foreach my $pc (split(/,/,$pcslist)) { + my $res = $navmap->getByMapPc($pc); + if (ref($res)) { + my $title = $res->compTitle(); + $title =~ s/\W+/_/g; + if ($title ne '') { + push(@pathitems,$title); + } + } + } + } + my $maptitle = $mapres->compTitle(); + $maptitle =~ s/\W+/_/g; + if ($maptitle ne '') { + push(@pathitems,$maptitle); + } + unless ($env{'request.state'} eq 'construct') { + my $res = $navmap->getBySymb($symb); + if (ref($res)) { + my $partlist = $res->parts(); + my $totaluploads = 0; + if (ref($partlist) eq 'ARRAY') { + foreach my $part (@{$partlist}) { + my @types = $res->responseType($part); + my @ids = $res->responseIds($part); + for (my $i=0; $i < scalar(@ids); $i++) { + if ($types[$i] eq 'essay') { + my $partid = $part.'_'.$ids[$i]; + if (&Apache::lonnet::EXT("resource.$partid.uploadedfiletypes") ne '') { + $totaluploads ++; + } + } + } + } + if ($totaluploads > 1) { + $multiresp = 1; + } + } + } + } + } else { + return; + } + } else { + return; + } + my $restitle=&Apache::lonnet::gettitle($symb); + $restitle =~ s/\W+/_/g; + if ($restitle eq '') { + $restitle = ($resurl =~ m{/[^/]+$}); + if ($restitle eq '') { + $restitle = time; + } + } + push(@pathitems,$restitle); + $path .= join('/',@pathitems); + } + return ($path,$multiresp); +} + +=pod + =back =head1 CSV Upload/Handling functions @@ -11205,7 +11415,10 @@ sub init_user_environment { } my %is_adv = ( is_adv => $env{'user.adv'} ); - my %domdef = &Apache::lonnet::get_domain_defaults($domain); + my %domdef; + unless ($domain eq 'public') { + %domdef = &Apache::lonnet::get_domain_defaults($domain); + } foreach my $tool ('aboutme','blog','portfolio') { $userenv{'availabletools.'.$tool} =