--- loncom/interface/loncommon.pm 2011/06/05 12:59:47 1.1009 +++ loncom/interface/loncommon.pm 2011/12/04 16:27:05 1.1029 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.1009 2011/06/05 12:59:47 www Exp $ +# $Id: loncommon.pm,v 1.1029 2011/12/04 16:27:05 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -475,7 +475,7 @@ sub selectstudent_link { &mt('Select User').''; } if ($env{'request.role'}=~/^(au|dc|su)/) { - $callargs .= ",1"; + $callargs .= ",'',1"; return ''. ''. &mt('Select User').''; @@ -632,6 +632,51 @@ ENDJS } +sub javascript_array_indexof { + return < +// >> 0; + if (len === 0) { + return -1; + } + var n = 0; + if (arguments.length > 0) { + n = Number(arguments[1]); + if (n !== n) { // shortcut for verifying if it's NaN + n = 0; + } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { + n = (n > 0 || -1) * Math.floor(Math.abs(n)); + } + } + if (n >= len) { + return -1; + } + var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); + for (; k < len; k++) { + if (k in t && t[k] === searchElement) { + return k; + } + } + return -1; + } +} + +// ]]> + + +ENDJS + +} + sub userbrowser_javascript { my $id_functions = &javascript_index_functions(); return <<"ENDUSERBRW"; @@ -802,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); @@ -3459,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); @@ -3467,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].''; @@ -3587,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 }).')'; @@ -4308,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'}; @@ -4318,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'}; @@ -4401,7 +4446,7 @@ sub get_legacy_domconf { close($fh); } } - if (-e '/home/httpd/html/adm/lonDomLogos/'.$udom.'.gif') { + if (-e $Apache::lonnet::perlvar{'lonDocRoot'}.'/adm/lonDomLogos/'.$udom.'.gif') { $legacyhash{$udom.'.login.domlogo'} = "/adm/lonDomLogos/$udom.gif"; } return %legacyhash; @@ -4459,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}; @@ -4484,27 +4532,39 @@ sub designparm { =item * &authorspace() -Inputs: ./. +Inputs: $url (usually will be undef). -Returns: Path to the Construction Space of the current user's - accessed author space - The author space will be that of the current user - when accessing the own author space - and that of the co-author/assistent co-author - when accessing the co-author's/assistent co-author's - space +Returns: Path to Construction Space containing the resource or + directory being viewed (or for which action is being taken). + If $url is provided, and begins /priv// + the path will be that portion of the $context argument. + Otherwise the path will be for the author space of the current + user when the current role is author, or for that of the + co-author/assistant co-author space when the current role + is co-author or assistant co-author. =cut sub authorspace { + my ($url) = @_; + if ($url ne '') { + if ($url =~ m{^(/priv/$match_domain/$match_username/)}) { + return $1; + } + } my $caname = ''; - if ($env{'request.role'} =~ /^ca|^aa/) { - (undef,$caname) = + my $cadom = ''; + if ($env{'request.role'} =~ /^(?:ca|aa)/) { + ($cadom,$caname) = ($env{'request.role'}=~/($match_domain)\/($match_username)$/); - } else { + } elsif ($env{'request.role'} =~ m{^au\./($match_domain)/}) { $caname = $env{'user.name'}; + $cadom = $env{'user.domain'}; + } + if (($caname ne '') && ($cadom ne '')) { + return "/priv/$cadom/$caname/"; } - return '/priv/'.$caname.'/'; + return; } ############################################## @@ -4532,7 +4592,9 @@ sub head_subbox { =item * &CSTR_pageheader() -Inputs: ./. +Input: (optional) filename from which breadcrumb trail is built. + In most cases no input as needed, as $env{'request.filename'} + is appropriate for use in building the breadcrumb trail. Returns: HTML div with CSTR path and recent box To be included on Construction Space pages @@ -4540,12 +4602,19 @@ Returns: HTML div with CSTR path and rec =cut sub CSTR_pageheader { - # this is for resources; directories have customtitle, and crumbs - # and select recent are created in lonpubdir.pm - my ($uname,$thisdisfn)= - ($env{'request.filename'} =~ m|^/home/([^/]+)/public_html/(.*)|); - my $formaction='/priv/'.$uname.'/'.$thisdisfn; - $formaction=~s/\/+/\//g; + my ($trailfile) = @_; + if ($trailfile eq '') { + $trailfile = $env{'request.filename'}; + } + +# this is for resources; directories have customtitle, and crumbs +# and select recent are created in lonpubdir.pm + + my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'}; + my ($udom,$uname,$thisdisfn)= + ($trailfile =~ m{^\Q$londocroot\E/priv/([^/]+)/([^/]+)/(.*)$}); + my $formaction = "/priv/$udom/$uname/$thisdisfn"; + $formaction =~ s{/+}{/}g; my $parentpath = ''; my $lastitem = ''; @@ -4562,7 +4631,7 @@ sub CSTR_pageheader { .''.&mt('Construction Space:').' ' .'
' #FIXME lonpubdir: target="_parent" - .&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv',undef,undef); + .&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv/'.$udom,undef,undef); if ($lastitem) { $output .= @@ -5455,6 +5524,11 @@ span.LC_current_location { background: $pgbg; } +span.LC_current_nav_location { + font-weight:bold; + background: $sidebg; +} + span.LC_parm_menu_item { font-size: larger; } @@ -6180,7 +6254,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; } @@ -6203,7 +6277,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 { @@ -6302,11 +6376,10 @@ ul.LC_TabContentBigger li.active b { 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, @@ -6348,6 +6421,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; @@ -6895,11 +6973,16 @@ sub validate_page { sub start_scrollbox { - my ($outerwidth,$width,$height)=@_; + my ($outerwidth,$width,$height,$id)=@_; unless ($outerwidth) { $outerwidth='520px'; } unless ($width) { $width='500px'; } unless ($height) { $height='200px'; } - return "
"; + my ($table_id,$div_id); + if ($id ne '') { + $table_id = " id='table_$id'"; + $div_id = " id='div_$id'"; + } + return "
"; } sub end_scrollbox { @@ -6933,10 +7016,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 { @@ -7063,7 +7150,7 @@ sub get_users_function { $function='admin'; } if (($env{'request.role'}=~/^(au|ca|aa)/) || - ($ENV{'REQUEST_URI'}=~/^(\/priv|\~)/)) { + ($ENV{'REQUEST_URI'}=~ m{/^(/priv)})) { $function='author'; } return $function; @@ -8387,8 +8474,8 @@ sub ask_for_embedded_content { $getpropath = 1; } elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank') || ($actionurl eq '/adm/imsimport')) { - ($uname,my $rest) = ($args->{'current_path'} =~ m{/priv/($match_username)/?(.*)$}); - $url = '/home/'.$uname.'/public_html/'; + my ($udom,$uname,$rest) = ($args->{'current_path'} =~ m{/priv/($match_domain)/($match_username)/?(.*)$}); + $url = $Apache::lonnet::perlvar{'lonDocRoot'}."/priv/$udom/$uname/"; $toplevel = $url; if ($rest ne '') { $url .= $rest; @@ -8438,10 +8525,13 @@ sub ask_for_embedded_content { foreach my $path (keys(%subdependencies)) { my %currsubfile; if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { - my @subdir_list = &Apache::lonnet::dirlist($url.$path,$udom,$uname,$getpropath); - foreach my $line (@subdir_list) { - my ($file_name,$rest) = split(/\&/,$line,2); - $currsubfile{$file_name} = 1; + my ($sublistref,$listerror) = + &Apache::lonnet::dirlist($url.$path,$udom,$uname,$getpropath); + if (ref($sublistref) eq 'ARRAY') { + foreach my $line (@{$sublistref}) { + my ($file_name,$rest) = split(/\&/,$line,2); + $currsubfile{$file_name} = 1; + } } } elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank')) { if (opendir(my $dir,$url.'/'.$path)) { @@ -8464,10 +8554,13 @@ sub ask_for_embedded_content { } my %currfile; if (($actionurl eq '/adm/portfolio') || ($actionurl eq '/adm/coursegrp_portfolio')) { - my @dir_list = &Apache::lonnet::dirlist($url,$udom,$uname,$getpropath); - foreach my $line (@dir_list) { - my ($file_name,$rest) = split(/\&/,$line,2); - $currfile{$file_name} = 1; + my ($dirlistref,$listerror) = + &Apache::lonnet::dirlist($url,$udom,$uname,$getpropath); + if (ref($dirlistref) eq 'ARRAY') { + foreach my $line (@{$dirlistref}) { + my ($file_name,$rest) = split(/\&/,$line,2); + $currfile{$file_name} = 1; + } } } elsif (($actionurl eq '/adm/upload') || ($actionurl eq '/adm/testbank')) { if (opendir(my $dir,$url)) { @@ -8746,12 +8839,12 @@ sub upload_embedded { my $fullpath = $dir_root.$dirpath.'/'.$path; my $dest = $fullpath.$fname; my $url = $url_root.$dirpath.'/'.$path.$fname; - my @parts=split(/\//,$fullpath); + my @parts=split(/\//,"$dirpath/$path"); my $count; my $filepath = $dir_root; - for ($count=4;$count<=$#parts;$count++) { - $filepath .= "/$parts[$count]"; - if ((-e $filepath)!=1) { + foreach my $subdir (@parts) { + $filepath .= "/$subdir"; + if (!-e $filepath) { mkdir($filepath,0770); } } @@ -8870,8 +8963,7 @@ sub modify_html_refs { } elsif ($context eq 'coursedoc') { $container = $env{'form.primaryurl'}; } else { - $container = $env{'form.filename'}; - $container =~ s{^/priv/(\Q$uname\E)/(.*)}{/home/$1/public_html/$2}; + $container = $Apache::lonnet::perlvar{'lonDocRoot'}.$env{'form.filename'}; } my (%allfiles,%codebase,$output,$content); my @changes = &get_env_multiple('form.namechange'); @@ -8987,8 +9079,8 @@ sub check_for_upload { } $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; @@ -8996,48 +9088,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); + } } } } @@ -9109,6 +9203,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 @@ -11239,7 +11440,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} =