--- loncom/interface/loncommon.pm	2006/05/09 14:38:09	1.365
+++ loncom/interface/loncommon.pm	2006/06/22 19:01:30	1.387
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.365 2006/05/09 14:38:09 albertel Exp $
+# $Id: loncommon.pm,v 1.387 2006/06/22 19:01:30 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -64,6 +64,7 @@ use HTML::Entities;
 use Apache::lonhtmlcommon();
 use Apache::loncoursedata();
 use Apache::lontexconvert();
+use LONCAPA;
 
 my $readit;
 
@@ -385,10 +386,11 @@ sub selectstudent_link {
 
 sub coursebrowser_javascript {
     my ($domainfilter)=@_;
+    my $crs_or_grp_alert = &mt('Please select the type of LON-CAPA entity - Course or Group - for which you wish to add/modify a user role');
    return (<<ENDSTDBRW);
 <script type="text/javascript" language="Javascript" >
     var stdeditbrowser;
-    function opencrsbrowser(formname,uname,udom,desc,extra_element,multflag) {
+    function opencrsbrowser(formname,uname,udom,desc,extra_element,multflag,crstype) {
         var url = '/adm/pickcourse?';
         var filter;
         if (filter != null) {
@@ -414,6 +416,18 @@ sub coursebrowser_javascript {
         if (multflag !=null && multflag != '') {
             url += '&multiple='+multflag;
         }
+        if (crstype == 'Course/Group') {
+            if (formname == 'cu') {
+                crstype = document.cu.crstype.options[document.cu.crstype.selectedIndex].value; 
+                if (crstype == "") {
+                    alert("$crs_or_grp_alert");
+                    return;
+                }
+            }
+        }
+        if (crstype !=null && crstype != '') {
+            url += '&type='+crstype;
+        }
         var title = 'Course_Browser';
         var options = 'scrollbars=1,resizable=1,menubar=0';
         options += ',width=700,height=600';
@@ -425,9 +439,9 @@ ENDSTDBRW
 }
 
 sub selectcourse_link {
-   my ($form,$unameele,$udomele,$desc,$extra_element,$multflag)=@_;
+   my ($form,$unameele,$udomele,$desc,$extra_element,$multflag,$selecttype)=@_;
     return "<a href='".'javascript:opencrsbrowser("'.$form.'","'.$unameele.
-        '","'.$udomele.'","'.$desc.'","'.$extra_element.'","'.$multflag.'");'."'>".&mt('Select Course')."</a>";
+        '","'.$udomele.'","'.$desc.'","'.$extra_element.'","'.$multflag.'","'.$selecttype.'");'."'>".&mt('Select [_1]',$selecttype)."</a>";
 }
 
 sub check_uncheck_jscript {
@@ -709,15 +723,15 @@ sub help_open_menu {
     my $timestamp = time;
     foreach my $datum (\$color,\$function,\$topic,\$component_help,\$faq,
 		       \$bug,\$origurl) {
-        $$datum = &Apache::lonnet::escape($$datum);
+        $$datum = &escape($$datum);
     }
     if (!$stayOnPage) {
          $link = "javascript:helpMenu('open')";
     } else {
         $link = "javascript:helpMenu('display')";
     }
-    my $banner_link = "/adm/helpmenu?page=banner&color=$color&function=$function&topic=$topic&component_help=$component_help&faq=$faq&bug=$bug&origurl=$origurl&stamp=$timestamp&stayonpage=$stayOnPage";
-    my $details_link = "/adm/helpmenu?page=body&color=$color&function=$function&topic=$topic&component_help=$component_help&faq=$faq&bug=$bug&origurl=$origurl&stamp=$timestamp";
+    my $banner_link = "/adm/helpmenu?page=banner&amp;color=$color&amp;function=$function&amp;topic=$topic&amp;component_help=$component_help&amp;faq=$faq&amp;bug=$bug&amp;origurl=$origurl&amp;stamp=$timestamp&amp;stayonpage=$stayOnPage";
+    my $details_link = "/adm/helpmenu?page=body&amp;color=$color&amp;function=$function&amp;topic=$topic&amp;component_help=$component_help&amp;faq=$faq&amp;bug=$bug&amp;origurl=$origurl&amp;stamp=$timestamp";
     my $template;
     if ($text ne "") {
 	$template .= 
@@ -775,7 +789,7 @@ ENDTEMPLATE
 				       $width,$height).' '.$template;
 	} else {
 	    my $help_text;
-	    $help_text=&Apache::lonnet::unescape($topic);
+	    $help_text=&unescape($topic);
 	    $template='<table><tr><td>'.
 		&help_open_topic($component_help,$help_text,$stayOnPage,
 				 $width,$height).'</td><td>'.$template.
@@ -802,8 +816,8 @@ sub help_open_bug {
     $topic=~s/\W+/\+/g;
     my $link='';
     my $template='';
-    my $url=$Apache::lonnet::perlvar{'BugzillaHost'}.'enter_bug.cgi?product=LON-CAPA&bug_file_loc='.
-	&Apache::lonnet::escape($ENV{'REQUEST_URI'}).'&component='.$topic;
+    my $url=$Apache::lonnet::perlvar{'BugzillaHost'}.'enter_bug.cgi?product=LON-CAPA&amp;bug_file_loc='.
+	&escape($ENV{'REQUEST_URI'}).'&amp;component='.$topic;
     if (!$stayOnPage)
     {
 	$link = "javascript:void(open('$url', 'Bugzilla', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))";
@@ -2024,10 +2038,11 @@ sub screenname {
 # ------------------------------------------------------------- Message Wrapper
 
 sub messagewrapper {
-    my ($link,$username,$domain)=@_;
+    my ($link,$username,$domain,$subject,$text)=@_;
     return 
         '<a href="/adm/email?compose=individual&'.
-        'recname='.$username.'&recdom='.$domain.'" '.
+        'recname='.$username.'&recdom='.$domain.
+	'&subject='.&escape($subject).'&text='.&escape($text).'" '.
         'title="'.&mt('Send message').'">'.$link.'</a>';
 }
 # --------------------------------------------------------------- Notes Wrapper
@@ -2394,7 +2409,7 @@ sub get_previous_attempt {
 	       } else {
 		  $value=$returnhash{$version.':'.$key};
 	       }
-	       $prevattempts.='<td>'.&Apache::lonnet::unescape($value).'&nbsp;</td>';   
+	       $prevattempts.='<td>'.&unescape($value).'&nbsp;</td>';   
 	    }
 	 }
       }
@@ -2406,7 +2421,7 @@ sub get_previous_attempt {
 	} else {
 	  $value=$lasthash{$key};
 	}
-	$value=&Apache::lonnet::unescape($value);
+	$value=&unescape($value);
 	if ($key =~/$regexp$/ && (defined &$gradesub)) {$value = &$gradesub($value)}
 	$prevattempts.='<td>'.$value.'&nbsp;</td>';
       }
@@ -2528,7 +2543,7 @@ sub submlink {
 	if (!$symb) { $symb=$cursymb; }
     }
     if (!$symb) { $symb=&Apache::lonnet::symbread(); }
-    $symb=&Apache::lonnet::escape($symb);
+    $symb=&escape($symb);
     if ($target) { $target="target=\"$target\""; }
     return '<a href="/adm/grades?&command=submission&'.
 	'symb='.$symb.'&student='.$uname.
@@ -2574,7 +2589,7 @@ sub pprmlink {
 	if (!$symb) { $symb=$cursymb; }
     }
     if (!$symb) { $symb=&Apache::lonnet::symbread(); }
-    $symb=&Apache::lonnet::escape($symb);
+    $symb=&escape($symb);
     if ($target) { $target="target=\"$target\""; }
     return '<a href="/adm/parmset?&command=set&'.
 	'symb='.$symb.'&uname='.$uname.
@@ -2604,6 +2619,11 @@ sub timehash {
              'dlsav'   => $ltime[8] );
 }
 
+sub utc_string {
+    my ($date)=@_;
+    return strftime("%Y%m%dT%H%M%SZ",gmtime($date));
+}
+
 sub maketime {
     my %th=@_;
     return POSIX::mktime(
@@ -2806,11 +2826,19 @@ sub bodytag {
     @$addentries{keys(%design)} = @design{keys(%design)};
 
  # role and realm
-    my ($role,$realm) =
-	&Apache::lonnet::plaintext((split(/\./,$env{'request.role'}))[0]);
+    my ($role,$realm) = split(/\./,$env{'request.role'},2);
+    if ($role  eq 'ca') {
+        my ($rdom,$rname) = ($realm =~ m-^/(\w+)/(\w+)$-);
+        $realm = &plainname($rname,$rdom).':'.$rdom;
+    } 
 # realm
     if ($env{'request.course.id'}) {
+        if ($env{'request.role'} !~ /^cr/) {
+            $role = &Apache::lonnet::plaintext($role,&course_type());
+        }
 	$realm = $env{'course.'.$env{'request.course.id'}.'.description'};
+    } else {
+        $role = &Apache::lonnet::plaintext($role);
     }
     if (!$realm) { $realm='&nbsp;'; }
 # Set messages
@@ -2871,6 +2899,7 @@ ENDROLE
                                  '.domain'}.'/'})) {
         my $cid = $env{'request.course.id'};
         $dc_info.= $cid.' '.$env{'course.'.$cid.'.internal.coursecode'};
+        $dc_info =~ s/\s+$//;
         $dc_info = '('.$dc_info.')';
     }
 
@@ -2945,11 +2974,12 @@ ENDROLE
     return(<<ENDBODY);
 $bodytag
 <table id="LC_title_bar" class="LC_with_remote">
-<tr><td>$upperleft</td>
+<tr><td class="LC_title_bar_role_logo">$upperleft</td>
     <td class="LC_title_bar_domain_logo">$messages&nbsp;</td>
 </tr>
 <tr><td>$titleinfo $dc_info $menu</td>
 $roleinfo
+</tr>
 </table>
 ENDBODY
 }
@@ -3068,8 +3098,10 @@ sub standard_css {
     my $tabbg  = &designparm($function.'.tabbg', $domain);
     my $font   = &designparm($function.'.font',  $domain);
     my $sidebg = &designparm($function.'.sidebg',$domain);
-    my $pgbg   = $bgcolor ||
+    my $pgbg_or_bgcolor =
+	         $bgcolor ||
 	         &designparm($function.'.pgbg',  $domain);
+    my $pgbg   = &designparm($function.'.pgbg',  $domain);
     my $alink  = &designparm($function.'.alink', $domain);
     my $vlink  = &designparm($function.'.vlink', $domain);
     my $link   = &designparm($function.'.link',  $domain);
@@ -3095,7 +3127,7 @@ table.thinborder { border-collapse: coll
 table.thinborder tr th, table.thinborder tr td { border-style: solid; border-width: 1px}
 form, .inline { display: inline; }
 .center { text-align: center; }
-.filename {font-family: monospace;}
+.LC_filename {font-family: monospace;}
 .LC_error {
   color: red;
   font-size: larger;
@@ -3104,11 +3136,11 @@ form, .inline { display: inline; }
   color: green;
 }
 
-table#LC_top_nav, table#LC_menubuttons, table#LC_nav_location, table#LC_breadcrumbs {
+table#LC_top_nav, table#LC_menubuttons, table#LC_nav_location {
   width: 100%;
   background: $pgbg;
   border: 0px;
-  border-spacing: 2px 1px;
+  border-spacing: 2px 2px;
   padding: 0px;
   margin: 0px;
   border-collapse: separate;
@@ -3116,10 +3148,20 @@ table#LC_top_nav, table#LC_menubuttons,
 table#LC_title_bar {
   width: 100%;
   border: 0;
-  border-spacing: 0px 1px;
+  border-spacing: 0px 0px;
+  padding: 0px 2px 0px 2px;
   background: $pgbg;
   font-family: $sans;
-  border-collapse: collapse;
+  border-collapse: separate;
+}
+table#LC_breadcrumbs {
+  width: 100%;
+  border: 0;
+  border-spacing: 0px;
+  padding: 0px 2px 0px 2px;
+  background: $pgbg;
+  font-family: $sans;
+  border-collapse: separate;
 }
 table#LC_title_bar.LC_with_remote {
   width: 100%;
@@ -3145,13 +3187,18 @@ span.LC_title_bar_title {
 table#LC_title_bar td.LC_title_bar_domain_logo {
   background: $sidebg;
   text-align: right;
+  padding: 0px;
+}
+table#LC_title_bar td.LC_title_bar_role_logo {
+  background: $sidebg;
+  padding: 0px;
 }
 
 table#LC_menubuttons_mainmenu {
   background: $pgbg;
   border: 0px;
   border-spacing: 1px;
-  padding: 0px;
+  padding: 0px 1px;
   margin: 0px;
   border-collapse: separate;
 }
@@ -3182,6 +3229,10 @@ table#LC_breadcrumbs td.LC_breadcrumb_co
   font-size: larger;
   text-align: right;
 }
