--- loncom/interface/loncommon.pm 2009/09/07 13:11:33 1.889
+++ loncom/interface/loncommon.pm 2010/12/19 22:34:42 1.948.2.14
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common routines
#
-# $Id: loncommon.pm,v 1.889 2009/09/07 13:11:33 raeburn Exp $
+# $Id: loncommon.pm,v 1.948.2.14 2010/12/19 22:34:42 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -482,8 +482,11 @@ ENDAUTHORBRW
}
sub coursebrowser_javascript {
- my ($domainfilter,$sec_element,$formname)=@_;
- my $crs_or_grp_alert = &mt('Please select the type of LON-CAPA entity - Course or Community - for which you wish to add/modify a user role.');
+ my ($domainfilter,$sec_element,$formname,$role_element,$crstype) = @_;
+ my $wintitle = 'Course_Browser';
+ if ($crstype eq 'Community') {
+ $wintitle = 'Community_Browser';
+ }
my $id_functions = &javascript_index_functions();
my $output = '
END_MYBLOCK
+
+ $output = Apache::lonhtmlcommon::scripttag($output);
+
my $popupUrl = "/adm/blockingstatus/$querystring";
+ my $text = mt('Communication Blocked');
+
$output .= <<"END_BLOCK";
END_BLOCK
@@ -4043,7 +4247,7 @@ sub determinedomain {
my $domain=shift;
if (! $domain) {
# Determine domain if we have not been given one
- $domain = $Apache::lonnet::perlvar{'lonDefDomain'};
+ $domain = &Apache::lonnet::default_login_domain();
if ($env{'user.domain'}) { $domain=$env{'user.domain'}; }
if ($env{'request.role.domain'}) {
$domain=$env{'request.role.domain'};
@@ -4066,16 +4270,39 @@ sub get_domainconf {
if (defined($cached)) { return %{$result}; }
my %domconfig = &Apache::lonnet::get_dom('configuration',
- ['login','rolecolors'],$udom);
+ ['login','rolecolors','autoenroll'],$udom);
my (%designhash,%legacy);
if (keys(%domconfig) > 0) {
if (ref($domconfig{'login'}) eq 'HASH') {
if (keys(%{$domconfig{'login'}})) {
foreach my $key (keys(%{$domconfig{'login'}})) {
if (ref($domconfig{'login'}{$key}) eq 'HASH') {
- foreach my $img (keys(%{$domconfig{'login'}{$key}})) {
- $designhash{$udom.'.login.'.$key.'_'.$img} =
- $domconfig{'login'}{$key}{$img};
+ if ($key eq 'loginvia') {
+ if (ref($domconfig{'login'}{'loginvia'}) eq 'HASH') {
+ my @ids = &Apache::lonnet::current_machine_ids();
+ foreach my $hostname (@ids) {
+ if (ref($domconfig{'login'}{'loginvia'}{$hostname}) eq 'HASH') {
+ if ($domconfig{'login'}{'loginvia'}{$hostname}{'server'}) {
+ my $server = $domconfig{'login'}{'loginvia'}{$hostname}{'server'};
+ $designhash{$udom.'.login.loginvia'} = $server;
+ if ($domconfig{'login'}{'loginvia'}{$hostname}{'serverpath'} eq 'custom') {
+
+ $designhash{$udom.'.login.loginvia_'.$hostname} = $server.':'.$domconfig{'login'}{'loginvia'}{$hostname}{'custompath'};
+ } else {
+ $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'};
+ }
+ }
+ }
+ }
+ }
+ } else {
+ foreach my $img (keys(%{$domconfig{'login'}{$key}})) {
+ $designhash{$udom.'.login.'.$key.'_'.$img} =
+ $domconfig{'login'}{$key}{$img};
+ }
}
} else {
$designhash{$udom.'.login.'.$key}=$domconfig{'login'}{$key};
@@ -4102,6 +4329,11 @@ sub get_domainconf {
} else {
$legacy{'rolecolors'} = 1;
}
+ if (ref($domconfig{'autoenroll'}) eq 'HASH') {
+ if ($domconfig{'autoenroll'}{'co-owners'}) {
+ $designhash{$udom.'.autoassign.co-owners'}=$domconfig{'autoenroll'}{'co-owners'};
+ }
+ }
if (keys(%legacy) > 0) {
my %legacyhash = &get_legacy_domconf($udom);
foreach my $item (keys(%legacyhash)) {
@@ -4294,18 +4526,30 @@ sub CSTR_pageheader {
} else {
$lastitem = $thisdisfn;
}
- return
+
+ my $output =
'
'
.&Apache::loncommon::help_open_menu('','',3,'Authoring') #FIXME: Broken? Where is it?
.''.&mt('Construction Space:').' '
.''
.&Apache::lonmenu::constspaceform()
.'
';
+
+ return $output;
}
###############################################
@@ -4367,6 +4611,11 @@ sub bodytag {
my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,
$no_nav_bar,$bgcolor,$no_inline_link,$args)=@_;
+ my $public;
+ if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public'))
+ || ($env{'user.name'} eq '') && ($env{'user.domain'} eq '')) {
+ $public = 1;
+ }
if (!$args->{'no_auto_mt_title'}) { $title = &mt($title); }
$function = &get_users_function() if (!$function);
@@ -4393,6 +4642,9 @@ sub bodytag {
if ($env{'request.role'} !~ /^cr/) {
$role = &Apache::lonnet::plaintext($role,&course_type());
}
+ if ($env{'request.course.sec'}) {
+ $role .= (' 'x2).'- '.&mt('section:').' '.$env{'request.course.sec'};
+ }
$realm = $env{'course.'.$env{'request.course.id'}.'.description'};
} else {
$role = &Apache::lonnet::plaintext($role);
@@ -4413,12 +4665,12 @@ sub bodytag {
}
my $name = &plainname($env{'user.name'},$env{'user.domain'});
- if ($env{'user.name'} eq 'public' && $env{'user.domain'} eq 'public') {
+ if ($public) {
undef($role);
} else {
$name = &aboutmewrapper($name,$env{'user.name'},$env{'user.domain'});
}
-
+
my $titleinfo = '
'.$title.'
';
#
# Extra info if you are the DC
@@ -4427,40 +4679,68 @@ sub bodytag {
$env{'course.'.$env{'request.course.id'}.
'.domain'}.'/'})) {
my $cid = $env{'request.course.id'};
- $dc_info.= $cid.' '.$env{'course.'.$cid.'.internal.coursecode'};
+ $dc_info = $cid.' '.$env{'course.'.$cid.'.internal.coursecode'};
$dc_info =~ s/\s+$//;
- $dc_info = '('.$dc_info.')';
}
- $role = "($role)" if $role;
+ $role = '('.$role.')' if $role;
&get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['inhibitmenu']);
if ($env{'environment.remote'} eq 'off') {
# No Remote
- if ($env{'request.state'} eq 'construct') {
- $forcereg=1;
- }
+ if ($no_nav_bar || $env{'form.inhibitmenu'} eq 'yes') {
+ return $bodytag;
+ }
-# if ($env{'request.state'} eq 'construct') {
-# $titleinfo = &CSTR_pageheader(); #FIXME: Will be removed once all scripts have their own calls
-# }
-
- my $titletable = '
|;
+
+ #don't show menus for public users
+ if (!$public){
+ $bodytag .= Apache::lonmenu::secondary_menu();
+ $bodytag .= Apache::lonmenu::serverform();
+ $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');
+ if ($env{'request.state'} eq 'construct') {
+ $bodytag .= &Apache::lonmenu::innerregister($forcereg,'',
+ $args->{'bread_crumbs'});
+ } elsif ($forcereg) {
+ $bodytag .= &Apache::lonmenu::innerregister($forcereg);
}
+ }else{
+ # this is to seperate menu from content when there's no secondary
+ # menu. Especially needed for public accessible ressources.
+ $bodytag .= '';
+ $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');
}
+
return $bodytag;
}
@@ -4477,12 +4757,15 @@ sub bodytag {
# Explicit link to get inline menu
my $menu= ($no_inline_link?''
:''.&mt('Switch to Inline Menu Mode').'');
- $bodytag .= qq|
'."\n";;
}
@@ -6771,6 +7089,11 @@ sub simple_error_page {
sub end_data_table_header_row {
return '
'."\n";;
}
+
+ sub data_table_caption {
+ my $caption = shift;
+ return "
$caption
";
+ }
}
=pod
@@ -6841,7 +7164,7 @@ sub get_users_function {
if ($env{'request.role'}=~/^(st)/) {
$function='student';
}
- if ($env{'request.role'}=~/^(cc|in|ta|ep)/) {
+ if ($env{'request.role'}=~/^(cc|co|in|ta|ep)/) {
$function='coordinator';
}
if ($env{'request.role'}=~/^(su|dc|ad|li)/) {
@@ -6906,13 +7229,14 @@ role status: active, previous or future.
sub check_user_status {
my ($udom,$uname,$cdom,$crs,$role,$sec) = @_;
- my %userinfo = &Apache::lonnet::dump('roles',$udom,$uname);
+ my $extra = &Apache::lonnet::freeze_escape({'skipcheck' => 1});
+ my %userinfo = &Apache::lonnet::dump('roles',$udom,$uname,'.',undef,$extra);
my @uroles = keys %userinfo;
my $srchstr;
my $active_chk = 'none';
my $now = time;
if (@uroles > 0) {
- if (($role eq 'cc') || ($sec eq '') || (!defined($sec))) {
+ if (($role eq 'cc') || ($role eq 'co') || ($sec eq '') || (!defined($sec))) {
$srchstr = '/'.$cdom.'/'.$crs.'_'.$role;
} else {
$srchstr = '/'.$cdom.'/'.$crs.'/'.$sec.'_'.$role;
@@ -7945,6 +8269,10 @@ sub get_institutional_codes {
return;
}
+sub get_standard_codeitems {
+ return ('Year','Semester','Department','Number','Section');
+}
+
=pod
=head1 Slot Helpers
@@ -8136,14 +8464,83 @@ sub get_env_multiple {
sub ask_for_embedded_content {
my ($actionurl,$state,$allfiles,$codebase,$args)=@_;
- my $upload_output = '
- ';
+ if ($num) {
+ $upload_output = '';
+ }
return $upload_output;
}
@@ -8213,8 +8617,7 @@ sub upload_embedded {
$dir_root,$port_path,$disk_quota,
$current_disk_usage,$uname,$udom);
if ($state eq 'will_exceed_quota'
- || $state eq 'file_locked'
- || $state eq 'file_exists' ) {
+ || $state eq 'file_locked') {
$output .= $msg;
next;
}
@@ -8241,18 +8644,25 @@ sub upload_embedded {
$env{'form.embedded_item_'.$i.'.filename'}=$fname;
if ($context eq 'portfolio') {
- my $result=
- &Apache::lonnet::userfileupload('embedded_item_'.$i,'',
- $dirpath.$path);
- if ($result !~ m|^/uploaded/|) {
- $output .= ''
- .&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].'
- ,$result,$orig_uploaded_filename,$env{'form.embedded_orig_'.$i})
- .' ';
- next;
+ my $result;
+ if ($state eq 'existingfile') {
+ $result=
+ &Apache::lonnet::userfileupload('embedded_item_'.$i,'existingfile',
+ $dirpath.$path,);
} else {
- $output .= '
'.&mt('Uploaded [_1]',''.
- $path.$fname.'').'
';
+ $result=
+ &Apache::lonnet::userfileupload('embedded_item_'.$i,'',
+ $dirpath.$path);
+ if ($result !~ m|^/uploaded/|) {
+ $output .= ''
+ .&mt('An error occurred ([_1]) while trying to upload [_2] for embedded element [_3].'
+ ,$result,$orig_uploaded_filename,$env{'form.embedded_orig_'.$i})
+ .' ';
+ next;
+ } else {
+ $output .= '
'.&mt('Uploaded [_1]',''.
+ $path.$fname.'').'
';
+ }
}
} else {
# Save the file
@@ -8318,14 +8728,24 @@ sub check_for_existing {
sub check_for_upload {
my ($path,$fname,$group,$element,$portfolio_root,$port_path,
$disk_quota,$current_disk_usage,$uname,$udom) = @_;
- my $filesize = (length($env{'form.'.$element})) / 1000; #express in k (1024?)
+ my $filesize = length($env{'form.'.$element});
+ if (!$filesize) {
+ my $msg = ''.
+ &mt('Unable to upload [_1]. (size = [_2] bytes)',
+ ''.$fname.'',
+ $filesize).' '.
+ &mt('Either the file you uploaded 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 $found_file = 0;
my $locked_file = 0;
foreach my $line (@dir_list) {
- my ($file_name)=split(/\&/,$line,2);
+ my ($file_name,$rest)=split(/\&/,$line,2);
if ($file_name eq $fname){
$file_name = $path.$file_name;
if ($group ne '') {
@@ -8334,6 +8754,20 @@ sub check_for_upload {
$found_file = 1;
if (&Apache::lonnet::is_locked($file_name,$udom,$uname) eq 'true') {
$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);
+ }
+ }
}
}
}
@@ -8351,11 +8785,9 @@ sub check_for_upload {
return ('file_locked',$msg);
} else {
my $msg = '';
- $msg .= &mt('Unable to upload [_1]. A file by that name was found in [_2].',''.$fname.'',$port_path.$env{'form.currentpath'});
+ $msg .= &mt(' A file by that name: [_1] was found in [_2].',''.$fname.'',$port_path.$env{'form.currentpath'});
$msg .= '';
- $msg .= ' ';
- $msg .= &mt('To upload, rename or delete existing [_1] in [_2].',''.$fname.'', $port_path.$env{'form.currentpath'});
- return ('file_exists',$msg);
+ return ('existingfile',$msg);
}
}
}
@@ -9466,6 +9898,8 @@ sub extract_categories {
my $trailstr;
if ($name eq 'instcode') {
$trailstr = &mt('Official courses (with institutional codes)');
+ } elsif ($name eq 'communities') {
+ $trailstr = &mt('Communities');
} else {
$trailstr = $name;
}
@@ -9578,12 +10012,14 @@ cathash - reference to hash of categorie
currcat - scalar with an & separated list of categories assigned to a course.
+type - scalar contains course type (Course or Community).
+
Returns: $output (markup to be displayed)
=cut
sub assign_categories_table {
- my ($cathash,$currcat) = @_;
+ my ($cathash,$currcat,$type) = @_;
my $output;
if (ref($cathash) eq 'HASH') {
my (@cats,@trails,%allitems,%idx,@jsarray,@path,$maxdepth);
@@ -9592,15 +10028,20 @@ sub assign_categories_table {
if (@cats > 0) {
my $itemcount = 0;
if (ref($cats[0]) eq 'ARRAY') {
- $output = &Apache::loncommon::start_data_table();
my @currcategories;
if ($currcat ne '') {
@currcategories = split('&',$currcat);
}
+ my $table;
for (my $i=0; $i<@{$cats[0]}; $i++) {
my $parent = $cats[0][$i];
- my $css_class = $itemcount%2?' class="LC_odd_row"':'';
next if ($parent eq 'instcode');
+ if ($type eq 'Community') {
+ next unless ($parent eq 'communities');
+ } else {
+ next if ($parent eq 'communities');
+ }
+ my $css_class = $itemcount%2?' class="LC_odd_row"':'';
my $item = &escape($parent).'::0';
my $checked = '';
if (@currcategories > 0) {
@@ -9608,18 +10049,26 @@ sub assign_categories_table {
$checked = ' checked="checked"';
}
}
- $output .= '
';
$itemcount ++;
}
- $output .= &Apache::loncommon::end_data_table();
+ if ($itemcount) {
+ $output = &Apache::loncommon::start_data_table().
+ $table.
+ &Apache::loncommon::end_data_table();
+ }
}
}
}
@@ -9864,11 +10313,24 @@ sub check_clone {
my $clonehome=&Apache::lonnet::homeserver($clonecrsunum,$clonecrsudom);
my $clonemsg;
my $can_clone = 0;
-
+ my $lctype = lc($args->{'crstype'});
+ if ($lctype ne 'community') {
+ $lctype = 'course';
+ }
if ($clonehome eq 'no_host') {
- $clonemsg = &mt('No new course created.').$linefeed.&mt('A new course could not be cloned from the specified original - [_1] - because it is a non-existent course.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
+ if ($args->{'crstype'} eq 'Community') {
+ $clonemsg = &mt('No new community created.').$linefeed.&mt('A new community could not be cloned from the specified original - [_1] - because it is a non-existent community.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
+ } else {
+ $clonemsg = &mt('No new course created.').$linefeed.&mt('A new course could not be cloned from the specified original - [_1] - because it is a non-existent course.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
+ }
} else {
my %clonedesc = &Apache::lonnet::coursedescription($cloneid,{'one_time' => 1});
+ if ($args->{'crstype'} eq 'Community') {
+ if ($clonedesc{'type'} ne 'Community') {
+ $clonemsg = &mt('No new community created.').$linefeed.&mt('A new community could not be cloned from the specified original - [_1] - because it is a course not a community.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
+ return ($can_clone, $clonemsg, $cloneid, $clonehome);
+ }
+ }
if (($env{'request.role.domain'} eq $args->{'clonedomain'}) &&
(&Apache::lonnet::allowed('ccc',$env{'request.role.domain'}))) {
$can_clone = 1;
@@ -9881,15 +10343,25 @@ sub check_clone {
} elsif (grep(/^\*\:\Q$args->{'ccdomain'}\E$/,@cloners)) {
$can_clone = 1;
} else {
+ my $ccrole = 'cc';
+ if ($args->{'crstype'} eq 'Community') {
+ $ccrole = 'co';
+ }
my %roleshash =
&Apache::lonnet::get_my_roles($args->{'ccuname'},
$args->{'ccdomain'},
- 'userroles',['active'],['cc'],
+ 'userroles',['active'],[$ccrole],
[$args->{'clonedomain'}]);
- if (($roleshash{$args->{'clonecourse'}.':'.$args->{'clonedomain'}.':cc'}) || (grep(/^\Q$args->{'ccuname'}\E:\Q$args->{'ccdomain'}\E$/,@cloners))) {
- $can_clone = 1;
- } else {
- $clonemsg = &mt('No new course created.').$linefeed.&mt('The new course could not be cloned from the existing course because the new course owner ([_1]) does not have cloning rights in the existing course ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});
+ if (($roleshash{$args->{'clonecourse'}.':'.$args->{'clonedomain'}.':'.$ccrole}) || (grep(/^\Q$args->{'ccuname'}\E:\Q$args->{'ccdomain'}\E$/,@cloners))) {
+ $can_clone = 1;
+ } elsif (&Apache::lonnet::is_course_owner($args->{'clonedomain'},$args->{'clonecourse'},$args->{'ccuname'},$args->{'ccdomain'})) {
+ $can_clone = 1;
+ } else {
+ if ($args->{'crstype'} eq 'Community') {
+ $clonemsg = &mt('No new community created.').$linefeed.&mt('The new community could not be cloned from the existing community because the new community owner ([_1]) does not have cloning rights in the existing community ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});
+ } else {
+ $clonemsg = &mt('No new course created.').$linefeed.&mt('The new course could not be cloned from the existing course because the new course owner ([_1]) does not have cloning rights in the existing course ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});
+ }
}
}
}
@@ -9944,11 +10416,19 @@ sub construct_course {
# if anyone ever decides to not show this, and Utils::Course::new
# will need to be suitably modified.
$outcome .= &mt('New LON-CAPA [_1] ID: [_2]',$crstype,$$courseid).$linefeed;
+ if ($$courseid =~ /^error:/) {
+ return (0,$outcome);
+ }
+
#
# Check if created correctly
#
($$crsudom,$$crsunum)= &LONCAPA::split_courseid($$courseid);
my $crsuhome=&Apache::lonnet::homeserver($$crsunum,$$crsudom);
+ if ($crsuhome eq 'no_host') {
+ $outcome .= &mt('Course creation failed, unrecognized course home server.').$linefeed;
+ return (0,$outcome);
+ }
$outcome .= &mt('Created on').': '.$crsuhome.$linefeed;
#
@@ -9967,6 +10447,10 @@ sub construct_course {
$cenv{'url'}=$oldcenv{'url'};
# Restore title
$cenv{'description'}=$oldcenv{'description'};
+# Restore creation date, creator and creation context.
+ $cenv{'internal.created'}=$oldcenv{'internal.created'};
+ $cenv{'internal.creator'}=$oldcenv{'internal.creator'};
+ $cenv{'internal.creationcontext'}=$oldcenv{'internal.creationcontext'};
# Mark as cloned
$cenv{'clonedfrom'}=$cloneid;
# Need to clone grading mode
@@ -10213,7 +10697,7 @@ sub construct_course {
$title=&mt('Syllabus');
$url='/public/'.$$crsudom.'/'.$$crsunum.'/syllabus';
} else {
- $title=&mt('Navigate Contents');
+ $title=&mt('Table of Contents');
$url='/adm/navmaps';
}
@@ -10251,6 +10735,16 @@ sub group_term {
return $names{$crstype};
}
+sub course_types {
+ my @types = ('official','unofficial','community');
+ my %typename = (
+ official => 'Official course',
+ unofficial => 'Unofficial course',
+ community => 'Community',
+ );
+ return (\@types,\%typename);
+}
+
sub icon {
my ($file)=@_;
my $curfext = lc((split(/\./,$file))[-1]);
@@ -10433,16 +10927,20 @@ sub init_user_environment {
$initial_env{"browser.interface"} = $form->{'interface'};
$env{'browser.interface'}=$form->{'interface'};
}
+ my %is_adv = ( is_adv => $env{'user.adv'} );
+ my %domdef = &Apache::lonnet::get_domain_defaults($domain);
foreach my $tool ('aboutme','blog','portfolio') {
$userenv{'availabletools.'.$tool} =
- &Apache::lonnet::usertools_access($username,$domain,$tool,'reload');
+ &Apache::lonnet::usertools_access($username,$domain,$tool,'reload',
+ undef,\%userenv,\%domdef,\%is_adv);
}
foreach my $crstype ('official','unofficial','community') {
$userenv{'canrequest.'.$crstype} =
&Apache::lonnet::usertools_access($username,$domain,$crstype,
- 'reload','requestcourses');
+ 'reload','requestcourses',
+ \%userenv,\%domdef,\%is_adv);
}
$env{'user.environment'} = "$lonids/$cookie.id";