+td.LC_table_cell_checkbox {
+  text-align: center;
+}
+
 .LC_menubuttons_inline_text {
   color: $font;
   font-family: $sans;
@@ -3264,6 +3315,36 @@ table.LC_mail_list tr.LC_mail_other {
 table.LC_mail_list tr.LC_mail_other:hover {
   background-color: $mail_other_hover;
 }
+
+table#LC_portfolio_actions {
+  width: auto;
+  background: $pgbg;
+  border: 0px;
+  border-spacing: 2px 2px;
+  padding: 0px;
+  margin: 0px;
+  border-collapse: separate;
+}
+table#LC_portfolio_actions td.LC_label {
+  background: $tabbg;
+  text-align: right;
+}
+table#LC_portfolio_actions td.LC_value {
+  background: $tabbg;
+}
+
+table.LC_brower {
+}
+table.LC_browser tr.LC_browser_file {
+  background: #CCFF88
+}
+table.LC_browser tr.LC_browser_file_locked {
+  background: #FFAA99
+}
+table.LC_browser tr.LC_browser_folder {
+  background: #CCCCFF
+}
+
 END
 }
 
@@ -3304,7 +3385,7 @@ sub headtag {
 		   $env{'environment.color.timestamp'},
 		   $function,$domain,$bgcolor);
 
-    $url = '/adm/css/'.&Apache::lonnet::escape($url).'.css';
+    $url = '/adm/css/'.&escape($url).'.css';
 
     my $result =
 	'<head>'.
@@ -3540,7 +3621,6 @@ Inputs:         $args - additional optio
 
 sub end_page {
     my ($args) = @_;
-    #&Apache::lonnet::logthis("end_page ".join(':',caller(0)));
     $env{'internal.end_page'}++;
     my $result;
     if ($args->{'discussion'}) {
@@ -3583,7 +3663,7 @@ sub js_ready {
     $result =~ s/[\n\r]/ /xmsg;
     $result =~ s/\\/\\\\/xmsg;
     $result =~ s/'/\\'/xmsg;
-    $result =~ s{</script>}{</scrip'+'t>}xmsg;
+    $result =~ s{</}{<\\/}xmsg;
     
     return $result;
 }
@@ -3646,6 +3726,14 @@ sub simple_error_page {
     sub end_data_table_row {
 	return '</tr>';
     }
+
+    sub start_data_table_header_row {
+	return  '<tr class="LC_header_row">';
+    }
+
+    sub end_data_table_header_row {
+	return '</tr>';
+    }
 }
 
 ###############################################
@@ -3688,7 +3776,7 @@ specific user. Roles can be active, prev
 
 Inputs: 
 user's domain, user's username, course's domain,
-course's number, optional section/group.
+course's number, optional section ID.
 
 Outputs:
 role status: active, previous or future. 
@@ -3739,32 +3827,40 @@ sub check_user_status {
 
 Determines all the sections for a course including
 sections with students and sections containing other roles.
-Incoming parameters: domain, course number, reference to 
-section hash (keys to be section/group IDs), reference to 
-array containing roles for which sections should be gathered
-(optional). If the fourth argument is undefined, sections
-are gathered for any role.
+Incoming parameters: domain, course number, 
+reference to array containing roles for which sections should 
+be gathered (optional). If the third argument is undefined,
+sections are gathered for any role.
  
-Returns number of sections.
+Returns section hash (keys are section IDs, values are
+number of users in each section), subject to the
+optional roles filter.
 
 =cut
 
 ###############################################
 sub get_sections {
-    my ($cdom,$cnum,$sectioncount,$possible_roles) = @_;
-    if (!($cdom && $cnum)) { return 0; }
-    my $numsections = 0;
+    my ($cdom,$cnum,$possible_roles) = @_;
+    if (!defined($cdom) || !defined($cnum)) {
+        my $cid =  $env{'request.course.id'};
+
+	return if (!defined($cid));
 
-    if (!defined($possible_roles) || (grep/^st$/,@$possible_roles)) {
+        $cdom = $env{'course.'.$cid.'.domain'};
+        $cnum = $env{'course.'.$cid.'.num'};
+    }
+
+    my %sectioncount;
+
+    if (!defined($possible_roles) || (grep(/^st$/,@$possible_roles))) {
 	my ($classlist) = &Apache::loncoursedata::get_classlist($cdom,$cnum);
 	my $sec_index = &Apache::loncoursedata::CL_SECTION();
 	my $status_index = &Apache::loncoursedata::CL_STATUS();
-	while (my ($student,$data) = each %$classlist) {
+	while (my ($student,$data) = each(%$classlist)) {
 	    my ($section,$status) = ($data->[$sec_index],
 				     $data->[$status_index]);
 	    unless ($section eq '-1' || $section =~ /^\s*$/) {
-		if (!defined($$sectioncount{$section})) { $numsections++; }
-		$$sectioncount{$section}++;
+		$sectioncount{$section}++;
 	    }
 	}
     }
@@ -3780,156 +3876,9 @@ sub get_sections {
 	}
 	if ($user =~ /^$role:[^:]*:[^:]*:(\w+)/) { $section=$1; }
 	if (!defined($section) || $section eq '-1') { next; }
-	if (!defined($$sectioncount{$section})) { $numsections++; } 
-	$$sectioncount{$section}++;
-    }
-    return $numsections;
-}
-
-###############################################
-                                                                                  
-=pod
-                                                                                  
-=item coursegroups
-
-Retrieve information about groups in a course,
-
-Input:
-1. Reference to hash to populate with group information. 
-2. Optional course domain
-3. Optional course number
-4. Optional group name
-
-Course domain and number will be taken from user's
-environment if not supplied. Optional group name will'
-be passed to lonnet::get_coursegroups() as a regexp to
-use in the call to the dump function.
-
-Output
-Returns number of groups in the course (subject to the
-optional group name filter).
-
-Side effects:
-Populates the referenced curr_groups hash, with key,
-value pairs. Keys are group names, corresponding values
-are scalars containing group information in XML. This
-can be sent to &get_group_settings() to be parsed.     
-
-=cut 
-
-###############################################
-
-sub coursegroups {
-    my ($cdom,$cnum,$group) = @_;
-    if (!defined($cdom) || !defined($cnum)) {
-        my $cid =  $env{'request.course.id'};
-
-	return if (!defined($cid));
-
-        $cdom = $env{'course.'.$cid.'.domain'};
-        $cnum = $env{'course.'.$cid.'.num'};
-    }
-    my %curr_groups = &Apache::lonnet::get_coursegroups($cdom,$cnum,$group);
-    my ($tmp) = keys(%curr_groups);
-    if ($tmp=~/^(con_lost|no_such_host|error: [^2] )/) {
-	undef(%curr_groups);
-	&logthis('Error retrieving groups: '.$tmp.' in '.$cnum.':'.$cdom);
-    } elsif ($tmp=~/^error: 2 /) {
-	undef(%curr_groups);
-    }
-    return %curr_groups;
-}
-
-###############################################
-
-=pod
-
-=item get_group_settings
-
-Uses TokeParser to extract group information from the
-XML used to describe course groups.
-
-Input:
-Scalar containing XML  - as retrieved from &coursegroups().
-
-Output:
-Hash containing group information as key=values for (a), and
-hash of hashes for (b)
-
-Keys (in two categories):
-(a) groupname, creator, creation, modified, startdate,enddate.
-Corresponding values are name of the group, creator of the group
-(username:domain), UNIX time for date group was created, and
-settings were last modified, and default start and end access
-times for group members.
-
-(b) functions returned in hash of hashes.
-Outer hash key is functions.
-Inner hash keys are chat,discussion,email,files,homepage,roster.
-Corresponding values are either on or off, depending on
-whether this type of functionality is available for the group.
-
-=cut
-                                                                                 
-###############################################
-
-sub get_group_settings {
-    my ($groupinfo)=@_;
-    my $parser=HTML::TokeParser->new(\$groupinfo);
-    my $token;
-    my $tool = '';
-    my $role = '';
-    my %content=();
-    while ($token=$parser->get_token) {
-        if ($token->[0] eq 'S')  {
-            my $entry=$token->[1];
-            if ($entry eq 'functions' || $entry eq 'autosec') {
-                %{$content{$entry}} = ();
-                $tool = $entry;
-            } elsif ($entry eq 'role') {
-                if ($tool eq 'autosec') {
-                    $role = $token->[2]{id};
-                }
-            } else {
-                my $value=$parser->get_text('/'.$entry);
-                if ($entry eq 'name') {
-                    if ($tool eq 'functions') {
-                        my $function = $token->[2]{id};
-                        $content{$tool}{$function} = $value;
-                    }
-                } elsif ($entry eq 'groupname') {
-                    $content{$entry}=&Apache::lonnet::unescape($value);
-                } elsif (($entry eq 'roles') || ($entry eq 'types') ||
-                         ($entry eq 'sectionpick') || ($entry eq 'defpriv')) {
-                    push(@{$content{$entry}},$value);
-                } elsif ($entry eq 'section') {
-                    if ($tool eq 'autosec'  && $role ne '') {
-                        push(@{$content{$tool}{$role}},$value);
-                    }
-                } else {
-                    $content{$entry}=$value;
-                }
-            }
-        } elsif ($token->[0] eq 'E') {
-            if ($token->[1] eq 'functions' || $token->[1] eq 'autosec') {
-                $tool = '';
-            } elsif ($token->[1] eq 'role') {
-                $role = '';
-            }
-
-        }
+	$sectioncount{$section}++;
     }
-    return %content;
-}
-
-sub check_group_access {
-    my ($group) = @_;
-    my $access = 1;
-    my $now = time;
-    my ($start,$end) = split(/\./,$env{'user.role.gr/'.$env{'request.course,id'}.'/'.$group});
-    if (($end!=0) && ($end<$now)) { $access = 0; }
-    if (($start!=0) && ($start>$now)) { $access=0; }
-    return $access;
+    return %sectioncount;
 }
 
 ###############################################
@@ -4065,6 +4014,43 @@ sub get_user_info {
     return;
 }
 
+sub get_secgrprole_info {
+    my ($cdom,$cnum,$needroles,$type)  = @_;
+    my %sections_count = &get_sections($cdom,$cnum);
+    my @sections =  (sort {$a <=> $b} keys(%sections_count));
+    my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
+    my @groups = sort(keys(%curr_groups));
+    my $allroles = [];
+    my $rolehash;
+    my $accesshash = {
+                     active => 'Currently has access',
+                     future => 'Will have future access',
+                     previous => 'Previously had access',
+                  };
+    if ($needroles) {
+        $rolehash = {'all' => 'all'};
+        my %user_roles = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum);
+	if (&Apache::lonnet::error(%user_roles)) {
+	    undef(%user_roles);
+	}
+        foreach my $item (keys(%user_roles)) {
+            my ($role)=split(/\:/,$item,2);
+            if ($role eq 'cr') { next; }
+            if ($role =~ /^cr/) {
+                $$rolehash{$role} = (split('/',$role))[3];
+            } else {
+                $$rolehash{$role} = &Apache::lonnet::plaintext($role,$type);
+            }
+        }
+        foreach my $key (sort(keys(%{$rolehash}))) {
+            push(@{$allroles},$key);
+        }
+        push (@{$allroles},'st');
+        $$rolehash{'st'} = &Apache::lonnet::plaintext('st',$type);
+    }
+    return (\@sections,\@groups,$allroles,$rolehash,$accesshash);
+}
+
 =pod
 
 =item * get_unprocessed_cgi($query,$possible_names)
@@ -4085,7 +4071,7 @@ sub get_unprocessed_cgi {
   # $Apache::lonxml::debug=1;
   foreach my $pair (split(/&/,$query)) {
     my ($name, $value) = split(/=/,$pair);
-    $name = &Apache::lonnet::unescape($name);
+    $name = &unescape($name);
     if (!defined($possible_names) || (grep {$_ eq $name} @$possible_names)) {
       $value =~ tr/+/ /;
       $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
@@ -4714,9 +4700,9 @@ sub DrawBarGraph {
     $Title  = '' if (! defined($Title));
     $xlabel = '' if (! defined($xlabel));
     $ylabel = '' if (! defined($ylabel));
-    $ValuesHash{$id.'.title'}    = &Apache::lonnet::escape($Title);
-    $ValuesHash{$id.'.xlabel'}   = &Apache::lonnet::escape($xlabel);
-    $ValuesHash{$id.'.ylabel'}   = &Apache::lonnet::escape($ylabel);
+    $ValuesHash{$id.'.title'}    = &escape($Title);
+    $ValuesHash{$id.'.xlabel'}   = &escape($xlabel);
+    $ValuesHash{$id.'.ylabel'}   = &escape($ylabel);
     $ValuesHash{$id.'.y_max_value'} = $Max;
     $ValuesHash{$id.'.NumBars'}  = $NumBars;
     $ValuesHash{$id.'.NumSets'}  = $NumSets;
@@ -4796,9 +4782,9 @@ sub DrawXYGraph {
     $ylabel = '' if (! defined($ylabel));
     my %ValuesHash = 
         (
-         $id.'.title'  => &Apache::lonnet::escape($Title),
-         $id.'.xlabel' => &Apache::lonnet::escape($xlabel),
-         $id.'.ylabel' => &Apache::lonnet::escape($ylabel),
+         $id.'.title'  => &escape($Title),
+         $id.'.xlabel' => &escape($xlabel),
+         $id.'.ylabel' => &escape($ylabel),
          $id.'.y_max_value'=> $Max,
          $id.'.labels'     => join(',',@$Xlabels),
          $id.'.PlotType'   => 'XY',
@@ -4893,9 +4879,9 @@ sub DrawXYYGraph {
     $ylabel = '' if (! defined($ylabel));
     my %ValuesHash = 
         (
-         $id.'.title'  => &Apache::lonnet::escape($Title),
-         $id.'.xlabel' => &Apache::lonnet::escape($xlabel),
-         $id.'.ylabel' => &Apache::lonnet::escape($ylabel),
+         $id.'.title'  => &escape($Title),
+         $id.'.xlabel' => &escape($xlabel),
+         $id.'.ylabel' => &escape($ylabel),
          $id.'.labels' => join(',',@$Xlabels),
          $id.'.PlotType' => 'XY',
          $id.'.NumSets' => 2,
@@ -4967,7 +4953,7 @@ Inputs:
 sub chartlink {
     my ($linktext, $sname, $sdomain) = @_;
     my $link = '<a href="/adm/statistics?reportSelected=student_assessment'.
-        '&amp;SelectedStudent='.&Apache::lonnet::escape($sname.':'.$sdomain).
+        '&amp;SelectedStudent='.&escape($sname.':'.$sdomain).
         '&amp;chartoutputmode='.HTML::Entities::encode('html, with all links').
        '">'.$linktext.'</a>';
 }
@@ -4997,6 +4983,7 @@ a hash ref describing the data to be sto
     'chartoutputmode' => 'scalar',
     'chartoutputdata' => 'scalar',
     'Section' => 'array',
+    'Group' => 'array',
     'StudentData' => 'array',
     'Maps' => 'array');
 
@@ -5030,11 +5017,11 @@ sub store_course_settings {
                 if (ref($env{'form.'.$setting})) {
                     $stored_form = join(',',
                                         map {
-                                            &Apache::lonnet::escape($_);
+                                            &escape($_);
                                         } sort(@{$env{'form.'.$setting}}));
                 } else {
                     $stored_form = 
-                        &Apache::lonnet::escape($env{'form.'.$setting});
+                        &escape($env{'form.'.$setting});
                 }
                 # Determine if the array contents are the same.
                 if ($stored_form ne $env{$envname}) {
@@ -5068,7 +5055,7 @@ sub restore_course_settings {
             } elsif ($type eq 'array') {
                 $env{'form.'.$setting} = [ 
                                            map { 
-                                               &Apache::lonnet::unescape($_); 
+                                               &unescape($_); 
                                            } split(',',$env{$envname})
                                            ];
             }
@@ -5079,15 +5066,17 @@ sub restore_course_settings {
 ############################################################
 ############################################################
 
-sub propath {
-    my ($udom,$uname)=@_;
-    $udom=~s/\W//g;
-    $uname=~s/\W//g;
-    my $subdir=$uname.'__';
-    $subdir =~ s/(.)(.)(.).*/$1\/$2\/$3/;
-    my $proname="$Apache::lonnet::perlvar{'lonUsersDir'}/$udom/$subdir/$uname";
-    return $proname;
-} 
+sub course_type {
+    my ($cid) = @_;
+    if (!defined($cid)) {
+        $cid = $env{'request.course.id'};
+    }
+    if (defined($env{'course.'.$cid.'type'})) {
+        return $env{'course.'.$cid.'type'};
+    } else {
+        return 'Course';
+    }
+}
 
 sub icon {
     my ($file)=@_;
@@ -5141,7 +5130,7 @@ sub escape_double {
 sub escape_url {
     my ($url)   = @_;
     my @urlslices = split(/\//, $url,-1);
-    my $lastitem = &Apache::lonnet::escape(pop(@urlslices));
+    my $lastitem = &escape(pop(@urlslices));
     return join('/',@urlslices).'/'.$lastitem;
 }
 =pod